@openfin/core 45.100.113 → 45.100.115

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.
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
 
@@ -2478,6 +2514,47 @@ class Application extends EmitterBase {
2478
2514
  constructor(wire, identity) {
2479
2515
  super(wire, 'application', identity.uuid);
2480
2516
  this.identity = identity;
2517
+ /**
2518
+ * @experimental
2519
+ * Retrieves a performance snapshot for all Windows, Views and Frames in the Application.
2520
+ *
2521
+ * By default, all custom marks and measures are collected, along with navigation/paint entries
2522
+ * and resource timing (`resources` defaults to `true`). Pass `include` to restrict custom
2523
+ * marks/measures to matching names (string substring or RegExp). Pass `browser: true` to also
2524
+ * include hereio internal runtime metrics.
2525
+ *
2526
+ * See also [MDN | Performance Mark API](https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark)
2527
+ *
2528
+ * Note - only currently running WebContents will be captured, and performance entries can only be
2529
+ * captured for the current navigation of each.
2530
+ */
2531
+ this.getPerformanceStats = async (options = {}) => {
2532
+ /**
2533
+ * Returns a filter object compatible with JSON.stringify (regexs stringify to `{}`).
2534
+ * @param include Array of strings or regexps.
2535
+ */
2536
+ const getSerializableFilterObject = (include) => {
2537
+ return include.map((filter) => {
2538
+ if (filter instanceof RegExp) {
2539
+ return {
2540
+ type: 'regex',
2541
+ expression: filter.source,
2542
+ flags: filter.flags
2543
+ };
2544
+ }
2545
+ return filter;
2546
+ });
2547
+ };
2548
+ const { include, resources = true, browser = false } = options;
2549
+ const result = await this.wire.sendAction('get-application-performance-stats', {
2550
+ ...this.identity,
2551
+ // Omit `include` when unspecified so the runtime collects all custom marks/measures.
2552
+ ...(include !== undefined ? { include: getSerializableFilterObject(include) } : {}),
2553
+ resources,
2554
+ browser
2555
+ });
2556
+ return result.payload.data;
2557
+ };
2481
2558
  this.window = new _Window(this.wire, {
2482
2559
  uuid: this.identity.uuid,
2483
2560
  name: this.identity.uuid
@@ -13045,6 +13122,45 @@ class PrivateChannelProvider {
13045
13122
  }
13046
13123
  }
13047
13124
 
13125
+ /**
13126
+ * The default FDC3 user channels advertised by the Interop Broker.
13127
+ */
13128
+ const defaultColorChannels = {
13129
+ 'fdc3.channel.1': { name: 'Channel 1', color: 'red', glyph: '1' },
13130
+ 'fdc3.channel.2': { name: 'Channel 2', color: 'orange', glyph: '2' },
13131
+ 'fdc3.channel.3': { name: 'Channel 3', color: 'yellow', glyph: '3' },
13132
+ 'fdc3.channel.4': { name: 'Channel 4', color: 'green', glyph: '4' },
13133
+ 'fdc3.channel.5': { name: 'Channel 5', color: 'cyan', glyph: '5' },
13134
+ 'fdc3.channel.6': { name: 'Channel 6', color: 'blue', glyph: '6' },
13135
+ 'fdc3.channel.7': { name: 'Channel 7', color: 'magenta', glyph: '7' },
13136
+ 'fdc3.channel.8': { name: 'Channel 8', color: 'purple', glyph: '8' }
13137
+ };
13138
+ const legacyColorChannelIds = {
13139
+ red: 'fdc3.channel.1',
13140
+ orange: 'fdc3.channel.2',
13141
+ yellow: 'fdc3.channel.3',
13142
+ green: 'fdc3.channel.4',
13143
+ teal: 'fdc3.channel.5',
13144
+ blue: 'fdc3.channel.6',
13145
+ pink: 'fdc3.channel.7',
13146
+ // Legacy indigo (workspace) and purple (core) intentionally converge on the same FDC3 purple channel.
13147
+ indigo: 'fdc3.channel.8',
13148
+ purple: 'fdc3.channel.8'
13149
+ };
13150
+ /**
13151
+ * Converts a legacy color-named channel ID to its canonical FDC3 user-channel ID.
13152
+ * The removed legacy gray channel resolves to no channel.
13153
+ */
13154
+ function normalizeColorChannelId(colorChannelId) {
13155
+ if (colorChannelId === 'gray') {
13156
+ return undefined;
13157
+ }
13158
+ if (Object.prototype.hasOwnProperty.call(legacyColorChannelIds, colorChannelId)) {
13159
+ return legacyColorChannelIds[colorChannelId];
13160
+ }
13161
+ return colorChannelId;
13162
+ }
13163
+
13048
13164
  var __classPrivateFieldSet$9 = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
13049
13165
  if (kind === "m") throw new TypeError("Private method is not writable");
13050
13166
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
@@ -13057,50 +13173,7 @@ var __classPrivateFieldGet$9 = (undefined && undefined.__classPrivateFieldGet) |
13057
13173
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
13058
13174
  };
13059
13175
  var _InteropBroker_fdc3Info, _InteropBroker_contextGroups, _InteropBroker_providerPromise;
13060
- const defaultContextGroups = [
13061
- {
13062
- id: 'green',
13063
- displayMetadata: {
13064
- color: '#00CC88',
13065
- name: 'green'
13066
- }
13067
- },
13068
- {
13069
- id: 'purple',
13070
- displayMetadata: {
13071
- color: '#8C61FF',
13072
- name: 'purple'
13073
- }
13074
- },
13075
- {
13076
- id: 'orange',
13077
- displayMetadata: {
13078
- color: '#FF8C4C',
13079
- name: 'orange'
13080
- }
13081
- },
13082
- {
13083
- id: 'red',
13084
- displayMetadata: {
13085
- color: '#FF5E60',
13086
- name: 'red'
13087
- }
13088
- },
13089
- {
13090
- id: 'pink',
13091
- displayMetadata: {
13092
- color: '#FF8FB8',
13093
- name: 'pink'
13094
- }
13095
- },
13096
- {
13097
- id: 'yellow',
13098
- displayMetadata: {
13099
- color: '#E9FF8F',
13100
- name: 'yellow'
13101
- }
13102
- }
13103
- ];
13176
+ const defaultContextGroups = Object.entries(defaultColorChannels).map(([id, displayMetadata]) => ({ id, displayMetadata }));
13104
13177
  /**
13105
13178
  * {@link https://developers.openfin.co/of-docs/docs/enable-color-linking}
13106
13179
  *
@@ -13130,17 +13203,19 @@ const defaultContextGroups = [
13130
13203
  * "interopBrokerConfiguration": {
13131
13204
  * "contextGroups": [
13132
13205
  * {
13133
- * "id": "green",
13206
+ * "id": "fdc3.channel.4",
13134
13207
  * "displayMetadata": {
13135
- * "color": "#00CC88",
13136
- * "name": "green"
13208
+ * "color": "green",
13209
+ * "name": "Channel 4",
13210
+ * "glyph": "4"
13137
13211
  * }
13138
13212
  * },
13139
13213
  * {
13140
- * "id": "purple",
13214
+ * "id": "fdc3.channel.8",
13141
13215
  * "displayMetadata": {
13142
- * "color": "#8C61FF",
13143
- * "name": "purple"
13216
+ * "color": "purple",
13217
+ * "name": "Channel 8",
13218
+ * "glyph": "8"
13144
13219
  * }
13145
13220
  * },
13146
13221
  * ]
@@ -13303,9 +13378,13 @@ class InteropBroker extends Base {
13303
13378
  this.wire.sendAction('interop-broker-set-context-for-group').catch((e) => {
13304
13379
  // don't expose, analytics-only call
13305
13380
  });
13306
- const contextGroupState = this.contextGroupsById.get(contextGroupId);
13381
+ const normalizedContextGroupId = this.normalizeContextGroupId(contextGroupId);
13382
+ if (normalizedContextGroupId === undefined) {
13383
+ return;
13384
+ }
13385
+ const contextGroupState = this.contextGroupsById.get(normalizedContextGroupId);
13307
13386
  if (!contextGroupState) {
13308
- throw new Error(`Unable to set context for context group that isn't in the context group mapping: ${contextGroupId}.`);
13387
+ throw new Error(`Unable to set context for context group that isn't in the context group mapping: ${normalizedContextGroupId}.`);
13309
13388
  }
13310
13389
  const contextIntegrityCheckResult = InteropBroker.checkContextIntegrity(context);
13311
13390
  if (contextIntegrityCheckResult.isValid === false) {
@@ -13313,8 +13392,8 @@ class InteropBroker extends Base {
13313
13392
  }
13314
13393
  const broadcastedContextType = context.type;
13315
13394
  contextGroupState.set(broadcastedContextType, context);
13316
- this.lastContextMap.set(contextGroupId, broadcastedContextType);
13317
- const clientsInSameContextGroup = Array.from(this.interopClients.values()).filter((connectedClient) => connectedClient.contextGroupId === contextGroupId);
13395
+ this.lastContextMap.set(normalizedContextGroupId, broadcastedContextType);
13396
+ const clientsInSameContextGroup = Array.from(this.interopClients.values()).filter((connectedClient) => connectedClient.contextGroupId === normalizedContextGroupId);
13318
13397
  clientsInSameContextGroup.forEach((client) => {
13319
13398
  for (const [, handlerInfo] of client.contextHandlers) {
13320
13399
  if (InteropBroker.isContextTypeCompatible(broadcastedContextType, handlerInfo.contextType)) {
@@ -13360,10 +13439,20 @@ class InteropBroker extends Base {
13360
13439
  * @param joinContextGroupOptions - Id of the Context Group and identity of the entity to join to the group.
13361
13440
  * @param senderIdentity - Identity of the client sender.
13362
13441
  */
13363
- async joinContextGroup({ contextGroupId, target }, senderIdentity) {
13442
+ async joinContextGroup({ contextGroupId: requestedContextGroupId, target }, senderIdentity) {
13364
13443
  this.wire.sendAction('interop-broker-join-context-group').catch((e) => {
13365
13444
  // don't expose, analytics-only call
13366
13445
  });
13446
+ const contextGroupId = this.normalizeContextGroupId(requestedContextGroupId);
13447
+ if (contextGroupId === undefined) {
13448
+ if (target) {
13449
+ await this.removeFromContextGroup({ target }, senderIdentity);
13450
+ }
13451
+ else {
13452
+ await this.removeClientFromContextGroup(senderIdentity);
13453
+ }
13454
+ return;
13455
+ }
13367
13456
  if (this.sessionContextGroupMap.has(contextGroupId)) {
13368
13457
  throw new Error(BROKER_ERRORS.joinSessionContextGroupWithJoinContextGroup);
13369
13458
  }
@@ -13405,10 +13494,15 @@ class InteropBroker extends Base {
13405
13494
  * @param addClientToContextGroupOptions - Contains the contextGroupId
13406
13495
  * @param clientIdentity - Identity of the client sender.
13407
13496
  */
13408
- async addClientToContextGroup({ contextGroupId }, clientIdentity) {
13497
+ async addClientToContextGroup({ contextGroupId: requestedContextGroupId }, clientIdentity) {
13409
13498
  this.wire.sendAction('interop-broker-add-client-to-context-group').catch((e) => {
13410
13499
  // don't expose, analytics-only call
13411
13500
  });
13501
+ const contextGroupId = this.normalizeContextGroupId(requestedContextGroupId);
13502
+ if (contextGroupId === undefined) {
13503
+ await this.removeClientFromContextGroup(clientIdentity);
13504
+ return;
13505
+ }
13412
13506
  const clientSubscriptionState = this.getClientState(clientIdentity);
13413
13507
  if (!clientSubscriptionState) {
13414
13508
  throw new Error(`Client with Identity: ${clientIdentity.uuid} ${clientIdentity.name} not in Client State Map`);
@@ -13507,6 +13601,9 @@ class InteropBroker extends Base {
13507
13601
  clientState.contextGroupId = undefined;
13508
13602
  }
13509
13603
  await this.setCurrentContextGroupInClientOptions(clientIdentity, null);
13604
+ if (previousContextGroupId === undefined) {
13605
+ return;
13606
+ }
13510
13607
  // All settled will suppress uncaught exceptions. We don't want to await this because it could
13511
13608
  // result in the operation hanging.
13512
13609
  Promise.allSettled(this.channel.publish('client-changed-context-group', {
@@ -13544,7 +13641,11 @@ class InteropBroker extends Base {
13544
13641
  this.wire.sendAction('interop-broker-get-info-for-context-group').catch((e) => {
13545
13642
  // don't expose, analytics-only call
13546
13643
  });
13547
- return this.getContextGroups().find((contextGroup) => contextGroup.id === contextGroupId);
13644
+ const normalizedContextGroupId = this.normalizeContextGroupId(contextGroupId);
13645
+ if (normalizedContextGroupId === undefined) {
13646
+ return undefined;
13647
+ }
13648
+ return this.getContextGroups().find((contextGroup) => contextGroup.id === normalizedContextGroupId);
13548
13649
  }
13549
13650
  // Used by platform windows to get all clients for a context group.
13550
13651
  /**
@@ -13560,8 +13661,12 @@ class InteropBroker extends Base {
13560
13661
  this.wire.sendAction('interop-broker-get-all-clients-in-context-group').catch((e) => {
13561
13662
  // don't expose, analytics-only call
13562
13663
  });
13664
+ const normalizedContextGroupId = this.normalizeContextGroupId(contextGroupId);
13665
+ if (normalizedContextGroupId === undefined) {
13666
+ return [];
13667
+ }
13563
13668
  const clientsInContextGroup = Array.from(this.interopClients.values())
13564
- .filter((connectedClient) => connectedClient.contextGroupId === contextGroupId)
13669
+ .filter((connectedClient) => connectedClient.contextGroupId === normalizedContextGroupId)
13565
13670
  .map((subscriptionState) => {
13566
13671
  return subscriptionState.clientIdentity;
13567
13672
  });
@@ -14008,8 +14113,9 @@ class InteropBroker extends Base {
14008
14113
  }
14009
14114
  // Used to restore interop broker state in snapshots.
14010
14115
  applySnapshot(snapshot, options) {
14011
- const contextGroupStates = snapshot?.interopSnapshotDetails?.contextGroupStates;
14012
- if (contextGroupStates) {
14116
+ const incomingContextGroupStates = snapshot?.interopSnapshotDetails?.contextGroupStates;
14117
+ if (incomingContextGroupStates) {
14118
+ const contextGroupStates = this.normalizeContextGroupStates(incomingContextGroupStates);
14013
14119
  if (!options?.closeExistingWindows) {
14014
14120
  this.updateExistingClients(contextGroupStates);
14015
14121
  }
@@ -14154,6 +14260,23 @@ class InteropBroker extends Base {
14154
14260
  });
14155
14261
  return newObject;
14156
14262
  }
14263
+ normalizeContextGroupStates(incomingContextGroupStates) {
14264
+ const normalizedContextGroupStates = {};
14265
+ for (const [contextGroupId, contexts] of Object.entries(incomingContextGroupStates)) {
14266
+ const normalizedContextGroupId = this.normalizeContextGroupId(contextGroupId);
14267
+ if (normalizedContextGroupId !== undefined) {
14268
+ normalizedContextGroupStates[normalizedContextGroupId] = {
14269
+ ...normalizedContextGroupStates[normalizedContextGroupId],
14270
+ ...contexts
14271
+ };
14272
+ }
14273
+ }
14274
+ return normalizedContextGroupStates;
14275
+ }
14276
+ normalizeContextGroupId(contextGroupId) {
14277
+ const usesDefaultColorChannels = Object.keys(defaultColorChannels).every((defaultContextGroupId) => this.contextGroupsById.has(defaultContextGroupId));
14278
+ return usesDefaultColorChannels ? normalizeColorChannelId(contextGroupId) : contextGroupId;
14279
+ }
14157
14280
  // Util to check a client identity.
14158
14281
  static hasEndpointId(target) {
14159
14282
  return target.endpointId !== undefined;
@@ -14217,8 +14340,14 @@ class InteropBroker extends Base {
14217
14340
  clientIdentity
14218
14341
  };
14219
14342
  // Only allow the client to join a contextGroup that actually exists.
14220
- if (payload?.currentContextGroup && this.contextGroupsById.has(payload.currentContextGroup)) {
14221
- clientSubscriptionState.contextGroupId = payload?.currentContextGroup;
14343
+ const currentContextGroup = payload?.currentContextGroup
14344
+ ? this.normalizeContextGroupId(payload.currentContextGroup)
14345
+ : undefined;
14346
+ if (currentContextGroup && this.contextGroupsById.has(currentContextGroup)) {
14347
+ clientSubscriptionState.contextGroupId = currentContextGroup;
14348
+ if (currentContextGroup !== payload.currentContextGroup) {
14349
+ await this.setCurrentContextGroupInClientOptions(clientIdentity, currentContextGroup);
14350
+ }
14222
14351
  }
14223
14352
  this.interopClients.set(clientIdentity.endpointId, clientSubscriptionState);
14224
14353
  });
@@ -14788,7 +14917,7 @@ class InteropClient extends Base {
14788
14917
  *
14789
14918
  * getLastFocusedView()
14790
14919
  * .then(lastFocusedViewIdentity => {
14791
- * joinViewToContextGroup('red', lastFocusedViewIdentity)
14920
+ * joinViewToContextGroup('fdc3.channel.1', lastFocusedViewIdentity)
14792
14921
  * })
14793
14922
  * ```
14794
14923
  */
@@ -14838,7 +14967,7 @@ class InteropClient extends Base {
14838
14967
  *
14839
14968
  * @example
14840
14969
  * ```js
14841
- * fin.me.interop.getAllClientsInContextGroup('red')
14970
+ * fin.me.interop.getAllClientsInContextGroup('fdc3.channel.1')
14842
14971
  * .then(clientsInContextGroup => {
14843
14972
  * console.log(clientsInContextGroup)
14844
14973
  * })
@@ -14862,7 +14991,7 @@ class InteropClient extends Base {
14862
14991
  *
14863
14992
  * @example
14864
14993
  * ```js
14865
- * fin.me.interop.getInfoForContextGroup('red')
14994
+ * fin.me.interop.getInfoForContextGroup('fdc3.channel.1')
14866
14995
  * .then(contextGroupInfo => {
14867
14996
  * console.log(contextGroupInfo.displayMetadata.name)
14868
14997
  * console.log(contextGroupInfo.displayMetadata.color)
@@ -14951,12 +15080,12 @@ class InteropClient extends Base {
14951
15080
  *
14952
15081
  * @example
14953
15082
  * ```js
14954
- * await fin.me.interop.joinContextGroup('yellow');
15083
+ * await fin.me.interop.joinContextGroup('fdc3.channel.3');
14955
15084
  * await fin.me.interop.setContext({ type: 'instrument', id: { ticker: 'FOO' }});
14956
15085
  * const currentContext = await fin.me.interop.getCurrentContext();
14957
15086
  *
14958
15087
  * // with a specific context
14959
- * await fin.me.interop.joinContextGroup('yellow');
15088
+ * await fin.me.interop.joinContextGroup('fdc3.channel.3');
14960
15089
  * await fin.me.interop.setContext({ type: 'country', id: { ISOALPHA3: 'US' }});
14961
15090
  * await fin.me.interop.setContext({ type: 'instrument', id: { ticker: 'FOO' }});
14962
15091
  * const currentContext = await fin.me.interop.getCurrentContext('country');
@@ -15618,15 +15747,18 @@ class FDC3ModuleBase {
15618
15747
  async joinChannel(channelId) {
15619
15748
  this.wire.recordAnalytic('fdc3-join-channel');
15620
15749
  try {
15750
+ const contextGroup = await this.client.getInfoForContextGroup(channelId);
15751
+ if (!contextGroup) {
15752
+ console.error(`No User Channel was found with the ID "${channelId}". If this is an App Channel, use getOrCreateChannel instead.`);
15753
+ throw new Error(ChannelError.NoChannelFound);
15754
+ }
15621
15755
  return await this.client.joinContextGroup(channelId);
15622
15756
  }
15623
15757
  catch (error) {
15624
- if (error.message === BROKER_ERRORS.joinSessionContextGroupWithJoinContextGroup) {
15625
- console.error('The Channel you have tried to join is an App Channel. Custom Channels can only be defined by the Interop Broker through code or manifest configuration. Please use getOrCreateChannel.');
15626
- }
15627
- else {
15628
- console.error(error.message);
15758
+ if (error.message === ChannelError.NoChannelFound) {
15759
+ throw new Error(ChannelError.NoChannelFound);
15629
15760
  }
15761
+ console.error(error.message);
15630
15762
  if (error.message.startsWith('Attempting to join a context group that does not exist')) {
15631
15763
  throw new Error(ChannelError.NoChannelFound);
15632
15764
  }
@@ -16306,7 +16438,7 @@ class InteropModule extends Base {
16306
16438
  * @example
16307
16439
  * ```js
16308
16440
  * const interopConfig = {
16309
- * currentContextGroup: 'green'
16441
+ * currentContextGroup: 'fdc3.channel.4'
16310
16442
  * }
16311
16443
  *
16312
16444
  * const interopBroker = await fin.Interop.init('openfin');
@@ -17311,4 +17443,4 @@ const fin$1 = ((typeof window !== 'undefined' && window?.fin) ||
17311
17443
  return new Fin(transport);
17312
17444
  })());
17313
17445
 
17314
- export { OpenFin, OpenFin as default, fin$1 as fin };
17446
+ export { OpenFin, OpenFin as default, defaultColorChannels, fin$1 as fin, normalizeColorChannelId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfin/core",
3
- "version": "45.100.113",
3
+ "version": "45.100.115",
4
4
  "description": "The core renderer entry point of OpenFin",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "main": "out/stub.js",
@@ -34,7 +34,7 @@
34
34
  "@types/node": "^20.14.2",
35
35
  "events": "^3.0.0",
36
36
  "es-toolkit": "^1.39.3",
37
- "ws": "^7.5.10",
37
+ "ws": "^7.5.11",
38
38
  "tslib": "2.8.1"
39
39
  },
40
40
  "scripts": {