@openfin/node-adapter 46.100.63 → 46.100.65

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.
Files changed (2) hide show
  1. package/out/node-adapter.js +63 -27
  2. package/package.json +2 -2
@@ -293,6 +293,26 @@ class EmitterBase extends Base {
293
293
  }
294
294
  _EmitterBase_emitterAccessor = new WeakMap(), _EmitterBase_deregisterOnceListeners = new WeakMap();
295
295
 
296
+ const V8Error = Error;
297
+ function isCallSiteArray(stack) {
298
+ if (!Array.isArray(stack) || stack.length === 0) {
299
+ return Array.isArray(stack);
300
+ }
301
+ const first = stack[0];
302
+ return typeof first === 'object' && first !== null && typeof first.getFileName === 'function';
303
+ }
304
+ function isStackFrameLine(line) {
305
+ return /^\s*at\s/.test(line) || line.includes('@');
306
+ }
307
+ /**
308
+ * Split a native `error.stack` string into frames and drop the dummy Error header plus `framesToRemove` frames.
309
+ * Safari/Firefox ignore V8's Error.prepareStackTrace, so `.stack` stays a string and `.slice(n)` would cut characters.
310
+ */
311
+ function stackStringToFrames(stack, framesToRemove) {
312
+ const lines = stack.split('\n').filter((line) => line.length > 0);
313
+ const start = lines[0] !== undefined && !isStackFrameLine(lines[0]) ? 1 : 0;
314
+ return lines.slice(start + framesToRemove);
315
+ }
296
316
  class DisconnectedError extends Error {
297
317
  constructor(readyState) {
298
318
  super(`Expected websocket state OPEN but found ${readyState}`);
@@ -329,17 +349,17 @@ class DeserializedError extends Error {
329
349
  class RuntimeError extends Error {
330
350
  static trimEndCallSites(err, takeUntilRegex) {
331
351
  // save original props
332
- const length = Error.stackTraceLimit;
352
+ const length = V8Error.stackTraceLimit;
333
353
  // eslint-disable-next-line no-underscore-dangle
334
- const _prepareStackTrace = Error.prepareStackTrace;
354
+ const _prepareStackTrace = V8Error.prepareStackTrace;
335
355
  // This will be called when we access the `stack` property
336
- Error.prepareStackTrace = (_, stack) => stack;
356
+ V8Error.prepareStackTrace = (_, stack) => stack;
337
357
  // in channel errors, the error was already serialized so we need to handle both string and CallSite[]
338
358
  const isString = typeof err.stack === 'string';
339
359
  const stack = (isString ? err.stack?.split('\n') : err.stack) ?? [];
340
360
  // restore original props
341
- Error.prepareStackTrace = _prepareStackTrace;
342
- Error.stackTraceLimit = length;
361
+ V8Error.prepareStackTrace = _prepareStackTrace;
362
+ V8Error.stackTraceLimit = length;
343
363
  // stack is optional in non chromium contexts
344
364
  if (stack.length) {
345
365
  const newStack = [];
@@ -361,31 +381,47 @@ class RuntimeError extends Error {
361
381
  }
362
382
  }
363
383
  static getCallSite(callsToRemove = 0) {
364
- const length = Error.stackTraceLimit;
384
+ const length = V8Error.stackTraceLimit;
365
385
  const realCallsToRemove = callsToRemove + 1; // remove this call;
366
- Error.stackTraceLimit = length + realCallsToRemove;
386
+ const limit = typeof length === 'number' && Number.isFinite(length) ? length : 10;
367
387
  // eslint-disable-next-line no-underscore-dangle
368
- const _prepareStackTrace = Error.prepareStackTrace;
369
- // This will be called when we access the `stack` property
370
- Error.prepareStackTrace = (_, stack) => stack;
371
- // stack is optional in non chromium contexts
372
- const stack = new Error().stack?.slice(realCallsToRemove) ?? [];
373
- Error.prepareStackTrace = _prepareStackTrace;
374
- Error.stackTraceLimit = length;
375
- return stack;
388
+ const _prepareStackTrace = V8Error.prepareStackTrace;
389
+ try {
390
+ V8Error.stackTraceLimit = limit + realCallsToRemove;
391
+ // V8 only: accessing `.stack` invokes this and returns CallSite[]. Safari/Firefox ignore it.
392
+ V8Error.prepareStackTrace = (_, stack) => stack;
393
+ const rawStack = new Error().stack;
394
+ if (Array.isArray(rawStack)) {
395
+ return rawStack.slice(realCallsToRemove);
396
+ }
397
+ if (typeof rawStack === 'string' && rawStack.length > 0) {
398
+ return stackStringToFrames(rawStack, realCallsToRemove);
399
+ }
400
+ return [];
401
+ }
402
+ finally {
403
+ V8Error.prepareStackTrace = _prepareStackTrace;
404
+ V8Error.stackTraceLimit = length;
405
+ }
376
406
  }
377
407
  static prepareStackTrace(err, callSites) {
378
- if (typeof Error.prepareStackTrace === 'function') {
379
- return Error.prepareStackTrace(err, callSites);
380
- }
381
- // TODO: this is just a first iteration, we can make this "nicer" at some point
382
- // const EXCLUSIONS = ['IpcRenderer', 'Object.onMessage', 'Transport.onmessage', 'MessageReceiver.onmessage'];
383
- let stackTrace = `${err.name || 'Error'}: ${err.message || ''}\n`;
384
- stackTrace += callSites
385
- .map((line) => ` at ${line}`)
386
- // .filter((line) => !EXCLUSIONS.some((l) => line.includes(l)))
387
- .join('\n');
388
- return stackTrace;
408
+ const header = `${err.name || 'Error'}: ${err.message || ''}`;
409
+ const frames = typeof callSites === 'string' ? stackStringToFrames(callSites, 0) : callSites;
410
+ if (!Array.isArray(frames) || frames.length === 0) {
411
+ return header;
412
+ }
413
+ if (isCallSiteArray(frames)) {
414
+ const prepare = V8Error.prepareStackTrace;
415
+ // Only V8 CallSite[] may be passed to a user-supplied Error.prepareStackTrace.
416
+ if (typeof prepare === 'function') {
417
+ return prepare(err, frames);
418
+ }
419
+ // TODO: this is just a first iteration, we can make this "nicer" at some point
420
+ // const EXCLUSIONS = ['IpcRenderer', 'Object.onMessage', 'Transport.onmessage', 'MessageReceiver.onmessage'];
421
+ return `${header}\n${frames.map((line) => ` at ${line}`).join('\n')}`;
422
+ }
423
+ // Native Safari/Firefox frames already include their engine's format (`func@file:line:col`).
424
+ return `${header}\n${frames.join('\n')}`;
389
425
  }
390
426
  /*
391
427
 
@@ -17459,7 +17495,7 @@ class NodeEnvironment extends BaseEnvironment {
17459
17495
  };
17460
17496
  }
17461
17497
  getAdapterVersionSync() {
17462
- return "46.100.63";
17498
+ return "46.100.65";
17463
17499
  }
17464
17500
  observeBounds(element, onChange) {
17465
17501
  throw new Error('Method not implemented.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfin/node-adapter",
3
- "version": "46.100.63",
3
+ "version": "46.100.65",
4
4
  "description": "See README.md",
5
5
  "main": "out/node-adapter.js",
6
6
  "types": "out/node-adapter.d.ts",
@@ -20,7 +20,7 @@
20
20
  "es-toolkit": "^1.39.3",
21
21
  "ws": "^7.5.11",
22
22
  "tslib": "2.8.1",
23
- "@openfin/core": "46.100.63"
23
+ "@openfin/core": "46.100.65"
24
24
  },
25
25
  "scripts": {
26
26
  "prebuild": "rimraf ./out",