@openfin/node-adapter 47.100.26 → 47.100.29
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/node-adapter.js +276 -119
- package/package.json +2 -2
package/out/node-adapter.js
CHANGED
|
@@ -7571,19 +7571,39 @@ let ChannelError$1 = class ChannelError extends Error {
|
|
|
7571
7571
|
}
|
|
7572
7572
|
};
|
|
7573
7573
|
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7574
|
+
/**
|
|
7575
|
+
* Tracks live channel clients by their current endpoint id and routes runtime lifecycle events to them.
|
|
7576
|
+
*/
|
|
7577
|
+
class ChannelClientStore {
|
|
7578
|
+
// The provider for a channel has gone away: every client on that channel is disconnected.
|
|
7579
|
+
static handleProviderDisconnect(eventPayload) {
|
|
7580
|
+
[...ChannelClientStore.clients.values()].forEach((client) => {
|
|
7581
|
+
if (client.providerIdentity.channelId === eventPayload.channelId) {
|
|
7582
|
+
client[teardown](true, false);
|
|
7583
|
+
}
|
|
7584
|
+
});
|
|
7585
|
+
}
|
|
7586
|
+
// Old providers omit endpoint ids, so a new connection silently replaces the previous client on the channel.
|
|
7587
|
+
static handleEndpointDisconnect(endpointId) {
|
|
7588
|
+
ChannelClientStore.clients.get(endpointId)?.[teardown](false, false);
|
|
7589
|
+
}
|
|
7590
|
+
}
|
|
7591
|
+
ChannelClientStore.clients = new Map();
|
|
7592
|
+
|
|
7579
7593
|
var __classPrivateFieldSet$j = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7580
7594
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
7581
7595
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
7582
7596
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
7583
7597
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7584
7598
|
};
|
|
7585
|
-
var
|
|
7586
|
-
|
|
7599
|
+
var __classPrivateFieldGet$k = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
7600
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
7601
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
7602
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
7603
|
+
};
|
|
7604
|
+
var _ChannelClient_currentConnection, _ChannelClient_state, _ChannelClient_wire, _ChannelClient_reestablish, _ChannelClient_unsubscribeBFCache, _ChannelClient_disconnectListener, _ChannelClient_reconnectListener, _ChannelClient_releaseConnection, _ChannelClient_attach, _ChannelClient_sendDisconnectToRuntime, _ChannelClient_reconnect;
|
|
7605
|
+
// Key for ChannelClient's internal teardown function. Prevents the need to expose internal functions.
|
|
7606
|
+
const teardown = Symbol('teardown');
|
|
7587
7607
|
/**
|
|
7588
7608
|
* Instance created to enable use of a channel as a client. Allows for communication with the
|
|
7589
7609
|
* {@link ChannelProvider ChannelProvider} by invoking an action on the
|
|
@@ -7612,50 +7632,135 @@ class ChannelClient extends ChannelBase {
|
|
|
7612
7632
|
/**
|
|
7613
7633
|
* @internal
|
|
7614
7634
|
*/
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7635
|
+
constructor(config) {
|
|
7636
|
+
super();
|
|
7637
|
+
_ChannelClient_currentConnection.set(this, void 0);
|
|
7638
|
+
_ChannelClient_state.set(this, { status: 'connected' });
|
|
7639
|
+
_ChannelClient_wire.set(this, void 0);
|
|
7640
|
+
_ChannelClient_reestablish.set(this, void 0);
|
|
7641
|
+
_ChannelClient_unsubscribeBFCache.set(this, void 0);
|
|
7642
|
+
_ChannelClient_disconnectListener.set(this, void 0);
|
|
7643
|
+
_ChannelClient_reconnectListener.set(this, void 0);
|
|
7644
|
+
// needs to be bound;
|
|
7645
|
+
this.processAction = (action, payload, senderIdentity) => super.processAction(action, payload, senderIdentity);
|
|
7646
|
+
_ChannelClient_releaseConnection.set(this, async (connection, notifyRuntime) => {
|
|
7647
|
+
connection.strategy.close().catch(() => undefined);
|
|
7648
|
+
if (notifyRuntime) {
|
|
7649
|
+
await __classPrivateFieldGet$k(this, _ChannelClient_sendDisconnectToRuntime, "f").call(this, connection);
|
|
7650
|
+
}
|
|
7651
|
+
});
|
|
7652
|
+
_ChannelClient_attach.set(this, (instance) => {
|
|
7653
|
+
ChannelClientStore.clients.set(instance.routingInfo.endpointId, this);
|
|
7654
|
+
instance.strategy.receive(this.processAction);
|
|
7655
|
+
instance.strategy.onEndpointDisconnect(instance.routingInfo.channelId, () => {
|
|
7656
|
+
// Only a drop of the live endpoint disconnects. During a self-heal the endpoint is already being replaced
|
|
7657
|
+
// and the handshake decides the outcome; after it, closing the replaced strategy (RTC/combined fire this on
|
|
7658
|
+
// close) must not tear down the client now live on a fresh endpoint.
|
|
7659
|
+
if (__classPrivateFieldGet$k(this, _ChannelClient_currentConnection, "f") === instance && __classPrivateFieldGet$k(this, _ChannelClient_state, "f").status === 'connected') {
|
|
7660
|
+
this[teardown](true).catch((error) => {
|
|
7661
|
+
// eslint-disable-next-line no-console
|
|
7662
|
+
console.warn(`Failed to notify the runtime that channel '${instance.routingInfo.channelName}' endpoint ${instance.routingInfo.endpointId} disconnected.`, error);
|
|
7663
|
+
});
|
|
7664
|
+
}
|
|
7665
|
+
});
|
|
7666
|
+
});
|
|
7667
|
+
_ChannelClient_sendDisconnectToRuntime.set(this, async ({ routingInfo }) => {
|
|
7668
|
+
const { channelName, uuid, name, endpointId } = routingInfo;
|
|
7669
|
+
await __classPrivateFieldGet$k(this, _ChannelClient_wire, "f").sendAction('disconnect-from-channel', { channelName, uuid, name, endpointId });
|
|
7670
|
+
});
|
|
7671
|
+
// Re-handshakes (new endpointId) and swaps in the fresh endpoint. Client-side registrations and middleware live
|
|
7672
|
+
// on `this` (ChannelBase), so they carry over. Overlapping BF-Cache restores share one in-flight handshake.
|
|
7673
|
+
_ChannelClient_reconnect.set(this, async () => {
|
|
7674
|
+
if (__classPrivateFieldGet$k(this, _ChannelClient_state, "f").status === 'connected') {
|
|
7675
|
+
const performReconnect = async () => {
|
|
7676
|
+
let next;
|
|
7677
|
+
try {
|
|
7678
|
+
next = await __classPrivateFieldGet$k(this, _ChannelClient_reestablish, "f").call(this);
|
|
7679
|
+
}
|
|
7680
|
+
catch (error) {
|
|
7681
|
+
// No automatic retry: recovery is up to the onDisconnection handler.
|
|
7682
|
+
// eslint-disable-next-line no-console
|
|
7683
|
+
console.warn(`Channel '${__classPrivateFieldGet$k(this, _ChannelClient_currentConnection, "f").routingInfo.channelName}' failed to self-heal after BF-Cache restoration; disconnecting.`, error);
|
|
7684
|
+
await this[teardown](true).catch((disconnectError) => {
|
|
7685
|
+
// eslint-disable-next-line no-console
|
|
7686
|
+
console.warn(`Failed to notify the runtime that channel '${__classPrivateFieldGet$k(this, _ChannelClient_currentConnection, "f").routingInfo.channelName}' disconnected.`, disconnectError);
|
|
7687
|
+
});
|
|
7688
|
+
return;
|
|
7689
|
+
}
|
|
7690
|
+
// A disconnect() or provider disconnect may have landed while the handshake was in flight; if so,
|
|
7691
|
+
// tear down the freshly established endpoint instead of resurrecting a closed client.
|
|
7692
|
+
if (__classPrivateFieldGet$k(this, _ChannelClient_state, "f").status !== 'reconnecting') {
|
|
7693
|
+
__classPrivateFieldGet$k(this, _ChannelClient_releaseConnection, "f").call(this, next, true).catch(() => undefined);
|
|
7694
|
+
return;
|
|
7695
|
+
}
|
|
7696
|
+
const previous = __classPrivateFieldGet$k(this, _ChannelClient_currentConnection, "f");
|
|
7697
|
+
__classPrivateFieldSet$j(this, _ChannelClient_currentConnection, next, "f");
|
|
7698
|
+
__classPrivateFieldGet$k(this, _ChannelClient_attach, "f").call(this, next);
|
|
7699
|
+
__classPrivateFieldSet$j(this, _ChannelClient_state, { status: 'connected' }, "f");
|
|
7700
|
+
// A throwing listener must not abort the reconnect.
|
|
7701
|
+
try {
|
|
7702
|
+
__classPrivateFieldGet$k(this, _ChannelClient_reconnectListener, "f")?.call(this, {
|
|
7703
|
+
providerIdentity: this.providerIdentity,
|
|
7704
|
+
previousEndpointId: previous.routingInfo.endpointId,
|
|
7705
|
+
endpointId: next.routingInfo.endpointId
|
|
7706
|
+
});
|
|
7707
|
+
}
|
|
7708
|
+
catch (error) {
|
|
7709
|
+
// eslint-disable-next-line no-console
|
|
7710
|
+
console.warn(`An unexpected error occurred in a Channel Client Reconnection handler for channel ${next.routingInfo.channelName}`, error);
|
|
7711
|
+
}
|
|
7712
|
+
// The old endpoint is typically already gone (navigation); closing is best-effort cleanup.
|
|
7713
|
+
__classPrivateFieldGet$k(this, _ChannelClient_releaseConnection, "f").call(this, previous, false).catch(() => undefined);
|
|
7714
|
+
};
|
|
7715
|
+
// The endpoint is being replaced: against old providers the handshake supersedes it by id, which must
|
|
7716
|
+
// not close the reconnecting client.
|
|
7717
|
+
ChannelClientStore.clients.delete(__classPrivateFieldGet$k(this, _ChannelClient_currentConnection, "f").routingInfo.endpointId);
|
|
7718
|
+
const reconnectPromise = performReconnect();
|
|
7719
|
+
__classPrivateFieldSet$j(this, _ChannelClient_state, { status: 'reconnecting', waitForReconnection: () => reconnectPromise }, "f");
|
|
7720
|
+
}
|
|
7721
|
+
if (__classPrivateFieldGet$k(this, _ChannelClient_state, "f").status === 'reconnecting') {
|
|
7722
|
+
await __classPrivateFieldGet$k(this, _ChannelClient_state, "f").waitForReconnection();
|
|
7723
|
+
}
|
|
7724
|
+
});
|
|
7725
|
+
__classPrivateFieldSet$j(this, _ChannelClient_currentConnection, config.initialConnection, "f");
|
|
7726
|
+
__classPrivateFieldSet$j(this, _ChannelClient_wire, config.wire, "f");
|
|
7727
|
+
__classPrivateFieldSet$j(this, _ChannelClient_reestablish, config.reestablish, "f");
|
|
7728
|
+
__classPrivateFieldSet$j(this, _ChannelClient_unsubscribeBFCache, __classPrivateFieldGet$k(this, _ChannelClient_wire, "f").environment.onBFCacheRestore(__classPrivateFieldGet$k(this, _ChannelClient_reconnect, "f")), "f");
|
|
7729
|
+
__classPrivateFieldGet$k(this, _ChannelClient_attach, "f").call(this, config.initialConnection);
|
|
7620
7730
|
}
|
|
7621
7731
|
/**
|
|
7622
7732
|
* @internal
|
|
7623
|
-
*
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7733
|
+
* Closes the client. `notifyRuntime` sends `disconnect-from-channel` for the current endpoint; `emitEvent` then
|
|
7734
|
+
* fires the onDisconnection listener, even if notifying the runtime failed.
|
|
7735
|
+
*/
|
|
7736
|
+
async [(_ChannelClient_currentConnection = new WeakMap(), _ChannelClient_state = new WeakMap(), _ChannelClient_wire = new WeakMap(), _ChannelClient_reestablish = new WeakMap(), _ChannelClient_unsubscribeBFCache = new WeakMap(), _ChannelClient_disconnectListener = new WeakMap(), _ChannelClient_reconnectListener = new WeakMap(), _ChannelClient_releaseConnection = new WeakMap(), _ChannelClient_attach = new WeakMap(), _ChannelClient_sendDisconnectToRuntime = new WeakMap(), _ChannelClient_reconnect = new WeakMap(), teardown)](emitEvent = false, notifyRuntime = true) {
|
|
7737
|
+
if (__classPrivateFieldGet$k(this, _ChannelClient_state, "f").status !== 'closed') {
|
|
7738
|
+
const identity = this.providerIdentity;
|
|
7739
|
+
const connection = __classPrivateFieldGet$k(this, _ChannelClient_currentConnection, "f");
|
|
7740
|
+
__classPrivateFieldSet$j(this, _ChannelClient_state, { status: 'closed' }, "f");
|
|
7741
|
+
__classPrivateFieldGet$k(this, _ChannelClient_unsubscribeBFCache, "f").call(this);
|
|
7742
|
+
ChannelClientStore.clients.delete(connection.routingInfo.endpointId);
|
|
7743
|
+
try {
|
|
7744
|
+
await __classPrivateFieldGet$k(this, _ChannelClient_releaseConnection, "f").call(this, connection, notifyRuntime);
|
|
7745
|
+
}
|
|
7746
|
+
finally {
|
|
7747
|
+
if (emitEvent) {
|
|
7748
|
+
try {
|
|
7749
|
+
__classPrivateFieldGet$k(this, _ChannelClient_disconnectListener, "f")?.call(this, identity);
|
|
7750
|
+
}
|
|
7751
|
+
catch (error) {
|
|
7752
|
+
// eslint-disable-next-line no-console
|
|
7753
|
+
console.warn(`An unexpected error occurred in a Channel Client Disconnection handler for channel ${identity.channelName}`, error);
|
|
7754
|
+
}
|
|
7755
|
+
}
|
|
7630
7756
|
}
|
|
7631
7757
|
}
|
|
7632
7758
|
}
|
|
7633
|
-
/**
|
|
7634
|
-
* @internal
|
|
7635
|
-
*/
|
|
7636
|
-
constructor(routingInfo, close, strategy) {
|
|
7637
|
-
super();
|
|
7638
|
-
_ChannelClient_protectedObj.set(this, void 0);
|
|
7639
|
-
_ChannelClient_strategy.set(this, void 0);
|
|
7640
|
-
// needs to be bound;
|
|
7641
|
-
this.processAction = (action, payload, senderIdentity) => super.processAction(action, payload, senderIdentity);
|
|
7642
|
-
_ChannelClient_close.set(this, () => {
|
|
7643
|
-
channelClientsByEndpointId.delete(this.endpointId);
|
|
7644
|
-
__classPrivateFieldGet$k(this, _ChannelClient_strategy, "f").close();
|
|
7645
|
-
});
|
|
7646
|
-
__classPrivateFieldSet$j(this, _ChannelClient_protectedObj, new ProtectedItems(routingInfo, close), "f");
|
|
7647
|
-
this.disconnectListener = () => undefined;
|
|
7648
|
-
this.endpointId = routingInfo.endpointId;
|
|
7649
|
-
__classPrivateFieldSet$j(this, _ChannelClient_strategy, strategy, "f");
|
|
7650
|
-
channelClientsByEndpointId.set(this.endpointId, this);
|
|
7651
|
-
strategy.receive(this.processAction);
|
|
7652
|
-
}
|
|
7653
7759
|
/**
|
|
7654
7760
|
* a read-only provider identity
|
|
7655
7761
|
*/
|
|
7656
7762
|
get providerIdentity() {
|
|
7657
|
-
|
|
7658
|
-
return protectedObj.providerIdentity;
|
|
7763
|
+
return { ...__classPrivateFieldGet$k(this, _ChannelClient_currentConnection, "f").routingInfo };
|
|
7659
7764
|
}
|
|
7660
7765
|
/**
|
|
7661
7766
|
* Dispatch the given action to the channel provider. Returns a promise that resolves with the response from
|
|
@@ -7683,17 +7788,22 @@ class ChannelClient extends ChannelBase {
|
|
|
7683
7788
|
* ```
|
|
7684
7789
|
*/
|
|
7685
7790
|
async dispatch(action, payload) {
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
throw new ChannelError$1(e, action, payload, callSites);
|
|
7690
|
-
});
|
|
7791
|
+
// App pageshow handlers run alongside the bfcache restore; sending now would go out on the frozen endpoint.
|
|
7792
|
+
if (__classPrivateFieldGet$k(this, _ChannelClient_state, "f").status === 'reconnecting') {
|
|
7793
|
+
await __classPrivateFieldGet$k(this, _ChannelClient_state, "f").waitForReconnection();
|
|
7691
7794
|
}
|
|
7692
|
-
|
|
7795
|
+
const connection = __classPrivateFieldGet$k(this, _ChannelClient_currentConnection, "f");
|
|
7796
|
+
if (!connection.strategy.isEndpointConnected(this.providerIdentity.channelId)) {
|
|
7797
|
+
throw new Error('The client you are trying to dispatch from is disconnected from the target provider.');
|
|
7798
|
+
}
|
|
7799
|
+
const callSites = RuntimeError.getCallSite();
|
|
7800
|
+
return connection.strategy.send(this.providerIdentity.channelId, action, payload).catch((e) => {
|
|
7801
|
+
throw new ChannelError$1(e, action, payload, callSites);
|
|
7802
|
+
});
|
|
7693
7803
|
}
|
|
7694
7804
|
/**
|
|
7695
|
-
* Register a listener that is called
|
|
7696
|
-
*
|
|
7805
|
+
* Register a listener that is called when this client loses its channel: the provider disconnects, the
|
|
7806
|
+
* endpoint drops, or a self-heal fails. It is passed the provider identity.
|
|
7697
7807
|
*
|
|
7698
7808
|
* @param listener
|
|
7699
7809
|
*
|
|
@@ -7710,17 +7820,46 @@ class ChannelClient extends ChannelBase {
|
|
|
7710
7820
|
* ```
|
|
7711
7821
|
*/
|
|
7712
7822
|
onDisconnection(listener) {
|
|
7713
|
-
this
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7823
|
+
__classPrivateFieldSet$j(this, _ChannelClient_disconnectListener, listener, "f");
|
|
7824
|
+
}
|
|
7825
|
+
/**
|
|
7826
|
+
* Register a listener that is called each time this client transparently self-heals its connection to the
|
|
7827
|
+
* provider.
|
|
7828
|
+
*
|
|
7829
|
+
* @remarks
|
|
7830
|
+
* A channel client's underlying endpoint is torn down while its document sits in the back/forward cache
|
|
7831
|
+
* (bfcache). If the back/forward cache is supported and the document is restored from it, the client
|
|
7832
|
+
* automatically re-handshakes with the provider and swaps in a fresh endpoint; all of this client's
|
|
7833
|
+
* `register`/middleware handlers are preserved, so no re-registration is required.
|
|
7834
|
+
*
|
|
7835
|
+
* A restore is not guaranteed: Chromium may evict a cached document at any time, in which case navigating
|
|
7836
|
+
* back reloads the page and a new client must connect.
|
|
7837
|
+
*
|
|
7838
|
+
* This listener fires once per successful reconnect, after the new endpoint is live, and can fire multiple
|
|
7839
|
+
* times over the client's lifetime. It is triggered when the document is restored from the back/forward
|
|
7840
|
+
* cache (a bfcache `pageshow`). It does not fire for the initial connection, nor after
|
|
7841
|
+
* {@link ChannelClient#disconnect disconnect}. {@link ChannelClient#onDisconnection onDisconnection} fires
|
|
7842
|
+
* when the provider or endpoint goes away.
|
|
7843
|
+
*
|
|
7844
|
+
* The info provides the reconnected {@link OpenFin.ProviderIdentity provider identity} along with
|
|
7845
|
+
* the previous and new endpoint ids.
|
|
7846
|
+
*
|
|
7847
|
+
* @param listener
|
|
7848
|
+
*
|
|
7849
|
+
* @example
|
|
7850
|
+
*
|
|
7851
|
+
* ```js
|
|
7852
|
+
* (async () => {
|
|
7853
|
+
* const client = await fin.InterApplicationBus.Channel.connect('channelName');
|
|
7854
|
+
*
|
|
7855
|
+
* client.onReconnection(({ providerIdentity, previousEndpointId, endpointId }) => {
|
|
7856
|
+
* console.log(`Reconnected to ${providerIdentity.channelName}: ${previousEndpointId} -> ${endpointId}`);
|
|
7857
|
+
* });
|
|
7858
|
+
* })();
|
|
7859
|
+
* ```
|
|
7860
|
+
*/
|
|
7861
|
+
onReconnection(listener) {
|
|
7862
|
+
__classPrivateFieldSet$j(this, _ChannelClient_reconnectListener, listener, "f");
|
|
7724
7863
|
}
|
|
7725
7864
|
/**
|
|
7726
7865
|
* Disconnects the client from the channel.
|
|
@@ -7736,28 +7875,16 @@ class ChannelClient extends ChannelBase {
|
|
|
7736
7875
|
* ```
|
|
7737
7876
|
*/
|
|
7738
7877
|
async disconnect() {
|
|
7739
|
-
await this
|
|
7740
|
-
__classPrivateFieldGet$k(this, _ChannelClient_close, "f").call(this);
|
|
7741
|
-
}
|
|
7742
|
-
async sendDisconnectAction() {
|
|
7743
|
-
const protectedObj = __classPrivateFieldGet$k(this, _ChannelClient_protectedObj, "f");
|
|
7744
|
-
await protectedObj.close();
|
|
7878
|
+
await this[teardown](false);
|
|
7745
7879
|
}
|
|
7746
7880
|
/**
|
|
7747
7881
|
* @internal
|
|
7748
|
-
*
|
|
7882
|
+
* Notify the runtime that the current endpoint has disconnected.
|
|
7749
7883
|
*/
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
await wire.sendAction('disconnect-from-channel', {
|
|
7753
|
-
channelName,
|
|
7754
|
-
uuid,
|
|
7755
|
-
name,
|
|
7756
|
-
endpointId
|
|
7757
|
-
});
|
|
7884
|
+
async sendDisconnectAction() {
|
|
7885
|
+
await this.disconnect();
|
|
7758
7886
|
}
|
|
7759
7887
|
}
|
|
7760
|
-
_ChannelClient_protectedObj = new WeakMap(), _ChannelClient_strategy = new WeakMap(), _ChannelClient_close = new WeakMap();
|
|
7761
7888
|
|
|
7762
7889
|
function exhaustiveCheck(value, allowed) {
|
|
7763
7890
|
throw new Error(`Unsupported value: ${value}${allowed ? `\n Supported values are: ${allowed.join('')}` : ''}`);
|
|
@@ -8681,7 +8808,7 @@ class MessageReceiver extends Base {
|
|
|
8681
8808
|
const endpointIdFromPreviousConnection = this.latestEndpointIdByChannelId.get(channelId);
|
|
8682
8809
|
if (endpointIdFromPreviousConnection) {
|
|
8683
8810
|
// Not convinced by this way of doing things, but pushing up for now.
|
|
8684
|
-
|
|
8811
|
+
ChannelClientStore.handleEndpointDisconnect(endpointIdFromPreviousConnection);
|
|
8685
8812
|
// eslint-disable-next-line no-console
|
|
8686
8813
|
console.warn('You have created a second connection to an older provider. First connection has been removed from the clientMap');
|
|
8687
8814
|
// eslint-disable-next-line no-console
|
|
@@ -9056,7 +9183,7 @@ var __classPrivateFieldGet$e = (undefined && undefined.__classPrivateFieldGet) |
|
|
|
9056
9183
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
9057
9184
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
9058
9185
|
};
|
|
9059
|
-
var _Channel_connectionManager, _Channel_internalEmitter, _Channel_readyForProvider, _Channel_readyToConnect;
|
|
9186
|
+
var _Channel_connectionManager, _Channel_internalEmitter, _Channel_readyForProvider, _Channel_readyToConnect, _Channel_establishConnection;
|
|
9060
9187
|
function retryDelay(count) {
|
|
9061
9188
|
const interval = 500; // base delay
|
|
9062
9189
|
const steps = 10; // How many retries to do before incrementing the delay
|
|
@@ -9106,13 +9233,33 @@ class Channel extends EmitterBase {
|
|
|
9106
9233
|
await Promise.all([
|
|
9107
9234
|
__classPrivateFieldGet$e(this, _Channel_readyForProvider, "f").getValue(),
|
|
9108
9235
|
this.on('disconnected', (eventPayload) => {
|
|
9109
|
-
|
|
9236
|
+
ChannelClientStore.handleProviderDisconnect(eventPayload);
|
|
9110
9237
|
}),
|
|
9111
9238
|
this.on('connected', (...args) => {
|
|
9112
9239
|
__classPrivateFieldGet$e(this, _Channel_internalEmitter, "f").emit('connected', ...args);
|
|
9113
9240
|
})
|
|
9114
9241
|
]).catch(() => new Error('error setting up channel connection listeners'));
|
|
9115
9242
|
}));
|
|
9243
|
+
// Runs the client handshake (offer -> connect -> strategy). Re-runnable so a ChannelClient can reconnect
|
|
9244
|
+
// with a fresh endpointId; offers are single-use (esp. RTC) so a new offer is created each call.
|
|
9245
|
+
_Channel_establishConnection.set(this, async (channelName, opts, connectionUrl) => {
|
|
9246
|
+
const { offer, rtc: rtcPacket } = await __classPrivateFieldGet$e(this, _Channel_connectionManager, "f").createClientOffer(opts);
|
|
9247
|
+
// getInfo() can hang during a bfcache restore, so reconnects reuse the URL resolved on the first connect;
|
|
9248
|
+
// it cannot change within a client's lifetime.
|
|
9249
|
+
let targetUrl = connectionUrl;
|
|
9250
|
+
if (targetUrl === undefined && (this.fin.me.isFrame || this.fin.me.isView || this.fin.me.isWindow)) {
|
|
9251
|
+
targetUrl = (await this.fin.me.getInfo()).url;
|
|
9252
|
+
}
|
|
9253
|
+
const connectPayload = {
|
|
9254
|
+
channelName,
|
|
9255
|
+
...opts,
|
|
9256
|
+
offer,
|
|
9257
|
+
connectionUrl: targetUrl
|
|
9258
|
+
};
|
|
9259
|
+
const routingInfo = await this.safeConnect(channelName, opts.wait, connectPayload);
|
|
9260
|
+
const strategy = await __classPrivateFieldGet$e(this, _Channel_connectionManager, "f").createClientStrategy(rtcPacket, routingInfo);
|
|
9261
|
+
return { routingInfo, strategy, connectionUrl: targetUrl };
|
|
9262
|
+
});
|
|
9116
9263
|
__classPrivateFieldSet$d(this, _Channel_connectionManager, new ConnectionManager(wire), "f");
|
|
9117
9264
|
}
|
|
9118
9265
|
/**
|
|
@@ -9284,35 +9431,14 @@ class Channel extends EmitterBase {
|
|
|
9284
9431
|
throw new Error('Please provide a channelName string to connect to a channel.');
|
|
9285
9432
|
}
|
|
9286
9433
|
const opts = { wait: true, ...this.wire.environment.getDefaultChannelOptions().connect, ...options };
|
|
9287
|
-
const
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
|
|
9293
|
-
channelName,
|
|
9294
|
-
...opts,
|
|
9295
|
-
offer,
|
|
9296
|
-
connectionUrl
|
|
9297
|
-
};
|
|
9298
|
-
const routingInfo = await this.safeConnect(channelName, opts.wait, connectPayload);
|
|
9299
|
-
const strategy = await __classPrivateFieldGet$e(this, _Channel_connectionManager, "f").createClientStrategy(rtcPacket, routingInfo);
|
|
9300
|
-
const channel = new ChannelClient(routingInfo, () => ChannelClient.wireClose(this.wire, routingInfo, routingInfo.endpointId), strategy);
|
|
9301
|
-
// It is the client's responsibility to handle endpoint disconnection to the provider.
|
|
9302
|
-
// If the endpoint dies, the client will force a disconnection through the core.
|
|
9303
|
-
// The provider does not care about endpoint disconnection.
|
|
9304
|
-
strategy.onEndpointDisconnect(routingInfo.channelId, async () => {
|
|
9305
|
-
try {
|
|
9306
|
-
await channel.sendDisconnectAction();
|
|
9307
|
-
}
|
|
9308
|
-
catch (error) {
|
|
9309
|
-
console.warn(`Something went wrong during disconnect for client with uuid: ${routingInfo.uuid} / name: ${routingInfo.name} / endpointId: ${routingInfo.endpointId}.`);
|
|
9310
|
-
}
|
|
9311
|
-
finally {
|
|
9312
|
-
ChannelClient.handleProviderDisconnect(routingInfo);
|
|
9313
|
-
}
|
|
9434
|
+
const initialConnection = await __classPrivateFieldGet$e(this, _Channel_establishConnection, "f").call(this, channelName, opts);
|
|
9435
|
+
// Never wait on a self-heal: a provider missing at restore has gone away, which is a disconnection. A provider
|
|
9436
|
+
// created later under the same name is a new instance without this client's provider-side state.
|
|
9437
|
+
return new ChannelClient({
|
|
9438
|
+
initialConnection,
|
|
9439
|
+
wire: this.wire,
|
|
9440
|
+
reestablish: () => __classPrivateFieldGet$e(this, _Channel_establishConnection, "f").call(this, channelName, { ...opts, wait: false }, initialConnection.connectionUrl)
|
|
9314
9441
|
});
|
|
9315
|
-
return channel;
|
|
9316
9442
|
}
|
|
9317
9443
|
/**
|
|
9318
9444
|
* Create a new channel.
|
|
@@ -9369,7 +9495,7 @@ class Channel extends EmitterBase {
|
|
|
9369
9495
|
return __classPrivateFieldGet$e(this, _Channel_connectionManager, "f").createProvider(options, providerIdentity);
|
|
9370
9496
|
}
|
|
9371
9497
|
}
|
|
9372
|
-
_Channel_connectionManager = new WeakMap(), _Channel_internalEmitter = new WeakMap(), _Channel_readyForProvider = new WeakMap(), _Channel_readyToConnect = new WeakMap();
|
|
9498
|
+
_Channel_connectionManager = new WeakMap(), _Channel_internalEmitter = new WeakMap(), _Channel_readyForProvider = new WeakMap(), _Channel_readyToConnect = new WeakMap(), _Channel_establishConnection = new WeakMap();
|
|
9373
9499
|
|
|
9374
9500
|
/**
|
|
9375
9501
|
* Entry point for the OpenFin `InterApplicationBus` API (`fin.InterApplicationBus`).
|
|
@@ -9403,11 +9529,27 @@ class InterApplicationBus extends Base {
|
|
|
9403
9529
|
subscriberRemoved: 'subscriber-removed'
|
|
9404
9530
|
};
|
|
9405
9531
|
this.refCounter = new RefCounter();
|
|
9532
|
+
/**
|
|
9533
|
+
* One entry per subscription the runtime knows about, keyed by the same subscription key the
|
|
9534
|
+
* emitter and the ref counter use. Listeners sharing a key share a single entry.
|
|
9535
|
+
*/
|
|
9536
|
+
this.activeSubscriptions = new Map();
|
|
9406
9537
|
this.Channel = new Channel(wire);
|
|
9407
9538
|
this.emitter = new events.EventEmitter();
|
|
9408
9539
|
wire.registerMessageHandler(this.onmessage.bind(this));
|
|
9409
9540
|
this.on = this.emitter.on.bind(this.emitter);
|
|
9410
9541
|
this.removeAllListeners = this.emitter.removeAllListeners.bind(this.emitter);
|
|
9542
|
+
wire.environment.onBFCacheRestore(() => {
|
|
9543
|
+
Array.from(this.activeSubscriptions.values()).forEach(async (subscription) => {
|
|
9544
|
+
try {
|
|
9545
|
+
await this.wire.sendAction('subscribe', subscription);
|
|
9546
|
+
}
|
|
9547
|
+
catch (error) {
|
|
9548
|
+
// eslint-disable-next-line no-console
|
|
9549
|
+
console.error('Failed to restore InterApplicationBus subscription after bfcache restore', error);
|
|
9550
|
+
}
|
|
9551
|
+
});
|
|
9552
|
+
});
|
|
9411
9553
|
}
|
|
9412
9554
|
/**
|
|
9413
9555
|
* Publishes a message to all applications running on OpenFin Runtime that
|
|
@@ -9459,30 +9601,39 @@ class InterApplicationBus extends Base {
|
|
|
9459
9601
|
* Subscribes to messages from the specified application on the specified topic.
|
|
9460
9602
|
* @param source This object is described in the Identity in the typedef
|
|
9461
9603
|
* @param topic The topic on which the message is sent
|
|
9462
|
-
* @param listener A function that is called when a message has
|
|
9463
|
-
*
|
|
9604
|
+
* @param listener A function that is called when a message has been received. It is passed
|
|
9605
|
+
* two arguments: the message, and the identity (`{ uuid, name }`) of the sender.
|
|
9464
9606
|
* The message can be either a primitive data type (string, number, or boolean) or
|
|
9465
9607
|
* composite data type (object, array) that is composed of other primitive or composite
|
|
9466
9608
|
* data types
|
|
9467
9609
|
*
|
|
9610
|
+
* @remarks This differs from the legacy `fin.desktop.InterApplicationBus.subscribe` API,
|
|
9611
|
+
* which passes `(message, uuid, name)` as separate arguments.
|
|
9612
|
+
*
|
|
9468
9613
|
* @example
|
|
9469
9614
|
* ```js
|
|
9470
9615
|
* // subscribe to a specified application
|
|
9471
|
-
* fin.InterApplicationBus.subscribe(fin.me, 'topic',
|
|
9616
|
+
* fin.InterApplicationBus.subscribe(fin.me, 'topic', (message, sender) => {
|
|
9617
|
+
* console.log(`Received from ${sender.uuid}/${sender.name}:`, message);
|
|
9618
|
+
* }).then(() => console.log('Subscribed to the specified application')).catch(err => console.log(err));
|
|
9472
9619
|
*
|
|
9473
9620
|
* // subscribe to wildcard
|
|
9474
9621
|
* fin.InterApplicationBus.subscribe({ uuid: '*' }, 'topic', sub_msg => console.log(sub_msg)).then(() => console.log('Subscribed to *')).catch(err => console.log(err));
|
|
9475
9622
|
* ```
|
|
9476
9623
|
*/
|
|
9477
9624
|
subscribe(source, topic, listener) {
|
|
9478
|
-
const
|
|
9625
|
+
const sourceWindowName = source.name || '*';
|
|
9626
|
+
const subKey = this.createSubscriptionKey(source.uuid, sourceWindowName, topic);
|
|
9627
|
+
const subscription = {
|
|
9628
|
+
sourceUuid: source.uuid,
|
|
9629
|
+
sourceWindowName,
|
|
9630
|
+
topic,
|
|
9631
|
+
destinationWindowName: this.me.name
|
|
9632
|
+
};
|
|
9479
9633
|
const sendSubscription = async () => {
|
|
9480
|
-
await
|
|
9481
|
-
|
|
9482
|
-
|
|
9483
|
-
topic,
|
|
9484
|
-
destinationWindowName: this.me.name
|
|
9485
|
-
});
|
|
9634
|
+
// Journaled before the await so a concurrent unsubscribe can find it.
|
|
9635
|
+
this.activeSubscriptions.set(subKey, subscription);
|
|
9636
|
+
await this.wire.sendAction('subscribe', subscription);
|
|
9486
9637
|
};
|
|
9487
9638
|
const alreadySubscribed = () => {
|
|
9488
9639
|
return Promise.resolve();
|
|
@@ -9518,6 +9669,9 @@ class InterApplicationBus extends Base {
|
|
|
9518
9669
|
const sourceWindowName = source.name || '*';
|
|
9519
9670
|
const subKey = this.createSubscriptionKey(source.uuid, sourceWindowName, topic);
|
|
9520
9671
|
const sendUnsubscription = async () => {
|
|
9672
|
+
// Dropped before the await so that a restoration landing while this unsubscribe is
|
|
9673
|
+
// still in flight does not replay the subscription being torn down.
|
|
9674
|
+
this.activeSubscriptions.delete(subKey);
|
|
9521
9675
|
await this.wire.sendAction('unsubscribe', {
|
|
9522
9676
|
sourceUuid: source.uuid,
|
|
9523
9677
|
sourceWindowName,
|
|
@@ -9526,6 +9680,9 @@ class InterApplicationBus extends Base {
|
|
|
9526
9680
|
});
|
|
9527
9681
|
};
|
|
9528
9682
|
const dontSendUnsubscription = () => {
|
|
9683
|
+
// TODO(CORE-2749): never settles - the executor evaluates `r` instead of calling it,
|
|
9684
|
+
// so awaiting a non-final unsubscribe hangs the caller. Should be `Promise.resolve()`,
|
|
9685
|
+
// but that changes long-standing behavior, so it is tracked separately from CORE-2740.
|
|
9529
9686
|
return new Promise((r) => r).then(() => undefined);
|
|
9530
9687
|
};
|
|
9531
9688
|
this.emitter.removeListener(subKey, listener);
|
|
@@ -17594,7 +17751,7 @@ class NodeEnvironment extends BaseEnvironment {
|
|
|
17594
17751
|
};
|
|
17595
17752
|
}
|
|
17596
17753
|
getAdapterVersionSync() {
|
|
17597
|
-
return "47.100.
|
|
17754
|
+
return "47.100.29";
|
|
17598
17755
|
}
|
|
17599
17756
|
observeBounds(element, onChange) {
|
|
17600
17757
|
throw new Error('Method not implemented.');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openfin/node-adapter",
|
|
3
|
-
"version": "47.100.
|
|
3
|
+
"version": "47.100.29",
|
|
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": "47.100.
|
|
23
|
+
"@openfin/core": "47.100.29"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"prebuild": "rimraf ./out",
|