UNPKG

@2toad/reflex

Version:

A simple approach to state management

182 lines 6.07 kB
/** * Function to be called when a reactive value changes */ export type Subscriber<T> = (value: T) => unknown; /** * Function returned by subscribe() that removes the subscription when called */ export type Unsubscribe = () => void; /** * Middleware function that can transform values before they are set */ export type Middleware<T> = (value: T) => T | Promise<T>; /** * Function that computes a result from dependency values in a computed reflex */ export type ComputeFunction<TDeps extends Reflex<unknown>[], TResult> = (values: DependencyValues<TDeps>) => TResult | Promise<TResult>; /** * Internal state for computed reflex values */ export interface ComputedState<TResult> { isComputing: boolean; isAsync: boolean; currentComputed: TResult; computePromise: Promise<void> | null; cleanups: Unsubscribe[]; subscriptionCount: number; } /** * Error messages for computed reflex operations */ export declare const COMPUTED_ERRORS: { readonly SET_VALUE: "Cannot set the value of a computed reactive"; readonly ADD_MIDDLEWARE: "Cannot add middleware to a computed reactive"; readonly REMOVE_MIDDLEWARE: "Cannot remove middleware from a computed reactive"; readonly SYNC_BATCH: "Cannot use sync batch on async computed value"; }; /** * Options for creating a Reflex value */ export interface ReflexOptions<T> { /** Initial value */ initialValue: T; /** Optional equality function to determine if value has changed */ equals?: (prev: T, next: T) => boolean; /** Enable debug logging */ debug?: boolean; /** Array of middleware functions to transform values */ middleware?: Middleware<T>[]; /** Whether to notify subscribers during batch operations */ notifyDuringBatch?: boolean; } /** * A Reflex value that can be subscribed to for changes */ export interface Reflex<T> { /** Get the current value */ readonly value: T; /** Set a new value and notify subscribers */ setValue(newValue: T): void; /** Set a new value asynchronously and notify subscribers */ setValueAsync(newValue: T): Promise<void>; /** Subscribe to value changes */ subscribe(callback: Subscriber<T>): Unsubscribe; /** * Batch multiple updates together and notify subscribers only once at the end. * Returns the result of the update function. */ batch<R>(updateFn: (value: T) => R): R; /** * Batch multiple async updates together and notify subscribers only once at the end. * Returns a promise that resolves to the result of the update function. */ batchAsync<R>(updateFn: (value: T) => Promise<R> | R): Promise<R>; /** Add a middleware function */ addMiddleware(fn: Middleware<T>): void; /** Remove a middleware function */ removeMiddleware(fn: Middleware<T>): void; } /** * Type for property path segments */ export type PropertyPath = (string | number)[]; /** * Type for property change value */ export type PropertyValue = unknown; /** * Options for creating a deep Reflex value */ export interface DeepReflexOptions<T extends object> extends ReflexOptions<T> { /** Whether to make nested objects deeply reactive (default: true) */ deep?: boolean; /** Custom handler for specific property changes */ onPropertyChange?: (path: PropertyPath, value: PropertyValue) => void; } /** * Type for batched changes */ export interface BatchedChange { path: PropertyPath; value: PropertyValue; } /** * Internal state for deep Reflex values */ export interface ProxyState { isUpdating: boolean; isBatching: boolean; batchedChanges: BatchedChange[]; batchDepth: number; } /** * Extracts the underlying value types from an array of reflex values. * Used in computed values to transform an array of Reflex<T> into a tuple of their contained types. */ export type DependencyValues<T extends Reflex<unknown>[]> = { [K in keyof T]: T[K] extends Reflex<infer V> ? V : never; }; /** * A Reflex with an optional error state */ export interface ReflexWithError<T> extends Reflex<T> { _errorState?: Reflex<Error | null>; } /** * Represents strategies for handling backpressure situations */ export declare enum BackpressureStrategy { /** Discards new values when the system is overwhelmed */ Drop = "drop", /** Stores values up to a limit for later processing */ Buffer = "buffer", /** Maintains a fixed-size window of most recent values */ Sliding = "sliding", /** Throws an error when capacity is exceeded */ Error = "error" } /** * Options for configuring backpressure behavior */ export interface BackpressureOptions { /** The strategy to use for handling backpressure */ strategy: BackpressureStrategy; /** The buffer size when using buffer or sliding strategies */ bufferSize?: number; /** Custom predicate to determine when to apply backpressure */ shouldApplyBackpressure?: () => boolean; } /** * Interface for objects that implement backpressure control methods. * This interface provides methods to control the flow of data by pausing/resuming emission * and monitoring buffer state. */ export interface BackpressureCapable { /** Request the producer to pause emission */ pause: () => void; /** Request the producer to resume emission */ resume: () => void; /** Check if the producer is currently paused */ isPaused: () => boolean; /** Get the current buffer size (if applicable) */ getBufferSize: () => number; } /** * Internal state for backpressure handling */ export interface BackpressureState<T> { buffer: T[]; isPaused: boolean; valueCount: number; sourceUnsubscribe: (() => void) | null; subscriberCount: number; timeoutId?: NodeJS.Timeout | null; isInitialized?: boolean; pendingValue?: T | null; lastEmitTime: number; } /** * Type for functions that project values from a source to a new Reflex or Promise */ export type ProjectFunction<T, R> = (value: T) => Reflex<R> | Promise<R>; //# sourceMappingURL=types.d.ts.map