@orpc/shared
Version:
> [!WARNING] > > `@orpc/shared` is an internal dependency of oRPC packages. It does not follow semver and may change at any time without notice. > Please do not use it in your project.
209 lines (194 loc) • 9.82 kB
TypeScript
import { Promisable } from 'type-fest';
export { IsEqual, IsNever, PartialDeep, Promisable } from 'type-fest';
export { group, guard, mapEntries, mapValues, omit } from 'radash';
type MaybeOptionalOptions<TOptions> = Record<never, never> extends TOptions ? [options?: TOptions] : [options: TOptions];
declare function resolveMaybeOptionalOptions<T>(rest: MaybeOptionalOptions<T>): T;
declare function toArray<T>(value: T): T extends readonly any[] ? T : Exclude<T, undefined | null>[];
declare function splitInHalf<T>(arr: readonly T[]): [T[], T[]];
type AnyFunction = (...args: any[]) => any;
declare function once<T extends () => any>(fn: T): () => ReturnType<T>;
declare function sequential<A extends any[], R>(fn: (...args: A) => Promise<R>): (...args: A) => Promise<R>;
/**
* Executes the callback function after the current call stack has been cleared.
*/
declare function defer(callback: () => void): void;
type OmitChainMethodDeep<T extends object, K extends keyof any> = {
[P in keyof Omit<T, K>]: T[P] extends AnyFunction ? ((...args: Parameters<T[P]>) => OmitChainMethodDeep<ReturnType<T[P]>, K>) : T[P];
};
interface EventPublisherOptions {
/**
* Maximum number of events to buffer for async iterator subscribers.
*
* If the buffer exceeds this limit, the oldest event is dropped.
* This prevents unbounded memory growth if consumers process events slowly.
*
* Set to:
* - `0`: Disable buffering. Events must be consumed before the next one arrives.
* - `1`: Only keep the latest event. Useful for real-time updates where only the most recent value matters.
* - `Infinity`: Keep all events. Ensures no data loss, but may lead to high memory usage.
*
* @default 100
*/
maxBufferedEvents?: number;
}
interface EventPublisherSubscribeIteratorOptions extends EventPublisherOptions {
/**
* Aborts the async iterator. Throws if aborted before or during pulling.
*/
signal?: AbortSignal;
}
declare class EventPublisher<T extends Record<PropertyKey, any>> {
#private;
constructor(options?: EventPublisherOptions);
get size(): number;
/**
* Emits an event and delivers the payload to all subscribed listeners.
*/
publish<K extends keyof T>(event: K, payload: T[K]): void;
/**
* Subscribes to a specific event using a callback function.
* Returns an unsubscribe function to remove the listener.
*
* @example
* ```ts
* const unsubscribe = publisher.subscribe('event', (payload) => {
* console.log(payload)
* })
*
* // Later
* unsubscribe()
* ```
*/
subscribe<K extends keyof T>(event: K, listener: (payload: T[K]) => void): () => void;
/**
* Subscribes to a specific event using an async iterator.
* Useful for `for await...of` loops with optional buffering and abort support.
*
* @example
* ```ts
* for await (const payload of publisher.subscribe('event', { signal })) {
* console.log(payload)
* }
* ```
*/
subscribe<K extends keyof T>(event: K, options?: EventPublisherSubscribeIteratorOptions): AsyncGenerator<T[K]> & AsyncIteratorObject<T[K]>;
}
declare class SequentialIdGenerator {
private nextId;
generate(): number;
}
type SetOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type IntersectPick<T, U> = Pick<T, keyof T & keyof U>;
type PromiseWithError<T, TError> = Promise<T> & {
__error?: {
type: TError;
};
};
/**
* The place where you can config the orpc types.
*
* - `throwableError` the error type that represent throwable errors should be `Error` or `null | undefined | {}` if you want more strict.
*/
interface Registry {
}
type ThrowableError = Registry extends {
throwableError: infer T;
} ? T : Error;
type InterceptableOptions = Record<string, any>;
type InterceptorOptions<TOptions extends InterceptableOptions, TResult> = Omit<TOptions, 'next'> & {
next(options?: TOptions): TResult;
};
type Interceptor<TOptions extends InterceptableOptions, TResult> = (options: InterceptorOptions<TOptions, TResult>) => TResult;
/**
* Can used for interceptors or middlewares
*/
declare function onStart<T, TOptions extends {
next(): any;
}, TRest extends any[]>(callback: NoInfer<(options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
/**
* Can used for interceptors or middlewares
*/
declare function onSuccess<T, TOptions extends {
next(): any;
}, TRest extends any[]>(callback: NoInfer<(result: Awaited<ReturnType<TOptions['next']>>, options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
/**
* Can used for interceptors or middlewares
*/
declare function onError<T, TOptions extends {
next(): any;
}, TRest extends any[]>(callback: NoInfer<(error: ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError, options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
type OnFinishState<TResult, TError> = [error: TError, data: undefined, isSuccess: false] | [error: null, data: TResult, isSuccess: true];
/**
* Can used for interceptors or middlewares
*/
declare function onFinish<T, TOptions extends {
next(): any;
}, TRest extends any[]>(callback: NoInfer<(state: OnFinishState<Awaited<ReturnType<TOptions['next']>>, ReturnType<TOptions['next']> extends PromiseWithError<any, infer E> ? E : ThrowableError>, options: TOptions, ...rest: TRest) => Promisable<void>>): (options: TOptions, ...rest: TRest) => T | Promise<Awaited<ReturnType<TOptions['next']>>>;
declare function intercept<TOptions extends InterceptableOptions, TResult>(interceptors: Interceptor<TOptions, TResult>[], options: NoInfer<TOptions>, main: NoInfer<(options: TOptions) => TResult>): TResult;
declare function isAsyncIteratorObject(maybe: unknown): maybe is AsyncIteratorObject<any, any, any>;
interface AsyncIteratorClassNextFn<T, TReturn> {
(): Promise<IteratorResult<T, TReturn>>;
}
interface AsyncIteratorClassCleanupFn {
(reason: 'return' | 'throw' | 'next' | 'dispose'): Promise<void>;
}
declare const fallbackAsyncDisposeSymbol: unique symbol;
declare const asyncDisposeSymbol: typeof Symbol extends {
asyncDispose: infer T;
} ? T : typeof fallbackAsyncDisposeSymbol;
declare class AsyncIteratorClass<T, TReturn = unknown, TNext = unknown> implements AsyncIteratorObject<T, TReturn, TNext>, AsyncGenerator<T, TReturn, TNext> {
#private;
constructor(next: AsyncIteratorClassNextFn<T, TReturn>, cleanup: AsyncIteratorClassCleanupFn);
next(): Promise<IteratorResult<T, TReturn>>;
return(value?: any): Promise<IteratorResult<T, TReturn>>;
throw(err: any): Promise<IteratorResult<T, TReturn>>;
/**
* asyncDispose symbol only available in esnext, we should fallback to Symbol.for('asyncDispose')
*/
[asyncDisposeSymbol](): Promise<void>;
[Symbol.asyncIterator](): this;
}
declare function replicateAsyncIterator<T, TReturn, TNext>(source: AsyncIterator<T, TReturn, TNext>, count: number): (AsyncIteratorClass<T, TReturn, TNext>)[];
declare function parseEmptyableJSON(text: string | null | undefined): unknown;
declare function stringifyJSON<T>(value: T | {
toJSON(): T;
}): undefined extends T ? undefined | string : string;
type Segment = string | number;
declare function findDeepMatches(check: (value: unknown) => boolean, payload: unknown, segments?: Segment[], maps?: Segment[][], values?: unknown[]): {
maps: Segment[][];
values: unknown[];
};
/**
* Check if the value is an object even it created by `Object.create(null)` or more tricky way.
*/
declare function isObject(value: unknown): value is Record<PropertyKey, unknown>;
/**
* Check if the value satisfy a `object` type in typescript
*/
declare function isTypescriptObject(value: unknown): value is object & Record<PropertyKey, unknown>;
declare function clone<T>(value: T): T;
declare function get(object: object, path: readonly string[]): unknown;
declare function isPropertyKey(value: unknown): value is PropertyKey;
declare const NullProtoObj: ({
new <T extends Record<PropertyKey, unknown>>(): T;
});
interface AsyncIdQueueCloseOptions {
id?: number;
reason?: unknown;
}
declare class AsyncIdQueue<T> {
private readonly openIds;
private readonly items;
private readonly pendingPulls;
get length(): number;
open(id: number): void;
isOpen(id: number): boolean;
push(id: number, item: T): void;
pull(id: number): Promise<T>;
close({ id, reason }?: AsyncIdQueueCloseOptions): void;
assertOpen(id: number): void;
}
type Value<T, TArgs extends any[] = []> = T | ((...args: TArgs) => T);
declare function value<T, TArgs extends any[]>(value: Value<T, TArgs>, ...args: NoInfer<TArgs>): T extends Value<infer U, any> ? U : never;
export { AsyncIdQueue, AsyncIteratorClass, EventPublisher, NullProtoObj, SequentialIdGenerator, clone, defer, findDeepMatches, get, intercept, isAsyncIteratorObject, isObject, isPropertyKey, isTypescriptObject, onError, onFinish, onStart, onSuccess, once, parseEmptyableJSON, replicateAsyncIterator, resolveMaybeOptionalOptions, sequential, splitInHalf, stringifyJSON, toArray, value };
export type { AnyFunction, AsyncIdQueueCloseOptions, AsyncIteratorClassCleanupFn, AsyncIteratorClassNextFn, EventPublisherOptions, EventPublisherSubscribeIteratorOptions, InterceptableOptions, Interceptor, InterceptorOptions, IntersectPick, MaybeOptionalOptions, OmitChainMethodDeep, OnFinishState, PromiseWithError, Registry, Segment, SetOptional, ThrowableError, Value };