@lvce-editor/extension-host-worker 5.15.0 → 5.17.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.
@@ -1056,7 +1056,7 @@ const get$a = protocol => {
1056
1056
  }
1057
1057
  return provider;
1058
1058
  };
1059
- const set$9 = (id, provider) => {
1059
+ const set$a = (id, provider) => {
1060
1060
  if (!id) {
1061
1061
  throw new Error('Failed to register file system provider: missing id');
1062
1062
  }
@@ -1067,7 +1067,7 @@ const registerFileSystemProvider = fileSystemProvider => {
1067
1067
  if (!fileSystemProvider.id) {
1068
1068
  throw new Error('Failed to register file system provider: missing id');
1069
1069
  }
1070
- set$9(fileSystemProvider.id, fileSystemProvider);
1070
+ set$a(fileSystemProvider.id, fileSystemProvider);
1071
1071
  };
1072
1072
  const readDirWithFileTypes$2 = async (protocol, path) => {
1073
1073
  try {
@@ -1739,7 +1739,7 @@ const create$4$2 = (method, params) => {
1739
1739
  };
1740
1740
  };
1741
1741
  const callbacks = Object.create(null);
1742
- const set$8 = (id, fn) => {
1742
+ const set$9 = (id, fn) => {
1743
1743
  callbacks[id] = fn;
1744
1744
  };
1745
1745
  const get$9 = id => {
@@ -1758,7 +1758,7 @@ const registerPromise = () => {
1758
1758
  resolve,
1759
1759
  promise
1760
1760
  } = Promise.withResolvers();
1761
- set$8(id, resolve);
1761
+ set$9(id, resolve);
1762
1762
  return {
1763
1763
  id,
1764
1764
  promise
@@ -2570,7 +2570,7 @@ const getExtensionHostSubWorkerUrl = () => {
2570
2570
  };
2571
2571
  const extensionHostSubWorkerUrl = getExtensionHostSubWorkerUrl();
2572
2572
 
2573
- const set$7 = async (url, contentSecurityPolicy) => {
2573
+ const set$8 = async (url, contentSecurityPolicy) => {
2574
2574
  const pathName = new URL(url).pathname;
2575
2575
  await invoke$2('ExtensionHostWorkerContentSecurityPolicy.set', pathName, contentSecurityPolicy);
2576
2576
  };
@@ -2590,7 +2590,7 @@ const createLegacyRpc = async ({
2590
2590
  string(name);
2591
2591
  object(commandMap);
2592
2592
  if (contentSecurityPolicy) {
2593
- await set$7(url, contentSecurityPolicy);
2593
+ await set$8(url, contentSecurityPolicy);
2594
2594
  }
2595
2595
  const rpc = await create$2({
2596
2596
  method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug$1,
@@ -2623,7 +2623,7 @@ const register = (id, execute) => {
2623
2623
  const get$7 = id => {
2624
2624
  return rpcs[id];
2625
2625
  };
2626
- const set$6 = (id, rpc) => {
2626
+ const set$7 = (id, rpc) => {
2627
2627
  rpcs[id] = rpc;
2628
2628
  };
2629
2629
 
@@ -2644,14 +2644,14 @@ const createRpcWithId$1 = async (id, commandMap, execute) => {
2644
2644
  rpc.ipc.execute = execute;
2645
2645
  }
2646
2646
  await rpc.invoke('LoadFile.loadFile', info.url);
2647
- set$6(id, rpc);
2647
+ set$7(id, rpc);
2648
2648
  return rpc;
2649
2649
  };
2650
2650
 
2651
2651
  const getOrCreateRpc = async (id, commandMap, execute) => {
2652
2652
  const rpc = get$7(id);
2653
2653
  if (!rpc) {
2654
- set$6(id, createRpcWithId$1(id, commandMap, execute));
2654
+ set$7(id, createRpcWithId$1(id, commandMap, execute));
2655
2655
  }
2656
2656
  return get$7(id);
2657
2657
  };
@@ -3247,1430 +3247,1494 @@ const setup = ({
3247
3247
  global.vscode = api;
3248
3248
  };
3249
3249
 
3250
- const state$5 = {
3251
- webExtensions: []
3250
+ const create$1 = () => {
3251
+ return {
3252
+ finished: false
3253
+ };
3252
3254
  };
3253
-
3254
- const cache = Object.create(null);
3255
- const id = 1;
3256
- const get$6 = () => {
3257
- return cache[id];
3255
+ const cancel = token => {
3256
+ token.finished = true;
3258
3257
  };
3259
- const has = () => {
3260
- return id in cache;
3258
+ const isCanceled = token => {
3259
+ return token.finished;
3261
3260
  };
3262
- const set$5 = value => {
3263
- cache[id] = value;
3261
+
3262
+ const modules = Object.create(null);
3263
+ const set$6 = (extensionId, module) => {
3264
+ modules[extensionId] = module;
3264
3265
  };
3265
- const clear = () => {
3266
- delete cache[id];
3266
+ const acquire = extensionId => {
3267
+ const module = modules[extensionId];
3268
+ delete modules[extensionId];
3269
+ return module;
3267
3270
  };
3268
3271
 
3269
- const getJson = async url => {
3270
- try {
3271
- const response = await fetch(url);
3272
- if (!response.ok) {
3273
- throw new Error(response.statusText);
3274
- }
3275
- const json = await response.json();
3276
- return json;
3277
- } catch (error) {
3278
- throw new VError(error, `Failed to get json`);
3272
+ const baseName = path => {
3273
+ const slashIndex = path.lastIndexOf('/');
3274
+ return path.slice(slashIndex + 1);
3275
+ };
3276
+ const getExtensionId = extension => {
3277
+ if (extension && extension.id) {
3278
+ return extension.id;
3279
+ }
3280
+ if (extension && extension.path) {
3281
+ return baseName(extension.path);
3279
3282
  }
3283
+ return '<unknown>';
3280
3284
  };
3281
3285
 
3282
- const NewLine = '\n';
3283
- const Slash$1 = '/';
3286
+ const states = Object.create(null);
3287
+ const set$5 = status => {
3288
+ states[status.id] = status;
3289
+ };
3290
+ const get$6 = extensionId => {
3291
+ return states[extensionId];
3292
+ };
3293
+ const update = (id, update) => {
3294
+ states[id] = {
3295
+ ...states[id],
3296
+ ...update
3297
+ };
3298
+ };
3284
3299
 
3285
- const interExtensionId = path => {
3286
- const slashIndex = path.lastIndexOf(Slash$1);
3287
- return path.slice(slashIndex + 1);
3300
+ const None = 0;
3301
+ const Importing = 1;
3302
+ const Activating = 2;
3303
+ const Activated = 3;
3304
+ const Error$1 = 4;
3305
+
3306
+ const sleep = duration => {
3307
+ const {
3308
+ resolve,
3309
+ promise
3310
+ } = Promise.withResolvers();
3311
+ setTimeout(resolve, duration);
3312
+ return promise;
3288
3313
  };
3289
3314
 
3290
- const getWebExtensionManifest = async (path, manifestPath) => {
3315
+ // TODO make activation timeout configurable or remove it.
3316
+ // some extension might do workspace indexing which could take some time
3317
+ const activationTimeout$1 = 10_000;
3318
+ const rejectAfterTimeout$1 = async (timeout, token) => {
3319
+ await sleep(timeout);
3320
+ if (isCanceled(token)) {
3321
+ return;
3322
+ }
3323
+ throw new Error(`Activation timeout of ${timeout}ms exceeded`);
3324
+ };
3325
+
3326
+ // TODO separate importing extension and activating extension for smaller functions
3327
+ // and better error handling
3328
+ const activateExtension2 = async (extensionId, extension) => {
3329
+ const token = create$1();
3291
3330
  try {
3292
- const manifest = await getJson(manifestPath);
3293
- return {
3294
- ...manifest,
3295
- path,
3296
- uri: path
3297
- };
3331
+ const startTime = performance.now();
3332
+ update(extensionId, {
3333
+ status: Activating,
3334
+ activationStartTime: startTime
3335
+ });
3336
+ const module = acquire(extensionId);
3337
+ await Promise.race([module.activate(extension), rejectAfterTimeout$1(activationTimeout$1, token)]);
3338
+ const endTime = performance.now();
3339
+ const time = endTime - startTime;
3340
+ update(extensionId, {
3341
+ status: Activated,
3342
+ activationTime: time,
3343
+ activationEndTime: endTime
3344
+ });
3298
3345
  } catch (error) {
3299
- const id = interExtensionId(path);
3300
- throw new VError(error, `Failed to load extension manifest for ${id}`);
3346
+ update(extensionId, {
3347
+ status: Error$1 // TODO maybe store error also in runtime status state
3348
+ });
3349
+ const id = getExtensionId(extension);
3350
+ throw new VError(error, `Failed to activate extension ${id}`);
3351
+ } finally {
3352
+ cancel(token);
3301
3353
  }
3302
3354
  };
3303
3355
 
3304
- const getWebManifestPath = path => {
3305
- const manifestPath = `${path}/extension.json`;
3306
- return manifestPath;
3356
+ const getUrlPrefix = (platform, extensionPath) => {
3357
+ if (extensionPath.startsWith('http://') || extensionPath.startsWith('https://')) {
3358
+ return extensionPath;
3359
+ }
3360
+ if (platform === Web) {
3361
+ return extensionPath;
3362
+ }
3363
+ if (extensionPath.startsWith('/')) {
3364
+ return `/remote${extensionPath}`;
3365
+ }
3366
+ return `/remote/${extensionPath}`;
3307
3367
  };
3308
3368
 
3309
- const addWebExtension = async path => {
3310
- const manifestPath = getWebManifestPath(path);
3311
- const manifest = await getWebExtensionManifest(path, manifestPath);
3312
- // TODO avoid mutation if possible
3313
- state$5.webExtensions.push(manifest);
3314
- clear();
3315
- return manifest;
3369
+ const handleRpcInfos = (extension, platform) => {
3370
+ try {
3371
+ if (!extension) {
3372
+ return;
3373
+ }
3374
+ const rpcs = extension.rpc;
3375
+ const urlPrefix = getUrlPrefix(platform, extension.path);
3376
+ if (!rpcs) {
3377
+ return;
3378
+ }
3379
+ if (!Array.isArray(rpcs)) {
3380
+ return;
3381
+ }
3382
+ for (const rpc of rpcs) {
3383
+ rpc.url = `${urlPrefix}/${rpc.url}`;
3384
+ add$1(rpc.id, rpc);
3385
+ }
3386
+ } catch (error) {
3387
+ console.warn(`Failed to handle extension rpcs: ${error}`);
3388
+ }
3316
3389
  };
3317
3390
 
3318
- const applyBulkReplacement = async (files, ranges, replacement) => {
3319
- // eslint-disable-next-line no-console
3320
- console.log({
3321
- files,
3322
- ranges,
3323
- replacement
3324
- });
3325
- throw new Error('not implemented');
3326
- };
3391
+ class ContentSecurityPolicyError extends Error {
3392
+ constructor(violatedDirective, sourceFile, lineNumber, columnNumber) {
3393
+ super(`Content Security Policy Violation: ${violatedDirective}`);
3394
+ this.name = 'ContentSecurityPolicyError';
3395
+ this.stack = sourceFile ? `Content Security Policy Violation
3396
+ at ${sourceFile}:${lineNumber}:${columnNumber}` : `Content Security Policy Violation
3397
+ at <unknown>`;
3398
+ }
3399
+ }
3327
3400
 
3328
- const addCssStyleSheet = (id, css) => {
3329
- return invoke$2('Css.addCssStyleSheet', id, css);
3401
+ const isImportErrorChrome = error => {
3402
+ return error && error instanceof Error && error.message.startsWith('Failed to fetch dynamically imported module');
3330
3403
  };
3331
3404
 
3332
- const warn = (...args) => {
3333
- console.warn(...args);
3405
+ const isImportErrorFirefox = error => {
3406
+ return error && error instanceof TypeError && error.message === 'error loading dynamically imported module';
3334
3407
  };
3335
3408
 
3336
- const transparent = (color, factor) => {
3337
- return color;
3338
- };
3339
- const toColorRule = ([key, value]) => {
3340
- return ` --${key}: ${value};`;
3409
+ const isSyntaxError = error => {
3410
+ return error instanceof SyntaxError;
3341
3411
  };
3342
- const toTokenColorRule = tokenColor => {
3343
- return `.${tokenColor.name} { color: ${tokenColor.foreground} }`;
3412
+
3413
+ const isImportError = error => {
3414
+ return isImportErrorChrome(error) || isImportErrorFirefox(error) || isSyntaxError(error);
3344
3415
  };
3345
- const addFallbackColors = colors => {
3346
- const newColors = {
3347
- ...colors
3348
- };
3349
- if (!newColors.ActivityBarInactiveForeground) {
3350
- // TODO don't assign, avoid mutation
3351
- newColors.ActivityBarInactiveForeground = transparent(newColors.ActivityBarForeground);
3416
+
3417
+ const NotFound = 404;
3418
+
3419
+ const RE_LINE_COLUMN = /(.*)(?:\(\d+:\d+\))/;
3420
+ const getBabelErrorMessage = message => {
3421
+ const match = message.match(RE_LINE_COLUMN);
3422
+ if (match) {
3423
+ return match[1].trim();
3352
3424
  }
3353
- newColors.CssVariableName ||= colors.VariableName;
3354
- return newColors;
3425
+ return message;
3355
3426
  };
3356
- const createColorThemeFromJson = (colorThemeId, colorThemeJson) => {
3357
- if (!colorThemeJson) {
3358
- warn(`color theme json for "${colorThemeId}" is empty: "${colorThemeJson}"`);
3359
- return '';
3360
- }
3361
- if (typeof colorThemeJson !== 'object') {
3362
- warn(`color theme json for "${colorThemeId}" cannot be converted to css: "${colorThemeJson}"`);
3363
- return '';
3364
- }
3365
- if (Array.isArray(colorThemeJson)) {
3366
- warn(`color theme json for "${colorThemeId}" cannot be converted to css, it must be of type object but was of type array`);
3367
- return '';
3427
+ class BabelParseError extends SyntaxError {
3428
+ constructor(url, error) {
3429
+ const message = getBabelErrorMessage(error.message);
3430
+ super(message);
3431
+ this.name = 'BabelParseError';
3432
+ // @ts-ignore
3433
+ const {
3434
+ line
3435
+ } = error.loc;
3436
+ // @ts-ignore
3437
+ const column = error.loc.column + 1;
3438
+ this.stack = `${message}
3439
+ at ${url}:${line}:${column}`;
3368
3440
  }
3369
- const {
3370
- colors
3371
- } = colorThemeJson;
3372
- if (!colors) {
3373
- return '';
3441
+ }
3442
+
3443
+ const getAssetDir = () => {
3444
+ // @ts-ignore
3445
+ if (typeof ASSET_DIR !== 'undefined') {
3446
+ // @ts-ignore
3447
+ return ASSET_DIR;
3374
3448
  }
3375
- const newColors = addFallbackColors(colors);
3376
- const colorRules = Object.entries(newColors).map(toColorRule);
3377
- const tokenColors = colorThemeJson.tokenColors || [];
3378
- const tokenColorRules = tokenColors.map(toTokenColorRule);
3379
- const extraRules = [];
3380
- if (colors.ContrastBorder) {
3381
- extraRules.push(`#ActivityBar, #SideBar {
3382
- border-left: 1px solid var(--ContrastBorder);
3383
- }`, `#Panel {
3384
- border-top: 1px solid var(--ContrastBorder);
3385
- }`, `#StatusBar {
3386
- border-top: 1px solid var(--ContrastBorder);
3387
- }`, `.ActivityBarItemBadge {
3388
- border: 1px solid var(--ContrastBorder);
3389
- }`, `#QuickPick {
3390
- border: 1px solid var(--ContrastBorder);
3391
- }`);
3449
+ if (platform === Electron) {
3450
+ return '../../../../..';
3392
3451
  }
3393
- const colorThemeCss = `:root {\n${colorRules.join(NewLine)}\n}\n\n${tokenColorRules.join(NewLine)}\n\n${extraRules.join(NewLine)}`;
3394
- return colorThemeCss;
3452
+ return '';
3395
3453
  };
3454
+ const assetDir = getAssetDir();
3396
3455
 
3397
- // for (let i = 0; i < 10000; i++) {
3398
- // createColorThemeFromJson({
3399
- // type: 'dark',
3400
- // colors: {
3401
- // ActivityBarBackground: 'rgb(40, 46, 47)',
3402
- // ActivityBarForeground: '#878f8c',
3403
- // ActivityBarActiveBackground: '#1f2727',
3404
-
3405
- // EditorBackGround: '#1e2324',
3406
- // EditorScrollBarBackground: 'rgba(57, 71, 71, 0.6)',
3407
- // EditorCursorBackground: '#a8df5a',
3408
-
3409
- // ListActiveSelectionBackground: '#515f59',
3410
- // ListActiveSelectionForeground: '#ffffff',
3411
- // ListHoverBackground: '#405c5033',
3412
- // ListHoverForeground: '#e0e0e0',
3413
- // ListInactiveSelectionBackground: '#3b474280',
3414
-
3415
- // MainBackground: '#1e2324',
3416
-
3417
- // PanelBackground: '#1b2020',
3418
- // PanelBorderTopColor: 'rgba(128, 128, 128, 0.35)',
3419
-
3420
- // SideBarBackground: '#1b2020',
3421
-
3422
- // StatusBarBackground: 'rgb(40, 46, 47)',
3423
- // StatusBarBorderTopColor: '#222222',
3424
-
3425
- // TabActiveBackground: '#24292a',
3426
- // TabInactiveBackground: '#282e2f',
3427
-
3428
- // TitleBarBackground: 'rgb(40, 46, 47)',
3429
- // TitleBarBorderBottomColor: '#222',
3430
- // TitleBarColor: '#cccccc',
3431
- // TitleBarColorInactive: 'rgba(204, 204, 204, 0.6)',
3432
- // },
3433
- // }) //?.
3434
- // }
3435
-
3436
- const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
3437
- let idbProxyableTypes;
3438
- let cursorAdvanceMethods;
3439
- // This is a function to prevent it throwing up in node environments.
3440
- function getIdbProxyableTypes() {
3441
- return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
3442
- }
3443
- // This is a function to prevent it throwing up in node environments.
3444
- function getCursorAdvanceMethods() {
3445
- return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
3446
- }
3447
- const transactionDoneMap = new WeakMap();
3448
- const transformCache = new WeakMap();
3449
- const reverseTransformCache = new WeakMap();
3450
- function promisifyRequest(request) {
3451
- const promise = new Promise((resolve, reject) => {
3452
- const unlisten = () => {
3453
- request.removeEventListener('success', success);
3454
- request.removeEventListener('error', error);
3455
- };
3456
- const success = () => {
3457
- resolve(wrap(request.result));
3458
- unlisten();
3459
- };
3460
- const error = () => {
3461
- reject(request.error);
3462
- unlisten();
3463
- };
3464
- request.addEventListener('success', success);
3465
- request.addEventListener('error', error);
3466
- });
3467
- // This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
3468
- // is because we create many promises from a single IDBRequest.
3469
- reverseTransformCache.set(promise, request);
3470
- return promise;
3471
- }
3472
- function cacheDonePromiseForTransaction(tx) {
3473
- // Early bail if we've already created a done promise for this transaction.
3474
- if (transactionDoneMap.has(tx)) return;
3475
- const done = new Promise((resolve, reject) => {
3476
- const unlisten = () => {
3477
- tx.removeEventListener('complete', complete);
3478
- tx.removeEventListener('error', error);
3479
- tx.removeEventListener('abort', error);
3480
- };
3481
- const complete = () => {
3482
- resolve();
3483
- unlisten();
3484
- };
3485
- const error = () => {
3486
- reject(tx.error || new DOMException('AbortError', 'AbortError'));
3487
- unlisten();
3488
- };
3489
- tx.addEventListener('complete', complete);
3490
- tx.addEventListener('error', error);
3491
- tx.addEventListener('abort', error);
3492
- });
3493
- // Cache it for later retrieval.
3494
- transactionDoneMap.set(tx, done);
3495
- }
3496
- let idbProxyTraps = {
3497
- get(target, prop, receiver) {
3498
- if (target instanceof IDBTransaction) {
3499
- // Special handling for transaction.done.
3500
- if (prop === 'done') return transactionDoneMap.get(target);
3501
- // Make tx.store return the only store in the transaction, or undefined if there are many.
3502
- if (prop === 'store') {
3503
- return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
3504
- }
3505
- }
3506
- // Else transform whatever we get back.
3507
- return wrap(target[prop]);
3508
- },
3509
- set(target, prop, value) {
3510
- target[prop] = value;
3511
- return true;
3512
- },
3513
- has(target, prop) {
3514
- if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
3515
- return true;
3516
- }
3517
- return prop in target;
3518
- }
3519
- };
3520
- function replaceTraps(callback) {
3521
- idbProxyTraps = callback(idbProxyTraps);
3522
- }
3523
- function wrapFunction(func) {
3524
- // Due to expected object equality (which is enforced by the caching in `wrap`), we
3525
- // only create one new func per func.
3526
- // Cursor methods are special, as the behaviour is a little more different to standard IDB. In
3527
- // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
3528
- // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
3529
- // with real promises, so each advance methods returns a new promise for the cursor object, or
3530
- // undefined if the end of the cursor has been reached.
3531
- if (getCursorAdvanceMethods().includes(func)) {
3532
- return function (...args) {
3533
- // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
3534
- // the original object.
3535
- func.apply(unwrap(this), args);
3536
- return wrap(this.request);
3537
- };
3538
- }
3539
- return function (...args) {
3540
- // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
3541
- // the original object.
3542
- return wrap(func.apply(unwrap(this), args));
3543
- };
3544
- }
3545
- function transformCachableValue(value) {
3546
- if (typeof value === 'function') return wrapFunction(value);
3547
- // This doesn't return, it just creates a 'done' promise for the transaction,
3548
- // which is later returned for transaction.done (see idbObjectHandler).
3549
- if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
3550
- if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
3551
- // Return the same value back if we're not going to transform it.
3552
- return value;
3553
- }
3554
- function wrap(value) {
3555
- // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
3556
- // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
3557
- if (value instanceof IDBRequest) return promisifyRequest(value);
3558
- // If we've already transformed this value before, reuse the transformed value.
3559
- // This is faster, but it also provides object equality.
3560
- if (transformCache.has(value)) return transformCache.get(value);
3561
- const newValue = transformCachableValue(value);
3562
- // Not all types are transformed.
3563
- // These may be primitive types, so they can't be WeakMap keys.
3564
- if (newValue !== value) {
3565
- transformCache.set(value, newValue);
3566
- reverseTransformCache.set(newValue, value);
3567
- }
3568
- return newValue;
3569
- }
3570
- const unwrap = value => reverseTransformCache.get(value);
3571
-
3572
- /**
3573
- * Open a database.
3574
- *
3575
- * @param name Name of the database.
3576
- * @param version Schema version.
3577
- * @param callbacks Additional callbacks.
3578
- */
3579
- function openDB(name, version, {
3580
- blocked,
3581
- upgrade,
3582
- blocking,
3583
- terminated
3584
- } = {}) {
3585
- const request = indexedDB.open(name, version);
3586
- const openPromise = wrap(request);
3587
- if (upgrade) {
3588
- request.addEventListener('upgradeneeded', event => {
3589
- upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
3590
- });
3591
- }
3592
- if (blocked) {
3593
- request.addEventListener('blocked', event => blocked(
3594
- // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
3595
- event.oldVersion, event.newVersion, event));
3596
- }
3597
- openPromise.then(db => {
3598
- if (terminated) db.addEventListener('close', () => terminated());
3599
- if (blocking) {
3600
- db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
3601
- }
3602
- }).catch(() => {});
3603
- return openPromise;
3604
- }
3605
- const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
3606
- const writeMethods = ['put', 'add', 'delete', 'clear'];
3607
- const cachedMethods = new Map();
3608
- function getMethod(target, prop) {
3609
- if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
3610
- return;
3611
- }
3612
- if (cachedMethods.get(prop)) return cachedMethods.get(prop);
3613
- const targetFuncName = prop.replace(/FromIndex$/, '');
3614
- const useIndex = prop !== targetFuncName;
3615
- const isWrite = writeMethods.includes(targetFuncName);
3616
- if (
3617
- // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
3618
- !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
3619
- return;
3620
- }
3621
- const method = async function (storeName, ...args) {
3622
- // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
3623
- const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
3624
- let target = tx.store;
3625
- if (useIndex) target = target.index(args.shift());
3626
- // Must reject if op rejects.
3627
- // If it's a write operation, must reject if tx.done rejects.
3628
- // Must reject with op rejection first.
3629
- // Must resolve with op value.
3630
- // Must handle both promises (no unhandled rejections)
3631
- return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
3632
- };
3633
- cachedMethods.set(prop, method);
3634
- return method;
3635
- }
3636
- replaceTraps(oldTraps => ({
3637
- ...oldTraps,
3638
- get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
3639
- has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
3640
- }));
3641
- const advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];
3642
- const methodMap = {};
3643
- const advanceResults = new WeakMap();
3644
- const ittrProxiedCursorToOriginalProxy = new WeakMap();
3645
- const cursorIteratorTraps = {
3646
- get(target, prop) {
3647
- if (!advanceMethodProps.includes(prop)) return target[prop];
3648
- let cachedFunc = methodMap[prop];
3649
- if (!cachedFunc) {
3650
- cachedFunc = methodMap[prop] = function (...args) {
3651
- advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
3652
- };
3653
- }
3654
- return cachedFunc;
3655
- }
3656
- };
3657
- async function* iterate(...args) {
3658
- // tslint:disable-next-line:no-this-assignment
3659
- let cursor = this;
3660
- if (!(cursor instanceof IDBCursor)) {
3661
- cursor = await cursor.openCursor(...args);
3662
- }
3663
- if (!cursor) return;
3664
- cursor = cursor;
3665
- const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
3666
- ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
3667
- // Map this double-proxy back to the original, so other cursor methods work.
3668
- reverseTransformCache.set(proxiedCursor, unwrap(cursor));
3669
- while (cursor) {
3670
- yield proxiedCursor;
3671
- // If one of the advancing methods was not called, call continue().
3672
- cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
3673
- advanceResults.delete(proxiedCursor);
3674
- }
3675
- }
3676
- function isIteratorProp(target, prop) {
3677
- return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
3678
- }
3679
- replaceTraps(oldTraps => ({
3680
- ...oldTraps,
3681
- get(target, prop, receiver) {
3682
- if (isIteratorProp(target, prop)) return iterate;
3683
- return oldTraps.get(target, prop, receiver);
3684
- },
3685
- has(target, prop) {
3686
- return isIteratorProp(target, prop) || oldTraps.has(target, prop);
3687
- }
3688
- }));
3689
-
3690
- const state$4 = {
3691
- dbVersion: 1,
3692
- /**
3693
- * @type {any}
3694
- */
3695
- cachedDb: undefined
3696
- };
3697
-
3698
- const storeId = 'lvce-keyvalue';
3699
-
3700
- // TODO high memory usage in idb because of transactionDoneMap
3701
-
3702
- const getDb$1 = async () => {
3703
- const db = await openDB(storeId, state$4.dbVersion, {
3704
- async upgrade(db, oldVersion) {
3705
- if (!db.objectStoreNames.contains(storeId)) {
3706
- await db.createObjectStore(storeId, {
3707
- autoIncrement: true
3708
- });
3709
- }
3710
- }
3711
- });
3712
- return db;
3713
- };
3714
-
3715
- // TODO high memory usage in idb because of transactionDoneMap
3716
-
3717
- const state$3 = {
3718
- cachedDb: undefined
3719
- };
3720
- const getDbMemoized$1 = async () => {
3721
- state$3.cachedDb ||= await getDb$1();
3722
- return state$3.cachedDb;
3723
- };
3724
-
3725
- // TODO high memory usage in idb because of transactionDoneMap
3726
-
3727
- const set$4 = async (key, value) => {
3728
- try {
3729
- const db = await getDbMemoized$1();
3730
- await db.put(storeId, value, key);
3731
- } catch (error) {
3732
- throw new VError(error, 'Failed to save value to indexed db');
3733
- }
3734
- };
3735
- const get$5 = async key => {
3736
- try {
3737
- const db = await getDbMemoized$1();
3738
- const value = await db.get(storeId, key);
3739
- return value;
3740
- } catch (error) {
3741
- throw new VError(error, 'Failed to get value from indexed db');
3742
- }
3743
- };
3744
-
3745
- const getCacheKey$1 = colorThemeId => {
3746
- return 'color-theme-' + colorThemeId;
3747
- };
3748
- const get$4 = colorThemeId => {
3749
- const cacheKey = getCacheKey$1(colorThemeId);
3750
- return get$5(cacheKey);
3751
- };
3752
- const set$3 = (colorThemeId, data) => {
3753
- const cacheKey = getCacheKey$1(colorThemeId);
3754
- return set$4(cacheKey, data);
3755
- };
3756
-
3757
- const GetColorThemeCssCachedIndexedDb = {
3758
- __proto__: null,
3759
- get: get$4,
3760
- set: set$3
3761
- };
3762
-
3763
- const getText$1 = key => {
3764
- return invoke$2('LocalStorage.getText', key);
3765
- };
3766
- const setText = (key, value) => {
3767
- return invoke$2('LocalStorage.setText', key, value);
3768
- };
3769
-
3770
- const getCacheKey = colorThemeId => {
3771
- return 'lvce-color-theme-' + colorThemeId;
3772
- };
3773
- const get$3 = colorThemeId => {
3774
- const cacheKey = getCacheKey(colorThemeId);
3775
- return getText$1(cacheKey);
3776
- };
3777
- const set$2 = (colorThemeId, data) => {
3778
- const cacheKey = getCacheKey(colorThemeId);
3779
- return setText(cacheKey, data);
3780
- };
3781
-
3782
- const GetColorThemeCssCachedLocalStorage = {
3783
- __proto__: null,
3784
- get: get$3,
3785
- set: set$2
3786
- };
3787
-
3788
- const get$2 = colorThemeId => {
3789
- return '';
3790
- };
3791
- const set$1 = (colorThemeId, data) => {
3792
- // noop
3793
- };
3794
-
3795
- const GetColorThemeCssCachedNoop = {
3796
- __proto__: null,
3797
- get: get$2,
3798
- set: set$1
3799
- };
3800
-
3801
- const get$1 = key => {
3802
- return invoke$2('Preferences.get', key);
3803
- };
3804
-
3805
- const getCacheFn = config => {
3806
- switch (config) {
3807
- case 'localStorage':
3808
- return GetColorThemeCssCachedLocalStorage;
3809
- case 'indexedDb':
3810
- return GetColorThemeCssCachedIndexedDb;
3811
- default:
3812
- return GetColorThemeCssCachedNoop;
3813
- }
3814
- };
3815
- const getColorThemeCssCached = async (colorThemeId, getData) => {
3816
- const config = await get$1('colorTheme.cache');
3817
- const module = await getCacheFn(config);
3818
- const cachedData = await module.get(colorThemeId);
3819
- if (cachedData) {
3820
- return cachedData;
3821
- }
3822
- const newData = await getData(colorThemeId);
3823
- await module.set(colorThemeId, newData);
3824
- return newData;
3825
- };
3826
-
3827
- const readJson = url => {
3828
- return invoke$2('FileSystem.readJson', url);
3829
- };
3830
-
3831
- const dirname = (pathSeparator, path) => {
3832
- const index = path.lastIndexOf(pathSeparator);
3833
- if (index === -1) {
3834
- return path;
3835
- }
3836
- return path.slice(0, index);
3837
- };
3838
- const extname = path => {
3839
- const index = path.lastIndexOf('.');
3840
- if (index === -1) {
3841
- return '';
3842
- }
3843
- return path.slice(index);
3844
- };
3845
- const join = (pathSeparator, ...parts) => {
3846
- return parts.join(pathSeparator);
3456
+ const loadBabelParser = () => {
3457
+ const url = `${assetDir}/js/babel-parser.js`;
3458
+ return import(url);
3847
3459
  };
3848
3460
 
3849
- const getColorThemeUri = (extensions, colorThemeId) => {
3850
- for (const extension of extensions) {
3851
- if (!extension.colorThemes) {
3852
- continue;
3853
- }
3854
- for (const colorTheme of extension.colorThemes) {
3855
- if (colorTheme.id !== colorThemeId) {
3856
- continue;
3857
- }
3858
- const absolutePath = join('/', extension.uri, colorTheme.path);
3859
- return absolutePath;
3860
- }
3861
- }
3862
- return '';
3461
+ const parse = async (code, options) => {
3462
+ const BabelParse = await loadBabelParser();
3463
+ return BabelParse.parse(code, options);
3863
3464
  };
3864
3465
 
3865
- const getAssetDir = () => {
3866
- // @ts-ignore
3867
- if (typeof ASSET_DIR !== 'undefined') {
3868
- // @ts-ignore
3869
- return ASSET_DIR;
3870
- }
3871
- if (platform === Electron) {
3872
- return '../../../../..';
3466
+ const Module = 'module';
3467
+
3468
+ const getLineAndColumn = (text, start, end) => {
3469
+ let index = -1;
3470
+ let line = 0;
3471
+ const column = 0;
3472
+ while ((index = text.indexOf('\n', index + 1)) !== -1) {
3473
+ line++;
3474
+ if (index >= start) {
3475
+ break;
3476
+ }
3873
3477
  }
3874
- return '';
3478
+ return {
3479
+ line,
3480
+ column
3481
+ };
3875
3482
  };
3876
- const assetDir = getAssetDir();
3877
3483
 
3878
- const extensionsUrl = `${assetDir}/config/extensions.json`;
3484
+ class DependencyNotFoundError extends Error {
3485
+ constructor(code, start, end, dependencyRelativePath, dependencyUrl, sourceUrl) {
3486
+ super(`Module not found "${dependencyRelativePath}"`);
3487
+ const {
3488
+ line,
3489
+ column
3490
+ } = getLineAndColumn(code, start);
3491
+ this.stack = `${this.message}
3492
+ at Module (${sourceUrl}:${line}:${column})`;
3493
+ }
3494
+ }
3879
3495
 
3880
- const getWebExtensions = async () => {
3881
- return getJson(extensionsUrl);
3882
- };
3496
+ const ArrowFunctionExpression = 'ArrowFunctionExpression';
3497
+ const AwaitExpression = 'AwaitExpression';
3498
+ const BlockStatement = 'BlockStatement';
3499
+ const CallExpression = 'CallExpression';
3500
+ const ExportAllDeclaration = 'ExportAllDeclaration';
3501
+ const ExportNamedDeclaration = 'ExportNamedDeclaration';
3502
+ const ExpressionStatement = 'ExpressionStatement';
3503
+ const File$2 = 'File';
3504
+ const Import = 'Import';
3505
+ const ImportDeclaration = 'ImportDeclaration';
3506
+ const Program = 'Program';
3507
+ const StringLiteral = 'StringLiteral';
3508
+ const VariableDeclaration = 'VariableDeclaration';
3509
+ const VariableDeclarator = 'VariableDeclarator';
3883
3510
 
3884
- const getSharedProcessExtensions = () => {
3885
- return invoke$2(/* ExtensionManagement.getExtensions */'ExtensionManagement.getExtensions');
3886
- };
3887
- const doGetExtensions = async () => {
3888
- const meta = state$5.webExtensions;
3889
- if (platform === Web) {
3890
- const webExtensions = await getWebExtensions();
3891
- return [...webExtensions, ...meta];
3511
+ const walk = (node, visitor) => {
3512
+ if (!node) {
3513
+ return;
3892
3514
  }
3893
- if (platform === Remote) {
3894
- const sharedProcessExtensions = await getSharedProcessExtensions();
3895
- return [...sharedProcessExtensions, ...meta];
3515
+ if (Array.isArray(node)) {
3516
+ for (const item of node) {
3517
+ walk(item, visitor);
3518
+ }
3519
+ return;
3520
+ }
3521
+ visitor(node);
3522
+ switch (node.type) {
3523
+ case File$2:
3524
+ walk(node.program, visitor);
3525
+ break;
3526
+ case Program:
3527
+ walk(node.body, visitor);
3528
+ break;
3529
+ case ExportNamedDeclaration:
3530
+ walk(node.declaration, visitor);
3531
+ break;
3532
+ case VariableDeclaration:
3533
+ walk(node.declarations, visitor);
3534
+ break;
3535
+ case VariableDeclarator:
3536
+ walk(node.init, visitor);
3537
+ break;
3538
+ case ArrowFunctionExpression:
3539
+ walk(node.body, visitor);
3540
+ break;
3541
+ case BlockStatement:
3542
+ walk(node.body, visitor);
3543
+ break;
3544
+ case ExpressionStatement:
3545
+ walk(node.expression, visitor);
3546
+ break;
3547
+ case AwaitExpression:
3548
+ walk(node.argument, visitor);
3549
+ break;
3550
+ case CallExpression:
3551
+ walk(node.callee, visitor);
3552
+ break;
3896
3553
  }
3897
- const extensions = await getSharedProcessExtensions();
3898
- return extensions;
3899
- };
3900
-
3901
- const getExtensions$1 = async () => {
3902
- return doGetExtensions();
3903
3554
  };
3904
3555
 
3905
- // TODO getExtensions is still called 6 times on startup instead of 1
3906
- const getExtensions = () => {
3907
- if (!has()) {
3908
- set$5(getExtensions$1());
3556
+ const getBabelAstDependencies = (code, ast) => {
3557
+ const {
3558
+ program
3559
+ } = ast;
3560
+ const {
3561
+ body
3562
+ } = program;
3563
+ const dependencies = [];
3564
+ for (const node of body) {
3565
+ if (node.type === ImportDeclaration || node.type === ExportAllDeclaration) {
3566
+ const relativePath = node.source.extra.rawValue;
3567
+ const {
3568
+ start
3569
+ } = node.source;
3570
+ const {
3571
+ end
3572
+ } = node.source;
3573
+ // @ts-ignore
3574
+ dependencies.push({
3575
+ relativePath,
3576
+ code,
3577
+ start,
3578
+ end
3579
+ });
3580
+ } else if (node.type === VariableDeclaration && node.declarations && node.declarations[0] && node.declarations[0].type === VariableDeclarator && node.declarations[0].init && node.declarations[0].init.type === AwaitExpression && node.declarations[0].init.argument && node.declarations[0].init.argument.type === CallExpression && node.declarations[0].init.argument.callee && node.declarations[0].init.argument.callee.type === Import && node.declarations[0].init.argument.arguments && node.declarations[0].init.argument.arguments[0] && node.declarations[0].init.argument.arguments[0].type === StringLiteral) {
3581
+ const relativePath = node.declarations[0].init.argument.arguments[0].extra.rawValue;
3582
+ const {
3583
+ start
3584
+ } = node.declarations[0].init.argument.arguments[0];
3585
+ const {
3586
+ end
3587
+ } = node.declarations[0].init.argument.arguments[0];
3588
+ // @ts-ignore
3589
+ dependencies.push({
3590
+ relativePath,
3591
+ code,
3592
+ start,
3593
+ end
3594
+ });
3595
+ }
3909
3596
  }
3910
- return get$6();
3597
+ const visitor = node => {
3598
+ if (node && node.type === CallExpression && node.callee && node.callee.type === Import && node.arguments && node.arguments[0] && node.arguments[0].type === StringLiteral) {
3599
+ const relativePath = node.arguments[0].extra.rawValue;
3600
+ const {
3601
+ start
3602
+ } = node.arguments[0];
3603
+ const {
3604
+ end
3605
+ } = node.arguments[0];
3606
+ // @ts-ignore
3607
+ dependencies.push({
3608
+ relativePath,
3609
+ code,
3610
+ start,
3611
+ end
3612
+ });
3613
+ }
3614
+ };
3615
+ walk(ast, visitor);
3616
+ return dependencies;
3911
3617
  };
3912
3618
 
3913
- const getColorThemeJson$2 = async colorThemeId => {
3914
- const extensions = await getExtensions();
3915
- const colorThemeUri = getColorThemeUri(extensions, colorThemeId);
3916
- const json = await readJson(colorThemeUri);
3917
- return json;
3619
+ const isBabelError = error => {
3620
+ // @ts-ignore
3621
+ return isSyntaxError(error) && error.code === BABEL_PARSER_SYNTAX_ERROR;
3918
3622
  };
3919
3623
 
3920
- const getColorThemeUrlWeb = colorThemeId => {
3921
- return `${assetDir}/extensions/builtin.theme-${colorThemeId}/color-theme.json`;
3922
- };
3923
- const getColorThemeJson$1 = colorThemeId => {
3924
- const url = getColorThemeUrlWeb(colorThemeId);
3925
- // TODO handle error ?
3926
- return getJson(url);
3624
+ const getOrigin = () => {
3625
+ return location.origin;
3927
3626
  };
3928
3627
 
3929
- const getColorThemeJson = colorThemeId => {
3930
- if (platform === Web) {
3931
- return getColorThemeJson$1(colorThemeId);
3628
+ const getAbsoluteUrl = (relativePath, sourceUrl) => {
3629
+ if (sourceUrl.startsWith('/')) {
3630
+ const origin = getOrigin();
3631
+ const absoluteSourceUrl = new URL(sourceUrl, origin).toString();
3632
+ return new URL(relativePath, absoluteSourceUrl).toString();
3932
3633
  }
3933
- return getColorThemeJson$2(colorThemeId);
3634
+ return new URL(relativePath, sourceUrl).toString();
3934
3635
  };
3935
3636
 
3936
- const getColorThemeCssFromJson = async (colorThemeId, colorThemeJson) => {
3937
- const colorThemeCss = createColorThemeFromJson(/* colorThemeId */colorThemeId, /* colorThemeJson */colorThemeJson);
3938
- return colorThemeCss;
3939
- // TODO generate color theme from jsonc
3940
- };
3941
- const getColorThemeCssNew = async colorThemeId => {
3942
- const colorThemeJson = await getColorThemeJson(colorThemeId);
3943
- const colorThemeCss = await getColorThemeCssFromJson(colorThemeId, colorThemeJson);
3944
- return colorThemeCss;
3945
- };
3946
- const getColorThemeCss = colorThemeId => {
3947
- return getColorThemeCssCached(colorThemeId, getColorThemeCssNew);
3637
+ const isExternal = url => {
3638
+ if (url.startsWith('/')) {
3639
+ return false;
3640
+ }
3641
+ if (url.startsWith(location.protocol)) {
3642
+ return false;
3643
+ }
3644
+ return true;
3948
3645
  };
3949
-
3950
- const getMetaThemeColor = colorThemeJson => {
3951
- return colorThemeJson && colorThemeJson.colors && colorThemeJson.colors.TitleBarBackground;
3646
+ const getErrorInDependencies = async (url, dependencies, seenUrls) => {
3647
+ for (const dependency of dependencies) {
3648
+ const dependencyUrl = getAbsoluteUrl(dependency.relativePath, url);
3649
+ if (isExternal(dependencyUrl) || seenUrls.includes(dependencyUrl)) {
3650
+ continue;
3651
+ }
3652
+ seenUrls.push(dependencyUrl);
3653
+ // let dependencyResponse
3654
+ // try {
3655
+ const dependencyResponse = await fetch(dependencyUrl);
3656
+ // } catch (error) {}
3657
+ if (dependencyResponse.ok) {
3658
+ await tryToGetActualErrorMessage(null, dependencyUrl, dependencyResponse, seenUrls);
3659
+ } else {
3660
+ switch (dependencyResponse.status) {
3661
+ case NotFound:
3662
+ throw new DependencyNotFoundError(dependency.code, dependency.start, dependency.end, dependency.relativePath, dependencyUrl, url);
3663
+ // return `Failed to import ${url}: ${error}`
3664
+ }
3665
+ }
3666
+ }
3952
3667
  };
3953
3668
 
3954
- const setThemeColor = async themeColor => {
3955
- await invoke$2(/* Meta.setThemeColor */'Meta.setThemeColor', /* color */themeColor);
3669
+ /**
3670
+ *
3671
+ * @param {string} url
3672
+ * @param {Response} response
3673
+ * @returns
3674
+ */
3675
+ const tryToGetActualErrorMessage = async (error, url, response, seenUrls = []) => {
3676
+ let text;
3677
+ try {
3678
+ text = await response.text();
3679
+ } catch {
3680
+ return `Failed to import ${url}: Unknown Network Error`;
3681
+ }
3682
+ let ast;
3683
+ try {
3684
+ ast = await parse(text, {
3685
+ sourceType: Module
3686
+ });
3687
+ } catch (error) {
3688
+ if (isBabelError(error)) {
3689
+ throw new BabelParseError(url, error);
3690
+ }
3691
+ throw error;
3692
+ }
3693
+ const dependencies = getBabelAstDependencies(text, ast);
3694
+ await getErrorInDependencies(url, dependencies, seenUrls);
3695
+ if (hasRecentErrors()) {
3696
+ const recentError = getRecentError();
3697
+ // @ts-ignore
3698
+ throw new ContentSecurityPolicyError(recentError.violatedDirective, recentError.sourceFile, recentError.lineNumber, recentError.columnNumber);
3699
+ }
3700
+ const contentType = response.headers.get('Content-Type');
3701
+ if (url.endsWith('.ts') && contentType === null) {
3702
+ return `Failed to import ${url}: Missing Content-Type header for javascript`;
3703
+ }
3704
+ return `Failed to import ${url}: Unknown Network Error`;
3956
3705
  };
3957
3706
 
3958
- // TODO by default color theme should come from local storage, session storage, cache storage, indexeddb or blob url -> fast initial load
3959
- // actual color theme can be computed after workbench has loaded (most times will be the same and doesn't need to be computed)
3960
-
3961
- const state$2 = {
3962
- watchedTheme: ''
3707
+ const tryToGetActualImportErrorMessage = async (url, error) => {
3708
+ let response;
3709
+ try {
3710
+ response = await fetch(url);
3711
+ } catch (error) {
3712
+ return `Failed to import ${url}: ${error}`;
3713
+ }
3714
+ if (response.ok) {
3715
+ return await tryToGetActualErrorMessage(error, url, response);
3716
+ }
3717
+ switch (response.status) {
3718
+ case NotFound:
3719
+ throw new Error(`Failed to import ${url}: Not found (404)`);
3720
+ default:
3721
+ return `Failed to import ${url}: ${error}`;
3722
+ }
3963
3723
  };
3964
- const FALLBACK_COLOR_THEME_ID = 'slime';
3965
-
3966
- // TODO json parsing should also happen in renderer worker
3967
- // so that all validation is here (json parsing errors, invalid shape, ...)
3968
3724
 
3969
- const applyColorTheme = async colorThemeId => {
3725
+ const importScript = async url => {
3970
3726
  try {
3971
- string(colorThemeId);
3972
- state$2.colorTheme = colorThemeId;
3973
- const colorThemeCss = await getColorThemeCss(colorThemeId);
3974
- await addCssStyleSheet('ContributedColorTheme', colorThemeCss);
3975
- if (platform === Web) {
3976
- const themeColor = getMetaThemeColor(colorThemeId) || '';
3977
- await setThemeColor(themeColor);
3727
+ return await import(url);
3728
+ } catch (error) {
3729
+ if (isImportError(error)) {
3730
+ const actualErrorMessage = await tryToGetActualImportErrorMessage(url, error);
3731
+ throw new Error(actualErrorMessage);
3978
3732
  }
3979
- if (platform !== Web && (await get$1('development.watchColorTheme'))) {
3980
- watch(colorThemeId);
3733
+ // content security policy errors arrive a little bit later
3734
+ await sleep(0);
3735
+ if (hasRecentErrors()) {
3736
+ const recentError = getRecentError();
3737
+ // @ts-ignore
3738
+ throw new ContentSecurityPolicyError(recentError.violatedDirective, recentError.sourceFile, recentError.lineNumber, recentError.columnNumber);
3981
3739
  }
3982
- } catch (error) {
3983
- throw new VError(error, `Failed to apply color theme "${colorThemeId}"`);
3740
+ throw error;
3984
3741
  }
3985
3742
  };
3986
- const watch = async id => {
3987
- if (state$2.watchedTheme === id) {
3743
+
3744
+ const activationTimeout = 10_000;
3745
+ const rejectAfterTimeout = async (timeout, token) => {
3746
+ await sleep(timeout);
3747
+ if (isCanceled(token)) {
3988
3748
  return;
3989
3749
  }
3990
- state$2.watchedTheme = id;
3991
- await invoke$2('ExtensionHost.watchColorTheme', id);
3992
- };
3993
- const getPreferredColorTheme = () => {
3994
- const preferredColorTheme = get$1('workbench.colorTheme');
3995
- return preferredColorTheme;
3750
+ throw new Error(`Activation timeout of ${timeout}ms exceeded`);
3996
3751
  };
3997
3752
 
3998
- // TODO test this, and also the error case
3999
- // TODO have icon theme, color theme together (maybe)
4000
- const hydrate$1 = async () => {
4001
- const preferredColorTheme = await getPreferredColorTheme();
4002
- const colorThemeId = preferredColorTheme || FALLBACK_COLOR_THEME_ID;
3753
+ // TODO separate importing extension and activating extension for smaller functions
3754
+ // and better error handling
3755
+
3756
+ /**
3757
+ * @deprecated use the separate functions importExtension and activateExtension instead
3758
+ *
3759
+ * @param extension
3760
+ * @param absolutePath
3761
+ * @param activationEvent
3762
+ */
3763
+ const activateExtension = async (extension, absolutePath, activationEvent) => {
3764
+ const extensionId = extension.id;
4003
3765
  try {
4004
- await applyColorTheme(colorThemeId);
4005
- } catch (error) {
4006
- if (colorThemeId === FALLBACK_COLOR_THEME_ID) {
3766
+ string(extension.path);
3767
+ string(extension.browser);
3768
+ string(absolutePath);
3769
+ const startTime = performance.now();
3770
+ set$5({
3771
+ activationEndTime: 0,
3772
+ activationEvent: activationEvent,
3773
+ activationStartTime: startTime,
3774
+ activationTime: 0,
3775
+ id: extensionId,
3776
+ status: Importing,
3777
+ importEndTime: 0,
3778
+ importStartTime: 0,
3779
+ importTime: 0
3780
+ });
3781
+ const module = await importScript(absolutePath);
3782
+ handleRpcInfos(extension, platform);
3783
+ update(extensionId, {
3784
+ status: Activating
3785
+ });
3786
+ const token = create$1();
3787
+ try {
3788
+ await Promise.race([module.activate(extension), rejectAfterTimeout(activationTimeout, token)]);
3789
+ const endTime = performance.now();
3790
+ const time = endTime - startTime;
3791
+ update(extensionId, {
3792
+ status: Activated,
3793
+ activationStartTime: time
3794
+ });
3795
+ } catch (error) {
3796
+ if (isImportError(error)) {
3797
+ const actualErrorMessage = await tryToGetActualImportErrorMessage(absolutePath, error);
3798
+ throw new Error(actualErrorMessage);
3799
+ }
4007
3800
  throw error;
3801
+ } finally {
3802
+ cancel(token);
4008
3803
  }
4009
- console.error(error);
4010
- await applyColorTheme(FALLBACK_COLOR_THEME_ID);
3804
+ } catch (error) {
3805
+ update(extensionId, {
3806
+ status: Error$1 // TODO maybe store error also in runtime status state
3807
+ });
3808
+ const id = getExtensionId(extension);
3809
+ throw new VError(error, `Failed to activate extension ${id}`);
4011
3810
  }
3811
+ // console.info('activated', path)
4012
3812
  };
4013
3813
 
4014
- const iframeWorkerUrl = `${assetDir}/packages/renderer-worker/node_modules/@lvce-editor/iframe-worker/dist/iframeWorkerMain.js`;
4015
-
4016
- const getConfiguredIframeWorkerUrl = async () => {
4017
- let configuredWorkerUrl = (await get$1('develop.iframeWorkerPath')) || '';
4018
- if (configuredWorkerUrl) {
4019
- configuredWorkerUrl = '/remote' + configuredWorkerUrl;
4020
- }
4021
- configuredWorkerUrl = configuredWorkerUrl || iframeWorkerUrl;
4022
- return configuredWorkerUrl;
3814
+ const state$5 = {
3815
+ webExtensions: []
4023
3816
  };
4024
3817
 
4025
- const state$1 = {
4026
- id: 0
3818
+ const cache = Object.create(null);
3819
+ const id = 1;
3820
+ const get$5 = () => {
3821
+ return cache[id];
4027
3822
  };
4028
- const create$1 = () => {
4029
- return ++state$1.id;
3823
+ const has = () => {
3824
+ return id in cache;
4030
3825
  };
4031
-
4032
- const iframeWorkerCommandMap = {
4033
- 'WebView.compatExtensionHostWorkerInvoke': (...args) => invoke$2('WebView.compatExtensionHostWorkerInvoke', ...args),
4034
- 'WebView.compatExtensionHostWorkerInvokeAndTransfer': (...args) => invokeAndTransfer$2('WebView.compatExtensionHostWorkerInvokeAndTransfer', ...args),
4035
- 'WebView.compatRendererProcessInvoke': (...args) => invoke$2('WebView.compatRendererProcessInvoke', ...args),
4036
- 'WebView.compatRendererProcessInvokeAndTransfer': (...args) => invokeAndTransfer$2('WebView.compatRendererProcessInvokeAndTransfer', ...args),
4037
- // @ts-ignore
4038
- 'WebView.compatRendererWorkerInvokeAndTransfer': (...args) => invokeAndTransfer$2(...args),
4039
- // @ts-ignore
4040
- 'WebView.compatRendererWorkerInvoke': (...args) => invoke$2(...args),
4041
- 'WebView.compatSharedProcessInvoke': (...args) => invoke$2('WebView.compatSharedProcessInvoke', ...args),
4042
- 'WebView.getSavedState': (...args) => invoke$2('WebView.getSavedState', ...args),
4043
- 'WebView.getWebViewInfo': (...args) => invoke$2('WebView.getWebViewInfo', ...args),
4044
- 'WebView.getWebViews': (...args) => invoke$2('WebView.getWebViews', ...args),
4045
- 'WebView.setPort': (...args) => invoke$2('WebView.setPort', ...args),
4046
- 'ExtensionHostManagement.activateByEvent': (...args) => invoke$2('ExtensionHostManagement.activateByEvent', ...args),
4047
- 'WebView.getRemoteUrl': options => getRemoteUrlForWebView(options.uri, options)
3826
+ const set$4 = value => {
3827
+ cache[id] = value;
4048
3828
  };
4049
-
4050
- const launchIframeWorker = async () => {
4051
- const configuredWorkerUrl = await getConfiguredIframeWorkerUrl();
4052
- const name = 'Iframe Worker';
4053
- const id = create$1();
4054
- const rpc = await create$2({
4055
- method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug$1,
4056
- name,
4057
- url: configuredWorkerUrl,
4058
- id,
4059
- commandMap: iframeWorkerCommandMap
4060
- });
4061
- return rpc;
3829
+ const clear = () => {
3830
+ delete cache[id];
4062
3831
  };
4063
3832
 
4064
- let workerPromise;
4065
- const ensureWorker = () => {
4066
- if (!workerPromise) {
4067
- workerPromise = launchIframeWorker();
3833
+ const getJson = async url => {
3834
+ try {
3835
+ const response = await fetch(url);
3836
+ if (!response.ok) {
3837
+ throw new Error(response.statusText);
3838
+ }
3839
+ const json = await response.json();
3840
+ return json;
3841
+ } catch (error) {
3842
+ throw new VError(error, `Failed to get json`);
4068
3843
  }
4069
- return workerPromise;
4070
- };
4071
- const isActive = () => {
4072
- return Boolean(workerPromise);
4073
- };
4074
- const invoke = async (method, ...params) => {
4075
- const rpc = await ensureWorker();
4076
- return rpc.invoke(method, ...params);
4077
- };
4078
- const invokeAndTransfer = async (method, ...params) => {
4079
- const rpc = await ensureWorker();
4080
- return rpc.invokeAndTransfer(method, ...params);
4081
3844
  };
4082
3845
 
4083
- const createWebView3 = async ({
4084
- id,
4085
- uri,
4086
- isGitpod,
4087
- platform,
4088
- assetDir,
4089
- webViewScheme,
4090
- useNewWebViewHandler
4091
- }) => {
4092
- await invoke('WebView.create3', {
4093
- id,
4094
- uri,
4095
- isGitpod,
4096
- platform,
4097
- assetDir,
4098
- webViewScheme,
4099
- useNewWebViewHandler
4100
- });
3846
+ const NewLine = '\n';
3847
+ const Slash$1 = '/';
3848
+
3849
+ const interExtensionId = path => {
3850
+ const slashIndex = path.lastIndexOf(Slash$1);
3851
+ return path.slice(slashIndex + 1);
4101
3852
  };
4102
3853
 
4103
- const createWebViewWorkerRpc2 = async (rpcInfo, port) => {
4104
- // TODO this function is called from the iframe worker to create a direct
4105
- // connection between a webview/iframe and it's webworker. For this to work
4106
- // the iframe worker creates a messagechannel and sends one messageport to the webview
4107
- // and the other messageport to the webworker. This enables direct communication via
4108
- // the two message ports
3854
+ const getWebExtensionManifest = async (path, manifestPath) => {
3855
+ try {
3856
+ const manifest = await getJson(manifestPath);
3857
+ return {
3858
+ ...manifest,
3859
+ path,
3860
+ uri: path
3861
+ };
3862
+ } catch (error) {
3863
+ const id = interExtensionId(path);
3864
+ throw new VError(error, `Failed to load extension manifest for ${id}`);
3865
+ }
3866
+ };
4109
3867
 
4110
- // TODO have a way so that the worker already includes the webview api and the extension
4111
- // host subworker doesn't need to import the other file
4112
- await invokeAndTransfer$2('IpcParent.create', {
4113
- method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug,
4114
- url: rpcInfo.url,
4115
- name: rpcInfo.name,
4116
- raw: true,
4117
- port
4118
- });
3868
+ const getWebManifestPath = path => {
3869
+ const manifestPath = `${path}/extension.json`;
3870
+ return manifestPath;
4119
3871
  };
4120
3872
 
4121
- /**
4122
- * @deprecated use createWebViewWorkerRpc2 which passes the worker url as a parameter
4123
- */
4124
- const createWebViewWorkerRpc = async (rpcInfo, port) => {
4125
- // TODO this function is called from the iframe worker to create a direct
4126
- // connection between a webview/iframe and it's webworker. For this to work
4127
- // the iframe worker creates a messagechannel and sends one messageport to the webview
4128
- // and the other messageport to the webworker. This enables direct communication via
4129
- // the two message ports
3873
+ const addWebExtension = async path => {
3874
+ const manifestPath = getWebManifestPath(path);
3875
+ const manifest = await getWebExtensionManifest(path, manifestPath);
3876
+ // TODO avoid mutation if possible
3877
+ state$5.webExtensions.push(manifest);
3878
+ clear();
3879
+ return manifest;
3880
+ };
4130
3881
 
4131
- // TODO have a way so that the worker already includes the webview api and the extension
4132
- // host subworker doesn't need to import the other file
4133
- await invokeAndTransfer$2('IpcParent.create', {
4134
- method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug,
4135
- url: extensionHostSubWorkerUrl,
4136
- name: rpcInfo.name,
4137
- raw: true,
4138
- port
3882
+ const applyBulkReplacement = async (files, ranges, replacement) => {
3883
+ // eslint-disable-next-line no-console
3884
+ console.log({
3885
+ files,
3886
+ ranges,
3887
+ replacement
4139
3888
  });
3889
+ throw new Error('not implemented');
4140
3890
  };
4141
3891
 
4142
- const executeExternalCommand = (method, ...params) => {
4143
- return invoke$2(method, ...params);
3892
+ const addCssStyleSheet = (id, css) => {
3893
+ return invoke$2('Css.addCssStyleSheet', id, css);
4144
3894
  };
4145
3895
 
4146
- const BraceCompletionExecuteBraceCompletionProvider = 'ExtensionHostBraceCompletion.executeBraceCompletionProvider';
4147
- const ClosingTagExecuteClosingTagProvider = 'ExtensionHostClosingTag.executeClosingTagProvider';
4148
- const CommandExecute = 'ExtensionHostCommand.executeCommand';
4149
- const CompletionExecute = 'ExtensionHostCompletion.execute';
4150
- const CompletionResolveExecute = 'ExtensionHostCompletion.executeResolve';
4151
- const ConfigurationSetConfiguration = 'ExtensionHostConfiguration.setConfiguration';
4152
- const DefinitionExecuteDefinitionProvider = 'ExtensionHostDefinition.executeDefinitionProvider';
4153
- const DiagnosticExecuteDiagnosticProvider = 'ExtensionHost.executeDiagnosticProvider';
4154
- const ExtensionActivate = 'ExtensionHostExtension.activate';
4155
- const FileSystemGetPathSeparator = 'ExtensionHostFileSystem.getPathSeparator';
4156
- const FileSystemReadDirWithFileTypes = 'ExtensionHostFileSystem.readDirWithFileTypes';
4157
- const FileSystemReadFile = 'ExtensionHostFileSystem.readFile';
4158
- const FileSystemRename = 'ExtensionHostFileSystem.rename';
4159
- const FileSystemWriteFile = 'ExtensionHostFileSystem.writeFile';
4160
- const FormattingExecuteFormmattingProvider = 'ExtensionHostFormatting.executeFormattingProvider';
4161
- const HoverExecute = 'ExtensionHostHover.execute';
4162
- const ImplementationExecuteImplementationProvider = 'ExtensionHostImplementation.executeImplementationProvider';
4163
- const MockExec = 'ExtensionHostMockExec.mockExec';
4164
- const MockRpc = 'ExtensionHostMockRpc.mockRpc';
4165
- const OrganizeImportsExecute = 'ExtensionHostOrganizeImports.execute';
4166
- const ReferenceExecuteFileReferenceProvider = 'ExtensionHostReference.executeFileReferenceProvider';
4167
- const ReferenceExecuteReferenceProvider = 'ExtensionHostReference.executeReferenceProvider';
4168
- const ReferenceExecuteReferenceProvider2 = 'ExtensionHostReference.executeReferenceProvider2';
4169
- const SelectionExecuteSelectionProvider = 'ExtensionHostSelection.executeSelectionProvider';
4170
- const SourceControlAcceptInput = 'ExtensionHostSourceControl.acceptInput';
4171
- const SourceControlAdd = 'ExtensionHostSourceControl.add';
4172
- const SourceControlDiscard = 'ExtensionHostSourceControl.discard';
4173
- const SourceControlGetChangedFiles = 'ExtensionHost.sourceControlGetChangedFiles';
4174
- const SourceControlGetEnabledProviderIds = 'ExtensionHostSourceControl.getEnabledProviderIds';
4175
- const SourceControlGetFileBefore = 'ExtensionHostSourceControl.GetFileBefore';
4176
- const SourceControlGetGroups = 'ExtensionHostSourceControl.getGroups';
4177
- const StatusBarGetStatusBarItems = 'ExtensionHost.getStatusBarItems';
4178
- const StatusBarRegisterChangeListener = 'ExtensionHostStatusBar.registerChangeListener';
4179
- const TabCompletionExecuteTabCompletionProvider = 'ExtensionHost.executeTabCompletionProvider';
4180
- const TextDocumentSetLanguageId = 'ExtensionHostTextDocument.setLanguageId';
4181
- const TextDocumentSyncFull = 'ExtensionHostTextDocument.syncFull';
4182
- const TextDocumentSyncIncremental = 'ExtensionHostTextDocument.syncIncremental';
4183
- const TextSearchExecuteTextSearchProvider = 'ExtensionHostTextSearch.executeTextSearchProvider';
4184
- const TypeDefinitionExecuteTypeDefinitionProvider = 'ExtensionHostTypeDefinition.executeTypeDefinitionProvider';
4185
- const WorkspaceSetPath = 'Workspace.setWorkspacePath';
3896
+ const warn = (...args) => {
3897
+ console.warn(...args);
3898
+ };
4186
3899
 
4187
- const create = () => {
4188
- return {
4189
- finished: false
4190
- };
3900
+ const transparent = (color, factor) => {
3901
+ return color;
4191
3902
  };
4192
- const cancel = token => {
4193
- token.finished = true;
3903
+ const toColorRule = ([key, value]) => {
3904
+ return ` --${key}: ${value};`;
4194
3905
  };
4195
- const isCanceled = token => {
4196
- return token.finished;
3906
+ const toTokenColorRule = tokenColor => {
3907
+ return `.${tokenColor.name} { color: ${tokenColor.foreground} }`;
3908
+ };
3909
+ const addFallbackColors = colors => {
3910
+ const newColors = {
3911
+ ...colors
3912
+ };
3913
+ if (!newColors.ActivityBarInactiveForeground) {
3914
+ // TODO don't assign, avoid mutation
3915
+ newColors.ActivityBarInactiveForeground = transparent(newColors.ActivityBarForeground);
3916
+ }
3917
+ newColors.CssVariableName ||= colors.VariableName;
3918
+ return newColors;
3919
+ };
3920
+ const createColorThemeFromJson = (colorThemeId, colorThemeJson) => {
3921
+ if (!colorThemeJson) {
3922
+ warn(`color theme json for "${colorThemeId}" is empty: "${colorThemeJson}"`);
3923
+ return '';
3924
+ }
3925
+ if (typeof colorThemeJson !== 'object') {
3926
+ warn(`color theme json for "${colorThemeId}" cannot be converted to css: "${colorThemeJson}"`);
3927
+ return '';
3928
+ }
3929
+ if (Array.isArray(colorThemeJson)) {
3930
+ warn(`color theme json for "${colorThemeId}" cannot be converted to css, it must be of type object but was of type array`);
3931
+ return '';
3932
+ }
3933
+ const {
3934
+ colors
3935
+ } = colorThemeJson;
3936
+ if (!colors) {
3937
+ return '';
3938
+ }
3939
+ const newColors = addFallbackColors(colors);
3940
+ const colorRules = Object.entries(newColors).map(toColorRule);
3941
+ const tokenColors = colorThemeJson.tokenColors || [];
3942
+ const tokenColorRules = tokenColors.map(toTokenColorRule);
3943
+ const extraRules = [];
3944
+ if (colors.ContrastBorder) {
3945
+ extraRules.push(`#ActivityBar, #SideBar {
3946
+ border-left: 1px solid var(--ContrastBorder);
3947
+ }`, `#Panel {
3948
+ border-top: 1px solid var(--ContrastBorder);
3949
+ }`, `#StatusBar {
3950
+ border-top: 1px solid var(--ContrastBorder);
3951
+ }`, `.ActivityBarItemBadge {
3952
+ border: 1px solid var(--ContrastBorder);
3953
+ }`, `#QuickPick {
3954
+ border: 1px solid var(--ContrastBorder);
3955
+ }`);
3956
+ }
3957
+ const colorThemeCss = `:root {\n${colorRules.join(NewLine)}\n}\n\n${tokenColorRules.join(NewLine)}\n\n${extraRules.join(NewLine)}`;
3958
+ return colorThemeCss;
4197
3959
  };
4198
3960
 
4199
- const baseName = path => {
4200
- const slashIndex = path.lastIndexOf('/');
4201
- return path.slice(slashIndex + 1);
3961
+ // for (let i = 0; i < 10000; i++) {
3962
+ // createColorThemeFromJson({
3963
+ // type: 'dark',
3964
+ // colors: {
3965
+ // ActivityBarBackground: 'rgb(40, 46, 47)',
3966
+ // ActivityBarForeground: '#878f8c',
3967
+ // ActivityBarActiveBackground: '#1f2727',
3968
+
3969
+ // EditorBackGround: '#1e2324',
3970
+ // EditorScrollBarBackground: 'rgba(57, 71, 71, 0.6)',
3971
+ // EditorCursorBackground: '#a8df5a',
3972
+
3973
+ // ListActiveSelectionBackground: '#515f59',
3974
+ // ListActiveSelectionForeground: '#ffffff',
3975
+ // ListHoverBackground: '#405c5033',
3976
+ // ListHoverForeground: '#e0e0e0',
3977
+ // ListInactiveSelectionBackground: '#3b474280',
3978
+
3979
+ // MainBackground: '#1e2324',
3980
+
3981
+ // PanelBackground: '#1b2020',
3982
+ // PanelBorderTopColor: 'rgba(128, 128, 128, 0.35)',
3983
+
3984
+ // SideBarBackground: '#1b2020',
3985
+
3986
+ // StatusBarBackground: 'rgb(40, 46, 47)',
3987
+ // StatusBarBorderTopColor: '#222222',
3988
+
3989
+ // TabActiveBackground: '#24292a',
3990
+ // TabInactiveBackground: '#282e2f',
3991
+
3992
+ // TitleBarBackground: 'rgb(40, 46, 47)',
3993
+ // TitleBarBorderBottomColor: '#222',
3994
+ // TitleBarColor: '#cccccc',
3995
+ // TitleBarColorInactive: 'rgba(204, 204, 204, 0.6)',
3996
+ // },
3997
+ // }) //?.
3998
+ // }
3999
+
4000
+ const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
4001
+ let idbProxyableTypes;
4002
+ let cursorAdvanceMethods;
4003
+ // This is a function to prevent it throwing up in node environments.
4004
+ function getIdbProxyableTypes() {
4005
+ return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
4006
+ }
4007
+ // This is a function to prevent it throwing up in node environments.
4008
+ function getCursorAdvanceMethods() {
4009
+ return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
4010
+ }
4011
+ const transactionDoneMap = new WeakMap();
4012
+ const transformCache = new WeakMap();
4013
+ const reverseTransformCache = new WeakMap();
4014
+ function promisifyRequest(request) {
4015
+ const promise = new Promise((resolve, reject) => {
4016
+ const unlisten = () => {
4017
+ request.removeEventListener('success', success);
4018
+ request.removeEventListener('error', error);
4019
+ };
4020
+ const success = () => {
4021
+ resolve(wrap(request.result));
4022
+ unlisten();
4023
+ };
4024
+ const error = () => {
4025
+ reject(request.error);
4026
+ unlisten();
4027
+ };
4028
+ request.addEventListener('success', success);
4029
+ request.addEventListener('error', error);
4030
+ });
4031
+ // This mapping exists in reverseTransformCache but doesn't exist in transformCache. This
4032
+ // is because we create many promises from a single IDBRequest.
4033
+ reverseTransformCache.set(promise, request);
4034
+ return promise;
4035
+ }
4036
+ function cacheDonePromiseForTransaction(tx) {
4037
+ // Early bail if we've already created a done promise for this transaction.
4038
+ if (transactionDoneMap.has(tx)) return;
4039
+ const done = new Promise((resolve, reject) => {
4040
+ const unlisten = () => {
4041
+ tx.removeEventListener('complete', complete);
4042
+ tx.removeEventListener('error', error);
4043
+ tx.removeEventListener('abort', error);
4044
+ };
4045
+ const complete = () => {
4046
+ resolve();
4047
+ unlisten();
4048
+ };
4049
+ const error = () => {
4050
+ reject(tx.error || new DOMException('AbortError', 'AbortError'));
4051
+ unlisten();
4052
+ };
4053
+ tx.addEventListener('complete', complete);
4054
+ tx.addEventListener('error', error);
4055
+ tx.addEventListener('abort', error);
4056
+ });
4057
+ // Cache it for later retrieval.
4058
+ transactionDoneMap.set(tx, done);
4059
+ }
4060
+ let idbProxyTraps = {
4061
+ get(target, prop, receiver) {
4062
+ if (target instanceof IDBTransaction) {
4063
+ // Special handling for transaction.done.
4064
+ if (prop === 'done') return transactionDoneMap.get(target);
4065
+ // Make tx.store return the only store in the transaction, or undefined if there are many.
4066
+ if (prop === 'store') {
4067
+ return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
4068
+ }
4069
+ }
4070
+ // Else transform whatever we get back.
4071
+ return wrap(target[prop]);
4072
+ },
4073
+ set(target, prop, value) {
4074
+ target[prop] = value;
4075
+ return true;
4076
+ },
4077
+ has(target, prop) {
4078
+ if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
4079
+ return true;
4080
+ }
4081
+ return prop in target;
4082
+ }
4202
4083
  };
4203
- const getExtensionId = extension => {
4204
- if (extension && extension.id) {
4205
- return extension.id;
4084
+ function replaceTraps(callback) {
4085
+ idbProxyTraps = callback(idbProxyTraps);
4086
+ }
4087
+ function wrapFunction(func) {
4088
+ // Due to expected object equality (which is enforced by the caching in `wrap`), we
4089
+ // only create one new func per func.
4090
+ // Cursor methods are special, as the behaviour is a little more different to standard IDB. In
4091
+ // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the
4092
+ // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense
4093
+ // with real promises, so each advance methods returns a new promise for the cursor object, or
4094
+ // undefined if the end of the cursor has been reached.
4095
+ if (getCursorAdvanceMethods().includes(func)) {
4096
+ return function (...args) {
4097
+ // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
4098
+ // the original object.
4099
+ func.apply(unwrap(this), args);
4100
+ return wrap(this.request);
4101
+ };
4206
4102
  }
4207
- if (extension && extension.path) {
4208
- return baseName(extension.path);
4103
+ return function (...args) {
4104
+ // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use
4105
+ // the original object.
4106
+ return wrap(func.apply(unwrap(this), args));
4107
+ };
4108
+ }
4109
+ function transformCachableValue(value) {
4110
+ if (typeof value === 'function') return wrapFunction(value);
4111
+ // This doesn't return, it just creates a 'done' promise for the transaction,
4112
+ // which is later returned for transaction.done (see idbObjectHandler).
4113
+ if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
4114
+ if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
4115
+ // Return the same value back if we're not going to transform it.
4116
+ return value;
4117
+ }
4118
+ function wrap(value) {
4119
+ // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because
4120
+ // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.
4121
+ if (value instanceof IDBRequest) return promisifyRequest(value);
4122
+ // If we've already transformed this value before, reuse the transformed value.
4123
+ // This is faster, but it also provides object equality.
4124
+ if (transformCache.has(value)) return transformCache.get(value);
4125
+ const newValue = transformCachableValue(value);
4126
+ // Not all types are transformed.
4127
+ // These may be primitive types, so they can't be WeakMap keys.
4128
+ if (newValue !== value) {
4129
+ transformCache.set(value, newValue);
4130
+ reverseTransformCache.set(newValue, value);
4209
4131
  }
4210
- return '<unknown>';
4211
- };
4132
+ return newValue;
4133
+ }
4134
+ const unwrap = value => reverseTransformCache.get(value);
4212
4135
 
4213
- const getUrlPrefix = (platform, extensionPath) => {
4214
- if (extensionPath.startsWith('http://') || extensionPath.startsWith('https://')) {
4215
- return extensionPath;
4216
- }
4217
- if (platform === Web) {
4218
- return extensionPath;
4136
+ /**
4137
+ * Open a database.
4138
+ *
4139
+ * @param name Name of the database.
4140
+ * @param version Schema version.
4141
+ * @param callbacks Additional callbacks.
4142
+ */
4143
+ function openDB(name, version, {
4144
+ blocked,
4145
+ upgrade,
4146
+ blocking,
4147
+ terminated
4148
+ } = {}) {
4149
+ const request = indexedDB.open(name, version);
4150
+ const openPromise = wrap(request);
4151
+ if (upgrade) {
4152
+ request.addEventListener('upgradeneeded', event => {
4153
+ upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);
4154
+ });
4219
4155
  }
4220
- if (extensionPath.startsWith('/')) {
4221
- return `/remote${extensionPath}`;
4156
+ if (blocked) {
4157
+ request.addEventListener('blocked', event => blocked(
4158
+ // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405
4159
+ event.oldVersion, event.newVersion, event));
4222
4160
  }
4223
- return `/remote/${extensionPath}`;
4224
- };
4225
-
4226
- const handleRpcInfos = (extension, platform) => {
4227
- try {
4228
- if (!extension) {
4229
- return;
4230
- }
4231
- const rpcs = extension.rpc;
4232
- const urlPrefix = getUrlPrefix(platform, extension.path);
4233
- if (!rpcs) {
4234
- return;
4235
- }
4236
- if (!Array.isArray(rpcs)) {
4237
- return;
4161
+ openPromise.then(db => {
4162
+ if (terminated) db.addEventListener('close', () => terminated());
4163
+ if (blocking) {
4164
+ db.addEventListener('versionchange', event => blocking(event.oldVersion, event.newVersion, event));
4238
4165
  }
4239
- for (const rpc of rpcs) {
4240
- rpc.url = `${urlPrefix}/${rpc.url}`;
4241
- add$1(rpc.id, rpc);
4166
+ }).catch(() => {});
4167
+ return openPromise;
4168
+ }
4169
+ const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
4170
+ const writeMethods = ['put', 'add', 'delete', 'clear'];
4171
+ const cachedMethods = new Map();
4172
+ function getMethod(target, prop) {
4173
+ if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
4174
+ return;
4175
+ }
4176
+ if (cachedMethods.get(prop)) return cachedMethods.get(prop);
4177
+ const targetFuncName = prop.replace(/FromIndex$/, '');
4178
+ const useIndex = prop !== targetFuncName;
4179
+ const isWrite = writeMethods.includes(targetFuncName);
4180
+ if (
4181
+ // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.
4182
+ !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
4183
+ return;
4184
+ }
4185
+ const method = async function (storeName, ...args) {
4186
+ // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(
4187
+ const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
4188
+ let target = tx.store;
4189
+ if (useIndex) target = target.index(args.shift());
4190
+ // Must reject if op rejects.
4191
+ // If it's a write operation, must reject if tx.done rejects.
4192
+ // Must reject with op rejection first.
4193
+ // Must resolve with op value.
4194
+ // Must handle both promises (no unhandled rejections)
4195
+ return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
4196
+ };
4197
+ cachedMethods.set(prop, method);
4198
+ return method;
4199
+ }
4200
+ replaceTraps(oldTraps => ({
4201
+ ...oldTraps,
4202
+ get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
4203
+ has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
4204
+ }));
4205
+ const advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];
4206
+ const methodMap = {};
4207
+ const advanceResults = new WeakMap();
4208
+ const ittrProxiedCursorToOriginalProxy = new WeakMap();
4209
+ const cursorIteratorTraps = {
4210
+ get(target, prop) {
4211
+ if (!advanceMethodProps.includes(prop)) return target[prop];
4212
+ let cachedFunc = methodMap[prop];
4213
+ if (!cachedFunc) {
4214
+ cachedFunc = methodMap[prop] = function (...args) {
4215
+ advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));
4216
+ };
4242
4217
  }
4243
- } catch (error) {
4244
- console.warn(`Failed to handle extension rpcs: ${error}`);
4218
+ return cachedFunc;
4245
4219
  }
4246
4220
  };
4247
-
4248
- class ContentSecurityPolicyError extends Error {
4249
- constructor(violatedDirective, sourceFile, lineNumber, columnNumber) {
4250
- super(`Content Security Policy Violation: ${violatedDirective}`);
4251
- this.name = 'ContentSecurityPolicyError';
4252
- this.stack = sourceFile ? `Content Security Policy Violation
4253
- at ${sourceFile}:${lineNumber}:${columnNumber}` : `Content Security Policy Violation
4254
- at <unknown>`;
4221
+ async function* iterate(...args) {
4222
+ // tslint:disable-next-line:no-this-assignment
4223
+ let cursor = this;
4224
+ if (!(cursor instanceof IDBCursor)) {
4225
+ cursor = await cursor.openCursor(...args);
4226
+ }
4227
+ if (!cursor) return;
4228
+ cursor = cursor;
4229
+ const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
4230
+ ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
4231
+ // Map this double-proxy back to the original, so other cursor methods work.
4232
+ reverseTransformCache.set(proxiedCursor, unwrap(cursor));
4233
+ while (cursor) {
4234
+ yield proxiedCursor;
4235
+ // If one of the advancing methods was not called, call continue().
4236
+ cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
4237
+ advanceResults.delete(proxiedCursor);
4255
4238
  }
4256
4239
  }
4240
+ function isIteratorProp(target, prop) {
4241
+ return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
4242
+ }
4243
+ replaceTraps(oldTraps => ({
4244
+ ...oldTraps,
4245
+ get(target, prop, receiver) {
4246
+ if (isIteratorProp(target, prop)) return iterate;
4247
+ return oldTraps.get(target, prop, receiver);
4248
+ },
4249
+ has(target, prop) {
4250
+ return isIteratorProp(target, prop) || oldTraps.has(target, prop);
4251
+ }
4252
+ }));
4257
4253
 
4258
- const isImportErrorChrome = error => {
4259
- return error && error instanceof Error && error.message.startsWith('Failed to fetch dynamically imported module');
4254
+ const state$4 = {
4255
+ dbVersion: 1,
4256
+ /**
4257
+ * @type {any}
4258
+ */
4259
+ cachedDb: undefined
4260
4260
  };
4261
4261
 
4262
- const isImportErrorFirefox = error => {
4263
- return error && error instanceof TypeError && error.message === 'error loading dynamically imported module';
4264
- };
4262
+ const storeId = 'lvce-keyvalue';
4265
4263
 
4266
- const isSyntaxError = error => {
4267
- return error instanceof SyntaxError;
4268
- };
4264
+ // TODO high memory usage in idb because of transactionDoneMap
4269
4265
 
4270
- const isImportError = error => {
4271
- return isImportErrorChrome(error) || isImportErrorFirefox(error) || isSyntaxError(error);
4266
+ const getDb$1 = async () => {
4267
+ const db = await openDB(storeId, state$4.dbVersion, {
4268
+ async upgrade(db, oldVersion) {
4269
+ if (!db.objectStoreNames.contains(storeId)) {
4270
+ await db.createObjectStore(storeId, {
4271
+ autoIncrement: true
4272
+ });
4273
+ }
4274
+ }
4275
+ });
4276
+ return db;
4272
4277
  };
4273
4278
 
4274
- const sleep = duration => {
4275
- const {
4276
- resolve,
4277
- promise
4278
- } = Promise.withResolvers();
4279
- setTimeout(resolve, duration);
4280
- return promise;
4279
+ // TODO high memory usage in idb because of transactionDoneMap
4280
+
4281
+ const state$3 = {
4282
+ cachedDb: undefined
4283
+ };
4284
+ const getDbMemoized$1 = async () => {
4285
+ state$3.cachedDb ||= await getDb$1();
4286
+ return state$3.cachedDb;
4281
4287
  };
4282
4288
 
4283
- const NotFound = 404;
4289
+ // TODO high memory usage in idb because of transactionDoneMap
4284
4290
 
4285
- const RE_LINE_COLUMN = /(.*)(?:\(\d+:\d+\))/;
4286
- const getBabelErrorMessage = message => {
4287
- const match = message.match(RE_LINE_COLUMN);
4288
- if (match) {
4289
- return match[1].trim();
4291
+ const set$3 = async (key, value) => {
4292
+ try {
4293
+ const db = await getDbMemoized$1();
4294
+ await db.put(storeId, value, key);
4295
+ } catch (error) {
4296
+ throw new VError(error, 'Failed to save value to indexed db');
4290
4297
  }
4291
- return message;
4292
4298
  };
4293
- class BabelParseError extends SyntaxError {
4294
- constructor(url, error) {
4295
- const message = getBabelErrorMessage(error.message);
4296
- super(message);
4297
- this.name = 'BabelParseError';
4298
- // @ts-ignore
4299
- const {
4300
- line
4301
- } = error.loc;
4302
- // @ts-ignore
4303
- const column = error.loc.column + 1;
4304
- this.stack = `${message}
4305
- at ${url}:${line}:${column}`;
4299
+ const get$4 = async key => {
4300
+ try {
4301
+ const db = await getDbMemoized$1();
4302
+ const value = await db.get(storeId, key);
4303
+ return value;
4304
+ } catch (error) {
4305
+ throw new VError(error, 'Failed to get value from indexed db');
4306
4306
  }
4307
- }
4308
-
4309
- const loadBabelParser = () => {
4310
- const url = `${assetDir}/js/babel-parser.js`;
4311
- return import(url);
4312
4307
  };
4313
4308
 
4314
- const parse = async (code, options) => {
4315
- const BabelParse = await loadBabelParser();
4316
- return BabelParse.parse(code, options);
4309
+ const getCacheKey$1 = colorThemeId => {
4310
+ return 'color-theme-' + colorThemeId;
4311
+ };
4312
+ const get$3 = colorThemeId => {
4313
+ const cacheKey = getCacheKey$1(colorThemeId);
4314
+ return get$4(cacheKey);
4315
+ };
4316
+ const set$2 = (colorThemeId, data) => {
4317
+ const cacheKey = getCacheKey$1(colorThemeId);
4318
+ return set$3(cacheKey, data);
4317
4319
  };
4318
4320
 
4319
- const Module = 'module';
4320
-
4321
- const getLineAndColumn = (text, start, end) => {
4322
- let index = -1;
4323
- let line = 0;
4324
- const column = 0;
4325
- while ((index = text.indexOf('\n', index + 1)) !== -1) {
4326
- line++;
4327
- if (index >= start) {
4328
- break;
4329
- }
4330
- }
4331
- return {
4332
- line,
4333
- column
4334
- };
4321
+ const GetColorThemeCssCachedIndexedDb = {
4322
+ __proto__: null,
4323
+ get: get$3,
4324
+ set: set$2
4335
4325
  };
4336
4326
 
4337
- class DependencyNotFoundError extends Error {
4338
- constructor(code, start, end, dependencyRelativePath, dependencyUrl, sourceUrl) {
4339
- super(`Module not found "${dependencyRelativePath}"`);
4340
- const {
4341
- line,
4342
- column
4343
- } = getLineAndColumn(code, start);
4344
- this.stack = `${this.message}
4345
- at Module (${sourceUrl}:${line}:${column})`;
4346
- }
4347
- }
4327
+ const getText$1 = key => {
4328
+ return invoke$2('LocalStorage.getText', key);
4329
+ };
4330
+ const setText = (key, value) => {
4331
+ return invoke$2('LocalStorage.setText', key, value);
4332
+ };
4348
4333
 
4349
- const ArrowFunctionExpression = 'ArrowFunctionExpression';
4350
- const AwaitExpression = 'AwaitExpression';
4351
- const BlockStatement = 'BlockStatement';
4352
- const CallExpression = 'CallExpression';
4353
- const ExportAllDeclaration = 'ExportAllDeclaration';
4354
- const ExportNamedDeclaration = 'ExportNamedDeclaration';
4355
- const ExpressionStatement = 'ExpressionStatement';
4356
- const File$2 = 'File';
4357
- const Import = 'Import';
4358
- const ImportDeclaration = 'ImportDeclaration';
4359
- const Program = 'Program';
4360
- const StringLiteral = 'StringLiteral';
4361
- const VariableDeclaration = 'VariableDeclaration';
4362
- const VariableDeclarator = 'VariableDeclarator';
4334
+ const getCacheKey = colorThemeId => {
4335
+ return 'lvce-color-theme-' + colorThemeId;
4336
+ };
4337
+ const get$2 = colorThemeId => {
4338
+ const cacheKey = getCacheKey(colorThemeId);
4339
+ return getText$1(cacheKey);
4340
+ };
4341
+ const set$1 = (colorThemeId, data) => {
4342
+ const cacheKey = getCacheKey(colorThemeId);
4343
+ return setText(cacheKey, data);
4344
+ };
4363
4345
 
4364
- const walk = (node, visitor) => {
4365
- if (!node) {
4366
- return;
4367
- }
4368
- if (Array.isArray(node)) {
4369
- for (const item of node) {
4370
- walk(item, visitor);
4371
- }
4372
- return;
4373
- }
4374
- visitor(node);
4375
- switch (node.type) {
4376
- case File$2:
4377
- walk(node.program, visitor);
4378
- break;
4379
- case Program:
4380
- walk(node.body, visitor);
4381
- break;
4382
- case ExportNamedDeclaration:
4383
- walk(node.declaration, visitor);
4384
- break;
4385
- case VariableDeclaration:
4386
- walk(node.declarations, visitor);
4387
- break;
4388
- case VariableDeclarator:
4389
- walk(node.init, visitor);
4390
- break;
4391
- case ArrowFunctionExpression:
4392
- walk(node.body, visitor);
4393
- break;
4394
- case BlockStatement:
4395
- walk(node.body, visitor);
4396
- break;
4397
- case ExpressionStatement:
4398
- walk(node.expression, visitor);
4399
- break;
4400
- case AwaitExpression:
4401
- walk(node.argument, visitor);
4402
- break;
4403
- case CallExpression:
4404
- walk(node.callee, visitor);
4405
- break;
4406
- }
4346
+ const GetColorThemeCssCachedLocalStorage = {
4347
+ __proto__: null,
4348
+ get: get$2,
4349
+ set: set$1
4407
4350
  };
4408
4351
 
4409
- const getBabelAstDependencies = (code, ast) => {
4410
- const {
4411
- program
4412
- } = ast;
4413
- const {
4414
- body
4415
- } = program;
4416
- const dependencies = [];
4417
- for (const node of body) {
4418
- if (node.type === ImportDeclaration || node.type === ExportAllDeclaration) {
4419
- const relativePath = node.source.extra.rawValue;
4420
- const {
4421
- start
4422
- } = node.source;
4423
- const {
4424
- end
4425
- } = node.source;
4426
- // @ts-ignore
4427
- dependencies.push({
4428
- relativePath,
4429
- code,
4430
- start,
4431
- end
4432
- });
4433
- } else if (node.type === VariableDeclaration && node.declarations && node.declarations[0] && node.declarations[0].type === VariableDeclarator && node.declarations[0].init && node.declarations[0].init.type === AwaitExpression && node.declarations[0].init.argument && node.declarations[0].init.argument.type === CallExpression && node.declarations[0].init.argument.callee && node.declarations[0].init.argument.callee.type === Import && node.declarations[0].init.argument.arguments && node.declarations[0].init.argument.arguments[0] && node.declarations[0].init.argument.arguments[0].type === StringLiteral) {
4434
- const relativePath = node.declarations[0].init.argument.arguments[0].extra.rawValue;
4435
- const {
4436
- start
4437
- } = node.declarations[0].init.argument.arguments[0];
4438
- const {
4439
- end
4440
- } = node.declarations[0].init.argument.arguments[0];
4441
- // @ts-ignore
4442
- dependencies.push({
4443
- relativePath,
4444
- code,
4445
- start,
4446
- end
4447
- });
4448
- }
4449
- }
4450
- const visitor = node => {
4451
- if (node && node.type === CallExpression && node.callee && node.callee.type === Import && node.arguments && node.arguments[0] && node.arguments[0].type === StringLiteral) {
4452
- const relativePath = node.arguments[0].extra.rawValue;
4453
- const {
4454
- start
4455
- } = node.arguments[0];
4456
- const {
4457
- end
4458
- } = node.arguments[0];
4459
- // @ts-ignore
4460
- dependencies.push({
4461
- relativePath,
4462
- code,
4463
- start,
4464
- end
4465
- });
4466
- }
4467
- };
4468
- walk(ast, visitor);
4469
- return dependencies;
4352
+ const get$1 = colorThemeId => {
4353
+ return '';
4354
+ };
4355
+ const set = (colorThemeId, data) => {
4356
+ // noop
4470
4357
  };
4471
4358
 
4472
- const isBabelError = error => {
4473
- // @ts-ignore
4474
- return isSyntaxError(error) && error.code === BABEL_PARSER_SYNTAX_ERROR;
4359
+ const GetColorThemeCssCachedNoop = {
4360
+ __proto__: null,
4361
+ get: get$1,
4362
+ set
4475
4363
  };
4476
4364
 
4477
- const getOrigin = () => {
4478
- return location.origin;
4365
+ const get = key => {
4366
+ return invoke$2('Preferences.get', key);
4479
4367
  };
4480
4368
 
4481
- const getAbsoluteUrl = (relativePath, sourceUrl) => {
4482
- if (sourceUrl.startsWith('/')) {
4483
- const origin = getOrigin();
4484
- const absoluteSourceUrl = new URL(sourceUrl, origin).toString();
4485
- return new URL(relativePath, absoluteSourceUrl).toString();
4369
+ const getCacheFn = config => {
4370
+ switch (config) {
4371
+ case 'localStorage':
4372
+ return GetColorThemeCssCachedLocalStorage;
4373
+ case 'indexedDb':
4374
+ return GetColorThemeCssCachedIndexedDb;
4375
+ default:
4376
+ return GetColorThemeCssCachedNoop;
4486
4377
  }
4487
- return new URL(relativePath, sourceUrl).toString();
4378
+ };
4379
+ const getColorThemeCssCached = async (colorThemeId, getData) => {
4380
+ const config = await get('colorTheme.cache');
4381
+ const module = await getCacheFn(config);
4382
+ const cachedData = await module.get(colorThemeId);
4383
+ if (cachedData) {
4384
+ return cachedData;
4385
+ }
4386
+ const newData = await getData(colorThemeId);
4387
+ await module.set(colorThemeId, newData);
4388
+ return newData;
4488
4389
  };
4489
4390
 
4490
- const isExternal = url => {
4491
- if (url.startsWith('/')) {
4492
- return false;
4391
+ const readJson = url => {
4392
+ return invoke$2('FileSystem.readJson', url);
4393
+ };
4394
+
4395
+ const dirname = (pathSeparator, path) => {
4396
+ const index = path.lastIndexOf(pathSeparator);
4397
+ if (index === -1) {
4398
+ return path;
4493
4399
  }
4494
- if (url.startsWith(location.protocol)) {
4495
- return false;
4400
+ return path.slice(0, index);
4401
+ };
4402
+ const extname = path => {
4403
+ const index = path.lastIndexOf('.');
4404
+ if (index === -1) {
4405
+ return '';
4496
4406
  }
4497
- return true;
4407
+ return path.slice(index);
4498
4408
  };
4499
- const getErrorInDependencies = async (url, dependencies, seenUrls) => {
4500
- for (const dependency of dependencies) {
4501
- const dependencyUrl = getAbsoluteUrl(dependency.relativePath, url);
4502
- if (isExternal(dependencyUrl) || seenUrls.includes(dependencyUrl)) {
4409
+ const join = (pathSeparator, ...parts) => {
4410
+ return parts.join(pathSeparator);
4411
+ };
4412
+
4413
+ const getColorThemeUri = (extensions, colorThemeId) => {
4414
+ for (const extension of extensions) {
4415
+ if (!extension.colorThemes) {
4503
4416
  continue;
4504
4417
  }
4505
- seenUrls.push(dependencyUrl);
4506
- // let dependencyResponse
4507
- // try {
4508
- const dependencyResponse = await fetch(dependencyUrl);
4509
- // } catch (error) {}
4510
- if (dependencyResponse.ok) {
4511
- await tryToGetActualErrorMessage(null, dependencyUrl, dependencyResponse, seenUrls);
4512
- } else {
4513
- switch (dependencyResponse.status) {
4514
- case NotFound:
4515
- throw new DependencyNotFoundError(dependency.code, dependency.start, dependency.end, dependency.relativePath, dependencyUrl, url);
4516
- // return `Failed to import ${url}: ${error}`
4418
+ for (const colorTheme of extension.colorThemes) {
4419
+ if (colorTheme.id !== colorThemeId) {
4420
+ continue;
4517
4421
  }
4422
+ const absolutePath = join('/', extension.uri, colorTheme.path);
4423
+ return absolutePath;
4518
4424
  }
4519
4425
  }
4426
+ return '';
4520
4427
  };
4521
4428
 
4522
- /**
4523
- *
4524
- * @param {string} url
4525
- * @param {Response} response
4526
- * @returns
4527
- */
4528
- const tryToGetActualErrorMessage = async (error, url, response, seenUrls = []) => {
4529
- let text;
4429
+ const extensionsUrl = `${assetDir}/config/extensions.json`;
4430
+
4431
+ const getWebExtensions = async () => {
4432
+ return getJson(extensionsUrl);
4433
+ };
4434
+
4435
+ const getSharedProcessExtensions = () => {
4436
+ return invoke$2(/* ExtensionManagement.getExtensions */'ExtensionManagement.getExtensions');
4437
+ };
4438
+ const doGetExtensions = async () => {
4439
+ const meta = state$5.webExtensions;
4440
+ if (platform === Web) {
4441
+ const webExtensions = await getWebExtensions();
4442
+ return [...webExtensions, ...meta];
4443
+ }
4444
+ if (platform === Remote) {
4445
+ const sharedProcessExtensions = await getSharedProcessExtensions();
4446
+ return [...sharedProcessExtensions, ...meta];
4447
+ }
4448
+ const extensions = await getSharedProcessExtensions();
4449
+ return extensions;
4450
+ };
4451
+
4452
+ const getExtensions$1 = async () => {
4453
+ return doGetExtensions();
4454
+ };
4455
+
4456
+ // TODO getExtensions is still called 6 times on startup instead of 1
4457
+ const getExtensions = () => {
4458
+ if (!has()) {
4459
+ set$4(getExtensions$1());
4460
+ }
4461
+ return get$5();
4462
+ };
4463
+
4464
+ const getColorThemeJson$2 = async colorThemeId => {
4465
+ const extensions = await getExtensions();
4466
+ const colorThemeUri = getColorThemeUri(extensions, colorThemeId);
4467
+ const json = await readJson(colorThemeUri);
4468
+ return json;
4469
+ };
4470
+
4471
+ const getColorThemeUrlWeb = colorThemeId => {
4472
+ return `${assetDir}/extensions/builtin.theme-${colorThemeId}/color-theme.json`;
4473
+ };
4474
+ const getColorThemeJson$1 = colorThemeId => {
4475
+ const url = getColorThemeUrlWeb(colorThemeId);
4476
+ // TODO handle error ?
4477
+ return getJson(url);
4478
+ };
4479
+
4480
+ const getColorThemeJson = colorThemeId => {
4481
+ if (platform === Web) {
4482
+ return getColorThemeJson$1(colorThemeId);
4483
+ }
4484
+ return getColorThemeJson$2(colorThemeId);
4485
+ };
4486
+
4487
+ const getColorThemeCssFromJson = async (colorThemeId, colorThemeJson) => {
4488
+ const colorThemeCss = createColorThemeFromJson(/* colorThemeId */colorThemeId, /* colorThemeJson */colorThemeJson);
4489
+ return colorThemeCss;
4490
+ // TODO generate color theme from jsonc
4491
+ };
4492
+ const getColorThemeCssNew = async colorThemeId => {
4493
+ const colorThemeJson = await getColorThemeJson(colorThemeId);
4494
+ const colorThemeCss = await getColorThemeCssFromJson(colorThemeId, colorThemeJson);
4495
+ return colorThemeCss;
4496
+ };
4497
+ const getColorThemeCss = colorThemeId => {
4498
+ return getColorThemeCssCached(colorThemeId, getColorThemeCssNew);
4499
+ };
4500
+
4501
+ const getMetaThemeColor = colorThemeJson => {
4502
+ return colorThemeJson && colorThemeJson.colors && colorThemeJson.colors.TitleBarBackground;
4503
+ };
4504
+
4505
+ const setThemeColor = async themeColor => {
4506
+ await invoke$2(/* Meta.setThemeColor */'Meta.setThemeColor', /* color */themeColor);
4507
+ };
4508
+
4509
+ // TODO by default color theme should come from local storage, session storage, cache storage, indexeddb or blob url -> fast initial load
4510
+ // actual color theme can be computed after workbench has loaded (most times will be the same and doesn't need to be computed)
4511
+
4512
+ const state$2 = {
4513
+ watchedTheme: ''
4514
+ };
4515
+ const FALLBACK_COLOR_THEME_ID = 'slime';
4516
+
4517
+ // TODO json parsing should also happen in renderer worker
4518
+ // so that all validation is here (json parsing errors, invalid shape, ...)
4519
+
4520
+ const applyColorTheme = async colorThemeId => {
4530
4521
  try {
4531
- text = await response.text();
4532
- } catch {
4533
- return `Failed to import ${url}: Unknown Network Error`;
4522
+ string(colorThemeId);
4523
+ state$2.colorTheme = colorThemeId;
4524
+ const colorThemeCss = await getColorThemeCss(colorThemeId);
4525
+ await addCssStyleSheet('ContributedColorTheme', colorThemeCss);
4526
+ if (platform === Web) {
4527
+ const themeColor = getMetaThemeColor(colorThemeId) || '';
4528
+ await setThemeColor(themeColor);
4529
+ }
4530
+ if (platform !== Web && (await get('development.watchColorTheme'))) {
4531
+ watch(colorThemeId);
4532
+ }
4533
+ } catch (error) {
4534
+ throw new VError(error, `Failed to apply color theme "${colorThemeId}"`);
4534
4535
  }
4535
- let ast;
4536
+ };
4537
+ const watch = async id => {
4538
+ if (state$2.watchedTheme === id) {
4539
+ return;
4540
+ }
4541
+ state$2.watchedTheme = id;
4542
+ await invoke$2('ExtensionHost.watchColorTheme', id);
4543
+ };
4544
+ const getPreferredColorTheme = () => {
4545
+ const preferredColorTheme = get('workbench.colorTheme');
4546
+ return preferredColorTheme;
4547
+ };
4548
+
4549
+ // TODO test this, and also the error case
4550
+ // TODO have icon theme, color theme together (maybe)
4551
+ const hydrate$1 = async () => {
4552
+ const preferredColorTheme = await getPreferredColorTheme();
4553
+ const colorThemeId = preferredColorTheme || FALLBACK_COLOR_THEME_ID;
4536
4554
  try {
4537
- ast = await parse(text, {
4538
- sourceType: Module
4539
- });
4555
+ await applyColorTheme(colorThemeId);
4540
4556
  } catch (error) {
4541
- if (isBabelError(error)) {
4542
- throw new BabelParseError(url, error);
4557
+ if (colorThemeId === FALLBACK_COLOR_THEME_ID) {
4558
+ throw error;
4543
4559
  }
4544
- throw error;
4545
- }
4546
- const dependencies = getBabelAstDependencies(text, ast);
4547
- await getErrorInDependencies(url, dependencies, seenUrls);
4548
- if (hasRecentErrors()) {
4549
- const recentError = getRecentError();
4550
- // @ts-ignore
4551
- throw new ContentSecurityPolicyError(recentError.violatedDirective, recentError.sourceFile, recentError.lineNumber, recentError.columnNumber);
4560
+ console.error(error);
4561
+ await applyColorTheme(FALLBACK_COLOR_THEME_ID);
4552
4562
  }
4553
- const contentType = response.headers.get('Content-Type');
4554
- if (url.endsWith('.ts') && contentType === null) {
4555
- return `Failed to import ${url}: Missing Content-Type header for javascript`;
4563
+ };
4564
+
4565
+ const iframeWorkerUrl = `${assetDir}/packages/renderer-worker/node_modules/@lvce-editor/iframe-worker/dist/iframeWorkerMain.js`;
4566
+
4567
+ const getConfiguredIframeWorkerUrl = async () => {
4568
+ let configuredWorkerUrl = (await get('develop.iframeWorkerPath')) || '';
4569
+ if (configuredWorkerUrl) {
4570
+ configuredWorkerUrl = '/remote' + configuredWorkerUrl;
4556
4571
  }
4557
- return `Failed to import ${url}: Unknown Network Error`;
4572
+ configuredWorkerUrl = configuredWorkerUrl || iframeWorkerUrl;
4573
+ return configuredWorkerUrl;
4574
+ };
4575
+
4576
+ const state$1 = {
4577
+ id: 0
4578
+ };
4579
+ const create = () => {
4580
+ return ++state$1.id;
4581
+ };
4582
+
4583
+ const iframeWorkerCommandMap = {
4584
+ 'WebView.compatExtensionHostWorkerInvoke': (...args) => invoke$2('WebView.compatExtensionHostWorkerInvoke', ...args),
4585
+ 'WebView.compatExtensionHostWorkerInvokeAndTransfer': (...args) => invokeAndTransfer$2('WebView.compatExtensionHostWorkerInvokeAndTransfer', ...args),
4586
+ 'WebView.compatRendererProcessInvoke': (...args) => invoke$2('WebView.compatRendererProcessInvoke', ...args),
4587
+ 'WebView.compatRendererProcessInvokeAndTransfer': (...args) => invokeAndTransfer$2('WebView.compatRendererProcessInvokeAndTransfer', ...args),
4588
+ // @ts-ignore
4589
+ 'WebView.compatRendererWorkerInvokeAndTransfer': (...args) => invokeAndTransfer$2(...args),
4590
+ // @ts-ignore
4591
+ 'WebView.compatRendererWorkerInvoke': (...args) => invoke$2(...args),
4592
+ 'WebView.compatSharedProcessInvoke': (...args) => invoke$2('WebView.compatSharedProcessInvoke', ...args),
4593
+ 'WebView.getSavedState': (...args) => invoke$2('WebView.getSavedState', ...args),
4594
+ 'WebView.getWebViewInfo': (...args) => invoke$2('WebView.getWebViewInfo', ...args),
4595
+ 'WebView.getWebViews': (...args) => invoke$2('WebView.getWebViews', ...args),
4596
+ 'WebView.setPort': (...args) => invoke$2('WebView.setPort', ...args),
4597
+ 'ExtensionHostManagement.activateByEvent': (...args) => invoke$2('ExtensionHostManagement.activateByEvent', ...args),
4598
+ 'WebView.getRemoteUrl': options => getRemoteUrlForWebView(options.uri, options)
4558
4599
  };
4559
4600
 
4560
- const tryToGetActualImportErrorMessage = async (url, error) => {
4561
- let response;
4562
- try {
4563
- response = await fetch(url);
4564
- } catch (error) {
4565
- return `Failed to import ${url}: ${error}`;
4566
- }
4567
- if (response.ok) {
4568
- return await tryToGetActualErrorMessage(error, url, response);
4569
- }
4570
- switch (response.status) {
4571
- case NotFound:
4572
- throw new Error(`Failed to import ${url}: Not found (404)`);
4573
- default:
4574
- return `Failed to import ${url}: ${error}`;
4575
- }
4601
+ const launchIframeWorker = async () => {
4602
+ const configuredWorkerUrl = await getConfiguredIframeWorkerUrl();
4603
+ const name = 'Iframe Worker';
4604
+ const id = create();
4605
+ const rpc = await create$2({
4606
+ method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug$1,
4607
+ name,
4608
+ url: configuredWorkerUrl,
4609
+ id,
4610
+ commandMap: iframeWorkerCommandMap
4611
+ });
4612
+ return rpc;
4576
4613
  };
4577
4614
 
4578
- const importScript = async url => {
4579
- try {
4580
- return await import(url);
4581
- } catch (error) {
4582
- if (isImportError(error)) {
4583
- const actualErrorMessage = await tryToGetActualImportErrorMessage(url, error);
4584
- throw new Error(actualErrorMessage);
4585
- }
4586
- // content security policy errors arrive a little bit later
4587
- await sleep(0);
4588
- if (hasRecentErrors()) {
4589
- const recentError = getRecentError();
4590
- // @ts-ignore
4591
- throw new ContentSecurityPolicyError(recentError.violatedDirective, recentError.sourceFile, recentError.lineNumber, recentError.columnNumber);
4592
- }
4593
- throw error;
4615
+ let workerPromise;
4616
+ const ensureWorker = () => {
4617
+ if (!workerPromise) {
4618
+ workerPromise = launchIframeWorker();
4594
4619
  }
4620
+ return workerPromise;
4595
4621
  };
4596
-
4597
- const states = Object.create(null);
4598
- const set = status => {
4599
- states[status.id] = status;
4622
+ const isActive = () => {
4623
+ return Boolean(workerPromise);
4600
4624
  };
4601
- const get = extensionId => {
4602
- return states[extensionId];
4625
+ const invoke = async (method, ...params) => {
4626
+ const rpc = await ensureWorker();
4627
+ return rpc.invoke(method, ...params);
4603
4628
  };
4604
- const update = (id, update) => {
4605
- states[id] = {
4606
- ...states[id],
4607
- ...update
4608
- };
4629
+ const invokeAndTransfer = async (method, ...params) => {
4630
+ const rpc = await ensureWorker();
4631
+ return rpc.invokeAndTransfer(method, ...params);
4609
4632
  };
4610
4633
 
4611
- const None = 0;
4612
- const Importing = 1;
4613
- const Activating = 2;
4614
- const Activated = 3;
4615
- const Error$1 = 4;
4634
+ const createWebView3 = async ({
4635
+ id,
4636
+ uri,
4637
+ isGitpod,
4638
+ platform,
4639
+ assetDir,
4640
+ webViewScheme,
4641
+ useNewWebViewHandler
4642
+ }) => {
4643
+ await invoke('WebView.create3', {
4644
+ id,
4645
+ uri,
4646
+ isGitpod,
4647
+ platform,
4648
+ assetDir,
4649
+ webViewScheme,
4650
+ useNewWebViewHandler
4651
+ });
4652
+ };
4616
4653
 
4617
- const activationTimeout = 10_000;
4618
- const rejectAfterTimeout = async (timeout, token) => {
4619
- await sleep(timeout);
4620
- if (isCanceled(token)) {
4621
- return;
4622
- }
4623
- throw new Error(`Activation timeout of ${timeout}ms exceeded`);
4654
+ const createWebViewWorkerRpc2 = async (rpcInfo, port) => {
4655
+ // TODO this function is called from the iframe worker to create a direct
4656
+ // connection between a webview/iframe and it's webworker. For this to work
4657
+ // the iframe worker creates a messagechannel and sends one messageport to the webview
4658
+ // and the other messageport to the webworker. This enables direct communication via
4659
+ // the two message ports
4660
+
4661
+ // TODO have a way so that the worker already includes the webview api and the extension
4662
+ // host subworker doesn't need to import the other file
4663
+ await invokeAndTransfer$2('IpcParent.create', {
4664
+ method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug,
4665
+ url: rpcInfo.url,
4666
+ name: rpcInfo.name,
4667
+ raw: true,
4668
+ port
4669
+ });
4624
4670
  };
4625
4671
 
4626
- // TODO separate importing extension and activating extension for smaller functions
4627
- // and better error handling
4628
- const activate = async (extension, absolutePath, activationEvent) => {
4629
- const extensionId = extension.id;
4630
- try {
4631
- string(extension.path);
4632
- string(extension.browser);
4633
- string(absolutePath);
4634
- set({
4635
- activationEvent: activationEvent,
4636
- id: extensionId,
4637
- activationTime: 0,
4638
- status: Importing
4639
- });
4640
- const startTime = performance.now();
4641
- const module = await importScript(absolutePath);
4642
- handleRpcInfos(extension, platform);
4643
- update(extensionId, {
4644
- status: Activating
4645
- });
4646
- const token = create();
4647
- try {
4648
- await Promise.race([module.activate(extension), rejectAfterTimeout(activationTimeout, token)]);
4649
- const endTime = performance.now();
4650
- const time = endTime - startTime;
4651
- update(extensionId, {
4652
- status: Activated,
4653
- activationTime: time
4654
- });
4655
- } catch (error) {
4656
- if (isImportError(error)) {
4657
- const actualErrorMessage = await tryToGetActualImportErrorMessage(absolutePath, error);
4658
- throw new Error(actualErrorMessage);
4659
- }
4660
- throw error;
4661
- } finally {
4662
- cancel(token);
4663
- }
4664
- } catch (error) {
4665
- update(extensionId, {
4666
- status: Error$1 // TODO maybe store error also in runtime status state
4667
- });
4668
- const id = getExtensionId(extension);
4669
- throw new VError(error, `Failed to activate extension ${id}`);
4670
- }
4671
- // console.info('activated', path)
4672
+ /**
4673
+ * @deprecated use createWebViewWorkerRpc2 which passes the worker url as a parameter
4674
+ */
4675
+ const createWebViewWorkerRpc = async (rpcInfo, port) => {
4676
+ // TODO this function is called from the iframe worker to create a direct
4677
+ // connection between a webview/iframe and it's webworker. For this to work
4678
+ // the iframe worker creates a messagechannel and sends one messageport to the webview
4679
+ // and the other messageport to the webworker. This enables direct communication via
4680
+ // the two message ports
4681
+
4682
+ // TODO have a way so that the worker already includes the webview api and the extension
4683
+ // host subworker doesn't need to import the other file
4684
+ await invokeAndTransfer$2('IpcParent.create', {
4685
+ method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug,
4686
+ url: extensionHostSubWorkerUrl,
4687
+ name: rpcInfo.name,
4688
+ raw: true,
4689
+ port
4690
+ });
4691
+ };
4692
+
4693
+ const executeExternalCommand = (method, ...params) => {
4694
+ return invoke$2(method, ...params);
4672
4695
  };
4673
4696
 
4697
+ const BraceCompletionExecuteBraceCompletionProvider = 'ExtensionHostBraceCompletion.executeBraceCompletionProvider';
4698
+ const ClosingTagExecuteClosingTagProvider = 'ExtensionHostClosingTag.executeClosingTagProvider';
4699
+ const CommandExecute = 'ExtensionHostCommand.executeCommand';
4700
+ const CompletionExecute = 'ExtensionHostCompletion.execute';
4701
+ const CompletionResolveExecute = 'ExtensionHostCompletion.executeResolve';
4702
+ const ConfigurationSetConfiguration = 'ExtensionHostConfiguration.setConfiguration';
4703
+ const DefinitionExecuteDefinitionProvider = 'ExtensionHostDefinition.executeDefinitionProvider';
4704
+ const DiagnosticExecuteDiagnosticProvider = 'ExtensionHost.executeDiagnosticProvider';
4705
+ const ExtensionActivate = 'ExtensionHostExtension.activate';
4706
+ const FileSystemGetPathSeparator = 'ExtensionHostFileSystem.getPathSeparator';
4707
+ const FileSystemReadDirWithFileTypes = 'ExtensionHostFileSystem.readDirWithFileTypes';
4708
+ const FileSystemReadFile = 'ExtensionHostFileSystem.readFile';
4709
+ const FileSystemRename = 'ExtensionHostFileSystem.rename';
4710
+ const FileSystemWriteFile = 'ExtensionHostFileSystem.writeFile';
4711
+ const FormattingExecuteFormmattingProvider = 'ExtensionHostFormatting.executeFormattingProvider';
4712
+ const HoverExecute = 'ExtensionHostHover.execute';
4713
+ const ImplementationExecuteImplementationProvider = 'ExtensionHostImplementation.executeImplementationProvider';
4714
+ const MockExec = 'ExtensionHostMockExec.mockExec';
4715
+ const MockRpc = 'ExtensionHostMockRpc.mockRpc';
4716
+ const OrganizeImportsExecute = 'ExtensionHostOrganizeImports.execute';
4717
+ const ReferenceExecuteFileReferenceProvider = 'ExtensionHostReference.executeFileReferenceProvider';
4718
+ const ReferenceExecuteReferenceProvider = 'ExtensionHostReference.executeReferenceProvider';
4719
+ const ReferenceExecuteReferenceProvider2 = 'ExtensionHostReference.executeReferenceProvider2';
4720
+ const SelectionExecuteSelectionProvider = 'ExtensionHostSelection.executeSelectionProvider';
4721
+ const SourceControlAcceptInput = 'ExtensionHostSourceControl.acceptInput';
4722
+ const SourceControlAdd = 'ExtensionHostSourceControl.add';
4723
+ const SourceControlDiscard = 'ExtensionHostSourceControl.discard';
4724
+ const SourceControlGetChangedFiles = 'ExtensionHost.sourceControlGetChangedFiles';
4725
+ const SourceControlGetEnabledProviderIds = 'ExtensionHostSourceControl.getEnabledProviderIds';
4726
+ const SourceControlGetFileBefore = 'ExtensionHostSourceControl.GetFileBefore';
4727
+ const SourceControlGetGroups = 'ExtensionHostSourceControl.getGroups';
4728
+ const StatusBarGetStatusBarItems = 'ExtensionHost.getStatusBarItems';
4729
+ const StatusBarRegisterChangeListener = 'ExtensionHostStatusBar.registerChangeListener';
4730
+ const TabCompletionExecuteTabCompletionProvider = 'ExtensionHost.executeTabCompletionProvider';
4731
+ const TextDocumentSetLanguageId = 'ExtensionHostTextDocument.setLanguageId';
4732
+ const TextDocumentSyncFull = 'ExtensionHostTextDocument.syncFull';
4733
+ const TextDocumentSyncIncremental = 'ExtensionHostTextDocument.syncIncremental';
4734
+ const TextSearchExecuteTextSearchProvider = 'ExtensionHostTextSearch.executeTextSearchProvider';
4735
+ const TypeDefinitionExecuteTypeDefinitionProvider = 'ExtensionHostTypeDefinition.executeTypeDefinitionProvider';
4736
+ const WorkspaceSetPath = 'Workspace.setWorkspacePath';
4737
+
4674
4738
  class ExecError extends Error {
4675
4739
  constructor(command, args, stdout, stderr, exitCode) {
4676
4740
  super(`Failed to execute ${command}: process exited with code ${exitCode}`);
@@ -5146,10 +5210,15 @@ const emptyStatus = {
5146
5210
  status: None,
5147
5211
  id: '',
5148
5212
  activationEvent: '',
5149
- activationTime: 0
5213
+ activationStartTime: 0,
5214
+ activationEndTime: 0,
5215
+ activationTime: 0,
5216
+ importEndTime: 0,
5217
+ importStartTime: 0,
5218
+ importTime: 0
5150
5219
  };
5151
5220
  const getRuntimeStatus = extensionId => {
5152
- return get(extensionId) || emptyStatus;
5221
+ return get$6(extensionId) || emptyStatus;
5153
5222
  };
5154
5223
 
5155
5224
  const getWebViewInfo2 = providerId => {
@@ -5254,10 +5323,49 @@ const setIconTheme = async iconThemeId => {
5254
5323
  }
5255
5324
  };
5256
5325
  const hydrate = async () => {
5257
- const iconThemeId = (await get$1('icon-theme')) || 'vscode-icons';
5326
+ const iconThemeId = (await get('icon-theme')) || 'vscode-icons';
5258
5327
  await setIconTheme(iconThemeId);
5259
5328
  };
5260
5329
 
5330
+ const importExtension = async (extensionId, absolutePath, activationEvent) => {
5331
+ try {
5332
+ string(absolutePath);
5333
+ const startTime = performance.now();
5334
+ set$5({
5335
+ activationEvent: activationEvent,
5336
+ id: extensionId,
5337
+ activationStartTime: performance.now(),
5338
+ status: Importing,
5339
+ activationEndTime: 0,
5340
+ activationTime: 0,
5341
+ importStartTime: startTime,
5342
+ importEndTime: 0,
5343
+ importTime: 0
5344
+ });
5345
+ try {
5346
+ const module = await importScript(absolutePath);
5347
+ const endTime = performance.now();
5348
+ const time = endTime - startTime;
5349
+ set$6(extensionId, module);
5350
+ update(extensionId, {
5351
+ importEndTime: endTime,
5352
+ importTime: time
5353
+ });
5354
+ } catch (error) {
5355
+ update(extensionId, {
5356
+ status: Error$1 // TODO maybe store error also in runtime status state
5357
+ });
5358
+ if (isImportError(error)) {
5359
+ const actualErrorMessage = await tryToGetActualImportErrorMessage(absolutePath, error);
5360
+ throw new Error(actualErrorMessage);
5361
+ }
5362
+ throw error;
5363
+ }
5364
+ } catch (error) {
5365
+ throw new VError(error, `Failed to import extension ${extensionId}`);
5366
+ }
5367
+ };
5368
+
5261
5369
  const isDataCloneError = error => {
5262
5370
  return error && error.name === 'DataCloneError';
5263
5371
  };
@@ -5776,7 +5884,9 @@ const commandMap = {
5776
5884
  'ColorTheme.getColorThemeNames': getColorThemeNames,
5777
5885
  'ColorTheme.hydrate': hydrate$1,
5778
5886
  'ExecuteExternalCommand.executeExternalCommand': executeExternalCommand,
5887
+ 'ExtensionHost.activateExtension2': activateExtension2,
5779
5888
  'ExtensionHost.getRuntimeStatus': getRuntimeStatus,
5889
+ 'ExtensionHost.importExtension': importExtension,
5780
5890
  'ExtensionHost.launchIframeWorker': launchIframeWorker,
5781
5891
  'ExtensionHostDebug.evaluate': evaluate,
5782
5892
  'ExtensionHostDebug.getCallStack': getCallStack,
@@ -5831,12 +5941,12 @@ const commandMap = {
5831
5941
  'IconTheme.hydrate': hydrate,
5832
5942
  'IconTheme.setIconTheme': setIconTheme,
5833
5943
  'IndexedDb.addHandle': addHandle,
5834
- 'IndexedDb.get': get$5,
5944
+ 'IndexedDb.get': get$4,
5835
5945
  'IndexedDb.getHandle': getHandle$1,
5836
5946
  'IndexedDb.getValues': getValues,
5837
5947
  'IndexedDb.getValuesByIndexName': getValuesByIndexName,
5838
5948
  'IndexedDb.saveValue': saveValue,
5839
- 'IndexedDb.set': set$4,
5949
+ 'IndexedDb.set': set$3,
5840
5950
  'Languages.getLanguages': getLanguages,
5841
5951
  'SaveState.saveState': saveState,
5842
5952
  'SearchFileWithFetch.searchFileWithFetch': searchFile$2,
@@ -5860,7 +5970,7 @@ const commandMap = {
5860
5970
  [ConfigurationSetConfiguration]: setConfigurations,
5861
5971
  [DefinitionExecuteDefinitionProvider]: executeDefinitionProvider,
5862
5972
  [DiagnosticExecuteDiagnosticProvider]: executeDiagnosticProvider,
5863
- [ExtensionActivate]: activate,
5973
+ [ExtensionActivate]: activateExtension,
5864
5974
  [FileSystemGetPathSeparator]: getPathSeparator,
5865
5975
  [FileSystemReadDirWithFileTypes]: readDirWithFileTypes$2,
5866
5976
  [FileSystemReadFile]: readFile$2,