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