@lvce-editor/file-search-worker 1.15.0 → 2.0.0

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.
@@ -1,1805 +1,1759 @@
1
- const commands = Object.create(null);
2
- const registerCommand = (key, fn) => {
3
- commands[key] = fn;
1
+ const Two = '2.0';
2
+ const state$3 = {
3
+ callbacks: Object.create(null)
4
4
  };
5
- const register = commandMap => {
6
- for (const [key, value] of Object.entries(commandMap)) {
7
- registerCommand(key, value);
8
- }
5
+ const set = (id, fn) => {
6
+ state$3.callbacks[id] = fn;
9
7
  };
10
- const getCommand = key => {
11
- return commands[key];
8
+ const get = id => {
9
+ return state$3.callbacks[id];
12
10
  };
13
- const execute = (command, ...args) => {
14
- const fn = getCommand(command);
11
+ const remove$2 = id => {
12
+ delete state$3.callbacks[id];
13
+ };
14
+ let id = 0;
15
+ const create$3 = () => {
16
+ return ++id;
17
+ };
18
+ const warn = (...args) => {
19
+ console.warn(...args);
20
+ };
21
+ const registerPromise = () => {
22
+ const id = create$3();
23
+ const {
24
+ resolve,
25
+ promise
26
+ } = Promise.withResolvers();
27
+ set(id, resolve);
28
+ return {
29
+ id,
30
+ promise
31
+ };
32
+ };
33
+ const resolve = (id, response) => {
34
+ const fn = get(id);
15
35
  if (!fn) {
16
- throw new Error(`command not found ${command}`);
36
+ console.log(response);
37
+ warn(`callback ${id} may already be disposed`);
38
+ return;
17
39
  }
18
- return fn(...args);
40
+ fn(response);
41
+ remove$2(id);
19
42
  };
20
-
21
- const assetDir = '';
22
-
23
- const Directory$1 = 3;
24
- const File$1 = 7;
25
-
26
- const fileMapUrl = `${assetDir}/config/fileMap.json`;
27
-
28
- const normalizeLine$1 = line => {
29
- if (line.startsWith('Error: ')) {
30
- return line.slice(`Error: `.length);
31
- }
32
- if (line.startsWith('VError: ')) {
33
- return line.slice(`VError: `.length);
34
- }
35
- return line;
43
+ const create$2 = (method, params) => {
44
+ const {
45
+ id,
46
+ promise
47
+ } = registerPromise();
48
+ const message = {
49
+ jsonrpc: Two,
50
+ method,
51
+ params,
52
+ id
53
+ };
54
+ return {
55
+ message,
56
+ promise
57
+ };
36
58
  };
37
- const getCombinedMessage$1 = (error, message) => {
38
- const stringifiedError = normalizeLine$1(`${error}`);
39
- if (message) {
40
- return `${message}: ${stringifiedError}`;
59
+ class JsonRpcError extends Error {
60
+ constructor(message) {
61
+ super(message);
62
+ this.name = 'JsonRpcError';
41
63
  }
42
- return stringifiedError;
43
- };
64
+ }
44
65
  const NewLine$3 = '\n';
45
- const getNewLineIndex$2 = (string, startIndex = undefined) => {
46
- return string.indexOf(NewLine$3, startIndex);
47
- };
48
- const mergeStacks$1 = (parent, child) => {
49
- if (!child) {
50
- return parent;
66
+ const DomException = 'DOMException';
67
+ const ReferenceError$1 = 'ReferenceError';
68
+ const SyntaxError$1 = 'SyntaxError';
69
+ const TypeError$1 = 'TypeError';
70
+ const getErrorConstructor = (message, type) => {
71
+ if (type) {
72
+ switch (type) {
73
+ case DomException:
74
+ return DOMException;
75
+ case TypeError$1:
76
+ return TypeError;
77
+ case SyntaxError$1:
78
+ return SyntaxError;
79
+ case ReferenceError$1:
80
+ return ReferenceError;
81
+ default:
82
+ return Error;
83
+ }
51
84
  }
52
- const parentNewLineIndex = getNewLineIndex$2(parent);
53
- const childNewLineIndex = getNewLineIndex$2(child);
54
- if (childNewLineIndex === -1) {
55
- return parent;
85
+ if (message.startsWith('TypeError: ')) {
86
+ return TypeError;
56
87
  }
57
- const parentFirstLine = parent.slice(0, parentNewLineIndex);
58
- const childRest = child.slice(childNewLineIndex);
59
- const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
60
- if (parentFirstLine.includes(childFirstLine)) {
61
- return parentFirstLine + childRest;
88
+ if (message.startsWith('SyntaxError: ')) {
89
+ return SyntaxError;
62
90
  }
63
- return child;
64
- };
65
- let VError$1 = class VError extends Error {
66
- constructor(error, message) {
67
- const combinedMessage = getCombinedMessage$1(error, message);
68
- super(combinedMessage);
69
- this.name = 'VError';
70
- if (error instanceof Error) {
71
- this.stack = mergeStacks$1(this.stack, error.stack);
72
- }
73
- if (error.codeFrame) {
74
- // @ts-ignore
75
- this.codeFrame = error.codeFrame;
76
- }
77
- if (error.code) {
78
- // @ts-ignore
79
- this.code = error.code;
80
- }
91
+ if (message.startsWith('ReferenceError: ')) {
92
+ return ReferenceError;
81
93
  }
94
+ return Error;
82
95
  };
83
-
84
- const getJson = async url => {
85
- try {
86
- const response = await fetch(url);
87
- if (!response.ok) {
88
- throw new Error(response.statusText);
89
- }
90
- const text = await response.json();
91
- return text;
92
- } catch (error) {
93
- throw new VError$1(error, `Failed to request json for ${url}`);
96
+ const constructError = (message, type, name) => {
97
+ const ErrorConstructor = getErrorConstructor(message, type);
98
+ if (ErrorConstructor === DOMException && name) {
99
+ return new ErrorConstructor(message, name);
94
100
  }
95
- };
96
-
97
- const getText = async url => {
98
- try {
99
- const response = await fetch(url);
100
- if (!response.ok) {
101
- throw new Error(response.statusText);
101
+ if (ErrorConstructor === Error) {
102
+ const error = new Error(message);
103
+ if (name && name !== 'VError') {
104
+ error.name = name;
102
105
  }
103
- const text = await response.text();
104
- return text;
105
- } catch (error) {
106
- throw new VError$1(error, `Failed to request text for ${url}`);
106
+ return error;
107
107
  }
108
+ return new ErrorConstructor(message);
108
109
  };
109
-
110
- const Slash$1 = '/';
111
-
112
- const Slash = Slash$1;
113
-
114
- // TODO move all of this to an extension
115
-
116
- const readFile$1 = async uri => {
117
- const fetchUri = `${assetDir}${uri}`;
118
- const text = await getText(fetchUri);
119
- return text;
110
+ const getNewLineIndex$2 = (string, startIndex = undefined) => {
111
+ return string.indexOf(NewLine$3, startIndex);
120
112
  };
121
- const writeFile$1 = () => {
122
- throw new Error('not implemented');
113
+ const getParentStack = error => {
114
+ let parentStack = error.stack || error.data || error.message || '';
115
+ if (parentStack.startsWith(' at')) {
116
+ parentStack = error.message + NewLine$3 + parentStack;
117
+ }
118
+ return parentStack;
123
119
  };
124
- const mkdir$1 = () => {
125
- throw new Error('not implemented');
120
+ const joinLines$1 = lines => {
121
+ return lines.join(NewLine$3);
126
122
  };
127
- const remove$2 = () => {
128
- throw new Error('not implemented');
123
+ const MethodNotFound = -32601;
124
+ const Custom = -32001;
125
+ const splitLines$2 = lines => {
126
+ return lines.split(NewLine$3);
129
127
  };
130
- const readDirWithFileTypes$1 = async uri => {
131
- const fileList = await getJson(fileMapUrl);
132
- const dirents = [];
133
- for (const fileUri of fileList) {
134
- if (fileUri.startsWith(uri)) {
135
- const rest = fileUri.slice(uri.length + 1);
136
- if (rest.includes(Slash)) {
137
- const name = rest.slice(0, rest.indexOf(Slash));
138
- if (dirents.some(dirent => dirent.name === name)) {
139
- continue;
140
- }
141
- dirents.push({
142
- type: Directory$1,
143
- name
144
- });
145
- } else {
146
- dirents.push({
147
- type: File$1,
148
- name: rest
149
- });
128
+ const restoreJsonRpcError = error => {
129
+ if (error && error instanceof Error) {
130
+ return error;
131
+ }
132
+ const currentStack = joinLines$1(splitLines$2(new Error().stack || '').slice(1));
133
+ if (error && error.code && error.code === MethodNotFound) {
134
+ const restoredError = new JsonRpcError(error.message);
135
+ const parentStack = getParentStack(error);
136
+ restoredError.stack = parentStack + NewLine$3 + currentStack;
137
+ return restoredError;
138
+ }
139
+ if (error && error.message) {
140
+ const restoredError = constructError(error.message, error.type, error.name);
141
+ if (error.data) {
142
+ if (error.data.stack && error.data.type && error.message) {
143
+ restoredError.stack = error.data.type + ': ' + error.message + NewLine$3 + error.data.stack + NewLine$3 + currentStack;
144
+ } else if (error.data.stack) {
145
+ restoredError.stack = error.data.stack;
146
+ }
147
+ if (error.data.codeFrame) {
148
+ // @ts-ignore
149
+ restoredError.codeFrame = error.data.codeFrame;
150
+ }
151
+ if (error.data.code) {
152
+ // @ts-ignore
153
+ restoredError.code = error.data.code;
154
+ }
155
+ if (error.data.type) {
156
+ // @ts-ignore
157
+ restoredError.name = error.data.type;
158
+ }
159
+ } else {
160
+ if (error.stack) {
161
+ const lowerStack = restoredError.stack || '';
162
+ // @ts-ignore
163
+ const indexNewLine = getNewLineIndex$2(lowerStack);
164
+ const parentStack = getParentStack(error);
165
+ // @ts-ignore
166
+ restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
167
+ }
168
+ if (error.codeFrame) {
169
+ // @ts-ignore
170
+ restoredError.codeFrame = error.codeFrame;
150
171
  }
151
172
  }
173
+ return restoredError;
152
174
  }
153
- return dirents;
175
+ if (typeof error === 'string') {
176
+ return new Error(`JsonRpc Error: ${error}`);
177
+ }
178
+ return new Error(`JsonRpc Error: ${error}`);
154
179
  };
155
- const chmod$1 = () => {
156
- throw new Error('[memfs] chmod not implemented');
157
- };
158
- const getBlob$1 = async uri => {
159
- const content = await readFile$1(uri);
160
- const blob = new Blob([content]);
161
- return blob;
162
- };
163
-
164
- class FileNotFoundError extends Error {
165
- constructor(uri) {
166
- super(`File not found: ${uri}`);
167
- this.code = 'ENOENT';
180
+ const unwrapJsonRpcResult = responseMessage => {
181
+ if ('error' in responseMessage) {
182
+ const restoredError = restoreJsonRpcError(responseMessage.error);
183
+ throw restoredError;
168
184
  }
169
- }
170
-
171
- // TODO move this to an extension?
172
-
173
- const state$4 = {
174
- files: Object.create(null)
175
- };
176
- const getDirent = uri => {
177
- return state$4.files[uri];
185
+ if ('result' in responseMessage) {
186
+ return responseMessage.result;
187
+ }
188
+ throw new JsonRpcError('unexpected response message');
178
189
  };
179
- const readFile = uri => {
180
- const dirent = getDirent(uri);
181
- if (!dirent) {
182
- throw new FileNotFoundError(uri);
190
+ const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
191
+ const getErrorType = prettyError => {
192
+ if (prettyError && prettyError.type) {
193
+ return prettyError.type;
183
194
  }
184
- if (dirent.type !== File$1) {
185
- throw new Error('file is a directory');
195
+ if (prettyError && prettyError.constructor && prettyError.constructor.name) {
196
+ return prettyError.constructor.name;
186
197
  }
187
- return dirent.content;
198
+ return undefined;
188
199
  };
189
- const ensureParentDir = uri => {
190
- const startIndex = 0;
191
- let endIndex = uri.indexOf(Slash);
192
- while (endIndex >= 0) {
193
- const part = uri.slice(startIndex, endIndex + 1);
194
- state$4.files[part] = {
195
- type: Directory$1,
196
- content: ''
200
+ const getErrorProperty = (error, prettyError) => {
201
+ if (error && error.code === E_COMMAND_NOT_FOUND) {
202
+ return {
203
+ code: MethodNotFound,
204
+ message: error.message,
205
+ data: error.stack
197
206
  };
198
- endIndex = uri.indexOf(Slash, endIndex + 1);
199
207
  }
208
+ return {
209
+ code: Custom,
210
+ message: prettyError.message,
211
+ data: {
212
+ stack: prettyError.stack,
213
+ codeFrame: prettyError.codeFrame,
214
+ type: getErrorType(prettyError),
215
+ code: prettyError.code,
216
+ name: prettyError.name
217
+ }
218
+ };
200
219
  };
201
- const writeFile = (uri, content) => {
202
- const dirent = getDirent(uri);
203
- if (dirent) {
204
- dirent.content = content;
205
- } else {
206
- ensureParentDir(uri);
207
- state$4.files[uri] = {
208
- type: File$1,
209
- content
210
- };
211
- }
220
+ const create$1 = (message, error) => {
221
+ return {
222
+ jsonrpc: Two,
223
+ id: message.id,
224
+ error
225
+ };
212
226
  };
213
- const mkdir = uri => {
214
- if (!uri.endsWith(Slash)) {
215
- uri += Slash;
216
- }
217
- ensureParentDir(uri);
218
- state$4.files[uri] = {
219
- type: Directory$1,
220
- content: ''
227
+ const getErrorResponse = (message, error, preparePrettyError, logError) => {
228
+ const prettyError = preparePrettyError(error);
229
+ logError(error, prettyError);
230
+ const errorProperty = getErrorProperty(error, prettyError);
231
+ return create$1(message, errorProperty);
232
+ };
233
+ const create$4 = (message, result) => {
234
+ return {
235
+ jsonrpc: Two,
236
+ id: message.id,
237
+ result: result ?? null
221
238
  };
222
239
  };
223
- const remove$1 = uri => {
224
- const toDelete = [];
225
- for (const key of Object.keys(state$4.files)) {
226
- if (key.startsWith(uri)) {
227
- toDelete.push(key);
228
- }
229
- }
230
- for (const key of toDelete) {
231
- delete state$4.files[key];
232
- }
240
+ const getSuccessResponse = (message, result) => {
241
+ const resultProperty = result ?? null;
242
+ return create$4(message, resultProperty);
233
243
  };
234
- const readDirWithFileTypes = uri => {
235
- if (!uri.endsWith(Slash)) {
236
- uri += Slash;
237
- }
238
- const dirents = [];
239
- for (const [key, value] of Object.entries(state$4.files)) {
240
- if (key.startsWith(uri)) {
241
- // @ts-ignore
242
- switch (value.type) {
243
- case Directory$1:
244
- if (!key.slice(0, -1).includes(Slash, uri.length) && key !== `${uri}/` && key !== uri) {
245
- dirents.push({
246
- // @ts-ignore
247
- type: value.type,
248
- name: key.slice(uri.length, -1)
249
- });
250
- }
251
- break;
252
- case File$1:
253
- if (!key.includes(Slash, uri.length + 1)) {
254
- dirents.push({
255
- // @ts-ignore
256
- type: value.type,
257
- name: key.slice(uri.length)
258
- });
259
- }
260
- break;
261
- }
262
- }
244
+ const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
245
+ try {
246
+ const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
247
+ return getSuccessResponse(message, result);
248
+ } catch (error) {
249
+ return getErrorResponse(message, error, preparePrettyError, logError);
263
250
  }
264
- return dirents;
265
251
  };
266
- const getBlobUrl = uri => {
267
- const content = readFile(uri);
268
- const blob = new Blob([content]);
269
- const url = URL.createObjectURL(blob);
270
- return url;
271
- };
272
- const getBlob = uri => {
273
- const content = readFile(uri);
274
- const blob = new Blob([content]);
275
- return blob;
252
+ const defaultPreparePrettyError = error => {
253
+ return error;
276
254
  };
277
- const chmod = () => {
278
- throw new Error('[memfs] chmod not implemented');
255
+ const defaultLogError = () => {
256
+ // ignore
279
257
  };
280
- const getFiles = () => {
281
- return state$4.files;
258
+ const defaultRequiresSocket = () => {
259
+ return false;
282
260
  };
261
+ const defaultResolve = resolve;
283
262
 
284
- const Memfs = 'memfs';
285
- const Html = 'html';
286
- const Fetch = 'fetch';
287
-
288
- const RE_PROTOCOL = /^([a-z-]+):\/\//;
289
- const getProtocol = uri => {
290
- const protocolMatch = uri.match(RE_PROTOCOL);
291
- if (protocolMatch) {
292
- return protocolMatch[1];
263
+ // TODO maybe remove this in v6 or v7, only accept options object to simplify the code
264
+ const normalizeParams = args => {
265
+ if (args.length === 1) {
266
+ const options = args[0];
267
+ return {
268
+ ipc: options.ipc,
269
+ message: options.message,
270
+ execute: options.execute,
271
+ resolve: options.resolve || defaultResolve,
272
+ preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
273
+ logError: options.logError || defaultLogError,
274
+ requiresSocket: options.requiresSocket || defaultRequiresSocket
275
+ };
293
276
  }
294
- return '';
295
- };
296
-
297
- const searchFile$4 = async () => {
298
- const files = await getFiles();
299
- const keys = Object.keys(files);
300
- return keys;
277
+ return {
278
+ ipc: args[0],
279
+ message: args[1],
280
+ execute: args[2],
281
+ resolve: args[3],
282
+ preparePrettyError: args[4],
283
+ logError: args[5],
284
+ requiresSocket: args[6]
285
+ };
301
286
  };
302
-
303
- const SearchFileMemfs = {
304
- __proto__: null,
305
- searchFile: searchFile$4
287
+ const handleJsonRpcMessage = async (...args) => {
288
+ const options = normalizeParams(args);
289
+ const {
290
+ message,
291
+ ipc,
292
+ execute,
293
+ resolve,
294
+ preparePrettyError,
295
+ logError,
296
+ requiresSocket
297
+ } = options;
298
+ if ('id' in message) {
299
+ if ('method' in message) {
300
+ const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
301
+ try {
302
+ ipc.send(response);
303
+ } catch (error) {
304
+ const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
305
+ ipc.send(errorResponse);
306
+ }
307
+ return;
308
+ }
309
+ resolve(message.id, message);
310
+ return;
311
+ }
312
+ if ('method' in message) {
313
+ await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
314
+ return;
315
+ }
316
+ throw new JsonRpcError('unexpected message');
306
317
  };
307
-
308
- const removeLeadingSlash = path => {
309
- if (path.startsWith('/')) {
310
- return path.slice(1);
318
+ const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
319
+ const {
320
+ message,
321
+ promise
322
+ } = create$2(method, params);
323
+ {
324
+ ipc.send(message);
311
325
  }
312
- return path;
326
+ const responseMessage = await promise;
327
+ return unwrapJsonRpcResult(responseMessage);
328
+ };
329
+ const invoke$2 = (ipc, method, ...params) => {
330
+ return invokeHelper(ipc, method, params);
313
331
  };
314
332
 
315
- // TODO simplify code
316
- // 1. don't have playground prefix in fileMap json
317
- // 2. remove code here that removes the prefix
318
- const searchFile$3 = async path => {
319
- const fileList = await getJson(fileMapUrl);
320
- const result = fileList.map(removeLeadingSlash);
321
- const prefixLength = path.length - 'file:///'.length;
322
- const final = [];
323
- for (const item of result) {
324
- final.push(item.slice(prefixLength));
333
+ const commands = Object.create(null);
334
+ const register = commandMap => {
335
+ Object.assign(commands, commandMap);
336
+ };
337
+ const getCommand = key => {
338
+ return commands[key];
339
+ };
340
+ const execute = (command, ...args) => {
341
+ const fn = getCommand(command);
342
+ if (!fn) {
343
+ throw new Error(`command not found ${command}`);
325
344
  }
326
- return final;
345
+ return fn(...args);
327
346
  };
328
347
 
329
- const SearchFileFetch = {
330
- __proto__: null,
331
- searchFile: searchFile$3
348
+ const getData$1 = event => {
349
+ return event.data;
332
350
  };
333
-
334
- const Directory = 'directory';
335
- const File = 'file';
336
-
337
- // based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
338
-
339
- const fromAsync = async asyncIterable => {
340
- const children = [];
341
- for await (const value of asyncIterable) {
342
- children.push(value);
351
+ const walkValue = (value, transferrables, isTransferrable) => {
352
+ if (!value) {
353
+ return;
354
+ }
355
+ if (isTransferrable(value)) {
356
+ transferrables.push(value);
357
+ return;
358
+ }
359
+ if (Array.isArray(value)) {
360
+ for (const item of value) {
361
+ walkValue(item, transferrables, isTransferrable);
362
+ }
363
+ return;
364
+ }
365
+ if (typeof value === 'object') {
366
+ for (const property of Object.values(value)) {
367
+ walkValue(property, transferrables, isTransferrable);
368
+ }
369
+ return;
343
370
  }
344
- return children;
345
371
  };
346
-
347
- /**
348
- * Do not use directly, use FileSystemHtml.getChildHandles
349
- * instead which prompts for the required permission to
350
- * retrieve the child handles
351
- *
352
- */
353
- const getChildHandles = async handle => {
354
- // @ts-ignore
355
- const handles = await fromAsync(handle.values());
356
- return handles;
372
+ const isMessagePort = value => {
373
+ return value && value instanceof MessagePort;
357
374
  };
358
-
359
- const dirname = (pathSeparator, path) => {
360
- const index = path.lastIndexOf(pathSeparator);
361
- if (index === -1) {
362
- return path;
363
- }
364
- return path.slice(0, index);
375
+ const isMessagePortMain = value => {
376
+ return value && value.constructor && value.constructor.name === 'MessagePortMain';
365
377
  };
366
-
367
- const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
368
- let idbProxyableTypes;
369
- let cursorAdvanceMethods;
370
- // This is a function to prevent it throwing up in node environments.
371
- function getIdbProxyableTypes() {
372
- return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
373
- }
374
- // This is a function to prevent it throwing up in node environments.
375
- function getCursorAdvanceMethods() {
376
- return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
377
- }
378
- const transactionDoneMap = new WeakMap();
379
- const transformCache = new WeakMap();
380
- const reverseTransformCache = new WeakMap();
381
- function promisifyRequest(request) {
382
- const promise = new Promise((resolve, reject) => {
383
- const unlisten = () => {
384
- request.removeEventListener('success', success);
385
- request.removeEventListener('error', error);
386
- };
387
- const success = () => {
388
- resolve(wrap(request.result));
389
- unlisten();
390
- };
391
- const error = () => {
392
- reject(request.error);
393
- unlisten();
394
- };
395
- request.addEventListener('success', success);
396
- request.addEventListener('error', error);
397
- });
398
- // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This
399
- // is because we create many promises from a single IDBRequest.
400
- reverseTransformCache.set(promise, request);
401
- return promise;
402
- }
403
- function cacheDonePromiseForTransaction(tx) {
404
- // Early bail if we've already created a done promise for this transaction.
405
- if (transactionDoneMap.has(tx)) return;
406
- const done = new Promise((resolve, reject) => {
407
- const unlisten = () => {
408
- tx.removeEventListener('complete', complete);
409
- tx.removeEventListener('error', error);
410
- tx.removeEventListener('abort', error);
411
- };
412
- const complete = () => {
413
- resolve();
414
- unlisten();
415
- };
416
- const error = () => {
417
- reject(tx.error || new DOMException('AbortError', 'AbortError'));
418
- unlisten();
419
- };
420
- tx.addEventListener('complete', complete);
421
- tx.addEventListener('error', error);
422
- tx.addEventListener('abort', error);
423
- });
424
- // Cache it for later retrieval.
425
- transactionDoneMap.set(tx, done);
426
- }
427
- let idbProxyTraps = {
428
- get(target, prop, receiver) {
429
- if (target instanceof IDBTransaction) {
430
- // Special handling for transaction.done.
431
- if (prop === 'done') return transactionDoneMap.get(target);
432
- // Make tx.store return the only store in the transaction, or undefined if there are many.
433
- if (prop === 'store') {
434
- return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
435
- }
436
- }
437
- // Else transform whatever we get back.
438
- return wrap(target[prop]);
439
- },
440
- set(target, prop, value) {
441
- target[prop] = value;
442
- return true;
443
- },
444
- has(target, prop) {
445
- if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
378
+ const isOffscreenCanvas = value => {
379
+ return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
380
+ };
381
+ const isInstanceOf = (value, constructorName) => {
382
+ return value?.constructor?.name === constructorName;
383
+ };
384
+ const isSocket = value => {
385
+ return isInstanceOf(value, 'Socket');
386
+ };
387
+ const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
388
+ const isTransferrable = value => {
389
+ for (const fn of transferrables) {
390
+ if (fn(value)) {
446
391
  return true;
447
392
  }
448
- return prop in target;
449
393
  }
394
+ return false;
450
395
  };
451
- function replaceTraps(callback) {
452
- idbProxyTraps = callback(idbProxyTraps);
453
- }
454
- function wrapFunction(func) {
455
- // Due to expected object equality (which is enforced by the caching in `wrap`), we
456
- // only create one new func per func.
457
- // Cursor methods are special, as the behaviour is a little more different to standard IDB. In
458
- // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
459
- // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
460
- // with real promises, so each advance methods returns a new promise for the cursor object, or
461
- // undefined if the end of the cursor has been reached.
462
- if (getCursorAdvanceMethods().includes(func)) {
463
- return function (...args) {
464
- // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
465
- // the original object.
466
- func.apply(unwrap(this), args);
467
- return wrap(this.request);
468
- };
469
- }
470
- return function (...args) {
471
- // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
472
- // the original object.
473
- return wrap(func.apply(unwrap(this), args));
396
+ const getTransferrables = value => {
397
+ const transferrables = [];
398
+ walkValue(value, transferrables, isTransferrable);
399
+ return transferrables;
400
+ };
401
+ const attachEvents = that => {
402
+ const handleMessage = (...args) => {
403
+ const data = that.getData(...args);
404
+ that.dispatchEvent(new MessageEvent('message', {
405
+ data
406
+ }));
474
407
  };
475
- }
476
- function transformCachableValue(value) {
477
- if (typeof value === 'function') return wrapFunction(value);
478
- // This doesn't return, it just creates a 'done' promise for the transaction,
479
- // which is later returned for transaction.done (see idbObjectHandler).
480
- if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
481
- if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
482
- // Return the same value back if we're not going to transform it.
483
- return value;
484
- }
485
- function wrap(value) {
486
- // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
487
- // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
488
- if (value instanceof IDBRequest) return promisifyRequest(value);
489
- // If we've already transformed this value before, reuse the transformed value.
490
- // This is faster, but it also provides object equality.
491
- if (transformCache.has(value)) return transformCache.get(value);
492
- const newValue = transformCachableValue(value);
493
- // Not all types are transformed.
494
- // These may be primitive types, so they can't be WeakMap keys.
495
- if (newValue !== value) {
496
- transformCache.set(value, newValue);
497
- reverseTransformCache.set(newValue, value);
408
+ that.onMessage(handleMessage);
409
+ const handleClose = event => {
410
+ that.dispatchEvent(new Event('close'));
411
+ };
412
+ that.onClose(handleClose);
413
+ };
414
+ class Ipc extends EventTarget {
415
+ constructor(rawIpc) {
416
+ super();
417
+ this._rawIpc = rawIpc;
418
+ attachEvents(this);
498
419
  }
499
- return newValue;
500
420
  }
501
- const unwrap = value => reverseTransformCache.get(value);
502
-
503
- /**
504
- * Open a database.
505
- *
506
- * @param name Name of the database.
507
- * @param version Schema version.
508
- * @param callbacks Additional callbacks.
509
- */
510
- function openDB(name, version, {
511
- blocked,
512
- upgrade,
513
- blocking,
514
- terminated
515
- } = {}) {
516
- const request = indexedDB.open(name, version);
517
- const openPromise = wrap(request);
518
- if (upgrade) {
519
- request.addEventListener('upgradeneeded', event => {
520
- upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
521
- });
421
+ const readyMessage = 'ready';
422
+ const listen$4 = () => {
423
+ // @ts-ignore
424
+ if (typeof WorkerGlobalScope === 'undefined') {
425
+ throw new TypeError('module is not in web worker scope');
522
426
  }
523
- if (blocked) {
524
- request.addEventListener('blocked', event => blocked(
525
- // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
526
- event.oldVersion, event.newVersion, event));
427
+ return globalThis;
428
+ };
429
+ const signal$3 = global => {
430
+ global.postMessage(readyMessage);
431
+ };
432
+ class IpcChildWithModuleWorker extends Ipc {
433
+ getData(event) {
434
+ return getData$1(event);
527
435
  }
528
- openPromise.then(db => {
529
- if (terminated) db.addEventListener('close', () => terminated());
530
- if (blocking) {
531
- db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
532
- }
533
- }).catch(() => {});
534
- return openPromise;
535
- }
536
- const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
537
- const writeMethods = ['put', 'add', 'delete', 'clear'];
538
- const cachedMethods = new Map();
539
- function getMethod(target, prop) {
540
- if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
541
- return;
436
+ send(message) {
437
+ // @ts-ignore
438
+ this._rawIpc.postMessage(message);
542
439
  }
543
- if (cachedMethods.get(prop)) return cachedMethods.get(prop);
544
- const targetFuncName = prop.replace(/FromIndex$/, '');
545
- const useIndex = prop !== targetFuncName;
546
- const isWrite = writeMethods.includes(targetFuncName);
547
- if (
548
- // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
549
- !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
550
- return;
440
+ sendAndTransfer(message) {
441
+ const transfer = getTransferrables(message);
442
+ // @ts-ignore
443
+ this._rawIpc.postMessage(message, transfer);
551
444
  }
552
- const method = async function (storeName, ...args) {
553
- // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
554
- const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
555
- let target = tx.store;
556
- if (useIndex) target = target.index(args.shift());
557
- // Must reject if op rejects.
558
- // If it's a write operation, must reject if tx.done rejects.
559
- // Must reject with op rejection first.
560
- // Must resolve with op value.
561
- // Must handle both promises (no unhandled rejections)
562
- return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
563
- };
564
- cachedMethods.set(prop, method);
565
- return method;
566
- }
567
- replaceTraps(oldTraps => ({
568
- ...oldTraps,
569
- get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
570
- has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
571
- }));
572
- const advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];
573
- const methodMap = {};
574
- const advanceResults = new WeakMap();
575
- const ittrProxiedCursorToOriginalProxy = new WeakMap();
576
- const cursorIteratorTraps = {
577
- get(target, prop) {
578
- if (!advanceMethodProps.includes(prop)) return target[prop];
579
- let cachedFunc = methodMap[prop];
580
- if (!cachedFunc) {
581
- cachedFunc = methodMap[prop] = function (...args) {
582
- advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
583
- };
584
- }
585
- return cachedFunc;
445
+ dispose() {
446
+ // ignore
586
447
  }
587
- };
588
- async function* iterate(...args) {
589
- // tslint:disable-next-line:no-this-assignment
590
- let cursor = this;
591
- if (!(cursor instanceof IDBCursor)) {
592
- cursor = await cursor.openCursor(...args);
448
+ onClose(callback) {
449
+ // ignore
593
450
  }
594
- if (!cursor) return;
595
- cursor = cursor;
596
- const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
597
- ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
598
- // Map this double-proxy back to the original, so other cursor methods work.
599
- reverseTransformCache.set(proxiedCursor, unwrap(cursor));
600
- while (cursor) {
601
- yield proxiedCursor;
602
- // If one of the advancing methods was not called, call continue().
603
- cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
604
- advanceResults.delete(proxiedCursor);
451
+ onMessage(callback) {
452
+ this._rawIpc.addEventListener('message', callback);
605
453
  }
606
454
  }
607
- function isIteratorProp(target, prop) {
608
- return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
609
- }
610
- replaceTraps(oldTraps => ({
611
- ...oldTraps,
612
- get(target, prop, receiver) {
613
- if (isIteratorProp(target, prop)) return iterate;
614
- return oldTraps.get(target, prop, receiver);
615
- },
616
- has(target, prop) {
617
- return isIteratorProp(target, prop) || oldTraps.has(target, prop);
455
+ const wrap$6 = global => {
456
+ return new IpcChildWithModuleWorker(global);
457
+ };
458
+ const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
459
+ const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
460
+ const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
461
+ const NewLine$1 = '\n';
462
+ const joinLines = lines => {
463
+ return lines.join(NewLine$1);
464
+ };
465
+ const splitLines$1 = lines => {
466
+ return lines.split(NewLine$1);
467
+ };
468
+ const isModuleNotFoundMessage = line => {
469
+ return line.includes('[ERR_MODULE_NOT_FOUND]');
470
+ };
471
+ const getModuleNotFoundError = stderr => {
472
+ const lines = splitLines$1(stderr);
473
+ const messageIndex = lines.findIndex(isModuleNotFoundMessage);
474
+ const message = lines[messageIndex];
475
+ return {
476
+ message,
477
+ code: ERR_MODULE_NOT_FOUND
478
+ };
479
+ };
480
+ const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
481
+ const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
482
+ const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
483
+ const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
484
+ const RE_AT = /^\s+at/;
485
+ const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
486
+ const isUnhelpfulNativeModuleError = stderr => {
487
+ return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
488
+ };
489
+ const isMessageCodeBlockStartIndex = line => {
490
+ return RE_MESSAGE_CODE_BLOCK_START.test(line);
491
+ };
492
+ const isMessageCodeBlockEndIndex = line => {
493
+ return RE_MESSAGE_CODE_BLOCK_END.test(line);
494
+ };
495
+ const getMessageCodeBlock = stderr => {
496
+ const lines = splitLines$1(stderr);
497
+ const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
498
+ const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
499
+ const relevantLines = lines.slice(startIndex, endIndex);
500
+ const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
501
+ return relevantMessage;
502
+ };
503
+ const getNativeModuleErrorMessage = stderr => {
504
+ const message = getMessageCodeBlock(stderr);
505
+ return {
506
+ message: `Incompatible native node module: ${message}`,
507
+ code: E_INCOMPATIBLE_NATIVE_MODULE
508
+ };
509
+ };
510
+ const isModulesSyntaxError = stderr => {
511
+ if (!stderr) {
512
+ return false;
618
513
  }
619
- }));
620
-
621
- const state$3 = {
622
- databases: Object.create(null),
623
- eventId: 0,
624
- dbVersion: 1,
625
- cachedDb: undefined
514
+ return stderr.includes('SyntaxError: Cannot use import statement outside a module');
626
515
  };
627
-
628
- // TODO high memory usage in idb because of transactionDoneMap
629
-
630
- const getHandleDb = async () => {
631
- // @ts-ignore
632
- const db = await openDB('handle', state$3.dbVersion, {
633
- async upgrade(db) {
634
- if (!db.objectStoreNames.contains('file-handles-store')) {
635
- await db.createObjectStore('file-handles-store', {});
636
- }
637
- }
638
- });
639
- return db;
516
+ const getModuleSyntaxError = () => {
517
+ return {
518
+ message: `ES Modules are not supported in electron`,
519
+ code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
520
+ };
640
521
  };
641
- const getHandle$1 = async uri => {
642
- const handleDb = await getHandleDb();
643
- const handle = await handleDb.get('file-handles-store', uri);
644
- return handle;
522
+ const isModuleNotFoundError = stderr => {
523
+ if (!stderr) {
524
+ return false;
525
+ }
526
+ return stderr.includes('ERR_MODULE_NOT_FOUND');
645
527
  };
646
-
647
- const getHandle = async uri => {
648
- try {
649
- // TODO retrieve handle from state or from indexeddb
650
- // TODO if not found, throw error
651
- const handle = await getHandle$1(uri);
652
- return handle;
653
- } catch (error) {
654
- throw new VError$1(error, 'Failed to get handle');
528
+ const isNormalStackLine = line => {
529
+ return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
530
+ };
531
+ const getDetails = lines => {
532
+ const index = lines.findIndex(isNormalStackLine);
533
+ if (index === -1) {
534
+ return {
535
+ actualMessage: joinLines(lines),
536
+ rest: []
537
+ };
538
+ }
539
+ let lastIndex = index - 1;
540
+ while (++lastIndex < lines.length) {
541
+ if (!isNormalStackLine(lines[lastIndex])) {
542
+ break;
543
+ }
655
544
  }
545
+ return {
546
+ actualMessage: lines[index - 1],
547
+ rest: lines.slice(index, lastIndex)
548
+ };
656
549
  };
657
-
658
- const getDirectoryHandle = async uri => {
659
- const handle = await getHandle(uri);
660
- if (handle) {
661
- return handle;
550
+ const getHelpfulChildProcessError = (stdout, stderr) => {
551
+ if (isUnhelpfulNativeModuleError(stderr)) {
552
+ return getNativeModuleErrorMessage(stderr);
662
553
  }
663
- const dirname$1 = dirname('/', uri);
664
- if (uri === dirname$1) {
665
- return undefined;
554
+ if (isModulesSyntaxError(stderr)) {
555
+ return getModuleSyntaxError();
666
556
  }
667
- return getDirectoryHandle(dirname$1);
557
+ if (isModuleNotFoundError(stderr)) {
558
+ return getModuleNotFoundError(stderr);
559
+ }
560
+ const lines = splitLines$1(stderr);
561
+ const {
562
+ actualMessage,
563
+ rest
564
+ } = getDetails(lines);
565
+ return {
566
+ message: `${actualMessage}`,
567
+ code: '',
568
+ stack: rest
569
+ };
668
570
  };
669
- const toIgnore = ['.git', 'node_modules', 'dist', 'dist2'];
670
- const searchFilesRecursively = async (all, parent, handle) => {
671
- const childHandles = await getChildHandles(handle);
672
- const promises = [];
673
- for (const childHandle of childHandles) {
674
- if (toIgnore.includes(childHandle.name)) {
675
- continue;
676
- }
677
- const absolutePath = parent + '/' + childHandle.name;
678
- switch (childHandle.kind) {
679
- case Directory:
680
- promises.push(searchFilesRecursively(all, absolutePath, childHandle));
681
- break;
682
- case File:
683
- all.push(absolutePath);
684
- break;
685
- }
571
+ const normalizeLine$1 = line => {
572
+ if (line.startsWith('Error: ')) {
573
+ return line.slice(`Error: `.length);
574
+ }
575
+ if (line.startsWith('VError: ')) {
576
+ return line.slice(`VError: `.length);
686
577
  }
687
- await Promise.all(promises);
578
+ return line;
688
579
  };
689
- const searchFile$2 = async uri => {
690
- const path = uri.slice('html://'.length);
691
- const handle = await getDirectoryHandle(path);
692
- if (!handle) {
693
- // @ts-ignore
694
- throw new VError$1(`Folder not found ${uri}`);
580
+ const getCombinedMessage$1 = (error, message) => {
581
+ const stringifiedError = normalizeLine$1(`${error}`);
582
+ if (message) {
583
+ return `${message}: ${stringifiedError}`;
695
584
  }
696
- const all = [];
697
- await searchFilesRecursively(all, '', handle);
698
- return all;
585
+ return stringifiedError;
699
586
  };
700
-
701
- const SearchFileHtml = {
702
- __proto__: null,
703
- searchFile: searchFile$2
587
+ const NewLine$2 = '\n';
588
+ const getNewLineIndex$1 = (string, startIndex = undefined) => {
589
+ return string.indexOf(NewLine$2, startIndex);
704
590
  };
705
-
706
- const Diagonal = 1;
707
- const Left = 2;
708
-
709
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
710
-
711
- const createTable = size => {
712
- const table = [];
713
- for (let i = 0; i < size; i++) {
714
- const row = new Uint8Array(size);
715
- table.push(row);
591
+ const mergeStacks$1 = (parent, child) => {
592
+ if (!child) {
593
+ return parent;
716
594
  }
717
- return table;
718
- };
719
- const EmptyMatches = [];
720
- const Dash = '-';
721
- const Dot = '.';
722
- const EmptyString = '';
723
- const Space = ' ';
724
- const Underline = '_';
725
- const T = 't';
726
- const isLowerCase = char => {
727
- return char === char.toLowerCase();
728
- };
729
- const isUpperCase = char => {
730
- return char === char.toUpperCase();
731
- };
732
-
733
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
734
- const isGap = (columnCharBefore, columnChar) => {
735
- switch (columnCharBefore) {
736
- case Dash:
737
- case Underline:
738
- case EmptyString:
739
- case T:
740
- case Space:
741
- case Dot:
742
- return true;
595
+ const parentNewLineIndex = getNewLineIndex$1(parent);
596
+ const childNewLineIndex = getNewLineIndex$1(child);
597
+ if (childNewLineIndex === -1) {
598
+ return parent;
743
599
  }
744
- if (isLowerCase(columnCharBefore) && isUpperCase(columnChar)) {
745
- return true;
600
+ const parentFirstLine = parent.slice(0, parentNewLineIndex);
601
+ const childRest = child.slice(childNewLineIndex);
602
+ const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
603
+ if (parentFirstLine.includes(childFirstLine)) {
604
+ return parentFirstLine + childRest;
746
605
  }
747
- return false;
606
+ return child;
748
607
  };
749
-
750
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
751
- const getScore = (rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, isDiagonalMatch) => {
752
- if (rowCharLow !== columnCharLow) {
753
- return -1;
754
- }
755
- const isMatch = rowChar === columnChar;
756
- if (isMatch) {
757
- if (isDiagonalMatch) {
758
- return 8;
608
+ let VError$1 = class VError extends Error {
609
+ constructor(error, message) {
610
+ const combinedMessage = getCombinedMessage$1(error, message);
611
+ super(combinedMessage);
612
+ this.name = 'VError';
613
+ if (error instanceof Error) {
614
+ this.stack = mergeStacks$1(this.stack, error.stack);
759
615
  }
760
- if (isGap(columnCharBefore, columnChar)) {
761
- return 8;
616
+ if (error.codeFrame) {
617
+ // @ts-ignore
618
+ this.codeFrame = error.codeFrame;
619
+ }
620
+ if (error.code) {
621
+ // @ts-ignore
622
+ this.code = error.code;
762
623
  }
763
- return 5;
764
- }
765
- if (isGap(columnCharBefore, columnChar)) {
766
- return 8;
767
624
  }
768
- return 5;
769
625
  };
770
-
771
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
772
-
773
- const isPatternInWord = (patternLow, patternPos, patternLen, wordLow, wordPos, wordLen) => {
774
- while (patternPos < patternLen && wordPos < wordLen) {
775
- if (patternLow[patternPos] === wordLow[wordPos]) {
776
- patternPos += 1;
626
+ class IpcError extends VError$1 {
627
+ // @ts-ignore
628
+ constructor(betterMessage, stdout = '', stderr = '') {
629
+ if (stdout || stderr) {
630
+ // @ts-ignore
631
+ const {
632
+ message,
633
+ code,
634
+ stack
635
+ } = getHelpfulChildProcessError(stdout, stderr);
636
+ const cause = new Error(message);
637
+ // @ts-ignore
638
+ cause.code = code;
639
+ cause.stack = stack;
640
+ super(cause, betterMessage);
641
+ } else {
642
+ super(betterMessage);
777
643
  }
778
- wordPos += 1;
644
+ // @ts-ignore
645
+ this.name = 'IpcError';
646
+ // @ts-ignore
647
+ this.stdout = stdout;
648
+ // @ts-ignore
649
+ this.stderr = stderr;
779
650
  }
780
- return patternPos === patternLen; // pattern must be exhausted
651
+ }
652
+ const withResolvers = () => {
653
+ let _resolve;
654
+ const promise = new Promise(resolve => {
655
+ _resolve = resolve;
656
+ });
657
+ return {
658
+ resolve: _resolve,
659
+ promise
660
+ };
781
661
  };
782
-
783
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
784
- const traceHighlights = (table, arrows, patternLength, wordLength) => {
785
- let row = patternLength;
786
- let column = wordLength;
787
- const matches = [];
788
- while (row >= 1 && column >= 1) {
789
- const arrow = arrows[row][column];
790
- if (arrow === Left) {
791
- column--;
792
- } else if (arrow === Diagonal) {
793
- row--;
794
- column--;
795
- const start = column + 1;
796
- while (row >= 1 && column >= 1) {
797
- const arrow = arrows[row][column];
798
- if (arrow === Left) {
799
- break;
800
- }
801
- if (arrow === Diagonal) {
802
- row--;
803
- column--;
804
- }
805
- }
806
- const end = column;
807
- matches.unshift(end, start);
808
- }
662
+ const waitForFirstMessage = async port => {
663
+ const {
664
+ resolve,
665
+ promise
666
+ } = withResolvers();
667
+ port.addEventListener('message', resolve, {
668
+ once: true
669
+ });
670
+ const event = await promise;
671
+ // @ts-ignore
672
+ return event.data;
673
+ };
674
+ const listen$3 = async () => {
675
+ const parentIpcRaw = listen$4();
676
+ signal$3(parentIpcRaw);
677
+ const parentIpc = wrap$6(parentIpcRaw);
678
+ const firstMessage = await waitForFirstMessage(parentIpc);
679
+ if (firstMessage.method !== 'initialize') {
680
+ throw new IpcError('unexpected first message');
809
681
  }
810
- matches.unshift(table[patternLength][wordLength - 1]);
811
- return matches;
682
+ const type = firstMessage.params[0];
683
+ if (type === 'message-port') {
684
+ parentIpc.send({
685
+ jsonrpc: '2.0',
686
+ id: firstMessage.id,
687
+ result: null
688
+ });
689
+ parentIpc.dispose();
690
+ const port = firstMessage.params[1];
691
+ return port;
692
+ }
693
+ return globalThis;
812
694
  };
813
-
814
- // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
815
- const gridSize = 128;
816
- const table = createTable(gridSize);
817
- const arrows = createTable(gridSize);
818
- const fuzzySearch = (pattern, word) => {
819
- const patternLength = Math.min(pattern.length, gridSize - 1);
820
- const wordLength = Math.min(word.length, gridSize - 1);
821
- const patternLower = pattern.toLowerCase();
822
- const wordLower = word.toLowerCase();
823
- if (!isPatternInWord(patternLower, 0, patternLength, wordLower, 0, wordLength)) {
824
- return EmptyMatches;
695
+ class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
696
+ constructor(port) {
697
+ super(port);
825
698
  }
826
- let strongMatch = false;
827
- for (let row = 1; row < patternLength + 1; row++) {
828
- const rowChar = pattern[row - 1];
829
- const rowCharLow = patternLower[row - 1];
830
- for (let column = 1; column < wordLength + 1; column++) {
831
- const columnChar = word[column - 1];
832
- const columnCharLow = wordLower[column - 1];
833
- const columnCharBefore = word[column - 2] || '';
834
- const isDiagonalMatch = arrows[row - 1][column - 1] === Diagonal;
835
- const score = getScore(rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, isDiagonalMatch);
836
- if (row === 1 && score > 5) {
837
- strongMatch = true;
838
- }
839
- let diagonalScore = score + table[row - 1][column - 1];
840
- if (isDiagonalMatch && score !== -1) {
841
- diagonalScore += 2;
842
- }
843
- const leftScore = table[row][column - 1];
844
- if (leftScore > diagonalScore) {
845
- table[row][column] = leftScore;
846
- arrows[row][column] = Left;
847
- } else {
848
- table[row][column] = diagonalScore;
849
- arrows[row][column] = Diagonal;
850
- }
699
+ getData(event) {
700
+ return getData$1(event);
701
+ }
702
+ send(message) {
703
+ this._rawIpc.postMessage(message);
704
+ }
705
+ sendAndTransfer(message) {
706
+ const transfer = getTransferrables(message);
707
+ this._rawIpc.postMessage(message, transfer);
708
+ }
709
+ dispose() {
710
+ if (this._rawIpc.close) {
711
+ this._rawIpc.close();
851
712
  }
852
713
  }
853
- if (!strongMatch) {
854
- return EmptyMatches;
714
+ onClose(callback) {
715
+ // ignore
855
716
  }
856
- const highlights = traceHighlights(table, arrows, patternLength, wordLength);
857
- return highlights;
717
+ onMessage(callback) {
718
+ this._rawIpc.addEventListener('message', callback);
719
+ this._rawIpc.start();
720
+ }
721
+ }
722
+ const wrap$5 = port => {
723
+ return new IpcChildWithModuleWorkerAndMessagePort(port);
858
724
  };
859
-
860
- const filterQuickPickItem = (pattern, word) => {
861
- const matches = fuzzySearch(pattern, word);
862
- return matches;
725
+ const IpcChildWithModuleWorkerAndMessagePort$1 = {
726
+ __proto__: null,
727
+ listen: listen$3,
728
+ wrap: wrap$5
863
729
  };
864
730
 
865
- const getBaseName = path => {
866
- return path.slice(path.lastIndexOf('/') + 1);
867
- };
868
- const emptyMatches = [];
869
- const convertToPick = item => {
870
- return {
871
- pick: item,
872
- matches: emptyMatches
731
+ const createRpc = ipc => {
732
+ const rpc = {
733
+ invoke(method, ...params) {
734
+ return invoke$2(ipc, method, ...params);
735
+ }
873
736
  };
737
+ return rpc;
874
738
  };
875
- const filterQuickPickItems = (items, value) => {
876
- if (!value) {
877
- return items.map(convertToPick);
878
- }
879
- const results = [];
880
- for (const item of items) {
881
- const baseName = getBaseName(item);
882
- const matches = filterQuickPickItem(value, baseName);
883
- if (matches.length > 0) {
884
- results.push({
885
- pick: item,
886
- matches
887
- });
888
- }
889
- }
890
- return results;
739
+ const requiresSocket = () => {
740
+ return false;
891
741
  };
892
-
893
- const getFileSearchRipGrepArgs = () => {
894
- const ripGrepArgs = ['--files', '--sort-files'];
895
- return ripGrepArgs;
742
+ const preparePrettyError = error => {
743
+ return error;
744
+ };
745
+ const logError = () => {
746
+ // handled by renderer worker
747
+ };
748
+ const handleMessage = event => {
749
+ return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
750
+ };
751
+ const handleIpc = ipc => {
752
+ ipc.addEventListener('message', handleMessage);
896
753
  };
897
754
 
898
- const state$2 = {
899
- /**
900
- * @type {any}
901
- */
902
- ipc: undefined
755
+ // @ts-ignore
756
+ const listen$1 = async () => {
757
+ const module = IpcChildWithModuleWorkerAndMessagePort$1;
758
+ const rawIpc = await module.listen();
759
+ const ipc = module.wrap(rawIpc);
760
+ return ipc;
903
761
  };
904
- const get$1 = () => {
905
- return state$2.ipc;
762
+ const create = async ({
763
+ commandMap
764
+ }) => {
765
+ // TODO create a commandMap per rpc instance
766
+ register(commandMap);
767
+ const ipc = await listen$1();
768
+ handleIpc(ipc);
769
+ const rpc = createRpc(ipc);
770
+ return rpc;
906
771
  };
907
- const set$1 = ipc => {
908
- state$2.ipc = ipc;
772
+ const WebWorkerRpcClient = {
773
+ __proto__: null,
774
+ create
909
775
  };
910
776
 
911
- const Two = '2.0';
912
- class AssertionError extends Error {
913
- constructor(message) {
914
- super(message);
915
- this.name = 'AssertionError';
777
+ const assetDir = '';
778
+
779
+ const Directory$1 = 3;
780
+ const File$1 = 7;
781
+
782
+ const fileMapUrl = `${assetDir}/config/fileMap.json`;
783
+
784
+ const normalizeLine = line => {
785
+ if (line.startsWith('Error: ')) {
786
+ return line.slice('Error: '.length);
916
787
  }
917
- }
918
- const getType = value => {
919
- switch (typeof value) {
920
- case 'number':
921
- return 'number';
922
- case 'function':
923
- return 'function';
924
- case 'string':
925
- return 'string';
926
- case 'object':
927
- if (value === null) {
928
- return 'null';
929
- }
930
- if (Array.isArray(value)) {
931
- return 'array';
932
- }
933
- return 'object';
934
- case 'boolean':
935
- return 'boolean';
936
- default:
937
- return 'unknown';
788
+ if (line.startsWith('VError: ')) {
789
+ return line.slice('VError: '.length);
938
790
  }
791
+ return line;
939
792
  };
940
- const number = value => {
941
- const type = getType(value);
942
- if (type !== 'number') {
943
- throw new AssertionError('expected value to be of type number');
793
+ const getCombinedMessage = (error, message) => {
794
+ const stringifiedError = normalizeLine(`${error}`);
795
+ if (message) {
796
+ return `${message}: ${stringifiedError}`;
944
797
  }
798
+ return stringifiedError;
945
799
  };
946
- const state$1 = {
947
- callbacks: Object.create(null)
948
- };
949
- const set = (id, fn) => {
950
- state$1.callbacks[id] = fn;
951
- };
952
- const get = id => {
953
- return state$1.callbacks[id];
954
- };
955
- const remove = id => {
956
- delete state$1.callbacks[id];
957
- };
958
- const state = {
959
- id: 0
960
- };
961
- const create$3 = () => {
962
- return ++state.id;
963
- };
964
- const warn = (...args) => {
965
- console.warn(...args);
966
- };
967
- const registerPromise = () => {
968
- const id = create$3();
969
- const {
970
- resolve,
971
- promise
972
- } = Promise.withResolvers();
973
- set(id, resolve);
974
- return {
975
- id,
976
- promise
977
- };
800
+ const NewLine = '\n';
801
+ const getNewLineIndex = (string, startIndex = undefined) => {
802
+ return string.indexOf(NewLine, startIndex);
978
803
  };
979
- const resolve = (id, args) => {
980
- number(id);
981
- const fn = get(id);
982
- if (!fn) {
983
- console.log(args);
984
- warn(`callback ${id} may already be disposed`);
985
- return;
804
+ const mergeStacks = (parent, child) => {
805
+ if (!child) {
806
+ return parent;
986
807
  }
987
- fn(args);
988
- remove(id);
989
- };
990
- const create$2 = (method, params) => {
991
- const {
992
- id,
993
- promise
994
- } = registerPromise();
995
- const message = {
996
- jsonrpc: Two,
997
- method,
998
- params,
999
- id
1000
- };
1001
- return {
1002
- message,
1003
- promise
1004
- };
808
+ const parentNewLineIndex = getNewLineIndex(parent);
809
+ const childNewLineIndex = getNewLineIndex(child);
810
+ if (childNewLineIndex === -1) {
811
+ return parent;
812
+ }
813
+ const parentFirstLine = parent.slice(0, parentNewLineIndex);
814
+ const childRest = child.slice(childNewLineIndex);
815
+ const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
816
+ if (parentFirstLine.includes(childFirstLine)) {
817
+ return parentFirstLine + childRest;
818
+ }
819
+ return child;
1005
820
  };
1006
- class JsonRpcError extends Error {
1007
- constructor(message) {
1008
- super(message);
1009
- this.name = 'JsonRpcError';
821
+ class VError extends Error {
822
+ constructor(error, message) {
823
+ const combinedMessage = getCombinedMessage(error, message);
824
+ super(combinedMessage);
825
+ this.name = 'VError';
826
+ if (error instanceof Error) {
827
+ this.stack = mergeStacks(this.stack, error.stack);
828
+ }
829
+ if (error.codeFrame) {
830
+ // @ts-ignore
831
+ this.codeFrame = error.codeFrame;
832
+ }
833
+ if (error.code) {
834
+ // @ts-ignore
835
+ this.code = error.code;
836
+ }
1010
837
  }
1011
838
  }
1012
- const NewLine$2 = '\n';
1013
- const DomException = 'DOMException';
1014
- const ReferenceError$1 = 'ReferenceError';
1015
- const SyntaxError$1 = 'SyntaxError';
1016
- const TypeError$1 = 'TypeError';
1017
- const getErrorConstructor = (message, type) => {
1018
- if (type) {
1019
- switch (type) {
1020
- case DomException:
1021
- return DOMException;
1022
- case TypeError$1:
1023
- return TypeError;
1024
- case SyntaxError$1:
1025
- return SyntaxError;
1026
- case ReferenceError$1:
1027
- return ReferenceError;
1028
- default:
1029
- return Error;
839
+
840
+ const getJson = async url => {
841
+ try {
842
+ const response = await fetch(url);
843
+ if (!response.ok) {
844
+ throw new Error(response.statusText);
1030
845
  }
846
+ const text = await response.json();
847
+ return text;
848
+ } catch (error) {
849
+ throw new VError(error, `Failed to request json for ${url}`);
1031
850
  }
1032
- if (message.startsWith('TypeError: ')) {
1033
- return TypeError;
1034
- }
1035
- if (message.startsWith('SyntaxError: ')) {
1036
- return SyntaxError;
1037
- }
1038
- if (message.startsWith('ReferenceError: ')) {
1039
- return ReferenceError;
1040
- }
1041
- return Error;
1042
851
  };
1043
- const constructError = (message, type, name) => {
1044
- const ErrorConstructor = getErrorConstructor(message, type);
1045
- if (ErrorConstructor === DOMException && name) {
1046
- return new ErrorConstructor(message, name);
1047
- }
1048
- if (ErrorConstructor === Error) {
1049
- const error = new Error(message);
1050
- if (name && name !== 'VError') {
1051
- error.name = name;
852
+
853
+ const getText = async url => {
854
+ try {
855
+ const response = await fetch(url);
856
+ if (!response.ok) {
857
+ throw new Error(response.statusText);
1052
858
  }
1053
- return error;
859
+ const text = await response.text();
860
+ return text;
861
+ } catch (error) {
862
+ throw new VError(error, `Failed to request text for ${url}`);
1054
863
  }
1055
- return new ErrorConstructor(message);
1056
- };
1057
- const getNewLineIndex$1 = (string, startIndex = undefined) => {
1058
- return string.indexOf(NewLine$2, startIndex);
1059
864
  };
1060
- const getParentStack = error => {
1061
- let parentStack = error.stack || error.data || error.message || '';
1062
- if (parentStack.startsWith(' at')) {
1063
- parentStack = error.message + NewLine$2 + parentStack;
1064
- }
1065
- return parentStack;
865
+
866
+ const Slash$1 = '/';
867
+
868
+ const Slash = Slash$1;
869
+
870
+ // TODO move all of this to an extension
871
+
872
+ const readFile$1 = async uri => {
873
+ const fetchUri = `${assetDir}${uri}`;
874
+ const text = await getText(fetchUri);
875
+ return text;
1066
876
  };
1067
- const joinLines$1 = lines => {
1068
- return lines.join(NewLine$2);
877
+ const writeFile$1 = () => {
878
+ throw new Error('not implemented');
1069
879
  };
1070
- const MethodNotFound = -32601;
1071
- const Custom = -32001;
1072
- const splitLines$2 = lines => {
1073
- return lines.split(NewLine$2);
880
+ const mkdir$1 = () => {
881
+ throw new Error('not implemented');
1074
882
  };
1075
- const restoreJsonRpcError = error => {
1076
- if (error && error instanceof Error) {
1077
- return error;
1078
- }
1079
- const currentStack = joinLines$1(splitLines$2(new Error().stack || '').slice(1));
1080
- if (error && error.code && error.code === MethodNotFound) {
1081
- const restoredError = new JsonRpcError(error.message);
1082
- const parentStack = getParentStack(error);
1083
- restoredError.stack = parentStack + NewLine$2 + currentStack;
1084
- return restoredError;
1085
- }
1086
- if (error && error.message) {
1087
- const restoredError = constructError(error.message, error.type, error.name);
1088
- if (error.data) {
1089
- if (error.data.stack && error.data.type && error.message) {
1090
- restoredError.stack = error.data.type + ': ' + error.message + NewLine$2 + error.data.stack + NewLine$2 + currentStack;
1091
- } else if (error.data.stack) {
1092
- restoredError.stack = error.data.stack;
1093
- }
1094
- if (error.data.codeFrame) {
1095
- // @ts-ignore
1096
- restoredError.codeFrame = error.data.codeFrame;
1097
- }
1098
- if (error.data.code) {
1099
- // @ts-ignore
1100
- restoredError.code = error.data.code;
1101
- }
1102
- if (error.data.type) {
1103
- // @ts-ignore
1104
- restoredError.name = error.data.type;
1105
- }
1106
- } else {
1107
- if (error.stack) {
1108
- const lowerStack = restoredError.stack || '';
1109
- // @ts-ignore
1110
- const indexNewLine = getNewLineIndex$1(lowerStack);
1111
- const parentStack = getParentStack(error);
1112
- // @ts-ignore
1113
- restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
1114
- }
1115
- if (error.codeFrame) {
1116
- // @ts-ignore
1117
- restoredError.codeFrame = error.codeFrame;
883
+ const remove$1 = () => {
884
+ throw new Error('not implemented');
885
+ };
886
+ const readDirWithFileTypes$1 = async uri => {
887
+ const fileList = await getJson(fileMapUrl);
888
+ const dirents = [];
889
+ for (const fileUri of fileList) {
890
+ if (fileUri.startsWith(uri)) {
891
+ const rest = fileUri.slice(uri.length + 1);
892
+ if (rest.includes(Slash)) {
893
+ const name = rest.slice(0, rest.indexOf(Slash));
894
+ if (dirents.some(dirent => dirent.name === name)) {
895
+ continue;
896
+ }
897
+ dirents.push({
898
+ type: Directory$1,
899
+ name
900
+ });
901
+ } else {
902
+ dirents.push({
903
+ type: File$1,
904
+ name: rest
905
+ });
1118
906
  }
1119
907
  }
1120
- return restoredError;
1121
- }
1122
- if (typeof error === 'string') {
1123
- return new Error(`JsonRpc Error: ${error}`);
1124
908
  }
1125
- return new Error(`JsonRpc Error: ${error}`);
909
+ return dirents;
1126
910
  };
1127
- const unwrapJsonRpcResult = responseMessage => {
1128
- if ('error' in responseMessage) {
1129
- const restoredError = restoreJsonRpcError(responseMessage.error);
1130
- throw restoredError;
1131
- }
1132
- if ('result' in responseMessage) {
1133
- return responseMessage.result;
911
+ const chmod$1 = () => {
912
+ throw new Error('[memfs] chmod not implemented');
913
+ };
914
+ const getBlob$1 = async uri => {
915
+ const content = await readFile$1(uri);
916
+ const blob = new Blob([content]);
917
+ return blob;
918
+ };
919
+
920
+ class FileNotFoundError extends Error {
921
+ constructor(uri) {
922
+ super(`File not found: ${uri}`);
923
+ this.code = 'ENOENT';
1134
924
  }
1135
- throw new JsonRpcError('unexpected response message');
925
+ }
926
+
927
+ // TODO move this to an extension?
928
+
929
+ const state$2 = {
930
+ files: Object.create(null)
1136
931
  };
1137
- const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
1138
- const getErrorType = prettyError => {
1139
- if (prettyError && prettyError.type) {
1140
- return prettyError.type;
932
+ const getDirent = uri => {
933
+ return state$2.files[uri];
934
+ };
935
+ const readFile = uri => {
936
+ const dirent = getDirent(uri);
937
+ if (!dirent) {
938
+ throw new FileNotFoundError(uri);
1141
939
  }
1142
- if (prettyError && prettyError.constructor && prettyError.constructor.name) {
1143
- return prettyError.constructor.name;
940
+ if (dirent.type !== File$1) {
941
+ throw new Error('file is a directory');
1144
942
  }
1145
- return undefined;
943
+ return dirent.content;
1146
944
  };
1147
- const getErrorProperty = (error, prettyError) => {
1148
- if (error && error.code === E_COMMAND_NOT_FOUND) {
1149
- return {
1150
- code: MethodNotFound,
1151
- message: error.message,
1152
- data: error.stack
945
+ const ensureParentDir = uri => {
946
+ const startIndex = 0;
947
+ let endIndex = uri.indexOf(Slash);
948
+ while (endIndex >= 0) {
949
+ const part = uri.slice(startIndex, endIndex + 1);
950
+ state$2.files[part] = {
951
+ type: Directory$1,
952
+ content: ''
1153
953
  };
954
+ endIndex = uri.indexOf(Slash, endIndex + 1);
1154
955
  }
1155
- return {
1156
- code: Custom,
1157
- message: prettyError.message,
1158
- data: {
1159
- stack: prettyError.stack,
1160
- codeFrame: prettyError.codeFrame,
1161
- type: getErrorType(prettyError),
1162
- code: prettyError.code,
1163
- name: prettyError.name
1164
- }
1165
- };
1166
- };
1167
- const create$1 = (message, error) => {
1168
- return {
1169
- jsonrpc: Two,
1170
- id: message.id,
1171
- error
1172
- };
1173
956
  };
1174
- const getErrorResponse = (message, error, preparePrettyError, logError) => {
1175
- const prettyError = preparePrettyError(error);
1176
- logError(error, prettyError);
1177
- const errorProperty = getErrorProperty(error, prettyError);
1178
- return create$1(message, errorProperty);
957
+ const writeFile = (uri, content) => {
958
+ const dirent = getDirent(uri);
959
+ if (dirent) {
960
+ dirent.content = content;
961
+ } else {
962
+ ensureParentDir(uri);
963
+ state$2.files[uri] = {
964
+ type: File$1,
965
+ content
966
+ };
967
+ }
1179
968
  };
1180
- const create = (message, result) => {
1181
- return {
1182
- jsonrpc: Two,
1183
- id: message.id,
1184
- result: result ?? null
969
+ const mkdir = uri => {
970
+ if (!uri.endsWith(Slash)) {
971
+ uri += Slash;
972
+ }
973
+ ensureParentDir(uri);
974
+ state$2.files[uri] = {
975
+ type: Directory$1,
976
+ content: ''
1185
977
  };
1186
978
  };
1187
- const getSuccessResponse = (message, result) => {
1188
- const resultProperty = result ?? null;
1189
- return create(message, resultProperty);
1190
- };
1191
- const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
1192
- try {
1193
- const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
1194
- return getSuccessResponse(message, result);
1195
- } catch (error) {
1196
- return getErrorResponse(message, error, preparePrettyError, logError);
979
+ const remove = uri => {
980
+ const toDelete = [];
981
+ for (const key of Object.keys(state$2.files)) {
982
+ if (key.startsWith(uri)) {
983
+ toDelete.push(key);
984
+ }
985
+ }
986
+ for (const key of toDelete) {
987
+ delete state$2.files[key];
1197
988
  }
1198
989
  };
1199
- const defaultPreparePrettyError = error => {
1200
- return error;
1201
- };
1202
- const defaultLogError = () => {
1203
- // ignore
1204
- };
1205
- const defaultRequiresSocket = () => {
1206
- return false;
1207
- };
1208
- const defaultResolve = resolve;
1209
- const handleJsonRpcMessage = async (...args) => {
1210
- let message;
1211
- let ipc;
1212
- let execute;
1213
- let preparePrettyError;
1214
- let logError;
1215
- let resolve;
1216
- let requiresSocket;
1217
- if (args.length === 1) {
1218
- const arg = args[0];
1219
- message = arg.message;
1220
- ipc = arg.ipc;
1221
- execute = arg.execute;
1222
- preparePrettyError = arg.preparePrettyError || defaultPreparePrettyError;
1223
- logError = arg.logError || defaultLogError;
1224
- requiresSocket = arg.requiresSocket || defaultRequiresSocket;
1225
- resolve = arg.resolve || defaultResolve;
1226
- } else {
1227
- ipc = args[0];
1228
- message = args[1];
1229
- execute = args[2];
1230
- resolve = args[3];
1231
- preparePrettyError = args[4];
1232
- logError = args[5];
1233
- requiresSocket = args[6];
990
+ const readDirWithFileTypes = uri => {
991
+ if (!uri.endsWith(Slash)) {
992
+ uri += Slash;
1234
993
  }
1235
- if ('id' in message) {
1236
- if ('method' in message) {
1237
- const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
1238
- try {
1239
- ipc.send(response);
1240
- } catch (error) {
1241
- const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
1242
- ipc.send(errorResponse);
994
+ const dirents = [];
995
+ for (const [key, value] of Object.entries(state$2.files)) {
996
+ if (key.startsWith(uri)) {
997
+ // @ts-ignore
998
+ switch (value.type) {
999
+ case Directory$1:
1000
+ if (!key.slice(0, -1).includes(Slash, uri.length) && key !== `${uri}/` && key !== uri) {
1001
+ dirents.push({
1002
+ // @ts-ignore
1003
+ type: value.type,
1004
+ name: key.slice(uri.length, -1)
1005
+ });
1006
+ }
1007
+ break;
1008
+ case File$1:
1009
+ if (!key.includes(Slash, uri.length + 1)) {
1010
+ dirents.push({
1011
+ // @ts-ignore
1012
+ type: value.type,
1013
+ name: key.slice(uri.length)
1014
+ });
1015
+ }
1016
+ break;
1243
1017
  }
1244
- return;
1245
1018
  }
1246
- resolve(message.id, message);
1247
- return;
1248
1019
  }
1249
- if ('method' in message) {
1250
- await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
1251
- return;
1020
+ return dirents;
1021
+ };
1022
+ const getContentType = uri => {
1023
+ if (uri.endsWith('.png')) {
1024
+ return 'image/png';
1252
1025
  }
1253
- throw new JsonRpcError('unexpected message');
1026
+ if (uri.endsWith('.svg')) {
1027
+ return 'image/svg+xml';
1028
+ }
1029
+ // TODO support more
1030
+ return '';
1031
+ };
1032
+ const getBlobUrl = uri => {
1033
+ const content = readFile(uri);
1034
+ const contentType = getContentType(uri);
1035
+ const blob = new Blob([content], {
1036
+ type: contentType
1037
+ });
1038
+ const url = URL.createObjectURL(blob);
1039
+ return url;
1254
1040
  };
1255
- const invoke$2 = async (ipc, method, ...params) => {
1256
- const {
1257
- message,
1258
- promise
1259
- } = create$2(method, params);
1260
- ipc.send(message);
1261
- const responseMessage = await promise;
1262
- const result = unwrapJsonRpcResult(responseMessage);
1263
- return result;
1041
+ const getBlob = uri => {
1042
+ const content = readFile(uri);
1043
+ const blob = new Blob([content]);
1044
+ return blob;
1264
1045
  };
1265
-
1266
- const invoke$1 = (method, ...params) => {
1267
- const ipc = get$1();
1268
- return invoke$2(ipc, method, ...params);
1046
+ const chmod = () => {
1047
+ throw new Error('[memfs] chmod not implemented');
1269
1048
  };
1270
- const listen$2 = ipc => {
1271
- set$1(ipc);
1049
+ const getFiles = () => {
1050
+ return state$2.files;
1272
1051
  };
1273
1052
 
1274
- const invoke = (method, ...params) => {
1275
- return invoke$1('SearchProcess.invoke', method, ...params);
1276
- };
1053
+ const Memfs = 'memfs';
1054
+ const Html = 'html';
1055
+ const Fetch = 'fetch';
1277
1056
 
1278
- const splitLines$1 = lines => {
1279
- if (!lines) {
1280
- return [];
1057
+ const RE_PROTOCOL = /^([a-z-]+):\/\//;
1058
+ const getProtocol = uri => {
1059
+ const protocolMatch = uri.match(RE_PROTOCOL);
1060
+ if (protocolMatch) {
1061
+ return protocolMatch[1];
1281
1062
  }
1282
- return lines.split('\n');
1063
+ return '';
1283
1064
  };
1284
1065
 
1285
- // TODO create direct connection from electron to file search worker using message ports
1286
-
1287
- const searchFile$1 = async (path, value, prepare) => {
1288
- const ripGrepArgs = getFileSearchRipGrepArgs();
1289
- const options = {
1290
- ripGrepArgs,
1291
- searchPath: path,
1292
- limit: 9999999
1293
- };
1294
- const stdout = await invoke('SearchFile.searchFile', options);
1295
- const lines = splitLines$1(stdout);
1296
- if (!prepare) {
1297
- return lines;
1298
- }
1299
- const filtered = filterQuickPickItems(lines, value);
1300
- return filtered;
1066
+ const searchFile$4 = async () => {
1067
+ const files = await getFiles();
1068
+ const keys = Object.keys(files);
1069
+ return keys;
1301
1070
  };
1302
1071
 
1303
- const SearchFileRipGrep = {
1072
+ const SearchFileMemfs = {
1304
1073
  __proto__: null,
1305
- searchFile: searchFile$1
1074
+ searchFile: searchFile$4
1306
1075
  };
1307
1076
 
1308
- const getModule$1 = protocol => {
1309
- switch (protocol) {
1310
- case Memfs:
1311
- return SearchFileMemfs;
1312
- case Fetch:
1313
- return SearchFileFetch;
1314
- case Html:
1315
- return SearchFileHtml;
1316
- default:
1317
- return SearchFileRipGrep;
1077
+ const removeLeadingSlash = path => {
1078
+ if (path.startsWith('/')) {
1079
+ return path.slice(1);
1318
1080
  }
1319
- };
1320
- const searchFile = async (path, value, prepare, assetDir) => {
1321
- const protocol = getProtocol(path);
1322
- // TODO call different providers depending on protocol
1323
- const module = await getModule$1(protocol);
1324
- const result = await module.searchFile(path, value, prepare, assetDir);
1325
- return result;
1081
+ return path;
1326
1082
  };
1327
1083
 
1328
- const commandMap = {
1329
- 'FileSystemFetch.chmod': chmod$1,
1330
- 'FileSystemFetch.getBlob': getBlob$1,
1331
- 'FileSystemFetch.mkdir': mkdir$1,
1332
- 'FileSystemFetch.readDirWithFileTypes': readDirWithFileTypes$1,
1333
- 'FileSystemFetch.readFile': readFile$1,
1334
- 'FileSystemFetch.remove': remove$2,
1335
- 'FileSystemFetch.writeFile': writeFile$1,
1336
- 'FileSystemMemory.chmod': chmod,
1337
- 'FileSystemMemory.getBlob': getBlob,
1338
- 'FileSystemMemory.getBlobUrl': getBlobUrl,
1339
- 'FileSystemMemory.getFiles': getFiles,
1340
- 'FileSystemMemory.mkdir': mkdir,
1341
- 'FileSystemMemory.readDirWithFileTypes': readDirWithFileTypes,
1342
- 'FileSystemMemory.readFile': readFile,
1343
- 'FileSystemMemory.remove': remove$1,
1344
- 'FileSystemMemory.writeFile': writeFile,
1345
- 'SearchFile.searchFile': searchFile,
1346
- 'SearchFile.searchFileWithFetch': searchFile$3,
1347
- 'SearchFile.searchFileWithHtml': searchFile$2,
1348
- 'SearchFile.searchFileWithRipGrep': searchFile$1
1084
+ // TODO simplify code
1085
+ // 1. don't have playground prefix in fileMap json
1086
+ // 2. remove code here that removes the prefix
1087
+ const searchFile$3 = async path => {
1088
+ const fileList = await getJson(fileMapUrl);
1089
+ const result = fileList.map(removeLeadingSlash);
1090
+ const prefixLength = path.length - 'file:///'.length;
1091
+ const final = [];
1092
+ for (const item of result) {
1093
+ final.push(item.slice(prefixLength));
1094
+ }
1095
+ return final;
1349
1096
  };
1350
1097
 
1351
- const requiresSocket = () => {
1352
- return false;
1353
- };
1354
- const preparePrettyError = error => {
1355
- return error;
1098
+ const SearchFileFetch = {
1099
+ __proto__: null,
1100
+ searchFile: searchFile$3
1356
1101
  };
1357
- const logError = () => {
1358
- // handled by renderer worker
1102
+
1103
+ const Directory = 'directory';
1104
+ const File = 'file';
1105
+
1106
+ // based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
1107
+
1108
+ const fromAsync = async asyncIterable => {
1109
+ const children = [];
1110
+ for await (const value of asyncIterable) {
1111
+ children.push(value);
1112
+ }
1113
+ return children;
1359
1114
  };
1360
- const handleMessage = event => {
1361
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
1115
+
1116
+ /**
1117
+ * Do not use directly, use FileSystemHtml.getChildHandles
1118
+ * instead which prompts for the required permission to
1119
+ * retrieve the child handles
1120
+ *
1121
+ */
1122
+ const getChildHandles = async handle => {
1123
+ // @ts-ignore
1124
+ const handles = await fromAsync(handle.values());
1125
+ return handles;
1362
1126
  };
1363
1127
 
1364
- const handleIpc = ipc => {
1365
- ipc.addEventListener('message', handleMessage);
1128
+ const dirname = (pathSeparator, path) => {
1129
+ const index = path.lastIndexOf(pathSeparator);
1130
+ if (index === -1) {
1131
+ return path;
1132
+ }
1133
+ return path.slice(0, index);
1366
1134
  };
1367
1135
 
1368
- const MessagePort$1 = 1;
1369
- const ModuleWorker = 2;
1370
- const ReferencePort = 3;
1371
- const ModuleWorkerAndMessagePort = 8;
1372
- const Auto = () => {
1373
- // @ts-ignore
1374
- if (globalThis.acceptPort) {
1375
- return MessagePort$1;
1136
+ const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
1137
+ let idbProxyableTypes;
1138
+ let cursorAdvanceMethods;
1139
+ // This is a function to prevent it throwing up in node environments.
1140
+ function getIdbProxyableTypes() {
1141
+ return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
1142
+ }
1143
+ // This is a function to prevent it throwing up in node environments.
1144
+ function getCursorAdvanceMethods() {
1145
+ return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
1146
+ }
1147
+ const transactionDoneMap = new WeakMap();
1148
+ const transformCache = new WeakMap();
1149
+ const reverseTransformCache = new WeakMap();
1150
+ function promisifyRequest(request) {
1151
+ const promise = new Promise((resolve, reject) => {
1152
+ const unlisten = () => {
1153
+ request.removeEventListener('success', success);
1154
+ request.removeEventListener('error', error);
1155
+ };
1156
+ const success = () => {
1157
+ resolve(wrap(request.result));
1158
+ unlisten();
1159
+ };
1160
+ const error = () => {
1161
+ reject(request.error);
1162
+ unlisten();
1163
+ };
1164
+ request.addEventListener('success', success);
1165
+ request.addEventListener('error', error);
1166
+ });
1167
+ // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This
1168
+ // is because we create many promises from a single IDBRequest.
1169
+ reverseTransformCache.set(promise, request);
1170
+ return promise;
1171
+ }
1172
+ function cacheDonePromiseForTransaction(tx) {
1173
+ // Early bail if we've already created a done promise for this transaction.
1174
+ if (transactionDoneMap.has(tx)) return;
1175
+ const done = new Promise((resolve, reject) => {
1176
+ const unlisten = () => {
1177
+ tx.removeEventListener('complete', complete);
1178
+ tx.removeEventListener('error', error);
1179
+ tx.removeEventListener('abort', error);
1180
+ };
1181
+ const complete = () => {
1182
+ resolve();
1183
+ unlisten();
1184
+ };
1185
+ const error = () => {
1186
+ reject(tx.error || new DOMException('AbortError', 'AbortError'));
1187
+ unlisten();
1188
+ };
1189
+ tx.addEventListener('complete', complete);
1190
+ tx.addEventListener('error', error);
1191
+ tx.addEventListener('abort', error);
1192
+ });
1193
+ // Cache it for later retrieval.
1194
+ transactionDoneMap.set(tx, done);
1195
+ }
1196
+ let idbProxyTraps = {
1197
+ get(target, prop, receiver) {
1198
+ if (target instanceof IDBTransaction) {
1199
+ // Special handling for transaction.done.
1200
+ if (prop === 'done') return transactionDoneMap.get(target);
1201
+ // Make tx.store return the only store in the transaction, or undefined if there are many.
1202
+ if (prop === 'store') {
1203
+ return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
1204
+ }
1205
+ }
1206
+ // Else transform whatever we get back.
1207
+ return wrap(target[prop]);
1208
+ },
1209
+ set(target, prop, value) {
1210
+ target[prop] = value;
1211
+ return true;
1212
+ },
1213
+ has(target, prop) {
1214
+ if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
1215
+ return true;
1216
+ }
1217
+ return prop in target;
1376
1218
  }
1377
- // @ts-ignore
1378
- if (globalThis.acceptReferencePort) {
1379
- return ReferencePort;
1219
+ };
1220
+ function replaceTraps(callback) {
1221
+ idbProxyTraps = callback(idbProxyTraps);
1222
+ }
1223
+ function wrapFunction(func) {
1224
+ // Due to expected object equality (which is enforced by the caching in `wrap`), we
1225
+ // only create one new func per func.
1226
+ // Cursor methods are special, as the behaviour is a little more different to standard IDB. In
1227
+ // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
1228
+ // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
1229
+ // with real promises, so each advance methods returns a new promise for the cursor object, or
1230
+ // undefined if the end of the cursor has been reached.
1231
+ if (getCursorAdvanceMethods().includes(func)) {
1232
+ return function (...args) {
1233
+ // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
1234
+ // the original object.
1235
+ func.apply(unwrap(this), args);
1236
+ return wrap(this.request);
1237
+ };
1238
+ }
1239
+ return function (...args) {
1240
+ // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
1241
+ // the original object.
1242
+ return wrap(func.apply(unwrap(this), args));
1243
+ };
1244
+ }
1245
+ function transformCachableValue(value) {
1246
+ if (typeof value === 'function') return wrapFunction(value);
1247
+ // This doesn't return, it just creates a 'done' promise for the transaction,
1248
+ // which is later returned for transaction.done (see idbObjectHandler).
1249
+ if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
1250
+ if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
1251
+ // Return the same value back if we're not going to transform it.
1252
+ return value;
1253
+ }
1254
+ function wrap(value) {
1255
+ // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
1256
+ // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
1257
+ if (value instanceof IDBRequest) return promisifyRequest(value);
1258
+ // If we've already transformed this value before, reuse the transformed value.
1259
+ // This is faster, but it also provides object equality.
1260
+ if (transformCache.has(value)) return transformCache.get(value);
1261
+ const newValue = transformCachableValue(value);
1262
+ // Not all types are transformed.
1263
+ // These may be primitive types, so they can't be WeakMap keys.
1264
+ if (newValue !== value) {
1265
+ transformCache.set(value, newValue);
1266
+ reverseTransformCache.set(newValue, value);
1380
1267
  }
1381
- return ModuleWorkerAndMessagePort;
1382
- };
1268
+ return newValue;
1269
+ }
1270
+ const unwrap = value => reverseTransformCache.get(value);
1383
1271
 
1384
- const getData$1 = event => {
1385
- return event.data;
1386
- };
1387
- const walkValue = (value, transferrables, isTransferrable) => {
1388
- if (!value) {
1389
- return;
1272
+ /**
1273
+ * Open a database.
1274
+ *
1275
+ * @param name Name of the database.
1276
+ * @param version Schema version.
1277
+ * @param callbacks Additional callbacks.
1278
+ */
1279
+ function openDB(name, version, {
1280
+ blocked,
1281
+ upgrade,
1282
+ blocking,
1283
+ terminated
1284
+ } = {}) {
1285
+ const request = indexedDB.open(name, version);
1286
+ const openPromise = wrap(request);
1287
+ if (upgrade) {
1288
+ request.addEventListener('upgradeneeded', event => {
1289
+ upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
1290
+ });
1390
1291
  }
1391
- if (isTransferrable(value)) {
1392
- transferrables.push(value);
1393
- return;
1292
+ if (blocked) {
1293
+ request.addEventListener('blocked', event => blocked(
1294
+ // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
1295
+ event.oldVersion, event.newVersion, event));
1394
1296
  }
1395
- if (Array.isArray(value)) {
1396
- for (const item of value) {
1397
- walkValue(item, transferrables, isTransferrable);
1297
+ openPromise.then(db => {
1298
+ if (terminated) db.addEventListener('close', () => terminated());
1299
+ if (blocking) {
1300
+ db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
1398
1301
  }
1302
+ }).catch(() => {});
1303
+ return openPromise;
1304
+ }
1305
+ const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
1306
+ const writeMethods = ['put', 'add', 'delete', 'clear'];
1307
+ const cachedMethods = new Map();
1308
+ function getMethod(target, prop) {
1309
+ if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
1399
1310
  return;
1400
1311
  }
1401
- if (typeof value === 'object') {
1402
- for (const property of Object.values(value)) {
1403
- walkValue(property, transferrables, isTransferrable);
1404
- }
1312
+ if (cachedMethods.get(prop)) return cachedMethods.get(prop);
1313
+ const targetFuncName = prop.replace(/FromIndex$/, '');
1314
+ const useIndex = prop !== targetFuncName;
1315
+ const isWrite = writeMethods.includes(targetFuncName);
1316
+ if (
1317
+ // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
1318
+ !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
1405
1319
  return;
1406
1320
  }
1407
- };
1408
- const isMessagePort = value => {
1409
- return value && value instanceof MessagePort;
1410
- };
1411
- const isMessagePortMain = value => {
1412
- return value && value.constructor && value.constructor.name === 'MessagePortMain';
1413
- };
1414
- const isOffscreenCanvas = value => {
1415
- return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
1416
- };
1417
- const isInstanceOf = (value, constructorName) => {
1418
- return value?.constructor?.name === constructorName;
1419
- };
1420
- const isSocket = value => {
1421
- return isInstanceOf(value, 'Socket');
1422
- };
1423
- const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
1424
- const isTransferrable = value => {
1425
- for (const fn of transferrables) {
1426
- if (fn(value)) {
1427
- return true;
1321
+ const method = async function (storeName, ...args) {
1322
+ // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
1323
+ const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
1324
+ let target = tx.store;
1325
+ if (useIndex) target = target.index(args.shift());
1326
+ // Must reject if op rejects.
1327
+ // If it's a write operation, must reject if tx.done rejects.
1328
+ // Must reject with op rejection first.
1329
+ // Must resolve with op value.
1330
+ // Must handle both promises (no unhandled rejections)
1331
+ return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
1332
+ };
1333
+ cachedMethods.set(prop, method);
1334
+ return method;
1335
+ }
1336
+ replaceTraps(oldTraps => ({
1337
+ ...oldTraps,
1338
+ get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
1339
+ has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
1340
+ }));
1341
+ const advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];
1342
+ const methodMap = {};
1343
+ const advanceResults = new WeakMap();
1344
+ const ittrProxiedCursorToOriginalProxy = new WeakMap();
1345
+ const cursorIteratorTraps = {
1346
+ get(target, prop) {
1347
+ if (!advanceMethodProps.includes(prop)) return target[prop];
1348
+ let cachedFunc = methodMap[prop];
1349
+ if (!cachedFunc) {
1350
+ cachedFunc = methodMap[prop] = function (...args) {
1351
+ advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
1352
+ };
1428
1353
  }
1354
+ return cachedFunc;
1429
1355
  }
1430
- return false;
1431
- };
1432
- const getTransferrables = value => {
1433
- const transferrables = [];
1434
- walkValue(value, transferrables, isTransferrable);
1435
- return transferrables;
1436
- };
1437
- const attachEvents = that => {
1438
- const handleMessage = (...args) => {
1439
- const data = that.getData(...args);
1440
- that.dispatchEvent(new MessageEvent('message', {
1441
- data
1442
- }));
1443
- };
1444
- that.onMessage(handleMessage);
1445
- const handleClose = event => {
1446
- that.dispatchEvent(new Event('close'));
1447
- };
1448
- that.onClose(handleClose);
1449
1356
  };
1450
- class Ipc extends EventTarget {
1451
- constructor(rawIpc) {
1452
- super();
1453
- this._rawIpc = rawIpc;
1454
- attachEvents(this);
1357
+ async function* iterate(...args) {
1358
+ // tslint:disable-next-line:no-this-assignment
1359
+ let cursor = this;
1360
+ if (!(cursor instanceof IDBCursor)) {
1361
+ cursor = await cursor.openCursor(...args);
1362
+ }
1363
+ if (!cursor) return;
1364
+ cursor = cursor;
1365
+ const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
1366
+ ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
1367
+ // Map this double-proxy back to the original, so other cursor methods work.
1368
+ reverseTransformCache.set(proxiedCursor, unwrap(cursor));
1369
+ while (cursor) {
1370
+ yield proxiedCursor;
1371
+ // If one of the advancing methods was not called, call continue().
1372
+ cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
1373
+ advanceResults.delete(proxiedCursor);
1455
1374
  }
1456
1375
  }
1457
- const readyMessage = 'ready';
1458
- const listen$4 = () => {
1459
- // @ts-ignore
1460
- if (typeof WorkerGlobalScope === 'undefined') {
1461
- throw new TypeError('module is not in web worker scope');
1376
+ function isIteratorProp(target, prop) {
1377
+ return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
1378
+ }
1379
+ replaceTraps(oldTraps => ({
1380
+ ...oldTraps,
1381
+ get(target, prop, receiver) {
1382
+ if (isIteratorProp(target, prop)) return iterate;
1383
+ return oldTraps.get(target, prop, receiver);
1384
+ },
1385
+ has(target, prop) {
1386
+ return isIteratorProp(target, prop) || oldTraps.has(target, prop);
1462
1387
  }
1463
- return globalThis;
1388
+ }));
1389
+
1390
+ const state$1 = {
1391
+ dbVersion: 1};
1392
+
1393
+ // TODO high memory usage in idb because of transactionDoneMap
1394
+
1395
+ const getHandleDb = async () => {
1396
+ // @ts-ignore
1397
+ const db = await openDB('handle', state$1.dbVersion, {
1398
+ async upgrade(db) {
1399
+ if (!db.objectStoreNames.contains('file-handles-store')) {
1400
+ await db.createObjectStore('file-handles-store', {});
1401
+ }
1402
+ }
1403
+ });
1404
+ return db;
1464
1405
  };
1465
- const signal$3 = global => {
1466
- global.postMessage(readyMessage);
1406
+ const getHandle$1 = async uri => {
1407
+ const handleDb = await getHandleDb();
1408
+ const handle = await handleDb.get('file-handles-store', uri);
1409
+ return handle;
1467
1410
  };
1468
- class IpcChildWithModuleWorker extends Ipc {
1469
- getData(event) {
1470
- return getData$1(event);
1411
+
1412
+ const getHandle = async uri => {
1413
+ try {
1414
+ // TODO retrieve handle from state or from indexeddb
1415
+ // TODO if not found, throw error
1416
+ const handle = await getHandle$1(uri);
1417
+ return handle;
1418
+ } catch (error) {
1419
+ throw new VError(error, 'Failed to get handle');
1471
1420
  }
1472
- send(message) {
1473
- // @ts-ignore
1474
- this._rawIpc.postMessage(message);
1421
+ };
1422
+
1423
+ const getDirectoryHandle = async uri => {
1424
+ const handle = await getHandle(uri);
1425
+ if (handle) {
1426
+ return handle;
1427
+ }
1428
+ const dirname$1 = dirname('/', uri);
1429
+ if (uri === dirname$1) {
1430
+ return undefined;
1431
+ }
1432
+ return getDirectoryHandle(dirname$1);
1433
+ };
1434
+ const toIgnore = ['.git', 'node_modules', 'dist', 'dist2'];
1435
+ const searchFilesRecursively = async (all, parent, handle) => {
1436
+ const childHandles = await getChildHandles(handle);
1437
+ const promises = [];
1438
+ for (const childHandle of childHandles) {
1439
+ if (toIgnore.includes(childHandle.name)) {
1440
+ continue;
1441
+ }
1442
+ const absolutePath = parent + '/' + childHandle.name;
1443
+ switch (childHandle.kind) {
1444
+ case Directory:
1445
+ promises.push(searchFilesRecursively(all, absolutePath, childHandle));
1446
+ break;
1447
+ case File:
1448
+ all.push(absolutePath);
1449
+ break;
1450
+ }
1475
1451
  }
1476
- sendAndTransfer(message) {
1477
- const transfer = getTransferrables(message);
1452
+ await Promise.all(promises);
1453
+ };
1454
+ const searchFile$2 = async uri => {
1455
+ const path = uri.slice('html://'.length);
1456
+ const handle = await getDirectoryHandle(path);
1457
+ if (!handle) {
1478
1458
  // @ts-ignore
1479
- this._rawIpc.postMessage(message, transfer);
1459
+ throw new VError(`Folder not found ${uri}`);
1480
1460
  }
1481
- dispose() {
1482
- // ignore
1483
- }
1484
- onClose(callback) {
1485
- // ignore
1486
- }
1487
- onMessage(callback) {
1488
- this._rawIpc.addEventListener('message', callback);
1489
- }
1490
- }
1491
- const wrap$6 = global => {
1492
- return new IpcChildWithModuleWorker(global);
1461
+ const all = [];
1462
+ await searchFilesRecursively(all, '', handle);
1463
+ return all;
1493
1464
  };
1494
- const IpcChildWithModuleWorker$1 = {
1465
+
1466
+ const SearchFileHtml = {
1495
1467
  __proto__: null,
1496
- listen: listen$4,
1497
- signal: signal$3,
1498
- wrap: wrap$6
1499
- };
1500
- const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
1501
- const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
1502
- const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
1503
- const NewLine$1 = '\n';
1504
- const joinLines = lines => {
1505
- return lines.join(NewLine$1);
1506
- };
1507
- const splitLines = lines => {
1508
- return lines.split(NewLine$1);
1509
- };
1510
- const isModuleNotFoundMessage = line => {
1511
- return line.includes('[ERR_MODULE_NOT_FOUND]');
1512
- };
1513
- const getModuleNotFoundError = stderr => {
1514
- const lines = splitLines(stderr);
1515
- const messageIndex = lines.findIndex(isModuleNotFoundMessage);
1516
- const message = lines[messageIndex];
1517
- return {
1518
- message,
1519
- code: ERR_MODULE_NOT_FOUND
1520
- };
1521
- };
1522
- const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
1523
- const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
1524
- const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
1525
- const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
1526
- const RE_AT = /^\s+at/;
1527
- const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
1528
- const isUnhelpfulNativeModuleError = stderr => {
1529
- return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
1530
- };
1531
- const isMessageCodeBlockStartIndex = line => {
1532
- return RE_MESSAGE_CODE_BLOCK_START.test(line);
1468
+ searchFile: searchFile$2
1533
1469
  };
1534
- const isMessageCodeBlockEndIndex = line => {
1535
- return RE_MESSAGE_CODE_BLOCK_END.test(line);
1470
+
1471
+ const Diagonal = 1;
1472
+ const Left = 2;
1473
+
1474
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1475
+
1476
+ const createTable = size => {
1477
+ const table = [];
1478
+ for (let i = 0; i < size; i++) {
1479
+ const row = new Uint8Array(size);
1480
+ table.push(row);
1481
+ }
1482
+ return table;
1536
1483
  };
1537
- const getMessageCodeBlock = stderr => {
1538
- const lines = splitLines(stderr);
1539
- const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
1540
- const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
1541
- const relevantLines = lines.slice(startIndex, endIndex);
1542
- const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
1543
- return relevantMessage;
1484
+ const EmptyMatches = [];
1485
+ const Dash = '-';
1486
+ const Dot = '.';
1487
+ const EmptyString = '';
1488
+ const Space = ' ';
1489
+ const Underline = '_';
1490
+ const T = 't';
1491
+ const isLowerCase = char => {
1492
+ return char === char.toLowerCase();
1544
1493
  };
1545
- const getNativeModuleErrorMessage = stderr => {
1546
- const message = getMessageCodeBlock(stderr);
1547
- return {
1548
- message: `Incompatible native node module: ${message}`,
1549
- code: E_INCOMPATIBLE_NATIVE_MODULE
1550
- };
1494
+ const isUpperCase = char => {
1495
+ return char === char.toUpperCase();
1551
1496
  };
1552
- const isModulesSyntaxError = stderr => {
1553
- if (!stderr) {
1554
- return false;
1497
+
1498
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1499
+ const isGap = (columnCharBefore, columnChar) => {
1500
+ switch (columnCharBefore) {
1501
+ case Dash:
1502
+ case Underline:
1503
+ case EmptyString:
1504
+ case T:
1505
+ case Space:
1506
+ case Dot:
1507
+ return true;
1555
1508
  }
1556
- return stderr.includes('SyntaxError: Cannot use import statement outside a module');
1557
- };
1558
- const getModuleSyntaxError = () => {
1559
- return {
1560
- message: `ES Modules are not supported in electron`,
1561
- code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
1562
- };
1563
- };
1564
- const isModuleNotFoundError = stderr => {
1565
- if (!stderr) {
1566
- return false;
1509
+ if (isLowerCase(columnCharBefore) && isUpperCase(columnChar)) {
1510
+ return true;
1567
1511
  }
1568
- return stderr.includes('ERR_MODULE_NOT_FOUND');
1569
- };
1570
- const isNormalStackLine = line => {
1571
- return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
1512
+ return false;
1572
1513
  };
1573
- const getDetails = lines => {
1574
- const index = lines.findIndex(isNormalStackLine);
1575
- if (index === -1) {
1576
- return {
1577
- actualMessage: joinLines(lines),
1578
- rest: []
1579
- };
1514
+
1515
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1516
+ const getScore = (rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, isDiagonalMatch) => {
1517
+ if (rowCharLow !== columnCharLow) {
1518
+ return -1;
1580
1519
  }
1581
- let lastIndex = index - 1;
1582
- while (++lastIndex < lines.length) {
1583
- if (!isNormalStackLine(lines[lastIndex])) {
1584
- break;
1520
+ const isMatch = rowChar === columnChar;
1521
+ if (isMatch) {
1522
+ if (isDiagonalMatch) {
1523
+ return 8;
1524
+ }
1525
+ if (isGap(columnCharBefore, columnChar)) {
1526
+ return 8;
1585
1527
  }
1528
+ return 5;
1586
1529
  }
1587
- return {
1588
- actualMessage: lines[index - 1],
1589
- rest: lines.slice(index, lastIndex)
1590
- };
1591
- };
1592
- const getHelpfulChildProcessError = (stdout, stderr) => {
1593
- if (isUnhelpfulNativeModuleError(stderr)) {
1594
- return getNativeModuleErrorMessage(stderr);
1530
+ if (isGap(columnCharBefore, columnChar)) {
1531
+ return 8;
1595
1532
  }
1596
- if (isModulesSyntaxError(stderr)) {
1597
- return getModuleSyntaxError();
1533
+ return 5;
1534
+ };
1535
+
1536
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1537
+
1538
+ const isPatternInWord = (patternLow, patternPos, patternLen, wordLow, wordPos, wordLen) => {
1539
+ while (patternPos < patternLen && wordPos < wordLen) {
1540
+ if (patternLow[patternPos] === wordLow[wordPos]) {
1541
+ patternPos += 1;
1542
+ }
1543
+ wordPos += 1;
1598
1544
  }
1599
- if (isModuleNotFoundError(stderr)) {
1600
- return getModuleNotFoundError(stderr);
1545
+ return patternPos === patternLen; // pattern must be exhausted
1546
+ };
1547
+
1548
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1549
+ const traceHighlights = (table, arrows, patternLength, wordLength) => {
1550
+ let row = patternLength;
1551
+ let column = wordLength;
1552
+ const matches = [];
1553
+ while (row >= 1 && column >= 1) {
1554
+ const arrow = arrows[row][column];
1555
+ if (arrow === Left) {
1556
+ column--;
1557
+ } else if (arrow === Diagonal) {
1558
+ row--;
1559
+ column--;
1560
+ const start = column + 1;
1561
+ while (row >= 1 && column >= 1) {
1562
+ const arrow = arrows[row][column];
1563
+ if (arrow === Left) {
1564
+ break;
1565
+ }
1566
+ if (arrow === Diagonal) {
1567
+ row--;
1568
+ column--;
1569
+ }
1570
+ }
1571
+ const end = column;
1572
+ matches.unshift(end, start);
1573
+ }
1601
1574
  }
1602
- const lines = splitLines(stderr);
1603
- const {
1604
- actualMessage,
1605
- rest
1606
- } = getDetails(lines);
1607
- return {
1608
- message: `${actualMessage}`,
1609
- code: '',
1610
- stack: rest
1611
- };
1575
+ matches.unshift(table[patternLength][wordLength - 1]);
1576
+ return matches;
1612
1577
  };
1613
- const normalizeLine = line => {
1614
- if (line.startsWith('Error: ')) {
1615
- return line.slice(`Error: `.length);
1578
+
1579
+ // based on https://github.com/microsoft/vscode/blob/3059063b805ed0ac10a6d9539e213386bfcfb852/src/vs/base/common/filters.ts by Microsoft (License MIT)
1580
+ const gridSize = 128;
1581
+ const table = createTable(gridSize);
1582
+ const arrows = createTable(gridSize);
1583
+ const fuzzySearch = (pattern, word) => {
1584
+ const patternLength = Math.min(pattern.length, gridSize - 1);
1585
+ const wordLength = Math.min(word.length, gridSize - 1);
1586
+ const patternLower = pattern.toLowerCase();
1587
+ const wordLower = word.toLowerCase();
1588
+ if (!isPatternInWord(patternLower, 0, patternLength, wordLower, 0, wordLength)) {
1589
+ return EmptyMatches;
1590
+ }
1591
+ let strongMatch = false;
1592
+ for (let row = 1; row < patternLength + 1; row++) {
1593
+ const rowChar = pattern[row - 1];
1594
+ const rowCharLow = patternLower[row - 1];
1595
+ for (let column = 1; column < wordLength + 1; column++) {
1596
+ const columnChar = word[column - 1];
1597
+ const columnCharLow = wordLower[column - 1];
1598
+ const columnCharBefore = word[column - 2] || '';
1599
+ const isDiagonalMatch = arrows[row - 1][column - 1] === Diagonal;
1600
+ const score = getScore(rowCharLow, rowChar, columnCharBefore, columnCharLow, columnChar, isDiagonalMatch);
1601
+ if (row === 1 && score > 5) {
1602
+ strongMatch = true;
1603
+ }
1604
+ let diagonalScore = score + table[row - 1][column - 1];
1605
+ if (isDiagonalMatch && score !== -1) {
1606
+ diagonalScore += 2;
1607
+ }
1608
+ const leftScore = table[row][column - 1];
1609
+ if (leftScore > diagonalScore) {
1610
+ table[row][column] = leftScore;
1611
+ arrows[row][column] = Left;
1612
+ } else {
1613
+ table[row][column] = diagonalScore;
1614
+ arrows[row][column] = Diagonal;
1615
+ }
1616
+ }
1616
1617
  }
1617
- if (line.startsWith('VError: ')) {
1618
- return line.slice(`VError: `.length);
1618
+ if (!strongMatch) {
1619
+ return EmptyMatches;
1619
1620
  }
1620
- return line;
1621
+ const highlights = traceHighlights(table, arrows, patternLength, wordLength);
1622
+ return highlights;
1621
1623
  };
1622
- const getCombinedMessage = (error, message) => {
1623
- const stringifiedError = normalizeLine(`${error}`);
1624
- if (message) {
1625
- return `${message}: ${stringifiedError}`;
1626
- }
1627
- return stringifiedError;
1624
+
1625
+ const filterQuickPickItem = (pattern, word) => {
1626
+ const matches = fuzzySearch(pattern, word);
1627
+ return matches;
1628
1628
  };
1629
- const NewLine = '\n';
1630
- const getNewLineIndex = (string, startIndex = undefined) => {
1631
- return string.indexOf(NewLine, startIndex);
1629
+
1630
+ const getBaseName = path => {
1631
+ return path.slice(path.lastIndexOf('/') + 1);
1632
1632
  };
1633
- const mergeStacks = (parent, child) => {
1634
- if (!child) {
1635
- return parent;
1636
- }
1637
- const parentNewLineIndex = getNewLineIndex(parent);
1638
- const childNewLineIndex = getNewLineIndex(child);
1639
- if (childNewLineIndex === -1) {
1640
- return parent;
1641
- }
1642
- const parentFirstLine = parent.slice(0, parentNewLineIndex);
1643
- const childRest = child.slice(childNewLineIndex);
1644
- const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
1645
- if (parentFirstLine.includes(childFirstLine)) {
1646
- return parentFirstLine + childRest;
1647
- }
1648
- return child;
1633
+ const emptyMatches = [];
1634
+ const convertToPick = item => {
1635
+ return {
1636
+ pick: item,
1637
+ matches: emptyMatches
1638
+ };
1649
1639
  };
1650
- class VError extends Error {
1651
- constructor(error, message) {
1652
- const combinedMessage = getCombinedMessage(error, message);
1653
- super(combinedMessage);
1654
- this.name = 'VError';
1655
- if (error instanceof Error) {
1656
- this.stack = mergeStacks(this.stack, error.stack);
1657
- }
1658
- if (error.codeFrame) {
1659
- // @ts-ignore
1660
- this.codeFrame = error.codeFrame;
1661
- }
1662
- if (error.code) {
1663
- // @ts-ignore
1664
- this.code = error.code;
1665
- }
1640
+ const filterQuickPickItems = (items, value) => {
1641
+ if (!value) {
1642
+ return items.map(convertToPick);
1666
1643
  }
1667
- }
1668
- class IpcError extends VError {
1669
- // @ts-ignore
1670
- constructor(betterMessage, stdout = '', stderr = '') {
1671
- if (stdout || stderr) {
1672
- // @ts-ignore
1673
- const {
1674
- message,
1675
- code,
1676
- stack
1677
- } = getHelpfulChildProcessError(stdout, stderr);
1678
- const cause = new Error(message);
1679
- // @ts-ignore
1680
- cause.code = code;
1681
- cause.stack = stack;
1682
- super(cause, betterMessage);
1683
- } else {
1684
- super(betterMessage);
1644
+ const results = [];
1645
+ for (const item of items) {
1646
+ const baseName = getBaseName(item);
1647
+ const matches = filterQuickPickItem(value, baseName);
1648
+ if (matches.length > 0) {
1649
+ results.push({
1650
+ pick: item,
1651
+ matches
1652
+ });
1685
1653
  }
1686
- // @ts-ignore
1687
- this.name = 'IpcError';
1688
- // @ts-ignore
1689
- this.stdout = stdout;
1690
- // @ts-ignore
1691
- this.stderr = stderr;
1692
1654
  }
1693
- }
1694
- const withResolvers = () => {
1695
- let _resolve;
1696
- const promise = new Promise(resolve => {
1697
- _resolve = resolve;
1698
- });
1699
- return {
1700
- resolve: _resolve,
1701
- promise
1702
- };
1655
+ return results;
1703
1656
  };
1704
- const waitForFirstMessage = async port => {
1705
- const {
1706
- resolve,
1707
- promise
1708
- } = withResolvers();
1709
- port.addEventListener('message', resolve, {
1710
- once: true
1711
- });
1712
- const event = await promise;
1657
+
1658
+ const getFileSearchRipGrepArgs = () => {
1659
+ const ripGrepArgs = ['--files', '--sort-files'];
1660
+ return ripGrepArgs;
1661
+ };
1662
+
1663
+ const state = {
1664
+ rpc: undefined
1665
+ };
1666
+ const invoke$1 = (method, ...params) => {
1667
+ const rpc = state.rpc;
1713
1668
  // @ts-ignore
1714
- return event.data;
1669
+ return rpc.invoke(method, ...params);
1715
1670
  };
1716
- const listen$3 = async () => {
1717
- const parentIpcRaw = listen$4();
1718
- signal$3(parentIpcRaw);
1719
- const parentIpc = wrap$6(parentIpcRaw);
1720
- const firstMessage = await waitForFirstMessage(parentIpc);
1721
- if (firstMessage.method !== 'initialize') {
1722
- throw new IpcError('unexpected first message');
1723
- }
1724
- const type = firstMessage.params[0];
1725
- if (type === 'message-port') {
1726
- parentIpc.send({
1727
- jsonrpc: '2.0',
1728
- id: firstMessage.id,
1729
- result: null
1730
- });
1731
- parentIpc.dispose();
1732
- const port = firstMessage.params[1];
1733
- return port;
1734
- }
1735
- return globalThis;
1671
+ const setRpc = rpc => {
1672
+ state.rpc = rpc;
1736
1673
  };
1737
- class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
1738
- constructor(port) {
1739
- super(port);
1740
- }
1741
- getData(event) {
1742
- return getData$1(event);
1743
- }
1744
- send(message) {
1745
- this._rawIpc.postMessage(message);
1746
- }
1747
- sendAndTransfer(message) {
1748
- const transfer = getTransferrables(message);
1749
- this._rawIpc.postMessage(message, transfer);
1750
- }
1751
- dispose() {
1752
- if (this._rawIpc.close) {
1753
- this._rawIpc.close();
1754
- }
1755
- }
1756
- onClose(callback) {
1757
- // ignore
1674
+
1675
+ const invoke = (method, ...params) => {
1676
+ return invoke$1('SearchProcess.invoke', method, ...params);
1677
+ };
1678
+
1679
+ const splitLines = lines => {
1680
+ if (!lines) {
1681
+ return [];
1758
1682
  }
1759
- onMessage(callback) {
1760
- this._rawIpc.addEventListener('message', callback);
1761
- this._rawIpc.start();
1683
+ return lines.split('\n');
1684
+ };
1685
+
1686
+ // TODO create direct connection from electron to file search worker using message ports
1687
+
1688
+ const searchFile$1 = async (path, value, prepare) => {
1689
+ const ripGrepArgs = getFileSearchRipGrepArgs();
1690
+ const options = {
1691
+ ripGrepArgs,
1692
+ searchPath: path,
1693
+ limit: 9999999
1694
+ };
1695
+ const stdout = await invoke('SearchFile.searchFile', options);
1696
+ const lines = splitLines(stdout);
1697
+ if (!prepare) {
1698
+ return lines;
1762
1699
  }
1763
- }
1764
- const wrap$5 = port => {
1765
- return new IpcChildWithModuleWorkerAndMessagePort(port);
1700
+ const filtered = filterQuickPickItems(lines, value);
1701
+ return filtered;
1766
1702
  };
1767
- const IpcChildWithModuleWorkerAndMessagePort$1 = {
1703
+
1704
+ const SearchFileRipGrep = {
1768
1705
  __proto__: null,
1769
- listen: listen$3,
1770
- wrap: wrap$5
1706
+ searchFile: searchFile$1
1771
1707
  };
1772
1708
 
1773
- const getModule = method => {
1774
- switch (method) {
1775
- case ModuleWorker:
1776
- return IpcChildWithModuleWorker$1;
1777
- case ModuleWorkerAndMessagePort:
1778
- return IpcChildWithModuleWorkerAndMessagePort$1;
1709
+ const getModule = protocol => {
1710
+ switch (protocol) {
1711
+ case Memfs:
1712
+ return SearchFileMemfs;
1713
+ case Fetch:
1714
+ return SearchFileFetch;
1715
+ case Html:
1716
+ return SearchFileHtml;
1779
1717
  default:
1780
- throw new Error('unexpected ipc type');
1718
+ return SearchFileRipGrep;
1781
1719
  }
1782
1720
  };
1721
+ const searchFile = async (path, value, prepare, assetDir) => {
1722
+ const protocol = getProtocol(path);
1723
+ // TODO call different providers depending on protocol
1724
+ const module = await getModule(protocol);
1725
+ const result = await module.searchFile(path, value, prepare, assetDir);
1726
+ return result;
1727
+ };
1783
1728
 
1784
- const listen$1 = async ({
1785
- method
1786
- }) => {
1787
- const module = await getModule(method);
1788
- const rawIpc = await module.listen();
1789
- if (module.signal) {
1790
- module.signal(rawIpc);
1791
- }
1792
- const ipc = module.wrap(rawIpc);
1793
- return ipc;
1729
+ const commandMap = {
1730
+ 'FileSystemFetch.chmod': chmod$1,
1731
+ 'FileSystemFetch.getBlob': getBlob$1,
1732
+ 'FileSystemFetch.mkdir': mkdir$1,
1733
+ 'FileSystemFetch.readDirWithFileTypes': readDirWithFileTypes$1,
1734
+ 'FileSystemFetch.readFile': readFile$1,
1735
+ 'FileSystemFetch.remove': remove$1,
1736
+ 'FileSystemFetch.writeFile': writeFile$1,
1737
+ 'FileSystemMemory.chmod': chmod,
1738
+ 'FileSystemMemory.getBlob': getBlob,
1739
+ 'FileSystemMemory.getBlobUrl': getBlobUrl,
1740
+ 'FileSystemMemory.getFiles': getFiles,
1741
+ 'FileSystemMemory.mkdir': mkdir,
1742
+ 'FileSystemMemory.readDirWithFileTypes': readDirWithFileTypes,
1743
+ 'FileSystemMemory.readFile': readFile,
1744
+ 'FileSystemMemory.remove': remove,
1745
+ 'FileSystemMemory.writeFile': writeFile,
1746
+ 'SearchFile.searchFile': searchFile,
1747
+ 'SearchFile.searchFileWithFetch': searchFile$3,
1748
+ 'SearchFile.searchFileWithHtml': searchFile$2,
1749
+ 'SearchFile.searchFileWithRipGrep': searchFile$1
1794
1750
  };
1795
1751
 
1796
1752
  const listen = async () => {
1797
- register(commandMap);
1798
- const ipc = await listen$1({
1799
- method: Auto()
1753
+ const rpc = await WebWorkerRpcClient.create({
1754
+ commandMap: commandMap
1800
1755
  });
1801
- handleIpc(ipc);
1802
- listen$2(ipc);
1756
+ setRpc(rpc);
1803
1757
  };
1804
1758
 
1805
1759
  const main = async () => {