@openfin/core 45.100.113 → 45.100.114

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.
@@ -2166,6 +2166,15 @@ declare type ByType_8<Type extends EventType_8> = Payload_10<Type>;
2166
2166
  */
2167
2167
  declare type ByType_9<Type extends EventType_9> = Payload_11<Type>;
2168
2168
 
2169
+ /** Minimal V8 CallSite shape — js-adapter does not include @types/node. */
2170
+ declare interface CallSite {
2171
+ getFileName(): string | null;
2172
+ toString(): string;
2173
+ }
2174
+
2175
+ /** V8 CallSite objects, or native stack-frame strings from browsers that ignore Error.prepareStackTrace. */
2176
+ declare type CapturedStack = CallSite[] | string[];
2177
+
2169
2178
  /**
2170
2179
  * Configuration for page capture.
2171
2180
  *
@@ -9445,6 +9454,10 @@ declare type Manifest = {
9445
9454
  experimentalExtensionPolicyBlockedHosts?: {
9446
9455
  hosts: string[];
9447
9456
  };
9457
+ /**
9458
+ * Chromium extensions to install and enable for this application.
9459
+ */
9460
+ extensions?: ManifestExtension[];
9448
9461
  licenseKey: string;
9449
9462
  offlineAccess?: boolean;
9450
9463
  platform?: PlatformOptions;
@@ -9498,6 +9511,27 @@ declare type ManifestChangedEvent = BaseEvents.IdentityEvent & {
9498
9511
  type: 'manifest-changed';
9499
9512
  };
9500
9513
 
9514
+ /**
9515
+ * Chromium extension entry in an application configuration.
9516
+ *
9517
+ * @interface
9518
+ */
9519
+ declare type ManifestExtension = {
9520
+ /** Chromium extension ID. */
9521
+ id: string;
9522
+ /** Extension server URL used to install the extension. */
9523
+ serverURL: string;
9524
+ /**
9525
+ * Rules declaring where this extension may inject content scripts into
9526
+ * non-tab surfaces (for example the AI Center). Omit or leave empty to keep
9527
+ * the extension restricted to browser tabs — identical to historic
9528
+ * behavior. A wildcard pattern in `match` grants blanket coverage.
9529
+ * `matchOptions` behaves as it does for domain settings. Intended for
9530
+ * security extensions rather than extensions that add visible UI.
9531
+ */
9532
+ nonTabInjections?: NonTabInjectionRule[];
9533
+ };
9534
+
9501
9535
  /**
9502
9536
  * @interface
9503
9537
  */
@@ -10288,6 +10322,32 @@ declare type NonPropagatedWebContentsEvent = never;
10288
10322
  */
10289
10323
  declare type NonPropagatedWindowEvent = never;
10290
10324
 
10325
+ /**
10326
+ * Rule permitting a Chromium extension to inject content scripts into non-tab
10327
+ * web content whose URL matches the given patterns.
10328
+ *
10329
+ * Match patterns use the same Chromium
10330
+ * [match pattern](https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns)
10331
+ * syntax as {@link DomainSettingsRule}. Omitting `matchOptions` uses the same
10332
+ * default scheme-matching behavior as domain settings.
10333
+ *
10334
+ * @interface
10335
+ */
10336
+ declare type NonTabInjectionRule = {
10337
+ /**
10338
+ * Array of [match patterns](https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns)
10339
+ * specifying the content locations where the extension may inject outside
10340
+ * browser tabs. An empty array grants no permission. A wildcard grants
10341
+ * blanket coverage of all content locations.
10342
+ */
10343
+ match: string[];
10344
+ /**
10345
+ * Options to use when comparing URIs to the `match` patterns. Behaves as
10346
+ * {@link DomainSettingsRule.matchOptions} / {@link RuleMatchOptions}.
10347
+ */
10348
+ matchOptions?: RuleMatchOptions;
10349
+ };
10350
+
10291
10351
  /* Excluded from this release type: NotCloseRequested */
10292
10352
 
10293
10353
  declare type NotificationEvent = {
@@ -10596,6 +10656,8 @@ declare namespace OpenFin_2 {
10596
10656
  ThemeColorsMap,
10597
10657
  ThemeColorId,
10598
10658
  ThemePalette,
10659
+ NonTabInjectionRule,
10660
+ ManifestExtension,
10599
10661
  Manifest,
10600
10662
  LayoutContent,
10601
10663
  LayoutItemConfig,
@@ -17554,7 +17616,7 @@ declare class Transport<MeType extends EntityType = EntityType> extends EventEmi
17554
17616
  connectByPort(config: ExistingConnectConfig): Promise<void>;
17555
17617
  private authorize;
17556
17618
  sendAction<T extends keyof ProtocolMap>(action: T, payload?: ProtocolMap[T]['request'], uncorrelated?: boolean): SentMessage<SendActionResponse<T>>;
17557
- protected nackHandler(payloadOrMessage: RuntimeErrorPayload | string, reject: Function, callSites?: NodeJS.CallSite[]): void;
17619
+ protected nackHandler(payloadOrMessage: RuntimeErrorPayload | string, reject: Function, callSites?: CapturedStack): void;
17558
17620
  ferryAction(origData: any): Promise<Message<any>>;
17559
17621
  registerMessageHandler(handler: MessageHandler): void;
17560
17622
  protected addWireListener(id: number, resolve: Function, handleNack: NackHandler, uncorrelated: boolean): void;
@@ -2166,6 +2166,15 @@ declare type ByType_8<Type extends EventType_8> = Payload_10<Type>;
2166
2166
  */
2167
2167
  declare type ByType_9<Type extends EventType_9> = Payload_11<Type>;
2168
2168
 
2169
+ /** Minimal V8 CallSite shape — js-adapter does not include @types/node. */
2170
+ declare interface CallSite {
2171
+ getFileName(): string | null;
2172
+ toString(): string;
2173
+ }
2174
+
2175
+ /** V8 CallSite objects, or native stack-frame strings from browsers that ignore Error.prepareStackTrace. */
2176
+ declare type CapturedStack = CallSite[] | string[];
2177
+
2169
2178
  /**
2170
2179
  * Configuration for page capture.
2171
2180
  *
@@ -9445,6 +9454,10 @@ declare type Manifest = {
9445
9454
  experimentalExtensionPolicyBlockedHosts?: {
9446
9455
  hosts: string[];
9447
9456
  };
9457
+ /**
9458
+ * Chromium extensions to install and enable for this application.
9459
+ */
9460
+ extensions?: ManifestExtension[];
9448
9461
  licenseKey: string;
9449
9462
  offlineAccess?: boolean;
9450
9463
  platform?: PlatformOptions;
@@ -9498,6 +9511,27 @@ declare type ManifestChangedEvent = BaseEvents.IdentityEvent & {
9498
9511
  type: 'manifest-changed';
9499
9512
  };
9500
9513
 
9514
+ /**
9515
+ * Chromium extension entry in an application configuration.
9516
+ *
9517
+ * @interface
9518
+ */
9519
+ declare type ManifestExtension = {
9520
+ /** Chromium extension ID. */
9521
+ id: string;
9522
+ /** Extension server URL used to install the extension. */
9523
+ serverURL: string;
9524
+ /**
9525
+ * Rules declaring where this extension may inject content scripts into
9526
+ * non-tab surfaces (for example the AI Center). Omit or leave empty to keep
9527
+ * the extension restricted to browser tabs — identical to historic
9528
+ * behavior. A wildcard pattern in `match` grants blanket coverage.
9529
+ * `matchOptions` behaves as it does for domain settings. Intended for
9530
+ * security extensions rather than extensions that add visible UI.
9531
+ */
9532
+ nonTabInjections?: NonTabInjectionRule[];
9533
+ };
9534
+
9501
9535
  /**
9502
9536
  * @interface
9503
9537
  */
@@ -10288,6 +10322,32 @@ declare type NonPropagatedWebContentsEvent = never;
10288
10322
  */
10289
10323
  declare type NonPropagatedWindowEvent = never;
10290
10324
 
10325
+ /**
10326
+ * Rule permitting a Chromium extension to inject content scripts into non-tab
10327
+ * web content whose URL matches the given patterns.
10328
+ *
10329
+ * Match patterns use the same Chromium
10330
+ * [match pattern](https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns)
10331
+ * syntax as {@link DomainSettingsRule}. Omitting `matchOptions` uses the same
10332
+ * default scheme-matching behavior as domain settings.
10333
+ *
10334
+ * @interface
10335
+ */
10336
+ declare type NonTabInjectionRule = {
10337
+ /**
10338
+ * Array of [match patterns](https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns)
10339
+ * specifying the content locations where the extension may inject outside
10340
+ * browser tabs. An empty array grants no permission. A wildcard grants
10341
+ * blanket coverage of all content locations.
10342
+ */
10343
+ match: string[];
10344
+ /**
10345
+ * Options to use when comparing URIs to the `match` patterns. Behaves as
10346
+ * {@link DomainSettingsRule.matchOptions} / {@link RuleMatchOptions}.
10347
+ */
10348
+ matchOptions?: RuleMatchOptions;
10349
+ };
10350
+
10291
10351
  /* Excluded from this release type: NotCloseRequested */
10292
10352
 
10293
10353
  declare type NotificationEvent = {
@@ -10596,6 +10656,8 @@ declare namespace OpenFin_2 {
10596
10656
  ThemeColorsMap,
10597
10657
  ThemeColorId,
10598
10658
  ThemePalette,
10659
+ NonTabInjectionRule,
10660
+ ManifestExtension,
10599
10661
  Manifest,
10600
10662
  LayoutContent,
10601
10663
  LayoutItemConfig,
@@ -17554,7 +17616,7 @@ declare class Transport<MeType extends EntityType = EntityType> extends EventEmi
17554
17616
  connectByPort(config: ExistingConnectConfig): Promise<void>;
17555
17617
  private authorize;
17556
17618
  sendAction<T extends keyof ProtocolMap>(action: T, payload?: ProtocolMap[T]['request'], uncorrelated?: boolean): SentMessage<SendActionResponse<T>>;
17557
- protected nackHandler(payloadOrMessage: RuntimeErrorPayload | string, reject: Function, callSites?: NodeJS.CallSite[]): void;
17619
+ protected nackHandler(payloadOrMessage: RuntimeErrorPayload | string, reject: Function, callSites?: CapturedStack): void;
17558
17620
  ferryAction(origData: any): Promise<Message<any>>;
17559
17621
  registerMessageHandler(handler: MessageHandler): void;
17560
17622
  protected addWireListener(id: number, resolve: Function, handleNack: NackHandler, uncorrelated: boolean): void;
@@ -2166,6 +2166,15 @@ declare type ByType_8<Type extends EventType_8> = Payload_10<Type>;
2166
2166
  */
2167
2167
  declare type ByType_9<Type extends EventType_9> = Payload_11<Type>;
2168
2168
 
2169
+ /** Minimal V8 CallSite shape — js-adapter does not include @types/node. */
2170
+ declare interface CallSite {
2171
+ getFileName(): string | null;
2172
+ toString(): string;
2173
+ }
2174
+
2175
+ /** V8 CallSite objects, or native stack-frame strings from browsers that ignore Error.prepareStackTrace. */
2176
+ declare type CapturedStack = CallSite[] | string[];
2177
+
2169
2178
  /**
2170
2179
  * Configuration for page capture.
2171
2180
  *
@@ -9445,6 +9454,10 @@ declare type Manifest = {
9445
9454
  experimentalExtensionPolicyBlockedHosts?: {
9446
9455
  hosts: string[];
9447
9456
  };
9457
+ /**
9458
+ * Chromium extensions to install and enable for this application.
9459
+ */
9460
+ extensions?: ManifestExtension[];
9448
9461
  licenseKey: string;
9449
9462
  offlineAccess?: boolean;
9450
9463
  platform?: PlatformOptions;
@@ -9498,6 +9511,27 @@ declare type ManifestChangedEvent = BaseEvents.IdentityEvent & {
9498
9511
  type: 'manifest-changed';
9499
9512
  };
9500
9513
 
9514
+ /**
9515
+ * Chromium extension entry in an application configuration.
9516
+ *
9517
+ * @interface
9518
+ */
9519
+ declare type ManifestExtension = {
9520
+ /** Chromium extension ID. */
9521
+ id: string;
9522
+ /** Extension server URL used to install the extension. */
9523
+ serverURL: string;
9524
+ /**
9525
+ * Rules declaring where this extension may inject content scripts into
9526
+ * non-tab surfaces (for example the AI Center). Omit or leave empty to keep
9527
+ * the extension restricted to browser tabs — identical to historic
9528
+ * behavior. A wildcard pattern in `match` grants blanket coverage.
9529
+ * `matchOptions` behaves as it does for domain settings. Intended for
9530
+ * security extensions rather than extensions that add visible UI.
9531
+ */
9532
+ nonTabInjections?: NonTabInjectionRule[];
9533
+ };
9534
+
9501
9535
  /**
9502
9536
  * @interface
9503
9537
  */
@@ -10288,6 +10322,32 @@ declare type NonPropagatedWebContentsEvent = never;
10288
10322
  */
10289
10323
  declare type NonPropagatedWindowEvent = never;
10290
10324
 
10325
+ /**
10326
+ * Rule permitting a Chromium extension to inject content scripts into non-tab
10327
+ * web content whose URL matches the given patterns.
10328
+ *
10329
+ * Match patterns use the same Chromium
10330
+ * [match pattern](https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns)
10331
+ * syntax as {@link DomainSettingsRule}. Omitting `matchOptions` uses the same
10332
+ * default scheme-matching behavior as domain settings.
10333
+ *
10334
+ * @interface
10335
+ */
10336
+ declare type NonTabInjectionRule = {
10337
+ /**
10338
+ * Array of [match patterns](https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns)
10339
+ * specifying the content locations where the extension may inject outside
10340
+ * browser tabs. An empty array grants no permission. A wildcard grants
10341
+ * blanket coverage of all content locations.
10342
+ */
10343
+ match: string[];
10344
+ /**
10345
+ * Options to use when comparing URIs to the `match` patterns. Behaves as
10346
+ * {@link DomainSettingsRule.matchOptions} / {@link RuleMatchOptions}.
10347
+ */
10348
+ matchOptions?: RuleMatchOptions;
10349
+ };
10350
+
10291
10351
  /* Excluded from this release type: NotCloseRequested */
10292
10352
 
10293
10353
  declare type NotificationEvent = {
@@ -10596,6 +10656,8 @@ declare namespace OpenFin_2 {
10596
10656
  ThemeColorsMap,
10597
10657
  ThemeColorId,
10598
10658
  ThemePalette,
10659
+ NonTabInjectionRule,
10660
+ ManifestExtension,
10599
10661
  Manifest,
10600
10662
  LayoutContent,
10601
10663
  LayoutItemConfig,
@@ -17554,7 +17616,7 @@ declare class Transport<MeType extends EntityType = EntityType> extends EventEmi
17554
17616
  connectByPort(config: ExistingConnectConfig): Promise<void>;
17555
17617
  private authorize;
17556
17618
  sendAction<T extends keyof ProtocolMap>(action: T, payload?: ProtocolMap[T]['request'], uncorrelated?: boolean): SentMessage<SendActionResponse<T>>;
17557
- protected nackHandler(payloadOrMessage: RuntimeErrorPayload | string, reject: Function, callSites?: NodeJS.CallSite[]): void;
17619
+ protected nackHandler(payloadOrMessage: RuntimeErrorPayload | string, reject: Function, callSites?: CapturedStack): void;
17558
17620
  ferryAction(origData: any): Promise<Message<any>>;
17559
17621
  registerMessageHandler(handler: MessageHandler): void;
17560
17622
  protected addWireListener(id: number, resolve: Function, handleNack: NackHandler, uncorrelated: boolean): void;
package/out/stub.d.ts CHANGED
@@ -2198,6 +2198,15 @@ declare type ByType_8<Type extends EventType_8> = Payload_10<Type>;
2198
2198
  */
2199
2199
  declare type ByType_9<Type extends EventType_9> = Payload_11<Type>;
2200
2200
 
2201
+ /** Minimal V8 CallSite shape — js-adapter does not include @types/node. */
2202
+ declare interface CallSite {
2203
+ getFileName(): string | null;
2204
+ toString(): string;
2205
+ }
2206
+
2207
+ /** V8 CallSite objects, or native stack-frame strings from browsers that ignore Error.prepareStackTrace. */
2208
+ declare type CapturedStack = CallSite[] | string[];
2209
+
2201
2210
  /**
2202
2211
  * Configuration for page capture.
2203
2212
  *
@@ -9803,6 +9812,10 @@ declare type Manifest = {
9803
9812
  experimentalExtensionPolicyBlockedHosts?: {
9804
9813
  hosts: string[];
9805
9814
  };
9815
+ /**
9816
+ * Chromium extensions to install and enable for this application.
9817
+ */
9818
+ extensions?: ManifestExtension[];
9806
9819
  licenseKey: string;
9807
9820
  offlineAccess?: boolean;
9808
9821
  platform?: PlatformOptions;
@@ -9856,6 +9869,27 @@ declare type ManifestChangedEvent = BaseEvents.IdentityEvent & {
9856
9869
  type: 'manifest-changed';
9857
9870
  };
9858
9871
 
9872
+ /**
9873
+ * Chromium extension entry in an application configuration.
9874
+ *
9875
+ * @interface
9876
+ */
9877
+ declare type ManifestExtension = {
9878
+ /** Chromium extension ID. */
9879
+ id: string;
9880
+ /** Extension server URL used to install the extension. */
9881
+ serverURL: string;
9882
+ /**
9883
+ * Rules declaring where this extension may inject content scripts into
9884
+ * non-tab surfaces (for example the AI Center). Omit or leave empty to keep
9885
+ * the extension restricted to browser tabs — identical to historic
9886
+ * behavior. A wildcard pattern in `match` grants blanket coverage.
9887
+ * `matchOptions` behaves as it does for domain settings. Intended for
9888
+ * security extensions rather than extensions that add visible UI.
9889
+ */
9890
+ nonTabInjections?: NonTabInjectionRule[];
9891
+ };
9892
+
9859
9893
  /**
9860
9894
  * @interface
9861
9895
  */
@@ -10658,6 +10692,32 @@ declare type NonPropagatedWebContentsEvent = never;
10658
10692
  */
10659
10693
  declare type NonPropagatedWindowEvent = never;
10660
10694
 
10695
+ /**
10696
+ * Rule permitting a Chromium extension to inject content scripts into non-tab
10697
+ * web content whose URL matches the given patterns.
10698
+ *
10699
+ * Match patterns use the same Chromium
10700
+ * [match pattern](https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns)
10701
+ * syntax as {@link DomainSettingsRule}. Omitting `matchOptions` uses the same
10702
+ * default scheme-matching behavior as domain settings.
10703
+ *
10704
+ * @interface
10705
+ */
10706
+ declare type NonTabInjectionRule = {
10707
+ /**
10708
+ * Array of [match patterns](https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns)
10709
+ * specifying the content locations where the extension may inject outside
10710
+ * browser tabs. An empty array grants no permission. A wildcard grants
10711
+ * blanket coverage of all content locations.
10712
+ */
10713
+ match: string[];
10714
+ /**
10715
+ * Options to use when comparing URIs to the `match` patterns. Behaves as
10716
+ * {@link DomainSettingsRule.matchOptions} / {@link RuleMatchOptions}.
10717
+ */
10718
+ matchOptions?: RuleMatchOptions;
10719
+ };
10720
+
10661
10721
  /**
10662
10722
  * @internal
10663
10723
  *
@@ -10979,6 +11039,8 @@ declare namespace OpenFin_2 {
10979
11039
  ThemeColorsMap,
10980
11040
  ThemeColorId,
10981
11041
  ThemePalette,
11042
+ NonTabInjectionRule,
11043
+ ManifestExtension,
10982
11044
  Manifest,
10983
11045
  LayoutContent,
10984
11046
  LayoutItemConfig,
@@ -18033,7 +18095,7 @@ declare class Transport<MeType extends EntityType = EntityType> extends EventEmi
18033
18095
  connectByPort(config: ExistingConnectConfig): Promise<void>;
18034
18096
  private authorize;
18035
18097
  sendAction<T extends keyof ProtocolMap>(action: T, payload?: ProtocolMap[T]['request'], uncorrelated?: boolean): SentMessage<SendActionResponse<T>>;
18036
- protected nackHandler(payloadOrMessage: RuntimeErrorPayload | string, reject: Function, callSites?: NodeJS.CallSite[]): void;
18098
+ protected nackHandler(payloadOrMessage: RuntimeErrorPayload | string, reject: Function, callSites?: CapturedStack): void;
18037
18099
  ferryAction(origData: any): Promise<Message<any>>;
18038
18100
  registerMessageHandler(handler: MessageHandler): void;
18039
18101
  protected addWireListener(id: number, resolve: Function, handleNack: NackHandler, uncorrelated: boolean): void;
package/out/stub.js CHANGED
@@ -469,6 +469,26 @@ class EmitterBase extends Base {
469
469
  }
470
470
  _EmitterBase_emitterAccessor = new WeakMap(), _EmitterBase_deregisterOnceListeners = new WeakMap();
471
471
 
472
+ const V8Error = Error;
473
+ function isCallSiteArray(stack) {
474
+ if (!Array.isArray(stack) || stack.length === 0) {
475
+ return Array.isArray(stack);
476
+ }
477
+ const first = stack[0];
478
+ return typeof first === 'object' && first !== null && typeof first.getFileName === 'function';
479
+ }
480
+ function isStackFrameLine(line) {
481
+ return /^\s*at\s/.test(line) || line.includes('@');
482
+ }
483
+ /**
484
+ * Split a native `error.stack` string into frames and drop the dummy Error header plus `framesToRemove` frames.
485
+ * Safari/Firefox ignore V8's Error.prepareStackTrace, so `.stack` stays a string and `.slice(n)` would cut characters.
486
+ */
487
+ function stackStringToFrames(stack, framesToRemove) {
488
+ const lines = stack.split('\n').filter((line) => line.length > 0);
489
+ const start = lines[0] !== undefined && !isStackFrameLine(lines[0]) ? 1 : 0;
490
+ return lines.slice(start + framesToRemove);
491
+ }
472
492
  class UnexpectedActionError extends Error {
473
493
  }
474
494
  class DuplicateCorrelationError extends Error {
@@ -497,17 +517,17 @@ class DeserializedError extends Error {
497
517
  class RuntimeError extends Error {
498
518
  static trimEndCallSites(err, takeUntilRegex) {
499
519
  // save original props
500
- const length = Error.stackTraceLimit;
520
+ const length = V8Error.stackTraceLimit;
501
521
  // eslint-disable-next-line no-underscore-dangle
502
- const _prepareStackTrace = Error.prepareStackTrace;
522
+ const _prepareStackTrace = V8Error.prepareStackTrace;
503
523
  // This will be called when we access the `stack` property
504
- Error.prepareStackTrace = (_, stack) => stack;
524
+ V8Error.prepareStackTrace = (_, stack) => stack;
505
525
  // in channel errors, the error was already serialized so we need to handle both string and CallSite[]
506
526
  const isString = typeof err.stack === 'string';
507
527
  const stack = (isString ? err.stack?.split('\n') : err.stack) ?? [];
508
528
  // restore original props
509
- Error.prepareStackTrace = _prepareStackTrace;
510
- Error.stackTraceLimit = length;
529
+ V8Error.prepareStackTrace = _prepareStackTrace;
530
+ V8Error.stackTraceLimit = length;
511
531
  // stack is optional in non chromium contexts
512
532
  if (stack.length) {
513
533
  const newStack = [];
@@ -529,31 +549,47 @@ class RuntimeError extends Error {
529
549
  }
530
550
  }
531
551
  static getCallSite(callsToRemove = 0) {
532
- const length = Error.stackTraceLimit;
552
+ const length = V8Error.stackTraceLimit;
533
553
  const realCallsToRemove = callsToRemove + 1; // remove this call;
534
- Error.stackTraceLimit = length + realCallsToRemove;
554
+ const limit = typeof length === 'number' && Number.isFinite(length) ? length : 10;
535
555
  // eslint-disable-next-line no-underscore-dangle
536
- const _prepareStackTrace = Error.prepareStackTrace;
537
- // This will be called when we access the `stack` property
538
- Error.prepareStackTrace = (_, stack) => stack;
539
- // stack is optional in non chromium contexts
540
- const stack = new Error().stack?.slice(realCallsToRemove) ?? [];
541
- Error.prepareStackTrace = _prepareStackTrace;
542
- Error.stackTraceLimit = length;
543
- return stack;
556
+ const _prepareStackTrace = V8Error.prepareStackTrace;
557
+ try {
558
+ V8Error.stackTraceLimit = limit + realCallsToRemove;
559
+ // V8 only: accessing `.stack` invokes this and returns CallSite[]. Safari/Firefox ignore it.
560
+ V8Error.prepareStackTrace = (_, stack) => stack;
561
+ const rawStack = new Error().stack;
562
+ if (Array.isArray(rawStack)) {
563
+ return rawStack.slice(realCallsToRemove);
564
+ }
565
+ if (typeof rawStack === 'string' && rawStack.length > 0) {
566
+ return stackStringToFrames(rawStack, realCallsToRemove);
567
+ }
568
+ return [];
569
+ }
570
+ finally {
571
+ V8Error.prepareStackTrace = _prepareStackTrace;
572
+ V8Error.stackTraceLimit = length;
573
+ }
544
574
  }
545
575
  static prepareStackTrace(err, callSites) {
546
- if (typeof Error.prepareStackTrace === 'function') {
547
- return Error.prepareStackTrace(err, callSites);
548
- }
549
- // TODO: this is just a first iteration, we can make this "nicer" at some point
550
- // const EXCLUSIONS = ['IpcRenderer', 'Object.onMessage', 'Transport.onmessage', 'MessageReceiver.onmessage'];
551
- let stackTrace = `${err.name || 'Error'}: ${err.message || ''}\n`;
552
- stackTrace += callSites
553
- .map((line) => ` at ${line}`)
554
- // .filter((line) => !EXCLUSIONS.some((l) => line.includes(l)))
555
- .join('\n');
556
- return stackTrace;
576
+ const header = `${err.name || 'Error'}: ${err.message || ''}`;
577
+ const frames = typeof callSites === 'string' ? stackStringToFrames(callSites, 0) : callSites;
578
+ if (!Array.isArray(frames) || frames.length === 0) {
579
+ return header;
580
+ }
581
+ if (isCallSiteArray(frames)) {
582
+ const prepare = V8Error.prepareStackTrace;
583
+ // Only V8 CallSite[] may be passed to a user-supplied Error.prepareStackTrace.
584
+ if (typeof prepare === 'function') {
585
+ return prepare(err, frames);
586
+ }
587
+ // TODO: this is just a first iteration, we can make this "nicer" at some point
588
+ // const EXCLUSIONS = ['IpcRenderer', 'Object.onMessage', 'Transport.onmessage', 'MessageReceiver.onmessage'];
589
+ return `${header}\n${frames.map((line) => ` at ${line}`).join('\n')}`;
590
+ }
591
+ // Native Safari/Firefox frames already include their engine's format (`func@file:line:col`).
592
+ return `${header}\n${frames.join('\n')}`;
557
593
  }
558
594
  /*
559
595
 
package/out/stub.mjs CHANGED
@@ -465,6 +465,26 @@ class EmitterBase extends Base {
465
465
  }
466
466
  _EmitterBase_emitterAccessor = new WeakMap(), _EmitterBase_deregisterOnceListeners = new WeakMap();
467
467
 
468
+ const V8Error = Error;
469
+ function isCallSiteArray(stack) {
470
+ if (!Array.isArray(stack) || stack.length === 0) {
471
+ return Array.isArray(stack);
472
+ }
473
+ const first = stack[0];
474
+ return typeof first === 'object' && first !== null && typeof first.getFileName === 'function';
475
+ }
476
+ function isStackFrameLine(line) {
477
+ return /^\s*at\s/.test(line) || line.includes('@');
478
+ }
479
+ /**
480
+ * Split a native `error.stack` string into frames and drop the dummy Error header plus `framesToRemove` frames.
481
+ * Safari/Firefox ignore V8's Error.prepareStackTrace, so `.stack` stays a string and `.slice(n)` would cut characters.
482
+ */
483
+ function stackStringToFrames(stack, framesToRemove) {
484
+ const lines = stack.split('\n').filter((line) => line.length > 0);
485
+ const start = lines[0] !== undefined && !isStackFrameLine(lines[0]) ? 1 : 0;
486
+ return lines.slice(start + framesToRemove);
487
+ }
468
488
  class UnexpectedActionError extends Error {
469
489
  }
470
490
  class DuplicateCorrelationError extends Error {
@@ -493,17 +513,17 @@ class DeserializedError extends Error {
493
513
  class RuntimeError extends Error {
494
514
  static trimEndCallSites(err, takeUntilRegex) {
495
515
  // save original props
496
- const length = Error.stackTraceLimit;
516
+ const length = V8Error.stackTraceLimit;
497
517
  // eslint-disable-next-line no-underscore-dangle
498
- const _prepareStackTrace = Error.prepareStackTrace;
518
+ const _prepareStackTrace = V8Error.prepareStackTrace;
499
519
  // This will be called when we access the `stack` property
500
- Error.prepareStackTrace = (_, stack) => stack;
520
+ V8Error.prepareStackTrace = (_, stack) => stack;
501
521
  // in channel errors, the error was already serialized so we need to handle both string and CallSite[]
502
522
  const isString = typeof err.stack === 'string';
503
523
  const stack = (isString ? err.stack?.split('\n') : err.stack) ?? [];
504
524
  // restore original props
505
- Error.prepareStackTrace = _prepareStackTrace;
506
- Error.stackTraceLimit = length;
525
+ V8Error.prepareStackTrace = _prepareStackTrace;
526
+ V8Error.stackTraceLimit = length;
507
527
  // stack is optional in non chromium contexts
508
528
  if (stack.length) {
509
529
  const newStack = [];
@@ -525,31 +545,47 @@ class RuntimeError extends Error {
525
545
  }
526
546
  }
527
547
  static getCallSite(callsToRemove = 0) {
528
- const length = Error.stackTraceLimit;
548
+ const length = V8Error.stackTraceLimit;
529
549
  const realCallsToRemove = callsToRemove + 1; // remove this call;
530
- Error.stackTraceLimit = length + realCallsToRemove;
550
+ const limit = typeof length === 'number' && Number.isFinite(length) ? length : 10;
531
551
  // eslint-disable-next-line no-underscore-dangle
532
- const _prepareStackTrace = Error.prepareStackTrace;
533
- // This will be called when we access the `stack` property
534
- Error.prepareStackTrace = (_, stack) => stack;
535
- // stack is optional in non chromium contexts
536
- const stack = new Error().stack?.slice(realCallsToRemove) ?? [];
537
- Error.prepareStackTrace = _prepareStackTrace;
538
- Error.stackTraceLimit = length;
539
- return stack;
552
+ const _prepareStackTrace = V8Error.prepareStackTrace;
553
+ try {
554
+ V8Error.stackTraceLimit = limit + realCallsToRemove;
555
+ // V8 only: accessing `.stack` invokes this and returns CallSite[]. Safari/Firefox ignore it.
556
+ V8Error.prepareStackTrace = (_, stack) => stack;
557
+ const rawStack = new Error().stack;
558
+ if (Array.isArray(rawStack)) {
559
+ return rawStack.slice(realCallsToRemove);
560
+ }
561
+ if (typeof rawStack === 'string' && rawStack.length > 0) {
562
+ return stackStringToFrames(rawStack, realCallsToRemove);
563
+ }
564
+ return [];
565
+ }
566
+ finally {
567
+ V8Error.prepareStackTrace = _prepareStackTrace;
568
+ V8Error.stackTraceLimit = length;
569
+ }
540
570
  }
541
571
  static prepareStackTrace(err, callSites) {
542
- if (typeof Error.prepareStackTrace === 'function') {
543
- return Error.prepareStackTrace(err, callSites);
544
- }
545
- // TODO: this is just a first iteration, we can make this "nicer" at some point
546
- // const EXCLUSIONS = ['IpcRenderer', 'Object.onMessage', 'Transport.onmessage', 'MessageReceiver.onmessage'];
547
- let stackTrace = `${err.name || 'Error'}: ${err.message || ''}\n`;
548
- stackTrace += callSites
549
- .map((line) => ` at ${line}`)
550
- // .filter((line) => !EXCLUSIONS.some((l) => line.includes(l)))
551
- .join('\n');
552
- return stackTrace;
572
+ const header = `${err.name || 'Error'}: ${err.message || ''}`;
573
+ const frames = typeof callSites === 'string' ? stackStringToFrames(callSites, 0) : callSites;
574
+ if (!Array.isArray(frames) || frames.length === 0) {
575
+ return header;
576
+ }
577
+ if (isCallSiteArray(frames)) {
578
+ const prepare = V8Error.prepareStackTrace;
579
+ // Only V8 CallSite[] may be passed to a user-supplied Error.prepareStackTrace.
580
+ if (typeof prepare === 'function') {
581
+ return prepare(err, frames);
582
+ }
583
+ // TODO: this is just a first iteration, we can make this "nicer" at some point
584
+ // const EXCLUSIONS = ['IpcRenderer', 'Object.onMessage', 'Transport.onmessage', 'MessageReceiver.onmessage'];
585
+ return `${header}\n${frames.map((line) => ` at ${line}`).join('\n')}`;
586
+ }
587
+ // Native Safari/Firefox frames already include their engine's format (`func@file:line:col`).
588
+ return `${header}\n${frames.join('\n')}`;
553
589
  }
554
590
  /*
555
591
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfin/core",
3
- "version": "45.100.113",
3
+ "version": "45.100.114",
4
4
  "description": "The core renderer entry point of OpenFin",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "main": "out/stub.js",