export = TransactionManager; /** * @typedef {Object} Transaction * @property {(data: unknown) => void} resolve * @property {(data: unknown) => void} reject */ /** * @template {AllowedMessages} TMsg * @typedef {Object} TransactionManagerEvents Events emitted by a {@link TransactionManager} instance. * * @property {(cmd: TMsg['rx']['cmd'] ) => void} cmd a command was received from the other peer * @property {(event: TMsg['rx']['event']) => void} event an event was received from the other peer */ /** @typedef {{ type: "binary", binaryData: ArrayBuffer } | { type: "utf8", utf8Data: string } | { data: string | Uint8Array } | string | Uint8Array} TransportMessage */ /** @typedef {(event: "message", listener: (msg: TransportMessage) => void) => void} TransportEventMethod */ /** * @typedef {( * { send(data: string): void } & ( * { addEventListener: TransportEventMethod, removeEventListener: TransportEventMethod } | * { addListener: TransportEventMethod, removeListener: TransportEventMethod } * ) * )} Transport * * interface of compatible transports that can be passed to a {@link TransactionManager} * instance. this includes, but is not limited to, websockets. */ /** * A transaction manager wrapping a WebSocket transport. * It is strongly recommended to specify the type parameter, see {@link AllowedMessages}. * * @template {AllowedMessages} [TMsg=UnknownAllowedMessages] * * @extends {EventEmitter>} */ declare class TransactionManager extends EventEmitter> { constructor(transport: Transport); maxId: number; namespaces: Map>; transactions: Map; transport: any; listener: (msg: any) => void; /** @protected */ protected _send(msg: WireMessage): void; /** * send a command to the peer * @template {string} N * @template {TMsg['tx']['cmd']['name']} K * @returns {Promise[0]>} */ cmd(name: K, data: (TMsg["tx"]["cmd"] & { namespace: N; name: K; })["data"], namespace?: N | undefined): Promise[0]>; /** * send an event to the peer * @template {string} N * @template {TMsg['tx']['event']['name']} K */ event(name: K_1, data: (TMsg["tx"]["event"] & { namespace: N_1; name: K_1; })["data"], namespace?: N_1 | undefined): void; /** * @template {string} N * @returns {Namespace} */ namespace(ns: N_2): Namespace; close(): void; } declare namespace TransactionManager { export { WireMessage, CommandWireMessage, ResponseWireMessage, EventWireMessage, AllowedMessages, AllowedMessagesDirection, Command, Event, UnknownCommand, UnknownAllowedMessages, NamespaceEvents, Transaction, TransactionManagerEvents, TransportMessage, TransportEventMethod, Transport }; } /** * classes {@link TransactionManager } and {@link Namespace } accept a generic * argument of this shape that allows the user to type the payload of messages * (commands and events) that travel through the transport. types are given * separately for both directions. * * **note:** setting this only assumes a particular type for messages, it * doesn't cause any validation to be performed, you as the user are still * responsible for this (strongly recommended if messages come from an * untrusted source). */ type AllowedMessages = { /** * - allowed incoming messages */ rx: AllowedMessagesDirection; /** * - allowed outgoing messages (fully enforcing these types would require an API change, right now a best effort is made) */ tx: AllowedMessagesDirection; }; type UnknownAllowedMessages = { rx: { cmd: UnknownCommand; event: Event; }; tx: { cmd: UnknownCommand; event: Event; }; }; /** * Events emitted by a {@link TransactionManager } instance. */ type TransactionManagerEvents = { /** * a command was received from the other peer */ cmd: (cmd: TMsg['rx']['cmd']) => void; /** * an event was received from the other peer */ event: (event: TMsg['rx']['event']) => void; }; import { TypedEmitter as EventEmitter } from "tiny-typed-emitter"; /** * @typedef {( * CommandWireMessage | * ResponseWireMessage | * EventWireMessage * )} WireMessage * * messages sent or received by {@link TransactionManager} through the underlying * transport are UTF-8 encoded JSON objects of this shape. this is an internal type, * and you won't need it unless you're writing your own version of `transaction-manager`. */ /** * @typedef {Object} CommandWireMessage * @property {"cmd"} type * @property {string} [namespace] * @property {string} name * @property {unknown} data * @property {number} transId */ /** * @typedef {Object} ResponseWireMessage * @property {"error" | "response"} type * @property {unknown} data * @property {number} transId */ /** * @typedef {Object} EventWireMessage * @property {"event"} type * @property {string} [namespace] * @property {string} name * @property {unknown} data */ /** * @typedef {Object} AllowedMessages * classes {@link TransactionManager} and {@link Namespace} accept a generic * argument of this shape that allows the user to type the payload of messages * (commands and events) that travel through the transport. types are given * separately for both directions. * * **note:** setting this only assumes a particular type for messages, it * doesn't cause any validation to be performed, you as the user are still * responsible for this (strongly recommended if messages come from an * untrusted source). * * @property {AllowedMessagesDirection} rx - allowed incoming messages * @property {AllowedMessagesDirection} tx - allowed outgoing messages (fully enforcing these types would require an API change, right now a best effort is made) */ /** * @typedef {Object} AllowedMessagesDirection * messages allowed to flow in one direction * @property {Command} cmd - allowed commands * @property {Event} event - allowed events * @see AllowedMessages */ /** * @typedef {Object} Command * object produced for `cmd` (incoming command) events. user code must handle * the command described by `namespace`, `name` and `data`, and then call * `accept` or `reject` with the response payload. it is the user's responsibility * to ensure only a single call to one of the functions happens. * * this is a generic bound (see {@link AllowedMessages}) that the user is * expected to specialize; the `accept` and `reject` functions accept `never` * because of this (since function arguments are contravariant). if no * specialization is provided, the default ({@link UnknownCommand}) accepts `unknown`. * * @property {string} [namespace] - namespace through which command was sent * @property {string} name - command name * @property {unknown} data - command payload * @property {(data: never) => void} accept - function called to send a successful response to the command * @property {(data: never) => void} reject - function called to send an error response to the command */ /** * @typedef {Object} Event * object produced for `cmd` (incoming command) events. user code must handle * * @property {string} [namespace] - namespace through which command was sent * @property {string} name - command name * @property {unknown} data - command payload */ /** * @typedef {Command & { * accept: (data: unknown) => void, * reject: (data: unknown) => void, * }} UnknownCommand * default type parameter value for command * @see Command */ /** * @typedef {{ * rx: { cmd: UnknownCommand, event: Event }, * tx: { cmd: UnknownCommand, event: Event }, * }} UnknownAllowedMessages */ /** * @template {AllowedMessages} TMsg * @template {string} N * @typedef {Object} NamespaceEvents Events emitted by a {@link Namespace} instance. * * @property {(cmd: TMsg['rx']['cmd'] & { namespace: N }) => void} cmd a command was received from the other peer * @property {(event: TMsg['rx']['event'] & { namespace: N }) => void} event an event was received from the other peer */ /** * Single namespace of a {@link TransactionManager}. * If created through {@link TransactionManager.namespace()}, this object sends and receives messages of a particular `namespace` value. * * @template {string} N * @template {AllowedMessages} [TMsg=UnknownAllowedMessages] * * @extends {EventEmitter>} */ declare class Namespace extends EventEmitter> { constructor(namespace: N, tm: TransactionManager); namespace: N; tm: import("."); /** * send a command to the peer * @template {TMsg['tx']['cmd']['name']} K * @returns {Promise[0]>} */ cmd(name: K, data: (TMsg["tx"]["cmd"] & { namespace: N; name: K; })["data"]): Promise[0]>; /** * send an event to the peer * @template {TMsg['tx']['event']['name']} K */ event(name: K_1, data: (TMsg["tx"]["event"] & { namespace: N; name: K_1; })["data"]): void; close(): boolean; } type Transaction = { resolve: (data: unknown) => void; reject: (data: unknown) => void; }; /** * * messages sent or received by {@link TransactionManager } through the underlying * transport are UTF-8 encoded JSON objects of this shape. this is an internal type, * and you won't need it unless you're writing your own version of `transaction-manager`. */ type WireMessage = (CommandWireMessage | ResponseWireMessage | EventWireMessage); /** * * interface of compatible transports that can be passed to a {@link TransactionManager }instance. this includes, but is not limited to, websockets. */ type Transport = { send(data: string): void; } & ({ addEventListener: TransportEventMethod; removeEventListener: TransportEventMethod; } | { addListener: TransportEventMethod; removeListener: TransportEventMethod; }); type CommandWireMessage = { type: "cmd"; namespace?: string | undefined; name: string; data: unknown; transId: number; }; type ResponseWireMessage = { type: "error" | "response"; data: unknown; transId: number; }; type EventWireMessage = { type: "event"; namespace?: string | undefined; name: string; data: unknown; }; /** * messages allowed to flow in one direction */ type AllowedMessagesDirection = { /** * - allowed commands */ cmd: Command; /** * - allowed events */ event: Event; }; /** * object produced for `cmd` (incoming command) events. user code must handle * the command described by `namespace`, `name` and `data`, and then call * `accept` or `reject` with the response payload. it is the user's responsibility * to ensure only a single call to one of the functions happens. * * this is a generic bound (see {@link AllowedMessages }) that the user is * expected to specialize; the `accept` and `reject` functions accept `never` * because of this (since function arguments are contravariant). if no * specialization is provided, the default ({@link UnknownCommand }) accepts `unknown`. */ type Command = { /** * - namespace through which command was sent */ namespace?: string | undefined; /** * - command name */ name: string; /** * - command payload */ data: unknown; /** * - function called to send a successful response to the command */ accept: (data: never) => void; /** * - function called to send an error response to the command */ reject: (data: never) => void; }; /** * object produced for `cmd` (incoming command) events. user code must handle */ type Event = { /** * - namespace through which command was sent */ namespace?: string | undefined; /** * - command name */ name: string; /** * - command payload */ data: unknown; }; /** * default type parameter value for command */ type UnknownCommand = Command & { accept: (data: unknown) => void; reject: (data: unknown) => void; }; /** * Events emitted by a {@link Namespace } instance. */ type NamespaceEvents = { /** * a command was received from the other peer */ cmd: (cmd: TMsg['rx']['cmd'] & { namespace: N; }) => void; /** * an event was received from the other peer */ event: (event: TMsg['rx']['event'] & { namespace: N; }) => void; }; type TransportMessage = { type: "binary"; binaryData: ArrayBuffer; } | { type: "utf8"; utf8Data: string; } | { data: string | Uint8Array; } | string | Uint8Array; type TransportEventMethod = (event: "message", listener: (msg: TransportMessage) => void) => void; //# sourceMappingURL=index.d.ts.map