+91
-67
@@ -1,6 +0,33 @@ | ||
| //#region src/index.d.ts | ||
| //#region src/messages.d.ts | ||
| declare const TYPE_REQUEST: "q"; | ||
| interface RpcRequest { | ||
| /** | ||
| * Type | ||
| */ | ||
| t: typeof TYPE_REQUEST; | ||
| /** | ||
| * ID | ||
| */ | ||
| i?: string; | ||
| /** | ||
| * Method | ||
| */ | ||
| m: string; | ||
| /** | ||
| * Arguments | ||
| */ | ||
| a: any[]; | ||
| /** | ||
| * Optional | ||
| */ | ||
| o?: boolean; | ||
| } | ||
| //#endregion | ||
| //#region src/utils.d.ts | ||
| type ArgumentsType<T> = T extends ((...args: infer A) => any) ? A : never; | ||
| type ReturnType<T> = T extends ((...args: any) => infer R) ? R : never; | ||
| type Thenable<T> = T | PromiseLike<T>; | ||
| //#endregion | ||
| //#region src/main.d.ts | ||
| type PromisifyFn<T> = ReturnType<T> extends Promise<any> ? T : (...args: ArgumentsType<T>) => Promise<Awaited<ReturnType<T>>>; | ||
| type Thenable<T> = T | PromiseLike<T>; | ||
| type BirpcResolver<This> = (this: This, name: string, resolved: (...args: unknown[]) => unknown) => Thenable<((...args: any[]) => any) | undefined>; | ||
@@ -11,11 +38,11 @@ interface ChannelOptions { | ||
| */ | ||
| post: (data: any, ...extras: any[]) => any | Promise<any>; | ||
| post: (data: any, ...extras: any[]) => Thenable<any>; | ||
| /** | ||
| * Listener to receive raw message | ||
| */ | ||
| on: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>; | ||
| on: (fn: (data: any, ...extras: any[]) => void) => Thenable<any>; | ||
| /** | ||
| * Clear the listener when `$close` is called | ||
| */ | ||
| off?: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>; | ||
| off?: (fn: (data: any, ...extras: any[]) => void) => Thenable<any>; | ||
| /** | ||
@@ -42,3 +69,3 @@ * Custom function to serialize data | ||
| } | ||
| interface EventOptions<RemoteFunctions, LocalFunctions extends object = Record<string, never>> { | ||
| interface EventOptions<RemoteFunctions extends object = Record<string, unknown>, LocalFunctions extends object = Record<string, unknown>, Proxify extends boolean = true> { | ||
| /** | ||
@@ -55,2 +82,12 @@ * Names of remote functions that do not need response. | ||
| /** | ||
| * Whether to proxy the remote functions. | ||
| * | ||
| * When `proxify` is false, calling the remote function | ||
| * with `rpc.$call('method', ...args)` instead of `rpc.method(...args)` | ||
| * explicitly is required. | ||
| * | ||
| * @default true | ||
| */ | ||
| proxify?: Proxify; | ||
| /** | ||
| * Custom resolver to resolve function to be called | ||
@@ -60,3 +97,3 @@ * | ||
| */ | ||
| resolver?: BirpcResolver<BirpcReturn<RemoteFunctions, LocalFunctions>>; | ||
| resolver?: BirpcResolver<BirpcReturn<RemoteFunctions, LocalFunctions, Proxify>>; | ||
| /** | ||
@@ -69,10 +106,4 @@ * Hook triggered before an event is sent to the remote | ||
| */ | ||
| onRequest?: (this: BirpcReturn<RemoteFunctions, LocalFunctions>, req: Request, next: (req?: Request) => Promise<any>, resolve: (res: any) => void) => void | Promise<void>; | ||
| onRequest?: (this: BirpcReturn<RemoteFunctions, LocalFunctions, Proxify>, req: RpcRequest, next: (req?: RpcRequest) => Promise<any>, resolve: (res: any) => void) => void | Promise<void>; | ||
| /** | ||
| * Custom error handler | ||
| * | ||
| * @deprecated use `onFunctionError` and `onGeneralError` instead | ||
| */ | ||
| onError?: (this: BirpcReturn<RemoteFunctions, LocalFunctions>, error: Error, functionName: string, args: any[]) => boolean | void; | ||
| /** | ||
| * Custom error handler for errors occurred in local functions being called | ||
@@ -82,3 +113,3 @@ * | ||
| */ | ||
| onFunctionError?: (this: BirpcReturn<RemoteFunctions, LocalFunctions>, error: Error, functionName: string, args: any[]) => boolean | void; | ||
| onFunctionError?: (this: BirpcReturn<RemoteFunctions, LocalFunctions, Proxify>, error: Error, functionName: string, args: any[]) => boolean | void; | ||
| /** | ||
@@ -89,3 +120,3 @@ * Custom error handler for errors occurred during serialization or messsaging | ||
| */ | ||
| onGeneralError?: (this: BirpcReturn<RemoteFunctions, LocalFunctions>, error: Error, functionName?: string, args?: any[]) => boolean | void; | ||
| onGeneralError?: (this: BirpcReturn<RemoteFunctions, LocalFunctions, Proxify>, error: Error, functionName?: string, args?: any[]) => boolean | void; | ||
| /** | ||
@@ -96,5 +127,5 @@ * Custom error handler for timeouts | ||
| */ | ||
| onTimeoutError?: (this: BirpcReturn<RemoteFunctions, LocalFunctions>, functionName: string, args: any[]) => boolean | void; | ||
| onTimeoutError?: (this: BirpcReturn<RemoteFunctions, LocalFunctions, Proxify>, functionName: string, args: any[]) => boolean | void; | ||
| } | ||
| type BirpcOptions<RemoteFunctions, LocalFunctions extends object = Record<string, never>> = EventOptions<RemoteFunctions, LocalFunctions> & ChannelOptions; | ||
| type BirpcOptions<RemoteFunctions extends object = Record<string, unknown>, LocalFunctions extends object = Record<string, unknown>, Proxify extends boolean = true> = EventOptions<RemoteFunctions, LocalFunctions, Proxify> & ChannelOptions; | ||
| type BirpcFn<T> = PromisifyFn<T> & { | ||
@@ -106,14 +137,4 @@ /** | ||
| }; | ||
| interface BirpcGroupFn<T> { | ||
| interface BirpcReturnBuiltin<RemoteFunctions, LocalFunctions = Record<string, unknown>> { | ||
| /** | ||
| * Call the remote function and wait for the result. | ||
| */ | ||
| (...args: ArgumentsType<T>): Promise<Awaited<ReturnType<T>>[]>; | ||
| /** | ||
| * Send event without asking for response | ||
| */ | ||
| asEvent: (...args: ArgumentsType<T>) => Promise<void>; | ||
| } | ||
| interface BirpcReturnBuiltin<RemoteFunctions, LocalFunctions = Record<string, never>> { | ||
| /** | ||
| * Raw functions object | ||
@@ -161,4 +182,21 @@ */ | ||
| } | ||
| type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = { [K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]> } & BirpcReturnBuiltin<RemoteFunctions, LocalFunctions>; | ||
| type ProxifiedRemoteFunctions<RemoteFunctions extends object = Record<string, unknown>> = { [K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]> }; | ||
| type BirpcReturn<RemoteFunctions extends object = Record<string, unknown>, LocalFunctions extends object = Record<string, unknown>, Proxify extends boolean = true> = Proxify extends true ? ProxifiedRemoteFunctions<RemoteFunctions> & BirpcReturnBuiltin<RemoteFunctions, LocalFunctions> : BirpcReturnBuiltin<RemoteFunctions, LocalFunctions>; | ||
| interface CallRawOptions { | ||
| method: string; | ||
| args: unknown[]; | ||
| event?: boolean; | ||
| optional?: boolean; | ||
| } | ||
| type PendingCallHandler = (options: Pick<PromiseEntry, 'method' | 'reject'>) => void | Promise<void>; | ||
| interface PromiseEntry { | ||
| resolve: (arg: any) => void; | ||
| reject: (error: any) => void; | ||
| method: string; | ||
| timeoutId?: ReturnType<typeof setTimeout>; | ||
| } | ||
| declare const setTimeout: typeof globalThis.setTimeout; | ||
| declare function createBirpc<RemoteFunctions extends object = Record<string, unknown>, LocalFunctions extends object = Record<string, unknown>, Proxify extends boolean = true>($functions: LocalFunctions, options: BirpcOptions<RemoteFunctions, LocalFunctions, Proxify>): BirpcReturn<RemoteFunctions, LocalFunctions, Proxify>; | ||
| //#endregion | ||
| //#region src/group.d.ts | ||
| interface BirpcGroupReturnBuiltin<RemoteFunctions> { | ||
@@ -169,3 +207,3 @@ /** | ||
| */ | ||
| $call: <K$1 extends keyof RemoteFunctions>(method: K$1, ...args: ArgumentsType<RemoteFunctions[K$1]>) => Promise<Awaited<ReturnType<RemoteFunctions[K$1]>>>; | ||
| $call: <K$1 extends keyof RemoteFunctions>(method: K$1, ...args: ArgumentsType<RemoteFunctions[K$1]>) => Promise<Awaited<ReturnType<RemoteFunctions[K$1]>>[]>; | ||
| /** | ||
@@ -179,45 +217,31 @@ * Same as `$call`, but returns `undefined` if the function is not defined on the remote side. | ||
| $callEvent: <K$1 extends keyof RemoteFunctions>(method: K$1, ...args: ArgumentsType<RemoteFunctions[K$1]>) => Promise<void>; | ||
| } | ||
| type BirpcGroupReturn<RemoteFunctions> = { [K in keyof RemoteFunctions]: BirpcGroupFn<RemoteFunctions[K]> } & BirpcGroupReturnBuiltin<RemoteFunctions>; | ||
| interface BirpcGroup<RemoteFunctions, LocalFunctions = Record<string, never>> { | ||
| readonly clients: BirpcReturn<RemoteFunctions, LocalFunctions>[]; | ||
| readonly functions: LocalFunctions; | ||
| readonly broadcast: BirpcGroupReturn<RemoteFunctions>; | ||
| updateChannels: (fn?: ((channels: ChannelOptions[]) => void)) => BirpcReturn<RemoteFunctions, LocalFunctions>[]; | ||
| } | ||
| interface PromiseEntry { | ||
| resolve: (arg: any) => void; | ||
| reject: (error: any) => void; | ||
| method: string; | ||
| timeoutId?: ReturnType<typeof setTimeout>; | ||
| } | ||
| declare const TYPE_REQUEST: "q"; | ||
| interface Request { | ||
| /** | ||
| * Type | ||
| * Call the remote function with the raw options. | ||
| */ | ||
| t: typeof TYPE_REQUEST; | ||
| $callRaw: (options: { | ||
| method: string; | ||
| args: unknown[]; | ||
| event?: boolean; | ||
| optional?: boolean; | ||
| }) => Promise<Awaited<ReturnType<any>>[]>; | ||
| } | ||
| interface BirpcGroupFn<T> { | ||
| /** | ||
| * ID | ||
| * Call the remote function and wait for the result. | ||
| */ | ||
| i?: string; | ||
| (...args: ArgumentsType<T>): Promise<Awaited<ReturnType<T>>[]>; | ||
| /** | ||
| * Method | ||
| * Send event without asking for response | ||
| */ | ||
| m: string; | ||
| /** | ||
| * Arguments | ||
| */ | ||
| a: any[]; | ||
| /** | ||
| * Optional | ||
| */ | ||
| o?: boolean; | ||
| asEvent: (...args: ArgumentsType<T>) => Promise<void>; | ||
| } | ||
| declare const DEFAULT_TIMEOUT = 60000; | ||
| declare const setTimeout: typeof globalThis.setTimeout; | ||
| declare function createBirpc<RemoteFunctions = Record<string, never>, LocalFunctions extends object = Record<string, never>>($functions: LocalFunctions, options: BirpcOptions<RemoteFunctions, LocalFunctions>): BirpcReturn<RemoteFunctions, LocalFunctions>; | ||
| declare function cachedMap<T, R$1>(items: T[], fn: ((i: T) => R$1)): R$1[]; | ||
| declare function createBirpcGroup<RemoteFunctions = Record<string, never>, LocalFunctions extends object = Record<string, never>>(functions: LocalFunctions, channels: ChannelOptions[] | (() => ChannelOptions[]), options?: EventOptions<RemoteFunctions, LocalFunctions>): BirpcGroup<RemoteFunctions, LocalFunctions>; | ||
| type BirpcGroupReturn<RemoteFunctions extends object = Record<string, unknown>, Proxify extends boolean = true> = Proxify extends true ? ProxifiedRemoteFunctions<RemoteFunctions> & BirpcGroupReturnBuiltin<RemoteFunctions> : BirpcGroupReturnBuiltin<RemoteFunctions>; | ||
| interface BirpcGroup<RemoteFunctions extends object = Record<string, unknown>, LocalFunctions extends object = Record<string, unknown>, Proxify extends boolean = true> { | ||
| readonly clients: BirpcReturn<RemoteFunctions, LocalFunctions, Proxify>[]; | ||
| readonly functions: LocalFunctions; | ||
| readonly broadcast: BirpcGroupReturn<RemoteFunctions, Proxify>; | ||
| updateChannels: (fn?: ((channels: ChannelOptions[]) => void)) => BirpcReturn<RemoteFunctions, LocalFunctions, Proxify>[]; | ||
| } | ||
| declare function createBirpcGroup<RemoteFunctions extends object = Record<string, unknown>, LocalFunctions extends object = Record<string, unknown>, Proxify extends boolean = true>(functions: LocalFunctions, channels: ChannelOptions[] | (() => ChannelOptions[]), options?: EventOptions<RemoteFunctions, LocalFunctions, Proxify>): BirpcGroup<RemoteFunctions, LocalFunctions, Proxify>; | ||
| //#endregion | ||
| export { ArgumentsType, BirpcFn, BirpcGroup, BirpcGroupFn, BirpcGroupReturn, BirpcGroupReturnBuiltin, BirpcOptions, BirpcResolver, BirpcReturn, BirpcReturnBuiltin, ChannelOptions, DEFAULT_TIMEOUT, EventOptions, PromisifyFn, ReturnType, Thenable, cachedMap, createBirpc, createBirpcGroup }; | ||
| export { BirpcFn, BirpcGroup, BirpcGroupFn, BirpcGroupReturn, BirpcGroupReturnBuiltin, BirpcOptions, BirpcResolver, BirpcReturn, BirpcReturnBuiltin, CallRawOptions, ChannelOptions, EventOptions, PendingCallHandler, PromisifyFn, ProxifiedRemoteFunctions, createBirpc, createBirpcGroup }; |
+73
-70
@@ -1,13 +0,47 @@ | ||
| //#region src/index.ts | ||
| //#region src/messages.ts | ||
| const TYPE_REQUEST = "q"; | ||
| const TYPE_RESPONSE = "s"; | ||
| //#endregion | ||
| //#region src/utils.ts | ||
| function createPromiseWithResolvers() { | ||
| let resolve; | ||
| let reject; | ||
| return { | ||
| promise: new Promise((res, rej) => { | ||
| resolve = res; | ||
| reject = rej; | ||
| }), | ||
| resolve, | ||
| reject | ||
| }; | ||
| } | ||
| const _cacheMap = /* @__PURE__ */ new WeakMap(); | ||
| function cachedMap(items, fn) { | ||
| return items.map((i) => { | ||
| let r = _cacheMap.get(i); | ||
| if (!r) { | ||
| r = fn(i); | ||
| _cacheMap.set(i, r); | ||
| } | ||
| return r; | ||
| }); | ||
| } | ||
| const random = Math.random.bind(Math); | ||
| const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; | ||
| function nanoid(size = 21) { | ||
| let id = ""; | ||
| let i = size; | ||
| while (i--) id += urlAlphabet[random() * 64 | 0]; | ||
| return id; | ||
| } | ||
| //#endregion | ||
| //#region src/main.ts | ||
| const DEFAULT_TIMEOUT = 6e4; | ||
| function defaultSerialize(i) { | ||
| return i; | ||
| } | ||
| const defaultSerialize = (i) => i; | ||
| const defaultDeserialize = defaultSerialize; | ||
| const { clearTimeout, setTimeout } = globalThis; | ||
| const random = Math.random.bind(Math); | ||
| function createBirpc($functions, options) { | ||
| const { post, on, off = () => {}, eventNames = [], serialize = defaultSerialize, deserialize = defaultDeserialize, resolver, bind = "rpc", timeout = DEFAULT_TIMEOUT } = options; | ||
| const { post, on, off = () => {}, eventNames = [], serialize = defaultSerialize, deserialize = defaultDeserialize, resolver, bind = "rpc", timeout = DEFAULT_TIMEOUT, proxify = true } = options; | ||
| let $closed = false; | ||
@@ -72,11 +106,7 @@ const _rpcPromiseMap = /* @__PURE__ */ new Map(); | ||
| } | ||
| const $call = (method, ...args) => _call(method, args, false); | ||
| const $callOptional = (method, ...args) => _call(method, args, false, true); | ||
| const $callEvent = (method, ...args) => _call(method, args, true); | ||
| const $callRaw = (options$1) => _call(options$1.method, options$1.args, options$1.event, options$1.optional); | ||
| const builtinMethods = { | ||
| $call, | ||
| $callOptional, | ||
| $callEvent, | ||
| $callRaw, | ||
| $call: (method, ...args) => _call(method, args, false), | ||
| $callOptional: (method, ...args) => _call(method, args, false, true), | ||
| $callEvent: (method, ...args) => _call(method, args, true), | ||
| $callRaw: (options$1) => _call(options$1.method, options$1.args, options$1.event, options$1.optional), | ||
| $rejectPendingCalls, | ||
@@ -92,3 +122,3 @@ get $closed() { | ||
| }; | ||
| rpc = new Proxy({}, { get(_, method) { | ||
| if (proxify) rpc = new Proxy({}, { get(_, method) { | ||
| if (Object.prototype.hasOwnProperty.call(builtinMethods, method)) return builtinMethods[method]; | ||
@@ -105,2 +135,3 @@ if (method === "then" && !eventNames.includes("then") && !("then" in $functions)) return void 0; | ||
| } }); | ||
| else rpc = builtinMethods; | ||
| function $close(customError) { | ||
@@ -150,3 +181,2 @@ $closed = true; | ||
| if (msg.i) { | ||
| if (error && options.onError) options.onError.call(rpc, error, method, args); | ||
| if (error && options.onFunctionError) { | ||
@@ -190,14 +220,7 @@ if (options.onFunctionError.call(rpc, error, method, args) === true) return; | ||
| } | ||
| const cacheMap = /* @__PURE__ */ new WeakMap(); | ||
| function cachedMap(items, fn) { | ||
| return items.map((i) => { | ||
| let r = cacheMap.get(i); | ||
| if (!r) { | ||
| r = fn(i); | ||
| cacheMap.set(i, r); | ||
| } | ||
| return r; | ||
| }); | ||
| } | ||
| //#endregion | ||
| //#region src/group.ts | ||
| function createBirpcGroup(functions, channels, options = {}) { | ||
| const { proxify = true } = options; | ||
| const getChannels = () => typeof channels === "function" ? channels() : channels; | ||
@@ -208,26 +231,26 @@ const getClients = (channels$1 = getChannels()) => cachedMap(channels$1, (s) => createBirpc(functions, { | ||
| })); | ||
| function _boardcast(method, args, event, optional) { | ||
| function _boardcast(options$1) { | ||
| const clients = getClients(); | ||
| return Promise.all(clients.map((c) => c.$callRaw({ | ||
| return Promise.all(clients.map((c) => c.$callRaw(options$1))); | ||
| } | ||
| const broadcastBuiltin = { | ||
| $call: (method, ...args) => _boardcast({ | ||
| method, | ||
| args, | ||
| event, | ||
| optional | ||
| }))); | ||
| } | ||
| function $call(method, ...args) { | ||
| return _boardcast(method, args, false); | ||
| } | ||
| function $callOptional(method, ...args) { | ||
| return _boardcast(method, args, false, true); | ||
| } | ||
| function $callEvent(method, ...args) { | ||
| return _boardcast(method, args, true); | ||
| } | ||
| const broadcastBuiltin = { | ||
| $call, | ||
| $callOptional, | ||
| $callEvent | ||
| event: false | ||
| }), | ||
| $callOptional: (method, ...args) => _boardcast({ | ||
| method, | ||
| args, | ||
| event: false, | ||
| optional: true | ||
| }), | ||
| $callEvent: (method, ...args) => _boardcast({ | ||
| method, | ||
| args, | ||
| event: true | ||
| }), | ||
| $callRaw: (options$1) => _boardcast(options$1) | ||
| }; | ||
| const broadcastProxy = new Proxy({}, { get(_, method) { | ||
| const broadcastProxy = proxify ? new Proxy({}, { get(_, method) { | ||
| if (Object.prototype.hasOwnProperty.call(broadcastBuiltin, method)) return broadcastBuiltin[method]; | ||
@@ -242,3 +265,3 @@ const callbacks = getClients().map((c) => c[method]); | ||
| return sendCall; | ||
| } }); | ||
| } }) : broadcastBuiltin; | ||
| function updateChannels(fn) { | ||
@@ -256,27 +279,7 @@ const channels$1 = getChannels(); | ||
| updateChannels, | ||
| broadcast: broadcastProxy, | ||
| boardcast: broadcastProxy | ||
| broadcast: broadcastProxy | ||
| }; | ||
| } | ||
| function createPromiseWithResolvers() { | ||
| let resolve; | ||
| let reject; | ||
| return { | ||
| promise: new Promise((res, rej) => { | ||
| resolve = res; | ||
| reject = rej; | ||
| }), | ||
| resolve, | ||
| reject | ||
| }; | ||
| } | ||
| const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; | ||
| function nanoid(size = 21) { | ||
| let id = ""; | ||
| let i = size; | ||
| while (i--) id += urlAlphabet[random() * 64 | 0]; | ||
| return id; | ||
| } | ||
| //#endregion | ||
| export { DEFAULT_TIMEOUT, cachedMap, createBirpc, createBirpcGroup }; | ||
| export { createBirpc, createBirpcGroup }; |
+5
-2
| { | ||
| "name": "birpc", | ||
| "type": "module", | ||
| "version": "3.0.0", | ||
| "version": "4.0.0", | ||
| "description": "Message based Two-way remote procedure call", | ||
@@ -39,2 +39,3 @@ "author": "Anthony Fu <anthonyfu117@hotmail.com>", | ||
| "eslint": "^9.39.1", | ||
| "tinyexec": "^1.0.2", | ||
| "tsdown": "0.17.0-beta.5", | ||
@@ -44,3 +45,5 @@ "tsx": "^4.21.0", | ||
| "vite": "^7.2.6", | ||
| "vitest": "^4.0.15" | ||
| "vitest": "^4.0.15", | ||
| "vitest-package-exports": "^0.1.1", | ||
| "yaml": "^2.8.2" | ||
| }, | ||
@@ -47,0 +50,0 @@ "scripts": { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
23544
5.85%0
-100%14
27.27%