@sylwellsoftware/glue 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter-upM7NC28.js","sources":["../src/debugging/eventBubble.ts","../src/debugging/eventBus.ts","../src/enums/fetchState.ts","../src/emitters/baseEmitter.ts","../src/emitters/emitter.ts"],"sourcesContent":["let nextEventId = 1\n\nexport interface EventOptions<TValue = unknown> {\n owner?: unknown\n purpose?: string\n value?: TValue\n cause?: unknown\n parent?: EventBubble<unknown> | null\n timestamp?: number\n}\n\n/** A causal diagnostic event. EventBus deliberately stores no history. */\nexport class EventBubble<TValue = unknown> {\n readonly id: string\n readonly timestamp: number\n readonly purpose: string\n readonly cause: unknown\n readonly value: TValue | undefined\n readonly parent: EventBubble<unknown> | null\n readonly parentBubble: EventBubble<unknown> | null\n readonly children: EventBubble<unknown>[] = []\n readonly ownerType: string | null\n private readonly ownerRef: WeakRef<object> | null\n private readonly strongOwner: unknown\n\n constructor(options: EventOptions<TValue> = {}) {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('EventBubble options must be an object')\n }\n\n this.id = `event-${nextEventId++}`\n this.timestamp = options.timestamp ?? Date.now()\n this.purpose = options.purpose ?? 'unspecified'\n this.cause = options.cause ?? null\n this.value = options.value\n this.parent = options.parent ?? null\n this.parentBubble = this.parent\n\n const owner = options.owner\n this.ownerType = owner == null\n ? null\n : getConstructorName(owner) ?? typeof owner\n if (canBeWeaklyReferenced(owner) && typeof WeakRef === 'function') {\n this.ownerRef = new WeakRef(owner)\n this.strongOwner = undefined\n } else {\n this.ownerRef = null\n this.strongOwner = owner\n }\n\n this.parent?.registerChild(this)\n }\n\n get owner(): unknown {\n return this.ownerRef?.deref() ?? this.strongOwner\n }\n\n registerChild(child: EventBubble<unknown>): void {\n if (!(child instanceof EventBubble)) {\n throw new TypeError('EventBubble children must be EventBubble instances')\n }\n if (!this.children.includes(child)) this.children.push(child)\n }\n}\n\nfunction canBeWeaklyReferenced(value: unknown): value is object {\n return (typeof value === 'object' && value !== null) || typeof value === 'function'\n}\n\nfunction getConstructorName(value: object): string | undefined {\n const constructor = Reflect.get(value, 'constructor')\n if (constructor == null || (typeof constructor !== 'object' && typeof constructor !== 'function')) {\n return undefined\n }\n const name = Reflect.get(constructor, 'name')\n return typeof name === 'string' ? name : undefined\n}\n","import type {EventBubble} from './eventBubble.js'\n\nexport type EventListener = (event: EventBubble<unknown>) => void\n\nexport interface BubbleGraph {\n addBubble(event: EventBubble<unknown>): void\n}\n\nconst listeners = new Set<EventListener>()\n\nfunction subscribe(listener: EventListener): () => void {\n if (typeof listener !== 'function') {\n throw new TypeError('EventBus.subscribe requires a function')\n }\n\n listeners.add(listener)\n let active = true\n return () => {\n if (!active) return\n active = false\n listeners.delete(listener)\n }\n}\n\nfunction emit(event: EventBubble<unknown>): void {\n for (const listener of [...listeners]) listener(event)\n}\n\n/** Process-local diagnostic observer that retains no event history. */\nexport const EventBus = Object.freeze({\n subscribe,\n emit,\n emitBubble: emit,\n registerBubbleGraph(graph: BubbleGraph): () => void {\n if (graph == null || typeof graph.addBubble !== 'function') {\n throw new TypeError('registerBubbleGraph requires an addBubble() method')\n }\n return subscribe((event) => graph.addBubble(event))\n },\n get hasSubscribers(): boolean {\n return listeners.size > 0\n },\n get subscriberCount(): number {\n return listeners.size\n },\n})\n","export const FetchState = Object.freeze({\n Error: 'error',\n Loading: 'loading',\n Initial: 'initial',\n Ready: 'ready',\n} as const)\n\nexport type FetchStateValue = typeof FetchState[keyof typeof FetchState]\n\n/** Higher values have higher precedence when source states are combined. */\nexport const FetchStateValues: ReadonlyMap<FetchStateValue, number> = new Map([\n [FetchState.Ready, 1],\n [FetchState.Initial, 2],\n [FetchState.Loading, 3],\n [FetchState.Error, 4],\n])\n\nexport function combineFetchStates(states: Iterable<FetchStateValue>): FetchStateValue {\n let combined: FetchStateValue = FetchState.Ready\n\n for (const state of states) {\n if (!FetchStateValues.has(state)) {\n throw new TypeError(`Unknown fetch state: ${String(state)}`)\n }\n if ((FetchStateValues.get(state) ?? 0) > (FetchStateValues.get(combined) ?? 0)) {\n combined = state\n }\n if (combined === FetchState.Error) break\n }\n\n return combined\n}\n","import {EventBubble} from '../debugging/eventBubble.js'\nimport {EventBus} from '../debugging/eventBus.js'\nimport {combineFetchStates, FetchState} from '../enums/fetchState.js'\nimport type {FetchStateValue} from '../enums/fetchState.js'\n\nexport interface EmitterNotification<TValue, TError = unknown> {\n readonly value: TValue\n readonly fetchState: FetchStateValue\n readonly error: TError | null\n readonly event: EventBubble<unknown> | null\n}\n\nexport interface EmitterOptions<TValue, TError = unknown> {\n fetchState?: FetchStateValue\n error?: TError | null\n owner?: unknown\n purpose?: string\n equals?: (left: TValue, right: TValue) => boolean\n trace?: boolean\n}\n\nexport interface SubscribeOptions {\n emitCurrent?: boolean\n parentEvent?: EventBubble<unknown> | null\n}\n\nexport interface SnapshotUpdate<TValue, TError> {\n value?: TValue\n fetchState?: FetchStateValue\n error?: TError | null\n cause?: unknown\n parentEvent?: EventBubble<unknown> | null\n}\n\nexport interface ReadableEmitter<TValue, TError = unknown> {\n get(): TValue\n getError(): TError | null\n getFetchState(): FetchStateValue\n subscribe(\n listener: (notification: EmitterNotification<TValue, TError>) => void,\n options?: SubscribeOptions,\n ): () => void\n}\n\nexport interface DerivedErrorEntry {\n readonly sourceIndex: number | null\n readonly error: unknown\n}\n\nexport type DerivedErrors = ReadonlyArray<Readonly<DerivedErrorEntry>>\n\nexport type EmitterValue<TEmitter> = TEmitter extends ReadableEmitter<infer TValue, unknown>\n ? TValue\n : never\n\nexport type EmitterValues<TSources extends readonly ReadableEmitter<unknown, unknown>[]> = {\n -readonly [TIndex in keyof TSources]: EmitterValue<TSources[TIndex]>\n}\n\ntype ArrayItem<TValue> = NonNullable<TValue> extends ReadonlyArray<infer TItem>\n ? NonNullable<TItem>\n : never\n\ntype MapEachResult<TValue, TMapped> = TValue extends null | undefined\n ? TValue\n : TValue extends ReadonlyArray<infer TItem>\n ? Array<TItem extends null | undefined ? TItem : TMapped>\n : never\n\nexport type MapOptions<TValue> = Pick<\n EmitterOptions<TValue, DerivedErrors>,\n 'owner' | 'purpose' | 'equals' | 'trace'\n>\n\n/** Shared read, subscription, mapping, tracing, and disposal behavior. */\nexport class BaseEmitter<TValue, TError = unknown>\nimplements ReadableEmitter<TValue, TError> {\n protected readonly subscribers = new Set<\n (notification: EmitterNotification<TValue, TError>) => void\n >()\n protected value: TValue\n protected fetchState: FetchStateValue\n protected error: TError | null\n protected readonly equals: (left: TValue, right: TValue) => boolean\n protected isDisposed = false\n readonly owner: unknown\n readonly purpose: string\n readonly trace: boolean\n\n constructor(initialValue: TValue, options: EmitterOptions<TValue, TError> = {}) {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('Emitter options must be an object')\n }\n\n this.value = initialValue\n this.fetchState = options.fetchState ?? FetchState.Ready\n this.error = options.error ?? null\n this.equals = options.equals ?? Object.is\n this.owner = options.owner\n this.purpose = options.purpose ?? this.constructor.name\n this.trace = options.trace ?? false\n\n if (typeof this.equals !== 'function') {\n throw new TypeError('Emitter equals option must be a function')\n }\n assertFetchState(this.fetchState)\n }\n\n subscribe(\n listener: (notification: EmitterNotification<TValue, TError>) => void,\n options: SubscribeOptions = {},\n ): () => void {\n if (this.isDisposed) throw new Error('Cannot subscribe to a disposed emitter')\n if (typeof listener !== 'function') {\n throw new TypeError('subscribe requires a function')\n }\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('subscribe options must be an object')\n }\n\n const {emitCurrent = true, parentEvent = null} = options\n this.subscribers.add(listener)\n if (emitCurrent) {\n const event = this.createEvent('subscribed', parentEvent, this.value)\n listener(this.notification(event))\n }\n\n let active = true\n return () => {\n if (!active) return\n active = false\n this.subscribers.delete(listener)\n }\n }\n\n subscribeFutureValues(\n listener: (notification: EmitterNotification<TValue, TError>) => void,\n ): () => void {\n return this.subscribe(listener, {emitCurrent: false})\n }\n\n get(): TValue {\n return this.value\n }\n\n getError(): TError | null {\n return this.error\n }\n\n getFetchState(): FetchStateValue {\n return this.fetchState\n }\n\n get disposed(): boolean {\n return this.isDisposed\n }\n\n get subscriberCount(): number {\n return this.subscribers.size\n }\n\n map<TMapped>(\n mapFn: (value: TValue) => TMapped,\n options: MapOptions<TMapped> = {},\n ): DerivedEmitter<TMapped, readonly [BaseEmitter<TValue, TError>]> {\n if (typeof mapFn !== 'function') throw new TypeError('map requires a function')\n return new DerivedEmitter<TMapped, readonly [BaseEmitter<TValue, TError>]>(\n [this] as readonly [BaseEmitter<TValue, TError>],\n ([value]) => mapFn(value),\n {\n ...options,\n owner: options.owner ?? this.owner,\n purpose: options.purpose ?? `${this.purpose}:map`,\n trace: options.trace ?? this.trace,\n },\n )\n }\n\n mapEach<TMapped>(\n this: TValue extends ReadonlyArray<unknown> | null | undefined\n ? BaseEmitter<TValue, TError>\n : never,\n mapFn: (value: ArrayItem<TValue>, index: number) => TMapped,\n options: MapOptions<MapEachResult<TValue, TMapped>> = {},\n ): DerivedEmitter<MapEachResult<TValue, TMapped>, readonly [BaseEmitter<TValue, TError>]> {\n if (typeof mapFn !== 'function') throw new TypeError('mapEach requires a function')\n return new DerivedEmitter<\n MapEachResult<TValue, TMapped>,\n readonly [BaseEmitter<TValue, TError>]\n >([this] as readonly [BaseEmitter<TValue, TError>], ([current]) => {\n if (current == null) return current as MapEachResult<TValue, TMapped>\n if (!Array.isArray(current)) {\n throw new TypeError('mapEach source value must be an array')\n }\n const items = current as ReadonlyArray<ArrayItem<TValue> | null | undefined>\n return items.map((item, index) => item == null ? item : mapFn(item, index)) as\n MapEachResult<TValue, TMapped>\n }, {\n ...options,\n purpose: options.purpose ?? `${this.purpose}:mapEach`,\n })\n }\n\n dispose(): void {\n if (this.isDisposed) return\n this.isDisposed = true\n this.subscribers.clear()\n }\n\n protected notification(\n event: EventBubble<unknown> | null = null,\n ): Readonly<EmitterNotification<TValue, TError>> {\n return Object.freeze({\n value: this.value,\n fetchState: this.fetchState,\n error: this.error,\n event,\n })\n }\n\n protected notify(event: EventBubble<unknown> | null = null): void {\n if (this.isDisposed) return\n const notification = this.notification(event)\n for (const listener of [...this.subscribers]) listener(notification)\n }\n\n protected setSnapshot(next: SnapshotUpdate<TValue, TError> = {}): boolean {\n if (this.isDisposed) return false\n const value = Object.hasOwn(next, 'value') ? next.value as TValue : this.value\n const fetchState = next.fetchState ?? this.fetchState\n const error = Object.hasOwn(next, 'error') ? next.error as TError | null : this.error\n const cause = next.cause ?? 'state changed'\n const parentEvent = next.parentEvent ?? null\n assertFetchState(fetchState)\n\n const changed = !this.equals(this.value, value)\n || this.fetchState !== fetchState\n || !Object.is(this.error, error)\n if (!changed) return false\n\n this.value = value\n this.fetchState = fetchState\n this.error = error\n const event = this.createEvent(cause, parentEvent, value)\n this.notify(event)\n return true\n }\n\n protected createEvent<TEventValue = TValue>(\n cause: unknown,\n parentEvent: EventBubble<unknown> | null = null,\n value: TEventValue = this.value as unknown as TEventValue,\n ): EventBubble<TEventValue> | null {\n if (!this.trace && !parentEvent && !EventBus.hasSubscribers) return null\n\n const event = new EventBubble({\n owner: this.owner ?? this,\n purpose: this.purpose,\n value,\n cause,\n parent: parentEvent,\n })\n if (!parentEvent) EventBus.emit(event)\n return event\n }\n}\n\nexport type DerivedEmitterOptions<TValue> = MapOptions<TValue> & {\n computeFetchState?: (states: FetchStateValue[]) => FetchStateValue\n}\n\n/** Reactive state computed from zero or more source emitters. */\nexport class DerivedEmitter<\n TValue,\n TSources extends readonly ReadableEmitter<unknown, unknown>[] = readonly ReadableEmitter<unknown, unknown>[],\n> extends BaseEmitter<TValue, DerivedErrors> {\n private sources: TSources\n private sourceUnsubscribers: Array<() => void> = []\n private compute: (values: EmitterValues<TSources>) => TValue\n private readonly computeFetchState: (states: FetchStateValue[]) => FetchStateValue\n\n constructor(\n sources: TSources,\n compute: (values: EmitterValues<TSources>) => TValue,\n options: DerivedEmitterOptions<TValue> = {},\n ) {\n const {computeFetchState = combineFetchStates, ...emitterOptions} = options\n // The first synchronous recomputation below establishes the real value.\n super(undefined as TValue, {\n ...emitterOptions,\n fetchState: FetchState.Initial,\n error: null,\n })\n this.sources = [] as unknown as TSources\n this.compute = compute\n this.computeFetchState = computeFetchState\n this.setSourcesAndCompute(sources, compute, {notify: false})\n }\n\n setSourcesAndCompute(\n sources: TSources,\n compute: (values: EmitterValues<TSources>) => TValue = this.compute,\n options: {notify?: boolean; parentEvent?: EventBubble<unknown> | null} = {},\n ): this {\n if (this.isDisposed) throw new Error('Cannot update a disposed derived emitter')\n if (!Array.isArray(sources) || sources.some((source) => !isEmitterLike(source))) {\n throw new TypeError('DerivedEmitter sources must be an array of emitters')\n }\n if (typeof compute !== 'function') {\n throw new TypeError('DerivedEmitter compute must be a function')\n }\n\n this.releaseSources()\n this.sources = [...sources] as unknown as TSources\n this.compute = compute\n this.sourceUnsubscribers = this.sources.map((source) =>\n source.subscribe(({event}) => this.recompute(event), {emitCurrent: false}),\n )\n this.recompute(options.parentEvent ?? null, options.notify ?? true)\n return this\n }\n\n override dispose(): void {\n if (this.isDisposed) return\n this.releaseSources()\n super.dispose()\n }\n\n private releaseSources(): void {\n for (const unsubscribe of this.sourceUnsubscribers) unsubscribe()\n this.sourceUnsubscribers = []\n }\n\n private recompute(parentEvent: EventBubble<unknown> | null = null, notify = true): void {\n // Array.map cannot retain tuple positions, so the runtime-validated source\n // array is narrowed back to its declared tuple at this single boundary.\n const values = this.sources.map((source) => source.get()) as EmitterValues<TSources>\n const states = this.sources.map((source) => source.getFetchState())\n const sourceErrors: DerivedErrorEntry[] = this.sources\n .map((source, sourceIndex) => ({sourceIndex, error: source.getError()}))\n .filter((entry) => entry.error != null)\n\n let value: TValue\n let computeError: unknown = null\n try {\n value = this.compute(values)\n } catch (error) {\n computeError = error\n value = undefined as TValue\n }\n\n const nextErrors: DerivedErrorEntry[] = computeError == null\n ? sourceErrors\n : [...sourceErrors, {sourceIndex: null, error: computeError}]\n const error = stabilizeErrors(this.error, nextErrors)\n let fetchState = this.computeFetchState(states)\n assertFetchState(fetchState)\n if (computeError != null || sourceErrors.length > 0) fetchState = FetchState.Error\n\n if (!notify) {\n this.value = value\n this.fetchState = fetchState\n this.error = error\n return\n }\n\n this.setSnapshot({\n value,\n fetchState,\n error,\n cause: 'derived source changed',\n parentEvent,\n })\n }\n}\n\nfunction stabilizeErrors(\n previous: DerivedErrors | null,\n next: DerivedErrorEntry[],\n): DerivedErrors | null {\n if (next.length === 0) return null\n if (previous != null\n && previous.length === next.length\n && previous.every((entry, index) =>\n entry.sourceIndex === next[index]?.sourceIndex\n && Object.is(entry.error, next[index]?.error))) {\n return previous\n }\n return Object.freeze(next.map((entry) => Object.freeze(entry)))\n}\n\nfunction isEmitterLike(source: unknown): source is ReadableEmitter<unknown, unknown> {\n if ((typeof source !== 'object' || source === null) && typeof source !== 'function') {\n return false\n }\n return typeof Reflect.get(source, 'get') === 'function'\n && typeof Reflect.get(source, 'getFetchState') === 'function'\n && typeof Reflect.get(source, 'getError') === 'function'\n && typeof Reflect.get(source, 'subscribe') === 'function'\n}\n\nfunction assertFetchState(fetchState: FetchStateValue): void {\n combineFetchStates([fetchState])\n}\n","import {EventBubble} from '../debugging/eventBubble.js'\nimport {FetchState} from '../enums/fetchState.js'\nimport type {FetchStateValue} from '../enums/fetchState.js'\nimport {BaseEmitter} from './baseEmitter.js'\nimport type {EmitterOptions} from './baseEmitter.js'\n\nexport class Emitter<TValue, TError = unknown> extends BaseEmitter<TValue, TError> {\n constructor(initialValue: TValue, options: EmitterOptions<TValue, TError> = {}) {\n super(initialValue, options)\n }\n\n setWithState(\n value: TValue,\n fetchState: FetchStateValue = FetchState.Ready,\n error: TError | null = null,\n eventOrCause: EventBubble<unknown> | unknown = null,\n ): boolean {\n const parentEvent = eventOrCause instanceof EventBubble ? eventOrCause : null\n const cause = parentEvent ? 'set called' : (eventOrCause ?? 'set called')\n return this.setSnapshot({value, fetchState, error, cause, parentEvent})\n }\n\n set(value: TValue, eventOrCause: EventBubble<unknown> | unknown = null): boolean {\n return this.setWithState(value, FetchState.Ready, null, eventOrCause)\n }\n}\n"],"names":["nextEventId","EventBubble","options","__publicField","_a","owner","getConstructorName","canBeWeaklyReferenced","child","value","constructor","name","listeners","subscribe","listener","active","emit","event","EventBus","graph","FetchState","FetchStateValues","combineFetchStates","states","combined","state","BaseEmitter","initialValue","assertFetchState","emitCurrent","parentEvent","mapFn","DerivedEmitter","current","item","index","notification","next","fetchState","error","cause","sources","compute","computeFetchState","emitterOptions","source","isEmitterLike","unsubscribe","notify","values","sourceErrors","sourceIndex","entry","computeError","nextErrors","stabilizeErrors","previous","_b","Emitter","eventOrCause"],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { EventBubble } from '../debugging/eventBubble.js';
2
+ import type { FetchStateValue } from '../enums/fetchState.js';
3
+ export interface EmitterNotification<TValue, TError = unknown> {
4
+ readonly value: TValue;
5
+ readonly fetchState: FetchStateValue;
6
+ readonly error: TError | null;
7
+ readonly event: EventBubble<unknown> | null;
8
+ }
9
+ export interface EmitterOptions<TValue, TError = unknown> {
10
+ fetchState?: FetchStateValue;
11
+ error?: TError | null;
12
+ owner?: unknown;
13
+ purpose?: string;
14
+ equals?: (left: TValue, right: TValue) => boolean;
15
+ trace?: boolean;
16
+ }
17
+ export interface SubscribeOptions {
18
+ emitCurrent?: boolean;
19
+ parentEvent?: EventBubble<unknown> | null;
20
+ }
21
+ export interface SnapshotUpdate<TValue, TError> {
22
+ value?: TValue;
23
+ fetchState?: FetchStateValue;
24
+ error?: TError | null;
25
+ cause?: unknown;
26
+ parentEvent?: EventBubble<unknown> | null;
27
+ }
28
+ export interface ReadableEmitter<TValue, TError = unknown> {
29
+ get(): TValue;
30
+ getError(): TError | null;
31
+ getFetchState(): FetchStateValue;
32
+ subscribe(listener: (notification: EmitterNotification<TValue, TError>) => void, options?: SubscribeOptions): () => void;
33
+ }
34
+ export interface DerivedErrorEntry {
35
+ readonly sourceIndex: number | null;
36
+ readonly error: unknown;
37
+ }
38
+ export type DerivedErrors = ReadonlyArray<Readonly<DerivedErrorEntry>>;
39
+ export type EmitterValue<TEmitter> = TEmitter extends ReadableEmitter<infer TValue, unknown> ? TValue : never;
40
+ export type EmitterValues<TSources extends readonly ReadableEmitter<unknown, unknown>[]> = {
41
+ -readonly [TIndex in keyof TSources]: EmitterValue<TSources[TIndex]>;
42
+ };
43
+ type ArrayItem<TValue> = NonNullable<TValue> extends ReadonlyArray<infer TItem> ? NonNullable<TItem> : never;
44
+ type MapEachResult<TValue, TMapped> = TValue extends null | undefined ? TValue : TValue extends ReadonlyArray<infer TItem> ? Array<TItem extends null | undefined ? TItem : TMapped> : never;
45
+ export type MapOptions<TValue> = Pick<EmitterOptions<TValue, DerivedErrors>, 'owner' | 'purpose' | 'equals' | 'trace'>;
46
+ /** Shared read, subscription, mapping, tracing, and disposal behavior. */
47
+ export declare class BaseEmitter<TValue, TError = unknown> implements ReadableEmitter<TValue, TError> {
48
+ protected readonly subscribers: Set<(notification: EmitterNotification<TValue, TError>) => void>;
49
+ protected value: TValue;
50
+ protected fetchState: FetchStateValue;
51
+ protected error: TError | null;
52
+ protected readonly equals: (left: TValue, right: TValue) => boolean;
53
+ protected isDisposed: boolean;
54
+ readonly owner: unknown;
55
+ readonly purpose: string;
56
+ readonly trace: boolean;
57
+ constructor(initialValue: TValue, options?: EmitterOptions<TValue, TError>);
58
+ subscribe(listener: (notification: EmitterNotification<TValue, TError>) => void, options?: SubscribeOptions): () => void;
59
+ subscribeFutureValues(listener: (notification: EmitterNotification<TValue, TError>) => void): () => void;
60
+ get(): TValue;
61
+ getError(): TError | null;
62
+ getFetchState(): FetchStateValue;
63
+ get disposed(): boolean;
64
+ get subscriberCount(): number;
65
+ map<TMapped>(mapFn: (value: TValue) => TMapped, options?: MapOptions<TMapped>): DerivedEmitter<TMapped, readonly [BaseEmitter<TValue, TError>]>;
66
+ mapEach<TMapped>(this: TValue extends ReadonlyArray<unknown> | null | undefined ? BaseEmitter<TValue, TError> : never, mapFn: (value: ArrayItem<TValue>, index: number) => TMapped, options?: MapOptions<MapEachResult<TValue, TMapped>>): DerivedEmitter<MapEachResult<TValue, TMapped>, readonly [BaseEmitter<TValue, TError>]>;
67
+ dispose(): void;
68
+ protected notification(event?: EventBubble<unknown> | null): Readonly<EmitterNotification<TValue, TError>>;
69
+ protected notify(event?: EventBubble<unknown> | null): void;
70
+ protected setSnapshot(next?: SnapshotUpdate<TValue, TError>): boolean;
71
+ protected createEvent<TEventValue = TValue>(cause: unknown, parentEvent?: EventBubble<unknown> | null, value?: TEventValue): EventBubble<TEventValue> | null;
72
+ }
73
+ export type DerivedEmitterOptions<TValue> = MapOptions<TValue> & {
74
+ computeFetchState?: (states: FetchStateValue[]) => FetchStateValue;
75
+ };
76
+ /** Reactive state computed from zero or more source emitters. */
77
+ export declare class DerivedEmitter<TValue, TSources extends readonly ReadableEmitter<unknown, unknown>[] = readonly ReadableEmitter<unknown, unknown>[]> extends BaseEmitter<TValue, DerivedErrors> {
78
+ private sources;
79
+ private sourceUnsubscribers;
80
+ private compute;
81
+ private readonly computeFetchState;
82
+ constructor(sources: TSources, compute: (values: EmitterValues<TSources>) => TValue, options?: DerivedEmitterOptions<TValue>);
83
+ setSourcesAndCompute(sources: TSources, compute?: (values: EmitterValues<TSources>) => TValue, options?: {
84
+ notify?: boolean;
85
+ parentEvent?: EventBubble<unknown> | null;
86
+ }): this;
87
+ dispose(): void;
88
+ private releaseSources;
89
+ private recompute;
90
+ }
91
+ export {};
92
+ //# sourceMappingURL=baseEmitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseEmitter.d.ts","sourceRoot":"","sources":["../../src/emitters/baseEmitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { EventBubble } from '../debugging/eventBubble.js';
2
+ import type { FetchStateValue } from '../enums/fetchState.js';
3
+ import { BaseEmitter } from './baseEmitter.js';
4
+ import type { EmitterOptions } from './baseEmitter.js';
5
+ export declare class Emitter<TValue, TError = unknown> extends BaseEmitter<TValue, TError> {
6
+ constructor(initialValue: TValue, options?: EmitterOptions<TValue, TError>);
7
+ setWithState(value: TValue, fetchState?: FetchStateValue, error?: TError | null, eventOrCause?: EventBubble<unknown> | unknown): boolean;
8
+ set(value: TValue, eventOrCause?: EventBubble<unknown> | unknown): boolean;
9
+ }
10
+ //# sourceMappingURL=emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAA;AAEvD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAA;AAEpD,qBAAa,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAE,SAAQ,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;gBAClE,YAAY,EAAE,MAAM,EAAE,OAAO,GAAE,cAAc,CAAC,MAAM,EAAE,MAAM,CAAM;IAI9E,YAAY,CACR,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,eAAkC,EAC9C,KAAK,GAAE,MAAM,GAAG,IAAW,EAC3B,YAAY,GAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAc,GACpD,OAAO;IAMV,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,GAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAc,GAAG,OAAO;CAGnF"}
@@ -0,0 +1,36 @@
1
+ import { EventBubble } from '../debugging/eventBubble.js';
2
+ import type { QueryHandlerLike } from '../queryhandling/queryHandler.js';
3
+ import { BaseEmitter } from './baseEmitter.js';
4
+ import type { EmitterValue, ReadableEmitter } from './baseEmitter.js';
5
+ export type QueryArgumentEmitters = Record<string, ReadableEmitter<unknown, unknown>>;
6
+ export type QueryArgumentValues<TArguments extends QueryArgumentEmitters> = {
7
+ [TName in keyof TArguments]: EmitterValue<TArguments[TName]>;
8
+ };
9
+ export interface LiveQueryOptions<TResult, TArguments extends QueryArgumentEmitters> {
10
+ handler: QueryHandlerLike<QueryArgumentValues<TArguments>, TResult>;
11
+ args?: TArguments;
12
+ autoFetch?: boolean;
13
+ keepPreviousValue?: boolean;
14
+ owner?: unknown;
15
+ purpose?: string;
16
+ trace?: boolean;
17
+ }
18
+ /** Reactive, abortable query driven by a named record of emitter arguments. */
19
+ export declare class LiveQuery<TResult, TArguments extends QueryArgumentEmitters = Record<string, never>> extends BaseEmitter<TResult | undefined, unknown> {
20
+ readonly handler: QueryHandlerLike<QueryArgumentValues<TArguments>, TResult>;
21
+ readonly args: TArguments;
22
+ readonly keepPreviousValue: boolean;
23
+ private lastSuccessfulValue;
24
+ private argumentUnsubscribers;
25
+ private requestId;
26
+ private abortController;
27
+ /** Exposed for deterministic tests; consumers should use refresh()/retry(). */
28
+ _activeRequest: Promise<TResult | undefined> | null;
29
+ constructor(options: LiveQueryOptions<TResult, TArguments>);
30
+ get argumentValues(): QueryArgumentValues<TArguments>;
31
+ refresh(eventOrCause?: EventBubble<unknown> | unknown): Promise<TResult | undefined>;
32
+ retry(eventOrCause?: EventBubble<unknown> | unknown): Promise<TResult | undefined>;
33
+ dispose(): void;
34
+ private isCurrentRequest;
35
+ }
36
+ //# sourceMappingURL=liveQuery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveQuery.d.ts","sourceRoot":"","sources":["../../src/emitters/liveQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAA;AAEvD,OAAO,KAAK,EAAC,gBAAgB,EAAmC,MAAM,kCAAkC,CAAA;AACxG,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAEnE,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;AAErF,MAAM,MAAM,mBAAmB,CAAC,UAAU,SAAS,qBAAqB,IAAI;KACvE,KAAK,IAAI,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;CAC/D,CAAA;AAED,MAAM,WAAW,gBAAgB,CAC7B,OAAO,EACP,UAAU,SAAS,qBAAqB;IAExC,OAAO,EAAE,gBAAgB,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,CAAA;IACnE,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAWD,+EAA+E;AAC/E,qBAAa,SAAS,CAClB,OAAO,EACP,UAAU,SAAS,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAClE,SAAQ,WAAW,CAAC,OAAO,GAAG,SAAS,EAAE,OAAO,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,CAAA;IAC5E,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAA;IACnC,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,qBAAqB,CAAmB;IAChD,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,eAAe,CAAmC;IAC1D,+EAA+E;IAC/E,cAAc,EAAE,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,IAAI,CAAO;gBAE9C,OAAO,EAAE,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC;IAsC1D,IAAI,cAAc,IAAI,mBAAmB,CAAC,UAAU,CAAC,CAIpD;IAED,OAAO,CAAC,YAAY,GAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAmB,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IA8D/F,KAAK,CAAC,YAAY,GAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAiB,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAIlF,OAAO,IAAI,IAAI;IAWxB,OAAO,CAAC,gBAAgB;CAM3B"}
@@ -0,0 +1,11 @@
1
+ export declare const FetchState: Readonly<{
2
+ readonly Error: "error";
3
+ readonly Loading: "loading";
4
+ readonly Initial: "initial";
5
+ readonly Ready: "ready";
6
+ }>;
7
+ export type FetchStateValue = typeof FetchState[keyof typeof FetchState];
8
+ /** Higher values have higher precedence when source states are combined. */
9
+ export declare const FetchStateValues: ReadonlyMap<FetchStateValue, number>;
10
+ export declare function combineFetchStates(states: Iterable<FetchStateValue>): FetchStateValue;
11
+ //# sourceMappingURL=fetchState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchState.d.ts","sourceRoot":"","sources":["../../src/enums/fetchState.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;EAKZ,CAAA;AAEX,MAAM,MAAM,eAAe,GAAG,OAAO,UAAU,CAAC,MAAM,OAAO,UAAU,CAAC,CAAA;AAExE,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,eAAe,EAAE,MAAM,CAKhE,CAAA;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,eAAe,CAcrF"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Experimental mutation APIs. These exports may change in any prerelease and
3
+ * are intentionally excluded from the stable package barrel.
4
+ */
5
+ export { AsyncCommand, AsyncCommandConcurrencyError, } from './commands/asyncCommand.js';
6
+ export type { AsyncCommandConcurrency, AsyncCommandContext, AsyncCommandExecutor, AsyncCommandOptions, } from './commands/asyncCommand.js';
7
+ //# sourceMappingURL=experimental.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../src/experimental.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACH,YAAY,EACZ,4BAA4B,GAC/B,MAAM,4BAA4B,CAAA;AACnC,YAAY,EACR,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,4BAA4B,CAAA"}
@@ -0,0 +1,151 @@
1
+ var p = Object.defineProperty;
2
+ var E = (e, i, t) => i in e ? p(e, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[i] = t;
3
+ var n = (e, i, t) => E(e, typeof i != "symbol" ? i + "" : i, t);
4
+ import { B as y, F as u, E as b, a as d } from "./emitter-upM7NC28.js";
5
+ class C extends Error {
6
+ constructor() {
7
+ super("AsyncCommand is already running"), this.name = "AsyncCommandConcurrencyError";
8
+ }
9
+ }
10
+ class R extends y {
11
+ constructor(t) {
12
+ v(t);
13
+ const {
14
+ execute: r,
15
+ concurrency: o = "ignore",
16
+ mapError: a = (m) => m,
17
+ owner: c,
18
+ purpose: l = "async command",
19
+ trace: s
20
+ } = t;
21
+ if (S(o), typeof a != "function")
22
+ throw new TypeError("AsyncCommand mapError must be a function");
23
+ super(void 0, {
24
+ fetchState: u.Initial,
25
+ error: null,
26
+ owner: c,
27
+ purpose: l,
28
+ ...s === void 0 ? {} : { trace: s }
29
+ });
30
+ n(this, "execute");
31
+ n(this, "concurrency");
32
+ n(this, "isRunning");
33
+ n(this, "mapError");
34
+ n(this, "runningEmitter");
35
+ n(this, "requestId", 0);
36
+ n(this, "abortController", null);
37
+ n(this, "lastSuccessfulValue");
38
+ n(this, "hasSuccessfulValue", !1);
39
+ /** Exposed for deterministic tests; consumers should use run()/abort(). */
40
+ n(this, "_activeRequest", null);
41
+ this.execute = r, this.concurrency = o, this.mapError = a, this.runningEmitter = new b(!1, {
42
+ owner: c ?? this,
43
+ purpose: `${l}:running`,
44
+ ...s === void 0 ? {} : { trace: s }
45
+ }), this.isRunning = this.runningEmitter;
46
+ }
47
+ run(t, r = "command run") {
48
+ var f;
49
+ if (this.isDisposed) return Promise.resolve(void 0);
50
+ if (this._activeRequest != null) {
51
+ if (this.concurrency === "ignore") return this._activeRequest;
52
+ if (this.concurrency === "reject")
53
+ return Promise.reject(new C());
54
+ (f = this.abortController) == null || f.abort();
55
+ }
56
+ const o = ++this.requestId, a = g();
57
+ this.abortController = a;
58
+ const c = r instanceof d ? r : null, l = c ? "parent command requested" : r;
59
+ this.setSnapshot({
60
+ value: this.lastSuccessfulValue,
61
+ fetchState: u.Loading,
62
+ error: null,
63
+ cause: l,
64
+ parentEvent: c
65
+ });
66
+ const s = this.createEvent("command execute", c, t);
67
+ this.runningEmitter.set(!0, s ?? l);
68
+ const m = Promise.resolve().then(() => this.execute(t, {
69
+ signal: a.signal,
70
+ event: s
71
+ })).then((h) => {
72
+ if (this.isCurrentRequest(o, a))
73
+ return this.lastSuccessfulValue = h, this.hasSuccessfulValue = !0, this.setSnapshot({
74
+ value: h,
75
+ fetchState: u.Ready,
76
+ error: null,
77
+ cause: "command succeeded",
78
+ parentEvent: s
79
+ }), h;
80
+ }).catch((h) => {
81
+ this.isCurrentRequest(o, a) && this.setSnapshot({
82
+ value: this.lastSuccessfulValue,
83
+ fetchState: u.Error,
84
+ error: this.mapCommandError(h),
85
+ cause: "command failed",
86
+ parentEvent: s
87
+ });
88
+ }).finally(() => {
89
+ this.isCurrentRequest(o, a) && (this.abortController = null, this._activeRequest = null, this.runningEmitter.set(!1, s ?? "command settled"));
90
+ });
91
+ return this._activeRequest = m, m;
92
+ }
93
+ abort(t = "command aborted") {
94
+ if (this.isDisposed || this.abortController == null) return !1;
95
+ const r = t instanceof d ? t : null, o = r ? "parent command aborted" : t;
96
+ return this.requestId += 1, this.abortController.abort(), this.abortController = null, this._activeRequest = null, this.runningEmitter.set(!1, r ?? o), this.setSnapshot({
97
+ value: this.lastSuccessfulValue,
98
+ fetchState: this.hasSuccessfulValue ? u.Ready : u.Initial,
99
+ error: null,
100
+ cause: o,
101
+ parentEvent: r
102
+ }), !0;
103
+ }
104
+ reset(t = "command reset") {
105
+ if (this.isDisposed) return;
106
+ this.abort(t), this.lastSuccessfulValue = void 0, this.hasSuccessfulValue = !1;
107
+ const r = t instanceof d ? t : null;
108
+ this.setSnapshot({
109
+ value: void 0,
110
+ fetchState: u.Initial,
111
+ error: null,
112
+ cause: r ? "parent command reset" : t,
113
+ parentEvent: r
114
+ });
115
+ }
116
+ dispose() {
117
+ var t;
118
+ this.isDisposed || (this.requestId += 1, (t = this.abortController) == null || t.abort(), this.abortController = null, this._activeRequest = null, this.runningEmitter.set(!1, "command disposed"), this.runningEmitter.dispose(), super.dispose());
119
+ }
120
+ isCurrentRequest(t, r) {
121
+ return !this.isDisposed && t === this.requestId && r === this.abortController && !r.signal.aborted;
122
+ }
123
+ mapCommandError(t) {
124
+ try {
125
+ return this.mapError(t);
126
+ } catch (r) {
127
+ return r;
128
+ }
129
+ }
130
+ }
131
+ function v(e) {
132
+ if (e == null || typeof e != "object" || Array.isArray(e))
133
+ throw new TypeError("AsyncCommand options must be an object");
134
+ if (typeof e.execute != "function")
135
+ throw new TypeError("AsyncCommand execute must be a function");
136
+ }
137
+ function S(e) {
138
+ if (e !== "ignore" && e !== "replace" && e !== "reject")
139
+ throw new TypeError(`Unknown AsyncCommand concurrency policy: ${e}`);
140
+ }
141
+ function g() {
142
+ const e = Reflect.get(globalThis, "AbortController");
143
+ if (typeof e != "function")
144
+ throw new Error("AsyncCommand requires AbortController in this runtime");
145
+ return new e();
146
+ }
147
+ export {
148
+ R as AsyncCommand,
149
+ C as AsyncCommandConcurrencyError
150
+ };
151
+ //# sourceMappingURL=experimental.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"experimental.js","sources":["../src/commands/asyncCommand.ts"],"sourcesContent":["import {EventBubble} from '../debugging/eventBubble.js'\nimport {BaseEmitter} from '../emitters/baseEmitter.js'\nimport type {ReadableEmitter} from '../emitters/baseEmitter.js'\nimport {Emitter} from '../emitters/emitter.js'\nimport {FetchState} from '../enums/fetchState.js'\nimport type {AbortSignalLike} from '../queryhandling/queryHandler.js'\n\nexport type AsyncCommandConcurrency = 'ignore' | 'replace' | 'reject'\n\nexport interface AsyncCommandContext {\n readonly signal: AbortSignalLike\n readonly event: EventBubble<unknown> | null\n}\n\nexport type AsyncCommandExecutor<TArguments, TResult> = (\n arguments_: TArguments,\n context: AsyncCommandContext,\n) => TResult | PromiseLike<TResult>\n\nexport interface AsyncCommandOptions<TArguments, TResult, TError = unknown> {\n execute: AsyncCommandExecutor<TArguments, TResult>\n concurrency?: AsyncCommandConcurrency\n mapError?: (error: unknown) => TError\n owner?: unknown\n purpose?: string\n trace?: boolean\n}\n\ninterface AbortControllerLike {\n readonly signal: AbortSignalLike\n abort(): void\n}\n\ninterface AbortControllerConstructor {\n new(): AbortControllerLike\n}\n\nexport class AsyncCommandConcurrencyError extends Error {\n constructor() {\n super('AsyncCommand is already running')\n this.name = 'AsyncCommandConcurrencyError'\n }\n}\n\n/** Experimental abortable mutation state with an explicit concurrency policy. */\nexport class AsyncCommand<TArguments, TResult, TError = unknown>\n extends BaseEmitter<TResult | undefined, TError> {\n readonly execute: AsyncCommandExecutor<TArguments, TResult>\n readonly concurrency: AsyncCommandConcurrency\n readonly isRunning: ReadableEmitter<boolean, never>\n private readonly mapError: (error: unknown) => TError\n private readonly runningEmitter: Emitter<boolean, never>\n private requestId = 0\n private abortController: AbortControllerLike | null = null\n private lastSuccessfulValue: TResult | undefined\n private hasSuccessfulValue = false\n /** Exposed for deterministic tests; consumers should use run()/abort(). */\n _activeRequest: Promise<TResult | undefined> | null = null\n\n constructor(options: AsyncCommandOptions<TArguments, TResult, TError>) {\n assertOptions(options)\n const {\n execute,\n concurrency = 'ignore',\n mapError = (error: unknown) => error as TError,\n owner,\n purpose = 'async command',\n trace,\n } = options\n assertConcurrency(concurrency)\n if (typeof mapError !== 'function') {\n throw new TypeError('AsyncCommand mapError must be a function')\n }\n super(undefined, {\n fetchState: FetchState.Initial,\n error: null,\n owner,\n purpose,\n ...(trace === undefined ? {} : {trace}),\n })\n this.execute = execute\n this.concurrency = concurrency\n this.mapError = mapError\n this.runningEmitter = new Emitter<boolean, never>(false, {\n owner: owner ?? this,\n purpose: `${purpose}:running`,\n ...(trace === undefined ? {} : {trace}),\n })\n this.isRunning = this.runningEmitter\n }\n\n run(\n arguments_: TArguments,\n eventOrCause: EventBubble<unknown> | unknown = 'command run',\n ): Promise<TResult | undefined> {\n if (this.isDisposed) return Promise.resolve(undefined)\n if (this._activeRequest != null) {\n if (this.concurrency === 'ignore') return this._activeRequest\n if (this.concurrency === 'reject') {\n return Promise.reject(new AsyncCommandConcurrencyError())\n }\n this.abortController?.abort()\n }\n\n const requestId = ++this.requestId\n const controller = createAbortController()\n this.abortController = controller\n const parentEvent = eventOrCause instanceof EventBubble ? eventOrCause : null\n const cause = parentEvent ? 'parent command requested' : eventOrCause\n this.setSnapshot({\n value: this.lastSuccessfulValue,\n fetchState: FetchState.Loading,\n error: null,\n cause,\n parentEvent,\n })\n const commandEvent = this.createEvent('command execute', parentEvent, arguments_)\n this.runningEmitter.set(true, commandEvent ?? cause)\n\n const request = Promise.resolve()\n .then(() => this.execute(arguments_, {\n signal: controller.signal,\n event: commandEvent,\n }))\n .then((result) => {\n if (!this.isCurrentRequest(requestId, controller)) return undefined\n this.lastSuccessfulValue = result\n this.hasSuccessfulValue = true\n this.setSnapshot({\n value: result,\n fetchState: FetchState.Ready,\n error: null,\n cause: 'command succeeded',\n parentEvent: commandEvent,\n })\n return result\n })\n .catch((error: unknown) => {\n if (!this.isCurrentRequest(requestId, controller)) return undefined\n this.setSnapshot({\n value: this.lastSuccessfulValue,\n fetchState: FetchState.Error,\n error: this.mapCommandError(error),\n cause: 'command failed',\n parentEvent: commandEvent,\n })\n return undefined\n })\n .finally(() => {\n if (!this.isCurrentRequest(requestId, controller)) return\n this.abortController = null\n this._activeRequest = null\n this.runningEmitter.set(false, commandEvent ?? 'command settled')\n })\n\n this._activeRequest = request\n return request\n }\n\n abort(eventOrCause: EventBubble<unknown> | unknown = 'command aborted'): boolean {\n if (this.isDisposed || this.abortController == null) return false\n const parentEvent = eventOrCause instanceof EventBubble ? eventOrCause : null\n const cause = parentEvent ? 'parent command aborted' : eventOrCause\n this.requestId += 1\n this.abortController.abort()\n this.abortController = null\n this._activeRequest = null\n this.runningEmitter.set(false, parentEvent ?? cause)\n this.setSnapshot({\n value: this.lastSuccessfulValue,\n fetchState: this.hasSuccessfulValue ? FetchState.Ready : FetchState.Initial,\n error: null,\n cause,\n parentEvent,\n })\n return true\n }\n\n reset(eventOrCause: EventBubble<unknown> | unknown = 'command reset'): void {\n if (this.isDisposed) return\n this.abort(eventOrCause)\n this.lastSuccessfulValue = undefined\n this.hasSuccessfulValue = false\n const parentEvent = eventOrCause instanceof EventBubble ? eventOrCause : null\n this.setSnapshot({\n value: undefined,\n fetchState: FetchState.Initial,\n error: null,\n cause: parentEvent ? 'parent command reset' : eventOrCause,\n parentEvent,\n })\n }\n\n override dispose(): void {\n if (this.isDisposed) return\n this.requestId += 1\n this.abortController?.abort()\n this.abortController = null\n this._activeRequest = null\n this.runningEmitter.set(false, 'command disposed')\n this.runningEmitter.dispose()\n super.dispose()\n }\n\n private isCurrentRequest(requestId: number, controller: AbortControllerLike): boolean {\n return !this.isDisposed\n && requestId === this.requestId\n && controller === this.abortController\n && !controller.signal.aborted\n }\n\n private mapCommandError(error: unknown): TError {\n try {\n return this.mapError(error)\n } catch (mappingError: unknown) {\n return mappingError as TError\n }\n }\n}\n\nfunction assertOptions<TArguments, TResult, TError>(\n options: AsyncCommandOptions<TArguments, TResult, TError>,\n): void {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('AsyncCommand options must be an object')\n }\n if (typeof options.execute !== 'function') {\n throw new TypeError('AsyncCommand execute must be a function')\n }\n}\n\nfunction assertConcurrency(value: string): asserts value is AsyncCommandConcurrency {\n if (value !== 'ignore' && value !== 'replace' && value !== 'reject') {\n throw new TypeError(`Unknown AsyncCommand concurrency policy: ${value}`)\n }\n}\n\nfunction createAbortController(): AbortControllerLike {\n const constructor = Reflect.get(globalThis, 'AbortController')\n if (typeof constructor !== 'function') {\n throw new Error('AsyncCommand requires AbortController in this runtime')\n }\n return new (constructor as AbortControllerConstructor)()\n}\n"],"names":["AsyncCommandConcurrencyError","AsyncCommand","BaseEmitter","options","assertOptions","execute","concurrency","mapError","error","owner","purpose","trace","assertConcurrency","FetchState","__publicField","Emitter","arguments_","eventOrCause","_a","requestId","controller","createAbortController","parentEvent","EventBubble","cause","commandEvent","request","result","mappingError","value","constructor"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export { EventBubble } from './debugging/eventBubble.js';
2
+ export type { EventOptions } from './debugging/eventBubble.js';
3
+ export { EventBus } from './debugging/eventBus.js';
4
+ export type { BubbleGraph, EventListener } from './debugging/eventBus.js';
5
+ export { BaseEmitter, DerivedEmitter } from './emitters/baseEmitter.js';
6
+ export type { DerivedEmitterOptions, DerivedErrorEntry, DerivedErrors, EmitterNotification, EmitterOptions, EmitterValue, EmitterValues, MapOptions, ReadableEmitter, SnapshotUpdate, SubscribeOptions, } from './emitters/baseEmitter.js';
7
+ export { Emitter } from './emitters/emitter.js';
8
+ export { LiveQuery } from './emitters/liveQuery.js';
9
+ export type { LiveQueryOptions, QueryArgumentEmitters, QueryArgumentValues, } from './emitters/liveQuery.js';
10
+ export { combineFetchStates, FetchState, FetchStateValues } from './enums/fetchState.js';
11
+ export type { FetchStateValue } from './enums/fetchState.js';
12
+ export { QueryArg } from './queryhandling/queryArg.js';
13
+ export { QueryHandler } from './queryhandling/queryHandler.js';
14
+ export type { AbortSignalLike, QueryHandlerLike, QueryRequestOptions, QueryValues, } from './queryhandling/queryHandler.js';
15
+ export { RestQueryHandler } from './queryhandling/restQueryHandler.js';
16
+ export type { FetchLike, JsonResponseLike, QuerySerializer, RestQueryHandlerOptions, SearchParamsLike, UrlLike, } from './queryhandling/restQueryHandler.js';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAA;AACtD,YAAY,EAAC,YAAY,EAAC,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAA;AAChD,YAAY,EAAC,WAAW,EAAE,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAEvE,OAAO,EAAC,WAAW,EAAE,cAAc,EAAC,MAAM,2BAA2B,CAAA;AACrE,YAAY,EACR,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,GACnB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAA;AAC7C,OAAO,EAAC,SAAS,EAAC,MAAM,yBAAyB,CAAA;AACjD,YAAY,EACR,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,EAAC,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAC,MAAM,uBAAuB,CAAA;AACtF,YAAY,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAA;AAE1D,OAAO,EAAC,QAAQ,EAAC,MAAM,6BAA6B,CAAA;AACpD,OAAO,EAAC,YAAY,EAAC,MAAM,iCAAiC,CAAA;AAC5D,YAAY,EACR,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,GACd,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAC,gBAAgB,EAAC,MAAM,qCAAqC,CAAA;AACpE,YAAY,EACR,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,OAAO,GACV,MAAM,qCAAqC,CAAA"}