@lvce-editor/extension-search-view 1.4.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.
- package/dist/extensionSearchViewWorkerMain.js +1246 -1123
- package/package.json +5 -6
|
@@ -1,73 +1,58 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
const getCommand = key => {
|
|
6
|
-
return commands[key];
|
|
7
|
-
};
|
|
8
|
-
const execute = (command, ...args) => {
|
|
9
|
-
const fn = getCommand(command);
|
|
10
|
-
if (!fn) {
|
|
11
|
-
throw new Error(`command not found ${command}`);
|
|
1
|
+
const normalizeLine = line => {
|
|
2
|
+
if (line.startsWith('Error: ')) {
|
|
3
|
+
return line.slice('Error: '.length);
|
|
12
4
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const handleError = async (error, notify = true, prefix = '') => {
|
|
17
|
-
console.error(error);
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const emptyObject = {};
|
|
21
|
-
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
22
|
-
const i18nString = (key, placeholders = emptyObject) => {
|
|
23
|
-
if (placeholders === emptyObject) {
|
|
24
|
-
return key;
|
|
5
|
+
if (line.startsWith('VError: ')) {
|
|
6
|
+
return line.slice('VError: '.length);
|
|
25
7
|
}
|
|
26
|
-
|
|
27
|
-
// @ts-ignore
|
|
28
|
-
return placeholders[rest];
|
|
29
|
-
};
|
|
30
|
-
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @enum {string}
|
|
35
|
-
*/
|
|
36
|
-
const UiStrings = {
|
|
37
|
-
NoExtensionsFound: 'No extensions found.',
|
|
38
|
-
Filter: 'Filter',
|
|
39
|
-
Refresh: 'Refresh',
|
|
40
|
-
ClearExtensionSearchResults: 'Clear extension search results',
|
|
41
|
-
Enable: 'Enable',
|
|
42
|
-
Disable: 'Disable',
|
|
43
|
-
Uninstall: 'Uninstall',
|
|
44
|
-
InstallAnotherVersion: 'Install Another Version',
|
|
45
|
-
SearchExtensionsInMarketplace: 'Search Extensions in Marketplace',
|
|
46
|
-
ViewsAndMoreActions: 'Views and more Actions...',
|
|
47
|
-
Extensions: 'Extensions',
|
|
48
|
-
Installed: 'Installed'
|
|
49
|
-
};
|
|
50
|
-
const noExtensionsFound = () => {
|
|
51
|
-
return i18nString(UiStrings.NoExtensionsFound);
|
|
52
|
-
};
|
|
53
|
-
const filter = () => {
|
|
54
|
-
return i18nString(UiStrings.Filter);
|
|
55
|
-
};
|
|
56
|
-
const extensions = () => {
|
|
57
|
-
return i18nString(UiStrings.Extensions);
|
|
8
|
+
return line;
|
|
58
9
|
};
|
|
59
|
-
const
|
|
60
|
-
|
|
10
|
+
const getCombinedMessage = (error, message) => {
|
|
11
|
+
const stringifiedError = normalizeLine(`${error}`);
|
|
12
|
+
if (message) {
|
|
13
|
+
return `${message}: ${stringifiedError}`;
|
|
14
|
+
}
|
|
15
|
+
return stringifiedError;
|
|
61
16
|
};
|
|
62
|
-
const
|
|
63
|
-
|
|
17
|
+
const NewLine$2 = '\n';
|
|
18
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
19
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
64
20
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
21
|
+
const mergeStacks = (parent, child) => {
|
|
22
|
+
if (!child) {
|
|
23
|
+
return parent;
|
|
24
|
+
}
|
|
25
|
+
const parentNewLineIndex = getNewLineIndex$1(parent);
|
|
26
|
+
const childNewLineIndex = getNewLineIndex$1(child);
|
|
27
|
+
if (childNewLineIndex === -1) {
|
|
28
|
+
return parent;
|
|
29
|
+
}
|
|
30
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
31
|
+
const childRest = child.slice(childNewLineIndex);
|
|
32
|
+
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
33
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
34
|
+
return parentFirstLine + childRest;
|
|
35
|
+
}
|
|
36
|
+
return child;
|
|
70
37
|
};
|
|
38
|
+
class VError extends Error {
|
|
39
|
+
constructor(error, message) {
|
|
40
|
+
const combinedMessage = getCombinedMessage(error, message);
|
|
41
|
+
super(combinedMessage);
|
|
42
|
+
this.name = 'VError';
|
|
43
|
+
if (error instanceof Error) {
|
|
44
|
+
this.stack = mergeStacks(this.stack, error.stack);
|
|
45
|
+
}
|
|
46
|
+
if (error.codeFrame) {
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
this.codeFrame = error.codeFrame;
|
|
49
|
+
}
|
|
50
|
+
if (error.code) {
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
this.code = error.code;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
71
56
|
|
|
72
57
|
class AssertionError extends Error {
|
|
73
58
|
constructor(message) {
|
|
@@ -104,759 +89,512 @@ const number = value => {
|
|
|
104
89
|
}
|
|
105
90
|
};
|
|
106
91
|
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
number(itemHeight);
|
|
110
|
-
number(maxHeight);
|
|
111
|
-
if (itemsLength === 0) {
|
|
112
|
-
return itemHeight;
|
|
113
|
-
}
|
|
114
|
-
const totalHeight = itemsLength * itemHeight;
|
|
115
|
-
return Math.min(totalHeight, maxHeight);
|
|
92
|
+
const isMessagePort = value => {
|
|
93
|
+
return value && value instanceof MessagePort;
|
|
116
94
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// of visible items needed, e.g. when not scrolled 5 items with
|
|
120
|
-
// 20px fill 100px but when scrolled 6 items are needed
|
|
121
|
-
const getNumberOfVisibleItems = (listHeight, itemHeight) => {
|
|
122
|
-
return Math.ceil(listHeight / itemHeight) + 1;
|
|
95
|
+
const isMessagePortMain = value => {
|
|
96
|
+
return value && value.constructor && value.constructor.name === 'MessagePortMain';
|
|
123
97
|
};
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
*
|
|
127
|
-
* @param {number} size
|
|
128
|
-
* @param {number} contentSize
|
|
129
|
-
* @param {number} minimumSliderSize
|
|
130
|
-
* @returns
|
|
131
|
-
*/
|
|
132
|
-
const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
|
|
133
|
-
if (size >= contentSize) {
|
|
134
|
-
return 0;
|
|
135
|
-
}
|
|
136
|
-
return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
|
|
98
|
+
const isOffscreenCanvas = value => {
|
|
99
|
+
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
|
|
137
100
|
};
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
return scrollBarOffset;
|
|
101
|
+
const isInstanceOf = (value, constructorName) => {
|
|
102
|
+
return value?.constructor?.name === constructorName;
|
|
141
103
|
};
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
const Installed = '@installed';
|
|
145
|
-
const Enabled = '@enabled';
|
|
146
|
-
const Disabled = '@disabled';
|
|
147
|
-
const Builtin = '@builtin';
|
|
148
|
-
const Sort = '@sort';
|
|
149
|
-
const Id = '@id';
|
|
150
|
-
const Outdated = '@outdated';
|
|
151
|
-
|
|
152
|
-
const RE_PARAM = /@\w+/g;
|
|
153
|
-
|
|
154
|
-
// TODO test sorting and filtering
|
|
155
|
-
const parseValue = value => {
|
|
156
|
-
const parameters = Object.create(null);
|
|
157
|
-
// TODO this is not very functional code (assignment)
|
|
158
|
-
const replaced = value.replaceAll(RE_PARAM, (match, by, order) => {
|
|
159
|
-
if (match.startsWith(Installed)) {
|
|
160
|
-
parameters.installed = true;
|
|
161
|
-
}
|
|
162
|
-
if (match.startsWith(Enabled)) {
|
|
163
|
-
parameters.enabled = true;
|
|
164
|
-
}
|
|
165
|
-
if (match.startsWith(Disabled)) {
|
|
166
|
-
parameters.disabled = true;
|
|
167
|
-
}
|
|
168
|
-
if (match.startsWith(Builtin)) {
|
|
169
|
-
parameters.builtin = true;
|
|
170
|
-
}
|
|
171
|
-
if (match.startsWith(Sort)) {
|
|
172
|
-
// TODO
|
|
173
|
-
parameters.sort = 'installs';
|
|
174
|
-
}
|
|
175
|
-
if (match.startsWith(Id)) {
|
|
176
|
-
// TODO
|
|
177
|
-
parameters.id = 'abc';
|
|
178
|
-
}
|
|
179
|
-
if (match.startsWith(Outdated)) {
|
|
180
|
-
parameters.outdated = true;
|
|
181
|
-
}
|
|
182
|
-
return '';
|
|
183
|
-
});
|
|
184
|
-
const isLocal = parameters.enabled || parameters.builtin || parameters.disabled || parameters.outdated || parameters.installed;
|
|
185
|
-
return {
|
|
186
|
-
query: replaced,
|
|
187
|
-
...parameters,
|
|
188
|
-
isLocal
|
|
189
|
-
};
|
|
104
|
+
const isSocket = value => {
|
|
105
|
+
return isInstanceOf(value, 'Socket');
|
|
190
106
|
};
|
|
191
|
-
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const Test = 4;
|
|
198
|
-
|
|
199
|
-
// TODO treeshake this function out
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* @returns {number}
|
|
203
|
-
*/
|
|
204
|
-
const getPlatform = () => {
|
|
205
|
-
// @ts-ignore
|
|
206
|
-
if (typeof PLATFORM !== 'undefined') {
|
|
207
|
-
// @ts-ignore
|
|
208
|
-
return PLATFORM;
|
|
107
|
+
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
108
|
+
const isTransferrable = value => {
|
|
109
|
+
for (const fn of transferrables) {
|
|
110
|
+
if (fn(value)) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
209
113
|
}
|
|
210
|
-
|
|
211
|
-
|
|
114
|
+
return false;
|
|
115
|
+
};
|
|
116
|
+
const walkValue = (value, transferrables, isTransferrable) => {
|
|
117
|
+
if (!value) {
|
|
118
|
+
return;
|
|
212
119
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return
|
|
120
|
+
if (isTransferrable(value)) {
|
|
121
|
+
transferrables.push(value);
|
|
122
|
+
return;
|
|
216
123
|
}
|
|
217
|
-
if (
|
|
218
|
-
|
|
124
|
+
if (Array.isArray(value)) {
|
|
125
|
+
for (const item of value) {
|
|
126
|
+
walkValue(item, transferrables, isTransferrable);
|
|
127
|
+
}
|
|
128
|
+
return;
|
|
219
129
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const getRemoteUrl = extension => {
|
|
225
|
-
if (platform === Remote || platform === Electron) {
|
|
226
|
-
if (extension.builtin) {
|
|
227
|
-
return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
|
|
130
|
+
if (typeof value === 'object') {
|
|
131
|
+
for (const property of Object.values(value)) {
|
|
132
|
+
walkValue(property, transferrables, isTransferrable);
|
|
228
133
|
}
|
|
229
|
-
return
|
|
134
|
+
return;
|
|
230
135
|
}
|
|
231
|
-
return '';
|
|
232
136
|
};
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const isLanguageBasicsExtension = extension => {
|
|
239
|
-
return extension.name && extension.name.startsWith('Language Basics');
|
|
137
|
+
const getTransferrables = value => {
|
|
138
|
+
const transferrables = [];
|
|
139
|
+
walkValue(value, transferrables, isTransferrable);
|
|
140
|
+
return transferrables;
|
|
240
141
|
};
|
|
241
|
-
const
|
|
242
|
-
|
|
142
|
+
const attachEvents = that => {
|
|
143
|
+
const handleMessage = (...args) => {
|
|
144
|
+
const data = that.getData(...args);
|
|
145
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
146
|
+
data
|
|
147
|
+
}));
|
|
148
|
+
};
|
|
149
|
+
that.onMessage(handleMessage);
|
|
150
|
+
const handleClose = event => {
|
|
151
|
+
that.dispatchEvent(new Event('close'));
|
|
152
|
+
};
|
|
153
|
+
that.onClose(handleClose);
|
|
243
154
|
};
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (isLanguageBasicsExtension(extension)) {
|
|
250
|
-
return ExtensionLanguageBasics;
|
|
251
|
-
}
|
|
252
|
-
if (isThemeExtension(extension)) {
|
|
253
|
-
return ExtensionTheme;
|
|
254
|
-
}
|
|
255
|
-
return ExtensionDefaultIcon;
|
|
155
|
+
class Ipc extends EventTarget {
|
|
156
|
+
constructor(rawIpc) {
|
|
157
|
+
super();
|
|
158
|
+
this._rawIpc = rawIpc;
|
|
159
|
+
attachEvents(this);
|
|
256
160
|
}
|
|
257
|
-
|
|
161
|
+
}
|
|
162
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
163
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
164
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
165
|
+
const NewLine$1 = '\n';
|
|
166
|
+
const joinLines$1 = lines => {
|
|
167
|
+
return lines.join(NewLine$1);
|
|
258
168
|
};
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (!extension || !extension.id) {
|
|
264
|
-
return 'n/a';
|
|
265
|
-
}
|
|
266
|
-
// TODO handle case when id is not of type string -> should not crash application
|
|
267
|
-
const match = extension.id.match(RE_PUBLISHER);
|
|
268
|
-
if (!match) {
|
|
269
|
-
return 'n/a';
|
|
270
|
-
}
|
|
271
|
-
return match[0];
|
|
169
|
+
const RE_AT = /^\s+at/;
|
|
170
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
171
|
+
const isNormalStackLine = line => {
|
|
172
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
272
173
|
};
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
174
|
+
const getDetails = lines => {
|
|
175
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
176
|
+
if (index === -1) {
|
|
177
|
+
return {
|
|
178
|
+
actualMessage: joinLines$1(lines),
|
|
179
|
+
rest: []
|
|
180
|
+
};
|
|
276
181
|
}
|
|
277
|
-
|
|
278
|
-
|
|
182
|
+
let lastIndex = index - 1;
|
|
183
|
+
while (++lastIndex < lines.length) {
|
|
184
|
+
if (!isNormalStackLine(lines[lastIndex])) {
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
279
187
|
}
|
|
280
|
-
return
|
|
188
|
+
return {
|
|
189
|
+
actualMessage: lines[index - 1],
|
|
190
|
+
rest: lines.slice(index, lastIndex)
|
|
191
|
+
};
|
|
281
192
|
};
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
return 'n/a';
|
|
285
|
-
}
|
|
286
|
-
return extension.description;
|
|
193
|
+
const splitLines$1 = lines => {
|
|
194
|
+
return lines.split(NewLine$1);
|
|
287
195
|
};
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return extension.id;
|
|
196
|
+
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
197
|
+
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
198
|
+
const isMessageCodeBlockStartIndex = line => {
|
|
199
|
+
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
293
200
|
};
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (extension && typeof extension.name === 'string') {
|
|
297
|
-
const extensionNameLower = extension.name.toLowerCase();
|
|
298
|
-
return extensionNameLower.includes(parsedValue.query);
|
|
299
|
-
}
|
|
300
|
-
if (extension && typeof extension.id === 'string') {
|
|
301
|
-
const extensionIdLower = extension.id.toLowerCase();
|
|
302
|
-
return extensionIdLower.includes(parsedValue.query);
|
|
303
|
-
}
|
|
304
|
-
return false;
|
|
201
|
+
const isMessageCodeBlockEndIndex = line => {
|
|
202
|
+
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
305
203
|
};
|
|
306
|
-
|
|
307
|
-
const
|
|
308
|
-
|
|
204
|
+
const getMessageCodeBlock = stderr => {
|
|
205
|
+
const lines = splitLines$1(stderr);
|
|
206
|
+
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
207
|
+
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
208
|
+
const relevantLines = lines.slice(startIndex, endIndex);
|
|
209
|
+
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
210
|
+
return relevantMessage;
|
|
309
211
|
};
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return extensionA.name.localeCompare(extensionB.name) || extensionA.id.localeCompare(extensionB.id);
|
|
212
|
+
const isModuleNotFoundMessage = line => {
|
|
213
|
+
return line.includes('[ERR_MODULE_NOT_FOUND]');
|
|
313
214
|
};
|
|
314
|
-
|
|
315
|
-
const
|
|
316
|
-
|
|
215
|
+
const getModuleNotFoundError = stderr => {
|
|
216
|
+
const lines = splitLines$1(stderr);
|
|
217
|
+
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
218
|
+
const message = lines[messageIndex];
|
|
219
|
+
return {
|
|
220
|
+
message,
|
|
221
|
+
code: ERR_MODULE_NOT_FOUND
|
|
222
|
+
};
|
|
317
223
|
};
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
for (const extension of extensions) {
|
|
322
|
-
if (matchesParsedValue(extension, parsedValue)) {
|
|
323
|
-
filteredExtensions.push({
|
|
324
|
-
name: getName(extension),
|
|
325
|
-
id: getId(extension),
|
|
326
|
-
publisher: getPublisher(extension),
|
|
327
|
-
icon: getIcon(extension),
|
|
328
|
-
description: getDescription(extension)
|
|
329
|
-
});
|
|
330
|
-
}
|
|
224
|
+
const isModuleNotFoundError = stderr => {
|
|
225
|
+
if (!stderr) {
|
|
226
|
+
return false;
|
|
331
227
|
}
|
|
332
|
-
|
|
333
|
-
return sortedExtensions;
|
|
228
|
+
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
334
229
|
};
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
return line.slice('Error: '.length);
|
|
339
|
-
}
|
|
340
|
-
if (line.startsWith('VError: ')) {
|
|
341
|
-
return line.slice('VError: '.length);
|
|
230
|
+
const isModulesSyntaxError = stderr => {
|
|
231
|
+
if (!stderr) {
|
|
232
|
+
return false;
|
|
342
233
|
}
|
|
343
|
-
return
|
|
234
|
+
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
344
235
|
};
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
return stringifiedError;
|
|
236
|
+
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
237
|
+
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
238
|
+
const isUnhelpfulNativeModuleError = stderr => {
|
|
239
|
+
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
351
240
|
};
|
|
352
|
-
const
|
|
353
|
-
const
|
|
354
|
-
return
|
|
241
|
+
const getNativeModuleErrorMessage = stderr => {
|
|
242
|
+
const message = getMessageCodeBlock(stderr);
|
|
243
|
+
return {
|
|
244
|
+
message: `Incompatible native node module: ${message}`,
|
|
245
|
+
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
246
|
+
};
|
|
355
247
|
};
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
248
|
+
const getModuleSyntaxError = () => {
|
|
249
|
+
return {
|
|
250
|
+
message: `ES Modules are not supported in electron`,
|
|
251
|
+
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
255
|
+
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
256
|
+
return getNativeModuleErrorMessage(stderr);
|
|
359
257
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
if (childNewLineIndex === -1) {
|
|
363
|
-
return parent;
|
|
258
|
+
if (isModulesSyntaxError(stderr)) {
|
|
259
|
+
return getModuleSyntaxError();
|
|
364
260
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
|
|
368
|
-
if (parentFirstLine.includes(childFirstLine)) {
|
|
369
|
-
return parentFirstLine + childRest;
|
|
261
|
+
if (isModuleNotFoundError(stderr)) {
|
|
262
|
+
return getModuleNotFoundError(stderr);
|
|
370
263
|
}
|
|
371
|
-
|
|
264
|
+
const lines = splitLines$1(stderr);
|
|
265
|
+
const {
|
|
266
|
+
actualMessage,
|
|
267
|
+
rest
|
|
268
|
+
} = getDetails(lines);
|
|
269
|
+
return {
|
|
270
|
+
message: actualMessage,
|
|
271
|
+
code: '',
|
|
272
|
+
stack: rest
|
|
273
|
+
};
|
|
372
274
|
};
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
this.name = 'VError';
|
|
378
|
-
if (error instanceof Error) {
|
|
379
|
-
this.stack = mergeStacks$1(this.stack, error.stack);
|
|
380
|
-
}
|
|
381
|
-
if (error.codeFrame) {
|
|
275
|
+
class IpcError extends VError {
|
|
276
|
+
// @ts-ignore
|
|
277
|
+
constructor(betterMessage, stdout = '', stderr = '') {
|
|
278
|
+
if (stdout || stderr) {
|
|
382
279
|
// @ts-ignore
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
280
|
+
const {
|
|
281
|
+
message,
|
|
282
|
+
code,
|
|
283
|
+
stack
|
|
284
|
+
} = getHelpfulChildProcessError(stdout, stderr);
|
|
285
|
+
const cause = new Error(message);
|
|
386
286
|
// @ts-ignore
|
|
387
|
-
|
|
287
|
+
cause.code = code;
|
|
288
|
+
cause.stack = stack;
|
|
289
|
+
super(cause, betterMessage);
|
|
290
|
+
} else {
|
|
291
|
+
super(betterMessage);
|
|
388
292
|
}
|
|
293
|
+
// @ts-ignore
|
|
294
|
+
this.name = 'IpcError';
|
|
295
|
+
// @ts-ignore
|
|
296
|
+
this.stdout = stdout;
|
|
297
|
+
// @ts-ignore
|
|
298
|
+
this.stderr = stderr;
|
|
389
299
|
}
|
|
300
|
+
}
|
|
301
|
+
const readyMessage = 'ready';
|
|
302
|
+
const getData$2 = event => {
|
|
303
|
+
return event.data;
|
|
390
304
|
};
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
const filteredExtensions = await getExtensions(extensions, parsedValue);
|
|
396
|
-
return filteredExtensions;
|
|
397
|
-
} catch (error) {
|
|
398
|
-
throw new VError$1(error, 'Failed to search for extensions');
|
|
305
|
+
const listen$7 = () => {
|
|
306
|
+
// @ts-ignore
|
|
307
|
+
if (typeof WorkerGlobalScope === 'undefined') {
|
|
308
|
+
throw new TypeError('module is not in web worker scope');
|
|
399
309
|
}
|
|
310
|
+
return globalThis;
|
|
400
311
|
};
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
height
|
|
410
|
-
} = state;
|
|
411
|
-
// TODO cancel ongoing requests
|
|
412
|
-
// TODO handle errors
|
|
413
|
-
const items = await searchExtensions(allExtensions, value);
|
|
414
|
-
if (items.length === 0) {
|
|
415
|
-
return {
|
|
416
|
-
...state,
|
|
417
|
-
items,
|
|
418
|
-
minLineY: 0,
|
|
419
|
-
deltaY: 0,
|
|
420
|
-
allExtensions,
|
|
421
|
-
maxLineY: 0,
|
|
422
|
-
scrollBarHeight: 0,
|
|
423
|
-
finalDeltaY: 0,
|
|
424
|
-
message: noExtensionsFound(),
|
|
425
|
-
searchValue: value,
|
|
426
|
-
placeholder: searchExtensionsInMarketPlace()
|
|
427
|
-
};
|
|
428
|
-
}
|
|
312
|
+
const signal$8 = global => {
|
|
313
|
+
global.postMessage(readyMessage);
|
|
314
|
+
};
|
|
315
|
+
class IpcChildWithModuleWorker extends Ipc {
|
|
316
|
+
getData(event) {
|
|
317
|
+
return getData$2(event);
|
|
318
|
+
}
|
|
319
|
+
send(message) {
|
|
429
320
|
// @ts-ignore
|
|
430
|
-
|
|
431
|
-
const total = items.length;
|
|
432
|
-
const contentHeight = total * itemHeight;
|
|
433
|
-
const scrollBarHeight = getScrollBarSize(height, contentHeight, minimumSliderSize);
|
|
434
|
-
const numberOfVisible = getNumberOfVisibleItems(listHeight, itemHeight);
|
|
435
|
-
const maxLineY = Math.min(numberOfVisible, total);
|
|
436
|
-
const finalDeltaY = getFinalDeltaY(listHeight, itemHeight, total);
|
|
437
|
-
return {
|
|
438
|
-
...state,
|
|
439
|
-
items,
|
|
440
|
-
minLineY: 0,
|
|
441
|
-
deltaY: 0,
|
|
442
|
-
allExtensions,
|
|
443
|
-
maxLineY,
|
|
444
|
-
scrollBarHeight,
|
|
445
|
-
finalDeltaY,
|
|
446
|
-
message: '',
|
|
447
|
-
searchValue: value,
|
|
448
|
-
placeholder: searchExtensionsInMarketPlace()
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
// TODO handle out of order responses (a bit complicated)
|
|
452
|
-
// for now just assume everything comes back in order
|
|
453
|
-
} catch (error) {
|
|
454
|
-
await handleError(error);
|
|
455
|
-
return {
|
|
456
|
-
...state,
|
|
457
|
-
searchValue: value,
|
|
458
|
-
message: `${error}`
|
|
459
|
-
};
|
|
321
|
+
this._rawIpc.postMessage(message);
|
|
460
322
|
}
|
|
323
|
+
sendAndTransfer(message) {
|
|
324
|
+
const transfer = getTransferrables(message);
|
|
325
|
+
// @ts-ignore
|
|
326
|
+
this._rawIpc.postMessage(message, transfer);
|
|
327
|
+
}
|
|
328
|
+
dispose() {
|
|
329
|
+
// ignore
|
|
330
|
+
}
|
|
331
|
+
onClose(callback) {
|
|
332
|
+
// ignore
|
|
333
|
+
}
|
|
334
|
+
onMessage(callback) {
|
|
335
|
+
this._rawIpc.addEventListener('message', callback);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
const wrap$f = global => {
|
|
339
|
+
return new IpcChildWithModuleWorker(global);
|
|
461
340
|
};
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
const Home = 12;
|
|
473
|
-
const UpArrow = 14;
|
|
474
|
-
const DownArrow = 16;
|
|
475
|
-
|
|
476
|
-
const CtrlCmd = 1 << 11 >>> 0;
|
|
477
|
-
|
|
478
|
-
const FocusExtensions = 15;
|
|
479
|
-
|
|
480
|
-
const getKeyBindings = () => {
|
|
481
|
-
return [{
|
|
482
|
-
key: Home,
|
|
483
|
-
command: 'Extensions.focusFirst',
|
|
484
|
-
when: FocusExtensions
|
|
485
|
-
}, {
|
|
486
|
-
key: End,
|
|
487
|
-
command: 'Extensions.focusLast',
|
|
488
|
-
when: FocusExtensions
|
|
489
|
-
}, {
|
|
490
|
-
key: PageUp,
|
|
491
|
-
command: 'Extensions.focusPreviousPage',
|
|
492
|
-
when: FocusExtensions
|
|
493
|
-
}, {
|
|
494
|
-
key: PageDown,
|
|
495
|
-
command: 'Extensions.focusNextPage',
|
|
496
|
-
when: FocusExtensions
|
|
497
|
-
}, {
|
|
498
|
-
key: UpArrow,
|
|
499
|
-
command: 'Extensions.focusPrevious',
|
|
500
|
-
when: FocusExtensions
|
|
501
|
-
}, {
|
|
502
|
-
key: DownArrow,
|
|
503
|
-
command: 'Extensions.focusNext',
|
|
504
|
-
when: FocusExtensions
|
|
505
|
-
}, {
|
|
506
|
-
key: Space,
|
|
507
|
-
command: 'Extensions.handleClickCurrentButKeepFocus',
|
|
508
|
-
when: FocusExtensions
|
|
509
|
-
}, {
|
|
510
|
-
key: Enter,
|
|
511
|
-
command: 'Extensions.handleClickCurrent',
|
|
512
|
-
when: FocusExtensions
|
|
513
|
-
}, {
|
|
514
|
-
key: CtrlCmd | Space,
|
|
515
|
-
command: 'Extensions.toggleSuggest',
|
|
516
|
-
when: FocusExtensions
|
|
517
|
-
}, {
|
|
518
|
-
key: CtrlCmd | DownArrow,
|
|
519
|
-
command: 'Extensions.scrollDown',
|
|
520
|
-
when: FocusExtensions
|
|
521
|
-
}];
|
|
341
|
+
const withResolvers = () => {
|
|
342
|
+
let _resolve;
|
|
343
|
+
const promise = new Promise(resolve => {
|
|
344
|
+
_resolve = resolve;
|
|
345
|
+
});
|
|
346
|
+
return {
|
|
347
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
348
|
+
resolve: _resolve,
|
|
349
|
+
promise
|
|
350
|
+
};
|
|
522
351
|
};
|
|
523
|
-
|
|
524
|
-
const Button = 1;
|
|
525
|
-
|
|
526
|
-
const ExtensionActions = 'ExtensionActions';
|
|
527
|
-
const ExtensionActive = 'ExtensionActive';
|
|
528
|
-
const ExtensionHeader = 'ExtensionHeader';
|
|
529
|
-
const ExtensionListItem = 'ExtensionListItem';
|
|
530
|
-
const ExtensionListItemAuthorName = 'ExtensionListItemAuthorName';
|
|
531
|
-
const ExtensionListItemDescription = 'ExtensionListItemDescription';
|
|
532
|
-
const ExtensionListItemDetail = 'ExtensionListItemDetail';
|
|
533
|
-
const ExtensionListItemFooter = 'ExtensionListItemFooter';
|
|
534
|
-
const ExtensionListItemIcon = 'ExtensionListItemIcon';
|
|
535
|
-
const ExtensionListItemName = 'ExtensionListItemName';
|
|
536
|
-
const ListItems = 'ListItems';
|
|
537
|
-
const MultilineInputBox = 'MultilineInputBox';
|
|
538
|
-
const ScrollBarThumb = 'ScrollBarThumb';
|
|
539
|
-
const ScrollBarThumbActive = 'ScrollBarThumbActive';
|
|
540
|
-
const SearchField = 'SearchField';
|
|
541
|
-
const SearchFieldButtons = 'SearchFieldButtons';
|
|
542
|
-
const SearchFieldContainer = 'SearchFieldContainer';
|
|
543
|
-
|
|
544
|
-
const CheckBox = 'checkbox';
|
|
545
|
-
const List = 'list';
|
|
546
|
-
const ListItem = 'listitem';
|
|
547
|
-
const None = 'none';
|
|
548
|
-
|
|
549
|
-
const Div = 4;
|
|
550
|
-
const Text = 12;
|
|
551
|
-
const Img = 17;
|
|
552
|
-
const TextArea = 62;
|
|
553
|
-
|
|
554
|
-
const getSearchFieldButtonVirtualDom = button => {
|
|
352
|
+
const waitForFirstMessage = async port => {
|
|
555
353
|
const {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
ariaChecked: checked,
|
|
566
|
-
tabIndex: 0,
|
|
567
|
-
childCount: 1
|
|
568
|
-
}, {
|
|
569
|
-
type: Div,
|
|
570
|
-
className: `MaskIcon ${icon}`,
|
|
571
|
-
childCount: 0
|
|
572
|
-
}];
|
|
354
|
+
resolve,
|
|
355
|
+
promise
|
|
356
|
+
} = withResolvers();
|
|
357
|
+
port.addEventListener('message', resolve, {
|
|
358
|
+
once: true
|
|
359
|
+
});
|
|
360
|
+
const event = await promise;
|
|
361
|
+
// @ts-ignore
|
|
362
|
+
return event.data;
|
|
573
363
|
};
|
|
574
|
-
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
name,
|
|
589
|
-
onInput,
|
|
590
|
-
onFocus,
|
|
591
|
-
childCount: 0
|
|
592
|
-
}, {
|
|
593
|
-
type: Div,
|
|
594
|
-
className: SearchFieldButtons,
|
|
595
|
-
childCount: insideButtons.length
|
|
596
|
-
}, ...insideButtons.flatMap(getSearchFieldButtonVirtualDom)];
|
|
597
|
-
if (outsideButtons.length > 0) {
|
|
598
|
-
dom.unshift({
|
|
599
|
-
type: Div,
|
|
600
|
-
className: SearchFieldContainer,
|
|
601
|
-
role: None,
|
|
602
|
-
childCount: 1 + outsideButtons.length
|
|
364
|
+
const listen$6 = async () => {
|
|
365
|
+
const parentIpcRaw = listen$7();
|
|
366
|
+
signal$8(parentIpcRaw);
|
|
367
|
+
const parentIpc = wrap$f(parentIpcRaw);
|
|
368
|
+
const firstMessage = await waitForFirstMessage(parentIpc);
|
|
369
|
+
if (firstMessage.method !== 'initialize') {
|
|
370
|
+
throw new IpcError('unexpected first message');
|
|
371
|
+
}
|
|
372
|
+
const type = firstMessage.params[0];
|
|
373
|
+
if (type === 'message-port') {
|
|
374
|
+
parentIpc.send({
|
|
375
|
+
jsonrpc: '2.0',
|
|
376
|
+
id: firstMessage.id,
|
|
377
|
+
result: null
|
|
603
378
|
});
|
|
604
|
-
|
|
379
|
+
parentIpc.dispose();
|
|
380
|
+
const port = firstMessage.params[1];
|
|
381
|
+
return port;
|
|
605
382
|
}
|
|
606
|
-
return
|
|
383
|
+
return globalThis;
|
|
607
384
|
};
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
}
|
|
385
|
+
class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
|
|
386
|
+
getData(event) {
|
|
387
|
+
return getData$2(event);
|
|
388
|
+
}
|
|
389
|
+
send(message) {
|
|
390
|
+
this._rawIpc.postMessage(message);
|
|
391
|
+
}
|
|
392
|
+
sendAndTransfer(message) {
|
|
393
|
+
const transfer = getTransferrables(message);
|
|
394
|
+
this._rawIpc.postMessage(message, transfer);
|
|
395
|
+
}
|
|
396
|
+
dispose() {
|
|
397
|
+
if (this._rawIpc.close) {
|
|
398
|
+
this._rawIpc.close();
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
onClose(callback) {
|
|
402
|
+
// ignore
|
|
403
|
+
}
|
|
404
|
+
onMessage(callback) {
|
|
405
|
+
this._rawIpc.addEventListener('message', callback);
|
|
406
|
+
this._rawIpc.start();
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
const wrap$e = port => {
|
|
410
|
+
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
411
|
+
};
|
|
412
|
+
const IpcChildWithModuleWorkerAndMessagePort$1 = {
|
|
413
|
+
__proto__: null,
|
|
414
|
+
listen: listen$6,
|
|
415
|
+
wrap: wrap$e
|
|
615
416
|
};
|
|
616
417
|
|
|
617
|
-
const
|
|
618
|
-
const
|
|
619
|
-
const HandleTouchStart = 'handleTouchStart';
|
|
620
|
-
const HandleWheel = 'handleWheel';
|
|
621
|
-
|
|
622
|
-
const Extension = 'Extension';
|
|
623
|
-
|
|
624
|
-
const text = data => {
|
|
418
|
+
const Two = '2.0';
|
|
419
|
+
const create$4 = (method, params) => {
|
|
625
420
|
return {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
421
|
+
jsonrpc: Two,
|
|
422
|
+
method,
|
|
423
|
+
params
|
|
629
424
|
};
|
|
630
425
|
};
|
|
631
|
-
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
className: ExtensionListItemDetail,
|
|
635
|
-
childCount: 3
|
|
636
|
-
};
|
|
637
|
-
const listItemName = {
|
|
638
|
-
type: Div,
|
|
639
|
-
className: ExtensionListItemName,
|
|
640
|
-
childCount: 1
|
|
426
|
+
const callbacks = Object.create(null);
|
|
427
|
+
const set$1 = (id, fn) => {
|
|
428
|
+
callbacks[id] = fn;
|
|
641
429
|
};
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
className: ExtensionListItemDescription,
|
|
645
|
-
childCount: 1
|
|
430
|
+
const get = id => {
|
|
431
|
+
return callbacks[id];
|
|
646
432
|
};
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
className: ExtensionListItemFooter,
|
|
650
|
-
childCount: 2
|
|
433
|
+
const remove = id => {
|
|
434
|
+
delete callbacks[id];
|
|
651
435
|
};
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
childCount: 1
|
|
436
|
+
let id = 0;
|
|
437
|
+
const create$3 = () => {
|
|
438
|
+
return ++id;
|
|
656
439
|
};
|
|
657
|
-
const
|
|
440
|
+
const registerPromise = () => {
|
|
441
|
+
const id = create$3();
|
|
658
442
|
const {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
name,
|
|
664
|
-
description,
|
|
665
|
-
publisher,
|
|
666
|
-
focused
|
|
667
|
-
} = extension;
|
|
668
|
-
const dom = [{
|
|
669
|
-
type: Div,
|
|
670
|
-
role: ListItem,
|
|
671
|
-
ariaRoleDescription: Extension,
|
|
672
|
-
className: ExtensionListItem,
|
|
673
|
-
ariaPosInSet: posInSet,
|
|
674
|
-
ariaSetSize: setSize,
|
|
675
|
-
top,
|
|
676
|
-
childCount: 2
|
|
677
|
-
}, {
|
|
678
|
-
type: Img,
|
|
679
|
-
src: icon,
|
|
680
|
-
className: ExtensionListItemIcon,
|
|
681
|
-
role: None,
|
|
682
|
-
childCount: 0
|
|
683
|
-
}, listItemDetail, listItemName, text(name), listItemDescription, text(description), listItemFooter, listItemAuthorName, text(publisher), {
|
|
684
|
-
type: Div,
|
|
685
|
-
className: ExtensionActions,
|
|
686
|
-
childCount: 0
|
|
687
|
-
}];
|
|
688
|
-
if (focused) {
|
|
689
|
-
dom[0].id = 'ExtensionActive';
|
|
690
|
-
dom[0].className += ' ' + ExtensionActive;
|
|
691
|
-
}
|
|
692
|
-
return dom;
|
|
693
|
-
};
|
|
694
|
-
|
|
695
|
-
const getExtensionsListVirtualDom = visibleExtensions => {
|
|
696
|
-
const dom = [{
|
|
697
|
-
type: Div,
|
|
698
|
-
className: ListItems,
|
|
699
|
-
tabIndex: 0,
|
|
700
|
-
ariaLabel: extensions(),
|
|
701
|
-
role: List,
|
|
702
|
-
oncontextmenu: HandleContextMenu,
|
|
703
|
-
onpointerdown: HandlePointerDown,
|
|
704
|
-
ontouchstart: HandleTouchStart,
|
|
705
|
-
onwheelpassive: HandleWheel,
|
|
706
|
-
childCount: visibleExtensions.length
|
|
707
|
-
}, ...visibleExtensions.flatMap(getExtensionListItemVirtualDom)];
|
|
708
|
-
return dom;
|
|
709
|
-
};
|
|
710
|
-
|
|
711
|
-
const getExtensionsVirtualDom = visibleExtensions => {
|
|
712
|
-
const dom = getExtensionsListVirtualDom(visibleExtensions);
|
|
713
|
-
// TODO
|
|
714
|
-
return dom;
|
|
715
|
-
};
|
|
716
|
-
|
|
717
|
-
const getVisibleItem = (item, setSize, itemHeight, minLineY, relative, i, focusedIndex) => {
|
|
443
|
+
resolve,
|
|
444
|
+
promise
|
|
445
|
+
} = Promise.withResolvers();
|
|
446
|
+
set$1(id, resolve);
|
|
718
447
|
return {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
posInSet: i + 1,
|
|
722
|
-
top: (i - minLineY) * itemHeight - relative,
|
|
723
|
-
focused: i === focusedIndex
|
|
448
|
+
id,
|
|
449
|
+
promise
|
|
724
450
|
};
|
|
725
451
|
};
|
|
726
|
-
const
|
|
727
|
-
const {
|
|
728
|
-
minLineY,
|
|
729
|
-
maxLineY,
|
|
730
|
-
items,
|
|
731
|
-
itemHeight,
|
|
732
|
-
deltaY,
|
|
733
|
-
focusedIndex
|
|
734
|
-
} = state;
|
|
735
|
-
const setSize = items.length;
|
|
736
|
-
const visible = [];
|
|
737
|
-
const relative = deltaY % itemHeight;
|
|
738
|
-
for (let i = minLineY; i < maxLineY; i++) {
|
|
739
|
-
const item = items[i];
|
|
740
|
-
visible.push(getVisibleItem(item, setSize, itemHeight, minLineY, relative, i, focusedIndex));
|
|
741
|
-
}
|
|
742
|
-
return visible;
|
|
743
|
-
};
|
|
744
|
-
|
|
745
|
-
const ClearAll = 'ClearAll';
|
|
746
|
-
const Filter = 'Filter';
|
|
747
|
-
|
|
748
|
-
const px = value => {
|
|
749
|
-
return `${value}px`;
|
|
750
|
-
};
|
|
751
|
-
const position = (x, y) => {
|
|
752
|
-
return `${x}px ${y}px`;
|
|
753
|
-
};
|
|
754
|
-
|
|
755
|
-
const SetMessage = 'setMessage';
|
|
756
|
-
const SetScrollBar = 'setScrollBar';
|
|
757
|
-
const SetSearchValue = 'setSearchValue';
|
|
758
|
-
|
|
759
|
-
const getListHeight = state => {
|
|
452
|
+
const create$2 = (method, params) => {
|
|
760
453
|
const {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
} =
|
|
764
|
-
|
|
454
|
+
id,
|
|
455
|
+
promise
|
|
456
|
+
} = registerPromise();
|
|
457
|
+
const message = {
|
|
458
|
+
jsonrpc: Two,
|
|
459
|
+
method,
|
|
460
|
+
params,
|
|
461
|
+
id
|
|
462
|
+
};
|
|
463
|
+
return {
|
|
464
|
+
message,
|
|
465
|
+
promise
|
|
466
|
+
};
|
|
765
467
|
};
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
apply(oldState, newState) {
|
|
771
|
-
// TODO render extensions incrementally when scrolling
|
|
772
|
-
const visibleExtensions = getVisible(newState);
|
|
773
|
-
const dom = getExtensionsVirtualDom(visibleExtensions);
|
|
774
|
-
return ['setExtensionsDom', dom];
|
|
468
|
+
class JsonRpcError extends Error {
|
|
469
|
+
constructor(message) {
|
|
470
|
+
super(message);
|
|
471
|
+
this.name = 'JsonRpcError';
|
|
775
472
|
}
|
|
776
|
-
}
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
473
|
+
}
|
|
474
|
+
const NewLine = '\n';
|
|
475
|
+
const DomException = 'DOMException';
|
|
476
|
+
const ReferenceError$1 = 'ReferenceError';
|
|
477
|
+
const SyntaxError$1 = 'SyntaxError';
|
|
478
|
+
const TypeError$1 = 'TypeError';
|
|
479
|
+
const getErrorConstructor = (message, type) => {
|
|
480
|
+
if (type) {
|
|
481
|
+
switch (type) {
|
|
482
|
+
case DomException:
|
|
483
|
+
return DOMException;
|
|
484
|
+
case TypeError$1:
|
|
485
|
+
return TypeError;
|
|
486
|
+
case SyntaxError$1:
|
|
487
|
+
return SyntaxError;
|
|
488
|
+
case ReferenceError$1:
|
|
489
|
+
return ReferenceError;
|
|
490
|
+
default:
|
|
491
|
+
return Error;
|
|
794
492
|
}
|
|
795
|
-
return [/* method */SetScrollBar, translateString, heightString, className];
|
|
796
493
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
isEqual(oldState, newState) {
|
|
800
|
-
return oldState.message === newState.message;
|
|
801
|
-
},
|
|
802
|
-
apply(oldState, newState) {
|
|
803
|
-
return [/* method */SetMessage, /* message */newState.message];
|
|
494
|
+
if (message.startsWith('TypeError: ')) {
|
|
495
|
+
return TypeError;
|
|
804
496
|
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
isEqual(oldState, newState) {
|
|
808
|
-
return oldState.searchValue === newState.searchValue;
|
|
809
|
-
},
|
|
810
|
-
apply(oldState, newState) {
|
|
811
|
-
return [/* method */SetSearchValue, oldState.searchValue, newState.searchValue];
|
|
497
|
+
if (message.startsWith('SyntaxError: ')) {
|
|
498
|
+
return SyntaxError;
|
|
812
499
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
isEqual(oldState, newState) {
|
|
816
|
-
return oldState.placeholder === newState.placeholder;
|
|
817
|
-
},
|
|
818
|
-
apply(oldState, newState) {
|
|
819
|
-
const actions = [{
|
|
820
|
-
type: Button,
|
|
821
|
-
title: clearExtensionSearchResults(),
|
|
822
|
-
icon: `MaskIcon${ClearAll}`,
|
|
823
|
-
command: 'Extensions.clearSearchResults'
|
|
824
|
-
}, {
|
|
825
|
-
type: Button,
|
|
826
|
-
title: filter(),
|
|
827
|
-
icon: `MaskIcon${Filter}`
|
|
828
|
-
}];
|
|
829
|
-
const dom = getExtensionHeaderVirtualDom(newState.placeholder, actions);
|
|
830
|
-
return ['setHeaderDom', dom];
|
|
500
|
+
if (message.startsWith('ReferenceError: ')) {
|
|
501
|
+
return ReferenceError;
|
|
831
502
|
}
|
|
503
|
+
return Error;
|
|
832
504
|
};
|
|
833
|
-
const
|
|
834
|
-
const
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
505
|
+
const constructError = (message, type, name) => {
|
|
506
|
+
const ErrorConstructor = getErrorConstructor(message, type);
|
|
507
|
+
if (ErrorConstructor === DOMException && name) {
|
|
508
|
+
return new ErrorConstructor(message, name);
|
|
509
|
+
}
|
|
510
|
+
if (ErrorConstructor === Error) {
|
|
511
|
+
const error = new Error(message);
|
|
512
|
+
if (name && name !== 'VError') {
|
|
513
|
+
error.name = name;
|
|
839
514
|
}
|
|
515
|
+
return error;
|
|
840
516
|
}
|
|
841
|
-
return
|
|
517
|
+
return new ErrorConstructor(message);
|
|
842
518
|
};
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
'SearchExtensions.clearSearchResults': clearSearchResults,
|
|
846
|
-
'SearchExtensions.getKeyBindings': getKeyBindings,
|
|
847
|
-
'SearchExtensions.render': doRender,
|
|
848
|
-
'SearchExtensions.searchExtensions': searchExtensions
|
|
519
|
+
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
520
|
+
return string.indexOf(NewLine, startIndex);
|
|
849
521
|
};
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
522
|
+
const getParentStack = error => {
|
|
523
|
+
let parentStack = error.stack || error.data || error.message || '';
|
|
524
|
+
if (parentStack.startsWith(' at')) {
|
|
525
|
+
parentStack = error.message + NewLine + parentStack;
|
|
526
|
+
}
|
|
527
|
+
return parentStack;
|
|
854
528
|
};
|
|
855
|
-
const
|
|
856
|
-
return
|
|
529
|
+
const joinLines = lines => {
|
|
530
|
+
return lines.join(NewLine);
|
|
857
531
|
};
|
|
858
|
-
const
|
|
859
|
-
|
|
532
|
+
const MethodNotFound = -32601;
|
|
533
|
+
const Custom = -32001;
|
|
534
|
+
const splitLines = lines => {
|
|
535
|
+
return lines.split(NewLine);
|
|
536
|
+
};
|
|
537
|
+
const restoreJsonRpcError = error => {
|
|
538
|
+
if (error && error instanceof Error) {
|
|
539
|
+
return error;
|
|
540
|
+
}
|
|
541
|
+
const currentStack = joinLines(splitLines(new Error().stack || '').slice(1));
|
|
542
|
+
if (error && error.code && error.code === MethodNotFound) {
|
|
543
|
+
const restoredError = new JsonRpcError(error.message);
|
|
544
|
+
const parentStack = getParentStack(error);
|
|
545
|
+
restoredError.stack = parentStack + NewLine + currentStack;
|
|
546
|
+
return restoredError;
|
|
547
|
+
}
|
|
548
|
+
if (error && error.message) {
|
|
549
|
+
const restoredError = constructError(error.message, error.type, error.name);
|
|
550
|
+
if (error.data) {
|
|
551
|
+
if (error.data.stack && error.data.type && error.message) {
|
|
552
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
|
|
553
|
+
} else if (error.data.stack) {
|
|
554
|
+
restoredError.stack = error.data.stack;
|
|
555
|
+
}
|
|
556
|
+
if (error.data.codeFrame) {
|
|
557
|
+
// @ts-ignore
|
|
558
|
+
restoredError.codeFrame = error.data.codeFrame;
|
|
559
|
+
}
|
|
560
|
+
if (error.data.code) {
|
|
561
|
+
// @ts-ignore
|
|
562
|
+
restoredError.code = error.data.code;
|
|
563
|
+
}
|
|
564
|
+
if (error.data.type) {
|
|
565
|
+
// @ts-ignore
|
|
566
|
+
restoredError.name = error.data.type;
|
|
567
|
+
}
|
|
568
|
+
} else {
|
|
569
|
+
if (error.stack) {
|
|
570
|
+
const lowerStack = restoredError.stack || '';
|
|
571
|
+
// @ts-ignore
|
|
572
|
+
const indexNewLine = getNewLineIndex(lowerStack);
|
|
573
|
+
const parentStack = getParentStack(error);
|
|
574
|
+
// @ts-ignore
|
|
575
|
+
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
576
|
+
}
|
|
577
|
+
if (error.codeFrame) {
|
|
578
|
+
// @ts-ignore
|
|
579
|
+
restoredError.codeFrame = error.codeFrame;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return restoredError;
|
|
583
|
+
}
|
|
584
|
+
if (typeof error === 'string') {
|
|
585
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
586
|
+
}
|
|
587
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
588
|
+
};
|
|
589
|
+
const unwrapJsonRpcResult = responseMessage => {
|
|
590
|
+
if ('error' in responseMessage) {
|
|
591
|
+
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
592
|
+
throw restoredError;
|
|
593
|
+
}
|
|
594
|
+
if ('result' in responseMessage) {
|
|
595
|
+
return responseMessage.result;
|
|
596
|
+
}
|
|
597
|
+
throw new JsonRpcError('unexpected response message');
|
|
860
598
|
};
|
|
861
599
|
const warn = (...args) => {
|
|
862
600
|
console.warn(...args);
|
|
@@ -866,19 +604,11 @@ const resolve = (id, response) => {
|
|
|
866
604
|
if (!fn) {
|
|
867
605
|
console.log(response);
|
|
868
606
|
warn(`callback ${id} may already be disposed`);
|
|
869
|
-
return;
|
|
870
|
-
}
|
|
871
|
-
fn(response);
|
|
872
|
-
remove(id);
|
|
873
|
-
};
|
|
874
|
-
class JsonRpcError extends Error {
|
|
875
|
-
constructor(message) {
|
|
876
|
-
super(message);
|
|
877
|
-
this.name = 'JsonRpcError';
|
|
607
|
+
return;
|
|
878
608
|
}
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
609
|
+
fn(response);
|
|
610
|
+
remove(id);
|
|
611
|
+
};
|
|
882
612
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
883
613
|
const getErrorType = prettyError => {
|
|
884
614
|
if (prettyError && prettyError.type) {
|
|
@@ -922,7 +652,7 @@ const getErrorResponse = (message, error, preparePrettyError, logError) => {
|
|
|
922
652
|
const errorProperty = getErrorProperty(error, prettyError);
|
|
923
653
|
return create$1(message, errorProperty);
|
|
924
654
|
};
|
|
925
|
-
const create = (message, result) => {
|
|
655
|
+
const create$5 = (message, result) => {
|
|
926
656
|
return {
|
|
927
657
|
jsonrpc: Two,
|
|
928
658
|
id: message.id,
|
|
@@ -931,7 +661,7 @@ const create = (message, result) => {
|
|
|
931
661
|
};
|
|
932
662
|
const getSuccessResponse = (message, result) => {
|
|
933
663
|
const resultProperty = result ?? null;
|
|
934
|
-
return create(message, resultProperty);
|
|
664
|
+
return create$5(message, resultProperty);
|
|
935
665
|
};
|
|
936
666
|
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
937
667
|
try {
|
|
@@ -1007,458 +737,851 @@ const handleJsonRpcMessage = async (...args) => {
|
|
|
1007
737
|
}
|
|
1008
738
|
throw new JsonRpcError('unexpected message');
|
|
1009
739
|
};
|
|
740
|
+
const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
|
|
741
|
+
const {
|
|
742
|
+
message,
|
|
743
|
+
promise
|
|
744
|
+
} = create$2(method, params);
|
|
745
|
+
if (useSendAndTransfer && ipc.sendAndTransfer) {
|
|
746
|
+
ipc.sendAndTransfer(message);
|
|
747
|
+
} else {
|
|
748
|
+
ipc.send(message);
|
|
749
|
+
}
|
|
750
|
+
const responseMessage = await promise;
|
|
751
|
+
return unwrapJsonRpcResult(responseMessage);
|
|
752
|
+
};
|
|
753
|
+
const send = (transport, method, ...params) => {
|
|
754
|
+
const message = create$4(method, params);
|
|
755
|
+
transport.send(message);
|
|
756
|
+
};
|
|
757
|
+
const invoke = (ipc, method, ...params) => {
|
|
758
|
+
return invokeHelper(ipc, method, params, false);
|
|
759
|
+
};
|
|
760
|
+
const invokeAndTransfer = (ipc, method, ...params) => {
|
|
761
|
+
return invokeHelper(ipc, method, params, true);
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
const commands = Object.create(null);
|
|
765
|
+
const register = commandMap => {
|
|
766
|
+
Object.assign(commands, commandMap);
|
|
767
|
+
};
|
|
768
|
+
const getCommand = key => {
|
|
769
|
+
return commands[key];
|
|
770
|
+
};
|
|
771
|
+
const execute = (command, ...args) => {
|
|
772
|
+
const fn = getCommand(command);
|
|
773
|
+
if (!fn) {
|
|
774
|
+
throw new Error(`command not found ${command}`);
|
|
775
|
+
}
|
|
776
|
+
return fn(...args);
|
|
777
|
+
};
|
|
1010
778
|
|
|
779
|
+
const createRpc = ipc => {
|
|
780
|
+
const rpc = {
|
|
781
|
+
// @ts-ignore
|
|
782
|
+
ipc,
|
|
783
|
+
/**
|
|
784
|
+
* @deprecated
|
|
785
|
+
*/
|
|
786
|
+
send(method, ...params) {
|
|
787
|
+
send(ipc, method, ...params);
|
|
788
|
+
},
|
|
789
|
+
invoke(method, ...params) {
|
|
790
|
+
return invoke(ipc, method, ...params);
|
|
791
|
+
},
|
|
792
|
+
invokeAndTransfer(method, ...params) {
|
|
793
|
+
return invokeAndTransfer(ipc, method, ...params);
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
return rpc;
|
|
797
|
+
};
|
|
1011
798
|
const requiresSocket = () => {
|
|
1012
799
|
return false;
|
|
1013
800
|
};
|
|
1014
801
|
const preparePrettyError = error => {
|
|
1015
802
|
return error;
|
|
1016
803
|
};
|
|
1017
|
-
const logError =
|
|
804
|
+
const logError = () => {
|
|
1018
805
|
// handled by renderer worker
|
|
1019
806
|
};
|
|
1020
807
|
const handleMessage = event => {
|
|
1021
|
-
|
|
808
|
+
const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
|
|
809
|
+
const actualExecute = event?.target?.execute || execute;
|
|
810
|
+
return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket);
|
|
1022
811
|
};
|
|
1023
|
-
|
|
1024
812
|
const handleIpc = ipc => {
|
|
1025
|
-
|
|
813
|
+
if ('addEventListener' in ipc) {
|
|
814
|
+
ipc.addEventListener('message', handleMessage);
|
|
815
|
+
} else if ('on' in ipc) {
|
|
816
|
+
// deprecated
|
|
817
|
+
ipc.on('message', handleMessage);
|
|
818
|
+
}
|
|
819
|
+
};
|
|
820
|
+
const listen$1 = async (module, options) => {
|
|
821
|
+
const rawIpc = await module.listen(options);
|
|
822
|
+
if (module.signal) {
|
|
823
|
+
module.signal(rawIpc);
|
|
824
|
+
}
|
|
825
|
+
const ipc = module.wrap(rawIpc);
|
|
826
|
+
return ipc;
|
|
827
|
+
};
|
|
828
|
+
const create = async ({
|
|
829
|
+
commandMap
|
|
830
|
+
}) => {
|
|
831
|
+
// TODO create a commandMap per rpc instance
|
|
832
|
+
register(commandMap);
|
|
833
|
+
const ipc = await listen$1(IpcChildWithModuleWorkerAndMessagePort$1);
|
|
834
|
+
handleIpc(ipc);
|
|
835
|
+
const rpc = createRpc(ipc);
|
|
836
|
+
return rpc;
|
|
837
|
+
};
|
|
838
|
+
const WebWorkerRpcClient = {
|
|
839
|
+
__proto__: null,
|
|
840
|
+
create
|
|
1026
841
|
};
|
|
1027
842
|
|
|
1028
|
-
const
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
const
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
843
|
+
const handleError = (error, notify = true, prefix = '') => {
|
|
844
|
+
console.error(error);
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
const emptyObject = {};
|
|
848
|
+
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
849
|
+
const i18nString = (key, placeholders = emptyObject) => {
|
|
850
|
+
if (placeholders === emptyObject) {
|
|
851
|
+
return key;
|
|
852
|
+
}
|
|
853
|
+
const replacer = (match, rest) => {
|
|
854
|
+
return placeholders[rest];
|
|
855
|
+
};
|
|
856
|
+
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* @enum {string}
|
|
861
|
+
*/
|
|
862
|
+
const UiStrings = {
|
|
863
|
+
NoExtensionsFound: 'No extensions found.',
|
|
864
|
+
Filter: 'Filter',
|
|
865
|
+
ClearExtensionSearchResults: 'Clear extension search results',
|
|
866
|
+
SearchExtensionsInMarketplace: 'Search Extensions in Marketplace',
|
|
867
|
+
Extensions: 'Extensions'};
|
|
868
|
+
const noExtensionsFound = () => {
|
|
869
|
+
return i18nString(UiStrings.NoExtensionsFound);
|
|
870
|
+
};
|
|
871
|
+
const filter = () => {
|
|
872
|
+
return i18nString(UiStrings.Filter);
|
|
873
|
+
};
|
|
874
|
+
const extensions = () => {
|
|
875
|
+
return i18nString(UiStrings.Extensions);
|
|
876
|
+
};
|
|
877
|
+
const clearExtensionSearchResults = () => {
|
|
878
|
+
return i18nString(UiStrings.ClearExtensionSearchResults);
|
|
879
|
+
};
|
|
880
|
+
const searchExtensionsInMarketPlace = () => {
|
|
881
|
+
return i18nString(UiStrings.SearchExtensionsInMarketplace);
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
const getFinalDeltaY = (height, itemHeight, itemsLength) => {
|
|
885
|
+
const contentHeight = itemsLength * itemHeight;
|
|
886
|
+
const finalDeltaY = Math.max(contentHeight - height, 0);
|
|
887
|
+
return finalDeltaY;
|
|
888
|
+
};
|
|
889
|
+
|
|
890
|
+
const getListHeight$1 = (itemsLength, itemHeight, maxHeight) => {
|
|
891
|
+
number(itemsLength);
|
|
892
|
+
number(itemHeight);
|
|
893
|
+
number(maxHeight);
|
|
894
|
+
if (itemsLength === 0) {
|
|
895
|
+
return itemHeight;
|
|
1036
896
|
}
|
|
897
|
+
const totalHeight = itemsLength * itemHeight;
|
|
898
|
+
return Math.min(totalHeight, maxHeight);
|
|
899
|
+
};
|
|
900
|
+
|
|
901
|
+
// TODO optimize this function to return the minimum number
|
|
902
|
+
// of visible items needed, e.g. when not scrolled 5 items with
|
|
903
|
+
// 20px fill 100px but when scrolled 6 items are needed
|
|
904
|
+
const getNumberOfVisibleItems = (listHeight, itemHeight) => {
|
|
905
|
+
return Math.ceil(listHeight / itemHeight) + 1;
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
const Web = 1;
|
|
909
|
+
const Electron = 2;
|
|
910
|
+
const Remote = 3;
|
|
911
|
+
const Test = 4;
|
|
912
|
+
|
|
913
|
+
// TODO treeshake this function out
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* @returns {number}
|
|
917
|
+
*/
|
|
918
|
+
const getPlatform = () => {
|
|
1037
919
|
// @ts-ignore
|
|
1038
|
-
if (
|
|
1039
|
-
|
|
920
|
+
if (typeof PLATFORM !== 'undefined') {
|
|
921
|
+
// @ts-ignore
|
|
922
|
+
return PLATFORM;
|
|
923
|
+
}
|
|
924
|
+
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
|
|
925
|
+
return Test;
|
|
926
|
+
}
|
|
927
|
+
// TODO find a better way to pass runtime environment
|
|
928
|
+
if (typeof name !== 'undefined' && name.endsWith('(Electron)')) {
|
|
929
|
+
return Electron;
|
|
930
|
+
}
|
|
931
|
+
if (typeof name !== 'undefined' && name.endsWith('(Web)')) {
|
|
932
|
+
return Web;
|
|
1040
933
|
}
|
|
1041
|
-
return
|
|
934
|
+
return Remote;
|
|
1042
935
|
};
|
|
936
|
+
const platform = getPlatform();
|
|
1043
937
|
|
|
1044
|
-
const
|
|
1045
|
-
|
|
938
|
+
const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
|
|
939
|
+
if (size >= contentSize) {
|
|
940
|
+
return 0;
|
|
941
|
+
}
|
|
942
|
+
return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
|
|
1046
943
|
};
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
944
|
+
|
|
945
|
+
const getScrollBarOffset = (delta, finalDelta, size, scrollBarSize) => {
|
|
946
|
+
const scrollBarOffset = delta / finalDelta * (size - scrollBarSize);
|
|
947
|
+
return scrollBarOffset;
|
|
948
|
+
};
|
|
949
|
+
const getScrollBarY = getScrollBarOffset;
|
|
950
|
+
|
|
951
|
+
const Installed = '@installed';
|
|
952
|
+
const Enabled = '@enabled';
|
|
953
|
+
const Disabled = '@disabled';
|
|
954
|
+
const Builtin = '@builtin';
|
|
955
|
+
const Sort = '@sort';
|
|
956
|
+
const Id = '@id';
|
|
957
|
+
const Outdated = '@outdated';
|
|
958
|
+
|
|
959
|
+
const RE_PARAM = /@\w+/g;
|
|
960
|
+
|
|
961
|
+
// TODO test sorting and filtering
|
|
962
|
+
const parseValue = value => {
|
|
963
|
+
const parameters = Object.create(null);
|
|
964
|
+
// TODO this is not very functional code (assignment)
|
|
965
|
+
const replaced = value.replaceAll(RE_PARAM, (match, by, order) => {
|
|
966
|
+
if (match.startsWith(Installed)) {
|
|
967
|
+
parameters.installed = true;
|
|
968
|
+
}
|
|
969
|
+
if (match.startsWith(Enabled)) {
|
|
970
|
+
parameters.enabled = true;
|
|
971
|
+
}
|
|
972
|
+
if (match.startsWith(Disabled)) {
|
|
973
|
+
parameters.disabled = true;
|
|
974
|
+
}
|
|
975
|
+
if (match.startsWith(Builtin)) {
|
|
976
|
+
parameters.builtin = true;
|
|
977
|
+
}
|
|
978
|
+
if (match.startsWith(Sort)) {
|
|
979
|
+
// TODO
|
|
980
|
+
parameters.sort = 'installs';
|
|
981
|
+
}
|
|
982
|
+
if (match.startsWith(Id)) {
|
|
983
|
+
// TODO
|
|
984
|
+
parameters.id = 'abc';
|
|
985
|
+
}
|
|
986
|
+
if (match.startsWith(Outdated)) {
|
|
987
|
+
parameters.outdated = true;
|
|
988
|
+
}
|
|
989
|
+
return '';
|
|
990
|
+
});
|
|
991
|
+
const isLocal = parameters.enabled || parameters.builtin || parameters.disabled || parameters.outdated || parameters.installed;
|
|
992
|
+
return {
|
|
993
|
+
query: replaced,
|
|
994
|
+
...parameters,
|
|
995
|
+
isLocal
|
|
1057
996
|
};
|
|
1058
|
-
that.onClose(handleClose);
|
|
1059
997
|
};
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
998
|
+
|
|
999
|
+
const assetDir = '';
|
|
1000
|
+
|
|
1001
|
+
const getRemoteUrl = (extension, platform$1) => {
|
|
1002
|
+
if (platform === Remote || platform === Electron) {
|
|
1003
|
+
if (extension.builtin) {
|
|
1004
|
+
return `${assetDir}/extensions/${extension.id}/${extension.icon}`;
|
|
1005
|
+
}
|
|
1006
|
+
return `/remote/${extension.path}/${extension.icon}`; // TODO support windows paths
|
|
1007
|
+
}
|
|
1008
|
+
return '';
|
|
1009
|
+
};
|
|
1010
|
+
|
|
1011
|
+
const ExtensionDefaultIcon = `${assetDir}/icons/extensionDefaultIcon.png`;
|
|
1012
|
+
const ExtensionLanguageBasics = `${assetDir}/icons/language-icon.svg`;
|
|
1013
|
+
const ExtensionTheme = `${assetDir}/icons/theme-icon.png`;
|
|
1014
|
+
|
|
1015
|
+
const isLanguageBasicsExtension = extension => {
|
|
1016
|
+
return extension.name && extension.name.startsWith('Language Basics');
|
|
1017
|
+
};
|
|
1018
|
+
const isThemeExtension = extension => {
|
|
1019
|
+
return extension.name && extension.name.endsWith(' Theme');
|
|
1020
|
+
};
|
|
1021
|
+
const getIcon = (extension, platform) => {
|
|
1022
|
+
if (!extension) {
|
|
1023
|
+
return ExtensionDefaultIcon;
|
|
1024
|
+
}
|
|
1025
|
+
if (!extension.path || !extension.icon) {
|
|
1026
|
+
if (isLanguageBasicsExtension(extension)) {
|
|
1027
|
+
return ExtensionLanguageBasics;
|
|
1028
|
+
}
|
|
1029
|
+
if (isThemeExtension(extension)) {
|
|
1030
|
+
return ExtensionTheme;
|
|
1031
|
+
}
|
|
1032
|
+
return ExtensionDefaultIcon;
|
|
1033
|
+
}
|
|
1034
|
+
return getRemoteUrl(extension);
|
|
1035
|
+
};
|
|
1036
|
+
const RE_PUBLISHER = /^[a-z\d-]+/;
|
|
1037
|
+
|
|
1038
|
+
// TODO handle case when extension is of type number|array|null|string
|
|
1039
|
+
const getPublisher = extension => {
|
|
1040
|
+
if (!extension || !extension.id) {
|
|
1041
|
+
return 'n/a';
|
|
1042
|
+
}
|
|
1043
|
+
// TODO handle case when id is not of type string -> should not crash application
|
|
1044
|
+
const match = extension.id.match(RE_PUBLISHER);
|
|
1045
|
+
if (!match) {
|
|
1046
|
+
return 'n/a';
|
|
1047
|
+
}
|
|
1048
|
+
return match[0];
|
|
1049
|
+
};
|
|
1050
|
+
const getName = extension => {
|
|
1051
|
+
if (extension && extension.name) {
|
|
1052
|
+
return extension.name;
|
|
1065
1053
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
const walkValue = (value, transferrables, isTransferrable) => {
|
|
1069
|
-
if (!value) {
|
|
1070
|
-
return;
|
|
1054
|
+
if (extension && extension.id) {
|
|
1055
|
+
return extension.id;
|
|
1071
1056
|
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1057
|
+
return 'n/a';
|
|
1058
|
+
};
|
|
1059
|
+
const getDescription = extension => {
|
|
1060
|
+
if (!extension || !extension.description) {
|
|
1061
|
+
return 'n/a';
|
|
1075
1062
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
return;
|
|
1063
|
+
return extension.description;
|
|
1064
|
+
};
|
|
1065
|
+
const getId = extension => {
|
|
1066
|
+
if (!extension || !extension.id) {
|
|
1067
|
+
return 'n/a';
|
|
1081
1068
|
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1069
|
+
return extension.id;
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
const matchesParsedValue = (extension, parsedValue) => {
|
|
1073
|
+
if (extension && typeof extension.name === 'string') {
|
|
1074
|
+
const extensionNameLower = extension.name.toLowerCase();
|
|
1075
|
+
return extensionNameLower.includes(parsedValue.query);
|
|
1076
|
+
}
|
|
1077
|
+
if (extension && typeof extension.id === 'string') {
|
|
1078
|
+
const extensionIdLower = extension.id.toLowerCase();
|
|
1079
|
+
return extensionIdLower.includes(parsedValue.query);
|
|
1087
1080
|
}
|
|
1081
|
+
return false;
|
|
1088
1082
|
};
|
|
1089
|
-
|
|
1090
|
-
|
|
1083
|
+
|
|
1084
|
+
const toSorted = (array, compare) => {
|
|
1085
|
+
return [...array].sort(compare);
|
|
1091
1086
|
};
|
|
1092
|
-
|
|
1093
|
-
|
|
1087
|
+
|
|
1088
|
+
const compareExtension = (extensionA, extensionB) => {
|
|
1089
|
+
return extensionA.name.localeCompare(extensionB.name) || extensionA.id.localeCompare(extensionB.id);
|
|
1094
1090
|
};
|
|
1095
|
-
|
|
1096
|
-
|
|
1091
|
+
|
|
1092
|
+
const sortExtensions = extensions => {
|
|
1093
|
+
return toSorted(extensions, compareExtension);
|
|
1097
1094
|
};
|
|
1098
|
-
|
|
1099
|
-
|
|
1095
|
+
|
|
1096
|
+
const getExtensions = async (extensions, parsedValue, platform) => {
|
|
1097
|
+
const filteredExtensions = [];
|
|
1098
|
+
for (const extension of extensions) {
|
|
1099
|
+
if (matchesParsedValue(extension, parsedValue)) {
|
|
1100
|
+
filteredExtensions.push({
|
|
1101
|
+
name: getName(extension),
|
|
1102
|
+
id: getId(extension),
|
|
1103
|
+
publisher: getPublisher(extension),
|
|
1104
|
+
icon: getIcon(extension),
|
|
1105
|
+
description: getDescription(extension)
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
const sortedExtensions = sortExtensions(filteredExtensions);
|
|
1110
|
+
return sortedExtensions;
|
|
1100
1111
|
};
|
|
1101
|
-
|
|
1102
|
-
|
|
1112
|
+
|
|
1113
|
+
const searchExtensions = async (extensions, value, platform$1) => {
|
|
1114
|
+
try {
|
|
1115
|
+
const parsedValue = parseValue(value);
|
|
1116
|
+
const filteredExtensions = await getExtensions(extensions, parsedValue, platform$1 || platform);
|
|
1117
|
+
return filteredExtensions;
|
|
1118
|
+
} catch (error) {
|
|
1119
|
+
throw new VError(error, 'Failed to search for extensions');
|
|
1120
|
+
}
|
|
1103
1121
|
};
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1122
|
+
|
|
1123
|
+
// TODO debounce
|
|
1124
|
+
const handleInput = async (state, value) => {
|
|
1125
|
+
try {
|
|
1126
|
+
const {
|
|
1127
|
+
allExtensions,
|
|
1128
|
+
itemHeight,
|
|
1129
|
+
minimumSliderSize,
|
|
1130
|
+
height,
|
|
1131
|
+
platform: platform$1
|
|
1132
|
+
} = state;
|
|
1133
|
+
// TODO cancel ongoing requests
|
|
1134
|
+
// TODO handle errors
|
|
1135
|
+
const items = await searchExtensions(allExtensions, value, platform$1 || platform);
|
|
1136
|
+
if (items.length === 0) {
|
|
1137
|
+
return {
|
|
1138
|
+
...state,
|
|
1139
|
+
items,
|
|
1140
|
+
minLineY: 0,
|
|
1141
|
+
deltaY: 0,
|
|
1142
|
+
allExtensions,
|
|
1143
|
+
maxLineY: 0,
|
|
1144
|
+
scrollBarHeight: 0,
|
|
1145
|
+
finalDeltaY: 0,
|
|
1146
|
+
message: noExtensionsFound(),
|
|
1147
|
+
searchValue: value,
|
|
1148
|
+
placeholder: searchExtensionsInMarketPlace()
|
|
1149
|
+
};
|
|
1109
1150
|
}
|
|
1151
|
+
// @ts-ignore
|
|
1152
|
+
const listHeight = getListHeight$1(state);
|
|
1153
|
+
const total = items.length;
|
|
1154
|
+
const contentHeight = total * itemHeight;
|
|
1155
|
+
const scrollBarHeight = getScrollBarSize(height, contentHeight, minimumSliderSize);
|
|
1156
|
+
const numberOfVisible = getNumberOfVisibleItems(listHeight, itemHeight);
|
|
1157
|
+
const maxLineY = Math.min(numberOfVisible, total);
|
|
1158
|
+
const finalDeltaY = getFinalDeltaY(listHeight, itemHeight, total);
|
|
1159
|
+
return {
|
|
1160
|
+
...state,
|
|
1161
|
+
items,
|
|
1162
|
+
minLineY: 0,
|
|
1163
|
+
deltaY: 0,
|
|
1164
|
+
allExtensions,
|
|
1165
|
+
maxLineY,
|
|
1166
|
+
scrollBarHeight,
|
|
1167
|
+
finalDeltaY,
|
|
1168
|
+
message: '',
|
|
1169
|
+
searchValue: value,
|
|
1170
|
+
placeholder: searchExtensionsInMarketPlace()
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1173
|
+
// TODO handle out of order responses (a bit complicated)
|
|
1174
|
+
// for now just assume everything comes back in order
|
|
1175
|
+
} catch (error) {
|
|
1176
|
+
handleError(error);
|
|
1177
|
+
return {
|
|
1178
|
+
...state,
|
|
1179
|
+
searchValue: value,
|
|
1180
|
+
message: `${error}`
|
|
1181
|
+
};
|
|
1110
1182
|
}
|
|
1111
|
-
return false;
|
|
1112
1183
|
};
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
return transferrables;
|
|
1184
|
+
|
|
1185
|
+
const clearSearchResults = state => {
|
|
1186
|
+
return handleInput(state, '');
|
|
1117
1187
|
};
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1188
|
+
|
|
1189
|
+
const Enter = 3;
|
|
1190
|
+
const Space = 9;
|
|
1191
|
+
const PageUp = 10;
|
|
1192
|
+
const PageDown = 11;
|
|
1193
|
+
const End = 255;
|
|
1194
|
+
const Home = 12;
|
|
1195
|
+
const UpArrow = 14;
|
|
1196
|
+
const DownArrow = 16;
|
|
1197
|
+
|
|
1198
|
+
const CtrlCmd = 1 << 11 >>> 0;
|
|
1199
|
+
|
|
1200
|
+
const FocusExtensions = 15;
|
|
1201
|
+
|
|
1202
|
+
const getKeyBindings = () => {
|
|
1203
|
+
return [{
|
|
1204
|
+
key: Home,
|
|
1205
|
+
command: 'Extensions.focusFirst',
|
|
1206
|
+
when: FocusExtensions
|
|
1207
|
+
}, {
|
|
1208
|
+
key: End,
|
|
1209
|
+
command: 'Extensions.focusLast',
|
|
1210
|
+
when: FocusExtensions
|
|
1211
|
+
}, {
|
|
1212
|
+
key: PageUp,
|
|
1213
|
+
command: 'Extensions.focusPreviousPage',
|
|
1214
|
+
when: FocusExtensions
|
|
1215
|
+
}, {
|
|
1216
|
+
key: PageDown,
|
|
1217
|
+
command: 'Extensions.focusNextPage',
|
|
1218
|
+
when: FocusExtensions
|
|
1219
|
+
}, {
|
|
1220
|
+
key: UpArrow,
|
|
1221
|
+
command: 'Extensions.focusPrevious',
|
|
1222
|
+
when: FocusExtensions
|
|
1223
|
+
}, {
|
|
1224
|
+
key: DownArrow,
|
|
1225
|
+
command: 'Extensions.focusNext',
|
|
1226
|
+
when: FocusExtensions
|
|
1227
|
+
}, {
|
|
1228
|
+
key: Space,
|
|
1229
|
+
command: 'Extensions.handleClickCurrentButKeepFocus',
|
|
1230
|
+
when: FocusExtensions
|
|
1231
|
+
}, {
|
|
1232
|
+
key: Enter,
|
|
1233
|
+
command: 'Extensions.handleClickCurrent',
|
|
1234
|
+
when: FocusExtensions
|
|
1235
|
+
}, {
|
|
1236
|
+
key: CtrlCmd | Space,
|
|
1237
|
+
command: 'Extensions.toggleSuggest',
|
|
1238
|
+
when: FocusExtensions
|
|
1239
|
+
}, {
|
|
1240
|
+
key: CtrlCmd | DownArrow,
|
|
1241
|
+
command: 'Extensions.scrollDown',
|
|
1242
|
+
when: FocusExtensions
|
|
1243
|
+
}];
|
|
1124
1244
|
};
|
|
1125
|
-
|
|
1126
|
-
|
|
1245
|
+
|
|
1246
|
+
const Button = 1;
|
|
1247
|
+
|
|
1248
|
+
const ExtensionActions = 'ExtensionActions';
|
|
1249
|
+
const ExtensionActive = 'ExtensionActive';
|
|
1250
|
+
const ExtensionHeader = 'ExtensionHeader';
|
|
1251
|
+
const ExtensionListItem = 'ExtensionListItem';
|
|
1252
|
+
const ExtensionListItemAuthorName = 'ExtensionListItemAuthorName';
|
|
1253
|
+
const ExtensionListItemDescription = 'ExtensionListItemDescription';
|
|
1254
|
+
const ExtensionListItemDetail = 'ExtensionListItemDetail';
|
|
1255
|
+
const ExtensionListItemFooter = 'ExtensionListItemFooter';
|
|
1256
|
+
const ExtensionListItemIcon = 'ExtensionListItemIcon';
|
|
1257
|
+
const ExtensionListItemName = 'ExtensionListItemName';
|
|
1258
|
+
const ListItems = 'ListItems';
|
|
1259
|
+
const MultilineInputBox = 'MultilineInputBox';
|
|
1260
|
+
const ScrollBarThumb = 'ScrollBarThumb';
|
|
1261
|
+
const ScrollBarThumbActive = 'ScrollBarThumbActive';
|
|
1262
|
+
const SearchField = 'SearchField';
|
|
1263
|
+
const SearchFieldButtons = 'SearchFieldButtons';
|
|
1264
|
+
const SearchFieldContainer = 'SearchFieldContainer';
|
|
1265
|
+
|
|
1266
|
+
const CheckBox = 'checkbox';
|
|
1267
|
+
const List = 'list';
|
|
1268
|
+
const ListItem = 'listitem';
|
|
1269
|
+
const None = 'none';
|
|
1270
|
+
|
|
1271
|
+
const Div = 4;
|
|
1272
|
+
const Text = 12;
|
|
1273
|
+
const Img = 17;
|
|
1274
|
+
const TextArea = 62;
|
|
1275
|
+
|
|
1276
|
+
const getSearchFieldButtonVirtualDom = button => {
|
|
1277
|
+
const {
|
|
1278
|
+
icon,
|
|
1279
|
+
checked,
|
|
1280
|
+
title
|
|
1281
|
+
} = button;
|
|
1282
|
+
return [{
|
|
1283
|
+
type: Div,
|
|
1284
|
+
className: `SearchFieldButton ${checked ? 'SearchFieldButtonChecked' : ''}`,
|
|
1285
|
+
title,
|
|
1286
|
+
role: CheckBox,
|
|
1287
|
+
ariaChecked: checked,
|
|
1288
|
+
tabIndex: 0,
|
|
1289
|
+
childCount: 1
|
|
1290
|
+
}, {
|
|
1291
|
+
type: Div,
|
|
1292
|
+
className: `MaskIcon ${icon}`,
|
|
1293
|
+
childCount: 0
|
|
1294
|
+
}];
|
|
1127
1295
|
};
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1296
|
+
|
|
1297
|
+
const getSearchFieldVirtualDom = (name, placeholder, onInput, insideButtons, outsideButtons, onFocus = '') => {
|
|
1298
|
+
const dom = [{
|
|
1299
|
+
type: Div,
|
|
1300
|
+
className: SearchField,
|
|
1301
|
+
role: None,
|
|
1302
|
+
childCount: 2
|
|
1303
|
+
}, {
|
|
1304
|
+
type: TextArea,
|
|
1305
|
+
className: MultilineInputBox,
|
|
1306
|
+
spellcheck: false,
|
|
1307
|
+
autocapitalize: 'off',
|
|
1308
|
+
autocorrect: 'off',
|
|
1309
|
+
placeholder,
|
|
1310
|
+
name,
|
|
1311
|
+
onInput,
|
|
1312
|
+
onFocus,
|
|
1313
|
+
childCount: 0
|
|
1314
|
+
}, {
|
|
1315
|
+
type: Div,
|
|
1316
|
+
className: SearchFieldButtons,
|
|
1317
|
+
childCount: insideButtons.length
|
|
1318
|
+
}, ...insideButtons.flatMap(getSearchFieldButtonVirtualDom)];
|
|
1319
|
+
if (outsideButtons.length > 0) {
|
|
1320
|
+
dom.unshift({
|
|
1321
|
+
type: Div,
|
|
1322
|
+
className: SearchFieldContainer,
|
|
1323
|
+
role: None,
|
|
1324
|
+
childCount: 1 + outsideButtons.length
|
|
1325
|
+
});
|
|
1326
|
+
dom.push(...outsideButtons.flatMap(getSearchFieldButtonVirtualDom));
|
|
1149
1327
|
}
|
|
1150
|
-
|
|
1151
|
-
const wrap$5 = global => {
|
|
1152
|
-
return new IpcChildWithModuleWorker(global);
|
|
1153
|
-
};
|
|
1154
|
-
const IpcChildWithModuleWorker$1 = {
|
|
1155
|
-
__proto__: null,
|
|
1156
|
-
listen: listen$2,
|
|
1157
|
-
signal: signal$2,
|
|
1158
|
-
wrap: wrap$5
|
|
1159
|
-
};
|
|
1160
|
-
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
1161
|
-
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
1162
|
-
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
1163
|
-
const NewLine$1 = '\n';
|
|
1164
|
-
const joinLines = lines => {
|
|
1165
|
-
return lines.join(NewLine$1);
|
|
1166
|
-
};
|
|
1167
|
-
const splitLines = lines => {
|
|
1168
|
-
return lines.split(NewLine$1);
|
|
1328
|
+
return dom;
|
|
1169
1329
|
};
|
|
1170
|
-
|
|
1171
|
-
|
|
1330
|
+
|
|
1331
|
+
const getExtensionHeaderVirtualDom = (placeholder, actions) => {
|
|
1332
|
+
return [{
|
|
1333
|
+
type: Div,
|
|
1334
|
+
className: ExtensionHeader,
|
|
1335
|
+
childCount: 1
|
|
1336
|
+
}, ...getSearchFieldVirtualDom('extensions', placeholder, 'handleExtensionsInput', actions, [])];
|
|
1172
1337
|
};
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1338
|
+
|
|
1339
|
+
const HandleContextMenu = 'handleContextMenu';
|
|
1340
|
+
const HandlePointerDown = 'handlePointerDown';
|
|
1341
|
+
const HandleTouchStart = 'handleTouchStart';
|
|
1342
|
+
const HandleWheel = 'handleWheel';
|
|
1343
|
+
|
|
1344
|
+
const Extension = 'Extension';
|
|
1345
|
+
|
|
1346
|
+
const text = data => {
|
|
1177
1347
|
return {
|
|
1178
|
-
|
|
1179
|
-
|
|
1348
|
+
type: Text,
|
|
1349
|
+
text: data,
|
|
1350
|
+
childCount: 0
|
|
1180
1351
|
};
|
|
1181
1352
|
};
|
|
1182
|
-
|
|
1183
|
-
const
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
1188
|
-
const isUnhelpfulNativeModuleError = stderr => {
|
|
1189
|
-
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
1190
|
-
};
|
|
1191
|
-
const isMessageCodeBlockStartIndex = line => {
|
|
1192
|
-
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
1193
|
-
};
|
|
1194
|
-
const isMessageCodeBlockEndIndex = line => {
|
|
1195
|
-
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
1353
|
+
|
|
1354
|
+
const listItemDetail = {
|
|
1355
|
+
type: Div,
|
|
1356
|
+
className: ExtensionListItemDetail,
|
|
1357
|
+
childCount: 3
|
|
1196
1358
|
};
|
|
1197
|
-
const
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
const relevantLines = lines.slice(startIndex, endIndex);
|
|
1202
|
-
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
1203
|
-
return relevantMessage;
|
|
1359
|
+
const listItemName = {
|
|
1360
|
+
type: Div,
|
|
1361
|
+
className: ExtensionListItemName,
|
|
1362
|
+
childCount: 1
|
|
1204
1363
|
};
|
|
1205
|
-
const
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
1210
|
-
};
|
|
1364
|
+
const listItemDescription = {
|
|
1365
|
+
type: Div,
|
|
1366
|
+
className: ExtensionListItemDescription,
|
|
1367
|
+
childCount: 1
|
|
1211
1368
|
};
|
|
1212
|
-
const
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
1369
|
+
const listItemFooter = {
|
|
1370
|
+
type: Div,
|
|
1371
|
+
className: ExtensionListItemFooter,
|
|
1372
|
+
childCount: 2
|
|
1217
1373
|
};
|
|
1218
|
-
const
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
};
|
|
1374
|
+
const listItemAuthorName = {
|
|
1375
|
+
type: Div,
|
|
1376
|
+
className: ExtensionListItemAuthorName,
|
|
1377
|
+
childCount: 1
|
|
1223
1378
|
};
|
|
1224
|
-
const
|
|
1225
|
-
|
|
1226
|
-
|
|
1379
|
+
const getExtensionListItemVirtualDom = extension => {
|
|
1380
|
+
const {
|
|
1381
|
+
posInSet,
|
|
1382
|
+
setSize,
|
|
1383
|
+
top,
|
|
1384
|
+
icon,
|
|
1385
|
+
name,
|
|
1386
|
+
description,
|
|
1387
|
+
publisher,
|
|
1388
|
+
focused
|
|
1389
|
+
} = extension;
|
|
1390
|
+
const dom = [{
|
|
1391
|
+
type: Div,
|
|
1392
|
+
role: ListItem,
|
|
1393
|
+
ariaRoleDescription: Extension,
|
|
1394
|
+
className: ExtensionListItem,
|
|
1395
|
+
ariaPosInSet: posInSet,
|
|
1396
|
+
ariaSetSize: setSize,
|
|
1397
|
+
top,
|
|
1398
|
+
childCount: 2
|
|
1399
|
+
}, {
|
|
1400
|
+
type: Img,
|
|
1401
|
+
src: icon,
|
|
1402
|
+
className: ExtensionListItemIcon,
|
|
1403
|
+
role: None,
|
|
1404
|
+
childCount: 0
|
|
1405
|
+
}, listItemDetail, listItemName, text(name), listItemDescription, text(description), listItemFooter, listItemAuthorName, text(publisher), {
|
|
1406
|
+
type: Div,
|
|
1407
|
+
className: ExtensionActions,
|
|
1408
|
+
childCount: 0
|
|
1409
|
+
}];
|
|
1410
|
+
if (focused) {
|
|
1411
|
+
dom[0].id = 'ExtensionActive';
|
|
1412
|
+
dom[0].className += ' ' + ExtensionActive;
|
|
1227
1413
|
}
|
|
1228
|
-
return
|
|
1414
|
+
return dom;
|
|
1229
1415
|
};
|
|
1230
|
-
|
|
1231
|
-
|
|
1416
|
+
|
|
1417
|
+
const getExtensionsListVirtualDom = visibleExtensions => {
|
|
1418
|
+
const dom = [{
|
|
1419
|
+
type: Div,
|
|
1420
|
+
className: ListItems,
|
|
1421
|
+
tabIndex: 0,
|
|
1422
|
+
ariaLabel: extensions(),
|
|
1423
|
+
role: List,
|
|
1424
|
+
oncontextmenu: HandleContextMenu,
|
|
1425
|
+
onpointerdown: HandlePointerDown,
|
|
1426
|
+
ontouchstart: HandleTouchStart,
|
|
1427
|
+
onwheelpassive: HandleWheel,
|
|
1428
|
+
childCount: visibleExtensions.length
|
|
1429
|
+
}, ...visibleExtensions.flatMap(getExtensionListItemVirtualDom)];
|
|
1430
|
+
return dom;
|
|
1232
1431
|
};
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
rest: []
|
|
1239
|
-
};
|
|
1240
|
-
}
|
|
1241
|
-
let lastIndex = index - 1;
|
|
1242
|
-
while (++lastIndex < lines.length) {
|
|
1243
|
-
if (!isNormalStackLine(lines[lastIndex])) {
|
|
1244
|
-
break;
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
return {
|
|
1248
|
-
actualMessage: lines[index - 1],
|
|
1249
|
-
rest: lines.slice(index, lastIndex)
|
|
1250
|
-
};
|
|
1432
|
+
|
|
1433
|
+
const getExtensionsVirtualDom = visibleExtensions => {
|
|
1434
|
+
const dom = getExtensionsListVirtualDom(visibleExtensions);
|
|
1435
|
+
// TODO
|
|
1436
|
+
return dom;
|
|
1251
1437
|
};
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
return getNativeModuleErrorMessage(stderr);
|
|
1255
|
-
}
|
|
1256
|
-
if (isModulesSyntaxError(stderr)) {
|
|
1257
|
-
return getModuleSyntaxError();
|
|
1258
|
-
}
|
|
1259
|
-
if (isModuleNotFoundError(stderr)) {
|
|
1260
|
-
return getModuleNotFoundError(stderr);
|
|
1261
|
-
}
|
|
1262
|
-
const lines = splitLines(stderr);
|
|
1263
|
-
const {
|
|
1264
|
-
actualMessage,
|
|
1265
|
-
rest
|
|
1266
|
-
} = getDetails(lines);
|
|
1438
|
+
|
|
1439
|
+
const getVisibleItem = (item, setSize, itemHeight, minLineY, relative, i, focusedIndex) => {
|
|
1267
1440
|
return {
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1441
|
+
...item,
|
|
1442
|
+
setSize,
|
|
1443
|
+
posInSet: i + 1,
|
|
1444
|
+
top: (i - minLineY) * itemHeight - relative,
|
|
1445
|
+
focused: i === focusedIndex
|
|
1271
1446
|
};
|
|
1272
1447
|
};
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1448
|
+
const getVisible = state => {
|
|
1449
|
+
const {
|
|
1450
|
+
minLineY,
|
|
1451
|
+
maxLineY,
|
|
1452
|
+
items,
|
|
1453
|
+
itemHeight,
|
|
1454
|
+
deltaY,
|
|
1455
|
+
focusedIndex
|
|
1456
|
+
} = state;
|
|
1457
|
+
const setSize = items.length;
|
|
1458
|
+
const visible = [];
|
|
1459
|
+
const relative = deltaY % itemHeight;
|
|
1460
|
+
for (let i = minLineY; i < maxLineY; i++) {
|
|
1461
|
+
const item = items[i];
|
|
1462
|
+
visible.push(getVisibleItem(item, setSize, itemHeight, minLineY, relative, i, focusedIndex));
|
|
1279
1463
|
}
|
|
1280
|
-
return
|
|
1464
|
+
return visible;
|
|
1281
1465
|
};
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
return
|
|
1466
|
+
|
|
1467
|
+
const ClearAll = 'ClearAll';
|
|
1468
|
+
const Filter = 'Filter';
|
|
1469
|
+
|
|
1470
|
+
const px = value => {
|
|
1471
|
+
return `${value}px`;
|
|
1288
1472
|
};
|
|
1289
|
-
const
|
|
1290
|
-
|
|
1291
|
-
return string.indexOf(NewLine, startIndex);
|
|
1473
|
+
const position = (x, y) => {
|
|
1474
|
+
return `${x}px ${y}px`;
|
|
1292
1475
|
};
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
1305
|
-
if (parentFirstLine.includes(childFirstLine)) {
|
|
1306
|
-
return parentFirstLine + childRest;
|
|
1307
|
-
}
|
|
1308
|
-
return child;
|
|
1476
|
+
|
|
1477
|
+
const SetMessage = 'setMessage';
|
|
1478
|
+
const SetScrollBar = 'setScrollBar';
|
|
1479
|
+
const SetSearchValue = 'setSearchValue';
|
|
1480
|
+
|
|
1481
|
+
const getListHeight = state => {
|
|
1482
|
+
const {
|
|
1483
|
+
height,
|
|
1484
|
+
headerHeight
|
|
1485
|
+
} = state;
|
|
1486
|
+
return height - headerHeight;
|
|
1309
1487
|
};
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
// @ts-ignore
|
|
1320
|
-
this.codeFrame = error.codeFrame;
|
|
1321
|
-
}
|
|
1322
|
-
if (error.code) {
|
|
1323
|
-
// @ts-ignore
|
|
1324
|
-
this.code = error.code;
|
|
1325
|
-
}
|
|
1488
|
+
const renderExtensions = {
|
|
1489
|
+
isEqual(oldState, newState) {
|
|
1490
|
+
return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.deltaY === newState.deltaY && oldState.focusedIndex === newState.focusedIndex;
|
|
1491
|
+
},
|
|
1492
|
+
apply(oldState, newState) {
|
|
1493
|
+
// TODO render extensions incrementally when scrolling
|
|
1494
|
+
const visibleExtensions = getVisible(newState);
|
|
1495
|
+
const dom = getExtensionsVirtualDom(visibleExtensions);
|
|
1496
|
+
return ['setExtensionsDom', dom];
|
|
1326
1497
|
}
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
const {
|
|
1334
|
-
message,
|
|
1335
|
-
code,
|
|
1336
|
-
stack
|
|
1337
|
-
} = getHelpfulChildProcessError(stdout, stderr);
|
|
1338
|
-
const cause = new Error(message);
|
|
1339
|
-
// @ts-ignore
|
|
1340
|
-
cause.code = code;
|
|
1341
|
-
cause.stack = stack;
|
|
1342
|
-
super(cause, betterMessage);
|
|
1343
|
-
} else {
|
|
1344
|
-
super(betterMessage);
|
|
1345
|
-
}
|
|
1346
|
-
// @ts-ignore
|
|
1347
|
-
this.name = 'IpcError';
|
|
1348
|
-
// @ts-ignore
|
|
1349
|
-
this.stdout = stdout;
|
|
1498
|
+
};
|
|
1499
|
+
const renderScrollBar = {
|
|
1500
|
+
isEqual(oldState, newState) {
|
|
1501
|
+
return oldState.negativeMargin === newState.negativeMargin && oldState.deltaY === newState.deltaY && oldState.height === newState.height && oldState.finalDeltaY === newState.finalDeltaY && oldState.items.length === newState.items.length && oldState.scrollBarActive === newState.scrollBarActive;
|
|
1502
|
+
},
|
|
1503
|
+
apply(oldState, newState) {
|
|
1350
1504
|
// @ts-ignore
|
|
1351
|
-
|
|
1505
|
+
const listHeight = getListHeight(newState);
|
|
1506
|
+
const total = newState.items.length;
|
|
1507
|
+
const contentHeight = total * newState.itemHeight;
|
|
1508
|
+
const scrollBarHeight = getScrollBarSize(listHeight, contentHeight, newState.minimumSliderSize);
|
|
1509
|
+
const scrollBarY = getScrollBarY(newState.deltaY, newState.finalDeltaY, newState.height - newState.headerHeight, scrollBarHeight);
|
|
1510
|
+
const roundedScrollBarY = Math.round(scrollBarY);
|
|
1511
|
+
const heightString = px(scrollBarHeight);
|
|
1512
|
+
const translateString = position(0, roundedScrollBarY);
|
|
1513
|
+
let className = ScrollBarThumb;
|
|
1514
|
+
if (newState.scrollBarActive) {
|
|
1515
|
+
className += ' ' + ScrollBarThumbActive;
|
|
1516
|
+
}
|
|
1517
|
+
return [/* method */SetScrollBar, translateString, heightString, className];
|
|
1352
1518
|
}
|
|
1353
|
-
}
|
|
1354
|
-
const withResolvers = () => {
|
|
1355
|
-
let _resolve;
|
|
1356
|
-
const promise = new Promise(resolve => {
|
|
1357
|
-
_resolve = resolve;
|
|
1358
|
-
});
|
|
1359
|
-
return {
|
|
1360
|
-
resolve: _resolve,
|
|
1361
|
-
promise
|
|
1362
|
-
};
|
|
1363
|
-
};
|
|
1364
|
-
const waitForFirstMessage = async port => {
|
|
1365
|
-
const {
|
|
1366
|
-
resolve,
|
|
1367
|
-
promise
|
|
1368
|
-
} = withResolvers();
|
|
1369
|
-
port.addEventListener('message', resolve, {
|
|
1370
|
-
once: true
|
|
1371
|
-
});
|
|
1372
|
-
const event = await promise;
|
|
1373
|
-
// @ts-ignore
|
|
1374
|
-
return event.data;
|
|
1375
1519
|
};
|
|
1376
|
-
const
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
throw new IpcError('unexpected first message');
|
|
1383
|
-
}
|
|
1384
|
-
const type = firstMessage.params[0];
|
|
1385
|
-
if (type === 'message-port') {
|
|
1386
|
-
parentIpc.send({
|
|
1387
|
-
jsonrpc: '2.0',
|
|
1388
|
-
id: firstMessage.id,
|
|
1389
|
-
result: null
|
|
1390
|
-
});
|
|
1391
|
-
parentIpc.dispose();
|
|
1392
|
-
const port = firstMessage.params[1];
|
|
1393
|
-
return port;
|
|
1520
|
+
const renderMessage = {
|
|
1521
|
+
isEqual(oldState, newState) {
|
|
1522
|
+
return oldState.message === newState.message;
|
|
1523
|
+
},
|
|
1524
|
+
apply(oldState, newState) {
|
|
1525
|
+
return [/* method */SetMessage, /* message */newState.message];
|
|
1394
1526
|
}
|
|
1395
|
-
return globalThis;
|
|
1396
1527
|
};
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
return
|
|
1403
|
-
}
|
|
1404
|
-
send(message) {
|
|
1405
|
-
this._rawIpc.postMessage(message);
|
|
1528
|
+
const renderSearchValue = {
|
|
1529
|
+
isEqual(oldState, newState) {
|
|
1530
|
+
return oldState.searchValue === newState.searchValue;
|
|
1531
|
+
},
|
|
1532
|
+
apply(oldState, newState) {
|
|
1533
|
+
return [/* method */SetSearchValue, oldState.searchValue, newState.searchValue];
|
|
1406
1534
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1535
|
+
};
|
|
1536
|
+
const renderHeader = {
|
|
1537
|
+
isEqual(oldState, newState) {
|
|
1538
|
+
return oldState.placeholder === newState.placeholder;
|
|
1539
|
+
},
|
|
1540
|
+
apply(oldState, newState) {
|
|
1541
|
+
const actions = [{
|
|
1542
|
+
type: Button,
|
|
1543
|
+
title: clearExtensionSearchResults(),
|
|
1544
|
+
icon: `MaskIcon${ClearAll}`,
|
|
1545
|
+
command: 'Extensions.clearSearchResults'
|
|
1546
|
+
}, {
|
|
1547
|
+
type: Button,
|
|
1548
|
+
title: filter(),
|
|
1549
|
+
icon: `MaskIcon${Filter}`
|
|
1550
|
+
}];
|
|
1551
|
+
const dom = getExtensionHeaderVirtualDom(newState.placeholder, actions);
|
|
1552
|
+
return ['setHeaderDom', dom];
|
|
1410
1553
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1554
|
+
};
|
|
1555
|
+
const render = [renderScrollBar, renderMessage, renderExtensions, renderSearchValue, renderHeader];
|
|
1556
|
+
const doRender = (oldState, newState) => {
|
|
1557
|
+
const commands = [];
|
|
1558
|
+
for (const item of render) {
|
|
1559
|
+
if (!item.isEqual(oldState, newState)) {
|
|
1560
|
+
commands.push(item.apply(oldState, newState));
|
|
1414
1561
|
}
|
|
1415
1562
|
}
|
|
1416
|
-
|
|
1417
|
-
// ignore
|
|
1418
|
-
}
|
|
1419
|
-
onMessage(callback) {
|
|
1420
|
-
this._rawIpc.addEventListener('message', callback);
|
|
1421
|
-
this._rawIpc.start();
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
const wrap$4 = port => {
|
|
1425
|
-
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
1426
|
-
};
|
|
1427
|
-
const IpcChildWithModuleWorkerAndMessagePort$1 = {
|
|
1428
|
-
__proto__: null,
|
|
1429
|
-
listen: listen$1$1,
|
|
1430
|
-
wrap: wrap$4
|
|
1563
|
+
return commands;
|
|
1431
1564
|
};
|
|
1432
1565
|
|
|
1433
|
-
const
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
return IpcChildWithModuleWorkerAndMessagePort$1;
|
|
1439
|
-
default:
|
|
1440
|
-
throw new Error('unexpected ipc type');
|
|
1441
|
-
}
|
|
1566
|
+
const commandMap = {
|
|
1567
|
+
'SearchExtensions.clearSearchResults': clearSearchResults,
|
|
1568
|
+
'SearchExtensions.getKeyBindings': getKeyBindings,
|
|
1569
|
+
'SearchExtensions.render': doRender,
|
|
1570
|
+
'SearchExtensions.searchExtensions': searchExtensions
|
|
1442
1571
|
};
|
|
1443
1572
|
|
|
1444
|
-
const
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
if (module.signal) {
|
|
1450
|
-
module.signal(rawIpc);
|
|
1451
|
-
}
|
|
1452
|
-
const ipc = module.wrap(rawIpc);
|
|
1453
|
-
return ipc;
|
|
1573
|
+
const RendererWorker = 1;
|
|
1574
|
+
|
|
1575
|
+
const rpcs = Object.create(null);
|
|
1576
|
+
const set = (id, rpc) => {
|
|
1577
|
+
rpcs[id] = rpc;
|
|
1454
1578
|
};
|
|
1455
1579
|
|
|
1456
1580
|
const listen = async () => {
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
method: Auto()
|
|
1581
|
+
const rpc = await WebWorkerRpcClient.create({
|
|
1582
|
+
commandMap: commandMap
|
|
1460
1583
|
});
|
|
1461
|
-
|
|
1584
|
+
set(RendererWorker, rpc);
|
|
1462
1585
|
};
|
|
1463
1586
|
|
|
1464
1587
|
const main = async () => {
|