@lvce-editor/extension-management-worker 1.5.0 → 1.6.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.
@@ -535,7 +535,7 @@ const create$4$1 = (method, params) => {
535
535
  };
536
536
  };
537
537
  const callbacks = Object.create(null);
538
- const set$4 = (id, fn) => {
538
+ const set$5 = (id, fn) => {
539
539
  callbacks[id] = fn;
540
540
  };
541
541
  const get$2 = id => {
@@ -554,7 +554,7 @@ const registerPromise = () => {
554
554
  resolve,
555
555
  promise
556
556
  } = Promise.withResolvers();
557
- set$4(id, resolve);
557
+ set$5(id, resolve);
558
558
  return {
559
559
  id,
560
560
  promise
@@ -769,7 +769,7 @@ const getErrorProperty = (error, prettyError) => {
769
769
  }
770
770
  };
771
771
  };
772
- const create$1$1 = (id, error) => {
772
+ const create$1$2 = (id, error) => {
773
773
  return {
774
774
  jsonrpc: Two,
775
775
  id,
@@ -780,7 +780,7 @@ const getErrorResponse = (id, error, preparePrettyError, logError) => {
780
780
  const prettyError = preparePrettyError(error);
781
781
  logError(error, prettyError);
782
782
  const errorProperty = getErrorProperty(error, prettyError);
783
- return create$1$1(id, errorProperty);
783
+ return create$1$2(id, errorProperty);
784
784
  };
785
785
  const create$6 = (message, result) => {
786
786
  return {
@@ -899,7 +899,7 @@ const send = (transport, method, ...params) => {
899
899
  const message = create$4$1(method, params);
900
900
  transport.send(message);
901
901
  };
902
- const invoke$2 = (ipc, method, ...params) => {
902
+ const invoke$3 = (ipc, method, ...params) => {
903
903
  return invokeHelper(ipc, method, params, false);
904
904
  };
905
905
  const invokeAndTransfer$1 = (ipc, method, ...params) => {
@@ -938,7 +938,7 @@ const createRpc = ipc => {
938
938
  send(ipc, method, ...params);
939
939
  },
940
940
  invoke(method, ...params) {
941
- return invoke$2(ipc, method, ...params);
941
+ return invoke$3(ipc, method, ...params);
942
942
  },
943
943
  invokeAndTransfer(method, ...params) {
944
944
  return invokeAndTransfer$1(ipc, method, ...params);
@@ -1047,7 +1047,7 @@ const getHost = () => {
1047
1047
  const getProtocol = () => {
1048
1048
  return location.protocol;
1049
1049
  };
1050
- const create$1 = async ({
1050
+ const create$1$1 = async ({
1051
1051
  commandMap,
1052
1052
  type
1053
1053
  }) => {
@@ -1063,7 +1063,7 @@ const create$1 = async ({
1063
1063
  };
1064
1064
  const WebSocketRpcParent2 = {
1065
1065
  __proto__: null,
1066
- create: create$1
1066
+ create: create$1$1
1067
1067
  };
1068
1068
  const create$4 = async ({
1069
1069
  commandMap
@@ -1080,21 +1080,23 @@ const WebWorkerRpcClient = {
1080
1080
  create: create$4
1081
1081
  };
1082
1082
 
1083
+ const Web = 1;
1083
1084
  const Electron = 2;
1084
1085
  const Remote = 3;
1085
1086
 
1087
+ const FileSystemWorker = 209;
1086
1088
  const RendererWorker = 1;
1087
1089
  const SharedProcess = 1;
1088
1090
 
1089
1091
  const rpcs = Object.create(null);
1090
- const set$3 = (id, rpc) => {
1092
+ const set$4 = (id, rpc) => {
1091
1093
  rpcs[id] = rpc;
1092
1094
  };
1093
1095
  const get$1 = id => {
1094
1096
  return rpcs[id];
1095
1097
  };
1096
1098
 
1097
- const create = rpcId => {
1099
+ const create$1 = rpcId => {
1098
1100
  return {
1099
1101
  async dispose() {
1100
1102
  const rpc = get$1(rpcId);
@@ -1113,16 +1115,36 @@ const create = rpcId => {
1113
1115
  return rpc.invokeAndTransfer(method, ...params);
1114
1116
  },
1115
1117
  set(rpc) {
1116
- set$3(rpcId, rpc);
1118
+ set$4(rpcId, rpc);
1117
1119
  }
1118
1120
  };
1119
1121
  };
1120
1122
 
1123
+ const {
1124
+ invoke: invoke$2,
1125
+ set: set$3
1126
+ } = create$1(FileSystemWorker);
1127
+ const readFile = async uri => {
1128
+ return invoke$2('FileSystem.readFile', uri);
1129
+ };
1130
+ const writeFile = async (uri, content) => {
1131
+ return invoke$2('FileSystem.writeFile', uri, content);
1132
+ };
1133
+ const exists = async uri => {
1134
+ // @ts-ignore
1135
+ return invoke$2('FileSystem.exists', uri);
1136
+ };
1137
+
1121
1138
  const {
1122
1139
  invoke: invoke$1,
1123
1140
  invokeAndTransfer,
1124
1141
  set: set$2
1125
- } = create(RendererWorker);
1142
+ } = create$1(RendererWorker);
1143
+ const sendMessagePortToFileSystemWorker = async (port, rpcId) => {
1144
+ const command = 'FileSystem.handleMessagePort';
1145
+ // @ts-ignore
1146
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToFileSystemWorker', port, command, rpcId);
1147
+ };
1126
1148
  const sendMessagePortToSharedProcess = async port => {
1127
1149
  const command = 'HandleElectronMessagePort.handleElectronMessagePort';
1128
1150
  // @ts-ignore
@@ -1136,7 +1158,132 @@ const getExtension$1 = async id => {
1136
1158
  const {
1137
1159
  invoke,
1138
1160
  set: set$1
1139
- } = create(SharedProcess);
1161
+ } = create$1(SharedProcess);
1162
+
1163
+ const create = () => {
1164
+ return {
1165
+ finished: false
1166
+ };
1167
+ };
1168
+ const cancel = token => {
1169
+ token.finished = true;
1170
+ };
1171
+ const isCanceled = token => {
1172
+ return token.finished;
1173
+ };
1174
+
1175
+ const baseName = path => {
1176
+ const slashIndex = path.lastIndexOf('/');
1177
+ return path.slice(slashIndex + 1);
1178
+ };
1179
+ const getExtensionId = extension => {
1180
+ if (extension && extension.id) {
1181
+ return extension.id;
1182
+ }
1183
+ if (extension && extension.path) {
1184
+ return baseName(extension.path);
1185
+ }
1186
+ return '<unknown>';
1187
+ };
1188
+
1189
+ const isImportErrorChrome = error => {
1190
+ return Boolean(error && error instanceof Error && error.message.startsWith('Failed to fetch dynamically imported module'));
1191
+ };
1192
+
1193
+ const isImportErrorFirefox = error => {
1194
+ return Boolean(error && error instanceof TypeError && error.message === 'error loading dynamically imported module');
1195
+ };
1196
+
1197
+ const isSyntaxError = error => {
1198
+ return error instanceof SyntaxError;
1199
+ };
1200
+
1201
+ const isImportError = error => {
1202
+ return isImportErrorChrome(error) || isImportErrorFirefox(error) || isSyntaxError(error);
1203
+ };
1204
+
1205
+ const states = Object.create(null);
1206
+ const update$1 = (id, update) => {
1207
+ states[id] = {
1208
+ ...states[id],
1209
+ ...update
1210
+ };
1211
+ };
1212
+
1213
+ const Activating = 2;
1214
+ const Activated = 3;
1215
+ const Error$1 = 4;
1216
+
1217
+ const sleep = duration => {
1218
+ const {
1219
+ promise,
1220
+ resolve
1221
+ } = Promise.withResolvers();
1222
+ setTimeout(resolve, duration);
1223
+ return promise;
1224
+ };
1225
+
1226
+ const NotFound = 404;
1227
+
1228
+ const tryToGetActualImportErrorMessage = async (url, error) => {
1229
+ let response;
1230
+ try {
1231
+ response = await fetch(url);
1232
+ } catch (error) {
1233
+ return `Failed to import ${url}: ${error}`;
1234
+ }
1235
+ if (response.ok) {
1236
+ throw new Error(`Failed to import ${url}: Unknown Error`);
1237
+ }
1238
+ switch (response.status) {
1239
+ case NotFound:
1240
+ throw new Error(`Failed to import ${url}: Not found (404)`);
1241
+ default:
1242
+ return `Failed to import ${url}: ${error}`;
1243
+ }
1244
+ };
1245
+
1246
+ // TODO make activation timeout configurable or remove it.
1247
+ // some extension might do workspace indexing which could take some time
1248
+ const activationTimeout = 10_000;
1249
+ const rejectAfterTimeout = async (timeout, token) => {
1250
+ await sleep(timeout);
1251
+ if (isCanceled(token)) {
1252
+ return;
1253
+ }
1254
+ throw new Error(`Activation timeout of ${timeout}ms exceeded`);
1255
+ };
1256
+ const activate = async extension => {};
1257
+ const activateExtension2 = async (extensionId, extension, absolutePath) => {
1258
+ const token = create();
1259
+ try {
1260
+ const startTime = performance.now();
1261
+ update$1(extensionId, {
1262
+ activationStartTime: startTime,
1263
+ status: Activating
1264
+ });
1265
+ await Promise.race([activate(extension), rejectAfterTimeout(activationTimeout, token)]);
1266
+ const endTime = performance.now();
1267
+ const time = endTime - startTime;
1268
+ update$1(extensionId, {
1269
+ activationEndTime: endTime,
1270
+ activationTime: time,
1271
+ status: Activated
1272
+ });
1273
+ } catch (error) {
1274
+ const id = getExtensionId(extension);
1275
+ if (isImportError(error)) {
1276
+ const actualErrorMessage = await tryToGetActualImportErrorMessage(absolutePath, error);
1277
+ throw new Error(`Failed to activate extension ${id}: ${actualErrorMessage}`);
1278
+ }
1279
+ update$1(extensionId, {
1280
+ status: Error$1 // TODO maybe store error also in runtime status state
1281
+ });
1282
+ throw new VError(error, `Failed to activate extension ${id}`);
1283
+ } finally {
1284
+ cancel(token);
1285
+ }
1286
+ };
1140
1287
 
1141
1288
  const invalidateExtensionsCache = async () => {
1142
1289
  await invoke$1('ExtensionManagement.invalidateExtensionsCache');
@@ -1161,9 +1308,9 @@ const get = () => {
1161
1308
  };
1162
1309
 
1163
1310
  const disableExtension = async (id, isTest) => {
1311
+ const oldState = get();
1164
1312
  try {
1165
1313
  if (isTest) {
1166
- const oldState = get();
1167
1314
  const newState = {
1168
1315
  ...oldState,
1169
1316
  disabledIds: [...oldState.disabledIds, id]
@@ -1180,22 +1327,34 @@ const disableExtension = async (id, isTest) => {
1180
1327
  };
1181
1328
 
1182
1329
  const enableExtension = async (id, isTest) => {
1183
- try {
1184
- if (isTest) {
1185
- const oldState = get();
1186
- const newState = {
1187
- ...oldState,
1188
- disabledIds: oldState.disabledIds.filter(existing => existing !== id)
1189
- };
1190
- set(newState);
1191
- } else {
1192
- await invoke('ExtensionManagement.enable', id);
1330
+ const oldState = get();
1331
+ const {
1332
+ platform
1333
+ } = oldState;
1334
+ if (platform === Remote || platform === Electron) {
1335
+ const disabledExtensionsJsonPath = await invoke$1('PlatformPaths.getBuiltinExtensionsJsonPath');
1336
+ const exists$1 = await exists(disabledExtensionsJsonPath);
1337
+ if (!exists$1) {
1338
+ return undefined;
1193
1339
  }
1194
- await invalidateExtensionsCache();
1195
- return undefined;
1196
- } catch (error) {
1197
- return error;
1340
+ const content = await readFile(disabledExtensionsJsonPath);
1341
+ const parsed = JSON.parse(content);
1342
+ const oldDisabled = parsed.disabledExtensions || [];
1343
+ const newDisabled = oldDisabled.filter(item => item !== id);
1344
+ const newData = {
1345
+ disabledExtensions: newDisabled
1346
+ };
1347
+ const newContent = JSON.stringify(newData, null, 2) + '\n';
1348
+ await writeFile(disabledExtensionsJsonPath, newContent);
1349
+ }
1350
+ if (isTest) {
1351
+ const newState = {
1352
+ ...oldState,
1353
+ disabledIds: oldState.disabledIds.filter(existing => existing !== id)
1354
+ };
1355
+ set(newState);
1198
1356
  }
1357
+ return undefined;
1199
1358
  };
1200
1359
 
1201
1360
  const getExtension = async id => {
@@ -1204,6 +1363,14 @@ const getExtension = async id => {
1204
1363
  return extension;
1205
1364
  };
1206
1365
 
1366
+ const getAllExtensions = async () => {
1367
+ const state = get();
1368
+ if (state.platform === Web) {
1369
+ return [];
1370
+ }
1371
+ return invoke(/* ExtensionManagement.getAllExtensions */'ExtensionManagement.getAllExtensions');
1372
+ };
1373
+
1207
1374
  const commandMapRef = {};
1208
1375
 
1209
1376
  const handleMessagePort = async port => {
@@ -1213,6 +1380,16 @@ const handleMessagePort = async port => {
1213
1380
  });
1214
1381
  };
1215
1382
 
1383
+ const initializeFileSystemWorker = async () => {
1384
+ const rpc = await TransferMessagePortRpcParent.create({
1385
+ commandMap: commandMapRef,
1386
+ async send(port) {
1387
+ await sendMessagePortToFileSystemWorker(port, 0);
1388
+ }
1389
+ });
1390
+ set$3(rpc);
1391
+ };
1392
+
1216
1393
  const getRpc = async platform => {
1217
1394
  // TODO create connection to shared process
1218
1395
  if (platform === Remote) {
@@ -1244,7 +1421,7 @@ const initialize = async platform => {
1244
1421
  update({
1245
1422
  platform
1246
1423
  });
1247
- await initializeSharedProcess(platform);
1424
+ await Promise.all([initializeFileSystemWorker(), initializeSharedProcess(platform)]);
1248
1425
  };
1249
1426
 
1250
1427
  const installExtension = async () => {
@@ -1256,8 +1433,10 @@ const uninstallExtension = async () => {
1256
1433
  };
1257
1434
 
1258
1435
  const commandMap = {
1436
+ 'Extensions.activate2': activateExtension2,
1259
1437
  'Extensions.disable': disableExtension,
1260
1438
  'Extensions.enable': enableExtension,
1439
+ 'Extensions.getAllExtensions': getAllExtensions,
1261
1440
  'Extensions.getExtension': getExtension,
1262
1441
  'Extensions.handleMessagePort': handleMessagePort,
1263
1442
  'Extensions.initialize': initialize,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-management-worker",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Webworker for the Extension Management functionality in Lvce Editor.",
5
5
  "keywords": [
6
6
  "web-worker"