@lvce-editor/extension-management-worker 4.73.0 → 4.74.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.
@@ -1986,177 +1986,14 @@ const createExtensionCommandExecutor = commandMap => {
1986
1986
  };
1987
1987
  };
1988
1988
 
1989
- const rpcs$1 = Object.create(null);
1990
- const applicationRpcs = new Map();
1991
- const get$3 = (extensionId, applicationId) => {
1992
- if (applicationId !== undefined) {
1993
- return applicationRpcs.get(applicationId)?.get(extensionId);
1994
- }
1995
- return rpcs$1[extensionId];
1996
- };
1997
- const getAll = applicationId => {
1998
- if (applicationId !== undefined) {
1999
- return [...(applicationRpcs.get(applicationId)?.values() || [])];
2000
- }
2001
- return Object.values(rpcs$1);
2002
- };
2003
- const getIds = applicationId => {
2004
- if (applicationId !== undefined) {
2005
- return [...(applicationRpcs.get(applicationId)?.keys() || [])];
2006
- }
2007
- return Object.keys(rpcs$1);
2008
- };
2009
- const set$2 = (extensionId, rpc, applicationId) => {
2010
- if (applicationId !== undefined) {
2011
- const entries = applicationRpcs.get(applicationId) || new Map();
2012
- entries.set(extensionId, rpc);
2013
- applicationRpcs.set(applicationId, entries);
2014
- return;
2015
- }
2016
- rpcs$1[extensionId] = rpc;
2017
- };
2018
- const remove$1 = (extensionId, applicationId) => {
2019
- const rpc = rpcs$1[extensionId];
2020
- delete rpcs$1[extensionId];
2021
- return rpc;
2022
- };
2023
- const clear = applicationId => {
2024
- if (applicationId !== undefined) {
2025
- applicationRpcs.delete(applicationId);
2026
- return;
2027
- }
2028
- for (const key of Object.keys(rpcs$1)) {
2029
- delete rpcs$1[key];
2030
- }
2031
- };
2032
-
2033
- /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
2034
-
2035
- const pendingRpcs = Object.create(null);
2036
- const getPendingExtensionIds = application => {
2037
- return Object.keys(pendingRpcs).flatMap(key => {
2038
- const [applicationId, generation, extensionId] = JSON.parse(key);
2039
- return applicationId === application.applicationId && generation === application.applicationGeneration ? [extensionId] : [];
2040
- });
2041
- };
2042
- const getRuntimeId = (extensionId, application) => {
2043
- return application?.applicationId === undefined ? extensionId : JSON.stringify([application.applicationId, application.applicationGeneration, extensionId]);
2044
- };
2045
- const bindCommandMap = (rpc, commandMap) => {
2046
- if (rpc.ipc) {
2047
- rpc.ipc.execute = createExtensionCommandExecutor(commandMap);
2048
- }
2049
- return rpc;
2050
- };
2051
- const createIsolatedExtensionHostWorker = async (extensionId, absolutePath, workerName, contentSecurityPolicy, createRpc, invokeAndTransfer, application) => {
2052
- const runtimeId = getRuntimeId(extensionId, application);
2053
- const invokeCommand = application === undefined ? undefined : (method, ...args) => {
2054
- assertCurrentApplication(application);
2055
- if (method === 'Extensions.registerFileChangeHandler') {
2056
- return register$1(extensionId, application.applicationId);
2057
- }
2058
- if (method === 'Extensions.unregisterFileChangeHandler') {
2059
- return unregister(extensionId, application.applicationId);
2060
- }
2061
- const invokeApplication = commandMapRef['Extensions.invokeForApplication'];
2062
- if (!invokeApplication) {
2063
- throw new Error('Application extension command routing is not initialized');
2064
- }
2065
- return invokeApplication(application.applicationId, method, ...args);
2066
- };
2067
- const commandMap = createExtensionCommandMap(runtimeId, invokeCommand);
2068
- const rpc = await createRpc({
2069
- // PlainMessagePortRpc registers this map process-wide. Bind the restricted
2070
- // callbacks to this port below, never to the shared host command table.
2071
- commandMap: {},
2072
- isMessagePortOpen: true,
2073
- send(port) {
2074
- return invokeAndTransfer('LaunchIsolatedExtensionHostWorker.launchIsolatedExtensionHostWorker', port, runtimeId, absolutePath, workerName, contentSecurityPolicy);
2075
- }
2076
- });
2077
- return bindCommandMap(rpc, commandMap);
2078
- };
2079
- const createWorker$1 = (extensionId, absolutePath, workerName, contentSecurityPolicy, application) => {
2080
- return createIsolatedExtensionHostWorker(extensionId, absolutePath, workerName, contentSecurityPolicy, create$6, invokeAndTransfer, application);
2081
- };
2082
- const createAndStoreRpc = async (extensionId, absolutePath, workerName, contentSecurityPolicy, create, application) => {
2083
- try {
2084
- const rpc = application === undefined ? await create(extensionId, absolutePath, workerName, contentSecurityPolicy) : await create(extensionId, absolutePath, workerName, contentSecurityPolicy, application);
2085
- if (application !== undefined) {
2086
- try {
2087
- assertCurrentApplication(application);
2088
- } catch (error) {
2089
- await Promise.allSettled([rpc.dispose(), invoke('LaunchIsolatedExtensionHostWorker.disposeIsolatedExtensionHostWorker', getRuntimeId(extensionId, application))]);
2090
- throw error;
2091
- }
2092
- }
2093
- set$2(extensionId, rpc, application?.applicationId);
2094
- return rpc;
2095
- } catch (error) {
2096
- console.error(`[extension-management-worker] ${extensionId} failed to activate`, error);
2097
- throw error;
2098
- }
2099
- };
2100
- const getOrCreateIsolatedExtensionHostWorker = async (extensionId, absolutePath, workerName = '', contentSecurityPolicy = '', create = createWorker$1, applicationId) => {
2101
- const application = applicationId === undefined ? undefined : get$7(applicationId);
2102
- const existingRpc = get$3(extensionId, applicationId);
2103
- if (existingRpc) {
2104
- return existingRpc;
2105
- }
2106
- const key = JSON.stringify([applicationId ?? null, application?.applicationGeneration ?? null, extensionId]);
2107
- const pendingRpc = pendingRpcs[key];
2108
- if (pendingRpc !== undefined) {
2109
- return pendingRpc;
2110
- }
2111
- const newRpc = createAndStoreRpc(extensionId, absolutePath, workerName, contentSecurityPolicy, create, application);
2112
- pendingRpcs[key] = newRpc;
2113
- try {
2114
- return await newRpc;
2115
- } finally {
2116
- if (pendingRpcs[key] === newRpc) {
2117
- delete pendingRpcs[key];
2118
- }
2119
- }
1989
+ const sourcePathMarker = '/extension-management-worker/src/';
1990
+ const getExtensionHostSubWorkerUrl = (currentUrl = import.meta.url) => {
1991
+ const relativePath = currentUrl.includes(sourcePathMarker) ? '../../../../extension-host-sub-worker/src/extensionHostSubWorkerMain.js' : '../../extension-host-sub-worker/dist/extensionHostSubWorkerMain.js';
1992
+ return new URL(relativePath, currentUrl).href;
2120
1993
  };
1994
+ const extensionHostSubWorkerUrl = getExtensionHostSubWorkerUrl();
2121
1995
 
2122
- const activateIsolatedExtension = async (extensionId, absolutePath, workerName, contentSecurityPolicy, activationEvent, getOrCreate = getOrCreateIsolatedExtensionHostWorker, applicationId) => {
2123
- const application = applicationId === undefined ? undefined : get$7(applicationId);
2124
- const updateStatus = status => {
2125
- if (applicationId === undefined) {
2126
- updateRuntimeStatus(extensionId, status);
2127
- return;
2128
- }
2129
- const current = get$7(applicationId);
2130
- if (current.applicationGeneration !== application?.applicationGeneration) {
2131
- throw new Error(`Stale extension application: ${applicationId}`);
2132
- }
2133
- updateRuntimeStatus(extensionId, status, applicationId);
2134
- };
2135
- const startTime = performance.now();
2136
- updateStatus({
2137
- activationEvent,
2138
- activationStartTime: startTime,
2139
- status: Activating
2140
- });
2141
- try {
2142
- const rpc = applicationId === undefined ? await getOrCreate(extensionId, absolutePath, workerName, contentSecurityPolicy) : await getOrCreate(extensionId, absolutePath, workerName, contentSecurityPolicy, undefined, applicationId);
2143
- const endTime = performance.now();
2144
- updateStatus({
2145
- activationEndTime: endTime,
2146
- activationTime: endTime - startTime,
2147
- status: Activated
2148
- });
2149
- return rpc;
2150
- } catch (error) {
2151
- if (application === undefined || isCurrentApplication(application)) {
2152
- updateStatus({
2153
- error: getErrorMessage(error),
2154
- status: Error$1
2155
- });
2156
- }
2157
- throw error;
2158
- }
2159
- };
1996
+ // TODO
2160
1997
 
2161
1998
  const getOrigin = () => {
2162
1999
  return globalThis.location?.origin || 'http://localhost';
@@ -2287,15 +2124,6 @@ const getContentSecurityPolicy = (directives, absolutePath, rpcInfos) => {
2287
2124
  return `default-src 'none'; script-src ${[...scriptSources].join(' ')}; worker-src 'none'; child-src 'none'; connect-src ${connectDirective};`;
2288
2125
  };
2289
2126
 
2290
- const sourcePathMarker = '/extension-management-worker/src/';
2291
- const getExtensionHostSubWorkerUrl = (currentUrl = import.meta.url) => {
2292
- const relativePath = currentUrl.includes(sourcePathMarker) ? '../../../../extension-host-sub-worker/src/extensionHostSubWorkerMain.js' : '../../extension-host-sub-worker/dist/extensionHostSubWorkerMain.js';
2293
- return new URL(relativePath, currentUrl).href;
2294
- };
2295
- const extensionHostSubWorkerUrl = getExtensionHostSubWorkerUrl();
2296
-
2297
- // TODO
2298
-
2299
2127
  const getUrlPrefix = (platform, extensionPath) => {
2300
2128
  if (extensionPath.startsWith('http://') || extensionPath.startsWith('https://')) {
2301
2129
  return extensionPath;
@@ -2318,10 +2146,11 @@ const getServices = application => {
2318
2146
  let services = applications.get(generation);
2319
2147
  if (!services) {
2320
2148
  services = {
2321
- children: new Set(),
2149
+ children: new Map(),
2322
2150
  declarations: new Map(),
2151
+ extensionVersions: new Map(),
2323
2152
  nextChild: 0,
2324
- ports: new Set()
2153
+ ports: new Map()
2325
2154
  };
2326
2155
  applications.set(generation, services);
2327
2156
  }
@@ -2339,6 +2168,7 @@ const register = (extension, platform) => {
2339
2168
  }
2340
2169
  services.declarations.set(info.id, {
2341
2170
  ...info,
2171
+ extensionId: extension.id,
2342
2172
  url: `${prefix}/${info.url}`
2343
2173
  });
2344
2174
  }
@@ -2348,15 +2178,16 @@ const getRpcInfo$1 = (application, id) => {
2348
2178
  if (!info) throw new Error(`Rpc not found ${id}`);
2349
2179
  return info;
2350
2180
  };
2351
- const createWorker = async (application, info, port, legacy = false) => {
2181
+ const createWorker$1 = async (application, info, port, legacy = false, extensionId) => {
2352
2182
  const services = getServices(application);
2353
2183
  const id = JSON.stringify([application.applicationId, application.applicationGeneration, 'child', ++services.nextChild]);
2354
- services.children.add(id);
2184
+ services.children.set(id, extensionId);
2355
2185
  const url = legacy ? extensionHostSubWorkerUrl : info.url;
2356
2186
  try {
2357
2187
  const policy = getContentSecurityPolicy(info.contentSecurityPolicy || [], url);
2358
2188
  await invokeAndTransfer('LaunchIsolatedExtensionHostWorker.launchIsolatedExtensionHostWorker', port, id, url, info.name || '', policy);
2359
2189
  assertCurrentApplication(application);
2190
+ if (!services.children.has(id)) throw new Error('Extension worker was disposed during launch');
2360
2191
  } catch (error) {
2361
2192
  services.children.delete(id);
2362
2193
  await invoke('LaunchIsolatedExtensionHostWorker.disposeIsolatedExtensionHostWorker', id);
@@ -2364,8 +2195,9 @@ const createWorker = async (application, info, port, legacy = false) => {
2364
2195
  }
2365
2196
  };
2366
2197
  const fileSystemMethods = new Set(['readFile', 'readDirWithFileTypes', 'stat', 'exists', 'writeFile', 'mkdir', 'remove', 'rename', 'copy', 'getBlob']);
2367
- const createFileSystemPort = async (application, port) => {
2198
+ const createFileSystemPort = async (application, port, extensionId) => {
2368
2199
  const services = getServices(application);
2200
+ const version = extensionId === undefined ? 0 : services.extensionVersions.get(extensionId) || 0;
2369
2201
  const rpc = await create$7({
2370
2202
  commandMap: {},
2371
2203
  messagePort: port
@@ -2381,7 +2213,10 @@ const createFileSystemPort = async (application, port) => {
2381
2213
  };
2382
2214
  try {
2383
2215
  assertCurrentApplication(application);
2384
- services.ports.add(rpc);
2216
+ if (extensionId !== undefined && (services.extensionVersions.get(extensionId) || 0) !== version) {
2217
+ throw new Error('Extension was reloaded while opening its filesystem port');
2218
+ }
2219
+ services.ports.set(rpc, extensionId);
2385
2220
  } catch (error) {
2386
2221
  await rpc.dispose();
2387
2222
  throw error;
@@ -2391,13 +2226,215 @@ const dispose = async application => {
2391
2226
  const services = applications.get(application.applicationGeneration);
2392
2227
  if (!services) return;
2393
2228
  applications.delete(application.applicationGeneration);
2394
- const results = await Promise.allSettled([...Array.from(services.ports, rpc => Promise.try(() => rpc.dispose())), ...Array.from(services.children, id => invoke('LaunchIsolatedExtensionHostWorker.disposeIsolatedExtensionHostWorker', id))]);
2229
+ const results = await Promise.allSettled([...Array.from(services.ports.keys(), rpc => Promise.try(() => rpc.dispose())), ...Array.from(services.children.keys(), id => invoke('LaunchIsolatedExtensionHostWorker.disposeIsolatedExtensionHostWorker', id))]);
2395
2230
  services.ports.clear();
2396
2231
  services.children.clear();
2397
2232
  services.declarations.clear();
2398
2233
  const errors = results.filter(result => result.status === 'rejected').map(result => result.reason);
2399
2234
  if (errors.length > 0) throw new AggregateError(errors, 'Failed to dispose application services');
2400
2235
  };
2236
+ const disposeExtension = async (application, extensionId) => {
2237
+ const services = applications.get(application.applicationGeneration);
2238
+ if (!services) return;
2239
+ services.extensionVersions.set(extensionId, (services.extensionVersions.get(extensionId) || 0) + 1);
2240
+ const ports = [...services.ports].filter(([, owner]) => owner === extensionId).map(([rpc]) => rpc);
2241
+ const children = [...services.children].filter(([, owner]) => owner === extensionId).map(([id]) => id);
2242
+ for (const rpc of ports) services.ports.delete(rpc);
2243
+ for (const id of children) services.children.delete(id);
2244
+ for (const [id, info] of services.declarations) {
2245
+ if (info.extensionId === extensionId) services.declarations.delete(id);
2246
+ }
2247
+ const results = await Promise.allSettled([...ports.map(rpc => Promise.try(() => rpc.dispose())), ...children.map(id => invoke('LaunchIsolatedExtensionHostWorker.disposeIsolatedExtensionHostWorker', id))]);
2248
+ const errors = results.filter(result => result.status === 'rejected').map(result => result.reason);
2249
+ if (errors.length > 0) throw new AggregateError(errors, `Failed to dispose extension services: ${extensionId}`);
2250
+ };
2251
+
2252
+ const rpcs$1 = Object.create(null);
2253
+ const applicationRpcs = new Map();
2254
+ const get$3 = (extensionId, applicationId) => {
2255
+ if (applicationId !== undefined) {
2256
+ return applicationRpcs.get(applicationId)?.get(extensionId);
2257
+ }
2258
+ return rpcs$1[extensionId];
2259
+ };
2260
+ const getAll = applicationId => {
2261
+ if (applicationId !== undefined) {
2262
+ return [...(applicationRpcs.get(applicationId)?.values() || [])];
2263
+ }
2264
+ return Object.values(rpcs$1);
2265
+ };
2266
+ const getIds = applicationId => {
2267
+ if (applicationId !== undefined) {
2268
+ return [...(applicationRpcs.get(applicationId)?.keys() || [])];
2269
+ }
2270
+ return Object.keys(rpcs$1);
2271
+ };
2272
+ const set$2 = (extensionId, rpc, applicationId) => {
2273
+ if (applicationId !== undefined) {
2274
+ const entries = applicationRpcs.get(applicationId) || new Map();
2275
+ entries.set(extensionId, rpc);
2276
+ applicationRpcs.set(applicationId, entries);
2277
+ return;
2278
+ }
2279
+ rpcs$1[extensionId] = rpc;
2280
+ };
2281
+ const remove$1 = (extensionId, applicationId) => {
2282
+ if (applicationId !== undefined) {
2283
+ const entries = applicationRpcs.get(applicationId);
2284
+ const rpc = entries?.get(extensionId);
2285
+ entries?.delete(extensionId);
2286
+ if (entries?.size === 0) {
2287
+ applicationRpcs.delete(applicationId);
2288
+ }
2289
+ return rpc;
2290
+ }
2291
+ const rpc = rpcs$1[extensionId];
2292
+ delete rpcs$1[extensionId];
2293
+ return rpc;
2294
+ };
2295
+ const clear = applicationId => {
2296
+ if (applicationId !== undefined) {
2297
+ applicationRpcs.delete(applicationId);
2298
+ return;
2299
+ }
2300
+ for (const key of Object.keys(rpcs$1)) {
2301
+ delete rpcs$1[key];
2302
+ }
2303
+ };
2304
+
2305
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
2306
+
2307
+ const pendingRpcs = Object.create(null);
2308
+ const getPendingExtensionIds = application => {
2309
+ return Object.keys(pendingRpcs).flatMap(key => {
2310
+ const [applicationId, generation, extensionId] = JSON.parse(key);
2311
+ return applicationId === application.applicationId && generation === application.applicationGeneration ? [extensionId] : [];
2312
+ });
2313
+ };
2314
+ const getRuntimeId = (extensionId, application) => {
2315
+ return application?.applicationId === undefined ? extensionId : JSON.stringify([application.applicationId, application.applicationGeneration, extensionId]);
2316
+ };
2317
+ const bindCommandMap = (rpc, commandMap) => {
2318
+ if (rpc.ipc) {
2319
+ rpc.ipc.execute = createExtensionCommandExecutor(commandMap);
2320
+ }
2321
+ return rpc;
2322
+ };
2323
+ const createIsolatedExtensionHostWorker = async (extensionId, absolutePath, workerName, contentSecurityPolicy, createRpc, invokeAndTransfer, application) => {
2324
+ const runtimeId = getRuntimeId(extensionId, application);
2325
+ const invokeCommand = application === undefined ? undefined : (method, ...args) => {
2326
+ assertCurrentApplication(application);
2327
+ if (method === 'Extensions.registerFileChangeHandler') {
2328
+ return register$1(extensionId, application.applicationId);
2329
+ }
2330
+ if (method === 'Extensions.unregisterFileChangeHandler') {
2331
+ return unregister(extensionId, application.applicationId);
2332
+ }
2333
+ if (method === 'Extensions.sendMessagePortToFileSystemWorker') {
2334
+ return createFileSystemPort(application, args[0], extensionId);
2335
+ }
2336
+ if (method === 'Extensions.createWebViewWorkerRpc' || method === 'Extensions.createWebViewWorkerRpc2') {
2337
+ return createWorker$1(application, args[0], args[1], method === 'Extensions.createWebViewWorkerRpc', extensionId);
2338
+ }
2339
+ const invokeApplication = commandMapRef['Extensions.invokeForApplication'];
2340
+ if (!invokeApplication) {
2341
+ throw new Error('Application extension command routing is not initialized');
2342
+ }
2343
+ return invokeApplication(application.applicationId, method, ...args);
2344
+ };
2345
+ const commandMap = createExtensionCommandMap(runtimeId, invokeCommand);
2346
+ const rpc = await createRpc({
2347
+ // PlainMessagePortRpc registers this map process-wide. Bind the restricted
2348
+ // callbacks to this port below, never to the shared host command table.
2349
+ commandMap: {},
2350
+ isMessagePortOpen: true,
2351
+ send(port) {
2352
+ return invokeAndTransfer('LaunchIsolatedExtensionHostWorker.launchIsolatedExtensionHostWorker', port, runtimeId, absolutePath, workerName, contentSecurityPolicy);
2353
+ }
2354
+ });
2355
+ return bindCommandMap(rpc, commandMap);
2356
+ };
2357
+ const createWorker = (extensionId, absolutePath, workerName, contentSecurityPolicy, application) => {
2358
+ return createIsolatedExtensionHostWorker(extensionId, absolutePath, workerName, contentSecurityPolicy, create$6, invokeAndTransfer, application);
2359
+ };
2360
+ const createAndStoreRpc = async (extensionId, absolutePath, workerName, contentSecurityPolicy, create, application) => {
2361
+ try {
2362
+ const rpc = application === undefined ? await create(extensionId, absolutePath, workerName, contentSecurityPolicy) : await create(extensionId, absolutePath, workerName, contentSecurityPolicy, application);
2363
+ if (application !== undefined) {
2364
+ try {
2365
+ assertCurrentApplication(application);
2366
+ } catch (error) {
2367
+ await Promise.allSettled([rpc.dispose(), invoke('LaunchIsolatedExtensionHostWorker.disposeIsolatedExtensionHostWorker', getRuntimeId(extensionId, application))]);
2368
+ throw error;
2369
+ }
2370
+ }
2371
+ set$2(extensionId, rpc, application?.applicationId);
2372
+ return rpc;
2373
+ } catch (error) {
2374
+ console.error(`[extension-management-worker] ${extensionId} failed to activate`, error);
2375
+ throw error;
2376
+ }
2377
+ };
2378
+ const getOrCreateIsolatedExtensionHostWorker = async (extensionId, absolutePath, workerName = '', contentSecurityPolicy = '', create = createWorker, applicationId) => {
2379
+ const application = applicationId === undefined ? undefined : get$7(applicationId);
2380
+ const existingRpc = get$3(extensionId, applicationId);
2381
+ if (existingRpc) {
2382
+ return existingRpc;
2383
+ }
2384
+ const key = JSON.stringify([applicationId ?? null, application?.applicationGeneration ?? null, extensionId]);
2385
+ const pendingRpc = pendingRpcs[key];
2386
+ if (pendingRpc !== undefined) {
2387
+ return pendingRpc;
2388
+ }
2389
+ const newRpc = createAndStoreRpc(extensionId, absolutePath, workerName, contentSecurityPolicy, create, application);
2390
+ pendingRpcs[key] = newRpc;
2391
+ try {
2392
+ return await newRpc;
2393
+ } finally {
2394
+ if (pendingRpcs[key] === newRpc) {
2395
+ delete pendingRpcs[key];
2396
+ }
2397
+ }
2398
+ };
2399
+
2400
+ const activateIsolatedExtension = async (extensionId, absolutePath, workerName, contentSecurityPolicy, activationEvent, getOrCreate = getOrCreateIsolatedExtensionHostWorker, applicationId) => {
2401
+ const application = applicationId === undefined ? undefined : get$7(applicationId);
2402
+ const updateStatus = status => {
2403
+ if (applicationId === undefined) {
2404
+ updateRuntimeStatus(extensionId, status);
2405
+ return;
2406
+ }
2407
+ const current = get$7(applicationId);
2408
+ if (current.applicationGeneration !== application?.applicationGeneration) {
2409
+ throw new Error(`Stale extension application: ${applicationId}`);
2410
+ }
2411
+ updateRuntimeStatus(extensionId, status, applicationId);
2412
+ };
2413
+ const startTime = performance.now();
2414
+ updateStatus({
2415
+ activationEvent,
2416
+ activationStartTime: startTime,
2417
+ status: Activating
2418
+ });
2419
+ try {
2420
+ const rpc = applicationId === undefined ? await getOrCreate(extensionId, absolutePath, workerName, contentSecurityPolicy) : await getOrCreate(extensionId, absolutePath, workerName, contentSecurityPolicy, undefined, applicationId);
2421
+ const endTime = performance.now();
2422
+ updateStatus({
2423
+ activationEndTime: endTime,
2424
+ activationTime: endTime - startTime,
2425
+ status: Activated
2426
+ });
2427
+ return rpc;
2428
+ } catch (error) {
2429
+ if (application === undefined || isCurrentApplication(application)) {
2430
+ updateStatus({
2431
+ error: getErrorMessage(error),
2432
+ status: Error$1
2433
+ });
2434
+ }
2435
+ throw error;
2436
+ }
2437
+ };
2401
2438
 
2402
2439
  const rpcs = Object.create(null);
2403
2440
  const add = (id, rpc) => {
@@ -5806,6 +5843,69 @@ const getLanguages = async (platform, assetDir) => {
5806
5843
  }
5807
5844
  };
5808
5845
 
5846
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
5847
+
5848
+ const queues = new Map();
5849
+ const replace = async (application, extensionId, extension) => {
5850
+ assertCurrentApplication(application);
5851
+ if (!extension || typeof extension.id !== 'string' || !extension.id || typeof extension.browser !== 'string' || extension.isolated !== true) {
5852
+ throw new Error('Expected an isolated web extension');
5853
+ }
5854
+ const applicationId = application.applicationId;
5855
+ const current = get$7(applicationId);
5856
+ if (current.webExtensions.every(({
5857
+ id
5858
+ }) => id !== extensionId)) {
5859
+ throw new Error(`Application extension not found: ${extensionId}`);
5860
+ }
5861
+ if (extension.id !== extensionId && current.webExtensions.some(({
5862
+ id
5863
+ }) => id === extension.id)) {
5864
+ throw new Error(`Duplicate application extension: ${extension.id}`);
5865
+ }
5866
+ // Finish pending startup before removing its RPC, including failed activations.
5867
+ try {
5868
+ await waitForExtensionActivations(current);
5869
+ } catch {
5870
+ // Failed startup must still allow replacing the broken extension.
5871
+ }
5872
+ assertCurrentApplication(application);
5873
+ const rpc = remove$1(extensionId, applicationId);
5874
+ unregister(extensionId, applicationId);
5875
+ const results = await Promise.allSettled([disposeExtension(application, extensionId), Promise.try(() => rpc?.dispose()), invoke('LaunchIsolatedExtensionHostWorker.disposeIsolatedExtensionHostWorker', getRuntimeId(extensionId, application))]);
5876
+ assertCurrentApplication(application);
5877
+ resetExtensionActivation(extensionId, application);
5878
+ resetExtensionRuntimeState(extensionId, applicationId);
5879
+ const errors = results.filter(result => result.status === 'rejected').map(result => result.reason);
5880
+ if (errors.length > 0) throw new AggregateError(errors, `Failed to reload extension ${extensionId}`);
5881
+ update({
5882
+ cachedExtensions: undefined,
5883
+ webExtensions: get$7(applicationId).webExtensions.map(previous => previous.id === extensionId ? {
5884
+ ...extension
5885
+ } : previous)
5886
+ }, applicationId);
5887
+ };
5888
+ const run = async (previous, application, extensionId, extension) => {
5889
+ try {
5890
+ await previous;
5891
+ } catch {
5892
+ // A later save can recover from an earlier reload failure.
5893
+ }
5894
+ await replace(application, extensionId, extension);
5895
+ };
5896
+ const reloadApplicationExtension = async (applicationId, extensionId, extension) => {
5897
+ const application = get$7(applicationId);
5898
+ const key = application.applicationGeneration;
5899
+ const previous = queues.get(key) || Promise.resolve();
5900
+ const operation = run(previous, application, extensionId, extension);
5901
+ queues.set(key, operation);
5902
+ try {
5903
+ await operation;
5904
+ } finally {
5905
+ if (queues.get(key) === operation) queues.delete(key);
5906
+ }
5907
+ };
5908
+
5809
5909
  const sendMessagePortToElectron = async (port, initialCommand) => {
5810
5910
  await invokeAndTransfer$1('SendMessagePortToElectron.sendMessagePortToElectron', port, initialCommand, EmbedsWorker);
5811
5911
  };
@@ -5875,9 +5975,9 @@ const invokeForApplication = async (applicationId, method, ...args) => {
5875
5975
  case 'Extensions.activateByEvent':
5876
5976
  return activateByEvent(args[0], args[1], args[2] ?? application.platform, application);
5877
5977
  case 'Extensions.createWebViewWorkerRpc':
5878
- return createWorker(application, args[0], args[1], true);
5978
+ return createWorker$1(application, args[0], args[1], true);
5879
5979
  case 'Extensions.createWebViewWorkerRpc2':
5880
- return createWorker(application, args[0], args[1]);
5980
+ return createWorker$1(application, args[0], args[1]);
5881
5981
  case 'Extensions.getAllExtensions':
5882
5982
  return getAllExtensionsWithState(application, args[0] || '', args[1] ?? application.platform);
5883
5983
  case 'Extensions.getDynamicWebExtensions':
@@ -5995,6 +6095,7 @@ const commandMap = {
5995
6095
  'Extensions.invalidateExtensionsCache': invalidateExtensionsCache,
5996
6096
  'Extensions.invokeForApplication': invokeForApplication,
5997
6097
  'Extensions.readOutputChannel': wrapCommand(readOutputChannel),
6098
+ 'Extensions.reloadApplicationExtension': reloadApplicationExtension,
5998
6099
  'Extensions.renderViewInstance': renderViewInstance,
5999
6100
  'Extensions.requestViewRerender': requestViewRerender,
6000
6101
  'Extensions.saveViewInstanceState': saveViewInstanceState,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-management-worker",
3
- "version": "4.73.0",
3
+ "version": "4.74.0",
4
4
  "description": "Webworker for the Extension Management functionality in Lvce Editor.",
5
5
  "keywords": [
6
6
  "web-worker"