@lvce-editor/preview-sandbox-worker 1.4.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.
@@ -1774,7 +1774,7 @@ const dispatchMouseupEvent = (element, window, clientX = 0, clientY = 0) => {
1774
1774
  dispatchEvent(element, mouseupEvent);
1775
1775
  };
1776
1776
 
1777
- const handleMouseupLocal = (uid, hdId) => {
1777
+ const handleMouseupLocal = (uid, hdId, clientX, clientY) => {
1778
1778
  const happyDomInstance = get(uid);
1779
1779
  if (!happyDomInstance) {
1780
1780
  return;
@@ -1783,7 +1783,7 @@ const handleMouseupLocal = (uid, hdId) => {
1783
1783
  if (!element) {
1784
1784
  return;
1785
1785
  }
1786
- dispatchMouseupEvent(element, happyDomInstance.window);
1786
+ dispatchMouseupEvent(element, happyDomInstance.window, clientX, clientY);
1787
1787
  const elementMap = new Map();
1788
1788
  set$1(uid, {
1789
1789
  document: happyDomInstance.document,
@@ -1791,8 +1791,8 @@ const handleMouseupLocal = (uid, hdId) => {
1791
1791
  window: happyDomInstance.window
1792
1792
  });
1793
1793
  };
1794
- const handleMouseup = (uid, hdId) => {
1795
- return handleMouseupLocal(uid, hdId);
1794
+ const handleMouseup = (uid, hdId, clientX, clientY) => {
1795
+ return handleMouseupLocal(uid, hdId, clientX, clientY);
1796
1796
  };
1797
1797
 
1798
1798
  function getDefaultExportFromCjs (x) {
@@ -89376,10 +89376,133 @@ const createWindow = rawHtml => {
89376
89376
  };
89377
89377
  };
89378
89378
 
89379
+ /**
89380
+ * Extracts line and column information from an error stack trace
89381
+ * Looks for patterns like "<anonymous>:114:26" in the stack trace
89382
+ */
89383
+ const extractLineColumnFromStack = stack => {
89384
+ // Match patterns like "<anonymous>:114:26" or eval:114:26
89385
+ const match = stack.match(/<anonymous>:(\d+):(\d+)/);
89386
+ if (match) {
89387
+ return {
89388
+ column: Number.parseInt(match[2], 10),
89389
+ line: Number.parseInt(match[1], 10)
89390
+ };
89391
+ }
89392
+ return null;
89393
+ };
89394
+
89395
+ /**
89396
+ * Generates a code frame showing the error location with context
89397
+ * @param scriptContent The original script content
89398
+ * @param error The error object
89399
+ * @param contextLines Number of lines to show before/after the error (default: 2)
89400
+ * @returns Formatted code frame string or empty string if line info cannot be extracted
89401
+ */
89402
+ const getErrorCodeFrame = (scriptContent, error, contextLines = 2) => {
89403
+ if (!error || !error.stack) {
89404
+ return '';
89405
+ }
89406
+ const lineColumn = extractLineColumnFromStack(error.stack);
89407
+ if (!lineColumn) {
89408
+ return '';
89409
+ }
89410
+ const {
89411
+ column,
89412
+ line
89413
+ } = lineColumn;
89414
+ const lines = scriptContent.split('\n');
89415
+
89416
+ // Line numbers in stack traces are 1-based
89417
+ // Offset by -4 to account for the anonymous function wrapper
89418
+ const errorLineIndex = line - 1 - 2;
89419
+ if (errorLineIndex < 0 || errorLineIndex >= lines.length) {
89420
+ return '';
89421
+ }
89422
+ const startLine = Math.max(0, errorLineIndex - contextLines);
89423
+ const endLine = Math.min(lines.length - 1, errorLineIndex + contextLines);
89424
+
89425
+ // Find the width of line numbers for padding
89426
+ const maxLineNum = endLine + 1;
89427
+ const numberWidth = String(maxLineNum).length;
89428
+ let codeFrame = '\n';
89429
+
89430
+ // Add context lines before
89431
+ for (let i = startLine; i <= endLine; i++) {
89432
+ const lineNum = i + 1;
89433
+ const isErrorLine = i === errorLineIndex;
89434
+ const lineContent = lines[i];
89435
+ const lineNumStr = String(lineNum).padStart(numberWidth, ' ');
89436
+ const prefix = isErrorLine ? '> ' : ' ';
89437
+ codeFrame += `${prefix}${lineNumStr} | ${lineContent}\n`;
89438
+
89439
+ // Add a caret pointing to the error column on the error line
89440
+ if (isErrorLine && column > 0) {
89441
+ const caretPosition = column - 1;
89442
+ codeFrame += ` ${' '.repeat(numberWidth)} | ${' '.repeat(caretPosition)}^\n`;
89443
+ }
89444
+ }
89445
+ return codeFrame;
89446
+ };
89447
+
89379
89448
  const alert = message => {
89380
89449
  void invoke('ConfirmPrompt.prompt', message);
89381
89450
  };
89382
89451
 
89452
+ const createLocalStorage = () => {
89453
+ const store = new Map();
89454
+ const getItem = key => {
89455
+ if (store.has(key)) {
89456
+ return store.get(key);
89457
+ }
89458
+ return null;
89459
+ };
89460
+ const setItem = (key, value) => {
89461
+ store.set(key, String(value));
89462
+ };
89463
+ const removeItem = key => {
89464
+ store.delete(key);
89465
+ };
89466
+ const clear = () => {
89467
+ store.clear();
89468
+ };
89469
+ const key = index => {
89470
+ const keys = [...store.keys()];
89471
+ if (index < 0 || index >= keys.length) {
89472
+ return null;
89473
+ }
89474
+ return keys[index];
89475
+ };
89476
+ const localStorage = {
89477
+ clear,
89478
+ getItem,
89479
+ key,
89480
+ get length() {
89481
+ return store.size;
89482
+ },
89483
+ removeItem,
89484
+ setItem
89485
+ };
89486
+ return localStorage;
89487
+ };
89488
+
89489
+ const getGlobals = (width, height) => {
89490
+ const localStorage = createLocalStorage();
89491
+ return {
89492
+ globalGlobals: {
89493
+ alert: alert,
89494
+ innerHeight: height,
89495
+ innerWidth: width,
89496
+ localStorage
89497
+ },
89498
+ windowGlobals: {
89499
+ alert: alert,
89500
+ innerHeight: height,
89501
+ innerWidth: width
89502
+ }
89503
+ };
89504
+ };
89505
+
89383
89506
  // const FUNCTION_REGEX = /(?:^|[\n;])\s*function\s+([a-zA-Z_$][\w$]*)/g
89384
89507
 
89385
89508
  const getTopLevelFunctionNames = script => {
@@ -89467,57 +89590,30 @@ const getTopLevelFunctionNames = script => {
89467
89590
  return names;
89468
89591
  };
89469
89592
 
89470
- const createLocalStorage = () => {
89471
- const store = new Map();
89472
- const getItem = key => {
89473
- if (store.has(key)) {
89474
- return store.get(key);
89475
- }
89476
- return null;
89477
- };
89478
- const setItem = (key, value) => {
89479
- store.set(key, String(value));
89480
- };
89481
- const removeItem = key => {
89482
- store.delete(key);
89483
- };
89484
- const clear = () => {
89485
- store.clear();
89486
- };
89487
- const key = index => {
89488
- const keys = [...store.keys()];
89489
- if (index < 0 || index >= keys.length) {
89490
- return null;
89491
- }
89492
- return keys[index];
89493
- };
89494
- const localStorage = {
89495
- clear,
89496
- getItem,
89497
- key,
89498
- get length() {
89499
- return store.size;
89500
- },
89501
- removeItem,
89502
- setItem
89503
- };
89504
- return localStorage;
89593
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
89594
+
89595
+ const setGlobals = (window, globalGlobals, windowGlobals) => {
89596
+ for (const [key, value] of Object.entries(globalGlobals)) {
89597
+ // @ts-ignore
89598
+ globalThis[key] = value;
89599
+ }
89600
+ for (const [key, value] of Object.entries(windowGlobals)) {
89601
+ // @ts-ignore
89602
+ window[key] = value;
89603
+ }
89505
89604
  };
89506
89605
 
89606
+ /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
89507
89607
  /* eslint-disable @typescript-eslint/no-implied-eval */
89608
+
89508
89609
  const executeScripts = (window, document, scripts, width = 0, height = 0) => {
89509
- window.alert = alert;
89510
- // @ts-ignore
89511
- globalThis.alert = alert;
89512
- const localStorage = createLocalStorage();
89513
- // @ts-ignore
89514
- globalThis.localStorage = localStorage;
89515
- window.innerWidth = width;
89516
- window.innerHeight = height;
89517
- // @ts-ignore
89518
- globalThis.innerWidth = width;
89519
- // @ts-ignore
89520
- globalThis.innerHeight = height;
89610
+ const {
89611
+ globalGlobals,
89612
+ windowGlobals
89613
+ } = getGlobals(width, height);
89614
+ setGlobals(window, globalGlobals, windowGlobals);
89615
+ let firstError = null;
89616
+ let firstCodeFrame = '';
89521
89617
  // Execute each script with the happy-dom window and document as context
89522
89618
  for (const scriptContent of scripts) {
89523
89619
  try {
@@ -89529,9 +89625,17 @@ const executeScripts = (window, document, scripts, width = 0, height = 0) => {
89529
89625
  const fn = new Function('window', 'document', 'console', scriptContent + suffix);
89530
89626
  fn(window, document, console);
89531
89627
  } catch (error) {
89532
- console.warn('[preview-sandbox-worker] Script execution error:', error);
89628
+ // Record the first error but continue executing remaining scripts
89629
+ if (firstError === null) {
89630
+ firstCodeFrame = getErrorCodeFrame(scriptContent, error);
89631
+ firstError = error;
89632
+ }
89533
89633
  }
89534
89634
  }
89635
+ return {
89636
+ codeFrame: firstCodeFrame,
89637
+ error: firstError
89638
+ };
89535
89639
  };
89536
89640
 
89537
89641
  const getParsedNodesChildNodeCount = parsedDom => {
@@ -89705,7 +89809,10 @@ const updateContent = async (uid, width, height, content, scripts) => {
89705
89809
  window: happyDomWindow
89706
89810
  } = createWindow(content);
89707
89811
  await patchCanvasElements(happyDomDocument, uid);
89708
- executeScripts(happyDomWindow, happyDomDocument, scripts, width, height);
89812
+ const {
89813
+ codeFrame,
89814
+ error
89815
+ } = executeScripts(happyDomWindow, happyDomDocument, scripts, width, height);
89709
89816
  const elementMap = new Map();
89710
89817
  set$1(uid, {
89711
89818
  document: happyDomDocument,
@@ -89714,12 +89821,16 @@ const updateContent = async (uid, width, height, content, scripts) => {
89714
89821
  });
89715
89822
  observe(uid, happyDomDocument, happyDomWindow);
89716
89823
  return {
89824
+ codeFrame,
89825
+ error,
89717
89826
  errorMessage: ''
89718
89827
  };
89719
89828
  } catch (error) {
89720
89829
  // If file reading or parsing fails, return empty content and parsedDom with error message
89721
89830
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
89722
89831
  return {
89832
+ codeFrame: '',
89833
+ error,
89723
89834
  errorMessage
89724
89835
  };
89725
89836
  }
@@ -89732,8 +89843,13 @@ const loadContent = async (uid, width, height, content, scripts) => {
89732
89843
 
89733
89844
  // Read and parse file contents if we have a URI
89734
89845
  const {
89846
+ codeFrame,
89847
+ error,
89735
89848
  errorMessage
89736
89849
  } = await updateContent(uid, width, height, content, scripts);
89850
+ if (error) {
89851
+ console.warn(`preview error: ${error} ${codeFrame}`);
89852
+ }
89737
89853
  return {
89738
89854
  errorMessage
89739
89855
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/preview-sandbox-worker",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "Preview SandBox Worker",
5
5
  "repository": {
6
6
  "type": "git",