@dynamic-labs/message-transport 0.0.0-exp20240808.0

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 (78) hide show
  1. package/CHANGELOG.md +3746 -0
  2. package/LICENSE +21 -0
  3. package/README.md +3 -0
  4. package/_virtual/_tslib.cjs +49 -0
  5. package/_virtual/_tslib.js +44 -0
  6. package/package.json +33 -0
  7. package/src/index.cjs +32 -0
  8. package/src/index.d.ts +8 -0
  9. package/src/index.js +13 -0
  10. package/src/messageTransport/decorators/applyDefaultMessageOrigin/applyDefaultMessageOrigin.cjs +12 -0
  11. package/src/messageTransport/decorators/applyDefaultMessageOrigin/applyDefaultMessageOrigin.d.ts +15 -0
  12. package/src/messageTransport/decorators/applyDefaultMessageOrigin/applyDefaultMessageOrigin.js +8 -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 +35 -0
  17. package/src/messageTransport/decorators/makeWaitForInitEvent/makeWaitForInitEvent.d.ts +25 -0
  18. package/src/messageTransport/decorators/makeWaitForInitEvent/makeWaitForInitEvent.js +31 -0
  19. package/src/messageTransport/decorators/makeWaitForUnblock/index.d.ts +1 -0
  20. package/src/messageTransport/decorators/makeWaitForUnblock/makeWaitForUnblock.cjs +53 -0
  21. package/src/messageTransport/decorators/makeWaitForUnblock/makeWaitForUnblock.d.ts +23 -0
  22. package/src/messageTransport/decorators/makeWaitForUnblock/makeWaitForUnblock.js +49 -0
  23. package/src/messageTransport/index.d.ts +2 -0
  24. package/src/messageTransport/messageTransport.cjs +16 -0
  25. package/src/messageTransport/messageTransport.d.ts +44 -0
  26. package/src/messageTransport/messageTransport.js +12 -0
  27. package/src/messageTypes/AuthModuleMessages.d.ts +8 -0
  28. package/src/messageTypes/ConsoleMessages.d.ts +11 -0
  29. package/src/messageTypes/EmbeddedWalletsModuleMessages.d.ts +8 -0
  30. package/src/messageTypes/EthMessages.d.ts +13 -0
  31. package/src/messageTypes/ExternalAuthMessages.d.ts +16 -0
  32. package/src/messageTypes/FetchMessages.d.ts +8 -0
  33. package/src/messageTypes/NetworksModuleMessages.d.ts +5 -0
  34. package/src/messageTypes/OtpMessages.d.ts +17 -0
  35. package/src/messageTypes/PasskeyMessages.d.ts +32 -0
  36. package/src/messageTypes/PlatformServiceMessages.d.ts +17 -0
  37. package/src/messageTypes/SdkModuleMessages.cjs +9 -0
  38. package/src/messageTypes/SdkModuleMessages.d.ts +25 -0
  39. package/src/messageTypes/SdkModuleMessages.js +5 -0
  40. package/src/messageTypes/SocialAuthModuleMessages.d.ts +17 -0
  41. package/src/messageTypes/SolanaMessages.d.ts +42 -0
  42. package/src/messageTypes/UserInterfaceModuleMessages.d.ts +8 -0
  43. package/src/messageTypes/WalletsModuleMessages.d.ts +30 -0
  44. package/src/messageTypes/WebViewVisibilityMessages.d.ts +3 -0
  45. package/src/messageTypes/index.d.ts +16 -0
  46. package/src/requestChannel/index.d.ts +1 -0
  47. package/src/requestChannel/requestChannel.cjs +121 -0
  48. package/src/requestChannel/requestChannel.d.ts +55 -0
  49. package/src/requestChannel/requestChannel.js +115 -0
  50. package/src/store/createEventEmitterForMessages/createEventEmitterForMessages.cjs +24 -0
  51. package/src/store/createEventEmitterForMessages/createEventEmitterForMessages.d.ts +22 -0
  52. package/src/store/createEventEmitterForMessages/createEventEmitterForMessages.js +16 -0
  53. package/src/store/createEventEmitterForMessages/index.d.ts +1 -0
  54. package/src/store/index.d.ts +3 -0
  55. package/src/store/store.cjs +59 -0
  56. package/src/store/store.d.ts +8 -0
  57. package/src/store/store.js +51 -0
  58. package/src/store/storeSetter/index.d.ts +1 -0
  59. package/src/store/storeSetter/storeSetter.cjs +23 -0
  60. package/src/store/storeSetter/storeSetter.d.ts +8 -0
  61. package/src/store/storeSetter/storeSetter.js +19 -0
  62. package/src/store/types.d.ts +53 -0
  63. package/src/utils/isSerializedError/index.d.ts +1 -0
  64. package/src/utils/isSerializedError/isSerializedError.cjs +14 -0
  65. package/src/utils/isSerializedError/isSerializedError.d.ts +2 -0
  66. package/src/utils/isSerializedError/isSerializedError.js +10 -0
  67. package/src/utils/parseErrorFromTransport/index.d.ts +1 -0
  68. package/src/utils/parseErrorFromTransport/parseErrorFromTransport.cjs +54 -0
  69. package/src/utils/parseErrorFromTransport/parseErrorFromTransport.d.ts +11 -0
  70. package/src/utils/parseErrorFromTransport/parseErrorFromTransport.js +50 -0
  71. package/src/utils/parseMessageTransportData/index.d.ts +1 -0
  72. package/src/utils/parseMessageTransportData/parseMessageTransportData.cjs +27 -0
  73. package/src/utils/parseMessageTransportData/parseMessageTransportData.d.ts +2 -0
  74. package/src/utils/parseMessageTransportData/parseMessageTransportData.js +23 -0
  75. package/src/utils/serializeErrorForTransport/index.d.ts +1 -0
  76. package/src/utils/serializeErrorForTransport/serializeErrorForTransport.cjs +33 -0
  77. package/src/utils/serializeErrorForTransport/serializeErrorForTransport.d.ts +19 -0
  78. package/src/utils/serializeErrorForTransport/serializeErrorForTransport.js +29 -0
@@ -0,0 +1,5 @@
1
+ import { GenericNetwork } from '@dynamic-labs/types';
2
+ export type NetworksModuleState = {
3
+ evm: GenericNetwork[];
4
+ solana: GenericNetwork[];
5
+ };
@@ -0,0 +1,17 @@
1
+ import { OtpDestination, PhoneData } from '@dynamic-labs/types';
2
+ type OtpData = {
3
+ destination: Extract<OtpDestination, 'email'>;
4
+ target: string;
5
+ } | {
6
+ destination: Extract<OtpDestination, 'sms'>;
7
+ target: PhoneData;
8
+ };
9
+ export type OtpMessages = {
10
+ /** Request to send an OTP to a destination for verification */
11
+ sendOTP: (data: OtpData) => Promise<void>;
12
+ /** Performs verification for the latest send OTP */
13
+ verifyOTP: (token: string) => Promise<void>;
14
+ /** Re-sends the OTP for verification */
15
+ resendOTP: () => Promise<void>;
16
+ };
17
+ export {};
@@ -0,0 +1,32 @@
1
+ type CustomPublicKeyCredentialUserEntity = Omit<PublicKeyCredentialUserEntity, 'id'> & {
2
+ id: string;
3
+ };
4
+ type CustomPublicKeyCredentialRpEntity = Omit<PublicKeyCredentialRpEntity, 'id'> & {
5
+ id: string;
6
+ };
7
+ export type PasskeyMessages = {
8
+ createPasskey: (params: {
9
+ publicKey: {
10
+ authenticatorName: string;
11
+ attestation?: AttestationConveyancePreference;
12
+ authenticatorSelection?: AuthenticatorSelectionCriteria;
13
+ challenge?: string;
14
+ pubKeyCredParams: PublicKeyCredentialParameters[];
15
+ rp: CustomPublicKeyCredentialRpEntity;
16
+ timeout?: number;
17
+ user: CustomPublicKeyCredentialUserEntity;
18
+ };
19
+ }) => Promise<{
20
+ attestation: {
21
+ credentialId: string;
22
+ clientDataJson: string;
23
+ attestationObject: string;
24
+ transports: ('AUTHENTICATOR_TRANSPORT_BLE' | 'AUTHENTICATOR_TRANSPORT_INTERNAL' | 'AUTHENTICATOR_TRANSPORT_NFC' | 'AUTHENTICATOR_TRANSPORT_USB' | 'AUTHENTICATOR_TRANSPORT_HYBRID')[];
25
+ };
26
+ }>;
27
+ passkeyStamp: (rdId: string, payload: string) => Promise<{
28
+ stampHeaderName: string;
29
+ stampHeaderValue: string;
30
+ }>;
31
+ };
32
+ export {};
@@ -0,0 +1,17 @@
1
+ export type PlatformServiceMessages = {
2
+ /**
3
+ * Origin: Webview.
4
+ * Requests that a deeplink be open by whichever platform the client is running in.
5
+ */
6
+ openURL: (url: string) => Promise<void>;
7
+ /**
8
+ * Origin: Webview.
9
+ * Opens the URL in a secure browser window for authentication.
10
+ *
11
+ * Resolves with the URL used to deeplink back to this app.
12
+ */
13
+ openAuthenticationWindow: (props: {
14
+ url: string;
15
+ redirectUrl?: string;
16
+ }) => Promise<string>;
17
+ };
@@ -0,0 +1,9 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ /** Easy access to the event name that indicates the SDK has loaded */
7
+ const sdkHasLoadedEventName = 'sdk__loadedChanged';
8
+
9
+ exports.sdkHasLoadedEventName = sdkHasLoadedEventName;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Defines the settings required by the SDK to be properly initialized
3
+ * inside the webview
4
+ */
5
+ export type ClientManifest = {
6
+ apiBaseUrl?: string;
7
+ appLogoUrl?: string;
8
+ appName?: string;
9
+ appOrigin?: string;
10
+ clientVersion: string;
11
+ cssOverrides?: string;
12
+ environmentId: string;
13
+ platform: 'browser' | 'react-native' | 'flutter';
14
+ redirectUrl: string;
15
+ };
16
+ export type SdkModuleState = {
17
+ /** Indicates the SDK is set up and ready for requests */
18
+ loaded: boolean;
19
+ };
20
+ export type SdkModuleMessages = {
21
+ /** Sent from the webview app to request the SDK settings */
22
+ manifest: () => Promise<ClientManifest>;
23
+ };
24
+ /** Easy access to the event name that indicates the SDK has loaded */
25
+ export declare const sdkHasLoadedEventName = "sdk__loadedChanged";
@@ -0,0 +1,5 @@
1
+ 'use client'
2
+ /** Easy access to the event name that indicates the SDK has loaded */
3
+ const sdkHasLoadedEventName = 'sdk__loadedChanged';
4
+
5
+ export { sdkHasLoadedEventName };
@@ -0,0 +1,17 @@
1
+ export type SocialProvider = 'apple' | 'coinbaseSocial' | 'discord' | 'facebook' | 'farcaster' | 'github' | 'google' | 'telegram' | 'twitch' | 'twitter';
2
+ export type SocialAuthModuleMessages = {
3
+ connectWithSocial: (args: {
4
+ /**
5
+ * Provider with which to connect
6
+ */
7
+ provider: SocialProvider;
8
+ /**
9
+ * When using expo-router, which pathname to redirect back to after social connection.
10
+ *
11
+ * The router will create another stack when redirecting back to a different pathname than your
12
+ * app was at originally, which in iOS devices will cause visual flickering. To avoid this, pass
13
+ * `usePathname()` to this property.
14
+ */
15
+ redirectPathname?: string;
16
+ }) => Promise<void>;
17
+ };
@@ -0,0 +1,42 @@
1
+ type Commitment = 'processed' | 'confirmed' | 'finalized' | 'recent' | 'single' | 'singleGossip' | 'root' | 'max';
2
+ type SendOptions = {
3
+ skipPreflight?: boolean;
4
+ preflightCommitment?: Commitment;
5
+ maxRetries?: number;
6
+ minContextSlot?: number;
7
+ };
8
+ type EncodedTransaction = {
9
+ type: 'legacy' | 'versioned';
10
+ transaction: string;
11
+ };
12
+ /**
13
+ * Messages exchanged for solana requests.
14
+ */
15
+ export type SolanaMessages = {
16
+ solana_signMessage: (arg: {
17
+ message: string;
18
+ walletId: string;
19
+ }) => Promise<{
20
+ signature: string;
21
+ }>;
22
+ solana_signAndSendTransaction: (arg: {
23
+ walletId: string;
24
+ options?: SendOptions;
25
+ encodedTransaction: EncodedTransaction;
26
+ }) => Promise<{
27
+ signature: string;
28
+ }>;
29
+ solana_signTransaction: (arg: {
30
+ walletId: string;
31
+ encodedTransaction: EncodedTransaction;
32
+ }) => Promise<{
33
+ encodedTransaction: EncodedTransaction;
34
+ }>;
35
+ solana_signAllTransactions: (arg: {
36
+ walletId: string;
37
+ encodedTransactions: EncodedTransaction[];
38
+ }) => Promise<{
39
+ encodedTransactions: EncodedTransaction[];
40
+ }>;
41
+ };
42
+ export {};
@@ -0,0 +1,8 @@
1
+ export type UserInterfaceModuleMessages = {
2
+ openUserProfile: () => void;
3
+ openAuthFlow: () => void;
4
+ /** Opens the secret key export for embedded wallets */
5
+ revealEmbeddedWalletKey: (params: {
6
+ type: 'recovery-phrase' | 'private-key';
7
+ }) => void;
8
+ };
@@ -0,0 +1,30 @@
1
+ import { BaseWallet } from '@dynamic-labs/types';
2
+ export type WalletsModuleState = {
3
+ userWallets: BaseWallet[];
4
+ primary: BaseWallet | undefined;
5
+ };
6
+ export type WalletsModuleMessages = {
7
+ getBalance: (params: {
8
+ wallet: BaseWallet;
9
+ }) => Promise<{
10
+ balance: string;
11
+ }>;
12
+ signMessage: (params: {
13
+ wallet: BaseWallet;
14
+ message: string;
15
+ }) => Promise<{
16
+ signedMessage: string;
17
+ }>;
18
+ getNetwork: (params: {
19
+ wallet: BaseWallet;
20
+ }) => Promise<{
21
+ network: string | number;
22
+ }>;
23
+ switchNetwork: (params: {
24
+ wallet: BaseWallet;
25
+ chainId: string | number;
26
+ }) => Promise<void>;
27
+ setPrimary: (params: {
28
+ walletId: string;
29
+ }) => Promise<void>;
30
+ };
@@ -0,0 +1,3 @@
1
+ export type WebViewVisibilityMessages = {
2
+ setVisibility: (visible: boolean) => void;
3
+ };
@@ -0,0 +1,16 @@
1
+ export * from './AuthModuleMessages';
2
+ export * from './ConsoleMessages';
3
+ export * from './EmbeddedWalletsModuleMessages';
4
+ export * from './EthMessages';
5
+ export * from './ExternalAuthMessages';
6
+ export * from './FetchMessages';
7
+ export * from './NetworksModuleMessages';
8
+ export * from './OtpMessages';
9
+ export * from './PasskeyMessages';
10
+ export * from './PlatformServiceMessages';
11
+ export * from './SdkModuleMessages';
12
+ export * from './SocialAuthModuleMessages';
13
+ export * from './SolanaMessages';
14
+ export * from './UserInterfaceModuleMessages';
15
+ export * from './WalletsModuleMessages';
16
+ export * from './WebViewVisibilityMessages';
@@ -0,0 +1 @@
1
+ export * from './requestChannel';
@@ -0,0 +1,121 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../_virtual/_tslib.cjs');
7
+ var parseErrorFromTransport = require('../utils/parseErrorFromTransport/parseErrorFromTransport.cjs');
8
+ var serializeErrorForTransport = require('../utils/serializeErrorForTransport/serializeErrorForTransport.cjs');
9
+ var isSerializedError = require('../utils/isSerializedError/isSerializedError.cjs');
10
+
11
+ /** Given a request event name, returns the event name for its resolve */
12
+ const getResolveMessageType = (type) => `${type}__resolve`;
13
+ /** Given a request event name, returns the event name for its reject */
14
+ const getRejectMessageType = (type) => `${type}__reject`;
15
+ /**
16
+ * Allows handling and submitting requests to and from a webview.
17
+ * Requests are messages that (can) expect some response.
18
+ *
19
+ * Functions similarly to an event emitter, but adds a response feature:
20
+ * - Emitting an event type is the act of making a "request" of a specific type,
21
+ * and it returns a promise that will resolve to the request's response.
22
+ * - Listening to an event type is the act of "handling" requests of a specific type.
23
+ * This handler callback must return a promise if this request type expects responses.
24
+ *
25
+ * Think of it this way:
26
+ * Whenever I emit an event, I am submitting a request.
27
+ * Whoever listens to the event will handle my request.
28
+ * If the request type expects some kind of response, they will
29
+ * return a promise that resolves (or rejects) after my request is fulfilled.
30
+ *
31
+ * This is an abstraction built on top of the MessageTransport interface.
32
+ */
33
+ const createRequestChannel = (messageTransport) => {
34
+ /** Used to generated unique ids */
35
+ let uniqueIdCounter = 0;
36
+ /** Id prefix unique to this channel */
37
+ const idPrefix = Math.random().toString();
38
+ /** Always returns a different string */
39
+ const getUniqueId = () => `${idPrefix}-${uniqueIdCounter++}`;
40
+ return {
41
+ emit: (requestName, ...params) => {
42
+ // Generate the unique id for this message exchange session
43
+ // Although we won't listen for a response, it must still be unique
44
+ // to avoid tangling with other requests.
45
+ const messageSessionId = getUniqueId();
46
+ messageTransport.emit({
47
+ args: params,
48
+ messageSessionId,
49
+ type: requestName,
50
+ });
51
+ },
52
+ handle: (requestType, handler) => {
53
+ const messageHandler = (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ args, messageSessionId, type: incomingType, }) {
54
+ if (requestType !== incomingType)
55
+ return;
56
+ const result = handler(...args);
57
+ // If the handler doesn't return a promise,
58
+ // that means we don't need to respond.
59
+ if (!(result instanceof Promise))
60
+ return;
61
+ try {
62
+ const response = yield result;
63
+ messageTransport.emit({
64
+ args: [response],
65
+ messageSessionId,
66
+ type: getResolveMessageType(requestType),
67
+ });
68
+ }
69
+ catch (error) {
70
+ messageTransport.emit({
71
+ args: [serializeErrorForTransport.serializeErrorForTransport(error)],
72
+ messageSessionId,
73
+ type: getRejectMessageType(requestType),
74
+ });
75
+ }
76
+ });
77
+ messageTransport.on(messageHandler);
78
+ return () => {
79
+ messageTransport.off(messageHandler);
80
+ };
81
+ },
82
+ request: (requestName, ...params) => new Promise((resolve, reject) => {
83
+ const requestType = requestName;
84
+ // Generate the unique id for this message exchange session
85
+ const messageSessionId = getUniqueId();
86
+ const resolveMessageType = getResolveMessageType(requestType);
87
+ const rejectMessageType = getRejectMessageType(requestType);
88
+ // Before actually emitting the event, we start listening to the
89
+ // response events
90
+ const handleMessage = ({ args: [result], messageSessionId: incomingSessionId, type: incomingType, }) => {
91
+ if (incomingSessionId !== messageSessionId)
92
+ return;
93
+ if (incomingType === resolveMessageType) {
94
+ resolve(result);
95
+ cleanup();
96
+ }
97
+ if (incomingType === rejectMessageType) {
98
+ if (isSerializedError.isSerializedError(result)) {
99
+ reject(parseErrorFromTransport.parseErrorFromTransport(result));
100
+ }
101
+ else {
102
+ reject(result);
103
+ }
104
+ cleanup();
105
+ }
106
+ };
107
+ const cleanup = () => messageTransport.off(handleMessage);
108
+ messageTransport.on(handleMessage);
109
+ // Now we emit the event to set off the request
110
+ messageTransport.emit({
111
+ args: params,
112
+ messageSessionId,
113
+ type: requestType,
114
+ });
115
+ }),
116
+ };
117
+ };
118
+
119
+ exports.createRequestChannel = createRequestChannel;
120
+ exports.getRejectMessageType = getRejectMessageType;
121
+ 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,115 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../_virtual/_tslib.js';
3
+ import { parseErrorFromTransport } from '../utils/parseErrorFromTransport/parseErrorFromTransport.js';
4
+ import { serializeErrorForTransport } from '../utils/serializeErrorForTransport/serializeErrorForTransport.js';
5
+ import { isSerializedError } from '../utils/isSerializedError/isSerializedError.js';
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 = (_a) => __awaiter(void 0, [_a], void 0, function* ({ args, messageSessionId, type: incomingType, }) {
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: [serializeErrorForTransport(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
+ if (isSerializedError(result)) {
95
+ reject(parseErrorFromTransport(result));
96
+ }
97
+ else {
98
+ reject(result);
99
+ }
100
+ cleanup();
101
+ }
102
+ };
103
+ const cleanup = () => messageTransport.off(handleMessage);
104
+ messageTransport.on(handleMessage);
105
+ // Now we emit the event to set off the request
106
+ messageTransport.emit({
107
+ args: params,
108
+ messageSessionId,
109
+ type: requestType,
110
+ });
111
+ }),
112
+ };
113
+ };
114
+
115
+ export { createRequestChannel, getRejectMessageType, getResolveMessageType };
@@ -0,0 +1,24 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var EventEmitter = require('eventemitter3');
7
+ var requestChannel = require('../../requestChannel/requestChannel.cjs');
8
+
9
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
+
11
+ var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
12
+
13
+ // There are way too many "any"s in this file. They are necessary because otherwise the generics won't work
14
+ function createEventEmitterForMessages({ messageTransport, initialEventEmitter, key, }) {
15
+ const events = initialEventEmitter !== null && initialEventEmitter !== void 0 ? initialEventEmitter : new EventEmitter__default["default"]();
16
+ const requestChannel$1 = requestChannel.createRequestChannel(messageTransport);
17
+ requestChannel$1.handle('eventEmitted', (eventKey, eventName, payload) => {
18
+ if (eventKey === key)
19
+ events.emit(eventName, ...payload);
20
+ });
21
+ return events;
22
+ }
23
+
24
+ exports.createEventEmitterForMessages = createEventEmitterForMessages;
@@ -0,0 +1,22 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import { MessageTransportWithDefaultOrigin } from '../../messageTransport';
3
+ export type MessagesForEventEmitter<T extends Record<string, (...args: any[]) => any>, U extends string> = {
4
+ eventEmitted: <E extends keyof T>(key: U, eventName: E, payload: Parameters<T[E]>) => void;
5
+ };
6
+ /**
7
+ * Use this function when you want to get an event emitter that will raise events for
8
+ * messages of type MessagesForEventEmitter
9
+ */
10
+ export declare function createEventEmitterForMessages<T extends Record<string, (...args: any[]) => any> = never, U extends string = never>(params: {
11
+ messageTransport: MessageTransportWithDefaultOrigin;
12
+ key: U;
13
+ }): EventEmitter<T>;
14
+ /**
15
+ * Use this function when you want to get an event emitter that will raise events for
16
+ * messages of type MessagesForEventEmitter
17
+ */
18
+ export declare function createEventEmitterForMessages<T extends Record<string, (...args: any[]) => any> = never, U extends string = never, E extends EventEmitter<any> = never>(params: {
19
+ messageTransport: MessageTransportWithDefaultOrigin;
20
+ initialEventEmitter: E;
21
+ key: U;
22
+ }): E extends EventEmitter<infer V> ? EventEmitter<T & V> : never;
@@ -0,0 +1,16 @@
1
+ 'use client'
2
+ import EventEmitter from 'eventemitter3';
3
+ import { createRequestChannel } from '../../requestChannel/requestChannel.js';
4
+
5
+ // There are way too many "any"s in this file. They are necessary because otherwise the generics won't work
6
+ function createEventEmitterForMessages({ messageTransport, initialEventEmitter, key, }) {
7
+ const events = initialEventEmitter !== null && initialEventEmitter !== void 0 ? initialEventEmitter : new EventEmitter();
8
+ const requestChannel = createRequestChannel(messageTransport);
9
+ requestChannel.handle('eventEmitted', (eventKey, eventName, payload) => {
10
+ if (eventKey === key)
11
+ events.emit(eventName, ...payload);
12
+ });
13
+ return events;
14
+ }
15
+
16
+ export { createEventEmitterForMessages };
@@ -0,0 +1 @@
1
+ export * from './createEventEmitterForMessages';
@@ -0,0 +1,3 @@
1
+ export * from './createEventEmitterForMessages';
2
+ export * from './store';
3
+ export * from './storeSetter';