@lvce-editor/preview-sandbox-worker 4.15.2 → 4.16.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.
@@ -645,6 +645,9 @@ const restoreExistingError = (error, currentStack) => {
645
645
  };
646
646
  const restoreMethodNotFoundError = (error, currentStack) => {
647
647
  const restoredError = new JsonRpcError(error.message);
648
+ Object.assign(restoredError, {
649
+ code: error.code
650
+ });
648
651
  const parentStack = getParentStack(error);
649
652
  setStack(restoredError, `${parentStack}${NewLine}${currentStack}`);
650
653
  return restoredError;
@@ -664,9 +667,13 @@ const applyDataProperties = (restoredError, error) => {
664
667
  // @ts-ignore
665
668
  restoredError.codeFrame = error.data.codeFrame;
666
669
  }
667
- if (error.data.code) {
670
+ if (typeof error.data.code === 'string' || typeof error.data.code === 'number') {
668
671
  // @ts-ignore
669
- restoredError.code = error.data.code;
672
+ Object.defineProperty(restoredError, 'code', {
673
+ configurable: true,
674
+ value: error.data.code,
675
+ writable: true
676
+ });
670
677
  }
671
678
  if (error.data.type) {
672
679
  // @ts-ignore
@@ -687,7 +694,14 @@ const applyDirectProperties = (restoredError, error) => {
687
694
  }
688
695
  };
689
696
  const restoreMessageError = (error, _currentStack) => {
690
- const restoredError = constructError(error.message, error.type, error.name);
697
+ const restoredError = constructError(error.message, error.type || error.data?.type, error.name);
698
+ if (typeof error.code === 'string' || typeof error.code === 'number') {
699
+ Object.defineProperty(restoredError, 'code', {
700
+ configurable: true,
701
+ value: error.code,
702
+ writable: true
703
+ });
704
+ }
691
705
  if (error.data) {
692
706
  applyDataProperties(restoredError, error);
693
707
  } else {
@@ -695,6 +709,23 @@ const restoreMessageError = (error, _currentStack) => {
695
709
  }
696
710
  return restoredError;
697
711
  };
712
+ const getFallbackMessage = error => {
713
+ if (error && typeof error.message === 'string' && error.message) {
714
+ return error.message;
715
+ }
716
+ if (error && error.data) {
717
+ return getFallbackMessage(error.data);
718
+ }
719
+ const stringified = String(error);
720
+ if (stringified !== '[object Object]') {
721
+ return stringified;
722
+ }
723
+ try {
724
+ return JSON.stringify(error);
725
+ } catch {
726
+ return stringified;
727
+ }
728
+ };
698
729
  const restoreJsonRpcError = error => {
699
730
  const currentStack = getCurrentStack();
700
731
  if (error && error instanceof Error) {
@@ -703,13 +734,13 @@ const restoreJsonRpcError = error => {
703
734
  if (error && error.code && error.code === MethodNotFound) {
704
735
  return restoreMethodNotFoundError(error, currentStack);
705
736
  }
737
+ if (error && error.error) {
738
+ return restoreJsonRpcError(error.error);
739
+ }
706
740
  if (error && error.message) {
707
741
  return restoreMessageError(error);
708
742
  }
709
- if (typeof error === 'string') {
710
- return new Error(`JsonRpc Error: ${error}`);
711
- }
712
- return new Error(`JsonRpc Error: ${error}`);
743
+ return new Error(`JsonRpc Error: ${getFallbackMessage(error)}`);
713
744
  };
714
745
  const unwrapJsonRpcResult = responseMessage => {
715
746
  if ('error' in responseMessage) {
@@ -766,9 +797,9 @@ const getErrorProperty = (error, prettyError) => {
766
797
  return {
767
798
  code: Custom,
768
799
  data: {
769
- code: prettyError.code,
800
+ code: prettyError.code ?? error?.code,
770
801
  codeFrame: prettyError.codeFrame,
771
- name: prettyError.name,
802
+ name: prettyError.name ?? error?.name,
772
803
  stack: getStack(prettyError),
773
804
  type: getErrorType(prettyError)
774
805
  },
@@ -803,7 +834,12 @@ const getErrorResponseSimple = (id, error) => {
803
834
  return {
804
835
  error: {
805
836
  code: Custom,
806
- data: error,
837
+ data: error instanceof Error ? {
838
+ ...error,
839
+ code: 'code' in error ? error.code : undefined,
840
+ stack: error.stack,
841
+ type: error.name
842
+ } : error,
807
843
  // @ts-ignore
808
844
  message: error.message
809
845
  },
@@ -90108,23 +90144,32 @@ const createWindow = (rawHtml, url = 'http://localhost:3000') => {
90108
90144
  /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
90109
90145
 
90110
90146
  const exposeCanvasGlobals = (window, document) => {
90111
- const existingCanvasRenderingContext2D = window.CanvasRenderingContext2D || globalThis.CanvasRenderingContext2D;
90147
+ const existingCanvasRenderingContext2D = globalThis.OffscreenCanvasRenderingContext2D || Object.getOwnPropertyDescriptor(window, 'CanvasRenderingContext2D')?.value || Object.getOwnPropertyDescriptor(globalThis, 'CanvasRenderingContext2D')?.value;
90112
90148
  if (existingCanvasRenderingContext2D) {
90113
90149
  window.CanvasRenderingContext2D = existingCanvasRenderingContext2D;
90114
90150
  globalThis.CanvasRenderingContext2D = existingCanvasRenderingContext2D;
90115
90151
  return;
90116
90152
  }
90117
- const canvas = document.querySelector('canvas');
90118
- if (!canvas || typeof canvas.getContext !== 'function') {
90119
- return;
90120
- }
90121
- const context = canvas.getContext('2d');
90122
- const CanvasRenderingContext2D = context?.constructor;
90123
- if (typeof CanvasRenderingContext2D !== 'function') {
90124
- return;
90153
+
90154
+ // Select a context only when a script actually uses the 2D constructor.
90155
+ // Eagerly asking for '2d' prevents the same canvas from using WebGL.
90156
+ const getConstructor = () => {
90157
+ const canvas = document.querySelector('canvas');
90158
+ return canvas?.getContext?.('2d')?.constructor;
90159
+ };
90160
+ for (const target of [window, globalThis]) {
90161
+ Object.defineProperty(target, 'CanvasRenderingContext2D', {
90162
+ configurable: true,
90163
+ get: getConstructor,
90164
+ set: value => {
90165
+ Object.defineProperty(target, 'CanvasRenderingContext2D', {
90166
+ configurable: true,
90167
+ value,
90168
+ writable: true
90169
+ });
90170
+ }
90171
+ });
90125
90172
  }
90126
- window.CanvasRenderingContext2D = CanvasRenderingContext2D;
90127
- globalThis.CanvasRenderingContext2D = CanvasRenderingContext2D;
90128
90173
  };
90129
90174
 
90130
90175
  /**
@@ -90757,9 +90802,58 @@ const remove = uid => {
90757
90802
  for (const handle of entry.animationFrameHandles) {
90758
90803
  clearTimeout(handle);
90759
90804
  }
90805
+ for (const instance of entry.instances) {
90806
+ instance.dispose?.();
90807
+ }
90760
90808
  }
90761
90809
  states.delete(uid);
90762
90810
  };
90811
+ const addAnimationFrameHandle = (uid, handle) => {
90812
+ const entry = states.get(uid);
90813
+ if (entry) {
90814
+ entry.animationFrameHandles.push(handle);
90815
+ }
90816
+ };
90817
+ const removeAnimationFrameHandle = (uid, handle) => {
90818
+ const entry = states.get(uid);
90819
+ if (entry) {
90820
+ const index = entry.animationFrameHandles.indexOf(handle);
90821
+ if (index !== -1) {
90822
+ entry.animationFrameHandles.splice(index, 1);
90823
+ }
90824
+ }
90825
+ };
90826
+
90827
+ const FRAME_INTERVAL = 16;
90828
+ const overrideRequestAnimationFrame = (window, uid) => {
90829
+ let nextId = 1;
90830
+ const callbacks = new Map();
90831
+ const tick = () => {
90832
+ const currentCallbacks = [...callbacks];
90833
+ callbacks.clear();
90834
+ const timestamp = performance.now();
90835
+ for (const [, callback] of currentCallbacks) {
90836
+ try {
90837
+ callback(timestamp);
90838
+ } catch (error) {
90839
+ warn(`[preview-sandbox-worker] requestAnimationFrame callback error: ${error}`);
90840
+ }
90841
+ }
90842
+ };
90843
+ window.requestAnimationFrame = callback => {
90844
+ const id = nextId++;
90845
+ callbacks.set(id, callback);
90846
+ const handle = setTimeout(() => {
90847
+ removeAnimationFrameHandle(uid, handle);
90848
+ tick();
90849
+ }, FRAME_INTERVAL);
90850
+ addAnimationFrameHandle(uid, handle);
90851
+ return id;
90852
+ };
90853
+ window.cancelAnimationFrame = id => {
90854
+ callbacks.delete(id);
90855
+ };
90856
+ };
90763
90857
 
90764
90858
  const toNumber = value => {
90765
90859
  if (typeof value === 'number') {
@@ -90804,12 +90898,17 @@ const patchCanvasElement = (element, uid, reservation) => {
90804
90898
  element.__canvasId = canvasId;
90805
90899
  element.__offscreenCanvas = offscreenCanvas;
90806
90900
  element.dataset.id = dataId;
90807
- const context = offscreenCanvas.getContext('2d');
90808
- element.getContext = contextType => {
90809
- if (contextType === '2d') {
90810
- return context;
90901
+ let webglContext = null;
90902
+ element.getContext = (contextType, options) => {
90903
+ const context = offscreenCanvas.getContext(contextType, options);
90904
+ if (context && (contextType === 'webgl' || contextType === 'webgl2')) {
90905
+ webglContext = context;
90811
90906
  }
90812
- return undefined;
90907
+ return context;
90908
+ };
90909
+ const dispose = () => {
90910
+ webglContext?.getExtension('WEBGL_lose_context')?.loseContext();
90911
+ webglContext = null;
90813
90912
  };
90814
90913
  let widthValue = width;
90815
90914
  Object.defineProperty(element, 'width', {
@@ -90871,6 +90970,7 @@ const patchCanvasElement = (element, uid, reservation) => {
90871
90970
  };
90872
90971
  addInstance(uid, {
90873
90972
  dataId,
90973
+ dispose,
90874
90974
  element,
90875
90975
  offscreenCanvas
90876
90976
  });
@@ -91006,6 +91106,7 @@ const updateContent = async (uid, width, height, content, scripts) => {
91006
91106
  } = createWindow(content);
91007
91107
  const dynamicCanvasCount = getCanvasCreationCount(scripts);
91008
91108
  await patchCanvasElements(happyDomDocument, uid, dynamicCanvasCount);
91109
+ overrideRequestAnimationFrame(happyDomWindow, uid);
91009
91110
  const initialElementMap = Object.create(null);
91010
91111
  serialize(happyDomDocument, initialElementMap);
91011
91112
  patchElementGeometry(uid, initialElementMap);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/preview-sandbox-worker",
3
- "version": "4.15.2",
3
+ "version": "4.16.0",
4
4
  "description": "Preview SandBox Worker",
5
5
  "repository": {
6
6
  "type": "git",