返回 DeepSeek-Reasonix
regexSearchClient.ts
根目录 / desktop / frontend / src / components / editors / regexSearchClient.ts
1 import {
2 REGEX_SEARCH_TIMEOUT_MS,
3 type RegexSearchRequest,
4 type RegexSearchResponse,
5 } from "./codeSearch";
6
7 export interface RegexSearchWorker {
8 onmessage: ((event: MessageEvent<RegexSearchResponse>) => void) | null;
9 onerror: ((event: ErrorEvent) => void) | null;
10 postMessage(request: RegexSearchRequest): void;
11 terminate(): void;
12 }
13
14 export interface RegexSearchCallbacks {
15 onResponse(response: RegexSearchResponse): void;
16 }
17
18 export interface RegexSearchTaskOptions {
19 createWorker?: () => Promise<RegexSearchWorker>;
20 timeoutMs?: number;
21 setTimer?: (callback: () => void, delay: number) => number;
22 clearTimer?: (timer: number) => void;
23 }
24
25 export function startRegexSearch(
26 request: RegexSearchRequest,
27 callbacks: RegexSearchCallbacks,
28 options: RegexSearchTaskOptions = {},
29 ): () => void {
30 const createWorker = options.createWorker ?? createInlineRegexWorker;
31 const setTimer = options.setTimer ?? ((callback, delay) => window.setTimeout(callback, delay));
32 const clearTimer = options.clearTimer ?? ((timer) => window.clearTimeout(timer));
33 const timeoutMs = options.timeoutMs ?? REGEX_SEARCH_TIMEOUT_MS;
34 let worker: RegexSearchWorker | null = null;
35 let timer: number | null = null;
36 let stopped = false;
37
38 const stop = () => {
39 if (timer != null) {
40 clearTimer(timer);
41 timer = null;
42 }
43 worker?.terminate();
44 worker = null;
45 };
46
47 const finish = (response: RegexSearchResponse) => {
48 if (stopped) return;
49 stopped = true;
50 stop();
51 callbacks.onResponse(response);
52 };
53
54 // Start the deadline before the async module/Worker creation. A stalled
55 // worker chunk must not leave the editor in a permanent pending state.
56 timer = setTimer(() => finish({
57 requestId: request.requestId,
58 ok: false,
59 error: "timeout",
60 }), timeoutMs);
61
62 void createWorker()
63 .then((createdWorker) => {
64 if (stopped) {
65 createdWorker.terminate();
66 return;
67 }
68 worker = createdWorker;
69 worker.onmessage = (event) => finish(event.data);
70 worker.onerror = () => finish({
71 requestId: request.requestId,
72 ok: false,
73 error: "unavailable",
74 });
75 worker.postMessage(request);
76 })
77 .catch(() => finish({
78 requestId: request.requestId,
79 ok: false,
80 error: "unavailable",
81 }));
82
83 return () => {
84 if (stopped) return;
85 stopped = true;
86 stop();
87 };
88 }
89
90 async function createInlineRegexWorker(): Promise<RegexSearchWorker> {
91 const { default: RegexSearchWorkerConstructor } = await import("./regexSearch.worker?worker&inline");
92 return new RegexSearchWorkerConstructor();
93 }
94
94 lines TYPESCRIPT