@opentuah/core 0.1.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/3d/SpriteResourceManager.d.ts +74 -0
- package/3d/SpriteUtils.d.ts +13 -0
- package/3d/TextureUtils.d.ts +24 -0
- package/3d/ThreeRenderable.d.ts +40 -0
- package/3d/WGPURenderer.d.ts +61 -0
- package/3d/animation/ExplodingSpriteEffect.d.ts +71 -0
- package/3d/animation/PhysicsExplodingSpriteEffect.d.ts +76 -0
- package/3d/animation/SpriteAnimator.d.ts +124 -0
- package/3d/animation/SpriteParticleGenerator.d.ts +62 -0
- package/3d/canvas.d.ts +44 -0
- package/3d/index.d.ts +12 -0
- package/3d/physics/PlanckPhysicsAdapter.d.ts +19 -0
- package/3d/physics/RapierPhysicsAdapter.d.ts +19 -0
- package/3d/physics/physics-interface.d.ts +27 -0
- package/3d.d.ts +2 -0
- package/3d.js +2805 -0
- package/3d.js.map +22 -0
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/Renderable.d.ts +334 -0
- package/animation/Timeline.d.ts +126 -0
- package/ansi.d.ts +13 -0
- package/assets/javascript/highlights.scm +205 -0
- package/assets/javascript/tree-sitter-javascript.wasm +0 -0
- package/assets/markdown/highlights.scm +150 -0
- package/assets/markdown/injections.scm +27 -0
- package/assets/markdown/tree-sitter-markdown.wasm +0 -0
- package/assets/markdown_inline/highlights.scm +115 -0
- package/assets/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
- package/assets/typescript/highlights.scm +604 -0
- package/assets/typescript/tree-sitter-typescript.wasm +0 -0
- package/assets/zig/highlights.scm +284 -0
- package/assets/zig/tree-sitter-zig.wasm +0 -0
- package/buffer.d.ts +98 -0
- package/console.d.ts +140 -0
- package/edit-buffer.d.ts +98 -0
- package/editor-view.d.ts +73 -0
- package/index-cgvb25mm.js +14921 -0
- package/index-cgvb25mm.js.map +56 -0
- package/index.d.ts +17 -0
- package/index.js +9331 -0
- package/index.js.map +37 -0
- package/lib/KeyHandler.d.ts +61 -0
- package/lib/RGBA.d.ts +27 -0
- package/lib/ascii.font.d.ts +508 -0
- package/lib/border.d.ts +49 -0
- package/lib/bunfs.d.ts +7 -0
- package/lib/clipboard.d.ts +17 -0
- package/lib/data-paths.d.ts +26 -0
- package/lib/debounce.d.ts +42 -0
- package/lib/env.d.ts +42 -0
- package/lib/extmarks-history.d.ts +17 -0
- package/lib/extmarks.d.ts +89 -0
- package/lib/hast-styled-text.d.ts +17 -0
- package/lib/index.d.ts +18 -0
- package/lib/keymapping.d.ts +25 -0
- package/lib/objects-in-viewport.d.ts +24 -0
- package/lib/output.capture.d.ts +24 -0
- package/lib/parse.keypress-kitty.d.ts +2 -0
- package/lib/parse.keypress.d.ts +26 -0
- package/lib/parse.mouse.d.ts +23 -0
- package/lib/queue.d.ts +15 -0
- package/lib/renderable.validations.d.ts +12 -0
- package/lib/scroll-acceleration.d.ts +43 -0
- package/lib/selection.d.ts +63 -0
- package/lib/singleton.d.ts +7 -0
- package/lib/stdin-buffer.d.ts +44 -0
- package/lib/styled-text.d.ts +63 -0
- package/lib/terminal-capability-detection.d.ts +30 -0
- package/lib/terminal-palette.d.ts +43 -0
- package/lib/tree-sitter/assets/update.d.ts +11 -0
- package/lib/tree-sitter/client.d.ts +47 -0
- package/lib/tree-sitter/default-parsers.d.ts +2 -0
- package/lib/tree-sitter/download-utils.d.ts +21 -0
- package/lib/tree-sitter/index.d.ts +8 -0
- package/lib/tree-sitter/parser.worker.d.ts +1 -0
- package/lib/tree-sitter/parsers-config.d.ts +38 -0
- package/lib/tree-sitter/resolve-ft.d.ts +2 -0
- package/lib/tree-sitter/types.d.ts +81 -0
- package/lib/tree-sitter-styled-text.d.ts +14 -0
- package/lib/validate-dir-name.d.ts +1 -0
- package/lib/yoga.options.d.ts +32 -0
- package/package.json +67 -0
- package/parser.worker.js +855 -0
- package/parser.worker.js.map +12 -0
- package/post/filters.d.ts +105 -0
- package/renderables/ASCIIFont.d.ts +52 -0
- package/renderables/Box.d.ts +72 -0
- package/renderables/Code.d.ts +66 -0
- package/renderables/Diff.d.ts +185 -0
- package/renderables/EditBufferRenderable.d.ts +162 -0
- package/renderables/FrameBuffer.d.ts +16 -0
- package/renderables/Input.d.ts +60 -0
- package/renderables/LineNumberRenderable.d.ts +111 -0
- package/renderables/Markdown.d.ts +98 -0
- package/renderables/ScrollBar.d.ts +77 -0
- package/renderables/ScrollBox.d.ts +116 -0
- package/renderables/Select.d.ts +115 -0
- package/renderables/Slider.d.ts +44 -0
- package/renderables/TabSelect.d.ts +96 -0
- package/renderables/Text.d.ts +36 -0
- package/renderables/TextBufferRenderable.d.ts +103 -0
- package/renderables/TextNode.d.ts +91 -0
- package/renderables/Textarea.d.ts +114 -0
- package/renderables/__tests__/renderable-test-utils.d.ts +7 -0
- package/renderables/composition/VRenderable.d.ts +16 -0
- package/renderables/composition/constructs.d.ts +35 -0
- package/renderables/composition/vnode.d.ts +46 -0
- package/renderables/index.d.ts +20 -0
- package/renderables/markdown-parser.d.ts +10 -0
- package/renderer.d.ts +370 -0
- package/syntax-style.d.ts +54 -0
- package/testing/mock-keys.d.ts +80 -0
- package/testing/mock-mouse.d.ts +38 -0
- package/testing/mock-tree-sitter-client.d.ts +23 -0
- package/testing/spy.d.ts +7 -0
- package/testing/test-recorder.d.ts +61 -0
- package/testing/test-renderer.d.ts +23 -0
- package/testing.d.ts +6 -0
- package/testing.js +670 -0
- package/testing.js.map +15 -0
- package/text-buffer-view.d.ts +42 -0
- package/text-buffer.d.ts +67 -0
- package/types.d.ts +120 -0
- package/utils.d.ts +14 -0
- package/zig-structs.d.ts +42 -0
- package/zig.d.ts +326 -0
package/parser.worker.js
ADDED
|
@@ -0,0 +1,855 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// src/lib/tree-sitter/parser.worker.ts
|
|
5
|
+
import { Parser, Query, Language } from "web-tree-sitter";
|
|
6
|
+
import { mkdir as mkdir2 } from "fs/promises";
|
|
7
|
+
import * as path2 from "path";
|
|
8
|
+
|
|
9
|
+
// src/lib/tree-sitter/download-utils.ts
|
|
10
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
11
|
+
import * as path from "path";
|
|
12
|
+
|
|
13
|
+
class DownloadUtils {
|
|
14
|
+
static hashUrl(url) {
|
|
15
|
+
let hash = 0;
|
|
16
|
+
for (let i = 0;i < url.length; i++) {
|
|
17
|
+
const char = url.charCodeAt(i);
|
|
18
|
+
hash = (hash << 5) - hash + char;
|
|
19
|
+
hash = hash & hash;
|
|
20
|
+
}
|
|
21
|
+
return Math.abs(hash).toString(16);
|
|
22
|
+
}
|
|
23
|
+
static async downloadOrLoad(source, cacheDir, cacheSubdir, fileExtension, useHashForCache = true, filetype) {
|
|
24
|
+
const isUrl = source.startsWith("http://") || source.startsWith("https://");
|
|
25
|
+
if (isUrl) {
|
|
26
|
+
let cacheFileName;
|
|
27
|
+
if (useHashForCache) {
|
|
28
|
+
const hash = this.hashUrl(source);
|
|
29
|
+
cacheFileName = filetype ? `${filetype}-${hash}${fileExtension}` : `${hash}${fileExtension}`;
|
|
30
|
+
} else {
|
|
31
|
+
cacheFileName = path.basename(source);
|
|
32
|
+
}
|
|
33
|
+
const cacheFile = path.join(cacheDir, cacheSubdir, cacheFileName);
|
|
34
|
+
await mkdir(path.dirname(cacheFile), { recursive: true });
|
|
35
|
+
try {
|
|
36
|
+
const cachedContent = await Bun.file(cacheFile).arrayBuffer();
|
|
37
|
+
if (cachedContent.byteLength > 0) {
|
|
38
|
+
return { content: cachedContent, filePath: cacheFile };
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {}
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(source);
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
return { error: `Failed to fetch from ${source}: ${response.statusText}` };
|
|
45
|
+
}
|
|
46
|
+
const content = await response.arrayBuffer();
|
|
47
|
+
try {
|
|
48
|
+
await writeFile(cacheFile, Buffer.from(content));
|
|
49
|
+
} catch (cacheError) {
|
|
50
|
+
console.warn(`Failed to cache: ${cacheError}`);
|
|
51
|
+
}
|
|
52
|
+
return { content, filePath: cacheFile };
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return { error: `Error downloading from ${source}: ${error}` };
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
try {
|
|
58
|
+
const content = await Bun.file(source).arrayBuffer();
|
|
59
|
+
return { content, filePath: source };
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return { error: `Error loading from local path ${source}: ${error}` };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
static async downloadToPath(source, targetPath) {
|
|
66
|
+
const isUrl = source.startsWith("http://") || source.startsWith("https://");
|
|
67
|
+
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
68
|
+
if (isUrl) {
|
|
69
|
+
try {
|
|
70
|
+
const response = await fetch(source);
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
return { error: `Failed to fetch from ${source}: ${response.statusText}` };
|
|
73
|
+
}
|
|
74
|
+
const content = await response.arrayBuffer();
|
|
75
|
+
await writeFile(targetPath, Buffer.from(content));
|
|
76
|
+
return { content, filePath: targetPath };
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return { error: `Error downloading from ${source}: ${error}` };
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
try {
|
|
82
|
+
const content = await Bun.file(source).arrayBuffer();
|
|
83
|
+
await writeFile(targetPath, Buffer.from(content));
|
|
84
|
+
return { content, filePath: targetPath };
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return { error: `Error copying from local path ${source}: ${error}` };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
static async fetchHighlightQueries(sources, cacheDir, filetype) {
|
|
91
|
+
const queryPromises = sources.map((source) => this.fetchHighlightQuery(source, cacheDir, filetype));
|
|
92
|
+
const queryResults = await Promise.all(queryPromises);
|
|
93
|
+
const validQueries = queryResults.filter((query) => query.trim().length > 0);
|
|
94
|
+
return validQueries.join(`
|
|
95
|
+
`);
|
|
96
|
+
}
|
|
97
|
+
static async fetchHighlightQuery(source, cacheDir, filetype) {
|
|
98
|
+
const result = await this.downloadOrLoad(source, cacheDir, "queries", ".scm", true, filetype);
|
|
99
|
+
if (result.error) {
|
|
100
|
+
console.error(`Error fetching highlight query from ${source}:`, result.error);
|
|
101
|
+
return "";
|
|
102
|
+
}
|
|
103
|
+
if (result.content) {
|
|
104
|
+
return new TextDecoder().decode(result.content);
|
|
105
|
+
}
|
|
106
|
+
return "";
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/lib/tree-sitter/parser.worker.ts
|
|
111
|
+
import { isMainThread } from "worker_threads";
|
|
112
|
+
|
|
113
|
+
// src/lib/bunfs.ts
|
|
114
|
+
import { basename as basename2, join as join2 } from "path";
|
|
115
|
+
function isBunfsPath(path2) {
|
|
116
|
+
return path2.includes("$bunfs") || /^B:[\\/]~BUN/i.test(path2);
|
|
117
|
+
}
|
|
118
|
+
function getBunfsRootPath() {
|
|
119
|
+
return process.platform === "win32" ? "B:\\~BUN\\root" : "/$bunfs/root";
|
|
120
|
+
}
|
|
121
|
+
function normalizeBunfsPath(fileName) {
|
|
122
|
+
return join2(getBunfsRootPath(), basename2(fileName));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/lib/tree-sitter/parser.worker.ts
|
|
126
|
+
var self = globalThis;
|
|
127
|
+
|
|
128
|
+
class ParserWorker {
|
|
129
|
+
bufferParsers = new Map;
|
|
130
|
+
filetypeParserOptions = new Map;
|
|
131
|
+
filetypeParsers = new Map;
|
|
132
|
+
filetypeParserPromises = new Map;
|
|
133
|
+
reusableParsers = new Map;
|
|
134
|
+
reusableParserPromises = new Map;
|
|
135
|
+
initializePromise;
|
|
136
|
+
performance;
|
|
137
|
+
dataPath;
|
|
138
|
+
tsDataPath;
|
|
139
|
+
initialized = false;
|
|
140
|
+
constructor() {
|
|
141
|
+
this.performance = {
|
|
142
|
+
averageParseTime: 0,
|
|
143
|
+
parseTimes: [],
|
|
144
|
+
averageQueryTime: 0,
|
|
145
|
+
queryTimes: []
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
async fetchQueries(sources, filetype) {
|
|
149
|
+
if (!this.tsDataPath) {
|
|
150
|
+
return "";
|
|
151
|
+
}
|
|
152
|
+
return DownloadUtils.fetchHighlightQueries(sources, this.tsDataPath, filetype);
|
|
153
|
+
}
|
|
154
|
+
async initialize({ dataPath }) {
|
|
155
|
+
if (this.initializePromise) {
|
|
156
|
+
return this.initializePromise;
|
|
157
|
+
}
|
|
158
|
+
this.initializePromise = new Promise(async (resolve, reject) => {
|
|
159
|
+
this.dataPath = dataPath;
|
|
160
|
+
this.tsDataPath = path2.join(dataPath, "tree-sitter");
|
|
161
|
+
try {
|
|
162
|
+
await mkdir2(path2.join(this.tsDataPath, "languages"), { recursive: true });
|
|
163
|
+
await mkdir2(path2.join(this.tsDataPath, "queries"), { recursive: true });
|
|
164
|
+
let { default: treeWasm } = await import("web-tree-sitter/tree-sitter.wasm", {
|
|
165
|
+
with: { type: "wasm" }
|
|
166
|
+
});
|
|
167
|
+
if (isBunfsPath(treeWasm)) {
|
|
168
|
+
treeWasm = normalizeBunfsPath(path2.parse(treeWasm).base);
|
|
169
|
+
}
|
|
170
|
+
await Parser.init({
|
|
171
|
+
locateFile() {
|
|
172
|
+
return treeWasm;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
this.initialized = true;
|
|
176
|
+
resolve();
|
|
177
|
+
} catch (error) {
|
|
178
|
+
reject(error);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
return this.initializePromise;
|
|
182
|
+
}
|
|
183
|
+
addFiletypeParser(filetypeParser) {
|
|
184
|
+
this.filetypeParserOptions.set(filetypeParser.filetype, filetypeParser);
|
|
185
|
+
}
|
|
186
|
+
async createQueries(filetypeParser, language) {
|
|
187
|
+
try {
|
|
188
|
+
const highlightQueryContent = await this.fetchQueries(filetypeParser.queries.highlights, filetypeParser.filetype);
|
|
189
|
+
if (!highlightQueryContent) {
|
|
190
|
+
console.error("Failed to fetch highlight queries for:", filetypeParser.filetype);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const highlightsQuery = new Query(language, highlightQueryContent);
|
|
194
|
+
const result = {
|
|
195
|
+
highlights: highlightsQuery
|
|
196
|
+
};
|
|
197
|
+
if (filetypeParser.queries.injections && filetypeParser.queries.injections.length > 0) {
|
|
198
|
+
const injectionQueryContent = await this.fetchQueries(filetypeParser.queries.injections, filetypeParser.filetype);
|
|
199
|
+
if (injectionQueryContent) {
|
|
200
|
+
result.injections = new Query(language, injectionQueryContent);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return result;
|
|
204
|
+
} catch (error) {
|
|
205
|
+
console.error("Error creating queries for", filetypeParser.filetype, filetypeParser.queries);
|
|
206
|
+
console.error(error);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async loadLanguage(languageSource) {
|
|
211
|
+
if (!this.initialized || !this.tsDataPath) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const result = await DownloadUtils.downloadOrLoad(languageSource, this.tsDataPath, "languages", ".wasm", false);
|
|
215
|
+
if (result.error) {
|
|
216
|
+
console.error(`Error loading language ${languageSource}:`, result.error);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (!result.filePath) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const normalizedPath = result.filePath.replaceAll("\\", "/");
|
|
223
|
+
try {
|
|
224
|
+
const language = await Language.load(normalizedPath);
|
|
225
|
+
return language;
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.error(`Error loading language from ${normalizedPath}:`, error);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async resolveFiletypeParser(filetype) {
|
|
232
|
+
if (this.filetypeParsers.has(filetype)) {
|
|
233
|
+
return this.filetypeParsers.get(filetype);
|
|
234
|
+
}
|
|
235
|
+
if (this.filetypeParserPromises.has(filetype)) {
|
|
236
|
+
return this.filetypeParserPromises.get(filetype);
|
|
237
|
+
}
|
|
238
|
+
const loadingPromise = this.loadFiletypeParser(filetype);
|
|
239
|
+
this.filetypeParserPromises.set(filetype, loadingPromise);
|
|
240
|
+
try {
|
|
241
|
+
const result = await loadingPromise;
|
|
242
|
+
if (result) {
|
|
243
|
+
this.filetypeParsers.set(filetype, result);
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
} finally {
|
|
247
|
+
this.filetypeParserPromises.delete(filetype);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async loadFiletypeParser(filetype) {
|
|
251
|
+
const filetypeParserOptions = this.filetypeParserOptions.get(filetype);
|
|
252
|
+
if (!filetypeParserOptions) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const language = await this.loadLanguage(filetypeParserOptions.wasm);
|
|
256
|
+
if (!language) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const queries = await this.createQueries(filetypeParserOptions, language);
|
|
260
|
+
if (!queries) {
|
|
261
|
+
console.error("Failed to create queries for:", filetype);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const filetypeParser = {
|
|
265
|
+
...filetypeParserOptions,
|
|
266
|
+
queries,
|
|
267
|
+
language
|
|
268
|
+
};
|
|
269
|
+
return filetypeParser;
|
|
270
|
+
}
|
|
271
|
+
async preloadParser(filetype) {
|
|
272
|
+
return this.resolveFiletypeParser(filetype);
|
|
273
|
+
}
|
|
274
|
+
async getReusableParser(filetype) {
|
|
275
|
+
if (this.reusableParsers.has(filetype)) {
|
|
276
|
+
return this.reusableParsers.get(filetype);
|
|
277
|
+
}
|
|
278
|
+
if (this.reusableParserPromises.has(filetype)) {
|
|
279
|
+
return this.reusableParserPromises.get(filetype);
|
|
280
|
+
}
|
|
281
|
+
const creationPromise = this.createReusableParser(filetype);
|
|
282
|
+
this.reusableParserPromises.set(filetype, creationPromise);
|
|
283
|
+
try {
|
|
284
|
+
const result = await creationPromise;
|
|
285
|
+
if (result) {
|
|
286
|
+
this.reusableParsers.set(filetype, result);
|
|
287
|
+
}
|
|
288
|
+
return result;
|
|
289
|
+
} finally {
|
|
290
|
+
this.reusableParserPromises.delete(filetype);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
async createReusableParser(filetype) {
|
|
294
|
+
const filetypeParser = await this.resolveFiletypeParser(filetype);
|
|
295
|
+
if (!filetypeParser) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
const parser = new Parser;
|
|
299
|
+
parser.setLanguage(filetypeParser.language);
|
|
300
|
+
const reusableState = {
|
|
301
|
+
parser,
|
|
302
|
+
filetypeParser,
|
|
303
|
+
queries: filetypeParser.queries
|
|
304
|
+
};
|
|
305
|
+
return reusableState;
|
|
306
|
+
}
|
|
307
|
+
async handleInitializeParser(bufferId, version, content, filetype, messageId) {
|
|
308
|
+
const filetypeParser = await this.resolveFiletypeParser(filetype);
|
|
309
|
+
if (!filetypeParser) {
|
|
310
|
+
self.postMessage({
|
|
311
|
+
type: "PARSER_INIT_RESPONSE",
|
|
312
|
+
bufferId,
|
|
313
|
+
messageId,
|
|
314
|
+
hasParser: false,
|
|
315
|
+
warning: `No parser available for filetype ${filetype}`
|
|
316
|
+
});
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
const parser = new Parser;
|
|
320
|
+
parser.setLanguage(filetypeParser.language);
|
|
321
|
+
const tree = parser.parse(content);
|
|
322
|
+
if (!tree) {
|
|
323
|
+
self.postMessage({
|
|
324
|
+
type: "PARSER_INIT_RESPONSE",
|
|
325
|
+
bufferId,
|
|
326
|
+
messageId,
|
|
327
|
+
hasParser: false,
|
|
328
|
+
error: "Failed to parse buffer"
|
|
329
|
+
});
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const parserState = {
|
|
333
|
+
parser,
|
|
334
|
+
tree,
|
|
335
|
+
queries: filetypeParser.queries,
|
|
336
|
+
filetype,
|
|
337
|
+
content,
|
|
338
|
+
injectionMapping: filetypeParser.injectionMapping
|
|
339
|
+
};
|
|
340
|
+
this.bufferParsers.set(bufferId, parserState);
|
|
341
|
+
self.postMessage({
|
|
342
|
+
type: "PARSER_INIT_RESPONSE",
|
|
343
|
+
bufferId,
|
|
344
|
+
messageId,
|
|
345
|
+
hasParser: true
|
|
346
|
+
});
|
|
347
|
+
const highlights = await this.initialQuery(parserState);
|
|
348
|
+
self.postMessage({
|
|
349
|
+
type: "HIGHLIGHT_RESPONSE",
|
|
350
|
+
bufferId,
|
|
351
|
+
version,
|
|
352
|
+
...highlights
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
async initialQuery(parserState) {
|
|
356
|
+
const query = parserState.queries.highlights;
|
|
357
|
+
const matches = query.captures(parserState.tree.rootNode);
|
|
358
|
+
let injectionRanges = new Map;
|
|
359
|
+
if (parserState.queries.injections) {
|
|
360
|
+
const injectionResult = await this.processInjections(parserState);
|
|
361
|
+
matches.push(...injectionResult.captures);
|
|
362
|
+
injectionRanges = injectionResult.injectionRanges;
|
|
363
|
+
}
|
|
364
|
+
return this.getHighlights(parserState, matches, injectionRanges);
|
|
365
|
+
}
|
|
366
|
+
getNodeText(node, content) {
|
|
367
|
+
return content.substring(node.startIndex, node.endIndex);
|
|
368
|
+
}
|
|
369
|
+
async processInjections(parserState) {
|
|
370
|
+
const injectionMatches = [];
|
|
371
|
+
const injectionRanges = new Map;
|
|
372
|
+
if (!parserState.queries.injections) {
|
|
373
|
+
return { captures: injectionMatches, injectionRanges };
|
|
374
|
+
}
|
|
375
|
+
const content = parserState.content;
|
|
376
|
+
const injectionCaptures = parserState.queries.injections.captures(parserState.tree.rootNode);
|
|
377
|
+
const languageGroups = new Map;
|
|
378
|
+
const injectionMapping = parserState.injectionMapping;
|
|
379
|
+
for (const capture of injectionCaptures) {
|
|
380
|
+
const captureName = capture.name;
|
|
381
|
+
if (captureName === "injection.content" || captureName.includes("injection")) {
|
|
382
|
+
const nodeType = capture.node.type;
|
|
383
|
+
let targetLanguage;
|
|
384
|
+
if (injectionMapping?.nodeTypes && injectionMapping.nodeTypes[nodeType]) {
|
|
385
|
+
targetLanguage = injectionMapping.nodeTypes[nodeType];
|
|
386
|
+
} else if (nodeType === "code_fence_content") {
|
|
387
|
+
const parent = capture.node.parent;
|
|
388
|
+
if (parent) {
|
|
389
|
+
const infoString = parent.children.find((child) => child.type === "info_string");
|
|
390
|
+
if (infoString) {
|
|
391
|
+
const languageNode = infoString.children.find((child) => child.type === "language");
|
|
392
|
+
if (languageNode) {
|
|
393
|
+
const languageName = this.getNodeText(languageNode, content);
|
|
394
|
+
if (injectionMapping?.infoStringMap && injectionMapping.infoStringMap[languageName]) {
|
|
395
|
+
targetLanguage = injectionMapping.infoStringMap[languageName];
|
|
396
|
+
} else {
|
|
397
|
+
targetLanguage = languageName;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (targetLanguage) {
|
|
404
|
+
if (!languageGroups.has(targetLanguage)) {
|
|
405
|
+
languageGroups.set(targetLanguage, []);
|
|
406
|
+
}
|
|
407
|
+
languageGroups.get(targetLanguage).push({ node: capture.node, name: capture.name });
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
for (const [language, captures] of languageGroups.entries()) {
|
|
412
|
+
const injectedParser = await this.getReusableParser(language);
|
|
413
|
+
if (!injectedParser) {
|
|
414
|
+
console.warn(`No parser found for injection language: ${language}`);
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
if (!injectionRanges.has(language)) {
|
|
418
|
+
injectionRanges.set(language, []);
|
|
419
|
+
}
|
|
420
|
+
const parser = injectedParser.parser;
|
|
421
|
+
for (const { node: injectionNode } of captures) {
|
|
422
|
+
try {
|
|
423
|
+
injectionRanges.get(language).push({
|
|
424
|
+
start: injectionNode.startIndex,
|
|
425
|
+
end: injectionNode.endIndex
|
|
426
|
+
});
|
|
427
|
+
const injectionContent = this.getNodeText(injectionNode, content);
|
|
428
|
+
const tree = parser.parse(injectionContent);
|
|
429
|
+
if (tree) {
|
|
430
|
+
const matches = injectedParser.queries.highlights.captures(tree.rootNode);
|
|
431
|
+
for (const match of matches) {
|
|
432
|
+
const offsetCapture = {
|
|
433
|
+
name: match.name,
|
|
434
|
+
patternIndex: match.patternIndex,
|
|
435
|
+
_injectedQuery: injectedParser.queries.highlights,
|
|
436
|
+
node: {
|
|
437
|
+
...match.node,
|
|
438
|
+
startPosition: {
|
|
439
|
+
row: match.node.startPosition.row + injectionNode.startPosition.row,
|
|
440
|
+
column: match.node.startPosition.row === 0 ? match.node.startPosition.column + injectionNode.startPosition.column : match.node.startPosition.column
|
|
441
|
+
},
|
|
442
|
+
endPosition: {
|
|
443
|
+
row: match.node.endPosition.row + injectionNode.startPosition.row,
|
|
444
|
+
column: match.node.endPosition.row === 0 ? match.node.endPosition.column + injectionNode.startPosition.column : match.node.endPosition.column
|
|
445
|
+
},
|
|
446
|
+
startIndex: match.node.startIndex + injectionNode.startIndex,
|
|
447
|
+
endIndex: match.node.endIndex + injectionNode.startIndex
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
injectionMatches.push(offsetCapture);
|
|
451
|
+
}
|
|
452
|
+
tree.delete();
|
|
453
|
+
}
|
|
454
|
+
} catch (error) {
|
|
455
|
+
console.error(`Error processing injection for language ${language}:`, error);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return { captures: injectionMatches, injectionRanges };
|
|
460
|
+
}
|
|
461
|
+
editToRange(edit) {
|
|
462
|
+
return {
|
|
463
|
+
startPosition: {
|
|
464
|
+
column: edit.startPosition.column,
|
|
465
|
+
row: edit.startPosition.row
|
|
466
|
+
},
|
|
467
|
+
endPosition: {
|
|
468
|
+
column: edit.newEndPosition.column,
|
|
469
|
+
row: edit.newEndPosition.row
|
|
470
|
+
},
|
|
471
|
+
startIndex: edit.startIndex,
|
|
472
|
+
endIndex: edit.newEndIndex
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
async handleEdits(bufferId, content, edits) {
|
|
476
|
+
const parserState = this.bufferParsers.get(bufferId);
|
|
477
|
+
if (!parserState) {
|
|
478
|
+
return { warning: "No parser state found for buffer" };
|
|
479
|
+
}
|
|
480
|
+
parserState.content = content;
|
|
481
|
+
for (const edit of edits) {
|
|
482
|
+
parserState.tree.edit(edit);
|
|
483
|
+
}
|
|
484
|
+
const startParse = performance.now();
|
|
485
|
+
const newTree = parserState.parser.parse(content, parserState.tree);
|
|
486
|
+
const endParse = performance.now();
|
|
487
|
+
const parseTime = endParse - startParse;
|
|
488
|
+
this.performance.parseTimes.push(parseTime);
|
|
489
|
+
if (this.performance.parseTimes.length > 10) {
|
|
490
|
+
this.performance.parseTimes.shift();
|
|
491
|
+
}
|
|
492
|
+
this.performance.averageParseTime = this.performance.parseTimes.reduce((acc, time) => acc + time, 0) / this.performance.parseTimes.length;
|
|
493
|
+
if (!newTree) {
|
|
494
|
+
return { error: "Failed to parse buffer" };
|
|
495
|
+
}
|
|
496
|
+
const changedRanges = parserState.tree.getChangedRanges(newTree);
|
|
497
|
+
parserState.tree = newTree;
|
|
498
|
+
const startQuery = performance.now();
|
|
499
|
+
const matches = [];
|
|
500
|
+
if (changedRanges.length === 0) {
|
|
501
|
+
edits.forEach((edit) => {
|
|
502
|
+
const range = this.editToRange(edit);
|
|
503
|
+
changedRanges.push(range);
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
for (const range of changedRanges) {
|
|
507
|
+
let node = parserState.tree.rootNode.descendantForPosition(range.startPosition, range.endPosition);
|
|
508
|
+
if (!node) {
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
if (node.equals(parserState.tree.rootNode)) {
|
|
512
|
+
const rangeCaptures = parserState.queries.highlights.captures(node, {
|
|
513
|
+
startIndex: range.startIndex - 100,
|
|
514
|
+
endIndex: range.endIndex + 1000
|
|
515
|
+
});
|
|
516
|
+
matches.push(...rangeCaptures);
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
while (node && !this.nodeContainsRange(node, range)) {
|
|
520
|
+
node = node.parent;
|
|
521
|
+
}
|
|
522
|
+
if (!node) {
|
|
523
|
+
node = parserState.tree.rootNode;
|
|
524
|
+
}
|
|
525
|
+
const nodeCaptures = parserState.queries.highlights.captures(node);
|
|
526
|
+
matches.push(...nodeCaptures);
|
|
527
|
+
}
|
|
528
|
+
let injectionRanges = new Map;
|
|
529
|
+
if (parserState.queries.injections) {
|
|
530
|
+
const injectionResult = await this.processInjections(parserState);
|
|
531
|
+
matches.push(...injectionResult.captures);
|
|
532
|
+
injectionRanges = injectionResult.injectionRanges;
|
|
533
|
+
}
|
|
534
|
+
const endQuery = performance.now();
|
|
535
|
+
const queryTime = endQuery - startQuery;
|
|
536
|
+
this.performance.queryTimes.push(queryTime);
|
|
537
|
+
if (this.performance.queryTimes.length > 10) {
|
|
538
|
+
this.performance.queryTimes.shift();
|
|
539
|
+
}
|
|
540
|
+
this.performance.averageQueryTime = this.performance.queryTimes.reduce((acc, time) => acc + time, 0) / this.performance.queryTimes.length;
|
|
541
|
+
return this.getHighlights(parserState, matches, injectionRanges);
|
|
542
|
+
}
|
|
543
|
+
nodeContainsRange(node, range) {
|
|
544
|
+
return node.startPosition.row <= range.startPosition.row && node.endPosition.row >= range.endPosition.row && (node.startPosition.row < range.startPosition.row || node.startPosition.column <= range.startPosition.column) && (node.endPosition.row > range.endPosition.row || node.endPosition.column >= range.endPosition.column);
|
|
545
|
+
}
|
|
546
|
+
getHighlights(parserState, matches, injectionRanges) {
|
|
547
|
+
const lineHighlights = new Map;
|
|
548
|
+
const droppedHighlights = new Map;
|
|
549
|
+
for (const match of matches) {
|
|
550
|
+
const node = match.node;
|
|
551
|
+
const startLine = node.startPosition.row;
|
|
552
|
+
const endLine = node.endPosition.row;
|
|
553
|
+
const highlight = {
|
|
554
|
+
startCol: node.startPosition.column,
|
|
555
|
+
endCol: node.endPosition.column,
|
|
556
|
+
group: match.name
|
|
557
|
+
};
|
|
558
|
+
if (!lineHighlights.has(startLine)) {
|
|
559
|
+
lineHighlights.set(startLine, new Map);
|
|
560
|
+
droppedHighlights.set(startLine, new Map);
|
|
561
|
+
}
|
|
562
|
+
if (lineHighlights.get(startLine)?.has(node.id)) {
|
|
563
|
+
droppedHighlights.get(startLine)?.set(node.id, lineHighlights.get(startLine)?.get(node.id));
|
|
564
|
+
}
|
|
565
|
+
lineHighlights.get(startLine)?.set(node.id, highlight);
|
|
566
|
+
if (startLine !== endLine) {
|
|
567
|
+
for (let line = startLine + 1;line <= endLine; line++) {
|
|
568
|
+
if (!lineHighlights.has(line)) {
|
|
569
|
+
lineHighlights.set(line, new Map);
|
|
570
|
+
}
|
|
571
|
+
const hl = {
|
|
572
|
+
startCol: 0,
|
|
573
|
+
endCol: node.endPosition.column,
|
|
574
|
+
group: match.name
|
|
575
|
+
};
|
|
576
|
+
lineHighlights.get(line)?.set(node.id, hl);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return {
|
|
581
|
+
highlights: Array.from(lineHighlights.entries()).map(([line, lineHighlights2]) => ({
|
|
582
|
+
line,
|
|
583
|
+
highlights: Array.from(lineHighlights2.values()),
|
|
584
|
+
droppedHighlights: droppedHighlights.get(line) ? Array.from(droppedHighlights.get(line).values()) : []
|
|
585
|
+
}))
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
getSimpleHighlights(matches, injectionRanges) {
|
|
589
|
+
const highlights = [];
|
|
590
|
+
const flatInjectionRanges = [];
|
|
591
|
+
for (const [lang, ranges] of injectionRanges.entries()) {
|
|
592
|
+
for (const range of ranges) {
|
|
593
|
+
flatInjectionRanges.push({ ...range, lang });
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
for (const match of matches) {
|
|
597
|
+
const node = match.node;
|
|
598
|
+
let isInjection = false;
|
|
599
|
+
let injectionLang;
|
|
600
|
+
let containsInjection = false;
|
|
601
|
+
for (const injRange of flatInjectionRanges) {
|
|
602
|
+
if (node.startIndex >= injRange.start && node.endIndex <= injRange.end) {
|
|
603
|
+
isInjection = true;
|
|
604
|
+
injectionLang = injRange.lang;
|
|
605
|
+
break;
|
|
606
|
+
} else if (node.startIndex <= injRange.start && node.endIndex >= injRange.end) {
|
|
607
|
+
containsInjection = true;
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
const matchQuery = match._injectedQuery;
|
|
612
|
+
const patternProperties = matchQuery?.setProperties?.[match.patternIndex];
|
|
613
|
+
const concealValue = patternProperties?.conceal ?? match.setProperties?.conceal;
|
|
614
|
+
const concealLines = patternProperties?.conceal_lines ?? match.setProperties?.conceal_lines;
|
|
615
|
+
const meta = {};
|
|
616
|
+
if (isInjection && injectionLang) {
|
|
617
|
+
meta.isInjection = true;
|
|
618
|
+
meta.injectionLang = injectionLang;
|
|
619
|
+
}
|
|
620
|
+
if (containsInjection) {
|
|
621
|
+
meta.containsInjection = true;
|
|
622
|
+
}
|
|
623
|
+
if (concealValue !== undefined) {
|
|
624
|
+
meta.conceal = concealValue;
|
|
625
|
+
}
|
|
626
|
+
if (concealLines !== undefined) {
|
|
627
|
+
meta.concealLines = concealLines;
|
|
628
|
+
}
|
|
629
|
+
if (Object.keys(meta).length > 0) {
|
|
630
|
+
highlights.push([node.startIndex, node.endIndex, match.name, meta]);
|
|
631
|
+
} else {
|
|
632
|
+
highlights.push([node.startIndex, node.endIndex, match.name]);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
highlights.sort((a, b) => a[0] - b[0]);
|
|
636
|
+
return highlights;
|
|
637
|
+
}
|
|
638
|
+
async handleResetBuffer(bufferId, version, content) {
|
|
639
|
+
const parserState = this.bufferParsers.get(bufferId);
|
|
640
|
+
if (!parserState) {
|
|
641
|
+
return { warning: "No parser state found for buffer" };
|
|
642
|
+
}
|
|
643
|
+
parserState.content = content;
|
|
644
|
+
const newTree = parserState.parser.parse(content);
|
|
645
|
+
if (!newTree) {
|
|
646
|
+
return { error: "Failed to parse buffer during reset" };
|
|
647
|
+
}
|
|
648
|
+
parserState.tree = newTree;
|
|
649
|
+
const matches = parserState.queries.highlights.captures(parserState.tree.rootNode);
|
|
650
|
+
let injectionRanges = new Map;
|
|
651
|
+
if (parserState.queries.injections) {
|
|
652
|
+
const injectionResult = await this.processInjections(parserState);
|
|
653
|
+
matches.push(...injectionResult.captures);
|
|
654
|
+
injectionRanges = injectionResult.injectionRanges;
|
|
655
|
+
}
|
|
656
|
+
return this.getHighlights(parserState, matches, injectionRanges);
|
|
657
|
+
}
|
|
658
|
+
disposeBuffer(bufferId) {
|
|
659
|
+
const parserState = this.bufferParsers.get(bufferId);
|
|
660
|
+
if (!parserState) {
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
parserState.tree.delete();
|
|
664
|
+
parserState.parser.delete();
|
|
665
|
+
this.bufferParsers.delete(bufferId);
|
|
666
|
+
}
|
|
667
|
+
async handleOneShotHighlight(content, filetype, messageId) {
|
|
668
|
+
const reusableState = await this.getReusableParser(filetype);
|
|
669
|
+
if (!reusableState) {
|
|
670
|
+
self.postMessage({
|
|
671
|
+
type: "ONESHOT_HIGHLIGHT_RESPONSE",
|
|
672
|
+
messageId,
|
|
673
|
+
hasParser: false,
|
|
674
|
+
warning: `No parser available for filetype ${filetype}`
|
|
675
|
+
});
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
const parseContent = filetype === "markdown" && content.endsWith("```") ? content + `
|
|
679
|
+
` : content;
|
|
680
|
+
const tree = reusableState.parser.parse(parseContent);
|
|
681
|
+
if (!tree) {
|
|
682
|
+
self.postMessage({
|
|
683
|
+
type: "ONESHOT_HIGHLIGHT_RESPONSE",
|
|
684
|
+
messageId,
|
|
685
|
+
hasParser: false,
|
|
686
|
+
error: "Failed to parse content"
|
|
687
|
+
});
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
try {
|
|
691
|
+
const matches = reusableState.filetypeParser.queries.highlights.captures(tree.rootNode);
|
|
692
|
+
let injectionRanges = new Map;
|
|
693
|
+
if (reusableState.filetypeParser.queries.injections) {
|
|
694
|
+
const parserState = {
|
|
695
|
+
parser: reusableState.parser,
|
|
696
|
+
tree,
|
|
697
|
+
queries: reusableState.filetypeParser.queries,
|
|
698
|
+
filetype,
|
|
699
|
+
content,
|
|
700
|
+
injectionMapping: reusableState.filetypeParser.injectionMapping
|
|
701
|
+
};
|
|
702
|
+
const injectionResult = await this.processInjections(parserState);
|
|
703
|
+
matches.push(...injectionResult.captures);
|
|
704
|
+
injectionRanges = injectionResult.injectionRanges;
|
|
705
|
+
}
|
|
706
|
+
const highlights = this.getSimpleHighlights(matches, injectionRanges);
|
|
707
|
+
self.postMessage({
|
|
708
|
+
type: "ONESHOT_HIGHLIGHT_RESPONSE",
|
|
709
|
+
messageId,
|
|
710
|
+
hasParser: true,
|
|
711
|
+
highlights
|
|
712
|
+
});
|
|
713
|
+
} finally {
|
|
714
|
+
tree.delete();
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
async updateDataPath(dataPath) {
|
|
718
|
+
this.dataPath = dataPath;
|
|
719
|
+
this.tsDataPath = path2.join(dataPath, "tree-sitter");
|
|
720
|
+
try {
|
|
721
|
+
await mkdir2(path2.join(this.tsDataPath, "languages"), { recursive: true });
|
|
722
|
+
await mkdir2(path2.join(this.tsDataPath, "queries"), { recursive: true });
|
|
723
|
+
} catch (error) {
|
|
724
|
+
throw new Error(`Failed to update data path: ${error}`);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
async clearCache() {
|
|
728
|
+
if (!this.dataPath || !this.tsDataPath) {
|
|
729
|
+
throw new Error("No data path configured");
|
|
730
|
+
}
|
|
731
|
+
const { rm } = await import("fs/promises");
|
|
732
|
+
try {
|
|
733
|
+
const treeSitterPath = path2.join(this.dataPath, "tree-sitter");
|
|
734
|
+
await rm(treeSitterPath, { recursive: true, force: true });
|
|
735
|
+
await mkdir2(path2.join(treeSitterPath, "languages"), { recursive: true });
|
|
736
|
+
await mkdir2(path2.join(treeSitterPath, "queries"), { recursive: true });
|
|
737
|
+
this.filetypeParsers.clear();
|
|
738
|
+
this.filetypeParserPromises.clear();
|
|
739
|
+
this.reusableParsers.clear();
|
|
740
|
+
this.reusableParserPromises.clear();
|
|
741
|
+
} catch (error) {
|
|
742
|
+
throw new Error(`Failed to clear cache: ${error}`);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
if (!isMainThread) {
|
|
747
|
+
let logMessage = function(type, ...args) {
|
|
748
|
+
self.postMessage({
|
|
749
|
+
type: "WORKER_LOG",
|
|
750
|
+
logType: type,
|
|
751
|
+
data: args
|
|
752
|
+
});
|
|
753
|
+
};
|
|
754
|
+
const worker = new ParserWorker;
|
|
755
|
+
console.log = (...args) => logMessage("log", ...args);
|
|
756
|
+
console.error = (...args) => logMessage("error", ...args);
|
|
757
|
+
console.warn = (...args) => logMessage("warn", ...args);
|
|
758
|
+
self.onmessage = async (e) => {
|
|
759
|
+
const { type, bufferId, version, content, filetype, edits, filetypeParser, messageId, dataPath } = e.data;
|
|
760
|
+
try {
|
|
761
|
+
switch (type) {
|
|
762
|
+
case "INIT":
|
|
763
|
+
try {
|
|
764
|
+
await worker.initialize({ dataPath });
|
|
765
|
+
self.postMessage({ type: "INIT_RESPONSE" });
|
|
766
|
+
} catch (error) {
|
|
767
|
+
self.postMessage({
|
|
768
|
+
type: "INIT_RESPONSE",
|
|
769
|
+
error: error instanceof Error ? error.stack || error.message : String(error)
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
break;
|
|
773
|
+
case "ADD_FILETYPE_PARSER":
|
|
774
|
+
worker.addFiletypeParser(filetypeParser);
|
|
775
|
+
break;
|
|
776
|
+
case "PRELOAD_PARSER":
|
|
777
|
+
const maybeParser = await worker.preloadParser(filetype);
|
|
778
|
+
self.postMessage({ type: "PRELOAD_PARSER_RESPONSE", messageId, hasParser: !!maybeParser });
|
|
779
|
+
break;
|
|
780
|
+
case "INITIALIZE_PARSER":
|
|
781
|
+
await worker.handleInitializeParser(bufferId, version, content, filetype, messageId);
|
|
782
|
+
break;
|
|
783
|
+
case "HANDLE_EDITS":
|
|
784
|
+
const response = await worker.handleEdits(bufferId, content, edits);
|
|
785
|
+
if (response.highlights && response.highlights.length > 0) {
|
|
786
|
+
self.postMessage({ type: "HIGHLIGHT_RESPONSE", bufferId, version, ...response });
|
|
787
|
+
} else if (response.warning) {
|
|
788
|
+
self.postMessage({ type: "WARNING", bufferId, warning: response.warning });
|
|
789
|
+
} else if (response.error) {
|
|
790
|
+
self.postMessage({ type: "ERROR", bufferId, error: response.error });
|
|
791
|
+
}
|
|
792
|
+
break;
|
|
793
|
+
case "GET_PERFORMANCE":
|
|
794
|
+
self.postMessage({ type: "PERFORMANCE_RESPONSE", performance: worker.performance, messageId });
|
|
795
|
+
break;
|
|
796
|
+
case "RESET_BUFFER":
|
|
797
|
+
const resetResponse = await worker.handleResetBuffer(bufferId, version, content);
|
|
798
|
+
if (resetResponse.highlights && resetResponse.highlights.length > 0) {
|
|
799
|
+
self.postMessage({ type: "HIGHLIGHT_RESPONSE", bufferId, version, ...resetResponse });
|
|
800
|
+
} else if (resetResponse.warning) {
|
|
801
|
+
self.postMessage({ type: "WARNING", bufferId, warning: resetResponse.warning });
|
|
802
|
+
} else if (resetResponse.error) {
|
|
803
|
+
self.postMessage({ type: "ERROR", bufferId, error: resetResponse.error });
|
|
804
|
+
}
|
|
805
|
+
break;
|
|
806
|
+
case "DISPOSE_BUFFER":
|
|
807
|
+
worker.disposeBuffer(bufferId);
|
|
808
|
+
self.postMessage({ type: "BUFFER_DISPOSED", bufferId });
|
|
809
|
+
break;
|
|
810
|
+
case "ONESHOT_HIGHLIGHT":
|
|
811
|
+
await worker.handleOneShotHighlight(content, filetype, messageId);
|
|
812
|
+
break;
|
|
813
|
+
case "UPDATE_DATA_PATH":
|
|
814
|
+
try {
|
|
815
|
+
await worker.updateDataPath(dataPath);
|
|
816
|
+
self.postMessage({ type: "UPDATE_DATA_PATH_RESPONSE", messageId });
|
|
817
|
+
} catch (error) {
|
|
818
|
+
self.postMessage({
|
|
819
|
+
type: "UPDATE_DATA_PATH_RESPONSE",
|
|
820
|
+
messageId,
|
|
821
|
+
error: error instanceof Error ? error.message : String(error)
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
break;
|
|
825
|
+
case "CLEAR_CACHE":
|
|
826
|
+
try {
|
|
827
|
+
await worker.clearCache();
|
|
828
|
+
self.postMessage({ type: "CLEAR_CACHE_RESPONSE", messageId });
|
|
829
|
+
} catch (error) {
|
|
830
|
+
self.postMessage({
|
|
831
|
+
type: "CLEAR_CACHE_RESPONSE",
|
|
832
|
+
messageId,
|
|
833
|
+
error: error instanceof Error ? error.message : String(error)
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
break;
|
|
837
|
+
default:
|
|
838
|
+
self.postMessage({
|
|
839
|
+
type: "ERROR",
|
|
840
|
+
bufferId,
|
|
841
|
+
error: `Unknown message type: ${type}`
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
} catch (error) {
|
|
845
|
+
self.postMessage({
|
|
846
|
+
type: "ERROR",
|
|
847
|
+
bufferId,
|
|
848
|
+
error: error instanceof Error ? error.stack || error.message : String(error)
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
//# debugId=C9A95F2FF0DEFD0964756E2164756E21
|
|
855
|
+
//# sourceMappingURL=parser.worker.js.map
|