Skip to content

Commit 790e74f

Browse files
committed
added package and gh workflows
1 parent bd226dc commit 790e74f

File tree

9 files changed

+3676
-4713
lines changed

9 files changed

+3676
-4713
lines changed

.github/worksflow/main.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: CI
2+
on:
3+
push:
4+
branches:
5+
- "**"
6+
7+
jobs:
8+
build:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v3
12+
- uses: pnpm/action-setup@v2
13+
with:
14+
version: 7
15+
- uses: actions/setup-node@v3
16+
with:
17+
node-version: 16.x
18+
cache: "pnpm"
19+
20+
- run: pnpm install --frozen-lockfile
21+
- run: pnpm run lint && pnpm run build

.github/worksflow/publish.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Publish
2+
on:
3+
workflow_run:
4+
workflows: [CI]
5+
branches: [main]
6+
types: [completed]
7+
8+
concurrency: ${{ github.workflow }}-${{ github.ref }}
9+
10+
permissions:
11+
contents: write
12+
pull-requests: write
13+
14+
jobs:
15+
publish:
16+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v3
20+
- uses: pnpm/action-setup@v2
21+
with:
22+
version: 7
23+
- uses: actions/setup-node@v3
24+
with:
25+
node-version: 16.x
26+
cache: "pnpm"
27+
28+
- run: pnpm install --frozen-lockfile
29+
- name: Create Release Pull Request or Publish
30+
id: changesets
31+
uses: changesets/action@v1
32+
with:
33+
publish: pnpm run release
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Changesets
2+
3+
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4+
with multi-package repos, or single-package repos to help you version and publish your code. You can
5+
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6+
7+
We have a quick list of common questions to get you started engaging with this project in
8+
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
3+
"changelog": "@changesets/cli/changelog",
4+
"commit": false,
5+
"fixed": [],
6+
"linked": [],
7+
"access": "restricted",
8+
"baseBranch": "main",
9+
"updateInternalDependencies": "patch",
10+
"ignore": []
11+
}

packages/typer-diff/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist
2+
node_modules

packages/typer-diff/index.ts

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
export type DiffItem = {
2+
// the value can be a character, a word, a string
3+
value: string;
4+
type: "correct" | "extra" | "missing" | "wrong" | "untouched" | "spacer";
5+
};
6+
7+
export type DiffResult = {
8+
diff: DiffItem[];
9+
end: boolean;
10+
};
11+
12+
export const diff = (originalText: string, typedText: string): DiffResult => {
13+
const correctWords = originalText.split(" ");
14+
const typedWords = typedText.split(" ");
15+
const currentWordIndex = typedWords.length - 1;
16+
const diff: DiffItem[] = [];
17+
18+
// compare words BEFORE current word
19+
if (currentWordIndex > 0) {
20+
for (let i = 0; i < currentWordIndex; i++) {
21+
if (i >= correctWords.length) {
22+
break;
23+
}
24+
const correctWord = correctWords[i];
25+
const typedWord = typedWords[i];
26+
if (!correctWord || !typedWord) {
27+
continue;
28+
}
29+
const wordDiff = diffWord(correctWord, typedWord);
30+
diff.push(...wordDiff);
31+
diff.push({ value: " ", type: "spacer" });
32+
}
33+
}
34+
if (currentWordIndex >= correctWords.length) {
35+
return { diff, end: true };
36+
}
37+
// compare current word
38+
const correctWord = correctWords[currentWordIndex];
39+
const typedWord = typedWords[currentWordIndex];
40+
if (!correctWord || !typedWord) {
41+
return { diff, end: false };
42+
}
43+
const currentWordDiff = diffCurrentWord(correctWord, typedWord);
44+
diff.push(...currentWordDiff);
45+
46+
// words AFTER current word are untouched
47+
if (currentWordIndex + 1 < correctWords.length) {
48+
for (let i = currentWordIndex + 1; i < correctWords.length; i++) {
49+
const correctWord = correctWords[i];
50+
if (!correctWord) {
51+
continue;
52+
}
53+
diff.push({ value: correctWord, type: "untouched" });
54+
diff.push({ value: " ", type: "spacer" });
55+
}
56+
}
57+
58+
return { diff, end: false };
59+
};
60+
61+
const diffWord = (originalWord: string, typedWord: string) => {
62+
const diff: DiffItem[] = [];
63+
64+
// compare letters
65+
const correctLength = originalWord.length;
66+
const typedLength = typedWord.length;
67+
68+
// if typed word is shorter than correct word: typed: "hel", correct: "hello"
69+
if (typedLength < correctLength) {
70+
// check until typedLength
71+
for (let i = 0; i < typedLength; i++) {
72+
let originalChar = originalWord[i];
73+
let typedChar = typedWord[i];
74+
if (!originalChar || !typedChar) {
75+
continue;
76+
}
77+
diff.push(diffChar(originalChar, typedChar));
78+
}
79+
// the rest are missing
80+
for (let i = typedLength; i < correctLength; i++) {
81+
let originalChar = originalWord[i];
82+
if (!originalChar) {
83+
continue;
84+
}
85+
diff.push({ value: originalChar, type: "missing" });
86+
}
87+
}
88+
89+
// if typed word is longer than correct word: typed: "helloo", correct: "hello"
90+
if (typedLength > correctLength) {
91+
// check until correctLength
92+
for (let i = 0; i < correctLength; i++) {
93+
let originalChar = originalWord[i];
94+
let typedChar = typedWord[i];
95+
if (!originalChar || !typedChar) {
96+
continue;
97+
}
98+
diff.push(diffChar(originalChar, typedChar));
99+
}
100+
// the rest are extra
101+
for (let i = correctLength; i < typedLength; i++) {
102+
let typedChar = typedWord[i];
103+
if (!typedChar) {
104+
continue;
105+
}
106+
diff.push({ value: typedChar, type: "extra" });
107+
}
108+
}
109+
110+
// if typed word is equal to correct word: typed: "hello", correct: "alloh"
111+
if (typedLength === correctLength) {
112+
for (let i = 0; i < correctLength; i++) {
113+
let originalChar = originalWord[i];
114+
let typedChar = typedWord[i];
115+
if (!originalChar || !typedChar) {
116+
continue;
117+
}
118+
diff.push(diffChar(originalChar, typedChar));
119+
}
120+
}
121+
122+
return diff;
123+
};
124+
125+
const diffChar = (originalChar: string, typedChar: string): DiffItem => {
126+
if (originalChar === typedChar) {
127+
return { value: originalChar, type: "correct" };
128+
}
129+
return { value: typedChar, type: "wrong" };
130+
};
131+
132+
const diffCurrentWord = (correctWord: string, typedWord: string) => {
133+
const diff: DiffItem[] = [];
134+
const correctLength = correctWord.length;
135+
const typedLength = typedWord.length;
136+
137+
// if typed word is shorter than correct word: typed: "hel", correct: "hello"
138+
if (typedLength < correctLength) {
139+
// check until typedLength
140+
for (let i = 0; i < typedLength; i++) {
141+
let originalChar = correctWord[i];
142+
let typedChar = typedWord[i];
143+
if (!originalChar || !typedChar) {
144+
continue;
145+
}
146+
diff.push(diffChar(originalChar, typedChar));
147+
}
148+
// the rest are untouched
149+
for (let i = typedLength; i < correctLength; i++) {
150+
let originalChar = correctWord[i];
151+
if (!originalChar) {
152+
continue;
153+
}
154+
diff.push({ value: originalChar, type: "untouched" });
155+
}
156+
}
157+
158+
// if typed word is longer than correct word: typed: "helloo", correct: "hello"
159+
if (typedLength > correctLength) {
160+
// check until correctLength
161+
for (let i = 0; i < correctLength; i++) {
162+
let originalChar = correctWord[i];
163+
let typedChar = typedWord[i];
164+
if (!originalChar || !typedChar) {
165+
continue;
166+
}
167+
diff.push(diffChar(originalChar, typedChar));
168+
}
169+
// the rest are extra
170+
for (let i = correctLength; i < typedLength; i++) {
171+
let typedChar = typedWord[i];
172+
if (!typedChar) {
173+
continue;
174+
}
175+
diff.push({ value: typedChar, type: "extra" });
176+
}
177+
}
178+
179+
// if typed word is equal to correct word: typed: "hello", correct: "alloh"
180+
if (typedLength === correctLength) {
181+
for (let i = 0; i < correctLength; i++) {
182+
let originalChar = correctWord[i];
183+
let typedChar = typedWord[i];
184+
if (!originalChar || !typedChar) {
185+
continue;
186+
}
187+
diff.push(diffChar(originalChar, typedChar));
188+
}
189+
}
190+
191+
diff.push({ value: " ", type: "spacer" });
192+
193+
return diff;
194+
};

packages/typer-diff/package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "typer-diff",
3+
"license": "MIT",
4+
"version": "0.0.1",
5+
"main": "dist/index.js",
6+
"module": "dist/index.mjs",
7+
"types": "dist/index.d.ts",
8+
"scripts": {
9+
"build": "tsup index.ts --format cjs,esm --dts --minify",
10+
"lint": "tsc"
11+
},
12+
"dependencies": {
13+
"typescript": "^5.5.2"
14+
},
15+
"devDependencies": {
16+
"@changesets/cli": "^2.27.5",
17+
"tsup": "^8.1.0"
18+
}
19+
}

packages/typer-diff/tsconfig.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
4+
"module": "commonjs" /* Specify what module code is generated. */,
5+
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
6+
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
7+
"strict": true /* Enable all strict type-checking options. */,
8+
"skipLibCheck": true /* Skip type checking all .d.ts files. */,
9+
"noUncheckedIndexedAccess": true,
10+
"noEmit": true
11+
}
12+
}

0 commit comments

Comments
 (0)