@lvce-editor/extension-management-worker 4.40.1 → 4.41.1

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.
@@ -1438,6 +1438,7 @@ const Importing = 1;
1438
1438
  const Activating = 2;
1439
1439
  const Activated = 3;
1440
1440
  const Error$1 = 4;
1441
+ const Terminated = 5;
1441
1442
 
1442
1443
  /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
1443
1444
 
@@ -1534,6 +1535,13 @@ const resetExtensionRuntimeState = extensionId => {
1534
1535
  });
1535
1536
  };
1536
1537
 
1538
+ const getErrorMessage = error => {
1539
+ if (error instanceof Error) {
1540
+ return error.message;
1541
+ }
1542
+ return String(error);
1543
+ };
1544
+
1537
1545
  const baseName = path => {
1538
1546
  const slashIndex = path.lastIndexOf('/');
1539
1547
  return path.slice(slashIndex + 1);
@@ -1627,16 +1635,21 @@ const activateExtension2 = async (extensionId, extension, absolutePath, extensio
1627
1635
  });
1628
1636
  } catch (error) {
1629
1637
  const id = getExtensionId$4(extension);
1638
+ let activationError = error;
1630
1639
  if (isImportError(error)) {
1631
1640
  const actualErrorMessage = await tryToGetActualImportErrorMessage(absolutePath, error);
1632
- throw new Error(`Failed to activate extension ${id}: ${actualErrorMessage}`, {
1641
+ activationError = new Error(`Failed to activate extension ${id}: ${actualErrorMessage}`, {
1633
1642
  cause: error
1634
1643
  });
1635
1644
  }
1636
1645
  updateRuntimeStatus(extensionId, {
1637
- status: Error$1 // TODO maybe store error also in runtime status state
1646
+ error: getErrorMessage(activationError),
1647
+ status: Error$1
1638
1648
  });
1639
- throw new VError(error, `Failed to activate extension ${id}`);
1649
+ if (activationError !== error) {
1650
+ throw activationError;
1651
+ }
1652
+ throw new VError(activationError, `Failed to activate extension ${id}`);
1640
1653
  } finally {
1641
1654
  cancel(token);
1642
1655
  }
@@ -1821,6 +1834,7 @@ const activateIsolatedExtension = async (extensionId, absolutePath, workerName,
1821
1834
  });
1822
1835
  } catch (error) {
1823
1836
  updateRuntimeStatus(extensionId, {
1837
+ error: getErrorMessage(error),
1824
1838
  status: Error$1
1825
1839
  });
1826
1840
  throw error;
@@ -1915,16 +1929,18 @@ const importExtension = async (extensionId, absolutePath, activationEvent, exten
1915
1929
  importTime: time
1916
1930
  });
1917
1931
  } catch (error) {
1918
- updateRuntimeStatus(extensionId, {
1919
- status: Error$1 // TODO maybe store error also in runtime status state
1920
- });
1932
+ let importError = error;
1921
1933
  if (isImportError(error)) {
1922
1934
  const actualErrorMessage = await tryToGetActualImportErrorMessage(absolutePath, error);
1923
- throw new Error(actualErrorMessage, {
1935
+ importError = new Error(actualErrorMessage, {
1924
1936
  cause: error
1925
1937
  });
1926
1938
  }
1927
- throw error;
1939
+ updateRuntimeStatus(extensionId, {
1940
+ error: getErrorMessage(importError),
1941
+ status: Error$1
1942
+ });
1943
+ throw importError;
1928
1944
  }
1929
1945
  } catch (error) {
1930
1946
  throw new VError(error, `Failed to import extension ${extensionId}`);
@@ -2284,12 +2300,17 @@ const getExtensionId$3 = extension => {
2284
2300
  const getAbsolutePath$1 = (extension, assetDir, platform) => {
2285
2301
  return getExtensionAbsolutePath(extension.id, extension.isWeb, extension.builtin, extension.path || extension.uri, extension.browser, globalThis.location.origin, platform, assetDir);
2286
2302
  };
2303
+ const notifyRunningExtensionsChanged = () => {
2304
+ setTimeout(() => {
2305
+ void invoke$2('Layout.handleExtensionsChanged');
2306
+ }, 0);
2307
+ };
2287
2308
  const doActivateExtension = async (extension, absolutePath, event, platform) => {
2288
2309
  const extensionId = getExtensionId$3(extension);
2289
2310
  try {
2290
2311
  await activateExtension3(extension, absolutePath, event, platform);
2291
2312
  runningExtensions[extensionId] = true;
2292
- await invoke$2('Layout.handleExtensionsChanged');
2313
+ notifyRunningExtensionsChanged();
2293
2314
  } finally {
2294
2315
  delete activatingExtensions[extensionId];
2295
2316
  }
@@ -3599,10 +3620,16 @@ const getIcon = (extension, manifestView, assetDir, platform) => {
3599
3620
  return '';
3600
3621
  };
3601
3622
 
3623
+ const statusNames = {
3624
+ [Activated]: 'running',
3625
+ [Error$1]: 'error',
3626
+ [Terminated]: 'terminated'
3627
+ };
3602
3628
  const getRunningExtensionsFromState = (extensions, runtimeStatuses, assetDir, platform) => {
3603
3629
  return extensions.flatMap(extension => {
3604
3630
  const runtimeStatus = runtimeStatuses[extension.id];
3605
- if (!runtimeStatus || runtimeStatus.status !== Activated) {
3631
+ const status = runtimeStatus && statusNames[runtimeStatus.status];
3632
+ if (!runtimeStatus || !status) {
3606
3633
  return [];
3607
3634
  }
3608
3635
  const manifestIcon = typeof extension.icon === 'string' ? extension.icon.replace(/^\.\//, '') : undefined;
@@ -3613,19 +3640,51 @@ const getRunningExtensionsFromState = (extensions, runtimeStatuses, assetDir, pl
3613
3640
  ...extension,
3614
3641
  activationEvent: runtimeStatus.activationEvent,
3615
3642
  activationTime: runtimeStatus.activationTime,
3643
+ error: runtimeStatus.error || '',
3616
3644
  ...(icon && {
3617
3645
  icon
3618
- })
3646
+ }),
3647
+ status
3619
3648
  }];
3620
3649
  }).toSorted((a, b) => b.activationTime - a.activationTime);
3621
3650
  };
3622
3651
 
3652
+ const invokePing = async rpc => {
3653
+ try {
3654
+ await rpc.invoke('ExtensionApi.ping');
3655
+ } catch {
3656
+ // Any response proves that the worker is still alive.
3657
+ }
3658
+ return true;
3659
+ };
3660
+ const waitForTimeout = async (timeout, sleep) => {
3661
+ await sleep(timeout);
3662
+ return false;
3663
+ };
3664
+ const isResponsive = async (rpc, timeout, sleep) => {
3665
+ return Promise.race([invokePing(rpc), waitForTimeout(timeout, sleep)]);
3666
+ };
3667
+ const updateTerminatedExtensionStatuses = async (runtimeStatuses, getRpc = get$3, timeout = 250, sleep$1 = sleep) => {
3668
+ const activatedStatuses = Object.values(runtimeStatuses).filter(status => status.status === Activated);
3669
+ await Promise.all(activatedStatuses.map(async status => {
3670
+ const rpc = getRpc(status.id);
3671
+ if (!rpc || (await isResponsive(rpc, timeout, sleep$1))) {
3672
+ return;
3673
+ }
3674
+ updateRuntimeStatus(status.id, {
3675
+ error: 'Extension worker stopped responding',
3676
+ status: Terminated
3677
+ });
3678
+ }));
3679
+ };
3680
+
3623
3681
  const getRunningExtensions = async (assetDir, platform) => {
3624
3682
  const {
3625
3683
  assetDir: resolvedAssetDir,
3626
3684
  platform: resolvedPlatform
3627
3685
  } = await getRuntimeContext(assetDir, platform);
3628
3686
  const extensions = await getAllExtensions(resolvedAssetDir, resolvedPlatform);
3687
+ await updateTerminatedExtensionStatuses(get$5().runtimeStatuses);
3629
3688
  const {
3630
3689
  runtimeStatuses
3631
3690
  } = get$5();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-management-worker",
3
- "version": "4.40.1",
3
+ "version": "4.41.1",
4
4
  "description": "Webworker for the Extension Management functionality in Lvce Editor.",
5
5
  "keywords": [
6
6
  "web-worker"