state-event-target
Version:
Primary state with event-driven replicas.
125 lines (117 loc) • 4.9 kB
TypeScript
type PromiseWithMeta<T> = Promise<T> & {
status?: "pending" | "fulfilled" | "rejected";
value?: T;
reason?: unknown;
};
interface KVEvents<Param, Value, Key = unknown> {
"state:update": CustomEvent<{
param: Param;
key: Key;
value: Value;
}>;
"state:reset": CustomEvent<void>;
}
interface KVDataEventTargetConfig<Param, Key = string> {
getKey?: (param: Param) => Key;
}
declare class KVDataEventTarget<Param, Value, Key = unknown> extends EventTarget {
#private;
lastUpdated: number;
constructor(initialEntries?: readonly (readonly [Param, Value])[] | null, config?: KVDataEventTargetConfig<Param, Key>);
/**
* Read attempts to return the current value synchronously if one exists,
* but otherwise returns a Promise that will resolve when a value is set.
*/
read(param: Param): Value | Promise<Value>;
/**
* Prime ensures there is a Promise ready to receive a future value.
* Useful for setting up the Promise before you need the value.
*/
prime(param: Param): void;
/**
* Peek will always synchronously read the value.
* It will return undefined if no value has been set yet.
*/
peek(param: Param): Value | undefined;
/**
* GetAsync will always return a *stable* Promise that resolves when a value is set.
*/
getAsync(param: Param): PromiseWithMeta<Value>;
/**
* Sets the value, resolving any pending Promises.
*/
set(param: Param, value: Value): void;
onMissing(cb: EventListener): void;
clear(): void;
destroy(): void;
addEventListener<K extends keyof KVEvents<Param, Value, Key>>(type: K, listener: (ev: KVEvents<Param, Value, K>[K]) => void, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof KVEvents<Param, Value, Key>>(type: K, listener: (ev: KVEvents<Param, Value, K>[K]) => void, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
declare class DataEventTarget<Value> extends EventTarget {
#private;
lastUpdated: number;
constructor(initialValue?: Value);
/**
* Read attempts to return the current value synchronously if one exists,
* but otherwise returns a Promise that will resolve when a value is set.
*/
read(): Value | PromiseWithMeta<Value>;
/**
* Prime ensures there is a Promise ready to receive a future value.
* Useful for setting up the Promise before you need the value.
*/
prime(): void;
/**
* Peek will always synchronously read the value.
* It will return undefined if no value has been set yet.
*/
peek(): Value | undefined;
/**
* GetAsync will always return a *stable* Promise that resolves when a value is set.
*/
getAsync(): PromiseWithMeta<Value>;
/**
* Sets the value, resolving any pending Promises.
*/
set(value: Value): void;
onMissing(cb: EventListener): void;
clear(): void;
destroy(): void;
}
interface BroadcastMessageType {
type: string;
namespace: string;
detail: unknown;
}
declare abstract class Broadcast<MessageType extends BroadcastMessageType> {
protected controller: AbortController;
protected signal: AbortSignal;
abstract onMessage(handler: (event: MessageEvent<MessageType>) => void): void;
abstract postMessage(message: MessageType, options?: unknown): void;
detach(): void;
}
declare class WindowBroadcast<MessageType extends BroadcastMessageType> extends Broadcast<MessageType> {
private receiver;
private sender;
constructor(receiver: Window, sender: Window | Window[] | ((message: MessageType) => Window[]));
onMessage(handler: (event: MessageEvent<MessageType>) => void): void;
postMessage(message: MessageType, { targetOrigin, transfer }?: WindowPostMessageOptions): void;
}
declare function source<T extends EventTarget & {
lastUpdated?: number;
}>(toBroadcastTarget: WindowBroadcast<any>, fromSourceTarget: T, namespace: string, config?: {
id?: string;
eventsToBroadcast?: string[];
}): T;
type SinkEventTarget = EventTarget & {
set: (...args: any[]) => void;
clear: () => void;
onMissing: (cb: EventListener) => void;
};
type SinkEventHandlers<T extends SinkEventTarget> = {
[eventType: string]: (target: T, detail: any) => void;
};
declare function sink<T extends SinkEventTarget>(fromBroadcastSource: WindowBroadcast<any>, toSinkTarget: T, namespace: string, eventHandlers?: SinkEventHandlers<T>): T;
export { Broadcast, type BroadcastMessageType, DataEventTarget, KVDataEventTarget, type KVEvents, WindowBroadcast, sink, source };