@openfin/core 31.74.21 → 31.74.23
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/package.json +1 -1
- package/src/OpenFin.d.ts +77 -18
- package/src/api/api-exposer/api-consumer.d.ts +28 -0
- package/src/api/api-exposer/api-consumer.js +28 -0
- package/src/api/api-exposer/api-exposer.d.ts +35 -0
- package/src/api/api-exposer/api-exposer.js +38 -0
- package/src/api/api-exposer/decorators.d.ts +10 -0
- package/src/api/api-exposer/decorators.js +18 -0
- package/src/api/api-exposer/index.d.ts +4 -0
- package/src/api/api-exposer/index.js +20 -0
- package/src/api/api-exposer/strategies/index.d.ts +1 -0
- package/src/api/api-exposer/strategies/index.js +17 -0
- package/src/api/api-exposer/strategies/openfin-channels/channels-consumer.d.ts +14 -0
- package/src/api/api-exposer/strategies/openfin-channels/channels-consumer.js +20 -0
- package/src/api/api-exposer/strategies/openfin-channels/channels-exposer.d.ts +20 -0
- package/src/api/api-exposer/strategies/openfin-channels/channels-exposer.js +23 -0
- package/src/api/api-exposer/strategies/openfin-channels/index.d.ts +2 -0
- package/src/api/api-exposer/strategies/openfin-channels/index.js +18 -0
- package/src/api/application/Factory.js +0 -1
- package/src/api/application/Instance.js +23 -5
- package/src/api/base.d.ts +1 -2
- package/src/api/base.js +1 -2
- package/src/api/events/system.d.ts +6 -3
- package/src/api/fin.js +1 -2
- package/src/api/interappbus/channel/index.d.ts +1 -0
- package/src/api/interappbus/channel/index.js +47 -47
- package/src/api/interappbus/channel/protocols/classic/strategy.js +24 -6
- package/src/api/interappbus/index.js +1 -1
- package/src/api/interop/InteropClient.d.ts +1 -1
- package/src/api/interop/InteropClient.js +1 -1
- package/src/api/interop/SessionContextGroupBroker.d.ts +1 -1
- package/src/api/interop/SessionContextGroupBroker.js +5 -4
- package/src/api/interop/SessionContextGroupClient.js +1 -1
- package/src/api/interop/fdc3/PrivateChannelProvider.d.ts +1 -1
- package/src/api/interop/fdc3/PrivateChannelProvider.js +1 -8
- package/src/api/interop/fdc3/fdc3-1.2.js +34 -1
- package/src/api/interop/fdc3/fdc3-2.0.d.ts +11 -10
- package/src/api/interop/fdc3/fdc3-2.0.js +10 -9
- package/src/api/interop/fdc3/shapes/fdc3v2.d.ts +1 -1
- package/src/api/interop/fdc3/utils.js +24 -4
- package/src/api/platform/Factory.d.ts +2 -1
- package/src/api/platform/Factory.js +1 -4
- package/src/api/platform/Instance.d.ts +6 -5
- package/src/api/platform/Instance.js +1 -0
- package/src/api/platform/layout/Factory.js +15 -4
- package/src/api/platform/layout/Instance.d.ts +6 -0
- package/src/api/platform/layout/Instance.js +29 -1
- package/src/api/platform/layout/controllers/layout-content-cache.d.ts +9 -0
- package/src/api/platform/layout/controllers/layout-content-cache.js +54 -0
- package/src/api/platform/layout/controllers/layout-entities-controller.d.ts +119 -0
- package/src/api/platform/layout/controllers/layout-entities-controller.js +287 -0
- package/src/api/platform/layout/controllers/tab-drag-controller.d.ts +2 -1
- package/src/api/platform/layout/entities/layout-entities.d.ts +235 -0
- package/src/api/platform/layout/entities/layout-entities.js +312 -0
- package/src/api/platform/layout/entities/shapes.d.ts +6 -0
- package/src/api/platform/layout/entities/shapes.js +2 -0
- package/src/api/platform/layout/layout.constants.d.ts +1 -0
- package/src/api/platform/layout/layout.constants.js +4 -0
- package/src/api/platform/layout/shapes.d.ts +3 -0
- package/src/api/platform/layout/utils/layout-traversal.d.ts +4 -0
- package/src/api/platform/layout/utils/layout-traversal.js +65 -0
- package/src/api/platform/provider.d.ts +2 -1
- package/src/api/system/index.d.ts +9 -0
- package/src/api/system/index.js +78 -40
- package/src/api/view/Instance.d.ts +12 -3
- package/src/api/view/Instance.js +39 -4
- package/src/api/webcontents/main.d.ts +2 -22
- package/src/api/webcontents/main.js +2 -1
- package/src/api/window/Instance.d.ts +10 -0
- package/src/api/window/Instance.js +22 -0
- package/src/environment/mockEnvironment.d.ts +27 -0
- package/src/environment/mockEnvironment.js +61 -0
- package/src/mock.js +4 -83
- package/src/shapes/protocol.d.ts +17 -0
- package/src/transport/mockWire.d.ts +11 -0
- package/src/transport/mockWire.js +26 -0
- package/src/transport/transport-errors.d.ts +9 -1
- package/src/transport/transport-errors.js +45 -2
- package/src/transport/transport.d.ts +15 -5
- package/src/transport/transport.js +48 -20
- package/src/util/channel-api-relay.d.ts +13 -0
- package/src/util/channel-api-relay.js +47 -0
- package/src/util/errors.d.ts +1 -0
- package/src/util/errors.js +1 -0
- package/src/util/lazy.d.ts +34 -0
- package/src/util/lazy.js +54 -0
- package/src/util/ref-counter.d.ts +1 -1
- package/src/util/ref-counter.js +3 -2
- package/src/util/reversible-map.d.ts +11 -0
- package/src/util/reversible-map.js +49 -0
- package/src/transport/fin_store.d.ts +0 -4
- package/src/transport/fin_store.js +0 -16
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
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");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _Channel_connectionManager;
|
|
13
|
+
var _Channel_connectionManager, _Channel_internalEmitter, _Channel_readyToConnect;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.Channel = void 0;
|
|
16
16
|
/* eslint-disable no-console */
|
|
@@ -18,16 +18,29 @@ const client_1 = require("./client");
|
|
|
18
18
|
const provider_1 = require("./provider");
|
|
19
19
|
const base_1 = require("../../base");
|
|
20
20
|
const connection_manager_1 = require("./connection-manager");
|
|
21
|
-
|
|
22
|
-
const
|
|
21
|
+
const events_1 = require("events");
|
|
22
|
+
const lazy_1 = require("../../../util/lazy");
|
|
23
23
|
class Channel extends base_1.EmitterBase {
|
|
24
24
|
constructor(wire) {
|
|
25
25
|
super(wire, 'channel');
|
|
26
26
|
_Channel_connectionManager.set(this, void 0);
|
|
27
|
+
_Channel_internalEmitter.set(this, new events_1.EventEmitter());
|
|
28
|
+
// OpenFin API has not been injected at construction time, *must* wait for API to be ready.
|
|
29
|
+
_Channel_readyToConnect.set(this, new lazy_1.AsyncRetryableLazy(async () => {
|
|
30
|
+
await Promise.all([
|
|
31
|
+
this.on('disconnected', (eventPayload) => {
|
|
32
|
+
client_1.default.handleProviderDisconnect(eventPayload);
|
|
33
|
+
}),
|
|
34
|
+
this.on('connected', (...args) => {
|
|
35
|
+
__classPrivateFieldGet(this, _Channel_internalEmitter, "f").emit('connected', ...args);
|
|
36
|
+
})
|
|
37
|
+
]).catch(() => new Error('error setting up channel connection listeners'));
|
|
38
|
+
}));
|
|
27
39
|
__classPrivateFieldSet(this, _Channel_connectionManager, new connection_manager_1.ConnectionManager(wire), "f");
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
}
|
|
41
|
+
async channelExists(channelName) {
|
|
42
|
+
const channels = await this.getAllChannels();
|
|
43
|
+
return channels.some((providerIdentity) => providerIdentity.channelName === channelName);
|
|
31
44
|
}
|
|
32
45
|
async getAllChannels() {
|
|
33
46
|
return this.wire.sendAction('get-all-channels').then(({ payload }) => payload.data);
|
|
@@ -38,47 +51,39 @@ class Channel extends base_1.EmitterBase {
|
|
|
38
51
|
async onChannelDisconnect(listener) {
|
|
39
52
|
await this.on('disconnected', listener);
|
|
40
53
|
}
|
|
41
|
-
async connect(channelName, options) {
|
|
54
|
+
async connect(channelName, options = {}) {
|
|
55
|
+
// Make sure we don't connect before listeners are set up
|
|
56
|
+
// This also errors if we're not in OpenFin, ensuring we don't run unnecessary code
|
|
57
|
+
await __classPrivateFieldGet(this, _Channel_readyToConnect, "f").getValue();
|
|
42
58
|
if (!channelName || typeof channelName !== 'string') {
|
|
43
59
|
throw new Error('Please provide a channelName string to connect to a channel.');
|
|
44
60
|
}
|
|
45
|
-
const opts =
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
const opts = { wait: true, ...this.wire.environment.getDefaultChannelOptions().connect, ...options };
|
|
62
|
+
const shouldWait = opts.wait;
|
|
63
|
+
if (shouldWait) {
|
|
64
|
+
const channelExists = await this.channelExists(channelName);
|
|
65
|
+
if (!channelExists) {
|
|
66
|
+
console.warn(`Channel not found for channelName: ${channelName}, waiting for channel connection.`);
|
|
67
|
+
await new Promise((resolve) => {
|
|
68
|
+
const connectedListener = (payload) => {
|
|
69
|
+
if (channelName === payload.channelName) {
|
|
70
|
+
__classPrivateFieldGet(this, _Channel_internalEmitter, "f").removeListener('connected', connectedListener);
|
|
71
|
+
resolve();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
__classPrivateFieldGet(this, _Channel_internalEmitter, "f").on('connected', connectedListener);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
58
78
|
try {
|
|
59
79
|
const { offer, rtc: rtcPacket } = await __classPrivateFieldGet(this, _Channel_connectionManager, "f").createClientOffer(opts);
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
if (entityType === 'iframe') {
|
|
63
|
-
// @ts-expect-error
|
|
64
|
-
// TODO: type this correctly (frame types are broken)
|
|
65
|
-
connectionUrl = (await this.fin.me.getInfo()).url;
|
|
66
|
-
}
|
|
67
|
-
else if (entityType === 'window' || entityType === 'view') {
|
|
68
|
-
connectionUrl = (await this.fin.me.getInfo()).url;
|
|
69
|
-
}
|
|
70
|
-
const res = await this.wire.sendAction('connect-to-channel', {
|
|
80
|
+
const connectionUrl = (await this.fin.me.getInfo()).url;
|
|
81
|
+
const { payload: { data: routingInfo } } = await this.wire.sendAction('connect-to-channel', {
|
|
71
82
|
channelName,
|
|
72
83
|
...opts,
|
|
73
84
|
offer,
|
|
74
85
|
connectionUrl
|
|
75
86
|
});
|
|
76
|
-
const { payload: { data: routingInfo } } = res;
|
|
77
|
-
// If there isn't a matching channel, the above sendAction call will error out and go to catch, skipping the logic below.
|
|
78
|
-
if (resolver) {
|
|
79
|
-
resolver();
|
|
80
|
-
}
|
|
81
|
-
this.removeListener('connected', listener);
|
|
82
87
|
const strategy = await __classPrivateFieldGet(this, _Channel_connectionManager, "f").createClientStrategy(rtcPacket, routingInfo);
|
|
83
88
|
const channel = new client_1.default(routingInfo, this.wire, strategy);
|
|
84
89
|
// It is the client's responsibility to handle endpoint disconnection to the provider.
|
|
@@ -97,18 +102,13 @@ class Channel extends base_1.EmitterBase {
|
|
|
97
102
|
});
|
|
98
103
|
return channel;
|
|
99
104
|
}
|
|
100
|
-
catch (
|
|
101
|
-
const shouldWait = { wait: true, ...opts }.wait;
|
|
105
|
+
catch (error) {
|
|
102
106
|
const internalNackMessage = 'internal-nack';
|
|
103
|
-
if (
|
|
104
|
-
|
|
105
|
-
return waitResponse;
|
|
106
|
-
}
|
|
107
|
-
if (e.message === internalNackMessage) {
|
|
108
|
-
throw new Error(`No channel found for channelName: ${channelName}`);
|
|
107
|
+
if (error.message.includes(internalNackMessage)) {
|
|
108
|
+
throw new Error(`No channel found for channelName: ${channelName}.`);
|
|
109
109
|
}
|
|
110
110
|
else {
|
|
111
|
-
throw new Error(
|
|
111
|
+
throw new Error(error);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
}
|
|
@@ -129,4 +129,4 @@ class Channel extends base_1.EmitterBase {
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
exports.Channel = Channel;
|
|
132
|
-
_Channel_connectionManager = new WeakMap();
|
|
132
|
+
_Channel_connectionManager = new WeakMap(), _Channel_internalEmitter = new WeakMap(), _Channel_readyToConnect = new WeakMap();
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
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");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _ClassicStrategy_wire, _ClassicStrategy_endpointIdentityMap;
|
|
13
|
+
var _ClassicStrategy_wire, _ClassicStrategy_endpointIdentityMap, _ClassicStrategy_pendingMessagesByEndpointId;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.ClassicInfo = exports.ClassicStrategy = void 0;
|
|
16
16
|
/*
|
|
@@ -26,7 +26,11 @@ class ClassicStrategy {
|
|
|
26
26
|
// Store full endpointIdentity by endpointId of all known endpoints for this strategy instance.
|
|
27
27
|
// (clients will only have 1: the provider, the provider will have all clients)
|
|
28
28
|
_ClassicStrategy_endpointIdentityMap.set(this, new Map());
|
|
29
|
+
// Store a set of cancellable promises to be able to reject them when client
|
|
30
|
+
// connection problems occur
|
|
31
|
+
_ClassicStrategy_pendingMessagesByEndpointId.set(this, new Map);
|
|
29
32
|
this.send = async (endpointId, action, payload) => {
|
|
33
|
+
var _a;
|
|
30
34
|
const to = __classPrivateFieldGet(this, _ClassicStrategy_endpointIdentityMap, "f").get(endpointId);
|
|
31
35
|
if (!to) {
|
|
32
36
|
throw new Error(`Could not locate routing info for endpoint ${endpointId}`);
|
|
@@ -38,20 +42,27 @@ class ClassicStrategy {
|
|
|
38
42
|
delete cleanId.endpointId;
|
|
39
43
|
}
|
|
40
44
|
delete cleanId.isLocalEndpointId;
|
|
41
|
-
|
|
45
|
+
// grab the promise before awaiting it to save in our pending messages map
|
|
46
|
+
const p = __classPrivateFieldGet(this, _ClassicStrategy_wire, "f")
|
|
42
47
|
.sendAction('send-channel-message', {
|
|
43
48
|
...cleanId,
|
|
44
49
|
providerIdentity: this.providerIdentity,
|
|
45
50
|
action,
|
|
46
51
|
payload
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
});
|
|
53
|
+
(_a = __classPrivateFieldGet(this, _ClassicStrategy_pendingMessagesByEndpointId, "f").get(endpointId)) === null || _a === void 0 ? void 0 : _a.add(p);
|
|
54
|
+
const raw = await p.catch((error) => {
|
|
55
|
+
throw new Error(error.message);
|
|
56
|
+
}).finally(() => {
|
|
57
|
+
var _a;
|
|
58
|
+
// clean up the pending promise
|
|
59
|
+
(_a = __classPrivateFieldGet(this, _ClassicStrategy_pendingMessagesByEndpointId, "f").get(endpointId)) === null || _a === void 0 ? void 0 : _a.delete(p);
|
|
50
60
|
});
|
|
51
61
|
return raw.payload.data.result;
|
|
52
62
|
};
|
|
53
63
|
this.close = async () => {
|
|
54
64
|
this.messageReceiver.removeEndpoint(this.providerIdentity.channelId, this.endpointId);
|
|
65
|
+
[...__classPrivateFieldGet(this, _ClassicStrategy_endpointIdentityMap, "f").keys()].forEach((id) => this.closeEndpoint(id));
|
|
55
66
|
__classPrivateFieldSet(this, _ClassicStrategy_endpointIdentityMap, new Map(), "f");
|
|
56
67
|
};
|
|
57
68
|
__classPrivateFieldSet(this, _ClassicStrategy_wire, wire, "f");
|
|
@@ -63,13 +74,20 @@ class ClassicStrategy {
|
|
|
63
74
|
this.messageReceiver.addEndpoint(listener, this.providerIdentity.channelId, this.endpointId);
|
|
64
75
|
}
|
|
65
76
|
async closeEndpoint(endpointId) {
|
|
77
|
+
const id = __classPrivateFieldGet(this, _ClassicStrategy_endpointIdentityMap, "f").get(endpointId);
|
|
66
78
|
__classPrivateFieldGet(this, _ClassicStrategy_endpointIdentityMap, "f").delete(endpointId);
|
|
79
|
+
const pendingSet = __classPrivateFieldGet(this, _ClassicStrategy_pendingMessagesByEndpointId, "f").get(endpointId);
|
|
80
|
+
pendingSet === null || pendingSet === void 0 ? void 0 : pendingSet.forEach((p) => {
|
|
81
|
+
const errorMsg = `Channel connection with identity uuid: ${id === null || id === void 0 ? void 0 : id.uuid} / name: ${id === null || id === void 0 ? void 0 : id.name} / endpointId: ${endpointId} no longer connected.`;
|
|
82
|
+
p.cancel(new Error(errorMsg));
|
|
83
|
+
});
|
|
67
84
|
}
|
|
68
85
|
isEndpointConnected(endpointId) {
|
|
69
86
|
return __classPrivateFieldGet(this, _ClassicStrategy_endpointIdentityMap, "f").has(endpointId);
|
|
70
87
|
}
|
|
71
88
|
addEndpoint(endpointId, payload) {
|
|
72
89
|
__classPrivateFieldGet(this, _ClassicStrategy_endpointIdentityMap, "f").set(endpointId, payload.endpointIdentity);
|
|
90
|
+
__classPrivateFieldGet(this, _ClassicStrategy_pendingMessagesByEndpointId, "f").set(endpointId, new Set());
|
|
73
91
|
}
|
|
74
92
|
isValidEndpointPayload(payload) {
|
|
75
93
|
var _a, _b;
|
|
@@ -78,6 +96,6 @@ class ClassicStrategy {
|
|
|
78
96
|
}
|
|
79
97
|
}
|
|
80
98
|
exports.ClassicStrategy = ClassicStrategy;
|
|
81
|
-
_ClassicStrategy_wire = new WeakMap(), _ClassicStrategy_endpointIdentityMap = new WeakMap();
|
|
99
|
+
_ClassicStrategy_wire = new WeakMap(), _ClassicStrategy_endpointIdentityMap = new WeakMap(), _ClassicStrategy_pendingMessagesByEndpointId = new WeakMap();
|
|
82
100
|
// Arbitrarily starting at 5 to leave the door open to backfilling pre endpointId etc.
|
|
83
101
|
exports.ClassicInfo = { version: 5, minimumVersion: 0, type: 'classic' };
|
|
@@ -17,7 +17,7 @@ class InterApplicationBus extends base_1.Base {
|
|
|
17
17
|
subscriberAdded: 'subscriber-added',
|
|
18
18
|
subscriberRemoved: 'subscriber-removed'
|
|
19
19
|
};
|
|
20
|
-
this.refCounter = new ref_counter_1.
|
|
20
|
+
this.refCounter = new ref_counter_1.RefCounter();
|
|
21
21
|
this.Channel = new index_1.Channel(wire);
|
|
22
22
|
this.emitter = new events_1.EventEmitter();
|
|
23
23
|
wire.registerMessageHandler(this.onmessage.bind(this));
|
|
@@ -88,7 +88,7 @@ import { Base } from '../base';
|
|
|
88
88
|
* @summary A SessionContextGroup instance method for adding a handler for context change.
|
|
89
89
|
* @param {ContextHandler} contextHandler The callback to be invoked. Is invoked when (a) the context changes or (b) immediately after getting created if the context is already set.
|
|
90
90
|
* @param {string} [contextType] The context type this handler should listen to. If not specified, a global handler for all context types will get created. Only one global handler is allowed per SessionContextGroup.
|
|
91
|
-
* @return {Promise<
|
|
91
|
+
* @return {Promise<Subscription>}
|
|
92
92
|
*/
|
|
93
93
|
/**
|
|
94
94
|
* {@link https://developers.openfin.co/of-docs/docs/enable-color-linking}
|
|
@@ -103,7 +103,7 @@ const utils_1 = require("./utils");
|
|
|
103
103
|
* @summary A SessionContextGroup instance method for adding a handler for context change.
|
|
104
104
|
* @param {ContextHandler} contextHandler The callback to be invoked. Is invoked when (a) the context changes or (b) immediately after getting created if the context is already set.
|
|
105
105
|
* @param {string} [contextType] The context type this handler should listen to. If not specified, a global handler for all context types will get created. Only one global handler is allowed per SessionContextGroup.
|
|
106
|
-
* @return {Promise<
|
|
106
|
+
* @return {Promise<Subscription>}
|
|
107
107
|
*/
|
|
108
108
|
/**
|
|
109
109
|
* {@link https://developers.openfin.co/of-docs/docs/enable-color-linking}
|
|
@@ -18,7 +18,7 @@ export default class SessionContextGroupBroker {
|
|
|
18
18
|
handlerAdded(payload: {
|
|
19
19
|
handlerId: string;
|
|
20
20
|
contextType?: string;
|
|
21
|
-
}, clientIdentity: OpenFin.ClientIdentity): void
|
|
21
|
+
}, clientIdentity: OpenFin.ClientIdentity): Promise<void>;
|
|
22
22
|
handlerRemoved(payload: {
|
|
23
23
|
handlerId: string;
|
|
24
24
|
}, clientIdentity: OpenFin.ClientIdentity): void;
|
|
@@ -48,7 +48,7 @@ class SessionContextGroupBroker {
|
|
|
48
48
|
getClientState(id) {
|
|
49
49
|
return this.clients.get(id.endpointId);
|
|
50
50
|
}
|
|
51
|
-
handlerAdded(payload, clientIdentity) {
|
|
51
|
+
async handlerAdded(payload, clientIdentity) {
|
|
52
52
|
const { handlerId, contextType } = payload;
|
|
53
53
|
const clientSubscriptionState = this.getClientState(clientIdentity);
|
|
54
54
|
if (!clientSubscriptionState) {
|
|
@@ -59,17 +59,18 @@ class SessionContextGroupBroker {
|
|
|
59
59
|
clientSubscriptionState.contextHandlers.set(contextType, [...currentHandlerList, handlerId]);
|
|
60
60
|
const currentContext = this.contextGroupMap.get(contextType);
|
|
61
61
|
if (currentContext) {
|
|
62
|
-
this.provider.dispatch(clientIdentity, handlerId, currentContext);
|
|
62
|
+
await this.provider.dispatch(clientIdentity, handlerId, currentContext);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
66
|
clientSubscriptionState.globalHandler = handlerId;
|
|
67
|
-
[...this.contextGroupMap.keys()].
|
|
67
|
+
const globalDispatchPromises = [...this.contextGroupMap.keys()].map(async (currentContextType) => {
|
|
68
68
|
const currentContext = this.contextGroupMap.get(currentContextType);
|
|
69
69
|
if (currentContext) {
|
|
70
|
-
this.provider.dispatch(clientIdentity, handlerId, currentContext);
|
|
70
|
+
await this.provider.dispatch(clientIdentity, handlerId, currentContext);
|
|
71
71
|
}
|
|
72
72
|
});
|
|
73
|
+
await Promise.all(globalDispatchPromises);
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
handlerRemoved(payload, clientIdentity) {
|
|
@@ -63,7 +63,7 @@ class SessionContextGroupClient extends base_1.Base {
|
|
|
63
63
|
handlerId = `sessionContextHandler:invoke-${this.id}`;
|
|
64
64
|
}
|
|
65
65
|
client.register(handlerId, (0, utils_1.wrapContextHandler)(contextHandler, handlerId));
|
|
66
|
-
client.dispatch(`sessionContextGroup:handlerAdded-${this.id}`, { handlerId, contextType });
|
|
66
|
+
await client.dispatch(`sessionContextGroup:handlerAdded-${this.id}`, { handlerId, contextType });
|
|
67
67
|
return { unsubscribe: await this.createUnsubscribeCb(handlerId) };
|
|
68
68
|
}
|
|
69
69
|
async createUnsubscribeCb(handlerId) {
|
|
@@ -84,16 +84,9 @@ class PrivateChannelProvider {
|
|
|
84
84
|
if (contextType) {
|
|
85
85
|
const currentHandlersList = senderClientState.handlerIdsByContextTypes.get(contextType) || [];
|
|
86
86
|
senderClientState.handlerIdsByContextTypes.set(contextType, [...currentHandlersList, handlerId]);
|
|
87
|
-
const currContext = this.contextByContextType.get(contextType);
|
|
88
|
-
if (currContext) {
|
|
89
|
-
this.provider.dispatch(senderClientIdentity, handlerId, currContext);
|
|
90
|
-
}
|
|
91
87
|
}
|
|
92
88
|
else {
|
|
93
89
|
senderClientState.globalHandler = handlerId;
|
|
94
|
-
if (this.lastContext) {
|
|
95
|
-
this.provider.dispatch(senderClientIdentity, handlerId, this.lastContext);
|
|
96
|
-
}
|
|
97
90
|
}
|
|
98
91
|
Array.from(this.clients.values()).forEach((currClientState) => {
|
|
99
92
|
if (currClientState.clientIdentity.endpointId !== senderClientIdentity.endpointId &&
|
|
@@ -271,7 +264,7 @@ class PrivateChannelProvider {
|
|
|
271
264
|
const allClientInfo = await this.provider.getAllClientInfo();
|
|
272
265
|
return Array.from(this.clients.values()).filter((clientState) => {
|
|
273
266
|
const { uuid, name } = clientState.clientIdentity;
|
|
274
|
-
return allClientInfo.some(clientInfo => {
|
|
267
|
+
return allClientInfo.some((clientInfo) => {
|
|
275
268
|
return name === clientInfo.name && uuid === clientInfo.uuid;
|
|
276
269
|
});
|
|
277
270
|
});
|
|
@@ -4,6 +4,7 @@ const base_1 = require("../../base");
|
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
const utils_2 = require("../utils");
|
|
6
6
|
const InteropClient_1 = require("../InteropClient");
|
|
7
|
+
const lodash_1 = require("lodash");
|
|
7
8
|
/**
|
|
8
9
|
* @typedef { object } Listener
|
|
9
10
|
* @summary Listener object returned by addContextListener and addIntentListener
|
|
@@ -393,7 +394,39 @@ class Fdc3Module extends base_1.Base {
|
|
|
393
394
|
return {
|
|
394
395
|
...currentContextGroupInfo,
|
|
395
396
|
type: 'system',
|
|
396
|
-
addContextListener:
|
|
397
|
+
addContextListener: (contextType, handler) => {
|
|
398
|
+
let realHandler;
|
|
399
|
+
let realType;
|
|
400
|
+
if (typeof contextType === 'function') {
|
|
401
|
+
console.warn('addContextListener(handler) has been deprecated. Please use addContextListener(null, handler)');
|
|
402
|
+
realHandler = contextType;
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
realHandler = handler;
|
|
406
|
+
if (typeof contextType === 'string') {
|
|
407
|
+
realType = contextType;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const listener = (async () => {
|
|
411
|
+
let first = true;
|
|
412
|
+
const currentContext = await this.fin.me.interop.getCurrentContext(realType);
|
|
413
|
+
const wrappedHandler = (context, contextMetadata) => {
|
|
414
|
+
if (first) {
|
|
415
|
+
first = false;
|
|
416
|
+
if ((0, lodash_1.isEqual)(currentContext, context)) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
// eslint-disable-next-line consistent-return
|
|
421
|
+
return realHandler(context, contextMetadata);
|
|
422
|
+
};
|
|
423
|
+
return this.fin.me.interop.addContextHandler(wrappedHandler, realType);
|
|
424
|
+
})();
|
|
425
|
+
return {
|
|
426
|
+
...listener,
|
|
427
|
+
unsubscribe: () => listener.then((l) => l.unsubscribe())
|
|
428
|
+
};
|
|
429
|
+
},
|
|
397
430
|
broadcast: this.broadcast.bind(this),
|
|
398
431
|
getCurrentContext: async (contextType) => {
|
|
399
432
|
const context = await this.fin.me.interop.getCurrentContext(contextType);
|
|
@@ -171,14 +171,14 @@ export default class Fdc3Module2 extends Base implements FDC3v2.DesktopAgent {
|
|
|
171
171
|
* Find all the available instances for a particular application.
|
|
172
172
|
* @param { AppIdentifier } app
|
|
173
173
|
* @returns { Promise<Array<AppIdentifier>> }
|
|
174
|
-
* @tutorial findInstances
|
|
174
|
+
* @tutorial fdc3v2.findInstances
|
|
175
175
|
*/
|
|
176
176
|
findInstances(app: FDC3v2.AppIdentifier): Promise<Array<FDC3v2.AppIdentifier>>;
|
|
177
177
|
/**
|
|
178
178
|
* Retrieves the AppMetadata for an AppIdentifier, which provides additional metadata (such as icons, a title and description) from the App Directory record for the application, that may be used for display purposes.
|
|
179
179
|
* @param { AppIdentifier } app
|
|
180
180
|
* @returns { Promise<AppMetadata(2)> }
|
|
181
|
-
* @tutorial getAppMetadata
|
|
181
|
+
* @tutorial fdc3v2.getAppMetadata
|
|
182
182
|
*/
|
|
183
183
|
getAppMetadata(app: FDC3v2.AppIdentifier): Promise<FDC3v2.AppMetadata>;
|
|
184
184
|
/**
|
|
@@ -210,7 +210,7 @@ export default class Fdc3Module2 extends Base implements FDC3v2.DesktopAgent {
|
|
|
210
210
|
* @param { Context } context
|
|
211
211
|
* @param { string } [resultType] The type of result returned for any intent specified during resolution.
|
|
212
212
|
* @returns { Promise<Array<AppIntent(2)>> }
|
|
213
|
-
* @tutorial findIntentsByContext
|
|
213
|
+
* @tutorial fdc3v2.findIntentsByContext
|
|
214
214
|
*/
|
|
215
215
|
findIntentsByContext(context: FDC3v2.Context, resultType?: string): Promise<Array<FDC3v2.AppIntent>>;
|
|
216
216
|
/**
|
|
@@ -219,7 +219,7 @@ export default class Fdc3Module2 extends Base implements FDC3v2.DesktopAgent {
|
|
|
219
219
|
* @param { Context } context Context associated with the Intent
|
|
220
220
|
* @param { AppIdentifier | TargetApp } [app]
|
|
221
221
|
* @returns { Promise<IntentResolution(2)> }
|
|
222
|
-
* @tutorial raiseIntent
|
|
222
|
+
* @tutorial fdc3v2.raiseIntent
|
|
223
223
|
*/
|
|
224
224
|
raiseIntent(intent: string, context: FDC3v2.Context, app?: FDC3v2.AppIdentifier | FDC3v1.TargetApp): Promise<FDC3v2.IntentResolution>;
|
|
225
225
|
/**
|
|
@@ -227,7 +227,7 @@ export default class Fdc3Module2 extends Base implements FDC3v2.DesktopAgent {
|
|
|
227
227
|
* @param { Context } context Context associated with the Intent
|
|
228
228
|
* @param { AppIdentifier | TargetApp } [app]
|
|
229
229
|
* @returns { Promise<IntentResolution(2)> }
|
|
230
|
-
* @tutorial raiseIntentForContext
|
|
230
|
+
* @tutorial fdc3v2.raiseIntentForContext
|
|
231
231
|
*/
|
|
232
232
|
raiseIntentForContext(context: FDC3v2.Context, app?: FDC3v2.AppIdentifier | FDC3v1.TargetApp): Promise<FDC3v2.IntentResolution>;
|
|
233
233
|
/**
|
|
@@ -244,17 +244,17 @@ export default class Fdc3Module2 extends Base implements FDC3v2.DesktopAgent {
|
|
|
244
244
|
* @returns { Promise<Channel> }
|
|
245
245
|
* @tutorial fdc3.getOrCreateChannel
|
|
246
246
|
*/
|
|
247
|
-
getOrCreateChannel(channelId: string): Promise<
|
|
247
|
+
getOrCreateChannel(channelId: string): Promise<FDC3v2.Channel>;
|
|
248
248
|
/**
|
|
249
249
|
* Returns a Channel with an auto-generated identity that is intended for private communication between applications. Primarily used to create channels that will be returned to other applications via an IntentResolution for a raised intent.
|
|
250
250
|
* @returns { Promise<PrivateChannel> }
|
|
251
|
-
* @tutorial createPrivateChannel
|
|
251
|
+
* @tutorial fdc3v2.createPrivateChannel
|
|
252
252
|
*/
|
|
253
253
|
createPrivateChannel(): Promise<FDC3v2.PrivateChannel>;
|
|
254
254
|
/**
|
|
255
255
|
* Retrieves a list of the User Channels available for the app to join.
|
|
256
256
|
* @returns { Promise<Channel[]>}
|
|
257
|
-
* @tutorial getUserChannels
|
|
257
|
+
* @tutorial fdc3v2.getUserChannels
|
|
258
258
|
*/
|
|
259
259
|
getUserChannels(): Promise<Array<FDC3v1.SystemChannel>>;
|
|
260
260
|
/**
|
|
@@ -268,7 +268,7 @@ export default class Fdc3Module2 extends Base implements FDC3v2.DesktopAgent {
|
|
|
268
268
|
* Join an app to a specified User channel.
|
|
269
269
|
* @param { string } channelId Channel name
|
|
270
270
|
* @returns { Promise<void> }
|
|
271
|
-
* @tutorial joinUserChannel
|
|
271
|
+
* @tutorial fdc3v2.joinUserChannel
|
|
272
272
|
*/
|
|
273
273
|
joinUserChannel(channelId: string): Promise<void>;
|
|
274
274
|
/**
|
|
@@ -282,6 +282,7 @@ export default class Fdc3Module2 extends Base implements FDC3v2.DesktopAgent {
|
|
|
282
282
|
/**
|
|
283
283
|
* Returns the Channel object for the current User channel membership
|
|
284
284
|
* @returns { Promise<FDC3.Channel | null> }
|
|
285
|
+
* @tutorial fdc3.getCurrentChannel
|
|
285
286
|
*/
|
|
286
287
|
getCurrentChannel(): Promise<FDC3v2.Channel | null>;
|
|
287
288
|
/**
|
|
@@ -294,7 +295,7 @@ export default class Fdc3Module2 extends Base implements FDC3v2.DesktopAgent {
|
|
|
294
295
|
* Retrieves information about the FDC3 implementation, including the supported version of the FDC3 specification, the name of the provider of the implementation, its own version number, details of whether optional API features are implemented and the metadata of the calling application according to the desktop agent.
|
|
295
296
|
* fdc3HandleGetInfo must be overridden in the InteropBroker so that the ImplementationMetadata will have the appMetadata info.
|
|
296
297
|
* @returns { Promise<ImplementationMetadata(2)> }
|
|
297
|
-
* @tutorial getInfo
|
|
298
|
+
* @tutorial fdc3v2.getInfo
|
|
298
299
|
*/
|
|
299
300
|
getInfo(): Promise<FDC3v2.ImplementationMetadata>;
|
|
300
301
|
}
|
|
@@ -180,7 +180,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
180
180
|
* Find all the available instances for a particular application.
|
|
181
181
|
* @param { AppIdentifier } app
|
|
182
182
|
* @returns { Promise<Array<AppIdentifier>> }
|
|
183
|
-
* @tutorial findInstances
|
|
183
|
+
* @tutorial fdc3v2.findInstances
|
|
184
184
|
*/
|
|
185
185
|
async findInstances(app) {
|
|
186
186
|
this.wire.sendAction('fdc3-find-instances').catch((e) => {
|
|
@@ -198,7 +198,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
198
198
|
* Retrieves the AppMetadata for an AppIdentifier, which provides additional metadata (such as icons, a title and description) from the App Directory record for the application, that may be used for display purposes.
|
|
199
199
|
* @param { AppIdentifier } app
|
|
200
200
|
* @returns { Promise<AppMetadata(2)> }
|
|
201
|
-
* @tutorial getAppMetadata
|
|
201
|
+
* @tutorial fdc3v2.getAppMetadata
|
|
202
202
|
*/
|
|
203
203
|
async getAppMetadata(app) {
|
|
204
204
|
this.wire.sendAction('fdc3-get-app-metadata').catch((e) => {
|
|
@@ -276,7 +276,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
276
276
|
* @param { Context } context
|
|
277
277
|
* @param { string } [resultType] The type of result returned for any intent specified during resolution.
|
|
278
278
|
* @returns { Promise<Array<AppIntent(2)>> }
|
|
279
|
-
* @tutorial findIntentsByContext
|
|
279
|
+
* @tutorial fdc3v2.findIntentsByContext
|
|
280
280
|
*/
|
|
281
281
|
async findIntentsByContext(context, resultType) {
|
|
282
282
|
this.wire.sendAction('fdc3-find-intents-by-context').catch((e) => {
|
|
@@ -297,7 +297,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
297
297
|
* @param { Context } context Context associated with the Intent
|
|
298
298
|
* @param { AppIdentifier | TargetApp } [app]
|
|
299
299
|
* @returns { Promise<IntentResolution(2)> }
|
|
300
|
-
* @tutorial raiseIntent
|
|
300
|
+
* @tutorial fdc3v2.raiseIntent
|
|
301
301
|
*/
|
|
302
302
|
async raiseIntent(intent, context, app) {
|
|
303
303
|
this.wire.sendAction('fdc3-raise-intent').catch((e) => {
|
|
@@ -316,7 +316,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
316
316
|
* @param { Context } context Context associated with the Intent
|
|
317
317
|
* @param { AppIdentifier | TargetApp } [app]
|
|
318
318
|
* @returns { Promise<IntentResolution(2)> }
|
|
319
|
-
* @tutorial raiseIntentForContext
|
|
319
|
+
* @tutorial fdc3v2.raiseIntentForContext
|
|
320
320
|
*/
|
|
321
321
|
async raiseIntentForContext(context, app) {
|
|
322
322
|
// TODO: We have to do the same thing we do for raiseIntent here as well.
|
|
@@ -384,7 +384,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
384
384
|
/**
|
|
385
385
|
* Returns a Channel with an auto-generated identity that is intended for private communication between applications. Primarily used to create channels that will be returned to other applications via an IntentResolution for a raised intent.
|
|
386
386
|
* @returns { Promise<PrivateChannel> }
|
|
387
|
-
* @tutorial createPrivateChannel
|
|
387
|
+
* @tutorial fdc3v2.createPrivateChannel
|
|
388
388
|
*/
|
|
389
389
|
async createPrivateChannel() {
|
|
390
390
|
const channelId = (0, utils_1.generateId)();
|
|
@@ -396,7 +396,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
396
396
|
/**
|
|
397
397
|
* Retrieves a list of the User Channels available for the app to join.
|
|
398
398
|
* @returns { Promise<Channel[]>}
|
|
399
|
-
* @tutorial getUserChannels
|
|
399
|
+
* @tutorial fdc3v2.getUserChannels
|
|
400
400
|
*/
|
|
401
401
|
async getUserChannels() {
|
|
402
402
|
const channels = await this.fin.me.interop.getContextGroups();
|
|
@@ -420,7 +420,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
420
420
|
* Join an app to a specified User channel.
|
|
421
421
|
* @param { string } channelId Channel name
|
|
422
422
|
* @returns { Promise<void> }
|
|
423
|
-
* @tutorial joinUserChannel
|
|
423
|
+
* @tutorial fdc3v2.joinUserChannel
|
|
424
424
|
*/
|
|
425
425
|
async joinUserChannel(channelId) {
|
|
426
426
|
return this.fdc3Module.joinChannel(channelId);
|
|
@@ -439,6 +439,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
439
439
|
/**
|
|
440
440
|
* Returns the Channel object for the current User channel membership
|
|
441
441
|
* @returns { Promise<FDC3.Channel | null> }
|
|
442
|
+
* @tutorial fdc3.getCurrentChannel
|
|
442
443
|
*/
|
|
443
444
|
async getCurrentChannel() {
|
|
444
445
|
const currentChannel = await this.fdc3Module.getCurrentChannel();
|
|
@@ -463,7 +464,7 @@ class Fdc3Module2 extends base_1.Base {
|
|
|
463
464
|
* Retrieves information about the FDC3 implementation, including the supported version of the FDC3 specification, the name of the provider of the implementation, its own version number, details of whether optional API features are implemented and the metadata of the calling application according to the desktop agent.
|
|
464
465
|
* fdc3HandleGetInfo must be overridden in the InteropBroker so that the ImplementationMetadata will have the appMetadata info.
|
|
465
466
|
* @returns { Promise<ImplementationMetadata(2)> }
|
|
466
|
-
* @tutorial getInfo
|
|
467
|
+
* @tutorial fdc3v2.getInfo
|
|
467
468
|
*/
|
|
468
469
|
async getInfo() {
|
|
469
470
|
return InteropClient_1.InteropClient.ferryFdc3Call(this.fin.me.interop, 'fdc3v2GetInfo', { fdc3Version: '2.0' });
|
|
@@ -64,7 +64,7 @@ export interface DesktopAgent {
|
|
|
64
64
|
addContextListener(contextType: string | null, handler: ContextHandler): Promise<Listener>;
|
|
65
65
|
getUserChannels(): Promise<Array<SystemChannel>>;
|
|
66
66
|
joinUserChannel(channelId: string): Promise<void>;
|
|
67
|
-
getOrCreateChannel(channelId: string): Promise<
|
|
67
|
+
getOrCreateChannel(channelId: string): Promise<Channel>;
|
|
68
68
|
createPrivateChannel(): Promise<PrivateChannel>;
|
|
69
69
|
getCurrentChannel(): Promise<ChannelV1 | null>;
|
|
70
70
|
leaveCurrentChannel(): Promise<void>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getIntentResolution = exports.isChannel = exports.isContext = exports.connectPrivateChannel = exports.buildAppChannelObject = exports.buildPrivateChannelObject = exports.ChannelError = exports.ResultError = exports.UnsupportedChannelApiError = exports.getUnsupportedChannelApis = void 0;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
const PrivateChannelClient_1 = require("./PrivateChannelClient");
|
|
6
|
+
const lodash_1 = require("lodash");
|
|
6
7
|
const getUnsupportedChannelApis = (channelType) => {
|
|
7
8
|
return {
|
|
8
9
|
addContextListener: () => {
|
|
@@ -111,14 +112,33 @@ const buildAppChannelObject = (sessionContextGroup) => {
|
|
|
111
112
|
return context === undefined ? null : context;
|
|
112
113
|
},
|
|
113
114
|
addContextListener: (contextType, handler) => {
|
|
114
|
-
let
|
|
115
|
+
let realHandler;
|
|
116
|
+
let realType;
|
|
115
117
|
if (typeof contextType === 'function') {
|
|
116
118
|
console.warn('addContextListener(handler) has been deprecated. Please use addContextListener(null, handler)');
|
|
117
|
-
|
|
119
|
+
realHandler = contextType;
|
|
118
120
|
}
|
|
119
121
|
else {
|
|
120
|
-
|
|
122
|
+
realHandler = handler;
|
|
123
|
+
if (typeof contextType === 'string') {
|
|
124
|
+
realType = contextType;
|
|
125
|
+
}
|
|
121
126
|
}
|
|
127
|
+
const listener = (async () => {
|
|
128
|
+
let first = true;
|
|
129
|
+
const currentContext = await sessionContextGroup.getCurrentContext(realType);
|
|
130
|
+
const wrappedHandler = (context, contextMetadata) => {
|
|
131
|
+
if (first) {
|
|
132
|
+
first = false;
|
|
133
|
+
if ((0, lodash_1.isEqual)(currentContext, context)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// eslint-disable-next-line consistent-return
|
|
138
|
+
return realHandler(context, contextMetadata);
|
|
139
|
+
};
|
|
140
|
+
return sessionContextGroup.addContextHandler(wrappedHandler, realType);
|
|
141
|
+
})();
|
|
122
142
|
return {
|
|
123
143
|
...listener,
|
|
124
144
|
unsubscribe: () => listener.then((l) => l.unsubscribe())
|
|
@@ -149,7 +169,7 @@ exports.isContext = isContext;
|
|
|
149
169
|
const isChannel = (channel) => {
|
|
150
170
|
if (channel && typeof channel === 'object' && 'type' in channel && 'id' in channel) {
|
|
151
171
|
const { type, id } = channel;
|
|
152
|
-
return
|
|
172
|
+
return typeof type === 'string' && typeof id === 'string' && (type === 'app' || type === 'private');
|
|
153
173
|
}
|
|
154
174
|
return false;
|
|
155
175
|
};
|