@openfin/core 45.100.114 → 45.100.116

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
@@ -2514,6 +2514,47 @@ class Application extends EmitterBase {
2514
2514
  constructor(wire, identity) {
2515
2515
  super(wire, 'application', identity.uuid);
2516
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
+ };
2517
2558
  this.window = new _Window(this.wire, {
2518
2559
  uuid: this.identity.uuid,
2519
2560
  name: this.identity.uuid
@@ -13081,6 +13122,45 @@ class PrivateChannelProvider {
13081
13122
  }
13082
13123
  }
13083
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
+
13084
13164
  var __classPrivateFieldSet$9 = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
13085
13165
  if (kind === "m") throw new TypeError("Private method is not writable");
13086
13166
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
@@ -13093,50 +13173,7 @@ var __classPrivateFieldGet$9 = (undefined && undefined.__classPrivateFieldGet) |
13093
13173
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
13094
13174
  };
13095
13175
  var _InteropBroker_fdc3Info, _InteropBroker_contextGroups, _InteropBroker_providerPromise;
13096
- const defaultContextGroups = [
13097
- {
13098
- id: 'green',
13099
- displayMetadata: {
13100
- color: '#00CC88',
13101
- name: 'green'
13102
- }
13103
- },
13104
- {
13105
- id: 'purple',
13106
- displayMetadata: {
13107
- color: '#8C61FF',
13108
- name: 'purple'
13109
- }
13110
- },
13111
- {
13112
- id: 'orange',
13113
- displayMetadata: {
13114
- color: '#FF8C4C',
13115
- name: 'orange'
13116
- }
13117
- },
13118
- {
13119
- id: 'red',
13120
- displayMetadata: {
13121
- color: '#FF5E60',
13122
- name: 'red'
13123
- }
13124
- },
13125
- {
13126
- id: 'pink',
13127
- displayMetadata: {
13128
- color: '#FF8FB8',
13129
- name: 'pink'
13130
- }
13131
- },
13132
- {
13133
- id: 'yellow',
13134
- displayMetadata: {
13135
- color: '#E9FF8F',
13136
- name: 'yellow'
13137
- }
13138
- }
13139
- ];
13176
+ const defaultContextGroups = Object.entries(defaultColorChannels).map(([id, displayMetadata]) => ({ id, displayMetadata }));
13140
13177
  /**
13141
13178
  * {@link https://developers.openfin.co/of-docs/docs/enable-color-linking}
13142
13179
  *
@@ -13166,17 +13203,19 @@ const defaultContextGroups = [
13166
13203
  * "interopBrokerConfiguration": {
13167
13204
  * "contextGroups": [
13168
13205
  * {
13169
- * "id": "green",
13206
+ * "id": "fdc3.channel.4",
13170
13207
  * "displayMetadata": {
13171
- * "color": "#00CC88",
13172
- * "name": "green"
13208
+ * "color": "green",
13209
+ * "name": "Channel 4",
13210
+ * "glyph": "4"
13173
13211
  * }
13174
13212
  * },
13175
13213
  * {
13176
- * "id": "purple",
13214
+ * "id": "fdc3.channel.8",
13177
13215
  * "displayMetadata": {
13178
- * "color": "#8C61FF",
13179
- * "name": "purple"
13216
+ * "color": "purple",
13217
+ * "name": "Channel 8",
13218
+ * "glyph": "8"
13180
13219
  * }
13181
13220
  * },
13182
13221
  * ]
@@ -13339,9 +13378,13 @@ class InteropBroker extends Base {
13339
13378
  this.wire.sendAction('interop-broker-set-context-for-group').catch((e) => {
13340
13379
  // don't expose, analytics-only call
13341
13380
  });
13342
- 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);
13343
13386
  if (!contextGroupState) {
13344
- 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}.`);
13345
13388
  }
13346
13389
  const contextIntegrityCheckResult = InteropBroker.checkContextIntegrity(context);
13347
13390
  if (contextIntegrityCheckResult.isValid === false) {
@@ -13349,8 +13392,8 @@ class InteropBroker extends Base {
13349
13392
  }
13350
13393
  const broadcastedContextType = context.type;
13351
13394
  contextGroupState.set(broadcastedContextType, context);
13352
- this.lastContextMap.set(contextGroupId, broadcastedContextType);
13353
- 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);
13354
13397
  clientsInSameContextGroup.forEach((client) => {
13355
13398
  for (const [, handlerInfo] of client.contextHandlers) {
13356
13399
  if (InteropBroker.isContextTypeCompatible(broadcastedContextType, handlerInfo.contextType)) {
@@ -13396,10 +13439,20 @@ class InteropBroker extends Base {
13396
13439
  * @param joinContextGroupOptions - Id of the Context Group and identity of the entity to join to the group.
13397
13440
  * @param senderIdentity - Identity of the client sender.
13398
13441
  */
13399
- async joinContextGroup({ contextGroupId, target }, senderIdentity) {
13442
+ async joinContextGroup({ contextGroupId: requestedContextGroupId, target }, senderIdentity) {
13400
13443
  this.wire.sendAction('interop-broker-join-context-group').catch((e) => {
13401
13444
  // don't expose, analytics-only call
13402
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
+ }
13403
13456
  if (this.sessionContextGroupMap.has(contextGroupId)) {
13404
13457
  throw new Error(BROKER_ERRORS.joinSessionContextGroupWithJoinContextGroup);
13405
13458
  }
@@ -13441,10 +13494,15 @@ class InteropBroker extends Base {
13441
13494
  * @param addClientToContextGroupOptions - Contains the contextGroupId
13442
13495
  * @param clientIdentity - Identity of the client sender.
13443
13496
  */
13444
- async addClientToContextGroup({ contextGroupId }, clientIdentity) {
13497
+ async addClientToContextGroup({ contextGroupId: requestedContextGroupId }, clientIdentity) {
13445
13498
  this.wire.sendAction('interop-broker-add-client-to-context-group').catch((e) => {
13446
13499
  // don't expose, analytics-only call
13447
13500
  });
13501
+ const contextGroupId = this.normalizeContextGroupId(requestedContextGroupId);
13502
+ if (contextGroupId === undefined) {
13503
+ await this.removeClientFromContextGroup(clientIdentity);
13504
+ return;
13505
+ }
13448
13506
  const clientSubscriptionState = this.getClientState(clientIdentity);
13449
13507
  if (!clientSubscriptionState) {
13450
13508
  throw new Error(`Client with Identity: ${clientIdentity.uuid} ${clientIdentity.name} not in Client State Map`);
@@ -13543,6 +13601,9 @@ class InteropBroker extends Base {
13543
13601
  clientState.contextGroupId = undefined;
13544
13602
  }
13545
13603
  await this.setCurrentContextGroupInClientOptions(clientIdentity, null);
13604
+ if (previousContextGroupId === undefined) {
13605
+ return;
13606
+ }
13546
13607
  // All settled will suppress uncaught exceptions. We don't want to await this because it could
13547
13608
  // result in the operation hanging.
13548
13609
  Promise.allSettled(this.channel.publish('client-changed-context-group', {
@@ -13580,7 +13641,11 @@ class InteropBroker extends Base {
13580
13641
  this.wire.sendAction('interop-broker-get-info-for-context-group').catch((e) => {
13581
13642
  // don't expose, analytics-only call
13582
13643
  });
13583
- 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);
13584
13649
  }
13585
13650
  // Used by platform windows to get all clients for a context group.
13586
13651
  /**
@@ -13596,8 +13661,12 @@ class InteropBroker extends Base {
13596
13661
  this.wire.sendAction('interop-broker-get-all-clients-in-context-group').catch((e) => {
13597
13662
  // don't expose, analytics-only call
13598
13663
  });
13664
+ const normalizedContextGroupId = this.normalizeContextGroupId(contextGroupId);
13665
+ if (normalizedContextGroupId === undefined) {
13666
+ return [];
13667
+ }
13599
13668
  const clientsInContextGroup = Array.from(this.interopClients.values())
13600
- .filter((connectedClient) => connectedClient.contextGroupId === contextGroupId)
13669
+ .filter((connectedClient) => connectedClient.contextGroupId === normalizedContextGroupId)
13601
13670
  .map((subscriptionState) => {
13602
13671
  return subscriptionState.clientIdentity;
13603
13672
  });
@@ -14044,8 +14113,9 @@ class InteropBroker extends Base {
14044
14113
  }
14045
14114
  // Used to restore interop broker state in snapshots.
14046
14115
  applySnapshot(snapshot, options) {
14047
- const contextGroupStates = snapshot?.interopSnapshotDetails?.contextGroupStates;
14048
- if (contextGroupStates) {
14116
+ const incomingContextGroupStates = snapshot?.interopSnapshotDetails?.contextGroupStates;
14117
+ if (incomingContextGroupStates) {
14118
+ const contextGroupStates = this.normalizeContextGroupStates(incomingContextGroupStates);
14049
14119
  if (!options?.closeExistingWindows) {
14050
14120
  this.updateExistingClients(contextGroupStates);
14051
14121
  }
@@ -14190,6 +14260,23 @@ class InteropBroker extends Base {
14190
14260
  });
14191
14261
  return newObject;
14192
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
+ }
14193
14280
  // Util to check a client identity.
14194
14281
  static hasEndpointId(target) {
14195
14282
  return target.endpointId !== undefined;
@@ -14253,8 +14340,14 @@ class InteropBroker extends Base {
14253
14340
  clientIdentity
14254
14341
  };
14255
14342
  // Only allow the client to join a contextGroup that actually exists.
14256
- if (payload?.currentContextGroup && this.contextGroupsById.has(payload.currentContextGroup)) {
14257
- 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
+ }
14258
14351
  }
14259
14352
  this.interopClients.set(clientIdentity.endpointId, clientSubscriptionState);
14260
14353
  });
@@ -14824,7 +14917,7 @@ class InteropClient extends Base {
14824
14917
  *
14825
14918
  * getLastFocusedView()
14826
14919
  * .then(lastFocusedViewIdentity => {
14827
- * joinViewToContextGroup('red', lastFocusedViewIdentity)
14920
+ * joinViewToContextGroup('fdc3.channel.1', lastFocusedViewIdentity)
14828
14921
  * })
14829
14922
  * ```
14830
14923
  */
@@ -14874,7 +14967,7 @@ class InteropClient extends Base {
14874
14967
  *
14875
14968
  * @example
14876
14969
  * ```js
14877
- * fin.me.interop.getAllClientsInContextGroup('red')
14970
+ * fin.me.interop.getAllClientsInContextGroup('fdc3.channel.1')
14878
14971
  * .then(clientsInContextGroup => {
14879
14972
  * console.log(clientsInContextGroup)
14880
14973
  * })
@@ -14898,7 +14991,7 @@ class InteropClient extends Base {
14898
14991
  *
14899
14992
  * @example
14900
14993
  * ```js
14901
- * fin.me.interop.getInfoForContextGroup('red')
14994
+ * fin.me.interop.getInfoForContextGroup('fdc3.channel.1')
14902
14995
  * .then(contextGroupInfo => {
14903
14996
  * console.log(contextGroupInfo.displayMetadata.name)
14904
14997
  * console.log(contextGroupInfo.displayMetadata.color)
@@ -14987,12 +15080,12 @@ class InteropClient extends Base {
14987
15080
  *
14988
15081
  * @example
14989
15082
  * ```js
14990
- * await fin.me.interop.joinContextGroup('yellow');
15083
+ * await fin.me.interop.joinContextGroup('fdc3.channel.3');
14991
15084
  * await fin.me.interop.setContext({ type: 'instrument', id: { ticker: 'FOO' }});
14992
15085
  * const currentContext = await fin.me.interop.getCurrentContext();
14993
15086
  *
14994
15087
  * // with a specific context
14995
- * await fin.me.interop.joinContextGroup('yellow');
15088
+ * await fin.me.interop.joinContextGroup('fdc3.channel.3');
14996
15089
  * await fin.me.interop.setContext({ type: 'country', id: { ISOALPHA3: 'US' }});
14997
15090
  * await fin.me.interop.setContext({ type: 'instrument', id: { ticker: 'FOO' }});
14998
15091
  * const currentContext = await fin.me.interop.getCurrentContext('country');
@@ -15654,15 +15747,18 @@ class FDC3ModuleBase {
15654
15747
  async joinChannel(channelId) {
15655
15748
  this.wire.recordAnalytic('fdc3-join-channel');
15656
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
+ }
15657
15755
  return await this.client.joinContextGroup(channelId);
15658
15756
  }
15659
15757
  catch (error) {
15660
- if (error.message === BROKER_ERRORS.joinSessionContextGroupWithJoinContextGroup) {
15661
- 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.');
15662
- }
15663
- else {
15664
- console.error(error.message);
15758
+ if (error.message === ChannelError.NoChannelFound) {
15759
+ throw new Error(ChannelError.NoChannelFound);
15665
15760
  }
15761
+ console.error(error.message);
15666
15762
  if (error.message.startsWith('Attempting to join a context group that does not exist')) {
15667
15763
  throw new Error(ChannelError.NoChannelFound);
15668
15764
  }
@@ -16342,7 +16438,7 @@ class InteropModule extends Base {
16342
16438
  * @example
16343
16439
  * ```js
16344
16440
  * const interopConfig = {
16345
- * currentContextGroup: 'green'
16441
+ * currentContextGroup: 'fdc3.channel.4'
16346
16442
  * }
16347
16443
  *
16348
16444
  * const interopBroker = await fin.Interop.init('openfin');
@@ -17347,4 +17443,4 @@ const fin$1 = ((typeof window !== 'undefined' && window?.fin) ||
17347
17443
  return new Fin(transport);
17348
17444
  })());
17349
17445
 
17350
- 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.114",
3
+ "version": "45.100.116",
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": {