Skip to content

Commit a40bcc1

Browse files
authored
Merge pull request #4669 from easyops-cn/steve/v3-playground-spell-check
fix(playground): support spell check
2 parents 0acbe9b + 944151b commit a40bcc1

File tree

5 files changed

+127
-14
lines changed

5 files changed

+127
-14
lines changed

packages/brick-playground/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
"dependencies": {
2626
"@next-core/doc-helpers": "^0.2.18",
2727
"@next-core/serve-helpers": "^1.2.5",
28+
"@next-shared/spell-check": "^0.1.1",
29+
"comlink": "^4.4.2",
2830
"compression": "^1.8.0",
2931
"express": "^4.21.2",
3032
"glob": "^8.1.0"

packages/brick-playground/src/index.ts

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,29 @@ import { register as registerJavaScript } from "@next-core/monaco-contributions/
1212
import { register as registerTypeScript } from "@next-core/monaco-contributions/typescript";
1313
import { register as registerYaml } from "@next-core/monaco-contributions/yaml";
1414
import { register as registerHtml } from "@next-core/monaco-contributions/html";
15+
import { getRemoteSpellCheckWorker } from "./spellCheckRemoteWorker.js";
1516

1617
registerJavaScript(monaco);
1718
registerTypeScript(monaco);
1819
registerYaml(monaco);
1920
registerHtml(monaco);
2021

2122
const GZIP_HASH_PREFIX = "#gzip,";
23+
const SPELL_CHECK = "spell_check";
24+
const KNOWN_WORDS = [
25+
"microapp",
26+
"minmax",
27+
"ctrl",
28+
"dagre",
29+
"rankdir",
30+
"ranksep",
31+
"nodesep",
32+
"topo",
33+
"plaintext",
34+
"debuggable",
35+
"async",
36+
"searchable",
37+
];
2238

2339
interface Example extends Sources {
2440
key: string;
@@ -145,19 +161,6 @@ async function main() {
145161
}
146162
}
147163

148-
function debounce(func: Function, timeout = 300) {
149-
let timer = -1;
150-
return (...args: unknown[]) => {
151-
if (timer !== -1) {
152-
clearTimeout(timer);
153-
}
154-
timer = setTimeout(() => {
155-
timer = -1;
156-
func(...args);
157-
}, timeout) as unknown as number;
158-
};
159-
}
160-
161164
if (mode !== "yaml") {
162165
updateMode();
163166
selectType.value = mode.toUpperCase();
@@ -242,12 +245,38 @@ async function main() {
242245
insertSpaces: true,
243246
automaticLayout: true,
244247
});
245-
editor.onDidChangeModelContent((e) => {
248+
249+
const debouncedSpellCheck = debounce(async () => {
250+
const worker = await getRemoteSpellCheckWorker();
251+
const { markers: spellCheckMarkers } = await worker.spellCheck({
252+
source: editor.getValue(),
253+
knownWords: KNOWN_WORDS,
254+
});
255+
monaco.editor.setModelMarkers(
256+
model,
257+
SPELL_CHECK,
258+
spellCheckMarkers.map(({ start, end, message, severity }) => {
259+
const startPos = model.getPositionAt(start);
260+
const endPos = model.getPositionAt(end);
261+
return {
262+
startLineNumber: startPos.lineNumber,
263+
startColumn: startPos.column,
264+
endLineNumber: endPos.lineNumber,
265+
endColumn: endPos.column,
266+
severity: monaco.MarkerSeverity[severity],
267+
message,
268+
};
269+
})
270+
);
271+
});
272+
273+
model.onDidChangeContent((e) => {
246274
sources[type] = editor.getValue();
247275
if (saveToLocalStorage && !e.isFlush) {
248276
localStorage.setItem(storageKey, sources[type]);
249277
}
250278
debouncedRender();
279+
debouncedSpellCheck();
251280
});
252281
}
253282

@@ -461,6 +490,19 @@ function decorateAltCode(code: string, mode: string, altMode: string): string {
461490
}${code}`;
462491
}
463492

493+
function debounce(func: Function, timeout = 300) {
494+
let timer = -1;
495+
return (...args: unknown[]) => {
496+
if (timer !== -1) {
497+
clearTimeout(timer);
498+
}
499+
timer = setTimeout(() => {
500+
timer = -1;
501+
func(...args);
502+
}, timeout) as unknown as number;
503+
};
504+
}
505+
464506
main().catch((error) => {
465507
// eslint-disable-next-line no-console
466508
console.error(error);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// istanbul ignore file
2+
import { expose } from "comlink";
3+
import {
4+
spellCheck,
5+
type SpellCheckRequest,
6+
type SpellCheckResponse,
7+
} from "@next-shared/spell-check";
8+
9+
class SpellCheckWorker {
10+
spellCheck(req: SpellCheckRequest): SpellCheckResponse {
11+
return spellCheck(req);
12+
}
13+
}
14+
15+
expose(SpellCheckWorker);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// istanbul ignore file
2+
import { wrap } from "comlink";
3+
import type {
4+
SpellCheckRequest,
5+
SpellCheckResponse,
6+
} from "@next-shared/spell-check";
7+
8+
export interface RemoteSpellCheckWorker {
9+
spellCheck(req: SpellCheckRequest): Promise<SpellCheckResponse>;
10+
}
11+
12+
let remoteWorkerPromise: Promise<RemoteSpellCheckWorker> | undefined;
13+
14+
let worker: Worker | undefined;
15+
16+
export function getRemoteSpellCheckWorker() {
17+
if (!remoteWorkerPromise) {
18+
remoteWorkerPromise = (async () => {
19+
const Remote = wrap<{ new (): RemoteSpellCheckWorker }>(getWorker());
20+
return await new Remote();
21+
})();
22+
}
23+
return remoteWorkerPromise;
24+
}
25+
26+
function getWorker() {
27+
if (!worker) {
28+
worker = new Worker(new URL("./spellCheck.worker.ts", import.meta.url));
29+
}
30+
return worker;
31+
}

yarn.lock

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,6 +2006,14 @@
20062006
resolved "https://registry.npmjs.org/@next-shared/common-bricks/-/common-bricks-0.53.1.tgz#442db871109bb2d1bea51a43def37fb6564f3ca0"
20072007
integrity sha512-zsxkavhza9CdojCsrzQIgSK430VQxDes/0LS8Z2PTjm15R7JDeHNxKjU7qEM0zSm79Yo9QcGxto5igkjYKeQVw==
20082008

2009+
"@next-shared/spell-check@^0.1.1":
2010+
version "0.1.1"
2011+
resolved "https://registry.npmjs.org/@next-shared/spell-check/-/spell-check-0.1.1.tgz#2dfe56aa6cd1c4479d96c4e49bdfbb6a52303fd5"
2012+
integrity sha512-mRoZoacobIT2hu67GvK6cYZQ5bhrVvjImhHLVtrT0Wje69ufRRW0lNme0FfMh7/1ObxIHMQ9OrPvV8+Tx3iMjQ==
2013+
dependencies:
2014+
change-case "^5.4.4"
2015+
typo-js "^1.2.5"
2016+
20092017
"@nicolo-ribaudo/[email protected]":
20102018
version "2.1.8-no-fsevents.3"
20112019
resolved "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz"
@@ -4448,6 +4456,11 @@ change-case@^4.1.2:
44484456
snake-case "^3.0.4"
44494457
tslib "^2.0.3"
44504458

4459+
change-case@^5.4.4:
4460+
version "5.4.4"
4461+
resolved "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz#0d52b507d8fb8f204343432381d1a6d7bff97a02"
4462+
integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==
4463+
44514464
char-regex@^1.0.2:
44524465
version "1.0.2"
44534466
resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz"
@@ -4718,6 +4731,11 @@ combined-stream@^1.0.8, combined-stream@~1.0.6:
47184731
dependencies:
47194732
delayed-stream "~1.0.0"
47204733

4734+
comlink@^4.4.2:
4735+
version "4.4.2"
4736+
resolved "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz#cbbcd82742fbebc06489c28a183eedc5c60a2bca"
4737+
integrity sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==
4738+
47214739
commander@^13.1.0:
47224740
version "13.1.0"
47234741
resolved "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz#776167db68c78f38dcce1f9b8d7b8b9a488abf46"
@@ -13300,6 +13318,11 @@ typescript@~5.5.0:
1330013318
resolved "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba"
1330113319
integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==
1330213320

13321+
typo-js@^1.2.5:
13322+
version "1.2.5"
13323+
resolved "https://registry.npmjs.org/typo-js/-/typo-js-1.2.5.tgz#0aa65e0be9b69036463a3827de8185b4144e3086"
13324+
integrity sha512-F45vFWdGX8xahIk/sOp79z2NJs8ETMYsmMChm9D5Hlx3+9j7VnCyQyvij5MOCrNY3NNe8noSyokRjQRfq+Bc7A==
13325+
1330313326
uglify-js@^3.1.4:
1330413327
version "3.4.9"
1330513328
resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz"

0 commit comments

Comments
 (0)