@dynamic-labs/message-transport 3.0.3 → 4.0.0-alpha.1
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/CHANGELOG.md +11 -10
- package/package.json +6 -2
- package/src/index.d.ts +1 -1
- package/src/messageTypes/SecureStorageMessages.d.ts +5 -0
- package/src/messageTypes/index.d.ts +1 -0
- package/src/requestChannel/requestChannel.cjs +63 -6
- package/src/requestChannel/requestChannel.d.ts +39 -6
- package/src/requestChannel/requestChannel.js +62 -7
- package/src/utils/logger.cjs +10 -0
- package/src/utils/logger.d.ts +2 -0
- package/src/utils/logger.js +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
## [4.0.0-alpha.1](https://github.com/dynamic-labs/DynamicAuth/compare/v4.0.0-alpha.0...v4.0.0-alpha.1) (2024-09-17)
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
###
|
|
6
|
-
|
|
7
|
-
* deeplinking for magic eden ethereum and btc ([#6919](https://github.com/dynamic-labs/DynamicAuth/issues/6919)) ([822efaa](https://github.com/dynamic-labs/DynamicAuth/commit/822efaabdec4415a031afabeef13b66ae7d3cd7c))
|
|
8
|
-
* sendBitcoin for unisat ([#6903](https://github.com/dynamic-labs/DynamicAuth/issues/6903)) ([71f726d](https://github.com/dynamic-labs/DynamicAuth/commit/71f726df7d8ff8307048ba1390c4847a9b16ce64))
|
|
5
|
+
### Features
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
* blockaid website scanning for global connectivity ([#6874](https://github.com/dynamic-labs/DynamicAuth/issues/6874)) ([f8cbabd](https://github.com/dynamic-labs/DynamicAuth/commit/f8cbabd92fd4b5b096f47ff8e24c572ad7720dd8))
|
|
11
8
|
|
|
12
9
|
|
|
13
10
|
### Bug Fixes
|
|
14
11
|
|
|
15
|
-
*
|
|
12
|
+
* deeplinking on ethereum and bitcoin sats connector ([#6917](https://github.com/dynamic-labs/DynamicAuth/issues/6917)) ([3896c3a](https://github.com/dynamic-labs/DynamicAuth/commit/3896c3a97819459da74dc5b4771796d7991c1f07))
|
|
13
|
+
* emit walletAdded event when createEmbeddedWalletAccount called ([#6922](https://github.com/dynamic-labs/DynamicAuth/issues/6922)) ([2a8bdd6](https://github.com/dynamic-labs/DynamicAuth/commit/2a8bdd68c50efd946c6f9b398dfae2b3585db34f))
|
|
14
|
+
* interface for sendBitcoin on unisat ([37a1bc2](https://github.com/dynamic-labs/DynamicAuth/commit/37a1bc216f43eef817c40e23b9161327f9d29c59))
|
|
15
|
+
* remove ballet crypto and duplicate keplr entry ([#6906](https://github.com/dynamic-labs/DynamicAuth/issues/6906)) ([14aeeea](https://github.com/dynamic-labs/DynamicAuth/commit/14aeeeaa8d906344f4aeddf9e73527df346b9ea0))
|
|
16
|
+
* solana and cosmos signers not working properly ([#6898](https://github.com/dynamic-labs/DynamicAuth/issues/6898)) ([6f07981](https://github.com/dynamic-labs/DynamicAuth/commit/6f079811c0d7e45b97d2dae72f4141268ab4fe0c))
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
## [4.0.0-alpha.0](https://github.com/dynamic-labs/DynamicAuth/compare/v3.0.0...v4.0.0-alpha.0) (2024-09-13)
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
### Bug Fixes
|
|
21
22
|
|
|
22
|
-
* create v2 embedded wallet experience in manual mode ([#6887](https://github.com/dynamic-labs/DynamicAuth/issues/6887)) ([
|
|
23
|
-
* solana pk export format ([#6888](https://github.com/dynamic-labs/DynamicAuth/issues/6888)) ([
|
|
23
|
+
* create v2 embedded wallet experience in manual mode ([#6887](https://github.com/dynamic-labs/DynamicAuth/issues/6887)) ([8b0953a](https://github.com/dynamic-labs/DynamicAuth/commit/8b0953ac6d511ca254e01da689beb46faa68cf02))
|
|
24
|
+
* solana pk export format ([#6888](https://github.com/dynamic-labs/DynamicAuth/issues/6888)) ([31a5fe2](https://github.com/dynamic-labs/DynamicAuth/commit/31a5fe272cbfabf8e5d90bc8f18dcf0fff504fd1))
|
|
24
25
|
|
|
25
26
|
## [3.0.0](https://github.com/dynamic-labs/DynamicAuth/compare/v3.0.0-alpha.68...v3.0.0) (2024-09-13)
|
|
26
27
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/message-transport",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-alpha.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/dynamic-labs/dynamic-auth.git",
|
|
@@ -27,7 +27,11 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@vue/reactivity": "3.4.21",
|
|
30
|
-
"@dynamic-labs/types": "
|
|
30
|
+
"@dynamic-labs/types": "4.0.0-alpha.1",
|
|
31
31
|
"eventemitter3": "5.0.1"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@dynamic-labs/logger": "4.0.0-alpha.1",
|
|
35
|
+
"@dynamic-labs/utils": "4.0.0-alpha.1"
|
|
32
36
|
}
|
|
33
37
|
}
|
package/src/index.d.ts
CHANGED
|
@@ -5,4 +5,4 @@ export { parseMessageTransportData } from './utils/parseMessageTransportData';
|
|
|
5
5
|
export { serializeErrorForTransport } from './utils/serializeErrorForTransport';
|
|
6
6
|
export { createEventEmitterForMessages, createStore, createStoreSetter, type CreateStoreProps, type MessagesForEventEmitter, } from './store';
|
|
7
7
|
export type { Store, StoreEventListeners, StoreKeys, StoreSetter, StoreStateChangeEvent, StoreStateEvents, StoreStateGetters, } from './store/types';
|
|
8
|
-
export { sdkHasLoadedEventName, type AuthModuleMessages, type AuthModuleState, type ClientManifest, type ConsoleMessages, type EmailOtpParams, type EmbeddedWalletsModuleMessages, type EmbeddedWalletsModuleState, type EthMessages, type EthRequestWithAddressParams, type EthRequestWithChainIdParams, type ExternalAuthMessages, type FetchMessages, type NetworksModuleState, type OtpMessages, type PasskeyMessages, type PlatformServiceMessages, type SdkModuleMessages, type SdkModuleState, type SignInWithExternalJwtParams, type SmsOtpParams, type SocialAuthModuleMessages, type SocialProvider, type SolanaMessages, type UserInterfaceModuleMessages, type VerifyWithExternalJwtParams, type WalletsModuleMessages, type WalletsModuleState, type WebViewVisibilityMessages, } from './messageTypes';
|
|
8
|
+
export { sdkHasLoadedEventName, type AuthModuleMessages, type AuthModuleState, type ClientManifest, type ConsoleMessages, type EmailOtpParams, type EmbeddedWalletsModuleMessages, type EmbeddedWalletsModuleState, type EthMessages, type EthRequestWithAddressParams, type EthRequestWithChainIdParams, type ExternalAuthMessages, type FetchMessages, type NetworksModuleState, type OtpMessages, type PasskeyMessages, type PlatformServiceMessages, type SdkModuleMessages, type SdkModuleState, type SignInWithExternalJwtParams, type SmsOtpParams, type SecureStorageMessages, type SocialAuthModuleMessages, type SocialProvider, type SolanaMessages, type UserInterfaceModuleMessages, type VerifyWithExternalJwtParams, type WalletsModuleMessages, type WalletsModuleState, type WebViewVisibilityMessages, } from './messageTypes';
|
|
@@ -9,6 +9,7 @@ export * from './OtpMessages';
|
|
|
9
9
|
export * from './PasskeyMessages';
|
|
10
10
|
export * from './PlatformServiceMessages';
|
|
11
11
|
export * from './SdkModuleMessages';
|
|
12
|
+
export * from './SecureStorageMessages';
|
|
12
13
|
export * from './SocialAuthModuleMessages';
|
|
13
14
|
export * from './SolanaMessages';
|
|
14
15
|
export * from './UserInterfaceModuleMessages';
|
|
@@ -4,14 +4,32 @@
|
|
|
4
4
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
5
|
|
|
6
6
|
var _tslib = require('../../_virtual/_tslib.cjs');
|
|
7
|
+
var utils = require('@dynamic-labs/utils');
|
|
8
|
+
var isSerializedError = require('../utils/isSerializedError/isSerializedError.cjs');
|
|
9
|
+
var logger = require('../utils/logger.cjs');
|
|
7
10
|
var parseErrorFromTransport = require('../utils/parseErrorFromTransport/parseErrorFromTransport.cjs');
|
|
8
11
|
var serializeErrorForTransport = require('../utils/serializeErrorForTransport/serializeErrorForTransport.cjs');
|
|
9
|
-
var isSerializedError = require('../utils/isSerializedError/isSerializedError.cjs');
|
|
10
12
|
|
|
11
13
|
/** Given a request event name, returns the event name for its resolve */
|
|
12
14
|
const getResolveMessageType = (type) => `${type}__resolve`;
|
|
13
15
|
/** Given a request event name, returns the event name for its reject */
|
|
14
16
|
const getRejectMessageType = (type) => `${type}__reject`;
|
|
17
|
+
/** Given a request event name, returns the event name for its acknowledgement */
|
|
18
|
+
const getAckMessageType = (type) => `${type}__ack`;
|
|
19
|
+
/** Returns a "no handlers registered" error for a message type */
|
|
20
|
+
const createNoHandlerError = (type, cleanup) => {
|
|
21
|
+
const message = `No handlers were registered for message of type ${type}`;
|
|
22
|
+
logger.logger.error(message);
|
|
23
|
+
cleanup();
|
|
24
|
+
return new utils.RequestChannelNotHandledError(message);
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* When a request is sent, a timer will be started. If it times out before
|
|
28
|
+
* a corresponding ack message is received, we reject the request with NO_HANDLERS_REGISTERED.
|
|
29
|
+
*
|
|
30
|
+
* This controls how many ms we should wait before we time out.
|
|
31
|
+
*/
|
|
32
|
+
const TIMEOUT_DURATION = 3000;
|
|
15
33
|
/**
|
|
16
34
|
* Allows handling and submitting requests to and from a webview.
|
|
17
35
|
* Requests are messages that (can) expect some response.
|
|
@@ -37,22 +55,50 @@ const createRequestChannel = (messageTransport) => {
|
|
|
37
55
|
const idPrefix = Math.random().toString();
|
|
38
56
|
/** Always returns a different string */
|
|
39
57
|
const getUniqueId = () => `${idPrefix}-${uniqueIdCounter++}`;
|
|
58
|
+
/** Maps a request's session ID to its time out timer */
|
|
59
|
+
const timeoutMap = {};
|
|
40
60
|
return {
|
|
41
|
-
emit: (
|
|
61
|
+
emit: (requestType, ...params) => new Promise((resolve, reject) => {
|
|
42
62
|
// Generate the unique id for this message exchange session
|
|
43
63
|
// Although we won't listen for a response, it must still be unique
|
|
44
64
|
// to avoid tangling with other requests.
|
|
45
65
|
const messageSessionId = getUniqueId();
|
|
66
|
+
const ackMessageType = getAckMessageType(requestType);
|
|
67
|
+
// Before actually emitting the event, we start listening to the
|
|
68
|
+
// response events
|
|
69
|
+
const handleMessage = ({ messageSessionId: incomingSessionId, type: incomingType, }) => {
|
|
70
|
+
if (incomingSessionId !== messageSessionId ||
|
|
71
|
+
incomingType !== ackMessageType)
|
|
72
|
+
return;
|
|
73
|
+
clearTimeout(timeoutMap[messageSessionId]);
|
|
74
|
+
delete timeoutMap[messageSessionId];
|
|
75
|
+
resolve();
|
|
76
|
+
cleanup();
|
|
77
|
+
};
|
|
78
|
+
const cleanup = () => messageTransport.off(handleMessage);
|
|
79
|
+
messageTransport.on(handleMessage);
|
|
80
|
+
// Now we emit the event to set off the request
|
|
46
81
|
messageTransport.emit({
|
|
47
82
|
args: params,
|
|
48
83
|
messageSessionId,
|
|
49
|
-
type:
|
|
84
|
+
type: requestType,
|
|
50
85
|
});
|
|
51
|
-
|
|
86
|
+
// And start the time out timer
|
|
87
|
+
const timeoutTimer = setTimeout(() => {
|
|
88
|
+
reject(createNoHandlerError(requestType, cleanup));
|
|
89
|
+
}, TIMEOUT_DURATION);
|
|
90
|
+
timeoutMap[messageSessionId] = timeoutTimer;
|
|
91
|
+
}),
|
|
52
92
|
handle: (requestType, handler) => {
|
|
53
93
|
const messageHandler = (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ args, messageSessionId, type: incomingType, }) {
|
|
54
94
|
if (requestType !== incomingType)
|
|
55
95
|
return;
|
|
96
|
+
// Emit an Ack since the message will time out unless some handler acks it in time
|
|
97
|
+
messageTransport.emit({
|
|
98
|
+
args: [],
|
|
99
|
+
messageSessionId,
|
|
100
|
+
type: getAckMessageType(requestType),
|
|
101
|
+
});
|
|
56
102
|
const result = handler(...args);
|
|
57
103
|
// If the handler doesn't return a promise,
|
|
58
104
|
// that means we don't need to respond.
|
|
@@ -79,20 +125,26 @@ const createRequestChannel = (messageTransport) => {
|
|
|
79
125
|
messageTransport.off(messageHandler);
|
|
80
126
|
};
|
|
81
127
|
},
|
|
82
|
-
request: (
|
|
83
|
-
const requestType = requestName;
|
|
128
|
+
request: (requestType, ...params) => new Promise((resolve, reject) => {
|
|
84
129
|
// Generate the unique id for this message exchange session
|
|
85
130
|
const messageSessionId = getUniqueId();
|
|
86
131
|
const resolveMessageType = getResolveMessageType(requestType);
|
|
87
132
|
const rejectMessageType = getRejectMessageType(requestType);
|
|
133
|
+
const ackMessageType = getAckMessageType(requestType);
|
|
88
134
|
// Before actually emitting the event, we start listening to the
|
|
89
135
|
// response events
|
|
90
136
|
const handleMessage = ({ args: [result], messageSessionId: incomingSessionId, type: incomingType, }) => {
|
|
91
137
|
if (incomingSessionId !== messageSessionId)
|
|
92
138
|
return;
|
|
139
|
+
if (incomingType === ackMessageType) {
|
|
140
|
+
clearTimeout(timeoutMap[messageSessionId]);
|
|
141
|
+
delete timeoutMap[messageSessionId];
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
93
144
|
if (incomingType === resolveMessageType) {
|
|
94
145
|
resolve(result);
|
|
95
146
|
cleanup();
|
|
147
|
+
return;
|
|
96
148
|
}
|
|
97
149
|
if (incomingType === rejectMessageType) {
|
|
98
150
|
if (isSerializedError.isSerializedError(result)) {
|
|
@@ -112,10 +164,15 @@ const createRequestChannel = (messageTransport) => {
|
|
|
112
164
|
messageSessionId,
|
|
113
165
|
type: requestType,
|
|
114
166
|
});
|
|
167
|
+
// And start the time out timer
|
|
168
|
+
const timeoutTimer = setTimeout(() => reject(createNoHandlerError(requestType, cleanup)), TIMEOUT_DURATION);
|
|
169
|
+
timeoutMap[messageSessionId] = timeoutTimer;
|
|
115
170
|
}),
|
|
116
171
|
};
|
|
117
172
|
};
|
|
118
173
|
|
|
174
|
+
exports.TIMEOUT_DURATION = TIMEOUT_DURATION;
|
|
119
175
|
exports.createRequestChannel = createRequestChannel;
|
|
176
|
+
exports.getAckMessageType = getAckMessageType;
|
|
120
177
|
exports.getRejectMessageType = getRejectMessageType;
|
|
121
178
|
exports.getResolveMessageType = getResolveMessageType;
|
|
@@ -7,25 +7,49 @@ export type RequestTypes = Record<string, (...params: any[]) => Promise<any> | v
|
|
|
7
7
|
* Only the request types from T that return promises
|
|
8
8
|
* i.e. those that expect a response
|
|
9
9
|
*/
|
|
10
|
-
type TypesExpectingResponse<T extends RequestTypes> = {
|
|
10
|
+
type TypesExpectingResponse<T extends RequestTypes> = Extract<{
|
|
11
11
|
[K in keyof T]: ReturnType<T[K]> extends Promise<any> ? K : never;
|
|
12
|
-
}[keyof T]
|
|
12
|
+
}[keyof T], string>;
|
|
13
13
|
export type RequestChannel<T extends RequestTypes> = {
|
|
14
14
|
/**
|
|
15
15
|
* Listens to incoming requests of this type, and calls the handler when they arrive.
|
|
16
16
|
* If the type of this request expects some response, the handler must return a promise
|
|
17
17
|
* that resolves to this response.
|
|
18
|
+
*
|
|
18
19
|
* @returns an unsubscribe function.
|
|
19
20
|
*/
|
|
20
|
-
handle: <K extends keyof T
|
|
21
|
+
handle: <K extends Extract<keyof T, string>>(requestType: K, handler: T[K]) => VoidFunction;
|
|
21
22
|
/**
|
|
22
23
|
* Triggers handlers for this request type, with the given params.
|
|
23
|
-
* Doesn't
|
|
24
|
+
* Doesn't expect a response. Resolves as soon as the message is acknowledged by
|
|
25
|
+
* any handler.
|
|
26
|
+
*
|
|
27
|
+
* If no handlers emit an ack for this message, this will reject.
|
|
28
|
+
*
|
|
29
|
+
* Lifetime of an "emit" message:
|
|
30
|
+
* 1. "Emit" message is sent.
|
|
31
|
+
* 2. A handler receives the message.
|
|
32
|
+
* 3. The handler immediately emits an ack message for it, acknowledging it.
|
|
33
|
+
* 4. This method's promise resolves.
|
|
24
34
|
*/
|
|
25
|
-
emit: <K extends keyof T
|
|
35
|
+
emit: <K extends Extract<keyof T, string>>(requestName: K, ...params: Parameters<T[K]>) => Promise<void>;
|
|
26
36
|
/**
|
|
27
37
|
* Triggers handlers for this request type, with the given params.
|
|
28
|
-
*
|
|
38
|
+
* As opposed to emit, this expects a response message. A handler must still
|
|
39
|
+
* acknowledge this message, but the promise will only resolve when the handler
|
|
40
|
+
* emits back a response message. The promise resolves with whatever data was sent
|
|
41
|
+
* in the response.
|
|
42
|
+
*
|
|
43
|
+
* If no handlers emit an ack for this message, or if a handler responds
|
|
44
|
+
* with a failure, this will reject.
|
|
45
|
+
*
|
|
46
|
+
* Lifetime of a "request" message:
|
|
47
|
+
* 1. "Request" message is sent.
|
|
48
|
+
* 2. A handler receives the message.
|
|
49
|
+
* 3. The handler immediately emits an ack message for it, acknowledging it.
|
|
50
|
+
* 4. The handler performs the requested action.
|
|
51
|
+
* 5. The handler emits a response message.
|
|
52
|
+
* 6. This method's promise resolves with the response's data.
|
|
29
53
|
*/
|
|
30
54
|
request: <K extends TypesExpectingResponse<T>>(requestName: K, ...params: Parameters<T[K]>) => ReturnType<T[K]>;
|
|
31
55
|
};
|
|
@@ -33,6 +57,15 @@ export type RequestChannel<T extends RequestTypes> = {
|
|
|
33
57
|
export declare const getResolveMessageType: (type: string) => string;
|
|
34
58
|
/** Given a request event name, returns the event name for its reject */
|
|
35
59
|
export declare const getRejectMessageType: (type: string) => string;
|
|
60
|
+
/** Given a request event name, returns the event name for its acknowledgement */
|
|
61
|
+
export declare const getAckMessageType: (type: string) => string;
|
|
62
|
+
/**
|
|
63
|
+
* When a request is sent, a timer will be started. If it times out before
|
|
64
|
+
* a corresponding ack message is received, we reject the request with NO_HANDLERS_REGISTERED.
|
|
65
|
+
*
|
|
66
|
+
* This controls how many ms we should wait before we time out.
|
|
67
|
+
*/
|
|
68
|
+
export declare const TIMEOUT_DURATION = 3000;
|
|
36
69
|
/**
|
|
37
70
|
* Allows handling and submitting requests to and from a webview.
|
|
38
71
|
* Requests are messages that (can) expect some response.
|
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../_virtual/_tslib.js';
|
|
3
|
+
import { RequestChannelNotHandledError } from '@dynamic-labs/utils';
|
|
4
|
+
import { isSerializedError } from '../utils/isSerializedError/isSerializedError.js';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
3
6
|
import { parseErrorFromTransport } from '../utils/parseErrorFromTransport/parseErrorFromTransport.js';
|
|
4
7
|
import { serializeErrorForTransport } from '../utils/serializeErrorForTransport/serializeErrorForTransport.js';
|
|
5
|
-
import { isSerializedError } from '../utils/isSerializedError/isSerializedError.js';
|
|
6
8
|
|
|
7
9
|
/** Given a request event name, returns the event name for its resolve */
|
|
8
10
|
const getResolveMessageType = (type) => `${type}__resolve`;
|
|
9
11
|
/** Given a request event name, returns the event name for its reject */
|
|
10
12
|
const getRejectMessageType = (type) => `${type}__reject`;
|
|
13
|
+
/** Given a request event name, returns the event name for its acknowledgement */
|
|
14
|
+
const getAckMessageType = (type) => `${type}__ack`;
|
|
15
|
+
/** Returns a "no handlers registered" error for a message type */
|
|
16
|
+
const createNoHandlerError = (type, cleanup) => {
|
|
17
|
+
const message = `No handlers were registered for message of type ${type}`;
|
|
18
|
+
logger.error(message);
|
|
19
|
+
cleanup();
|
|
20
|
+
return new RequestChannelNotHandledError(message);
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* When a request is sent, a timer will be started. If it times out before
|
|
24
|
+
* a corresponding ack message is received, we reject the request with NO_HANDLERS_REGISTERED.
|
|
25
|
+
*
|
|
26
|
+
* This controls how many ms we should wait before we time out.
|
|
27
|
+
*/
|
|
28
|
+
const TIMEOUT_DURATION = 3000;
|
|
11
29
|
/**
|
|
12
30
|
* Allows handling and submitting requests to and from a webview.
|
|
13
31
|
* Requests are messages that (can) expect some response.
|
|
@@ -33,22 +51,50 @@ const createRequestChannel = (messageTransport) => {
|
|
|
33
51
|
const idPrefix = Math.random().toString();
|
|
34
52
|
/** Always returns a different string */
|
|
35
53
|
const getUniqueId = () => `${idPrefix}-${uniqueIdCounter++}`;
|
|
54
|
+
/** Maps a request's session ID to its time out timer */
|
|
55
|
+
const timeoutMap = {};
|
|
36
56
|
return {
|
|
37
|
-
emit: (
|
|
57
|
+
emit: (requestType, ...params) => new Promise((resolve, reject) => {
|
|
38
58
|
// Generate the unique id for this message exchange session
|
|
39
59
|
// Although we won't listen for a response, it must still be unique
|
|
40
60
|
// to avoid tangling with other requests.
|
|
41
61
|
const messageSessionId = getUniqueId();
|
|
62
|
+
const ackMessageType = getAckMessageType(requestType);
|
|
63
|
+
// Before actually emitting the event, we start listening to the
|
|
64
|
+
// response events
|
|
65
|
+
const handleMessage = ({ messageSessionId: incomingSessionId, type: incomingType, }) => {
|
|
66
|
+
if (incomingSessionId !== messageSessionId ||
|
|
67
|
+
incomingType !== ackMessageType)
|
|
68
|
+
return;
|
|
69
|
+
clearTimeout(timeoutMap[messageSessionId]);
|
|
70
|
+
delete timeoutMap[messageSessionId];
|
|
71
|
+
resolve();
|
|
72
|
+
cleanup();
|
|
73
|
+
};
|
|
74
|
+
const cleanup = () => messageTransport.off(handleMessage);
|
|
75
|
+
messageTransport.on(handleMessage);
|
|
76
|
+
// Now we emit the event to set off the request
|
|
42
77
|
messageTransport.emit({
|
|
43
78
|
args: params,
|
|
44
79
|
messageSessionId,
|
|
45
|
-
type:
|
|
80
|
+
type: requestType,
|
|
46
81
|
});
|
|
47
|
-
|
|
82
|
+
// And start the time out timer
|
|
83
|
+
const timeoutTimer = setTimeout(() => {
|
|
84
|
+
reject(createNoHandlerError(requestType, cleanup));
|
|
85
|
+
}, TIMEOUT_DURATION);
|
|
86
|
+
timeoutMap[messageSessionId] = timeoutTimer;
|
|
87
|
+
}),
|
|
48
88
|
handle: (requestType, handler) => {
|
|
49
89
|
const messageHandler = (_a) => __awaiter(void 0, [_a], void 0, function* ({ args, messageSessionId, type: incomingType, }) {
|
|
50
90
|
if (requestType !== incomingType)
|
|
51
91
|
return;
|
|
92
|
+
// Emit an Ack since the message will time out unless some handler acks it in time
|
|
93
|
+
messageTransport.emit({
|
|
94
|
+
args: [],
|
|
95
|
+
messageSessionId,
|
|
96
|
+
type: getAckMessageType(requestType),
|
|
97
|
+
});
|
|
52
98
|
const result = handler(...args);
|
|
53
99
|
// If the handler doesn't return a promise,
|
|
54
100
|
// that means we don't need to respond.
|
|
@@ -75,20 +121,26 @@ const createRequestChannel = (messageTransport) => {
|
|
|
75
121
|
messageTransport.off(messageHandler);
|
|
76
122
|
};
|
|
77
123
|
},
|
|
78
|
-
request: (
|
|
79
|
-
const requestType = requestName;
|
|
124
|
+
request: (requestType, ...params) => new Promise((resolve, reject) => {
|
|
80
125
|
// Generate the unique id for this message exchange session
|
|
81
126
|
const messageSessionId = getUniqueId();
|
|
82
127
|
const resolveMessageType = getResolveMessageType(requestType);
|
|
83
128
|
const rejectMessageType = getRejectMessageType(requestType);
|
|
129
|
+
const ackMessageType = getAckMessageType(requestType);
|
|
84
130
|
// Before actually emitting the event, we start listening to the
|
|
85
131
|
// response events
|
|
86
132
|
const handleMessage = ({ args: [result], messageSessionId: incomingSessionId, type: incomingType, }) => {
|
|
87
133
|
if (incomingSessionId !== messageSessionId)
|
|
88
134
|
return;
|
|
135
|
+
if (incomingType === ackMessageType) {
|
|
136
|
+
clearTimeout(timeoutMap[messageSessionId]);
|
|
137
|
+
delete timeoutMap[messageSessionId];
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
89
140
|
if (incomingType === resolveMessageType) {
|
|
90
141
|
resolve(result);
|
|
91
142
|
cleanup();
|
|
143
|
+
return;
|
|
92
144
|
}
|
|
93
145
|
if (incomingType === rejectMessageType) {
|
|
94
146
|
if (isSerializedError(result)) {
|
|
@@ -108,8 +160,11 @@ const createRequestChannel = (messageTransport) => {
|
|
|
108
160
|
messageSessionId,
|
|
109
161
|
type: requestType,
|
|
110
162
|
});
|
|
163
|
+
// And start the time out timer
|
|
164
|
+
const timeoutTimer = setTimeout(() => reject(createNoHandlerError(requestType, cleanup)), TIMEOUT_DURATION);
|
|
165
|
+
timeoutMap[messageSessionId] = timeoutTimer;
|
|
111
166
|
}),
|
|
112
167
|
};
|
|
113
168
|
};
|
|
114
169
|
|
|
115
|
-
export { createRequestChannel, getRejectMessageType, getResolveMessageType };
|
|
170
|
+
export { TIMEOUT_DURATION, createRequestChannel, getAckMessageType, getRejectMessageType, getResolveMessageType };
|