devstar插件

This commit is contained in:
2025-07-26 16:40:29 +08:00
commit 30033daafe
4387 changed files with 1041101 additions and 0 deletions

21
node_modules/birpc/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Anthony Fu <https://github.com/antfu>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

163
node_modules/birpc/README.md generated vendored Normal file
View File

@@ -0,0 +1,163 @@
# birpc
[![NPM version](https://img.shields.io/npm/v/birpc?color=a1b858&label=)](https://www.npmjs.com/package/birpc)
Message-based two-way remote procedure call. Useful for WebSockets and Workers communication.
## Features
- Intuitive - call remote functions just like locals, with Promise to get the response
- TypeScript - safe function calls for arguments and returns
- Protocol agonostic - WebSocket, MessageChannel, any protocols with messages communication would work!
- Zero deps, ~0.5KB
## Examples
### Using WebSocket
When using WebSocket, you need to pass your custom serializer and deserializer.
#### Client
```ts
import type { ServerFunctions } from './types'
const ws = new WebSocket('ws://url')
const clientFunctions: ClientFunctions = {
hey(name: string) {
return `Hey ${name} from client`
}
}
const rpc = createBirpc<ServerFunctions>(
clientFunctions,
{
post: data => ws.send(data),
on: data => ws.on('message', data),
// these are required when using WebSocket
serialize: v => JSON.stringify(v),
deserialize: v => JSON.parse(v),
},
)
await rpc.hi('Client') // Hi Client from server
```
#### Server
```ts
import type { ClientFunctions } from './types'
import { WebSocketServer } from 'ws'
const serverFunctions: ServerFunctions = {
hi(name: string) {
return `Hi ${name} from server`
}
}
const wss = new WebSocketServer()
wss.on('connection', (ws) => {
const rpc = createBirpc<ClientFunctions>(
serverFunctions,
{
post: data => ws.send(data),
on: fn => ws.on('message', fn),
serialize: v => JSON.stringify(v),
deserialize: v => JSON.parse(v),
},
)
await rpc.hey('Server') // Hey Server from client
})
```
### Circular References
As `JSON.stringify` does not supporting circular references, we recommend using [`structured-clone-es`](https://github.com/antfu/structured-clone-es) as the serializer when you expect to have circular references.
```ts
import { parse, stringify } from 'structured-clone-es'
const rpc = createBirpc<ServerFunctions>(
functions,
{
post: data => ws.send(data),
on: fn => ws.on('message', fn),
// use structured-clone-es as serializer
serialize: v => stringify(v),
deserialize: v => parse(v),
},
)
```
### Using MessageChannel
[MessageChannel](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel) will automatically serialize the message and support circular references out-of-box.
```ts
export const channel = new MessageChannel()
```
#### Bob
``` ts
import type { AliceFunctions } from './types'
import { channel } from './channel'
const Bob: BobFunctions = {
hey(name: string) {
return `Hey ${name}, I am Bob`
}
}
const rpc = createBirpc<AliceFunctions>(
Bob,
{
post: data => channel.port1.postMessage(data),
on: fn => channel.port1.on('message', fn),
},
)
await rpc.hi('Bob') // Hi Bob, I am Alice
```
#### Alice
``` ts
import type { BobFunctions } from './types'
import { channel } from './channel'
const Alice: AliceFunctions = {
hi(name: string) {
return `Hi ${name}, I am Alice`
}
}
const rpc = createBirpc<BobFunctions>(
Alice,
{
post: data => channel.port2.postMessage(data),
on: fn => channel.port2.on('message', fn),
},
)
await rpc.hey('Alice') // Hey Alice, I am Bob
```
### One-to-multiple Communication
Refer to [./test/group.test.ts](./test/group.test.ts) as an example.
## Sponsors
<p align="center">
<a href="https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg">
<img src='https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg'/>
</a>
</p>
## License
[MIT](./LICENSE) License © 2021 [Anthony Fu](https://github.com/antfu)

228
node_modules/birpc/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,228 @@
'use strict';
const TYPE_REQUEST = "q";
const TYPE_RESPONSE = "s";
const DEFAULT_TIMEOUT = 6e4;
function defaultSerialize(i) {
return 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 rpcPromiseMap = /* @__PURE__ */ new Map();
let _promise;
let closed = false;
const rpc = new Proxy({}, {
get(_, method) {
if (method === "$functions")
return functions;
if (method === "$close")
return close;
if (method === "$rejectPendingCalls") {
return rejectPendingCalls;
}
if (method === "$closed")
return closed;
if (method === "then" && !eventNames.includes("then") && !("then" in functions))
return void 0;
const sendEvent = (...args) => {
post(serialize({ m: method, a: args, t: TYPE_REQUEST }));
};
if (eventNames.includes(method)) {
sendEvent.asEvent = sendEvent;
return sendEvent;
}
const sendCall = async (...args) => {
if (closed)
throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
if (_promise) {
try {
await _promise;
} finally {
_promise = void 0;
}
}
return new Promise((resolve, reject) => {
const id = nanoid();
let timeoutId;
if (timeout >= 0) {
timeoutId = setTimeout(() => {
try {
const handleResult = options.onTimeoutError?.(method, args);
if (handleResult !== true)
throw new Error(`[birpc] timeout on calling "${method}"`);
} catch (e) {
reject(e);
}
rpcPromiseMap.delete(id);
}, timeout);
if (typeof timeoutId === "object")
timeoutId = timeoutId.unref?.();
}
rpcPromiseMap.set(id, { resolve, reject, timeoutId, method });
post(serialize({ m: method, a: args, i: id, t: "q" }));
});
};
sendCall.asEvent = sendEvent;
return sendCall;
}
});
function close(customError) {
closed = true;
rpcPromiseMap.forEach(({ reject, method }) => {
const error = new Error(`[birpc] rpc is closed, cannot call "${method}"`);
if (customError) {
customError.cause ??= error;
return reject(customError);
}
reject(error);
});
rpcPromiseMap.clear();
off(onMessage);
}
function rejectPendingCalls(handler) {
const entries = Array.from(rpcPromiseMap.values());
const handlerResults = entries.map(({ method, reject }) => {
if (!handler) {
return reject(new Error(`[birpc]: rejected pending call "${method}".`));
}
return handler({ method, reject });
});
rpcPromiseMap.clear();
return handlerResults;
}
async function onMessage(data, ...extra) {
let msg;
try {
msg = deserialize(data);
} catch (e) {
if (options.onGeneralError?.(e) !== true)
throw e;
return;
}
if (msg.t === TYPE_REQUEST) {
const { m: method, a: args } = msg;
let result, error;
const fn = resolver ? resolver(method, functions[method]) : functions[method];
if (!fn) {
error = new Error(`[birpc] function "${method}" not found`);
} else {
try {
result = await fn.apply(bind === "rpc" ? rpc : functions, args);
} catch (e) {
error = e;
}
}
if (msg.i) {
if (error && options.onError)
options.onError(error, method, args);
if (error && options.onFunctionError) {
if (options.onFunctionError(error, method, args) === true)
return;
}
if (!error) {
try {
post(serialize({ t: TYPE_RESPONSE, i: msg.i, r: result }), ...extra);
return;
} catch (e) {
error = e;
if (options.onGeneralError?.(e, method, args) !== true)
throw e;
}
}
try {
post(serialize({ t: TYPE_RESPONSE, i: msg.i, e: error }), ...extra);
} catch (e) {
if (options.onGeneralError?.(e, method, args) !== true)
throw e;
}
}
} else {
const { i: ack, r: result, e: error } = msg;
const promise = rpcPromiseMap.get(ack);
if (promise) {
clearTimeout(promise.timeoutId);
if (error)
promise.reject(error);
else
promise.resolve(result);
}
rpcPromiseMap.delete(ack);
}
}
_promise = on(onMessage);
return rpc;
}
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;
});
}
function createBirpcGroup(functions, channels, options = {}) {
const getChannels = () => typeof channels === "function" ? channels() : channels;
const getClients = (channels2 = getChannels()) => cachedMap(channels2, (s) => createBirpc(functions, { ...options, ...s }));
const broadcastProxy = new Proxy({}, {
get(_, method) {
const client = getClients();
const callbacks = client.map((c) => c[method]);
const sendCall = (...args) => {
return Promise.all(callbacks.map((i) => i(...args)));
};
sendCall.asEvent = (...args) => {
callbacks.map((i) => i.asEvent(...args));
};
return sendCall;
}
});
function updateChannels(fn) {
const channels2 = getChannels();
fn?.(channels2);
return getClients(channels2);
}
getClients();
return {
get clients() {
return getClients();
},
functions,
updateChannels,
broadcast: broadcastProxy,
/**
* @deprecated use `broadcast`
*/
// @ts-expect-error deprecated
boardcast: broadcastProxy
};
}
const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
function nanoid(size = 21) {
let id = "";
let i = size;
while (i--)
id += urlAlphabet[random() * 64 | 0];
return id;
}
exports.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
exports.cachedMap = cachedMap;
exports.createBirpc = createBirpc;
exports.createBirpcGroup = createBirpcGroup;

124
node_modules/birpc/dist/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,124 @@
type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
type PromisifyFn<T> = ReturnType<T> extends Promise<any> ? T : (...args: ArgumentsType<T>) => Promise<Awaited<ReturnType<T>>>;
type BirpcResolver = (name: string, resolved: (...args: unknown[]) => unknown) => ((...args: unknown[]) => unknown) | undefined;
interface ChannelOptions {
/**
* Function to post raw message
*/
post: (data: any, ...extras: any[]) => any | Promise<any>;
/**
* Listener to receive raw message
*/
on: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Clear the listener when `$close` is called
*/
off?: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Custom function to serialize data
*
* by default it passes the data as-is
*/
serialize?: (data: any) => any;
/**
* Custom function to deserialize data
*
* by default it passes the data as-is
*/
deserialize?: (data: any) => any;
/**
* Call the methods with the RPC context or the original functions object
*/
bind?: 'rpc' | 'functions';
}
interface EventOptions<Remote> {
/**
* Names of remote functions that do not need response.
*/
eventNames?: (keyof Remote)[];
/**
* Maximum timeout for waiting for response, in milliseconds.
*
* @default 60_000
*/
timeout?: number;
/**
* Custom resolver to resolve function to be called
*
* For advanced use cases only
*/
resolver?: BirpcResolver;
/**
* Custom error handler
*
* @deprecated use `onFunctionError` and `onGeneralError` instead
*/
onError?: (error: Error, functionName: string, args: any[]) => boolean | void;
/**
* Custom error handler for errors occurred in local functions being called
*
* @returns `true` to prevent the error from being thrown
*/
onFunctionError?: (error: Error, functionName: string, args: any[]) => boolean | void;
/**
* Custom error handler for errors occurred during serialization or messsaging
*
* @returns `true` to prevent the error from being thrown
*/
onGeneralError?: (error: Error, functionName?: string, args?: any[]) => boolean | void;
/**
* Custom error handler for timeouts
*
* @returns `true` to prevent the error from being thrown
*/
onTimeoutError?: (functionName: string, args: any[]) => boolean | void;
}
type BirpcOptions<Remote> = EventOptions<Remote> & ChannelOptions;
type BirpcFn<T> = PromisifyFn<T> & {
/**
* Send event without asking for response
*/
asEvent: (...args: ArgumentsType<T>) => void;
};
interface BirpcGroupFn<T> {
/**
* 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>) => void;
}
type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = {
[K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]>;
} & {
$functions: LocalFunctions;
$close: (error?: Error) => void;
$closed: boolean;
$rejectPendingCalls: (handler?: PendingCallHandler) => Promise<void>[];
};
type PendingCallHandler = (options: Pick<PromiseEntry, 'method' | 'reject'>) => void | Promise<void>;
type BirpcGroupReturn<RemoteFunctions> = {
[K in keyof RemoteFunctions]: BirpcGroupFn<RemoteFunctions[K]>;
};
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 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>): BirpcReturn<RemoteFunctions, LocalFunctions>;
declare function cachedMap<T, R>(items: T[], fn: ((i: T) => R)): R[];
declare function createBirpcGroup<RemoteFunctions = Record<string, never>, LocalFunctions extends object = Record<string, never>>(functions: LocalFunctions, channels: ChannelOptions[] | (() => ChannelOptions[]), options?: EventOptions<RemoteFunctions>): BirpcGroup<RemoteFunctions, LocalFunctions>;
export { type ArgumentsType, type BirpcFn, type BirpcGroup, type BirpcGroupFn, type BirpcGroupReturn, type BirpcOptions, type BirpcResolver, type BirpcReturn, type ChannelOptions, DEFAULT_TIMEOUT, type EventOptions, type PromisifyFn, type ReturnType, cachedMap, createBirpc, createBirpcGroup };

124
node_modules/birpc/dist/index.d.mts generated vendored Normal file
View File

@@ -0,0 +1,124 @@
type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
type PromisifyFn<T> = ReturnType<T> extends Promise<any> ? T : (...args: ArgumentsType<T>) => Promise<Awaited<ReturnType<T>>>;
type BirpcResolver = (name: string, resolved: (...args: unknown[]) => unknown) => ((...args: unknown[]) => unknown) | undefined;
interface ChannelOptions {
/**
* Function to post raw message
*/
post: (data: any, ...extras: any[]) => any | Promise<any>;
/**
* Listener to receive raw message
*/
on: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Clear the listener when `$close` is called
*/
off?: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Custom function to serialize data
*
* by default it passes the data as-is
*/
serialize?: (data: any) => any;
/**
* Custom function to deserialize data
*
* by default it passes the data as-is
*/
deserialize?: (data: any) => any;
/**
* Call the methods with the RPC context or the original functions object
*/
bind?: 'rpc' | 'functions';
}
interface EventOptions<Remote> {
/**
* Names of remote functions that do not need response.
*/
eventNames?: (keyof Remote)[];
/**
* Maximum timeout for waiting for response, in milliseconds.
*
* @default 60_000
*/
timeout?: number;
/**
* Custom resolver to resolve function to be called
*
* For advanced use cases only
*/
resolver?: BirpcResolver;
/**
* Custom error handler
*
* @deprecated use `onFunctionError` and `onGeneralError` instead
*/
onError?: (error: Error, functionName: string, args: any[]) => boolean | void;
/**
* Custom error handler for errors occurred in local functions being called
*
* @returns `true` to prevent the error from being thrown
*/
onFunctionError?: (error: Error, functionName: string, args: any[]) => boolean | void;
/**
* Custom error handler for errors occurred during serialization or messsaging
*
* @returns `true` to prevent the error from being thrown
*/
onGeneralError?: (error: Error, functionName?: string, args?: any[]) => boolean | void;
/**
* Custom error handler for timeouts
*
* @returns `true` to prevent the error from being thrown
*/
onTimeoutError?: (functionName: string, args: any[]) => boolean | void;
}
type BirpcOptions<Remote> = EventOptions<Remote> & ChannelOptions;
type BirpcFn<T> = PromisifyFn<T> & {
/**
* Send event without asking for response
*/
asEvent: (...args: ArgumentsType<T>) => void;
};
interface BirpcGroupFn<T> {
/**
* 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>) => void;
}
type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = {
[K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]>;
} & {
$functions: LocalFunctions;
$close: (error?: Error) => void;
$closed: boolean;
$rejectPendingCalls: (handler?: PendingCallHandler) => Promise<void>[];
};
type PendingCallHandler = (options: Pick<PromiseEntry, 'method' | 'reject'>) => void | Promise<void>;
type BirpcGroupReturn<RemoteFunctions> = {
[K in keyof RemoteFunctions]: BirpcGroupFn<RemoteFunctions[K]>;
};
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 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>): BirpcReturn<RemoteFunctions, LocalFunctions>;
declare function cachedMap<T, R>(items: T[], fn: ((i: T) => R)): R[];
declare function createBirpcGroup<RemoteFunctions = Record<string, never>, LocalFunctions extends object = Record<string, never>>(functions: LocalFunctions, channels: ChannelOptions[] | (() => ChannelOptions[]), options?: EventOptions<RemoteFunctions>): BirpcGroup<RemoteFunctions, LocalFunctions>;
export { type ArgumentsType, type BirpcFn, type BirpcGroup, type BirpcGroupFn, type BirpcGroupReturn, type BirpcOptions, type BirpcResolver, type BirpcReturn, type ChannelOptions, DEFAULT_TIMEOUT, type EventOptions, type PromisifyFn, type ReturnType, cachedMap, createBirpc, createBirpcGroup };

124
node_modules/birpc/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,124 @@
type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
type PromisifyFn<T> = ReturnType<T> extends Promise<any> ? T : (...args: ArgumentsType<T>) => Promise<Awaited<ReturnType<T>>>;
type BirpcResolver = (name: string, resolved: (...args: unknown[]) => unknown) => ((...args: unknown[]) => unknown) | undefined;
interface ChannelOptions {
/**
* Function to post raw message
*/
post: (data: any, ...extras: any[]) => any | Promise<any>;
/**
* Listener to receive raw message
*/
on: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Clear the listener when `$close` is called
*/
off?: (fn: (data: any, ...extras: any[]) => void) => any | Promise<any>;
/**
* Custom function to serialize data
*
* by default it passes the data as-is
*/
serialize?: (data: any) => any;
/**
* Custom function to deserialize data
*
* by default it passes the data as-is
*/
deserialize?: (data: any) => any;
/**
* Call the methods with the RPC context or the original functions object
*/
bind?: 'rpc' | 'functions';
}
interface EventOptions<Remote> {
/**
* Names of remote functions that do not need response.
*/
eventNames?: (keyof Remote)[];
/**
* Maximum timeout for waiting for response, in milliseconds.
*
* @default 60_000
*/
timeout?: number;
/**
* Custom resolver to resolve function to be called
*
* For advanced use cases only
*/
resolver?: BirpcResolver;
/**
* Custom error handler
*
* @deprecated use `onFunctionError` and `onGeneralError` instead
*/
onError?: (error: Error, functionName: string, args: any[]) => boolean | void;
/**
* Custom error handler for errors occurred in local functions being called
*
* @returns `true` to prevent the error from being thrown
*/
onFunctionError?: (error: Error, functionName: string, args: any[]) => boolean | void;
/**
* Custom error handler for errors occurred during serialization or messsaging
*
* @returns `true` to prevent the error from being thrown
*/
onGeneralError?: (error: Error, functionName?: string, args?: any[]) => boolean | void;
/**
* Custom error handler for timeouts
*
* @returns `true` to prevent the error from being thrown
*/
onTimeoutError?: (functionName: string, args: any[]) => boolean | void;
}
type BirpcOptions<Remote> = EventOptions<Remote> & ChannelOptions;
type BirpcFn<T> = PromisifyFn<T> & {
/**
* Send event without asking for response
*/
asEvent: (...args: ArgumentsType<T>) => void;
};
interface BirpcGroupFn<T> {
/**
* 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>) => void;
}
type BirpcReturn<RemoteFunctions, LocalFunctions = Record<string, never>> = {
[K in keyof RemoteFunctions]: BirpcFn<RemoteFunctions[K]>;
} & {
$functions: LocalFunctions;
$close: (error?: Error) => void;
$closed: boolean;
$rejectPendingCalls: (handler?: PendingCallHandler) => Promise<void>[];
};
type PendingCallHandler = (options: Pick<PromiseEntry, 'method' | 'reject'>) => void | Promise<void>;
type BirpcGroupReturn<RemoteFunctions> = {
[K in keyof RemoteFunctions]: BirpcGroupFn<RemoteFunctions[K]>;
};
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 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>): BirpcReturn<RemoteFunctions, LocalFunctions>;
declare function cachedMap<T, R>(items: T[], fn: ((i: T) => R)): R[];
declare function createBirpcGroup<RemoteFunctions = Record<string, never>, LocalFunctions extends object = Record<string, never>>(functions: LocalFunctions, channels: ChannelOptions[] | (() => ChannelOptions[]), options?: EventOptions<RemoteFunctions>): BirpcGroup<RemoteFunctions, LocalFunctions>;
export { type ArgumentsType, type BirpcFn, type BirpcGroup, type BirpcGroupFn, type BirpcGroupReturn, type BirpcOptions, type BirpcResolver, type BirpcReturn, type ChannelOptions, DEFAULT_TIMEOUT, type EventOptions, type PromisifyFn, type ReturnType, cachedMap, createBirpc, createBirpcGroup };

223
node_modules/birpc/dist/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,223 @@
const TYPE_REQUEST = "q";
const TYPE_RESPONSE = "s";
const DEFAULT_TIMEOUT = 6e4;
function defaultSerialize(i) {
return 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 rpcPromiseMap = /* @__PURE__ */ new Map();
let _promise;
let closed = false;
const rpc = new Proxy({}, {
get(_, method) {
if (method === "$functions")
return functions;
if (method === "$close")
return close;
if (method === "$rejectPendingCalls") {
return rejectPendingCalls;
}
if (method === "$closed")
return closed;
if (method === "then" && !eventNames.includes("then") && !("then" in functions))
return void 0;
const sendEvent = (...args) => {
post(serialize({ m: method, a: args, t: TYPE_REQUEST }));
};
if (eventNames.includes(method)) {
sendEvent.asEvent = sendEvent;
return sendEvent;
}
const sendCall = async (...args) => {
if (closed)
throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
if (_promise) {
try {
await _promise;
} finally {
_promise = void 0;
}
}
return new Promise((resolve, reject) => {
const id = nanoid();
let timeoutId;
if (timeout >= 0) {
timeoutId = setTimeout(() => {
try {
const handleResult = options.onTimeoutError?.(method, args);
if (handleResult !== true)
throw new Error(`[birpc] timeout on calling "${method}"`);
} catch (e) {
reject(e);
}
rpcPromiseMap.delete(id);
}, timeout);
if (typeof timeoutId === "object")
timeoutId = timeoutId.unref?.();
}
rpcPromiseMap.set(id, { resolve, reject, timeoutId, method });
post(serialize({ m: method, a: args, i: id, t: "q" }));
});
};
sendCall.asEvent = sendEvent;
return sendCall;
}
});
function close(customError) {
closed = true;
rpcPromiseMap.forEach(({ reject, method }) => {
const error = new Error(`[birpc] rpc is closed, cannot call "${method}"`);
if (customError) {
customError.cause ??= error;
return reject(customError);
}
reject(error);
});
rpcPromiseMap.clear();
off(onMessage);
}
function rejectPendingCalls(handler) {
const entries = Array.from(rpcPromiseMap.values());
const handlerResults = entries.map(({ method, reject }) => {
if (!handler) {
return reject(new Error(`[birpc]: rejected pending call "${method}".`));
}
return handler({ method, reject });
});
rpcPromiseMap.clear();
return handlerResults;
}
async function onMessage(data, ...extra) {
let msg;
try {
msg = deserialize(data);
} catch (e) {
if (options.onGeneralError?.(e) !== true)
throw e;
return;
}
if (msg.t === TYPE_REQUEST) {
const { m: method, a: args } = msg;
let result, error;
const fn = resolver ? resolver(method, functions[method]) : functions[method];
if (!fn) {
error = new Error(`[birpc] function "${method}" not found`);
} else {
try {
result = await fn.apply(bind === "rpc" ? rpc : functions, args);
} catch (e) {
error = e;
}
}
if (msg.i) {
if (error && options.onError)
options.onError(error, method, args);
if (error && options.onFunctionError) {
if (options.onFunctionError(error, method, args) === true)
return;
}
if (!error) {
try {
post(serialize({ t: TYPE_RESPONSE, i: msg.i, r: result }), ...extra);
return;
} catch (e) {
error = e;
if (options.onGeneralError?.(e, method, args) !== true)
throw e;
}
}
try {
post(serialize({ t: TYPE_RESPONSE, i: msg.i, e: error }), ...extra);
} catch (e) {
if (options.onGeneralError?.(e, method, args) !== true)
throw e;
}
}
} else {
const { i: ack, r: result, e: error } = msg;
const promise = rpcPromiseMap.get(ack);
if (promise) {
clearTimeout(promise.timeoutId);
if (error)
promise.reject(error);
else
promise.resolve(result);
}
rpcPromiseMap.delete(ack);
}
}
_promise = on(onMessage);
return rpc;
}
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;
});
}
function createBirpcGroup(functions, channels, options = {}) {
const getChannels = () => typeof channels === "function" ? channels() : channels;
const getClients = (channels2 = getChannels()) => cachedMap(channels2, (s) => createBirpc(functions, { ...options, ...s }));
const broadcastProxy = new Proxy({}, {
get(_, method) {
const client = getClients();
const callbacks = client.map((c) => c[method]);
const sendCall = (...args) => {
return Promise.all(callbacks.map((i) => i(...args)));
};
sendCall.asEvent = (...args) => {
callbacks.map((i) => i.asEvent(...args));
};
return sendCall;
}
});
function updateChannels(fn) {
const channels2 = getChannels();
fn?.(channels2);
return getClients(channels2);
}
getClients();
return {
get clients() {
return getClients();
},
functions,
updateChannels,
broadcast: broadcastProxy,
/**
* @deprecated use `broadcast`
*/
// @ts-expect-error deprecated
boardcast: broadcastProxy
};
}
const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
function nanoid(size = 21) {
let id = "";
let i = size;
while (i--)
id += urlAlphabet[random() * 64 | 0];
return id;
}
export { DEFAULT_TIMEOUT, cachedMap, createBirpc, createBirpcGroup };

56
node_modules/birpc/package.json generated vendored Normal file
View File

@@ -0,0 +1,56 @@
{
"name": "birpc",
"type": "module",
"version": "2.5.0",
"description": "Message based Two-way remote procedure call",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"license": "MIT",
"funding": "https://github.com/sponsors/antfu",
"homepage": "https://github.com/antfu/birpc#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/antfu/birpc.git"
},
"bugs": {
"url": "https://github.com/antfu/birpc/issues"
},
"keywords": [
"rpc",
"messages"
],
"sideEffects": false,
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"devDependencies": {
"@antfu/eslint-config": "^4.11.0",
"@antfu/ni": "^24.3.0",
"@types/node": "^22.13.13",
"bumpp": "^10.1.0",
"eslint": "^9.23.0",
"tsx": "^4.19.3",
"typescript": "^5.8.2",
"unbuild": "^3.5.0",
"vite": "^6.2.3",
"vitest": "^3.0.9"
},
"scripts": {
"build": "unbuild",
"dev": "unbuild --stub",
"lint": "eslint .",
"release": "bumpp && pnpm publish",
"start": "tsx src/index.ts",
"typecheck": "tsc --noEmit",
"test": "vitest"
}
}