|
| 1 | +/* eslint-disable no-await-in-loop */ |
1 | 2 | // @ts-ignore |
2 | 3 | // eslint-disable-next-line import/no-unresolved |
3 | 4 | import dts from "@App/types/scriptcat"; |
4 | 5 | import Hook from "@App/app/service/hook"; |
5 | 6 | import { languages } from "monaco-editor"; |
6 | | -import pako from "pako"; |
7 | 7 | import Cache from "@App/app/cache"; |
8 | | -import { isFirefox } from "./utils"; |
9 | 8 |
|
10 | 9 | // 注册eslint |
11 | 10 | const linterWorker = new Worker("/src/linter.worker.js"); |
| 11 | +const editorWorker = new Worker("/src/editor.worker.js", { type: "module" }); |
| 12 | + |
| 13 | +const getPartialBlob = (idx: number): Promise<Blob | null> => fetch( |
| 14 | + chrome.runtime.getURL(`/src/ts.worker.js.part${idx}`) |
| 15 | +).then((resp) => (resp.ok ? resp.blob() : null)) |
| 16 | + .catch(() => null); |
| 17 | +const combineBlobsToUrl = async (blobs: Blob[], defaultType?: string): Promise<string> => { |
| 18 | + const arrayBuffers: ArrayBuffer[] = []; |
| 19 | + let totalLength = 0; |
| 20 | + |
| 21 | + // Read all blobs into ArrayBuffers and compute total length |
| 22 | + for (const blob of blobs) { |
| 23 | + const arrayBuffer = await blob.arrayBuffer(); |
| 24 | + arrayBuffers.push(arrayBuffer); |
| 25 | + totalLength += arrayBuffer.byteLength; // <-- sum, don't overwrite |
| 26 | + } |
| 27 | + |
| 28 | + // Allocate a single Uint8Array large enough for everything |
| 29 | + const combined = new Uint8Array(totalLength); |
| 30 | + |
| 31 | + // Copy each buffer into the combined array |
| 32 | + let offset = 0; |
| 33 | + for (const buffer of arrayBuffers) { |
| 34 | + combined.set(new Uint8Array(buffer), offset); |
| 35 | + offset += buffer.byteLength; |
| 36 | + } |
| 37 | + |
| 38 | + // Create a single Blob out of the combined data |
| 39 | + const type = defaultType || blobs[0]?.type || "application/octet-stream"; |
| 40 | + const combinedBlob = new Blob([combined], { type }); |
| 41 | + |
| 42 | + // Create a Blob URL |
| 43 | + const blobUrl = URL.createObjectURL(combinedBlob); |
| 44 | + // 注意:此处生成的 Blob URL 在整个应用生命周期内用于 Worker,不会被释放。 |
| 45 | + // 如果未来 Worker 支持销毁重建,请在销毁时调用 URL.revokeObjectURL(blobUrl) 释放资源。 |
| 46 | + return blobUrl; |
| 47 | +} |
| 48 | + |
| 49 | + |
| 50 | +const tsWorkerPromise = fetch(chrome.runtime.getURL("/src/ts.worker.js.part0")).then((resp) => { |
| 51 | + return resp.ok ? resp.blob() : null; |
| 52 | +}).catch(() => { return null }).then(async (blob) => { |
| 53 | + let worker: Worker; |
| 54 | + if (blob) { |
| 55 | + // 有分割 |
| 56 | + const blobs: Blob[] = []; |
| 57 | + let idx = 0; |
| 58 | + do { |
| 59 | + blobs.push(blob); |
| 60 | + blob = await getPartialBlob(++idx); |
| 61 | + } while (blob); |
| 62 | + const url = await combineBlobsToUrl(blobs, "text/javascript"); |
| 63 | + worker = new Worker(url, { type: "module" }); |
| 64 | + } else { |
| 65 | + // 沒分割 |
| 66 | + worker = new Worker("/src/ts.worker.js", { type: "module" }); |
| 67 | + } |
| 68 | + return worker; |
| 69 | +}); |
12 | 70 |
|
13 | 71 | export default function registerEditor() { |
14 | | - // @ts-ignore |
15 | | - window.tsUrl = ""; |
16 | | - |
17 | | - fetch(chrome.runtime.getURL(`/src/ts.worker.js${isFirefox() ? ".gz" : ""}`)) |
18 | | - .then((resp) => resp.blob()) |
19 | | - .then(async (blob) => { |
20 | | - const result = pako.inflate(await blob.arrayBuffer()); |
21 | | - // @ts-ignore |
22 | | - window.tsUrl = URL.createObjectURL(new Blob([result])); |
23 | | - }); |
24 | | - // @ts-ignore |
| 72 | + |
25 | 73 | window.MonacoEnvironment = { |
26 | | - getWorkerUrl(moduleId: any, label: any) { |
| 74 | + // https://microsoft.github.io/monaco-editor/typedoc/interfaces/Environment.html#getWorker |
| 75 | + // Returns Worker | Promise<Worker> |
| 76 | + getWorker(workerId: string, label: string) { |
27 | 77 | if (label === "typescript" || label === "javascript") { |
28 | | - // return "/src/ts.worker.js"; |
29 | | - // @ts-ignore |
30 | | - return window.tsUrl; |
| 78 | + return tsWorkerPromise; |
31 | 79 | } |
32 | | - return "/src/editor.worker.js"; |
| 80 | + return editorWorker; |
33 | 81 | }, |
34 | 82 | }; |
35 | 83 |
|
|
0 commit comments