@lvce-editor/extension-management-worker 1.12.0 → 1.14.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.
@@ -587,7 +587,7 @@ const callbacks = Object.create(null);
587
587
  const set$8 = (id, fn) => {
588
588
  callbacks[id] = fn;
589
589
  };
590
- const get$4 = id => {
590
+ const get$5 = id => {
591
591
  return callbacks[id];
592
592
  };
593
593
  const remove = id => {
@@ -768,7 +768,7 @@ const warn$1 = (...args) => {
768
768
  console.warn(...args);
769
769
  };
770
770
  const resolve = (id, response) => {
771
- const fn = get$4(id);
771
+ const fn = get$5(id);
772
772
  if (!fn) {
773
773
  console.log(response);
774
774
  warn$1(`callback ${id} may already be disposed`);
@@ -948,10 +948,10 @@ const send = (transport, method, ...params) => {
948
948
  const message = create$4$1(method, params);
949
949
  transport.send(message);
950
950
  };
951
- const invoke$4 = (ipc, method, ...params) => {
951
+ const invoke$5 = (ipc, method, ...params) => {
952
952
  return invokeHelper(ipc, method, params, false);
953
953
  };
954
- const invokeAndTransfer$1 = (ipc, method, ...params) => {
954
+ const invokeAndTransfer$2 = (ipc, method, ...params) => {
955
955
  return invokeHelper(ipc, method, params, true);
956
956
  };
957
957
 
@@ -987,10 +987,10 @@ const createRpc = ipc => {
987
987
  send(ipc, method, ...params);
988
988
  },
989
989
  invoke(method, ...params) {
990
- return invoke$4(ipc, method, ...params);
990
+ return invoke$5(ipc, method, ...params);
991
991
  },
992
992
  invokeAndTransfer(method, ...params) {
993
- return invokeAndTransfer$1(ipc, method, ...params);
993
+ return invokeAndTransfer$2(ipc, method, ...params);
994
994
  },
995
995
  async dispose() {
996
996
  await ipc?.dispose();
@@ -1028,6 +1028,26 @@ const listen$1 = async (module, options) => {
1028
1028
  const ipc = module.wrap(rawIpc);
1029
1029
  return ipc;
1030
1030
  };
1031
+ const create$e = async ({
1032
+ commandMap,
1033
+ messagePort,
1034
+ isMessagePortOpen
1035
+ }) => {
1036
+ // TODO create a commandMap per rpc instance
1037
+ register(commandMap);
1038
+ const rawIpc = await IpcParentWithMessagePort$1.create({
1039
+ messagePort,
1040
+ isMessagePortOpen
1041
+ });
1042
+ const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
1043
+ handleIpc(ipc);
1044
+ const rpc = createRpc(ipc);
1045
+ return rpc;
1046
+ };
1047
+ const MessagePortRpcParent = {
1048
+ __proto__: null,
1049
+ create: create$e
1050
+ };
1031
1051
  const create$5 = async ({
1032
1052
  commandMap,
1033
1053
  messagePort
@@ -1138,29 +1158,29 @@ const FileSystemWorker = 209;
1138
1158
  const RendererWorker = 1;
1139
1159
  const SharedProcess = 1;
1140
1160
 
1141
- const rpcs = Object.create(null);
1161
+ const rpcs$1 = Object.create(null);
1142
1162
  const set$7 = (id, rpc) => {
1143
- rpcs[id] = rpc;
1163
+ rpcs$1[id] = rpc;
1144
1164
  };
1145
- const get$3 = id => {
1146
- return rpcs[id];
1165
+ const get$4 = id => {
1166
+ return rpcs$1[id];
1147
1167
  };
1148
1168
 
1149
1169
  const create$1 = rpcId => {
1150
1170
  return {
1151
1171
  async dispose() {
1152
- const rpc = get$3(rpcId);
1172
+ const rpc = get$4(rpcId);
1153
1173
  await rpc.dispose();
1154
1174
  },
1155
1175
  // @ts-ignore
1156
1176
  invoke(method, ...params) {
1157
- const rpc = get$3(rpcId);
1177
+ const rpc = get$4(rpcId);
1158
1178
  // @ts-ignore
1159
1179
  return rpc.invoke(method, ...params);
1160
1180
  },
1161
1181
  // @ts-ignore
1162
1182
  invokeAndTransfer(method, ...params) {
1163
- const rpc = get$3(rpcId);
1183
+ const rpc = get$4(rpcId);
1164
1184
  // @ts-ignore
1165
1185
  return rpc.invokeAndTransfer(method, ...params);
1166
1186
  },
@@ -1171,47 +1191,47 @@ const create$1 = rpcId => {
1171
1191
  };
1172
1192
 
1173
1193
  const {
1174
- invoke: invoke$3,
1194
+ invoke: invoke$4,
1175
1195
  set: set$6
1176
1196
  } = create$1(ExtensionHostWorker);
1177
1197
 
1178
1198
  const {
1179
- invoke: invoke$2,
1199
+ invoke: invoke$3,
1180
1200
  set: set$5
1181
1201
  } = create$1(FileSystemWorker);
1182
1202
  const readFile = async uri => {
1183
- return invoke$2('FileSystem.readFile', uri);
1203
+ return invoke$3('FileSystem.readFile', uri);
1184
1204
  };
1185
1205
  const writeFile = async (uri, content) => {
1186
- return invoke$2('FileSystem.writeFile', uri, content);
1206
+ return invoke$3('FileSystem.writeFile', uri, content);
1187
1207
  };
1188
1208
  const exists = async uri => {
1189
1209
  // @ts-ignore
1190
- return invoke$2('FileSystem.exists', uri);
1210
+ return invoke$3('FileSystem.exists', uri);
1191
1211
  };
1192
1212
 
1193
1213
  const {
1194
- invoke: invoke$1,
1195
- invokeAndTransfer,
1214
+ invoke: invoke$2,
1215
+ invokeAndTransfer: invokeAndTransfer$1,
1196
1216
  set: set$4
1197
1217
  } = create$1(RendererWorker);
1198
1218
  const sendMessagePortToFileSystemWorker = async (port, rpcId) => {
1199
1219
  const command = 'FileSystem.handleMessagePort';
1200
1220
  // @ts-ignore
1201
- await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToFileSystemWorker', port, command, rpcId);
1221
+ await invokeAndTransfer$1('SendMessagePortToExtensionHostWorker.sendMessagePortToFileSystemWorker', port, command, rpcId);
1202
1222
  };
1203
1223
  const sendMessagePortToExtensionHostWorker = async (port, rpcId = 0) => {
1204
1224
  const command = 'HandleMessagePort.handleMessagePort2';
1205
- await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, rpcId);
1225
+ await invokeAndTransfer$1('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, command, rpcId);
1206
1226
  };
1207
1227
  const sendMessagePortToSharedProcess = async port => {
1208
1228
  const command = 'HandleElectronMessagePort.handleElectronMessagePort';
1209
1229
  // @ts-ignore
1210
- await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToSharedProcess', port, command, 0);
1230
+ await invokeAndTransfer$1('SendMessagePortToExtensionHostWorker.sendMessagePortToSharedProcess', port, command, 0);
1211
1231
  };
1212
1232
 
1213
1233
  const {
1214
- invoke,
1234
+ invoke: invoke$1,
1215
1235
  set: set$3
1216
1236
  } = create$1(SharedProcess);
1217
1237
 
@@ -1261,7 +1281,7 @@ const states = Object.create(null);
1261
1281
  const set$2 = status => {
1262
1282
  states[status.id] = status;
1263
1283
  };
1264
- const get$2 = extensionId => {
1284
+ const get$3 = extensionId => {
1265
1285
  return states[extensionId];
1266
1286
  };
1267
1287
  const update$1 = (id, update) => {
@@ -1317,7 +1337,7 @@ const rejectAfterTimeout = async (timeout, token) => {
1317
1337
  throw new Error(`Activation timeout of ${timeout}ms exceeded`);
1318
1338
  };
1319
1339
  const activate = async (extensionId, extension) => {
1320
- await invoke$3('ExtensionHost.activateExtension3', extensionId, extension);
1340
+ await invoke$4('ExtensionHost.activateExtension3', extensionId, extension);
1321
1341
  };
1322
1342
  const activateExtension2 = async (extensionId, extension, absolutePath) => {
1323
1343
  string(extensionId);
@@ -1353,6 +1373,49 @@ const activateExtension2 = async (extensionId, extension, absolutePath) => {
1353
1373
  }
1354
1374
  };
1355
1375
 
1376
+ const rpcs = Object.create(null);
1377
+ const add = (id, rpc) => {
1378
+ rpcs[id] = rpc;
1379
+ };
1380
+ const get$2 = id => {
1381
+ return rpcs[id];
1382
+ };
1383
+
1384
+ const getUrlPrefix = (platform, extensionPath) => {
1385
+ if (extensionPath.startsWith('http://') || extensionPath.startsWith('https://')) {
1386
+ return extensionPath;
1387
+ }
1388
+ if (platform === Web) {
1389
+ return extensionPath;
1390
+ }
1391
+ if (extensionPath.startsWith('/')) {
1392
+ return `/remote${extensionPath}`;
1393
+ }
1394
+ return `/remote/${extensionPath}`;
1395
+ };
1396
+
1397
+ const handleRpcInfos = (extension, platform) => {
1398
+ try {
1399
+ if (!extension) {
1400
+ return;
1401
+ }
1402
+ const rpcs = extension.rpc;
1403
+ const urlPrefix = getUrlPrefix(platform, extension.path);
1404
+ if (!rpcs) {
1405
+ return;
1406
+ }
1407
+ if (!Array.isArray(rpcs)) {
1408
+ return;
1409
+ }
1410
+ for (const rpc of rpcs) {
1411
+ rpc.url = `${urlPrefix}/${rpc.url}`;
1412
+ add(rpc.id, rpc);
1413
+ }
1414
+ } catch (error) {
1415
+ console.warn(`Failed to handle extension rpcs: ${error}`);
1416
+ }
1417
+ };
1418
+
1356
1419
  const importExtension = async (extensionId, absolutePath, activationEvent) => {
1357
1420
  try {
1358
1421
  string(absolutePath);
@@ -1369,7 +1432,7 @@ const importExtension = async (extensionId, absolutePath, activationEvent) => {
1369
1432
  status: Importing
1370
1433
  });
1371
1434
  try {
1372
- await invoke$3('ExtensionHost.importExtension2', extensionId, absolutePath);
1435
+ await invoke$4('ExtensionHost.importExtension2', extensionId, absolutePath);
1373
1436
  const endTime = performance.now();
1374
1437
  const time = endTime - startTime;
1375
1438
  update$1(extensionId, {
@@ -1391,7 +1454,8 @@ const importExtension = async (extensionId, absolutePath, activationEvent) => {
1391
1454
  }
1392
1455
  };
1393
1456
 
1394
- const activateExtension3 = async (extension, absolutePath, activationEvent) => {
1457
+ const activateExtension3 = async (extension, absolutePath, activationEvent, platform) => {
1458
+ handleRpcInfos(extension, platform);
1395
1459
  const extensionId = extension.id;
1396
1460
  await importExtension(extensionId, absolutePath, activationEvent);
1397
1461
  await activateExtension2(extensionId, extension, absolutePath);
@@ -1450,8 +1514,62 @@ const addWebExtension = async path => {
1450
1514
  return manifest;
1451
1515
  };
1452
1516
 
1517
+ const ModuleWorkerAndWorkaroundForChromeDevtoolsBug = 6;
1518
+
1519
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
1520
+ const invoke = (method, ...params) => {
1521
+ return invoke$2(method, ...params);
1522
+ };
1523
+ const invokeAndTransfer = (method, ...params) => {
1524
+ return invokeAndTransfer$1(method, ...params);
1525
+ };
1526
+
1527
+ const createWebViewWorkerRpc2 = async (rpcInfo, port) => {
1528
+ // TODO this function is called from the iframe worker to create a direct
1529
+ // connection between a webview/iframe and it's webworker. For this to work
1530
+ // the iframe worker creates a messagechannel and sends one messageport to the webview
1531
+ // and the other messageport to the webworker. This enables direct communication via
1532
+ // the two message ports
1533
+
1534
+ // TODO have a way so that the worker already includes the webview api and the extension
1535
+ // host subworker doesn't need to import the other file
1536
+ await invokeAndTransfer('IpcParent.create', {
1537
+ method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug,
1538
+ name: rpcInfo.name,
1539
+ port,
1540
+ raw: true,
1541
+ url: rpcInfo.url
1542
+ });
1543
+ };
1544
+
1545
+ const getExtensionHostSubWorkerUrl = () => {
1546
+ return new URL('../../../../extension-host-sub-worker/src/extensionHostSubWorkerMain.js', import.meta.url).toString();
1547
+ };
1548
+ const extensionHostSubWorkerUrl = getExtensionHostSubWorkerUrl();
1549
+
1550
+ /**
1551
+ * @deprecated use createWebViewWorkerRpc2 which passes the worker url as a parameter
1552
+ */
1553
+ const createWebViewWorkerRpc = async (rpcInfo, port) => {
1554
+ // TODO this function is called from the iframe worker to create a direct
1555
+ // connection between a webview/iframe and it's webworker. For this to work
1556
+ // the iframe worker creates a messagechannel and sends one messageport to the webview
1557
+ // and the other messageport to the webworker. This enables direct communication via
1558
+ // the two message ports
1559
+
1560
+ // TODO have a way so that the worker already includes the webview api and the extension
1561
+ // host subworker doesn't need to import the other file
1562
+ await invokeAndTransfer('IpcParent.create', {
1563
+ method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug,
1564
+ name: rpcInfo.name,
1565
+ port,
1566
+ raw: true,
1567
+ url: extensionHostSubWorkerUrl
1568
+ });
1569
+ };
1570
+
1453
1571
  const invalidateExtensionsCache = async () => {
1454
- await invoke$1('ExtensionManagement.invalidateExtensionsCache');
1572
+ await invoke$2('ExtensionManagement.invalidateExtensionsCache');
1455
1573
  };
1456
1574
 
1457
1575
  let state = {
@@ -1482,7 +1600,7 @@ const disableExtension = async (id, isTest) => {
1482
1600
  };
1483
1601
  set$1(newState);
1484
1602
  } else {
1485
- await invoke('ExtensionManagement.disable', id);
1603
+ await invoke$1('ExtensionManagement.disable', id);
1486
1604
  }
1487
1605
  await invalidateExtensionsCache();
1488
1606
  return undefined;
@@ -1497,7 +1615,7 @@ const enableExtension = async (id, isTest) => {
1497
1615
  platform
1498
1616
  } = oldState;
1499
1617
  if (platform === Remote || platform === Electron) {
1500
- const disabledExtensionsJsonPath = await invoke$1('PlatformPaths.getBuiltinExtensionsJsonPath');
1618
+ const disabledExtensionsJsonPath = await invoke$2('PlatformPaths.getBuiltinExtensionsJsonPath');
1501
1619
  const exists$1 = await exists(disabledExtensionsJsonPath);
1502
1620
  if (!exists$1) {
1503
1621
  return undefined;
@@ -1663,7 +1781,7 @@ const getColorThemeCssCached = async (colorThemeId, platform, getData) => {
1663
1781
  };
1664
1782
 
1665
1783
  const readJson = url => {
1666
- return invoke$1('FileSystem.readJson', url);
1784
+ return invoke$2('FileSystem.readJson', url);
1667
1785
  };
1668
1786
 
1669
1787
  const join = (pathSeparator, ...parts) => {
@@ -1691,7 +1809,7 @@ const getAllExtensions = async () => {
1691
1809
  if (state.platform === Web) {
1692
1810
  return [];
1693
1811
  }
1694
- return invoke('ExtensionManagement.getAllExtensions');
1812
+ return invoke$1('ExtensionManagement.getAllExtensions');
1695
1813
  };
1696
1814
 
1697
1815
  const getColorThemeJson$2 = async colorThemeId => {
@@ -1764,6 +1882,70 @@ const getExtension = async id => {
1764
1882
  return undefined;
1765
1883
  };
1766
1884
 
1885
+ const getPortTuple = () => {
1886
+ const {
1887
+ port1,
1888
+ port2
1889
+ } = new MessageChannel();
1890
+ return {
1891
+ port1,
1892
+ port2
1893
+ };
1894
+ };
1895
+
1896
+ const createWebViewIpc = async webView => {
1897
+ const {
1898
+ origin,
1899
+ uid
1900
+ } = webView;
1901
+ const {
1902
+ port1,
1903
+ port2
1904
+ } = getPortTuple();
1905
+ const rpcPromise = MessagePortRpcParent.create({
1906
+ commandMap: {},
1907
+ isMessagePortOpen: false,
1908
+ messagePort: port2
1909
+ });
1910
+ const portType = 'test';
1911
+ await invokeAndTransfer('WebView.setPort', uid, port1, origin, portType);
1912
+ // TODO maybe don't send a message port only to get object url?
1913
+ // TODO dispose rpc to avoid memory leak
1914
+ const rpc = await rpcPromise;
1915
+ return rpc;
1916
+ };
1917
+
1918
+ const webViews = Object.create(null);
1919
+ const getWebView = id => {
1920
+ return webViews[id];
1921
+ };
1922
+
1923
+ // TODO if webViewId is provided,
1924
+ // 1. read file as blob
1925
+ // 2. send blob to webview
1926
+ // 3. create objecturl in webview
1927
+ // 4. send back objecturl to extension host worker
1928
+ // 5. provide objectUrl to extension
1929
+
1930
+ const getRemoteUrlForWebView = async (uri, options = {}) => {
1931
+ // TODO webviews should be stored in iframe worker
1932
+ const webView = getWebView(options.webViewId);
1933
+ if (!webView) {
1934
+ throw new Error(`webview ${options.webViewId} not found`);
1935
+ }
1936
+ const [rpc, blob] = await Promise.all([createWebViewIpc(webView), invoke('FileSystem.getBlob', uri)]);
1937
+ const objectUrl = await rpc.invoke('createObjectUrl', blob);
1938
+ return objectUrl;
1939
+ };
1940
+
1941
+ const getRpcInfo = rpcId => {
1942
+ const info = get$2(rpcId);
1943
+ if (!info) {
1944
+ throw new Error(`Rpc not found ${rpcId}`);
1945
+ }
1946
+ return info;
1947
+ };
1948
+
1767
1949
  const emptyStatus = {
1768
1950
  activationEndTime: 0,
1769
1951
  activationEvent: '',
@@ -1776,7 +1958,7 @@ const emptyStatus = {
1776
1958
  status: None
1777
1959
  };
1778
1960
  const getRuntimeStatus = extensionId => {
1779
- return get$2(extensionId) || emptyStatus;
1961
+ return get$3(extensionId) || emptyStatus;
1780
1962
  };
1781
1963
 
1782
1964
  const commandMapRef = {};
@@ -1905,6 +2087,8 @@ const commandMap = {
1905
2087
  'Extensions.activate2': activateExtension2,
1906
2088
  'Extensions.activate3': activateExtension3,
1907
2089
  'Extensions.addWebExtension': addWebExtension,
2090
+ 'Extensions.createWebViewWorkerRpc': createWebViewWorkerRpc,
2091
+ 'Extensions.createWebViewWorkerRpc2': createWebViewWorkerRpc2,
1908
2092
  'Extensions.disable': disableExtension,
1909
2093
  'Extensions.enable': enableExtension,
1910
2094
  'Extensions.getAllExtensions': getAllExtensions,
@@ -1914,6 +2098,8 @@ const commandMap = {
1914
2098
  'Extensions.getColorThemeNames': getColorThemeNames,
1915
2099
  'Extensions.getExtension': getExtension,
1916
2100
  'Extensions.getLanguages': getLanguages,
2101
+ 'Extensions.getRemoteUrlForWebView': getRemoteUrlForWebView,
2102
+ 'Extensions.getRpcInfo': getRpcInfo,
1917
2103
  'Extensions.getRuntimeStatus': getRuntimeStatus,
1918
2104
  'Extensions.handleMessagePort': handleMessagePort,
1919
2105
  'Extensions.importExtension': importExtension,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-management-worker",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "Webworker for the Extension Management functionality in Lvce Editor.",
5
5
  "keywords": [
6
6
  "web-worker"