@dynamic-labs/message-transport
Advanced tools
Comparing version 4.0.0-alpha.6 to 4.0.0-alpha.7
'use client' | ||
var version = "4.0.0-alpha.6"; | ||
var version = "4.0.0-alpha.7"; | ||
export { version }; |
{ | ||
"name": "@dynamic-labs/message-transport", | ||
"version": "4.0.0-alpha.6", | ||
"version": "4.0.0-alpha.7", | ||
"description": "Defines the interface to communicate with dynamic's webview", | ||
@@ -23,10 +23,10 @@ "author": "Dynamic Labs, Inc.", | ||
"@vue/reactivity": "3.4.21", | ||
"@dynamic-labs/types": "4.0.0-alpha.6", | ||
"@dynamic-labs/types": "4.0.0-alpha.7", | ||
"eventemitter3": "5.0.1" | ||
}, | ||
"peerDependencies": { | ||
"@dynamic-labs/assert-package-version": "4.0.0-alpha.6", | ||
"@dynamic-labs/logger": "4.0.0-alpha.6", | ||
"@dynamic-labs/utils": "4.0.0-alpha.6" | ||
"@dynamic-labs/assert-package-version": "4.0.0-alpha.7", | ||
"@dynamic-labs/logger": "4.0.0-alpha.7", | ||
"@dynamic-labs/utils": "4.0.0-alpha.7" | ||
} | ||
} |
@@ -8,2 +8,2 @@ export { applyDefaultMessageOrigin, createMessageTransport, makeWaitForInitEvent, makeWaitForUnblock, type BypassBlockCallback, type MessageTransport, type MessageTransportCallback, type MessageTransportData, type MessageTransportDataOptionalOrigin, type MessageTransportWithDefaultOrigin, } from './messageTransport'; | ||
export type { Store, StoreEventListeners, StoreKeys, StoreSetter, StoreStateChangeEvent, StoreStateEvents, StoreStateGetters, } from './store/types'; | ||
export { sdkHasLoadedEventName, type AuthModuleMessages, type AuthModuleState, type ClientManifest, type ConsoleMessages, type CreateEmbeddedWalletArgs, 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'; | ||
export { sdkHasLoadedEventName, type AccountAbstractionGetEOAWalletArgs, type AccountAbstractionGetSmartWalletArgs, type AccountAbstractionIsSmartWalletArgs, type AccountAbstractionMessages, type AuthModuleMessages, type AuthModuleState, type ClientManifest, type ConsoleMessages, type CreateEmbeddedWalletArgs, type EmailOtpParams, type EmbeddedWalletsModuleMessages, type EmbeddedWalletsModuleState, type EthMessages, type EthRequestParams, type EthRequestWithAddressParams, type EthRequestWithChainIdParams, type ExternalAuthMessages, type FetchMessages, type KernelAccountSettings, type NetworksModuleState, type OtpData, type OtpMessages, type PasskeyMessages, type PlatformServiceMessages, type ProjectSettingsMessages, type SdkModuleMessages, type SdkModuleState, type SecureStorageMessages, type SignInWithExternalJwtParams, type SmsOtpParams, type SocialAuthModuleMessages, type SocialProvider, type SolanaMessages, type UserInterfaceModuleMessages, type VerifyWithExternalJwtParams, type WalletEvents, type WalletsModuleMessages, type WalletsModuleState, type WebViewVisibilityMessages, type ZeroDevExtensionMessages, } from './messageTypes'; |
@@ -1,6 +0,6 @@ | ||
import { MessageTransport, MessageTransportData } from '../../messageTransport'; | ||
import { MessageTransport } from '../../messageTransport'; | ||
import { BypassBlockCallback } from '../makeWaitForUnblock'; | ||
type MakeWaitForInitEventProps = { | ||
type MakeWaitForInitEventProps<M extends MessageTransport> = { | ||
/** MessageTransport to add this decorator to */ | ||
messageTransport: MessageTransport; | ||
messageTransport: M; | ||
/** Which message type should trigger the initialization */ | ||
@@ -19,8 +19,3 @@ initializeMessageType: string; | ||
*/ | ||
export declare const makeWaitForInitEvent: ({ bypassBlockIf, initializeMessageType, messageTransport, }: MakeWaitForInitEventProps) => { | ||
unblock: () => void; | ||
emit: (message: MessageTransportData) => void; | ||
off: (callback: import("../../messageTransport").MessageTransportCallback) => void; | ||
on: (callback: import("../../messageTransport").MessageTransportCallback) => void; | ||
}; | ||
export declare const makeWaitForInitEvent: <M extends MessageTransport>({ bypassBlockIf, initializeMessageType, messageTransport, }: MakeWaitForInitEventProps<M>) => import("../makeWaitForUnblock").WithBlock<M>; | ||
export {}; |
import { MessageTransport, MessageTransportData } from '../../messageTransport'; | ||
export type BypassBlockCallback = (message: MessageTransportData) => boolean; | ||
type MakeWaitForUnblockProps = { | ||
type MakeWaitForUnblockProps<M extends MessageTransport> = { | ||
/** MessageTransport to add this decorator to */ | ||
messageTransport: MessageTransport; | ||
messageTransport: M; | ||
/** If true is return the message will not be blocked */ | ||
@@ -10,2 +10,15 @@ bypassBlockIf?: BypassBlockCallback; | ||
/** | ||
* A message transport that may have its messages blocked until unblock is called. | ||
* | ||
* This adds a second param to the emit method that allows triggering a callback when | ||
* the message is actually emitted. | ||
*/ | ||
export type WithBlock<M extends MessageTransport> = M & { | ||
emit: (message: Parameters<M['emit']>[0], options?: { | ||
onEmit?: VoidFunction; | ||
}) => void; | ||
unblock: () => void; | ||
isBlocked: boolean; | ||
}; | ||
/** | ||
* Decorator that adds the following features to a MessageTransport: | ||
@@ -18,8 +31,3 @@ * 1. Any emit calls will not emit the message yet. These messages will be stored. | ||
*/ | ||
export declare const makeWaitForUnblock: ({ messageTransport, bypassBlockIf, }: MakeWaitForUnblockProps) => { | ||
unblock: () => void; | ||
emit: (message: MessageTransportData) => void; | ||
off: (callback: import("../../messageTransport").MessageTransportCallback) => void; | ||
on: (callback: import("../../messageTransport").MessageTransportCallback) => void; | ||
}; | ||
export declare const makeWaitForUnblock: <M extends MessageTransport>({ messageTransport, bypassBlockIf, }: MakeWaitForUnblockProps<M>) => WithBlock<M>; | ||
export {}; |
@@ -13,3 +13,5 @@ 'use client' | ||
let blocked = true; | ||
/** Messages pending to be sent once unblocked */ | ||
/** | ||
* Messages pending to be sent once unblocked, along with their onEmit callbacks | ||
*/ | ||
let pendingMessages = []; | ||
@@ -21,4 +23,5 @@ /** | ||
const bypassedMessageSessionIds = new Set(); | ||
const extendedTransport = { | ||
emit: (message) => { | ||
return { | ||
emit: (message, options) => { | ||
const { onEmit } = options !== null && options !== void 0 ? options : {}; | ||
if (bypassBlockIf(message) && blocked) { | ||
@@ -30,23 +33,28 @@ bypassedMessageSessionIds.add(message.messageSessionId); | ||
if (blocked && !bypassedMessageSessionIds.has(message.messageSessionId)) { | ||
pendingMessages.push(message); | ||
pendingMessages.push({ message, onEmit }); | ||
return; | ||
} | ||
messageTransport.emit(message); | ||
onEmit === null || onEmit === void 0 ? void 0 : onEmit(); | ||
}, | ||
get isBlocked() { | ||
return blocked; | ||
}, | ||
off: (callback) => messageTransport.off(callback), | ||
on: (callback) => messageTransport.on(callback), | ||
unblock: () => { | ||
if (!blocked) | ||
return; | ||
blocked = false; | ||
// Emit all stored messages | ||
for (const { message, onEmit } of pendingMessages) { | ||
messageTransport.emit(message); | ||
onEmit === null || onEmit === void 0 ? void 0 : onEmit(); | ||
} | ||
pendingMessages = []; | ||
bypassedMessageSessionIds.clear(); | ||
}, | ||
}; | ||
const unblock = () => { | ||
if (!blocked) | ||
return; | ||
blocked = false; | ||
// Emit all stored messages | ||
for (const message of pendingMessages) | ||
messageTransport.emit(message); | ||
pendingMessages = []; | ||
bypassedMessageSessionIds.clear(); | ||
}; | ||
return Object.assign(Object.assign({}, extendedTransport), { unblock }); | ||
}; | ||
export { makeWaitForUnblock }; |
@@ -0,1 +1,2 @@ | ||
export * from './AccountAbstractionMessages'; | ||
export * from './AuthModuleMessages'; | ||
@@ -11,2 +12,3 @@ export * from './ConsoleMessages'; | ||
export * from './PlatformServiceMessages'; | ||
export * from './ProjectSettingsMessages'; | ||
export * from './SdkModuleMessages'; | ||
@@ -19,1 +21,2 @@ export * from './SecureStorageMessages'; | ||
export * from './WebViewVisibilityMessages'; | ||
export * from './ZeroDevExtensionMessages'; |
@@ -30,2 +30,17 @@ import { BaseWallet } from '@dynamic-labs/types'; | ||
}) => Promise<void>; | ||
onWalletEvent: (params: WalletEventArguments & { | ||
walletId: string; | ||
}) => void; | ||
}; | ||
export type WalletEvents = { | ||
chainChange: (props: { | ||
chain: string; | ||
}) => void; | ||
}; | ||
type WalletEventArguments = { | ||
[E in keyof WalletEvents]: { | ||
event: E; | ||
eventParams: Parameters<WalletEvents[E]>; | ||
}; | ||
}[keyof WalletEvents]; | ||
export {}; |
export * from './requestChannel'; | ||
export * from './types'; |
@@ -0,70 +1,5 @@ | ||
import { WithBlock } from '../messageTransport'; | ||
import { MessageTransportWithDefaultOrigin } from '../messageTransport/decorators/applyDefaultMessageOrigin/applyDefaultMessageOrigin'; | ||
import { RequestChannel, RequestTypes } from './types'; | ||
/** | ||
* An object that defines request types, and whether they expect a response | ||
*/ | ||
export type RequestTypes = Record<string, (...params: any[]) => Promise<any> | void>; | ||
/** | ||
* Only the request types from T that return promises | ||
* i.e. those that expect a response | ||
*/ | ||
type TypesExpectingResponse<T extends RequestTypes> = Extract<{ | ||
[K in keyof T]: ReturnType<T[K]> extends Promise<any> ? K : never; | ||
}[keyof T], string>; | ||
export type RequestChannel<T extends RequestTypes> = { | ||
/** | ||
* Listens to incoming requests of this type, and calls the handler when they arrive. | ||
* If the type of this request expects some response, the handler must return a promise | ||
* that resolves to this response. | ||
* | ||
* @returns an unsubscribe function. | ||
*/ | ||
handle: <K extends Extract<keyof T, string>>(requestType: K, handler: T[K]) => VoidFunction; | ||
/** | ||
* Triggers handlers for this request type, with the given params. | ||
* Doesn't expect a response. Resolves as soon as the message is acknowledged by | ||
* any handler. | ||
* | ||
* If no handlers emit an ack for this message, this will reject. | ||
* | ||
* Lifetime of an "emit" message: | ||
* 1. "Emit" message is sent. | ||
* 2. A handler receives the message. | ||
* 3. The handler immediately emits an ack message for it, acknowledging it. | ||
* 4. This method's promise resolves. | ||
*/ | ||
emit: <K extends Extract<keyof T, string>>(requestName: K, ...params: Parameters<T[K]>) => Promise<void>; | ||
/** | ||
* Triggers handlers for this request type, with the given params. | ||
* As opposed to emit, this expects a response message. A handler must still | ||
* acknowledge this message, but the promise will only resolve when the handler | ||
* emits back a response message. The promise resolves with whatever data was sent | ||
* in the response. | ||
* | ||
* If no handlers emit an ack for this message, or if a handler responds | ||
* with a failure, this will reject. | ||
* | ||
* Lifetime of a "request" message: | ||
* 1. "Request" message is sent. | ||
* 2. A handler receives the message. | ||
* 3. The handler immediately emits an ack message for it, acknowledging it. | ||
* 4. The handler performs the requested action. | ||
* 5. The handler emits a response message. | ||
* 6. This method's promise resolves with the response's data. | ||
*/ | ||
request: <K extends TypesExpectingResponse<T>>(requestName: K, ...params: Parameters<T[K]>) => ReturnType<T[K]>; | ||
}; | ||
/** Given a request event name, returns the event name for its resolve */ | ||
export declare const getResolveMessageType: (type: string) => string; | ||
/** Given a request event name, returns the event name for its reject */ | ||
export declare const getRejectMessageType: (type: string) => string; | ||
/** Given a request event name, returns the event name for its acknowledgement */ | ||
export declare const getAckMessageType: (type: string) => string; | ||
/** | ||
* When a request is sent, a timer will be started. If it times out before | ||
* a corresponding ack message is received, we reject the request with NO_HANDLERS_REGISTERED. | ||
* | ||
* This controls how many ms we should wait before we time out. | ||
*/ | ||
export declare const TIMEOUT_DURATION = 3000; | ||
/** | ||
* Allows handling and submitting requests to and from a webview. | ||
@@ -87,3 +22,2 @@ * Requests are messages that (can) expect some response. | ||
*/ | ||
export declare const createRequestChannel: <T extends RequestTypes = never>(messageTransport: MessageTransportWithDefaultOrigin) => RequestChannel<T>; | ||
export {}; | ||
export declare const createRequestChannel: <T extends RequestTypes = never>(messageTransport: MessageTransportWithDefaultOrigin | WithBlock<MessageTransportWithDefaultOrigin>) => RequestChannel<T>; |
'use client' | ||
import { __awaiter } from '../../_virtual/_tslib.js'; | ||
import { RequestChannelNotHandledError } from '@dynamic-labs/utils'; | ||
import { isSerializedError } from '../utils/isSerializedError/isSerializedError.js'; | ||
import { logger } from '../utils/logger.js'; | ||
import { parseErrorFromTransport } from '../utils/parseErrorFromTransport/parseErrorFromTransport.js'; | ||
import { serializeErrorForTransport } from '../utils/serializeErrorForTransport/serializeErrorForTransport.js'; | ||
import { createRequestChannelMessageSender } from './createRequestChannelMessageSender/createRequestChannelMessageSender.js'; | ||
import { createNoHandlerError, getAckMessageType, getResolveMessageType, getRejectMessageType } from './utils/utils.js'; | ||
/** Given a request event name, returns the event name for its resolve */ | ||
const getResolveMessageType = (type) => `${type}__resolve`; | ||
/** Given a request event name, returns the event name for its reject */ | ||
const getRejectMessageType = (type) => `${type}__reject`; | ||
/** Given a request event name, returns the event name for its acknowledgement */ | ||
const getAckMessageType = (type) => `${type}__ack`; | ||
/** Returns a "no handlers registered" error for a message type */ | ||
const createNoHandlerError = (type, cleanup) => { | ||
const message = `No handlers were registered for message of type ${type}`; | ||
logger.error(message); | ||
cleanup(); | ||
return new RequestChannelNotHandledError(message); | ||
}; | ||
/** | ||
* When a request is sent, a timer will be started. If it times out before | ||
* a corresponding ack message is received, we reject the request with NO_HANDLERS_REGISTERED. | ||
* | ||
* This controls how many ms we should wait before we time out. | ||
*/ | ||
const TIMEOUT_DURATION = 3000; | ||
/** | ||
* Allows handling and submitting requests to and from a webview. | ||
@@ -62,27 +42,20 @@ * Requests are messages that (can) expect some response. | ||
const messageSessionId = getUniqueId(); | ||
const ackMessageType = getAckMessageType(requestType); | ||
// Before actually emitting the event, we start listening to the | ||
// response events | ||
const handleMessage = ({ messageSessionId: incomingSessionId, type: incomingType, }) => { | ||
if (incomingSessionId !== messageSessionId || | ||
incomingType !== ackMessageType) | ||
return; | ||
clearTimeout(timeoutMap[messageSessionId]); | ||
delete timeoutMap[messageSessionId]; | ||
resolve(); | ||
cleanup(); | ||
}; | ||
const cleanup = () => messageTransport.off(handleMessage); | ||
messageTransport.on(handleMessage); | ||
// Now we emit the event to set off the request | ||
messageTransport.emit({ | ||
args: params, | ||
const { handleAckMessage, sendMessage } = createRequestChannelMessageSender({ | ||
messageSessionId, | ||
type: requestType, | ||
messageTransport, | ||
onReceiveAck: () => { | ||
cleanupMessageHandler(); | ||
resolve(); | ||
}, | ||
onTimeout: () => { | ||
cleanupMessageHandler(); | ||
reject(createNoHandlerError(requestType)); | ||
}, | ||
params, | ||
requestType, | ||
timeoutMap, | ||
}); | ||
// And start the time out timer | ||
const timeoutTimer = setTimeout(() => { | ||
reject(createNoHandlerError(requestType, cleanup)); | ||
}, TIMEOUT_DURATION); | ||
timeoutMap[messageSessionId] = timeoutTimer; | ||
const cleanupMessageHandler = () => messageTransport.off(handleAckMessage); | ||
messageTransport.on(handleAckMessage); | ||
sendMessage(); | ||
}), | ||
@@ -127,22 +100,30 @@ handle: (requestType, handler) => { | ||
// Generate the unique id for this message exchange session | ||
// Although we won't listen for a response, it must still be unique | ||
// to avoid tangling with other requests. | ||
const messageSessionId = getUniqueId(); | ||
const resolveMessageType = getResolveMessageType(requestType); | ||
const rejectMessageType = getRejectMessageType(requestType); | ||
const ackMessageType = getAckMessageType(requestType); | ||
// Before actually emitting the event, we start listening to the | ||
// response events | ||
const handleMessage = ({ args: [result], messageSessionId: incomingSessionId, type: incomingType, }) => { | ||
if (incomingSessionId !== messageSessionId) | ||
const { handleAckMessage, sendMessage } = createRequestChannelMessageSender({ | ||
messageSessionId, | ||
messageTransport, | ||
onTimeout: () => { | ||
cleanupMessageHandler(); | ||
reject(createNoHandlerError(requestType)); | ||
}, | ||
params, | ||
requestType, | ||
timeoutMap, | ||
}); | ||
// We also need to listen to resolve and reject messages, besides acks | ||
const handleMessage = (message) => { | ||
if (message.messageSessionId !== messageSessionId) | ||
return; | ||
if (incomingType === ackMessageType) { | ||
clearTimeout(timeoutMap[messageSessionId]); | ||
delete timeoutMap[messageSessionId]; | ||
return; | ||
} | ||
const { args: [result], type: incomingType, } = message; | ||
if (incomingType === resolveMessageType) { | ||
cleanupMessageHandler(); | ||
resolve(result); | ||
cleanup(); | ||
return; | ||
} | ||
if (incomingType === rejectMessageType) { | ||
cleanupMessageHandler(); | ||
if (isSerializedError(result)) { | ||
@@ -154,16 +135,9 @@ reject(parseErrorFromTransport(result)); | ||
} | ||
cleanup(); | ||
return; | ||
} | ||
handleAckMessage(message); | ||
}; | ||
const cleanup = () => messageTransport.off(handleMessage); | ||
const cleanupMessageHandler = () => messageTransport.off(handleMessage); | ||
messageTransport.on(handleMessage); | ||
// And start the time out timer | ||
const timeoutTimer = setTimeout(() => reject(createNoHandlerError(requestType, cleanup)), TIMEOUT_DURATION); | ||
timeoutMap[messageSessionId] = timeoutTimer; | ||
// Now we emit the event to set off the request | ||
messageTransport.emit({ | ||
args: params, | ||
messageSessionId, | ||
type: requestType, | ||
}); | ||
sendMessage(); | ||
}), | ||
@@ -173,2 +147,2 @@ }; | ||
export { TIMEOUT_DURATION, createRequestChannel, getAckMessageType, getRejectMessageType, getResolveMessageType }; | ||
export { createRequestChannel }; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
444269
96
1900
+ Added@dynamic-labs/assert-package-version@4.0.0-alpha.7(transitive)
+ Added@dynamic-labs/logger@4.0.0-alpha.7(transitive)
+ Added@dynamic-labs/types@4.0.0-alpha.7(transitive)
+ Added@dynamic-labs/utils@4.0.0-alpha.7(transitive)
- Removed@dynamic-labs/assert-package-version@4.0.0-alpha.6(transitive)
- Removed@dynamic-labs/logger@4.0.0-alpha.6(transitive)
- Removed@dynamic-labs/types@4.0.0-alpha.6(transitive)
- Removed@dynamic-labs/utils@4.0.0-alpha.6(transitive)