@lvce-editor/preview-worker 2.2.0 → 2.3.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.
@@ -514,7 +514,7 @@ const IpcParentWithMessagePort$1 = {
514
514
 
515
515
  const Two$1 = '2.0';
516
516
  const callbacks$1 = Object.create(null);
517
- const get$3 = id => {
517
+ const get$4 = id => {
518
518
  return callbacks$1[id];
519
519
  };
520
520
  const remove$1 = id => {
@@ -663,7 +663,7 @@ const warn = (...args) => {
663
663
  console.warn(...args);
664
664
  };
665
665
  const resolve = (id, response) => {
666
- const fn = get$3(id);
666
+ const fn = get$4(id);
667
667
  if (!fn) {
668
668
  console.log(response);
669
669
  warn(`callback ${id} may already be disposed`);
@@ -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,10 +1139,10 @@ 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
- const get$2 = id => {
1145
+ const get$3 = id => {
1145
1146
  return rpcs[id];
1146
1147
  };
1147
1148
  const remove = id => {
@@ -1152,18 +1153,18 @@ const remove = id => {
1152
1153
  const create$2 = rpcId => {
1153
1154
  return {
1154
1155
  async dispose() {
1155
- const rpc = get$2(rpcId);
1156
+ const rpc = get$3(rpcId);
1156
1157
  await rpc.dispose();
1157
1158
  },
1158
1159
  // @ts-ignore
1159
1160
  invoke(method, ...params) {
1160
- const rpc = get$2(rpcId);
1161
+ const rpc = get$3(rpcId);
1161
1162
  // @ts-ignore
1162
1163
  return rpc.invoke(method, ...params);
1163
1164
  },
1164
1165
  // @ts-ignore
1165
1166
  invokeAndTransfer(method, ...params) {
1166
- const rpc = get$2(rpcId);
1167
+ const rpc = get$3(rpcId);
1167
1168
  // @ts-ignore
1168
1169
  return rpc.invokeAndTransfer(method, ...params);
1169
1170
  },
@@ -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';
@@ -1293,11 +1294,11 @@ const terminate = () => {
1293
1294
  };
1294
1295
 
1295
1296
  const {
1296
- get: get$1,
1297
+ get: get$2,
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) => {
@@ -1359,7 +1360,7 @@ const diff2 = uid => {
1359
1360
  const {
1360
1361
  newState,
1361
1362
  oldState
1362
- } = get$1(uid);
1363
+ } = get$2(uid);
1363
1364
  const result = diff(oldState, newState);
1364
1365
  return result;
1365
1366
  };
@@ -1418,12 +1419,12 @@ const getParsedNodesChildNodeCount = parsedDom => {
1418
1419
 
1419
1420
  /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
1420
1421
 
1421
- const states = new Map();
1422
- const get = uid => {
1423
- return states.get(uid);
1422
+ const states$1 = new Map();
1423
+ const get$1 = uid => {
1424
+ return states$1.get(uid);
1424
1425
  };
1425
- const set = (uid, instance) => {
1426
- states.set(uid, instance);
1426
+ const set$1 = (uid, instance) => {
1427
+ states$1.set(uid, instance);
1427
1428
  };
1428
1429
 
1429
1430
  const text = data => {
@@ -1772,6 +1773,7 @@ const Dt = 'dt';
1772
1773
  const Iframe = 'iframe';
1773
1774
  const Del = 'del';
1774
1775
  const H6 = 'h6';
1776
+ const Canvas = 'canvas';
1775
1777
 
1776
1778
  const getVirtualDomTag = text => {
1777
1779
  switch (text) {
@@ -1787,6 +1789,8 @@ const getVirtualDomTag = text => {
1787
1789
  return Br$1;
1788
1790
  case Button:
1789
1791
  return Button$1;
1792
+ case Canvas:
1793
+ return Canvas$1;
1790
1794
  case Cite:
1791
1795
  return Cite$1;
1792
1796
  case Code:
@@ -2068,7 +2072,7 @@ const handleClick = (state, hdId) => {
2068
2072
  if (!hdId) {
2069
2073
  return state;
2070
2074
  }
2071
- const happyDomInstance = get(state.uid);
2075
+ const happyDomInstance = get$1(state.uid);
2072
2076
  if (!happyDomInstance) {
2073
2077
  return state;
2074
2078
  }
@@ -2086,7 +2090,7 @@ const handleClick = (state, hdId) => {
2086
2090
  const serialized = serialize(happyDomInstance.document, elementMap);
2087
2091
 
2088
2092
  // Update happy-dom state with new element map
2089
- set(state.uid, {
2093
+ set$1(state.uid, {
2090
2094
  document: happyDomInstance.document,
2091
2095
  elementMap,
2092
2096
  window: happyDomInstance.window
@@ -2670,7 +2674,7 @@ const handleEditorChanged = async () => {
2670
2674
  for (const previewUid of previewKeys) {
2671
2675
  const {
2672
2676
  newState: state
2673
- } = get$1(previewUid);
2677
+ } = get$2(previewUid);
2674
2678
 
2675
2679
  // Skip if no URI is set
2676
2680
  if (!state.uri) {
@@ -2701,7 +2705,7 @@ const handleEditorChanged = async () => {
2701
2705
  parsedDom: parseResult.dom,
2702
2706
  scripts: parseResult.scripts
2703
2707
  };
2704
- set$1(previewUid, state, updatedState);
2708
+ set$2(previewUid, state, updatedState);
2705
2709
  } catch (error) {
2706
2710
  // If getting text fails, update with error message
2707
2711
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
@@ -2713,7 +2717,7 @@ const handleEditorChanged = async () => {
2713
2717
  parsedDom: [],
2714
2718
  scripts: []
2715
2719
  };
2716
- set$1(previewUid, state, updatedState);
2720
+ set$2(previewUid, state, updatedState);
2717
2721
  }
2718
2722
  }
2719
2723
  }
@@ -90342,6 +90346,98 @@ const executeScripts = (window, document, scripts) => {
90342
90346
  }
90343
90347
  };
90344
90348
 
90349
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
90350
+
90351
+ const states = new Map();
90352
+ const get = uid => {
90353
+ return states.get(uid);
90354
+ };
90355
+ const set = (uid, entry) => {
90356
+ states.set(uid, entry);
90357
+ };
90358
+ const addAnimationFrameHandle = (uid, handle) => {
90359
+ const entry = states.get(uid);
90360
+ if (entry) {
90361
+ entry.animationFrameHandles.push(handle);
90362
+ }
90363
+ };
90364
+
90365
+ const flushCanvasFrame = uid => {
90366
+ const canvasStateEntry = get(uid);
90367
+ if (!canvasStateEntry) {
90368
+ return;
90369
+ }
90370
+ for (const instance of canvasStateEntry.instances) {
90371
+ try {
90372
+ const bitmap = instance.offscreenCanvas.transferToImageBitmap();
90373
+ // @ts-ignore
90374
+ void invoke('Preview.drawCanvas', uid, instance.dataId, bitmap);
90375
+ } catch {
90376
+ // transferToImageBitmap can fail if canvas is zero-sized
90377
+ }
90378
+ }
90379
+ };
90380
+
90381
+ const FRAME_INTERVAL = 16;
90382
+ const overrideRequestAnimationFrame = (window, uid) => {
90383
+ let nextId = 1;
90384
+ const callbacks = new Map();
90385
+ const tick = () => {
90386
+ const currentCallbacks = [...callbacks.entries()];
90387
+ callbacks.clear();
90388
+ const timestamp = performance.now();
90389
+ for (const [, callback] of currentCallbacks) {
90390
+ try {
90391
+ callback(timestamp);
90392
+ } catch (error) {
90393
+ console.warn('[preview-worker] requestAnimationFrame callback error:', error);
90394
+ }
90395
+ }
90396
+ flushCanvasFrame(uid);
90397
+ };
90398
+ window.requestAnimationFrame = callback => {
90399
+ const id = nextId++;
90400
+ callbacks.set(id, callback);
90401
+ const handle = setTimeout(tick, FRAME_INTERVAL);
90402
+ addAnimationFrameHandle(uid, handle);
90403
+ return id;
90404
+ };
90405
+ window.cancelAnimationFrame = id => {
90406
+ callbacks.delete(id);
90407
+ };
90408
+ };
90409
+
90410
+ const patchCanvasElements = (document, uid) => {
90411
+ const canvasElements = document.querySelectorAll('canvas');
90412
+ if (canvasElements.length === 0) {
90413
+ return;
90414
+ }
90415
+ const instances = [];
90416
+ for (let i = 0; i < canvasElements.length; i++) {
90417
+ const element = canvasElements[i];
90418
+ const width = Number.parseInt(element.getAttribute('width') || '300', 10);
90419
+ const height = Number.parseInt(element.getAttribute('height') || '150', 10);
90420
+ const offscreenCanvas = new OffscreenCanvas(width, height);
90421
+ const dataId = String(i);
90422
+ const context = offscreenCanvas.getContext('2d');
90423
+ element.getContext = contextType => {
90424
+ if (contextType === '2d') {
90425
+ return context;
90426
+ }
90427
+ return undefined;
90428
+ };
90429
+ instances.push({
90430
+ dataId,
90431
+ element,
90432
+ offscreenCanvas
90433
+ });
90434
+ }
90435
+ set(uid, {
90436
+ animationFrameHandles: [],
90437
+ instances
90438
+ });
90439
+ };
90440
+
90345
90441
  /* eslint-disable prefer-destructuring */
90346
90442
 
90347
90443
  const updateContent = async (state, uri) => {
@@ -90367,12 +90463,14 @@ const updateContent = async (state, uri) => {
90367
90463
  document: happyDomDocument,
90368
90464
  window: happyDomWindow
90369
90465
  } = createWindow(content);
90466
+ patchCanvasElements(happyDomDocument, state.uid);
90467
+ overrideRequestAnimationFrame(happyDomWindow, state.uid);
90370
90468
  executeScripts(happyDomWindow, happyDomDocument, scripts);
90371
90469
  const elementMap = new Map();
90372
90470
  const serialized = serialize(happyDomDocument, elementMap);
90373
90471
  parsedDom = serialized.dom;
90374
90472
  css = serialized.css;
90375
- set(state.uid, {
90473
+ set$1(state.uid, {
90376
90474
  document: happyDomDocument,
90377
90475
  elementMap,
90378
90476
  window: happyDomWindow
@@ -90436,7 +90534,7 @@ const handleInput = (state, hdId, value) => {
90436
90534
  if (!hdId) {
90437
90535
  return state;
90438
90536
  }
90439
- const happyDomInstance = get(state.uid);
90537
+ const happyDomInstance = get$1(state.uid);
90440
90538
  if (!happyDomInstance) {
90441
90539
  return state;
90442
90540
  }
@@ -90456,7 +90554,7 @@ const handleInput = (state, hdId, value) => {
90456
90554
  const serialized = serialize(happyDomInstance.document, elementMap);
90457
90555
 
90458
90556
  // Update happy-dom state with new element map
90459
- set(state.uid, {
90557
+ set$1(state.uid, {
90460
90558
  document: happyDomInstance.document,
90461
90559
  elementMap,
90462
90560
  window: happyDomInstance.window
@@ -90661,8 +90759,8 @@ const render2 = (uid, diffResult) => {
90661
90759
  const {
90662
90760
  newState,
90663
90761
  oldState
90664
- } = get$1(uid);
90665
- set$1(uid, newState, newState);
90762
+ } = get$2(uid);
90763
+ set$2(uid, newState, newState);
90666
90764
  const commands = applyRender(oldState, newState, diffResult);
90667
90765
  return commands;
90668
90766
  };
@@ -90748,12 +90846,12 @@ const listen = async () => {
90748
90846
  const rpc = await WebWorkerRpcClient.create({
90749
90847
  commandMap: commandMap
90750
90848
  });
90751
- set$2(rpc);
90849
+ set$3(rpc);
90752
90850
  const editorRpc = await LazyTransferMessagePortRpcParent.create({
90753
90851
  commandMap: {},
90754
90852
  send: port => sendMessagePortToEditorWorker(port, 9112)
90755
90853
  });
90756
- set$3(editorRpc);
90854
+ set$4(editorRpc);
90757
90855
  };
90758
90856
 
90759
90857
  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.3.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
  }