comctx
Version:
Cross-context RPC solution with type safety and flexible adapters.
60 lines (58 loc) • 2.78 kB
TypeScript
type MaybePromise<T> = T | Promise<T>;
type Context<T extends Record<string, any> = Record<string, any>> = (...args: any[]) => T;
interface Options {
namespace?: string;
heartbeatCheck?: boolean;
heartbeatInterval?: number;
heartbeatTimeout?: number;
backup?: boolean;
}
interface Message {
type: 'apply' | 'callback' | 'ping' | 'pong';
id: string;
path: string[];
sender: 'provide' | 'inject';
callbackIds?: string[];
args: any[];
error?: string;
data?: any;
namespace: string;
timeStamp: number;
}
type OffMessage = () => MaybePromise<void>;
type SendMessage<M extends Message = Message> = (message: M) => MaybePromise<void>;
type OnMessage<M extends Message = Message> = (callback: (message?: Partial<M>) => void) => MaybePromise<OffMessage | void>;
interface Adapter<M extends Message = Message> {
sendMessage: SendMessage<M>;
onMessage: OnMessage<M>;
}
/**
* Creates a pair of proxies for the provider (provide) and injector (inject) to facilitate method calls and callbacks across communication layers.
*
* @param context - A factory function for the context that returns the target object to be proxied:
* - For the provider: This object directly handles remote calls.
* - For the injector: When the backup option is enabled, it serves as a local fallback implementation.
* @param options - Configuration options:
* - namespace: The communication namespace used to isolate messages between different proxy instances (default is '__comctx__').
* - heartbeatCheck: Enable provider readiness check (default: true).
* - heartbeatInterval: The frequency at which to request heartbeats in milliseconds (default: 300).
* - heartbeatTimeout: Max wait time for heartbeat response in milliseconds (default: 1000).
* - backup: Whether to use a backup implementation of the original object in the injector (default is false).
* @returns Returns a tuple containing two elements:
* - [0] provideProxy: Accepts an adapter and creates a provider proxy.
* - [1] injectProxy: Accepts an adapter and creates an injector proxy.
*
* @example
* const [provide, inject] = defineProxy(() => ({
* add: (a, b) => a + b
* }), { namespace: 'math' })
*
* // Provider
* provide(providerAdapter)
*
* // Injector
* const math = inject(injectorAdapter)
* await math.add(2, 3) // 5
*/
declare const defineProxy: <T extends Context>(context: T, options?: Options) => readonly [<M extends Message = Message>(adapter: Adapter<M>, ...args: Parameters<T>) => ReturnType<T>, <M extends Message = Message>(adapter: Adapter<M>) => ReturnType<T>];
export { type Adapter, type Context, type Message, type OffMessage, type OnMessage, type Options, type SendMessage, defineProxy as default, defineProxy };