@lvce-editor/preview-worker 2.2.0 → 2.4.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.
@@ -865,9 +865,9 @@ const create$s = (id, method, params) => {
865
865
  };
866
866
  return message;
867
867
  };
868
- let id = 0;
868
+ let id$1 = 0;
869
869
  const create$r = () => {
870
- return ++id;
870
+ return ++id$1;
871
871
  };
872
872
 
873
873
  /* eslint-disable n/no-unsupported-features/es-syntax */
@@ -1129,6 +1129,7 @@ const Dt$1 = 67;
1129
1129
  const Iframe$1 = 68;
1130
1130
  const Style = 72;
1131
1131
  const Html = 73;
1132
+ const Canvas$1 = 77;
1132
1133
  const Reference = 100;
1133
1134
 
1134
1135
  const EditorWorker = 99;
@@ -1138,7 +1139,7 @@ const SetDom2 = 'Viewlet.setDom2';
1138
1139
  const SetPatches = 'Viewlet.setPatches';
1139
1140
 
1140
1141
  const rpcs = Object.create(null);
1141
- const set$4 = (id, rpc) => {
1142
+ const set$5 = (id, rpc) => {
1142
1143
  rpcs[id] = rpc;
1143
1144
  };
1144
1145
  const get$2 = id => {
@@ -1171,7 +1172,7 @@ const create$2 = rpcId => {
1171
1172
  const mockRpc = createMockRpc({
1172
1173
  commandMap
1173
1174
  });
1174
- set$4(rpcId, mockRpc);
1175
+ set$5(rpcId, mockRpc);
1175
1176
  // @ts-ignore
1176
1177
  mockRpc[Symbol.dispose] = () => {
1177
1178
  remove(rpcId);
@@ -1180,20 +1181,20 @@ const create$2 = rpcId => {
1180
1181
  return mockRpc;
1181
1182
  },
1182
1183
  set(rpc) {
1183
- set$4(rpcId, rpc);
1184
+ set$5(rpcId, rpc);
1184
1185
  }
1185
1186
  };
1186
1187
  };
1187
1188
 
1188
1189
  const {
1189
1190
  invoke: invoke$1,
1190
- set: set$3
1191
+ set: set$4
1191
1192
  } = create$2(EditorWorker);
1192
1193
 
1193
1194
  const {
1194
1195
  invoke,
1195
1196
  invokeAndTransfer,
1196
- set: set$2
1197
+ set: set$3
1197
1198
  } = create$2(RendererWorker);
1198
1199
  const sendMessagePortToEditorWorker = async (port, rpcId) => {
1199
1200
  const command = 'HandleMessagePort.handleMessagePort';
@@ -1297,7 +1298,7 @@ const {
1297
1298
  getCommandIds,
1298
1299
  getKeys: getKeys$1,
1299
1300
  registerCommands,
1300
- set: set$1,
1301
+ set: set$2,
1301
1302
  wrapCommand,
1302
1303
  wrapGetter
1303
1304
  } = create$1();
@@ -1318,7 +1319,7 @@ const create = (uid, uri, x, y, width, height, platform, assetDir) => {
1318
1319
  uri,
1319
1320
  warningCount: 0
1320
1321
  };
1321
- set$1(uid, state, state);
1322
+ set$2(uid, state, state);
1322
1323
  };
1323
1324
 
1324
1325
  const iEqual = (oldState, newState) => {
@@ -1364,6 +1365,43 @@ const diff2 = uid => {
1364
1365
  return result;
1365
1366
  };
1366
1367
 
1368
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
1369
+ const callBacks = Object.create(null);
1370
+ let id = 0;
1371
+ const registerCallback = () => {
1372
+ const nextId = id++;
1373
+ const {
1374
+ promise,
1375
+ resolve
1376
+ } = Promise.withResolvers();
1377
+ callBacks[nextId] = resolve;
1378
+ return {
1379
+ id: nextId,
1380
+ promise
1381
+ };
1382
+ };
1383
+ const executeCallback = (id, ...args) => {
1384
+ const callback = callBacks[id];
1385
+ if (callback) {
1386
+ callback(args);
1387
+ delete callBacks[id];
1388
+ } else {
1389
+ console.warn(`[preview-worker] No callback found for id ${id}`);
1390
+ }
1391
+ };
1392
+ const getOffscreenCanvas = async (width, height) => {
1393
+ const {
1394
+ id,
1395
+ promise
1396
+ } = registerCallback();
1397
+ await invoke('OffscreenCanvas.createForPreview', id, width, height);
1398
+ const [offscreenCanvas, canvasId] = await promise;
1399
+ return {
1400
+ canvasId,
1401
+ offscreenCanvas
1402
+ };
1403
+ };
1404
+
1367
1405
  const dispatchEvent = (element, event) => {
1368
1406
  element.dispatchEvent(event);
1369
1407
 
@@ -1418,12 +1456,12 @@ const getParsedNodesChildNodeCount = parsedDom => {
1418
1456
 
1419
1457
  /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
1420
1458
 
1421
- const states = new Map();
1459
+ const states$1 = new Map();
1422
1460
  const get = uid => {
1423
- return states.get(uid);
1461
+ return states$1.get(uid);
1424
1462
  };
1425
- const set = (uid, instance) => {
1426
- states.set(uid, instance);
1463
+ const set$1 = (uid, instance) => {
1464
+ states$1.set(uid, instance);
1427
1465
  };
1428
1466
 
1429
1467
  const text = data => {
@@ -1772,6 +1810,7 @@ const Dt = 'dt';
1772
1810
  const Iframe = 'iframe';
1773
1811
  const Del = 'del';
1774
1812
  const H6 = 'h6';
1813
+ const Canvas = 'canvas';
1775
1814
 
1776
1815
  const getVirtualDomTag = text => {
1777
1816
  switch (text) {
@@ -1787,6 +1826,8 @@ const getVirtualDomTag = text => {
1787
1826
  return Br$1;
1788
1827
  case Button:
1789
1828
  return Button$1;
1829
+ case Canvas:
1830
+ return Canvas$1;
1790
1831
  case Cite:
1791
1832
  return Cite$1;
1792
1833
  case Code:
@@ -1978,6 +2019,20 @@ const serializeNode = (node, dom, css, context) => {
1978
2019
  return childCount;
1979
2020
  }
1980
2021
 
2022
+ // Canvas element with transferred OffscreenCanvas — emit a Reference node
2023
+ if (tagName === 'canvas' && node.__canvasId !== undefined) {
2024
+ const refNode = {
2025
+ childCount: 0,
2026
+ type: Reference,
2027
+ uid: node.__canvasId
2028
+ };
2029
+ if (context.elementMap) {
2030
+ context.elementMap.set(node.__canvasId + '', node);
2031
+ }
2032
+ dom.push(refNode);
2033
+ return 1;
2034
+ }
2035
+
1981
2036
  // Normal element - create a VirtualDomNode
1982
2037
  const newNode = {
1983
2038
  childCount: 0,
@@ -2086,7 +2141,7 @@ const handleClick = (state, hdId) => {
2086
2141
  const serialized = serialize(happyDomInstance.document, elementMap);
2087
2142
 
2088
2143
  // Update happy-dom state with new element map
2089
- set(state.uid, {
2144
+ set$1(state.uid, {
2090
2145
  document: happyDomInstance.document,
2091
2146
  elementMap,
2092
2147
  window: happyDomInstance.window
@@ -2701,7 +2756,7 @@ const handleEditorChanged = async () => {
2701
2756
  parsedDom: parseResult.dom,
2702
2757
  scripts: parseResult.scripts
2703
2758
  };
2704
- set$1(previewUid, state, updatedState);
2759
+ set$2(previewUid, state, updatedState);
2705
2760
  } catch (error) {
2706
2761
  // If getting text fails, update with error message
2707
2762
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
@@ -2713,7 +2768,7 @@ const handleEditorChanged = async () => {
2713
2768
  parsedDom: [],
2714
2769
  scripts: []
2715
2770
  };
2716
- set$1(previewUid, state, updatedState);
2771
+ set$2(previewUid, state, updatedState);
2717
2772
  }
2718
2773
  }
2719
2774
  }
@@ -90342,6 +90397,84 @@ const executeScripts = (window, document, scripts) => {
90342
90397
  }
90343
90398
  };
90344
90399
 
90400
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
90401
+
90402
+ const states = new Map();
90403
+ const set = (uid, entry) => {
90404
+ states.set(uid, entry);
90405
+ };
90406
+ const addAnimationFrameHandle = (uid, handle) => {
90407
+ const entry = states.get(uid);
90408
+ if (entry) {
90409
+ entry.animationFrameHandles.push(handle);
90410
+ }
90411
+ };
90412
+
90413
+ const FRAME_INTERVAL = 16;
90414
+ const overrideRequestAnimationFrame = (window, uid) => {
90415
+ let nextId = 1;
90416
+ const callbacks = new Map();
90417
+ const tick = () => {
90418
+ const currentCallbacks = [...callbacks.entries()];
90419
+ callbacks.clear();
90420
+ const timestamp = performance.now();
90421
+ for (const [, callback] of currentCallbacks) {
90422
+ try {
90423
+ callback(timestamp);
90424
+ } catch (error) {
90425
+ console.warn('[preview-worker] requestAnimationFrame callback error:', error);
90426
+ }
90427
+ }
90428
+ };
90429
+ window.requestAnimationFrame = callback => {
90430
+ const id = nextId++;
90431
+ callbacks.set(id, callback);
90432
+ const handle = setTimeout(tick, FRAME_INTERVAL);
90433
+ addAnimationFrameHandle(uid, handle);
90434
+ return id;
90435
+ };
90436
+ window.cancelAnimationFrame = id => {
90437
+ callbacks.delete(id);
90438
+ };
90439
+ };
90440
+
90441
+ const patchCanvasElements = async (document, uid) => {
90442
+ const canvasElements = document.querySelectorAll('canvas');
90443
+ if (canvasElements.length === 0) {
90444
+ return;
90445
+ }
90446
+ const instances = [];
90447
+ for (let i = 0; i < canvasElements.length; i++) {
90448
+ const element = canvasElements[i];
90449
+ const width = element.getAttribute('width') || 300;
90450
+ const height = element.getAttribute('height') || 300;
90451
+ element.width = width;
90452
+ element.height = height;
90453
+ const {
90454
+ canvasId,
90455
+ offscreenCanvas
90456
+ } = await getOffscreenCanvas(width, height);
90457
+ const dataId = String(canvasId);
90458
+ element.__canvasId = canvasId;
90459
+ const context = offscreenCanvas.getContext('2d');
90460
+ element.getContext = contextType => {
90461
+ if (contextType === '2d') {
90462
+ return context;
90463
+ }
90464
+ return undefined;
90465
+ };
90466
+ instances.push({
90467
+ dataId,
90468
+ element,
90469
+ offscreenCanvas
90470
+ });
90471
+ }
90472
+ set(uid, {
90473
+ animationFrameHandles: [],
90474
+ instances
90475
+ });
90476
+ };
90477
+
90345
90478
  /* eslint-disable prefer-destructuring */
90346
90479
 
90347
90480
  const updateContent = async (state, uri) => {
@@ -90367,12 +90500,14 @@ const updateContent = async (state, uri) => {
90367
90500
  document: happyDomDocument,
90368
90501
  window: happyDomWindow
90369
90502
  } = createWindow(content);
90503
+ await patchCanvasElements(happyDomDocument, state.uid);
90504
+ overrideRequestAnimationFrame(happyDomWindow, state.uid);
90370
90505
  executeScripts(happyDomWindow, happyDomDocument, scripts);
90371
90506
  const elementMap = new Map();
90372
90507
  const serialized = serialize(happyDomDocument, elementMap);
90373
90508
  parsedDom = serialized.dom;
90374
90509
  css = serialized.css;
90375
- set(state.uid, {
90510
+ set$1(state.uid, {
90376
90511
  document: happyDomDocument,
90377
90512
  elementMap,
90378
90513
  window: happyDomWindow
@@ -90456,7 +90591,7 @@ const handleInput = (state, hdId, value) => {
90456
90591
  const serialized = serialize(happyDomInstance.document, elementMap);
90457
90592
 
90458
90593
  // Update happy-dom state with new element map
90459
- set(state.uid, {
90594
+ set$1(state.uid, {
90460
90595
  document: happyDomInstance.document,
90461
90596
  elementMap,
90462
90597
  window: happyDomInstance.window
@@ -90662,7 +90797,7 @@ const render2 = (uid, diffResult) => {
90662
90797
  newState,
90663
90798
  oldState
90664
90799
  } = get$1(uid);
90665
- set$1(uid, newState, newState);
90800
+ set$2(uid, newState, newState);
90666
90801
  const commands = applyRender(oldState, newState, diffResult);
90667
90802
  return commands;
90668
90803
  };
@@ -90729,6 +90864,7 @@ const commandMap = {
90729
90864
  handleEditorChanged: handleEditorChanged,
90730
90865
  'Preview.create': create,
90731
90866
  'Preview.diff2': diff2,
90867
+ 'Preview.executeCallback': executeCallback,
90732
90868
  'Preview.getCommandIds': getCommandIds,
90733
90869
  'Preview.handleClick': wrapCommand(handleClick),
90734
90870
  'Preview.handleFileEdited': wrapCommand(handleFileEdited),
@@ -90748,12 +90884,12 @@ const listen = async () => {
90748
90884
  const rpc = await WebWorkerRpcClient.create({
90749
90885
  commandMap: commandMap
90750
90886
  });
90751
- set$2(rpc);
90887
+ set$3(rpc);
90752
90888
  const editorRpc = await LazyTransferMessagePortRpcParent.create({
90753
90889
  commandMap: {},
90754
90890
  send: port => sendMessagePortToEditorWorker(port, 9112)
90755
90891
  });
90756
- set$3(editorRpc);
90892
+ set$4(editorRpc);
90757
90893
  };
90758
90894
 
90759
90895
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/preview-worker",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "Preview Worker",
5
5
  "repository": {
6
6
  "type": "git",
@@ -11,7 +11,7 @@
11
11
  "type": "module",
12
12
  "main": "dist/previewWorkerMain.js",
13
13
  "dependencies": {
14
- "@lvce-editor/virtual-dom-worker": "^7.2.0",
14
+ "@lvce-editor/virtual-dom-worker": "^7.3.0",
15
15
  "happy-dom-without-node": "^14.12.3"
16
16
  }
17
17
  }