Skip to content

Commit 106cd63

Browse files
committed
fix(): use comlink to simplify worker usage
1 parent ce695dc commit 106cd63

File tree

6 files changed

+87
-93
lines changed

6 files changed

+87
-93
lines changed

bricks/vs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
"@next-core/theme": "^1.5.4",
6767
"@next-core/utils": "^1.7.32",
6868
"@next-shared/form": "^0.7.9",
69+
"comlink": "^4.4.2",
6970
"monaco-editor": "^0.50.0",
7071
"monaco-editor-webpack-plugin": "^7.1.0",
7172
"react": "0.0.0-experimental-ee8509801-20230117",

bricks/vs/src/code-editor/index.tsx

Lines changed: 59 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ import classNames from "classnames";
5252
import "./index.css";
5353
import { EmbeddedModelContext } from "./utils/embeddedModelState.js";
5454
import { PlaceholderContentWidget } from "./widget/Placeholder.js";
55-
import { getYamlLinterWorker } from "./workers/yamlLinter.js";
56-
import type { LintResponse } from "./workers/lintYaml.js";
55+
import { getRemoteYamlLinterWorker } from "./workers/yamlLinter.js";
5756
import { register as registerCel } from "./languages/cel.js";
5857
import { register as registerCelYaml } from "./languages/cel-yaml.js";
5958
import { register as registerCelStr } from "./languages/cel-str.js";
@@ -953,67 +952,65 @@ export function CodeEditorComponent({
953952
// istanbul ignore next
954953
useEffect(() => {
955954
const editor = editorRef.current;
956-
if (editor && language === "brick_next_yaml") {
957-
const yamlLinter = getYamlLinterWorker();
958-
const handleChange = (): void => {
959-
const value = editor.getValue();
960-
yamlLinter.postMessage({
961-
id: workerId,
962-
source: value,
963-
links,
964-
markers,
965-
});
966-
};
967-
const debounceChange = debounce(handleChange, 200);
968-
const handleLintResponse = (event: MessageEvent<LintResponse>): void => {
969-
const { id, lintMarkers, lintDecorations } = event.data;
970-
if (id !== workerId) {
971-
return;
972-
}
973-
const model = editor.getModel();
974-
if (!model) {
975-
return;
976-
}
977-
monaco.editor.setModelMarkers(
978-
model,
979-
"brick_next_yaml_lint",
980-
lintMarkers.map(({ start, end, message, severity, code }) => {
981-
const startPos = model.getPositionAt(start);
982-
const endPos = model.getPositionAt(end);
983-
return {
984-
startLineNumber: startPos.lineNumber,
985-
startColumn: startPos.column,
986-
endLineNumber: endPos.lineNumber,
987-
endColumn: endPos.column,
988-
severity: monaco.MarkerSeverity[severity],
989-
message,
990-
code: code as monaco.editor.IMarkerData["code"],
991-
};
992-
})
993-
);
994-
decorationsCollection.current?.set(
995-
lintDecorations.map(({ start, end, options }) => ({
996-
range: monaco.Range.fromPositions(
997-
model.getPositionAt(start),
998-
model.getPositionAt(end)
999-
),
1000-
options,
1001-
}))
1002-
);
1003-
};
1004-
yamlLinter.addEventListener("message", handleLintResponse);
1005-
const change = editor.onDidChangeModelContent(debounceChange);
1006-
debounceChange();
1007-
return () => {
1008-
change.dispose();
1009-
monaco.editor.setModelMarkers(
1010-
editor.getModel()!,
1011-
"brick_next_yaml_lint",
1012-
[]
1013-
);
1014-
yamlLinter.removeEventListener("message", handleLintResponse);
1015-
};
955+
if (!(editor && language === "brick_next_yaml")) {
956+
return;
1016957
}
958+
959+
let ignore = false;
960+
const handleChange = async () => {
961+
const worker = await getRemoteYamlLinterWorker();
962+
if (ignore) {
963+
return;
964+
}
965+
const { lintMarkers, lintDecorations } = await worker.lint({
966+
source: editor.getValue(),
967+
links,
968+
markers,
969+
});
970+
const model = editor.getModel();
971+
if (ignore || !model) {
972+
return;
973+
}
974+
monaco.editor.setModelMarkers(
975+
model,
976+
"brick_next_yaml_lint",
977+
lintMarkers.map(({ start, end, message, severity, code }) => {
978+
const startPos = model.getPositionAt(start);
979+
const endPos = model.getPositionAt(end);
980+
return {
981+
startLineNumber: startPos.lineNumber,
982+
startColumn: startPos.column,
983+
endLineNumber: endPos.lineNumber,
984+
endColumn: endPos.column,
985+
severity: monaco.MarkerSeverity[severity],
986+
message,
987+
code: code as monaco.editor.IMarkerData["code"],
988+
};
989+
})
990+
);
991+
decorationsCollection.current?.set(
992+
lintDecorations.map(({ start, end, options }) => ({
993+
range: monaco.Range.fromPositions(
994+
model.getPositionAt(start),
995+
model.getPositionAt(end)
996+
),
997+
options,
998+
}))
999+
);
1000+
};
1001+
const debounceChange = debounce(handleChange, 200);
1002+
const change = editor.onDidChangeModelContent(debounceChange);
1003+
debounceChange();
1004+
1005+
return () => {
1006+
ignore = true;
1007+
change.dispose();
1008+
monaco.editor.setModelMarkers(
1009+
editor.getModel()!,
1010+
"brick_next_yaml_lint",
1011+
[]
1012+
);
1013+
};
10171014
}, [language, links, markers, theme, workerId]);
10181015

10191016
return (

bricks/vs/src/code-editor/workers/lintYaml.spec.ts

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,39 @@ import { lintYaml } from "./lintYaml";
44
describe("lintYaml", () => {
55
test("plain with no expressions", async () => {
66
const result = await lintYaml({
7-
id: "1",
87
source: "a",
98
});
109
expect(result).toEqual({
11-
id: "1",
1210
lintMarkers: [],
1311
lintDecorations: [],
1412
});
1513
});
1614

1715
test("plain with not string value", async () => {
1816
const result = await lintYaml({
19-
id: "1",
2017
source: "1",
2118
});
2219
expect(result).toEqual({
23-
id: "1",
2420
lintMarkers: [],
2521
lintDecorations: [],
2622
});
2723
});
2824

2925
test("plain with correct expression", async () => {
3026
const result = await lintYaml({
31-
id: "1",
3227
source: "<% a %>",
3328
});
3429
expect(result).toEqual({
35-
id: "1",
3630
lintMarkers: [],
3731
lintDecorations: [],
3832
});
3933
});
4034

4135
test("plain with incorrect expression", async () => {
4236
const result = await lintYaml({
43-
id: "1",
4437
source: "<% a. %>",
4538
});
4639
expect(result).toEqual({
47-
id: "1",
4840
lintMarkers: [
4941
{
5042
start: 5,
@@ -59,12 +51,10 @@ describe("lintYaml", () => {
5951

6052
test("block with CTX of links", async () => {
6153
const result = await lintYaml({
62-
id: "1",
6354
source: "|\n <%\n STATE.b,\n CTX.abc\n %>\n",
6455
links: ["CTX"],
6556
});
6657
expect(result).toEqual({
67-
id: "1",
6858
lintMarkers: [],
6959
lintDecorations: [
7060
{
@@ -80,7 +70,6 @@ describe("lintYaml", () => {
8070

8171
test("block with STATE of markers", async () => {
8272
const result = await lintYaml({
83-
id: "1",
8473
source: "|-\n <%\n STATE.b,\n CTX.abc\n %>\n",
8574
markers: [
8675
{
@@ -91,7 +80,6 @@ describe("lintYaml", () => {
9180
],
9281
});
9382
expect(result).toEqual({
94-
id: "1",
9583
lintMarkers: [
9684
{
9785
start: 12,
@@ -106,7 +94,6 @@ describe("lintYaml", () => {
10694

10795
test("single-quote with non-expressions", async () => {
10896
const result = await lintYaml({
109-
id: "1",
11097
source: "'CTX.a'",
11198
links: ["CTX"],
11299
markers: [
@@ -118,15 +105,13 @@ describe("lintYaml", () => {
118105
],
119106
});
120107
expect(result).toEqual({
121-
id: "1",
122108
lintMarkers: [],
123109
lintDecorations: [],
124110
});
125111
});
126112

127113
test("single-quote with CTX", async () => {
128114
const result = await lintYaml({
129-
id: "1",
130115
source: "'<% CTX(), CTX.b, STATE.c %>'",
131116
links: ["CTX"],
132117
markers: [
@@ -138,7 +123,6 @@ describe("lintYaml", () => {
138123
],
139124
});
140125
expect(result).toEqual({
141-
id: "1",
142126
lintMarkers: [
143127
{
144128
start: 18,
@@ -161,12 +145,10 @@ describe("lintYaml", () => {
161145

162146
test("single-quote incorrect expression", async () => {
163147
const result = await lintYaml({
164-
id: "1",
165148
source: "'<% CTX[''a''], CTX'' %>'",
166149
links: ["CTX"],
167150
});
168151
expect(result).toEqual({
169-
id: "1",
170152
lintMarkers: [
171153
{
172154
start: 19,
@@ -181,12 +163,10 @@ describe("lintYaml", () => {
181163

182164
test("double-quote with CTX", async () => {
183165
const result = await lintYaml({
184-
id: "1",
185166
source: '"<% CTX[\\"a\\"], CTX.b, CTX[\\"c\\"] %>"',
186167
links: ["CTX"],
187168
});
188169
expect(result).toEqual({
189-
id: "1",
190170
lintMarkers: [],
191171
lintDecorations: [
192172
{
@@ -202,12 +182,10 @@ describe("lintYaml", () => {
202182

203183
test("double-quote incorrect expression", async () => {
204184
const result = await lintYaml({
205-
id: "1",
206185
source: '"<% CTX[\\"a\\"], CTX) %>"',
207186
links: ["CTX"],
208187
});
209188
expect(result).toEqual({
210-
id: "1",
211189
lintMarkers: [
212190
{
213191
start: 19,

bricks/vs/src/code-editor/workers/lintYaml.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ import type * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
55
import type { Marker } from "..";
66

77
export interface LintRequest {
8-
id: string;
98
source: string;
109
links?: string[];
1110
markers?: Marker[];
1211
}
1312

1413
export interface LintResponse {
15-
id: string;
1614
lintMarkers: LintMarker[];
1715
lintDecorations: LintDecoration[];
1816
}
@@ -57,7 +55,6 @@ const LEVEL_TO_SEVERITY_NAME = {
5755
} as const;
5856

5957
export async function lintYaml({
60-
id,
6158
source,
6259
links,
6360
markers,
@@ -279,7 +276,6 @@ export async function lintYaml({
279276
}
280277

281278
return {
282-
id,
283279
lintMarkers,
284280
lintDecorations,
285281
};

bricks/vs/src/code-editor/workers/yamlLinter.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
// istanbul ignore file
2+
import { wrap } from "comlink";
3+
import type { LintRequest, LintResponse } from "./lintYaml";
4+
5+
export interface RemoteYamlLinterWorker {
6+
lint(req: LintRequest): Promise<LintResponse>;
7+
}
8+
9+
let remoteWorkerPromise: Promise<RemoteYamlLinterWorker> | undefined;
210

311
let worker: Worker | undefined;
412

5-
export function getYamlLinterWorker() {
13+
export function getRemoteYamlLinterWorker() {
14+
if (!remoteWorkerPromise) {
15+
remoteWorkerPromise = (async () => {
16+
const Remote = wrap<{ new (): RemoteYamlLinterWorker }>(getWorker());
17+
return await new Remote();
18+
})();
19+
}
20+
return remoteWorkerPromise;
21+
}
22+
23+
export function getWorker() {
624
if (!worker) {
725
worker = new Worker(new URL("./yamlLinter.worker.ts", import.meta.url));
826
}
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
// istanbul ignore file
2+
import { expose } from "comlink";
13
import { lintYaml, type LintRequest } from "./lintYaml";
24

3-
self.addEventListener("message", async (event: MessageEvent<LintRequest>) => {
4-
const response = await lintYaml(event.data);
5+
class YamlLinterWorker {
6+
lint(req: LintRequest) {
7+
return lintYaml(req);
8+
}
9+
}
510

6-
self.postMessage(response);
7-
});
11+
expose(YamlLinterWorker);

0 commit comments

Comments
 (0)