@openfin/core 31.74.22 → 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/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 _Transport_wire;
|
|
13
|
+
var _Transport_wire, _Transport_fin;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.Transport = void 0;
|
|
16
16
|
const events_1 = require("events");
|
|
@@ -18,6 +18,7 @@ const wire_1 = require("./wire");
|
|
|
18
18
|
const transport_errors_1 = require("./transport-errors");
|
|
19
19
|
const eventAggregator_1 = require("../api/events/eventAggregator");
|
|
20
20
|
const me_1 = require("../api/me");
|
|
21
|
+
const errors_1 = require("../util/errors");
|
|
21
22
|
class Transport extends events_1.EventEmitter {
|
|
22
23
|
constructor(WireType, environment, config) {
|
|
23
24
|
super();
|
|
@@ -26,6 +27,8 @@ class Transport extends events_1.EventEmitter {
|
|
|
26
27
|
this.eventAggregator = new eventAggregator_1.default();
|
|
27
28
|
this.messageHandlers = [this.eventAggregator.dispatchEvent];
|
|
28
29
|
_Transport_wire.set(this, void 0);
|
|
30
|
+
// Typing as unknown to avoid circular dependency, should not be used directly.
|
|
31
|
+
_Transport_fin.set(this, void 0);
|
|
29
32
|
this.connectSync = () => {
|
|
30
33
|
const wire = __classPrivateFieldGet(this, _Transport_wire, "f");
|
|
31
34
|
wire.connectSync();
|
|
@@ -40,8 +43,8 @@ class Transport extends events_1.EventEmitter {
|
|
|
40
43
|
this.sendRaw = __classPrivateFieldGet(this, _Transport_wire, "f").send.bind(__classPrivateFieldGet(this, _Transport_wire, "f"));
|
|
41
44
|
this.registerMessageHandler(this.handleMessage.bind(this));
|
|
42
45
|
__classPrivateFieldGet(this, _Transport_wire, "f").on('disconnected', () => {
|
|
43
|
-
for (const [, {
|
|
44
|
-
|
|
46
|
+
for (const [, { handleNack }] of this.wireListeners) {
|
|
47
|
+
handleNack({ reason: 'Remote connection has closed' });
|
|
45
48
|
}
|
|
46
49
|
this.wireListeners.clear();
|
|
47
50
|
this.emit('disconnected');
|
|
@@ -50,6 +53,18 @@ class Transport extends events_1.EventEmitter {
|
|
|
50
53
|
const entityType = this.environment.getCurrentEntityType();
|
|
51
54
|
this.me = (0, me_1.getBaseMe)(entityType, uuid, name);
|
|
52
55
|
}
|
|
56
|
+
getFin() {
|
|
57
|
+
if (!__classPrivateFieldGet(this, _Transport_fin, "f")) {
|
|
58
|
+
throw new Error("No Fin object registered for this transport");
|
|
59
|
+
}
|
|
60
|
+
return __classPrivateFieldGet(this, _Transport_fin, "f");
|
|
61
|
+
}
|
|
62
|
+
registerFin(_fin) {
|
|
63
|
+
if (__classPrivateFieldGet(this, _Transport_fin, "f")) {
|
|
64
|
+
throw new Error("Fin object has already been registered for this transport");
|
|
65
|
+
}
|
|
66
|
+
__classPrivateFieldSet(this, _Transport_fin, _fin, "f");
|
|
67
|
+
}
|
|
53
68
|
shutdown() {
|
|
54
69
|
const wire = __classPrivateFieldGet(this, _Transport_wire, "f");
|
|
55
70
|
return wire.shutdown();
|
|
@@ -95,20 +110,33 @@ class Transport extends events_1.EventEmitter {
|
|
|
95
110
|
throw new transport_errors_1.RuntimeError(requestAuthRet.payload);
|
|
96
111
|
}
|
|
97
112
|
}
|
|
98
|
-
sendAction(action, payload = {}, uncorrelated = false
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
113
|
+
sendAction(action, payload = {}, uncorrelated = false) {
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
115
|
+
let cancel = () => { };
|
|
116
|
+
// We want the callsite from the caller of this function, not from here.
|
|
117
|
+
const callSites = transport_errors_1.RuntimeError.getCallSite(1);
|
|
118
|
+
const prom = new Promise((resolve, reject) => {
|
|
119
|
+
cancel = reject;
|
|
120
|
+
const messageId = this.environment.getNextMessageId();
|
|
103
121
|
const msg = {
|
|
104
122
|
action,
|
|
105
123
|
payload,
|
|
106
|
-
messageId
|
|
124
|
+
messageId
|
|
107
125
|
};
|
|
108
126
|
const wire = __classPrivateFieldGet(this, _Transport_wire, "f");
|
|
109
|
-
this.addWireListener(
|
|
127
|
+
this.addWireListener(messageId, resolve, (payload) => this.nackHandler(payload, reject, callSites), uncorrelated);
|
|
110
128
|
return wire.send(msg).catch(reject);
|
|
111
129
|
});
|
|
130
|
+
return Object.assign(prom, { cancel });
|
|
131
|
+
}
|
|
132
|
+
nackHandler(payloadOrMessage, reject, callSites) {
|
|
133
|
+
if (typeof payloadOrMessage === 'string') {
|
|
134
|
+
// NOTE: this is for backwards compatibility to support plain string rejections
|
|
135
|
+
reject(payloadOrMessage);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
reject(new transport_errors_1.RuntimeError(payloadOrMessage, callSites));
|
|
139
|
+
}
|
|
112
140
|
}
|
|
113
141
|
ferryAction(origData) {
|
|
114
142
|
return new Promise((resolve, reject) => {
|
|
@@ -120,22 +148,22 @@ class Transport extends events_1.EventEmitter {
|
|
|
120
148
|
const wire = __classPrivateFieldGet(this, _Transport_wire, "f");
|
|
121
149
|
return wire
|
|
122
150
|
.send(origData)
|
|
123
|
-
.then(() => this.addWireListener(id, resolver, reject, false))
|
|
151
|
+
.then(() => this.addWireListener(id, resolver, (payload) => this.nackHandler(payload, reject), false))
|
|
124
152
|
.catch(reject);
|
|
125
153
|
});
|
|
126
154
|
}
|
|
127
155
|
registerMessageHandler(handler) {
|
|
128
156
|
this.messageHandlers.push(handler);
|
|
129
157
|
}
|
|
130
|
-
addWireListener(id, resolve,
|
|
158
|
+
addWireListener(id, resolve, handleNack, uncorrelated) {
|
|
131
159
|
if (uncorrelated) {
|
|
132
160
|
this.uncorrelatedListener = resolve;
|
|
133
161
|
}
|
|
134
162
|
else if (this.wireListeners.has(id)) {
|
|
135
|
-
|
|
163
|
+
handleNack({ reason: 'Duplicate handler id', error: (0, errors_1.errorToPOJO)(new transport_errors_1.DuplicateCorrelationError(String(id))) });
|
|
136
164
|
}
|
|
137
165
|
else {
|
|
138
|
-
this.wireListeners.set(id, { resolve,
|
|
166
|
+
this.wireListeners.set(id, { resolve, handleNack });
|
|
139
167
|
}
|
|
140
168
|
// Timeout and reject()?
|
|
141
169
|
}
|
|
@@ -161,23 +189,23 @@ class Transport extends events_1.EventEmitter {
|
|
|
161
189
|
else {
|
|
162
190
|
// We just checked for existence above
|
|
163
191
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
164
|
-
const { resolve,
|
|
192
|
+
const { resolve, handleNack } = this.wireListeners.get(id);
|
|
165
193
|
if (data.action !== 'ack') {
|
|
166
|
-
|
|
194
|
+
handleNack({ reason: 'Did not receive ack action', error: (0, errors_1.errorToPOJO)(new transport_errors_1.NoAckError(data.action)) });
|
|
167
195
|
}
|
|
168
196
|
else if (!('payload' in data)) {
|
|
169
197
|
// I'm not sure when this code would actually run, but passing in something that doeesn't have a reason to the runtimeerror constructor will not end well.
|
|
170
198
|
// @ts-expect-error
|
|
171
199
|
if (typeof data.reason === 'string') {
|
|
172
|
-
|
|
200
|
+
handleNack(data);
|
|
173
201
|
}
|
|
174
202
|
else {
|
|
175
203
|
console.warn('Received invalid response from core', data);
|
|
176
|
-
|
|
204
|
+
handleNack({ reason: 'invalid response shape' });
|
|
177
205
|
}
|
|
178
206
|
}
|
|
179
207
|
else if (!data.payload.success) {
|
|
180
|
-
|
|
208
|
+
handleNack(data.payload);
|
|
181
209
|
}
|
|
182
210
|
else {
|
|
183
211
|
resolve.call(null, data);
|
|
@@ -188,4 +216,4 @@ class Transport extends events_1.EventEmitter {
|
|
|
188
216
|
}
|
|
189
217
|
}
|
|
190
218
|
exports.Transport = Transport;
|
|
191
|
-
_Transport_wire = new WeakMap();
|
|
219
|
+
_Transport_wire = new WeakMap(), _Transport_fin = new WeakMap();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type * as OpenFin from '../OpenFin';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
* Create a channel relay for a given channel exposition, allowing a single provider to route
|
|
5
|
+
* actions to the designated clients.
|
|
6
|
+
*
|
|
7
|
+
* Designed to be used in conjunction with @expose
|
|
8
|
+
*
|
|
9
|
+
* @param channelProvider The channel provider to relay the actions on.
|
|
10
|
+
* @param config Determines which actions to relay. Please ensure action prefix matches the exposed api.
|
|
11
|
+
*/
|
|
12
|
+
export declare const relayChannelClientApi: (channelProvider: OpenFin.ChannelProvider, relayId: string) => Promise<void>;
|
|
13
|
+
export declare const createRelayedDispatch: (client: OpenFin.ChannelClient, target: OpenFin.Identity, relayId: string, relayErrorMsg?: string) => OpenFin.ChannelClient['dispatch'];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRelayedDispatch = exports.relayChannelClientApi = void 0;
|
|
4
|
+
const EXPECTED_ERRORS = [
|
|
5
|
+
'no longer connected',
|
|
6
|
+
'RTCDataChannel closed unexpectedly',
|
|
7
|
+
'The client you are trying to dispatch from is disconnected from the target provider',
|
|
8
|
+
];
|
|
9
|
+
// Checks possible error messages that we want to trap, client error message can originate
|
|
10
|
+
// from ChannelProvider::dispatch OR ClassicStrategy::closeEndpoint OR RTCEndPoint::dataChannel::onclose
|
|
11
|
+
const isDisconnectedError = (errorMsg) => {
|
|
12
|
+
return EXPECTED_ERRORS.some(e => errorMsg.includes(e));
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* @internal
|
|
16
|
+
* Create a channel relay for a given channel exposition, allowing a single provider to route
|
|
17
|
+
* actions to the designated clients.
|
|
18
|
+
*
|
|
19
|
+
* Designed to be used in conjunction with @expose
|
|
20
|
+
*
|
|
21
|
+
* @param channelProvider The channel provider to relay the actions on.
|
|
22
|
+
* @param config Determines which actions to relay. Please ensure action prefix matches the exposed api.
|
|
23
|
+
*/
|
|
24
|
+
const relayChannelClientApi = async (channelProvider, relayId) => {
|
|
25
|
+
channelProvider.register(`relay:${relayId}`, ({ action, target, payload }) => {
|
|
26
|
+
return channelProvider.dispatch(target, action, payload);
|
|
27
|
+
});
|
|
28
|
+
await Promise.resolve();
|
|
29
|
+
};
|
|
30
|
+
exports.relayChannelClientApi = relayChannelClientApi;
|
|
31
|
+
const createRelayedDispatch = (client, target, relayId, relayErrorMsg) => async (action, payload) => {
|
|
32
|
+
try {
|
|
33
|
+
return await client.dispatch(`relay:${relayId}`, {
|
|
34
|
+
action,
|
|
35
|
+
payload,
|
|
36
|
+
target
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
if (isDisconnectedError(e.message) && relayErrorMsg) {
|
|
41
|
+
throw new Error(relayErrorMsg);
|
|
42
|
+
}
|
|
43
|
+
;
|
|
44
|
+
throw e;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
exports.createRelayedDispatch = createRelayedDispatch;
|
package/src/util/errors.d.ts
CHANGED
package/src/util/errors.js
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handy class for managing asynchronous dependencies of classes.
|
|
3
|
+
*
|
|
4
|
+
* Will call the producer function once and only once when getValue is called,
|
|
5
|
+
* returning the resultant value for every subsequent call.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Lazy<T> {
|
|
8
|
+
private producerFn;
|
|
9
|
+
constructor(producerFn: () => T);
|
|
10
|
+
private value;
|
|
11
|
+
/**
|
|
12
|
+
* Lazily get the value returned by the producer.
|
|
13
|
+
* @returns The value returned from the producer function
|
|
14
|
+
*/
|
|
15
|
+
getValue(): T;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Handy class for managing asynchronous dependencies of classes.
|
|
19
|
+
*
|
|
20
|
+
* Will call asynchronous producer only after `getValue` is called. If the
|
|
21
|
+
* deferred code errors, we can try it again by re-calling `getValue` after
|
|
22
|
+
* the promise rejects.
|
|
23
|
+
*/
|
|
24
|
+
export declare class AsyncRetryableLazy<T> {
|
|
25
|
+
private producerFn;
|
|
26
|
+
constructor(producerFn: () => Promise<T>);
|
|
27
|
+
private promise?;
|
|
28
|
+
/**
|
|
29
|
+
* Lazily get the value returned by the async producer.
|
|
30
|
+
*
|
|
31
|
+
* @returns The value returned from the producer function
|
|
32
|
+
*/
|
|
33
|
+
getValue(): Promise<T>;
|
|
34
|
+
}
|
package/src/util/lazy.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AsyncRetryableLazy = exports.Lazy = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Handy class for managing asynchronous dependencies of classes.
|
|
6
|
+
*
|
|
7
|
+
* Will call the producer function once and only once when getValue is called,
|
|
8
|
+
* returning the resultant value for every subsequent call.
|
|
9
|
+
*/
|
|
10
|
+
class Lazy {
|
|
11
|
+
// eslint-disable-next-line
|
|
12
|
+
constructor(producerFn) {
|
|
13
|
+
this.producerFn = producerFn;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Lazily get the value returned by the producer.
|
|
17
|
+
* @returns The value returned from the producer function
|
|
18
|
+
*/
|
|
19
|
+
getValue() {
|
|
20
|
+
if (!this.value) {
|
|
21
|
+
this.value = this.producerFn();
|
|
22
|
+
}
|
|
23
|
+
return this.value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.Lazy = Lazy;
|
|
27
|
+
/**
|
|
28
|
+
* Handy class for managing asynchronous dependencies of classes.
|
|
29
|
+
*
|
|
30
|
+
* Will call asynchronous producer only after `getValue` is called. If the
|
|
31
|
+
* deferred code errors, we can try it again by re-calling `getValue` after
|
|
32
|
+
* the promise rejects.
|
|
33
|
+
*/
|
|
34
|
+
class AsyncRetryableLazy {
|
|
35
|
+
// eslint-disable-next-line
|
|
36
|
+
constructor(producerFn) {
|
|
37
|
+
this.producerFn = producerFn;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Lazily get the value returned by the async producer.
|
|
41
|
+
*
|
|
42
|
+
* @returns The value returned from the producer function
|
|
43
|
+
*/
|
|
44
|
+
async getValue() {
|
|
45
|
+
if (!this.promise) {
|
|
46
|
+
this.promise = this.producerFn().catch((e) => {
|
|
47
|
+
delete this.promise;
|
|
48
|
+
throw e;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return this.promise;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.AsyncRetryableLazy = AsyncRetryableLazy;
|
package/src/util/ref-counter.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
exports.RefCounter = void 0;
|
|
4
|
+
class RefCounter {
|
|
4
5
|
constructor() {
|
|
5
6
|
this.topicRefMap = new Map();
|
|
6
7
|
}
|
|
@@ -48,4 +49,4 @@ class RefCoutner {
|
|
|
48
49
|
return isLastRef ? lastAction() : nonLastAction();
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
exports.
|
|
52
|
+
exports.RefCounter = RefCounter;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class ReversibleMap<TKey extends string | number | symbol, TValue extends Object | string | number> {
|
|
2
|
+
private readonly valueToKey;
|
|
3
|
+
private readonly keyToValue;
|
|
4
|
+
setUnique: (key: TKey, value: TValue) => void;
|
|
5
|
+
getKey: (value: TValue) => TKey;
|
|
6
|
+
getValue(key: TKey): TValue;
|
|
7
|
+
deleteKey: (key: TKey) => TValue | undefined;
|
|
8
|
+
deleteValue: (value: TValue) => TKey | undefined;
|
|
9
|
+
hasKey: (key: TKey) => boolean;
|
|
10
|
+
hasValue: (value: TValue) => boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReversibleMap = void 0;
|
|
4
|
+
class ReversibleMap {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.valueToKey = new Map();
|
|
7
|
+
this.keyToValue = new Map();
|
|
8
|
+
this.setUnique = (key, value) => {
|
|
9
|
+
if (this.hasKey(key) || this.hasValue(value)) {
|
|
10
|
+
throw new Error('Key or value already in the map.');
|
|
11
|
+
}
|
|
12
|
+
this.keyToValue.set(key, value);
|
|
13
|
+
this.valueToKey.set(value, key);
|
|
14
|
+
};
|
|
15
|
+
this.getKey = (value) => {
|
|
16
|
+
const existingKey = this.valueToKey.get(value);
|
|
17
|
+
if (!existingKey) {
|
|
18
|
+
throw new Error('Value not found in the map.');
|
|
19
|
+
}
|
|
20
|
+
return existingKey;
|
|
21
|
+
};
|
|
22
|
+
this.deleteKey = (key) => {
|
|
23
|
+
const value = this.getValue(key);
|
|
24
|
+
this.keyToValue.delete(key);
|
|
25
|
+
this.valueToKey.delete(value);
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
28
|
+
this.deleteValue = (value) => {
|
|
29
|
+
const key = this.getKey(value);
|
|
30
|
+
this.keyToValue.delete(key);
|
|
31
|
+
this.valueToKey.delete(value);
|
|
32
|
+
return key;
|
|
33
|
+
};
|
|
34
|
+
this.hasKey = (key) => {
|
|
35
|
+
return this.keyToValue.has(key);
|
|
36
|
+
};
|
|
37
|
+
this.hasValue = (value) => {
|
|
38
|
+
return this.valueToKey.has(value);
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
getValue(key) {
|
|
42
|
+
const item = this.keyToValue.get(key);
|
|
43
|
+
if (!item) {
|
|
44
|
+
throw new Error('Key not found in the map.');
|
|
45
|
+
}
|
|
46
|
+
return item;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.ReversibleMap = ReversibleMap;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getFin = exports.registerFin = void 0;
|
|
4
|
-
const finMap = new WeakMap();
|
|
5
|
-
function registerFin(wire, fin) {
|
|
6
|
-
finMap.set(wire, fin);
|
|
7
|
-
}
|
|
8
|
-
exports.registerFin = registerFin;
|
|
9
|
-
function getFin(wire) {
|
|
10
|
-
const fin = finMap.get(wire);
|
|
11
|
-
if (!fin) {
|
|
12
|
-
throw new Error('Could not locate fin api for given transport');
|
|
13
|
-
}
|
|
14
|
-
return fin;
|
|
15
|
-
}
|
|
16
|
-
exports.getFin = getFin;
|