@dynamic-labs/message-transport 2.0.0-alpha.26

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +2899 -0
  2. package/LICENSE +21 -0
  3. package/README.md +3 -0
  4. package/_virtual/_tslib.cjs +35 -0
  5. package/_virtual/_tslib.js +31 -0
  6. package/package.json +28 -0
  7. package/src/index.cjs +21 -0
  8. package/src/index.d.ts +4 -0
  9. package/src/index.js +7 -0
  10. package/src/messageTransport/decorators/applyDefaultMessageOrigin/applyDefaultMessageOrigin.cjs +11 -0
  11. package/src/messageTransport/decorators/applyDefaultMessageOrigin/applyDefaultMessageOrigin.d.ts +15 -0
  12. package/src/messageTransport/decorators/applyDefaultMessageOrigin/applyDefaultMessageOrigin.js +7 -0
  13. package/src/messageTransport/decorators/applyDefaultMessageOrigin/index.d.ts +1 -0
  14. package/src/messageTransport/decorators/index.d.ts +3 -0
  15. package/src/messageTransport/decorators/makeWaitForInitEvent/index.d.ts +1 -0
  16. package/src/messageTransport/decorators/makeWaitForInitEvent/makeWaitForInitEvent.cjs +34 -0
  17. package/src/messageTransport/decorators/makeWaitForInitEvent/makeWaitForInitEvent.d.ts +25 -0
  18. package/src/messageTransport/decorators/makeWaitForInitEvent/makeWaitForInitEvent.js +30 -0
  19. package/src/messageTransport/decorators/makeWaitForUnblock/index.d.ts +1 -0
  20. package/src/messageTransport/decorators/makeWaitForUnblock/makeWaitForUnblock.cjs +52 -0
  21. package/src/messageTransport/decorators/makeWaitForUnblock/makeWaitForUnblock.d.ts +23 -0
  22. package/src/messageTransport/decorators/makeWaitForUnblock/makeWaitForUnblock.js +48 -0
  23. package/src/messageTransport/index.d.ts +2 -0
  24. package/src/messageTransport/messageTransport.cjs +15 -0
  25. package/src/messageTransport/messageTransport.d.ts +44 -0
  26. package/src/messageTransport/messageTransport.js +11 -0
  27. package/src/messageTypes/SdkModuleMessages.cjs +8 -0
  28. package/src/messageTypes/SdkModuleMessages.d.ts +20 -0
  29. package/src/messageTypes/SdkModuleMessages.js +4 -0
  30. package/src/messageTypes/index.d.ts +1 -0
  31. package/src/requestChannel/index.d.ts +1 -0
  32. package/src/requestChannel/requestChannel.cjs +112 -0
  33. package/src/requestChannel/requestChannel.d.ts +55 -0
  34. package/src/requestChannel/requestChannel.js +106 -0
  35. package/src/utils/parseMessageTransportData/index.d.ts +1 -0
  36. package/src/utils/parseMessageTransportData/parseMessageTransportData.cjs +26 -0
  37. package/src/utils/parseMessageTransportData/parseMessageTransportData.d.ts +2 -0
  38. package/src/utils/parseMessageTransportData/parseMessageTransportData.js +22 -0
@@ -0,0 +1,112 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _tslib = require('../../_virtual/_tslib.cjs');
6
+
7
+ /** Given a request event name, returns the event name for its resolve */
8
+ const getResolveMessageType = (type) => `${type}__resolve`;
9
+ /** Given a request event name, returns the event name for its reject */
10
+ const getRejectMessageType = (type) => `${type}__reject`;
11
+ /**
12
+ * Allows handling and submitting requests to and from a webview.
13
+ * Requests are messages that (can) expect some response.
14
+ *
15
+ * Functions similarly to an event emitter, but adds a response feature:
16
+ * - Emitting an event type is the act of making a "request" of a specific type,
17
+ * and it returns a promise that will resolve to the request's response.
18
+ * - Listening to an event type is the act of "handling" requests of a specific type.
19
+ * This handler callback must return a promise if this request type expects responses.
20
+ *
21
+ * Think of it this way:
22
+ * Whenever I emit an event, I am submitting a request.
23
+ * Whoever listens to the event will handle my request.
24
+ * If the request type expects some kind of response, they will
25
+ * return a promise that resolves (or rejects) after my request is fulfilled.
26
+ *
27
+ * This is an abstraction built on top of the MessageTransport interface.
28
+ */
29
+ const createRequestChannel = (messageTransport) => {
30
+ /** Used to generated unique ids */
31
+ let uniqueIdCounter = 0;
32
+ /** Id prefix unique to this channel */
33
+ const idPrefix = Math.random().toString();
34
+ /** Always returns a different string */
35
+ const getUniqueId = () => `${idPrefix}-${uniqueIdCounter++}`;
36
+ return {
37
+ emit: (requestName, ...params) => {
38
+ // Generate the unique id for this message exchange session
39
+ // Although we won't listen for a response, it must still be unique
40
+ // to avoid tangling with other requests.
41
+ const messageSessionId = getUniqueId();
42
+ messageTransport.emit({
43
+ args: params,
44
+ messageSessionId,
45
+ type: requestName,
46
+ });
47
+ },
48
+ handle: (requestType, handler) => {
49
+ const messageHandler = ({ args, messageSessionId, type: incomingType, }) => _tslib.__awaiter(void 0, void 0, void 0, function* () {
50
+ if (requestType !== incomingType)
51
+ return;
52
+ const result = handler(...args);
53
+ // If the handler doesn't return a promise,
54
+ // that means we don't need to respond.
55
+ if (!(result instanceof Promise))
56
+ return;
57
+ try {
58
+ const response = yield result;
59
+ messageTransport.emit({
60
+ args: [response],
61
+ messageSessionId,
62
+ type: getResolveMessageType(requestType),
63
+ });
64
+ }
65
+ catch (error) {
66
+ messageTransport.emit({
67
+ args: [error],
68
+ messageSessionId,
69
+ type: getRejectMessageType(requestType),
70
+ });
71
+ }
72
+ });
73
+ messageTransport.on(messageHandler);
74
+ return () => {
75
+ messageTransport.off(messageHandler);
76
+ };
77
+ },
78
+ request: (requestName, ...params) => new Promise((resolve, reject) => {
79
+ const requestType = requestName;
80
+ // Generate the unique id for this message exchange session
81
+ const messageSessionId = getUniqueId();
82
+ const resolveMessageType = getResolveMessageType(requestType);
83
+ const rejectMessageType = getRejectMessageType(requestType);
84
+ // Before actually emitting the event, we start listening to the
85
+ // response events
86
+ const handleMessage = ({ args: [result], messageSessionId: incomingSessionId, type: incomingType, }) => {
87
+ if (incomingSessionId !== messageSessionId)
88
+ return;
89
+ if (incomingType === resolveMessageType) {
90
+ resolve(result);
91
+ cleanup();
92
+ }
93
+ if (incomingType === rejectMessageType) {
94
+ reject(result);
95
+ cleanup();
96
+ }
97
+ };
98
+ const cleanup = () => messageTransport.off(handleMessage);
99
+ messageTransport.on(handleMessage);
100
+ // Now we emit the event to set off the request
101
+ messageTransport.emit({
102
+ args: params,
103
+ messageSessionId,
104
+ type: requestType,
105
+ });
106
+ }),
107
+ };
108
+ };
109
+
110
+ exports.createRequestChannel = createRequestChannel;
111
+ exports.getRejectMessageType = getRejectMessageType;
112
+ exports.getResolveMessageType = getResolveMessageType;
@@ -0,0 +1,55 @@
1
+ import { MessageTransportWithDefaultOrigin } from '../messageTransport/decorators/applyDefaultMessageOrigin/applyDefaultMessageOrigin';
2
+ /**
3
+ * An object that defines request types, and whether they expect a response
4
+ */
5
+ export type RequestTypes = Record<string, (...params: any[]) => Promise<any> | void>;
6
+ /**
7
+ * Only the request types from T that return promises
8
+ * i.e. those that expect a response
9
+ */
10
+ type TypesExpectingResponse<T extends RequestTypes> = {
11
+ [K in keyof T]: ReturnType<T[K]> extends Promise<any> ? K : never;
12
+ }[keyof T];
13
+ export type RequestChannel<T extends RequestTypes> = {
14
+ /**
15
+ * Listens to incoming requests of this type, and calls the handler when they arrive.
16
+ * If the type of this request expects some response, the handler must return a promise
17
+ * that resolves to this response.
18
+ * @returns an unsubscribe function.
19
+ */
20
+ handle: <K extends keyof T>(requestType: K, handler: T[K]) => VoidFunction;
21
+ /**
22
+ * Triggers handlers for this request type, with the given params.
23
+ * Doesn't care whether this request will have a response or not, so returns void.
24
+ */
25
+ emit: <K extends keyof T>(requestName: K, ...params: Parameters<T[K]>) => void;
26
+ /**
27
+ * Triggers handlers for this request type, with the given params.
28
+ * @returns a promise that resolves/rejects when a handler fulfills this request.
29
+ */
30
+ request: <K extends TypesExpectingResponse<T>>(requestName: K, ...params: Parameters<T[K]>) => ReturnType<T[K]>;
31
+ };
32
+ /** Given a request event name, returns the event name for its resolve */
33
+ export declare const getResolveMessageType: (type: string) => string;
34
+ /** Given a request event name, returns the event name for its reject */
35
+ export declare const getRejectMessageType: (type: string) => string;
36
+ /**
37
+ * Allows handling and submitting requests to and from a webview.
38
+ * Requests are messages that (can) expect some response.
39
+ *
40
+ * Functions similarly to an event emitter, but adds a response feature:
41
+ * - Emitting an event type is the act of making a "request" of a specific type,
42
+ * and it returns a promise that will resolve to the request's response.
43
+ * - Listening to an event type is the act of "handling" requests of a specific type.
44
+ * This handler callback must return a promise if this request type expects responses.
45
+ *
46
+ * Think of it this way:
47
+ * Whenever I emit an event, I am submitting a request.
48
+ * Whoever listens to the event will handle my request.
49
+ * If the request type expects some kind of response, they will
50
+ * return a promise that resolves (or rejects) after my request is fulfilled.
51
+ *
52
+ * This is an abstraction built on top of the MessageTransport interface.
53
+ */
54
+ export declare const createRequestChannel: <T extends RequestTypes = never>(messageTransport: MessageTransportWithDefaultOrigin) => RequestChannel<T>;
55
+ export {};
@@ -0,0 +1,106 @@
1
+ import { __awaiter } from '../../_virtual/_tslib.js';
2
+
3
+ /** Given a request event name, returns the event name for its resolve */
4
+ const getResolveMessageType = (type) => `${type}__resolve`;
5
+ /** Given a request event name, returns the event name for its reject */
6
+ const getRejectMessageType = (type) => `${type}__reject`;
7
+ /**
8
+ * Allows handling and submitting requests to and from a webview.
9
+ * Requests are messages that (can) expect some response.
10
+ *
11
+ * Functions similarly to an event emitter, but adds a response feature:
12
+ * - Emitting an event type is the act of making a "request" of a specific type,
13
+ * and it returns a promise that will resolve to the request's response.
14
+ * - Listening to an event type is the act of "handling" requests of a specific type.
15
+ * This handler callback must return a promise if this request type expects responses.
16
+ *
17
+ * Think of it this way:
18
+ * Whenever I emit an event, I am submitting a request.
19
+ * Whoever listens to the event will handle my request.
20
+ * If the request type expects some kind of response, they will
21
+ * return a promise that resolves (or rejects) after my request is fulfilled.
22
+ *
23
+ * This is an abstraction built on top of the MessageTransport interface.
24
+ */
25
+ const createRequestChannel = (messageTransport) => {
26
+ /** Used to generated unique ids */
27
+ let uniqueIdCounter = 0;
28
+ /** Id prefix unique to this channel */
29
+ const idPrefix = Math.random().toString();
30
+ /** Always returns a different string */
31
+ const getUniqueId = () => `${idPrefix}-${uniqueIdCounter++}`;
32
+ return {
33
+ emit: (requestName, ...params) => {
34
+ // Generate the unique id for this message exchange session
35
+ // Although we won't listen for a response, it must still be unique
36
+ // to avoid tangling with other requests.
37
+ const messageSessionId = getUniqueId();
38
+ messageTransport.emit({
39
+ args: params,
40
+ messageSessionId,
41
+ type: requestName,
42
+ });
43
+ },
44
+ handle: (requestType, handler) => {
45
+ const messageHandler = ({ args, messageSessionId, type: incomingType, }) => __awaiter(void 0, void 0, void 0, function* () {
46
+ if (requestType !== incomingType)
47
+ return;
48
+ const result = handler(...args);
49
+ // If the handler doesn't return a promise,
50
+ // that means we don't need to respond.
51
+ if (!(result instanceof Promise))
52
+ return;
53
+ try {
54
+ const response = yield result;
55
+ messageTransport.emit({
56
+ args: [response],
57
+ messageSessionId,
58
+ type: getResolveMessageType(requestType),
59
+ });
60
+ }
61
+ catch (error) {
62
+ messageTransport.emit({
63
+ args: [error],
64
+ messageSessionId,
65
+ type: getRejectMessageType(requestType),
66
+ });
67
+ }
68
+ });
69
+ messageTransport.on(messageHandler);
70
+ return () => {
71
+ messageTransport.off(messageHandler);
72
+ };
73
+ },
74
+ request: (requestName, ...params) => new Promise((resolve, reject) => {
75
+ const requestType = requestName;
76
+ // Generate the unique id for this message exchange session
77
+ const messageSessionId = getUniqueId();
78
+ const resolveMessageType = getResolveMessageType(requestType);
79
+ const rejectMessageType = getRejectMessageType(requestType);
80
+ // Before actually emitting the event, we start listening to the
81
+ // response events
82
+ const handleMessage = ({ args: [result], messageSessionId: incomingSessionId, type: incomingType, }) => {
83
+ if (incomingSessionId !== messageSessionId)
84
+ return;
85
+ if (incomingType === resolveMessageType) {
86
+ resolve(result);
87
+ cleanup();
88
+ }
89
+ if (incomingType === rejectMessageType) {
90
+ reject(result);
91
+ cleanup();
92
+ }
93
+ };
94
+ const cleanup = () => messageTransport.off(handleMessage);
95
+ messageTransport.on(handleMessage);
96
+ // Now we emit the event to set off the request
97
+ messageTransport.emit({
98
+ args: params,
99
+ messageSessionId,
100
+ type: requestType,
101
+ });
102
+ }),
103
+ };
104
+ };
105
+
106
+ export { createRequestChannel, getRejectMessageType, getResolveMessageType };
@@ -0,0 +1 @@
1
+ export * from './parseMessageTransportData';
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const parseMessageTransportData = (
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ parsedData) => {
8
+ if (!parsedData || typeof parsedData !== 'object') {
9
+ return undefined;
10
+ }
11
+ const message = {
12
+ args: parsedData.args,
13
+ messageSessionId: parsedData.messageSessionId,
14
+ origin: parsedData.origin,
15
+ type: parsedData.type,
16
+ };
17
+ if (!Array.isArray(message.args) ||
18
+ typeof message.messageSessionId !== 'string' ||
19
+ typeof message.origin !== 'string' ||
20
+ typeof message.type !== 'string') {
21
+ return undefined;
22
+ }
23
+ return message;
24
+ };
25
+
26
+ exports.parseMessageTransportData = parseMessageTransportData;
@@ -0,0 +1,2 @@
1
+ import { MessageTransportData } from '../../messageTransport';
2
+ export declare const parseMessageTransportData: (parsedData: any) => MessageTransportData | undefined;
@@ -0,0 +1,22 @@
1
+ const parseMessageTransportData = (
2
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3
+ parsedData) => {
4
+ if (!parsedData || typeof parsedData !== 'object') {
5
+ return undefined;
6
+ }
7
+ const message = {
8
+ args: parsedData.args,
9
+ messageSessionId: parsedData.messageSessionId,
10
+ origin: parsedData.origin,
11
+ type: parsedData.type,
12
+ };
13
+ if (!Array.isArray(message.args) ||
14
+ typeof message.messageSessionId !== 'string' ||
15
+ typeof message.origin !== 'string' ||
16
+ typeof message.type !== 'string') {
17
+ return undefined;
18
+ }
19
+ return message;
20
+ };
21
+
22
+ export { parseMessageTransportData };