@sylwellsoftware/glue 0.2.0 → 0.4.0
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.
- package/README.md +108 -11
- package/dist/commands/asyncCommand.d.ts +1 -1
- package/dist/commands/asyncCommand.d.ts.map +1 -1
- package/dist/emitters/liveQuery.d.ts +21 -1
- package/dist/emitters/liveQuery.d.ts.map +1 -1
- package/dist/emitters/liveResult.d.ts +14 -0
- package/dist/emitters/liveResult.d.ts.map +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +760 -110
- package/dist/index.js.map +1 -1
- package/dist/queryhandling/endpoints.d.ts +77 -0
- package/dist/queryhandling/endpoints.d.ts.map +1 -0
- package/dist/queryhandling/restQueryHandler.d.ts +3 -0
- package/dist/queryhandling/restQueryHandler.d.ts.map +1 -1
- package/package.json +2 -7
- package/EXPERIMENTAL.md +0 -44
- package/dist/emitter-upM7NC28.js +0 -293
- package/dist/emitter-upM7NC28.js.map +0 -1
- package/dist/experimental.d.ts +0 -7
- package/dist/experimental.d.ts.map +0 -1
- package/dist/experimental.js +0 -151
- package/dist/experimental.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/emitters/liveQuery.ts","../src/queryhandling/queryArg.ts","../src/queryhandling/queryHandler.ts","../src/queryhandling/restQueryHandler.ts"],"sourcesContent":["import {EventBubble} from '../debugging/eventBubble.js'\nimport {FetchState} from '../enums/fetchState.js'\nimport type {QueryHandlerLike, QueryRequestOptions, QueryValues} from '../queryhandling/queryHandler.js'\nimport {BaseEmitter} from './baseEmitter.js'\nimport type {EmitterValue, ReadableEmitter} from './baseEmitter.js'\n\nexport type QueryArgumentEmitters = Record<string, ReadableEmitter<unknown, unknown>>\n\nexport type QueryArgumentValues<TArguments extends QueryArgumentEmitters> = {\n [TName in keyof TArguments]: EmitterValue<TArguments[TName]>\n}\n\nexport interface LiveQueryOptions<\n TResult,\n TArguments extends QueryArgumentEmitters,\n> {\n handler: QueryHandlerLike<QueryArgumentValues<TArguments>, TResult>\n args?: TArguments\n autoFetch?: boolean\n keepPreviousValue?: boolean\n owner?: unknown\n purpose?: string\n trace?: boolean\n}\n\ninterface AbortControllerLike {\n readonly signal: QueryRequestOptions['signal'] & {readonly aborted: boolean}\n abort(): void\n}\n\ninterface AbortControllerConstructor {\n new(): AbortControllerLike\n}\n\n/** Reactive, abortable query driven by a named record of emitter arguments. */\nexport class LiveQuery<\n TResult,\n TArguments extends QueryArgumentEmitters = Record<string, never>,\n> extends BaseEmitter<TResult | undefined, unknown> {\n readonly handler: QueryHandlerLike<QueryArgumentValues<TArguments>, TResult>\n readonly args: TArguments\n readonly keepPreviousValue: boolean\n private lastSuccessfulValue: TResult | undefined\n private argumentUnsubscribers: Array<() => void>\n private requestId = 0\n private abortController: AbortControllerLike | null = null\n /** Exposed for deterministic tests; consumers should use refresh()/retry(). */\n _activeRequest: Promise<TResult | undefined> | null = null\n\n constructor(options: LiveQueryOptions<TResult, TArguments>) {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('LiveQuery options must be an object')\n }\n const {\n handler,\n args = {} as TArguments,\n autoFetch = true,\n keepPreviousValue = true,\n owner,\n purpose = 'live query',\n trace,\n } = options\n if (handler == null || typeof handler.fetch !== 'function') {\n throw new TypeError('LiveQuery handler must implement fetch()')\n }\n assertNamedArgs(args)\n\n super(undefined, {\n fetchState: FetchState.Initial,\n error: null,\n owner,\n purpose,\n ...(trace === undefined ? {} : {trace}),\n })\n this.handler = handler\n this.args = {...args}\n this.keepPreviousValue = keepPreviousValue\n this.lastSuccessfulValue = undefined\n this.argumentUnsubscribers = Object.values(this.args).map((argument) =>\n argument.subscribe(({event}) => {\n void this.refresh(event)\n }, {emitCurrent: false}),\n )\n\n if (autoFetch) this._activeRequest = this.refresh('initial fetch')\n }\n\n get argumentValues(): QueryArgumentValues<TArguments> {\n return Object.fromEntries(\n Object.entries(this.args).map(([name, argument]) => [name, argument.get()]),\n ) as QueryArgumentValues<TArguments>\n }\n\n refresh(eventOrCause: EventBubble<unknown> | unknown = 'refresh'): Promise<TResult | undefined> {\n if (this.isDisposed) return Promise.resolve(undefined)\n\n const requestId = ++this.requestId\n this.abortController?.abort()\n const controller = createAbortController()\n this.abortController = controller\n const parentEvent = eventOrCause instanceof EventBubble ? eventOrCause : null\n const cause = parentEvent ? 'query arguments changed' : eventOrCause\n const loadingValue = this.keepPreviousValue\n ? this.lastSuccessfulValue\n : undefined\n this.setSnapshot({\n value: loadingValue,\n fetchState: FetchState.Loading,\n error: null,\n cause,\n parentEvent,\n })\n const queryEvent = this.createEvent('query fetch', parentEvent, this.argumentValues)\n\n const request = Promise.resolve()\n .then(() => this.handler.fetch(this.argumentValues, {\n signal: controller.signal,\n event: queryEvent,\n }))\n .then((result) => {\n if (!this.isCurrentRequest(requestId, controller)) return undefined\n this.lastSuccessfulValue = result\n this.setSnapshot({\n value: result,\n fetchState: FetchState.Ready,\n error: null,\n cause: 'query succeeded',\n parentEvent: queryEvent,\n })\n return result\n })\n .catch((error: unknown) => {\n if (!this.isCurrentRequest(requestId, controller) || isAbortError(error)) {\n return undefined\n }\n this.setSnapshot({\n value: this.keepPreviousValue ? this.lastSuccessfulValue : undefined,\n fetchState: FetchState.Error,\n error,\n cause: 'query failed',\n parentEvent: queryEvent,\n })\n return undefined\n })\n .finally(() => {\n if (this.isCurrentRequest(requestId, controller)) {\n this.abortController = null\n this._activeRequest = null\n }\n })\n\n this._activeRequest = request\n return request\n }\n\n retry(eventOrCause: EventBubble<unknown> | unknown = 'retry'): Promise<TResult | undefined> {\n return this.refresh(eventOrCause)\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 for (const unsubscribe of this.argumentUnsubscribers) unsubscribe()\n this.argumentUnsubscribers = []\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\nfunction assertNamedArgs(args: unknown): asserts args is QueryArgumentEmitters {\n if (args == null || typeof args !== 'object' || Array.isArray(args)) {\n throw new TypeError('LiveQuery args must be a named record of emitters')\n }\n for (const [name, argument] of Object.entries(args)) {\n if (argument == null\n || typeof Reflect.get(argument, 'get') !== 'function'\n || typeof Reflect.get(argument, 'subscribe') !== 'function') {\n throw new TypeError(`LiveQuery argument ${name} must be an emitter`)\n }\n }\n}\n\nfunction createAbortController(): AbortControllerLike {\n const constructor = Reflect.get(globalThis, 'AbortController')\n if (typeof constructor !== 'function') {\n throw new Error('LiveQuery requires AbortController in this runtime')\n }\n return new (constructor as AbortControllerConstructor)()\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\n// QueryArgumentValues always produces a record, but keeping this assertion near\n// the handler boundary makes that relationship explicit in emitted declarations.\ntype _QueryValuesProof<T extends QueryValues> = T\ntype _LiveQueryValuesAreRecords<TArgs extends QueryArgumentEmitters> =\n _QueryValuesProof<QueryArgumentValues<TArgs>>\n","import {Emitter} from '../emitters/emitter.js'\nimport type {EmitterOptions, ReadableEmitter} from '../emitters/baseEmitter.js'\n\n/** A named reactive value used by LiveQuery. */\nexport class QueryArg<TValue, TError = unknown> extends Emitter<TValue, TError> {\n readonly name: string\n private sourceUnsubscribe: (() => void) | null\n\n constructor(\n name: string,\n source: ReadableEmitter<TValue, TError>,\n options: EmitterOptions<TValue, TError> = {},\n ) {\n if (typeof name !== 'string' || name.length === 0) {\n throw new TypeError('QueryArg name must be a non-empty string')\n }\n if (source == null\n || typeof source.get !== 'function'\n || typeof source.subscribe !== 'function') {\n throw new TypeError('QueryArg source must be an emitter')\n }\n\n super(source.get(), {\n ...options,\n fetchState: source.getFetchState(),\n error: source.getError(),\n purpose: options.purpose ?? `query argument: ${name}`,\n })\n this.name = name\n this.sourceUnsubscribe = source.subscribe((notification) => {\n this.setWithState(\n notification.value,\n notification.fetchState,\n notification.error,\n notification.event,\n )\n }, {emitCurrent: false})\n }\n\n override dispose(): void {\n if (this.isDisposed) return\n this.sourceUnsubscribe?.()\n this.sourceUnsubscribe = null\n super.dispose()\n }\n}\n","import type {EventBubble} from '../debugging/eventBubble.js'\n\nexport type QueryValues = Record<string, unknown>\n\n/** Minimal web-platform shape so Glue core does not require DOM declarations. */\nexport interface AbortSignalLike {\n readonly aborted: boolean\n}\n\nexport interface QueryRequestOptions {\n signal?: AbortSignalLike\n event?: EventBubble<unknown> | null\n}\n\nexport interface QueryHandlerLike<\n TArguments extends QueryValues,\n TResult,\n> {\n fetch(\n args: TArguments,\n options?: QueryRequestOptions,\n ): TResult | PromiseLike<TResult>\n}\n\n/** Interface/base class for asynchronous query adapters. */\nexport class QueryHandler<\n TArguments extends QueryValues = QueryValues,\n TResult = unknown,\n> implements QueryHandlerLike<TArguments, TResult> {\n fetch(_args: TArguments, _options: QueryRequestOptions = {}): TResult | PromiseLike<TResult> {\n throw new Error('fetch() must be implemented')\n }\n}\n","import {EventBubble} from '../debugging/eventBubble.js'\nimport {EventBus} from '../debugging/eventBus.js'\nimport {QueryHandler} from './queryHandler.js'\nimport type {AbortSignalLike, QueryRequestOptions, QueryValues} from './queryHandler.js'\n\nexport interface SearchParamsLike {\n append(name: string, value: string): void\n set(name: string, value: string): void\n}\n\nexport interface UrlLike {\n readonly searchParams: SearchParamsLike\n toString(): string\n}\n\nexport interface JsonResponseLike<TResult> {\n readonly ok: boolean\n readonly status?: number\n json(): TResult | PromiseLike<TResult>\n}\n\nexport type FetchLike<TResult> = {\n bivarianceHack(\n url: string,\n options?: {signal?: AbortSignalLike | null},\n ): JsonResponseLike<TResult>\n | JsonResponseLike<unknown>\n | PromiseLike<JsonResponseLike<TResult> | JsonResponseLike<unknown>>\n}['bivarianceHack']\n\nexport type QuerySerializer<TArguments extends QueryValues> = (\n url: UrlLike,\n args: TArguments,\n) => void | UrlLike\n\nexport interface RestQueryHandlerOptions<\n TArguments extends QueryValues,\n TResult,\n> {\n url: string\n baseUrl?: string\n fetch?: FetchLike<TResult>\n serialize?: QuerySerializer<TArguments>\n trace?: boolean\n}\n\ninterface UrlConstructor {\n new(url: string, base?: string): UrlLike\n}\n\nclass HttpError extends Error {\n readonly status: number | undefined\n\n constructor(status: number | undefined) {\n super(`HTTP ${status ?? 'unknown'}`)\n this.name = 'HttpError'\n this.status = status\n }\n}\n\n/** Fetch-based JSON query adapter with injectable environment capabilities. */\nexport class RestQueryHandler<\n TArguments extends QueryValues = QueryValues,\n TResult = unknown,\n> extends QueryHandler<TArguments, TResult> {\n readonly url: string\n readonly baseUrl: string | undefined\n readonly fetchImplementation: FetchLike<TResult>\n readonly serialize: QuerySerializer<TArguments>\n readonly trace: boolean\n\n constructor(options: string | RestQueryHandlerOptions<TArguments, TResult>) {\n super()\n const normalized = typeof options === 'string' ? {url: options} : options\n if (normalized == null || typeof normalized !== 'object') {\n throw new TypeError('RestQueryHandler requires a URL or options object')\n }\n if (typeof normalized.url !== 'string' || normalized.url.length === 0) {\n throw new TypeError('RestQueryHandler url must be a non-empty string')\n }\n\n this.url = normalized.url\n this.baseUrl = normalized.baseUrl ?? getLocationHref()\n this.fetchImplementation = normalized.fetch ?? getGlobalFetch<TResult>()\n this.serialize = normalized.serialize ?? serializeQuery\n this.trace = normalized.trace ?? false\n\n if (typeof this.fetchImplementation !== 'function') {\n throw new TypeError('RestQueryHandler requires an injected fetch implementation')\n }\n if (typeof this.serialize !== 'function') {\n throw new TypeError('RestQueryHandler serialize must be a function')\n }\n }\n\n override async fetch(args: TArguments, options: QueryRequestOptions = {}): Promise<TResult> {\n if (args == null || typeof args !== 'object' || Array.isArray(args)) {\n throw new TypeError('REST query args must be a named record')\n }\n\n const url = resolveUrl(this.url, this.baseUrl)\n const serialized = this.serialize(url, args) ?? url\n const Url = getUrlConstructor()\n if (!(serialized instanceof Url)) {\n throw new TypeError('REST serializer must mutate or return a URL')\n }\n\n const parent = options.event ?? null\n if (this.trace || parent || EventBus.hasSubscribers) {\n const event = new EventBubble({\n owner: this,\n purpose: 'REST fetch',\n value: serialized.toString(),\n cause: 'fetch called',\n parent,\n })\n if (!parent) EventBus.emit(event)\n }\n\n const fetchOptions = options.signal === undefined ? {} : {signal: options.signal}\n const response = await this.fetchImplementation(serialized.toString(), fetchOptions)\n if (!response?.ok) throw new HttpError(response?.status)\n return await response.json() as TResult\n }\n}\n\nfunction serializeQuery<TArguments extends QueryValues>(\n url: UrlLike,\n args: TArguments,\n): UrlLike {\n for (const [key, value] of Object.entries(args)) {\n appendValue(url.searchParams, key, value)\n }\n return url\n}\n\nfunction appendValue(params: SearchParamsLike, key: string, value: unknown): void {\n if (value === undefined) return\n if (value === null) {\n params.append(key, '')\n return\n }\n if (Array.isArray(value)) {\n for (const item of value) appendValue(params, key, item)\n return\n }\n if (typeof value === 'object') {\n params.append(key, JSON.stringify(value))\n return\n }\n params.append(key, String(value))\n}\n\nfunction resolveUrl(url: string, baseUrl: string | undefined): UrlLike {\n const Url = getUrlConstructor()\n try {\n return new Url(url)\n } catch (error) {\n if (baseUrl == null) {\n throw new TypeError(`Relative REST URL requires baseUrl: ${url}`, {cause: error})\n }\n return new Url(url, baseUrl)\n }\n}\n\nfunction getUrlConstructor(): UrlConstructor {\n const constructor = Reflect.get(globalThis, 'URL')\n if (typeof constructor !== 'function') {\n throw new Error('RestQueryHandler requires URL in this runtime')\n }\n return constructor as UrlConstructor\n}\n\nfunction getLocationHref(): string | undefined {\n const location = Reflect.get(globalThis, 'location')\n if (location == null || (typeof location !== 'object' && typeof location !== 'function')) {\n return undefined\n }\n const href = Reflect.get(location, 'href')\n return typeof href === 'string' ? href : undefined\n}\n\nfunction getGlobalFetch<TResult>(): FetchLike<TResult> {\n const implementation = Reflect.get(globalThis, 'fetch')\n return implementation as unknown as FetchLike<TResult>\n}\n"],"names":["LiveQuery","BaseEmitter","options","handler","args","autoFetch","keepPreviousValue","owner","purpose","trace","assertNamedArgs","FetchState","__publicField","argument","event","name","eventOrCause","requestId","_a","controller","createAbortController","parentEvent","EventBubble","cause","loadingValue","queryEvent","request","result","error","isAbortError","unsubscribe","constructor","QueryArg","Emitter","source","notification","QueryHandler","_args","_options","HttpError","status","RestQueryHandler","normalized","getLocationHref","getGlobalFetch","serializeQuery","url","resolveUrl","serialized","Url","getUrlConstructor","parent","EventBus","fetchOptions","response","key","value","appendValue","params","item","baseUrl","location","href"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/debugging/eventBubble.ts","../src/debugging/eventBus.ts","../src/enums/fetchState.ts","../src/emitters/baseEmitter.ts","../src/emitters/emitter.ts","../src/commands/asyncCommand.ts","../src/emitters/liveQuery.ts","../src/queryhandling/queryArg.ts","../src/queryhandling/queryHandler.ts","../src/queryhandling/restQueryHandler.ts","../src/queryhandling/endpoints.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","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/** 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","import {EventBubble} from '../debugging/eventBubble.js'\nimport {FetchState} from '../enums/fetchState.js'\nimport type {QueryHandlerLike, QueryRequestOptions, QueryValues} from '../queryhandling/queryHandler.js'\nimport {BaseEmitter} from './baseEmitter.js'\nimport type {EmitterValue, ReadableEmitter} from './baseEmitter.js'\nimport type {RefreshableLiveResult} from './liveResult.js'\n\nexport type QueryArgumentEmitters = Record<string, ReadableEmitter<unknown, unknown>>\n\nexport type QueryArgumentValues<TArguments extends QueryArgumentEmitters> = {\n [TName in keyof TArguments]: EmitterValue<TArguments[TName]>\n}\n\nexport interface PollingScheduler {\n schedule(callback: () => void, delayMs: number): unknown\n cancel(handle: unknown): void\n}\n\nexport interface LiveQueryPollingOptions {\n intervalMs: number | ReadableEmitter<number, unknown>\n enabled?: boolean | ReadableEmitter<boolean, unknown>\n scheduler?: PollingScheduler\n}\n\nexport interface LiveQueryOptions<\n TResult,\n TArguments extends QueryArgumentEmitters,\n> {\n handler: QueryHandlerLike<QueryArgumentValues<TArguments>, TResult>\n args?: TArguments\n autoFetch?: boolean\n keepPreviousValue?: boolean\n polling?: LiveQueryPollingOptions\n owner?: unknown\n purpose?: string\n trace?: boolean\n}\n\ninterface AbortControllerLike {\n readonly signal: QueryRequestOptions['signal'] & {readonly aborted: boolean}\n abort(): void\n}\n\ninterface AbortControllerConstructor {\n new(): AbortControllerLike\n}\n\n/** Reactive, abortable query driven by a named record of emitter arguments. */\nexport class LiveQuery<\n TResult,\n TArguments extends QueryArgumentEmitters = Record<string, never>,\n> extends BaseEmitter<TResult | undefined, unknown>\nimplements RefreshableLiveResult<TResult | undefined, unknown> {\n readonly handler: QueryHandlerLike<QueryArgumentValues<TArguments>, TResult>\n readonly args: TArguments\n readonly keepPreviousValue: boolean\n private lastSuccessfulValue: TResult | undefined\n private hasSuccessfulValue = false\n private argumentUnsubscribers: Array<() => void>\n private pollingUnsubscribers: Array<() => void> = []\n private readonly polling: LiveQueryPollingOptions | undefined\n private readonly pollingScheduler: PollingScheduler\n private pollingHandle: unknown = null\n private requestId = 0\n private abortController: AbortControllerLike | null = null\n /** Exposed for deterministic tests; consumers should use refresh()/retry(). */\n _activeRequest: Promise<TResult | undefined> | null = null\n\n constructor(options: LiveQueryOptions<TResult, TArguments>) {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('LiveQuery options must be an object')\n }\n const {\n handler,\n args = {} as TArguments,\n autoFetch = true,\n keepPreviousValue = true,\n polling,\n owner,\n purpose = 'live query',\n trace,\n } = options\n if (handler == null || typeof handler.fetch !== 'function') {\n throw new TypeError('LiveQuery handler must implement fetch()')\n }\n assertNamedArgs(args)\n if (polling != null) assertPollingOptions(polling)\n\n super(undefined, {\n fetchState: FetchState.Initial,\n error: null,\n owner,\n purpose,\n ...(trace === undefined ? {} : {trace}),\n })\n this.handler = handler\n this.args = {...args}\n this.keepPreviousValue = keepPreviousValue\n this.polling = polling\n this.pollingScheduler = polling?.scheduler ?? defaultPollingScheduler\n this.lastSuccessfulValue = undefined\n this.argumentUnsubscribers = Object.values(this.args).map((argument) =>\n argument.subscribe(({event}) => {\n void this.refresh(event)\n }, {emitCurrent: false}),\n )\n\n if (polling != null) this.initializePolling(polling)\n\n if (autoFetch) this._activeRequest = this.refresh('initial fetch')\n this.scheduleNextPoll()\n }\n\n get argumentValues(): QueryArgumentValues<TArguments> {\n return Object.fromEntries(\n Object.entries(this.args).map(([name, argument]) => [name, argument.get()]),\n ) as QueryArgumentValues<TArguments>\n }\n\n refresh(eventOrCause: EventBubble<unknown> | unknown = 'refresh'): Promise<TResult | undefined> {\n if (this.isDisposed) return Promise.resolve(undefined)\n\n const requestId = ++this.requestId\n this.abortController?.abort()\n const controller = createAbortController()\n this.abortController = controller\n const parentEvent = eventOrCause instanceof EventBubble ? eventOrCause : null\n const cause = parentEvent ? 'query arguments changed' : eventOrCause\n const loadingValue = this.keepPreviousValue\n ? this.lastSuccessfulValue\n : undefined\n this.setSnapshot({\n value: loadingValue,\n fetchState: FetchState.Loading,\n error: null,\n cause,\n parentEvent,\n })\n const queryEvent = this.createEvent('query fetch', parentEvent, this.argumentValues)\n\n const request = Promise.resolve()\n .then(() => this.handler.fetch(this.argumentValues, {\n signal: controller.signal,\n event: queryEvent,\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: 'query succeeded',\n parentEvent: queryEvent,\n })\n return result\n })\n .catch((error: unknown) => {\n if (!this.isCurrentRequest(requestId, controller) || isAbortError(error)) {\n return undefined\n }\n this.setSnapshot({\n value: this.keepPreviousValue ? this.lastSuccessfulValue : undefined,\n fetchState: FetchState.Error,\n error,\n cause: 'query failed',\n parentEvent: queryEvent,\n })\n return undefined\n })\n .finally(() => {\n if (this.isCurrentRequest(requestId, controller)) {\n this.abortController = null\n this._activeRequest = null\n }\n })\n\n this._activeRequest = request\n return request\n }\n\n retry(eventOrCause: EventBubble<unknown> | unknown = 'retry'): Promise<TResult | undefined> {\n return this.refresh(eventOrCause)\n }\n\n abort(eventOrCause: EventBubble<unknown> | unknown = 'query aborted'): void {\n if (this.isDisposed || this.abortController == null) return\n this.requestId += 1\n this.abortController.abort()\n this.abortController = null\n this._activeRequest = null\n const parentEvent = eventOrCause instanceof EventBubble ? eventOrCause : null\n this.setSnapshot({\n value: this.hasSuccessfulValue ? this.lastSuccessfulValue : undefined,\n fetchState: this.hasSuccessfulValue ? FetchState.Ready : FetchState.Initial,\n error: null,\n cause: parentEvent == null ? eventOrCause : 'query aborted',\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.cancelScheduledPoll()\n for (const unsubscribe of this.argumentUnsubscribers) unsubscribe()\n this.argumentUnsubscribers = []\n for (const unsubscribe of this.pollingUnsubscribers) unsubscribe()\n this.pollingUnsubscribers = []\n super.dispose()\n }\n\n private initializePolling(polling: LiveQueryPollingOptions): void {\n for (const source of [polling.intervalMs, polling.enabled]) {\n if (!isReadableEmitter(source)) continue\n this.pollingUnsubscribers.push(source.subscribe(() => {\n assertPollingInterval(readPollingValue(polling.intervalMs))\n assertPollingEnabled(readPollingValue(polling.enabled, true))\n this.cancelScheduledPoll()\n this.scheduleNextPoll()\n }, {emitCurrent: false}))\n }\n }\n\n private scheduleNextPoll(): void {\n if (this.isDisposed || this.polling == null || this.pollingHandle != null) return\n if (!readPollingValue(this.polling.enabled, true)) return\n const intervalMs = readPollingValue(this.polling.intervalMs)\n assertPollingInterval(intervalMs)\n this.pollingHandle = this.pollingScheduler.schedule(() => {\n this.pollingHandle = null\n this.scheduleNextPoll()\n if (this._activeRequest == null) void this.refresh('poll')\n }, intervalMs)\n }\n\n private cancelScheduledPoll(): void {\n if (this.pollingHandle == null) return\n this.pollingScheduler.cancel(this.pollingHandle)\n this.pollingHandle = null\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\nconst defaultPollingScheduler: PollingScheduler = {\n schedule(callback, delayMs) {\n const schedule = Reflect.get(globalThis, 'setTimeout')\n if (typeof schedule !== 'function') {\n throw new Error('LiveQuery polling requires an injected scheduler in this runtime')\n }\n return Reflect.apply(schedule, globalThis, [callback, delayMs])\n },\n cancel(handle) {\n const cancel = Reflect.get(globalThis, 'clearTimeout')\n if (typeof cancel === 'function') Reflect.apply(cancel, globalThis, [handle])\n },\n}\n\nfunction isReadableEmitter(value: unknown): value is ReadableEmitter<never, unknown> {\n return value != null\n && (typeof value === 'object' || typeof value === 'function')\n && typeof Reflect.get(value, 'get') === 'function'\n && typeof Reflect.get(value, 'subscribe') === 'function'\n}\n\nfunction assertPollingSource(value: unknown, name: string): void {\n if (typeof value !== 'number' && typeof value !== 'boolean' && !isReadableEmitter(value)) {\n throw new TypeError(`LiveQuery polling ${name} must be a value or emitter`)\n }\n}\n\nfunction assertPollingOptions(polling: LiveQueryPollingOptions): void {\n if (polling == null || typeof polling !== 'object' || Array.isArray(polling)) {\n throw new TypeError('LiveQuery polling options must be an object')\n }\n assertPollingSource(polling.intervalMs, 'intervalMs')\n if (polling.enabled !== undefined) assertPollingSource(polling.enabled, 'enabled')\n assertPollingInterval(readPollingValue(polling.intervalMs))\n assertPollingEnabled(readPollingValue(polling.enabled, true))\n if (polling.scheduler != null\n && (typeof polling.scheduler.schedule !== 'function'\n || typeof polling.scheduler.cancel !== 'function')) {\n throw new TypeError('LiveQuery polling scheduler must implement schedule() and cancel()')\n }\n}\n\nfunction readPollingValue<TValue>(\n value: TValue | ReadableEmitter<TValue, unknown> | undefined,\n fallback?: TValue,\n): TValue {\n if (value === undefined) return fallback as TValue\n if (isReadableEmitter(value)) return value.get() as TValue\n return value as TValue\n}\n\nfunction assertPollingInterval(value: number): void {\n if (!Number.isFinite(value) || value <= 0) {\n throw new RangeError('LiveQuery polling intervalMs must be a finite positive number')\n }\n}\n\nfunction assertPollingEnabled(value: boolean): void {\n if (typeof value !== 'boolean') {\n throw new TypeError('LiveQuery polling enabled must be a boolean')\n }\n}\n\nfunction assertNamedArgs(args: unknown): asserts args is QueryArgumentEmitters {\n if (args == null || typeof args !== 'object' || Array.isArray(args)) {\n throw new TypeError('LiveQuery args must be a named record of emitters')\n }\n for (const [name, argument] of Object.entries(args)) {\n if (argument == null\n || typeof Reflect.get(argument, 'get') !== 'function'\n || typeof Reflect.get(argument, 'subscribe') !== 'function') {\n throw new TypeError(`LiveQuery argument ${name} must be an emitter`)\n }\n }\n}\n\nfunction createAbortController(): AbortControllerLike {\n const constructor = Reflect.get(globalThis, 'AbortController')\n if (typeof constructor !== 'function') {\n throw new Error('LiveQuery requires AbortController in this runtime')\n }\n return new (constructor as AbortControllerConstructor)()\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n\n// QueryArgumentValues always produces a record, but keeping this assertion near\n// the handler boundary makes that relationship explicit in emitted declarations.\ntype _QueryValuesProof<T extends QueryValues> = T\ntype _LiveQueryValuesAreRecords<TArgs extends QueryArgumentEmitters> =\n _QueryValuesProof<QueryArgumentValues<TArgs>>\n","import {Emitter} from '../emitters/emitter.js'\nimport type {EmitterOptions, ReadableEmitter} from '../emitters/baseEmitter.js'\n\n/** A named reactive value used by LiveQuery. */\nexport class QueryArg<TValue, TError = unknown> extends Emitter<TValue, TError> {\n readonly name: string\n private sourceUnsubscribe: (() => void) | null\n\n constructor(\n name: string,\n source: ReadableEmitter<TValue, TError>,\n options: EmitterOptions<TValue, TError> = {},\n ) {\n if (typeof name !== 'string' || name.length === 0) {\n throw new TypeError('QueryArg name must be a non-empty string')\n }\n if (source == null\n || typeof source.get !== 'function'\n || typeof source.subscribe !== 'function') {\n throw new TypeError('QueryArg source must be an emitter')\n }\n\n super(source.get(), {\n ...options,\n fetchState: source.getFetchState(),\n error: source.getError(),\n purpose: options.purpose ?? `query argument: ${name}`,\n })\n this.name = name\n this.sourceUnsubscribe = source.subscribe((notification) => {\n this.setWithState(\n notification.value,\n notification.fetchState,\n notification.error,\n notification.event,\n )\n }, {emitCurrent: false})\n }\n\n override dispose(): void {\n if (this.isDisposed) return\n this.sourceUnsubscribe?.()\n this.sourceUnsubscribe = null\n super.dispose()\n }\n}\n","import type {EventBubble} from '../debugging/eventBubble.js'\n\nexport type QueryValues = Record<string, unknown>\n\n/** Minimal web-platform shape so Glue core does not require DOM declarations. */\nexport interface AbortSignalLike {\n readonly aborted: boolean\n}\n\nexport interface QueryRequestOptions {\n signal?: AbortSignalLike\n event?: EventBubble<unknown> | null\n}\n\nexport interface QueryHandlerLike<\n TArguments extends QueryValues,\n TResult,\n> {\n fetch(\n args: TArguments,\n options?: QueryRequestOptions,\n ): TResult | PromiseLike<TResult>\n}\n\n/** Interface/base class for asynchronous query adapters. */\nexport class QueryHandler<\n TArguments extends QueryValues = QueryValues,\n TResult = unknown,\n> implements QueryHandlerLike<TArguments, TResult> {\n fetch(_args: TArguments, _options: QueryRequestOptions = {}): TResult | PromiseLike<TResult> {\n throw new Error('fetch() must be implemented')\n }\n}\n","import {EventBubble} from '../debugging/eventBubble.js'\nimport {EventBus} from '../debugging/eventBus.js'\nimport {QueryHandler} from './queryHandler.js'\nimport type {AbortSignalLike, QueryRequestOptions, QueryValues} from './queryHandler.js'\n\nexport interface SearchParamsLike {\n append(name: string, value: string): void\n set(name: string, value: string): void\n}\n\nexport interface UrlLike {\n readonly searchParams: SearchParamsLike\n toString(): string\n}\n\nexport interface JsonResponseLike<TResult> {\n readonly ok: boolean\n readonly status?: number\n json(): TResult | PromiseLike<TResult>\n}\n\nexport type FetchLike<TResult> = {\n bivarianceHack(\n url: string,\n options?: {signal?: AbortSignalLike | null},\n ): JsonResponseLike<TResult>\n | JsonResponseLike<unknown>\n | PromiseLike<JsonResponseLike<TResult> | JsonResponseLike<unknown>>\n}['bivarianceHack']\n\nexport type QuerySerializer<TArguments extends QueryValues> = (\n url: UrlLike,\n args: TArguments,\n) => void | UrlLike\n\nexport type ResultParser<TResult> = (json: unknown) => TResult\n\nexport interface RestQueryHandlerOptions<\n TArguments extends QueryValues,\n TResult,\n> {\n url: string\n baseUrl?: string\n fetch?: FetchLike<TResult>\n serialize?: QuerySerializer<TArguments>\n parseResult?: ResultParser<TResult>\n trace?: boolean\n}\n\ninterface UrlConstructor {\n new(url: string, base?: string): UrlLike\n}\n\nclass HttpError extends Error {\n readonly status: number | undefined\n\n constructor(status: number | undefined) {\n super(`HTTP ${status ?? 'unknown'}`)\n this.name = 'HttpError'\n this.status = status\n }\n}\n\n/** Fetch-based JSON query adapter with injectable environment capabilities. */\nexport class RestQueryHandler<\n TArguments extends QueryValues = QueryValues,\n TResult = unknown,\n> extends QueryHandler<TArguments, TResult> {\n readonly url: string\n readonly baseUrl: string | undefined\n readonly fetchImplementation: FetchLike<TResult>\n readonly serialize: QuerySerializer<TArguments>\n readonly parseResult: ResultParser<TResult> | undefined\n readonly trace: boolean\n\n constructor(options: string | RestQueryHandlerOptions<TArguments, TResult>) {\n super()\n const normalized = typeof options === 'string' ? {url: options} : options\n if (normalized == null || typeof normalized !== 'object') {\n throw new TypeError('RestQueryHandler requires a URL or options object')\n }\n if (typeof normalized.url !== 'string' || normalized.url.length === 0) {\n throw new TypeError('RestQueryHandler url must be a non-empty string')\n }\n\n this.url = normalized.url\n this.baseUrl = normalized.baseUrl ?? getLocationHref()\n this.fetchImplementation = normalized.fetch ?? getGlobalFetch<TResult>()\n this.serialize = normalized.serialize ?? serializeQuery\n this.parseResult = normalized.parseResult\n this.trace = normalized.trace ?? false\n\n if (typeof this.fetchImplementation !== 'function') {\n throw new TypeError('RestQueryHandler requires an injected fetch implementation')\n }\n if (typeof this.serialize !== 'function') {\n throw new TypeError('RestQueryHandler serialize must be a function')\n }\n if (this.parseResult !== undefined && typeof this.parseResult !== 'function') {\n throw new TypeError('RestQueryHandler parseResult must be a function')\n }\n }\n\n override async fetch(args: TArguments, options: QueryRequestOptions = {}): Promise<TResult> {\n if (args == null || typeof args !== 'object' || Array.isArray(args)) {\n throw new TypeError('REST query args must be a named record')\n }\n\n const url = resolveUrl(this.url, this.baseUrl)\n const serialized = this.serialize(url, args) ?? url\n const Url = getUrlConstructor()\n if (!(serialized instanceof Url)) {\n throw new TypeError('REST serializer must mutate or return a URL')\n }\n\n const parent = options.event ?? null\n if (this.trace || parent || EventBus.hasSubscribers) {\n const event = new EventBubble({\n owner: this,\n purpose: 'REST fetch',\n value: serialized.toString(),\n cause: 'fetch called',\n parent,\n })\n if (!parent) EventBus.emit(event)\n }\n\n const fetchOptions = options.signal === undefined ? {} : {signal: options.signal}\n const response = await this.fetchImplementation(serialized.toString(), fetchOptions)\n if (!response?.ok) throw new HttpError(response?.status)\n const json: unknown = await response.json()\n return this.parseResult == null ? json as TResult : this.parseResult(json)\n }\n}\n\nfunction serializeQuery<TArguments extends QueryValues>(\n url: UrlLike,\n args: TArguments,\n): UrlLike {\n for (const [key, value] of Object.entries(args)) {\n appendValue(url.searchParams, key, value)\n }\n return url\n}\n\nfunction appendValue(params: SearchParamsLike, key: string, value: unknown): void {\n if (value === undefined) return\n if (value === null) {\n params.append(key, '')\n return\n }\n if (Array.isArray(value)) {\n for (const item of value) appendValue(params, key, item)\n return\n }\n if (typeof value === 'object') {\n params.append(key, JSON.stringify(value))\n return\n }\n params.append(key, String(value))\n}\n\nfunction resolveUrl(url: string, baseUrl: string | undefined): UrlLike {\n const Url = getUrlConstructor()\n try {\n return new Url(url)\n } catch (error) {\n if (baseUrl == null) {\n throw new TypeError(`Relative REST URL requires baseUrl: ${url}`, {cause: error})\n }\n return new Url(url, baseUrl)\n }\n}\n\nfunction getUrlConstructor(): UrlConstructor {\n const constructor = Reflect.get(globalThis, 'URL')\n if (typeof constructor !== 'function') {\n throw new Error('RestQueryHandler requires URL in this runtime')\n }\n return constructor as UrlConstructor\n}\n\nfunction getLocationHref(): string | undefined {\n const location = Reflect.get(globalThis, 'location')\n if (location == null || (typeof location !== 'object' && typeof location !== 'function')) {\n return undefined\n }\n const href = Reflect.get(location, 'href')\n return typeof href === 'string' ? href : undefined\n}\n\nfunction getGlobalFetch<TResult>(): FetchLike<TResult> {\n const implementation = Reflect.get(globalThis, 'fetch')\n return implementation as unknown as FetchLike<TResult>\n}\n","import {combineFetchStates, FetchState} from '../enums/fetchState.js'\nimport type {FetchStateValue} from '../enums/fetchState.js'\nimport {BaseEmitter} from '../emitters/baseEmitter.js'\nimport type {ReadableEmitter} from '../emitters/baseEmitter.js'\nimport {LiveQuery} from '../emitters/liveQuery.js'\nimport type {\n LiveQueryPollingOptions,\n QueryArgumentValues,\n} from '../emitters/liveQuery.js'\nimport type {LiveResult} from '../emitters/liveResult.js'\nimport type {QueryHandlerLike, QueryValues} from './queryHandler.js'\nimport {RestQueryHandler} from './restQueryHandler.js'\nimport type {RestQueryHandlerOptions} from './restQueryHandler.js'\n\nexport type EndpointArgumentEmitters<TArguments extends QueryValues> = {\n [TName in keyof TArguments]: ReadableEmitter<TArguments[TName], unknown>\n}\n\nexport interface EndpointQueryOptions {\n autoFetch?: boolean\n keepPreviousValue?: boolean\n polling?: LiveQueryPollingOptions\n owner?: unknown\n purpose?: string\n trace?: boolean\n}\n\nexport interface QueryEndpointOptions<\n TArguments extends QueryValues,\n TResult,\n> {\n handler: QueryHandlerLike<TArguments, TResult>\n query?: EndpointQueryOptions\n}\n\n/** Immutable reusable declaration for a query backed by any QueryHandler. */\nexport class QueryEndpoint<\n TArguments extends QueryValues = Record<string, never>,\n TResult = unknown,\n> {\n readonly handler: QueryHandlerLike<TArguments, TResult>\n readonly queryOptions: Readonly<EndpointQueryOptions>\n\n constructor(options: QueryEndpointOptions<TArguments, TResult>) {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('QueryEndpoint options must be an object')\n }\n if (options.handler == null || typeof options.handler.fetch !== 'function') {\n throw new TypeError('QueryEndpoint handler must implement fetch()')\n }\n const query = options.query ?? {}\n assertEndpointQueryOptions(query)\n this.handler = options.handler\n this.queryOptions = Object.freeze({...query})\n Object.freeze(this)\n }\n\n open<TEmitters extends EndpointArgumentEmitters<TArguments>>(\n args: TEmitters,\n options: EndpointQueryOptions = {},\n ): LiveQuery<TResult, TEmitters> {\n assertEndpointArguments(args)\n assertEndpointQueryOptions(options)\n return new LiveQuery<TResult, TEmitters>({\n handler: this.handler as QueryHandlerLike<QueryArgumentValues<TEmitters>, TResult>,\n args,\n ...this.queryOptions,\n ...options,\n })\n }\n}\n\nexport function queryEndpoint<\n TArguments extends QueryValues = Record<string, never>,\n TResult = unknown,\n>(options: QueryEndpointOptions<TArguments, TResult>): QueryEndpoint<TArguments, TResult> {\n return new QueryEndpoint(options)\n}\n\nexport type RestEndpointOptions<TArguments extends QueryValues, TResult> =\n RestQueryHandlerOptions<TArguments, TResult> & {\n query?: EndpointQueryOptions\n }\n\n/** Immutable reusable declaration for one REST-backed query endpoint. */\nexport class RestEndpoint<\n TArguments extends QueryValues = Record<string, never>,\n TResult = unknown,\n> {\n readonly handler: RestQueryHandler<TArguments, TResult>\n readonly queryOptions: Readonly<EndpointQueryOptions>\n\n constructor(options: RestEndpointOptions<TArguments, TResult>) {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('RestEndpoint options must be an object')\n }\n const {query = {}, ...handlerOptions} = options\n assertEndpointQueryOptions(query, 'RestEndpoint query options')\n this.handler = new RestQueryHandler(handlerOptions)\n this.queryOptions = Object.freeze({...query})\n Object.freeze(this)\n }\n\n open<TEmitters extends EndpointArgumentEmitters<TArguments>>(\n args: TEmitters,\n options: EndpointQueryOptions = {},\n ): LiveQuery<TResult, TEmitters> {\n assertEndpointArguments(args)\n assertEndpointQueryOptions(options)\n return new LiveQuery<TResult, TEmitters>({\n handler: this.handler as QueryHandlerLike<QueryArgumentValues<TEmitters>, TResult>,\n args,\n ...this.queryOptions,\n ...options,\n })\n }\n}\n\nexport function restEndpoint<\n TArguments extends QueryValues = Record<string, never>,\n TResult = unknown,\n>(options: RestEndpointOptions<TArguments, TResult>): RestEndpoint<TArguments, TResult> {\n return new RestEndpoint(options)\n}\n\nexport interface DerivedEndpointOptions<\n TSource,\n TArguments extends QueryValues,\n TResult,\n> {\n apply(source: TSource, args: TArguments): TResult\n purpose?: string\n}\n\nexport interface OpenDerivedEndpointOptions<\n TSource,\n TArguments extends QueryValues,\n TSourceError,\n> {\n source: ReadableEmitter<TSource, TSourceError>\n args: EndpointArgumentEmitters<TArguments>\n owner?: unknown\n purpose?: string\n trace?: boolean\n}\n\n/** Immutable declaration for a local live projection over another result. */\nexport class DerivedEndpoint<\n TSource,\n TArguments extends QueryValues,\n TResult,\n> {\n readonly apply: (source: TSource, args: TArguments) => TResult\n readonly purpose: string\n\n constructor(options: DerivedEndpointOptions<TSource, TArguments, TResult>) {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('DerivedEndpoint options must be an object')\n }\n if (typeof options.apply !== 'function') {\n throw new TypeError('DerivedEndpoint apply must be a function')\n }\n this.apply = options.apply\n this.purpose = options.purpose ?? 'derived endpoint'\n Object.freeze(this)\n }\n\n open<TSourceError = unknown>(\n options: OpenDerivedEndpointOptions<TSource, TArguments, TSourceError>,\n ): DerivedLiveResult<TSource, TArguments, TResult, TSourceError> {\n return new DerivedLiveResult({\n ...options,\n apply: this.apply,\n purpose: options.purpose ?? this.purpose,\n })\n }\n}\n\nexport function derivedEndpoint<\n TSource,\n TArguments extends QueryValues,\n TResult,\n>(options: DerivedEndpointOptions<TSource, TArguments, TResult>):\nDerivedEndpoint<TSource, TArguments, TResult> {\n return new DerivedEndpoint(options)\n}\n\ninterface DerivedLiveResultOptions<\n TSource,\n TArguments extends QueryValues,\n TResult,\n TSourceError,\n> extends OpenDerivedEndpointOptions<TSource, TArguments, TSourceError> {\n apply(source: TSource, args: TArguments): TResult\n}\n\n/** Caller-owned local result produced by a DerivedEndpoint declaration. */\nexport class DerivedLiveResult<\n TSource,\n TArguments extends QueryValues,\n TResult,\n TSourceError = unknown,\n> extends BaseEmitter<TResult, unknown>\nimplements LiveResult<TResult, unknown> {\n readonly source: ReadableEmitter<TSource, TSourceError>\n readonly args: EndpointArgumentEmitters<TArguments>\n private readonly apply: (source: TSource, args: TArguments) => TResult\n private unsubscribers: Array<() => void> = []\n private lastSuccessfulValue: TResult\n\n constructor(options: DerivedLiveResultOptions<TSource, TArguments, TResult, TSourceError>) {\n if (options == null || typeof options !== 'object' || Array.isArray(options)) {\n throw new TypeError('DerivedLiveResult options must be an object')\n }\n assertEndpointArguments(options.args)\n if (!isReadableEmitter(options.source)) {\n throw new TypeError('DerivedLiveResult source must be an emitter')\n }\n if (typeof options.apply !== 'function') {\n throw new TypeError('DerivedLiveResult apply must be a function')\n }\n super(undefined as TResult, {\n fetchState: FetchState.Initial,\n error: null,\n owner: options.owner,\n ...(options.purpose === undefined ? {} : {purpose: options.purpose}),\n ...(options.trace === undefined ? {} : {trace: options.trace}),\n })\n this.source = options.source\n this.args = {...options.args}\n this.apply = options.apply\n this.lastSuccessfulValue = undefined as TResult\n const sources: Array<ReadableEmitter<unknown, unknown>> = [\n this.source,\n ...Object.values(this.args),\n ]\n this.unsubscribers = sources.map((source) => source.subscribe(({event}) => {\n this.recompute(event)\n }, {emitCurrent: false}))\n this.recompute(null, false)\n }\n\n override dispose(): void {\n if (this.isDisposed) return\n for (const unsubscribe of this.unsubscribers) unsubscribe()\n this.unsubscribers = []\n super.dispose()\n }\n\n private recompute(parentEvent: import('../debugging/eventBubble.js').EventBubble<unknown> | null,\n notify = true): void {\n const sources: ReadonlyArray<ReadableEmitter<unknown, unknown>> = [\n this.source,\n ...Object.values(this.args),\n ]\n const sourceError = sources.find((source) => source.getError() != null)?.getError() ?? null\n let fetchState: FetchStateValue = combineFetchStates(\n sources.map((source) => source.getFetchState()),\n )\n const sourceValue = this.source.get()\n let value = this.lastSuccessfulValue\n let error: unknown = sourceError\n\n try {\n const argumentValues = Object.fromEntries(\n Object.entries(this.args).map(([name, argument]) => [name, argument.get()]),\n ) as TArguments\n value = this.apply(sourceValue, argumentValues)\n this.lastSuccessfulValue = value\n } catch (caught) {\n error = caught\n fetchState = FetchState.Error\n }\n if (sourceError != null) {\n error = sourceError\n fetchState = FetchState.Error\n }\n\n if (!notify) {\n this.value = value\n this.fetchState = fetchState\n this.error = error\n return\n }\n this.setSnapshot({\n value,\n fetchState,\n error,\n cause: 'derived endpoint source changed',\n parentEvent,\n })\n }\n}\n\nfunction assertEndpointQueryOptions(\n value: unknown,\n label = 'Endpoint query options',\n): asserts value is EndpointQueryOptions {\n if (value == null || typeof value !== 'object' || Array.isArray(value)) {\n throw new TypeError(`${label} must be an object`)\n }\n}\n\nfunction assertEndpointArguments(value: unknown): asserts value is Record<\nstring,\nReadableEmitter<unknown, unknown>\n> {\n if (value == null || typeof value !== 'object' || Array.isArray(value)) {\n throw new TypeError('Endpoint args must be a named record of emitters')\n }\n for (const [name, argument] of Object.entries(value)) {\n if (!isReadableEmitter(argument)) {\n throw new TypeError(`Endpoint argument ${name} must be an emitter`)\n }\n }\n}\n\nfunction isReadableEmitter(value: unknown): value is ReadableEmitter<unknown, unknown> {\n return value != null\n && (typeof value === 'object' || typeof value === 'function')\n && typeof Reflect.get(value, 'get') === 'function'\n && typeof Reflect.get(value, 'getFetchState') === 'function'\n && typeof Reflect.get(value, 'getError') === 'function'\n && typeof Reflect.get(value, 'subscribe') === 'function'\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","AsyncCommandConcurrencyError","AsyncCommand","assertOptions","execute","concurrency","mapError","purpose","trace","assertConcurrency","arguments_","requestId","controller","createAbortController","commandEvent","request","result","mappingError","LiveQuery","handler","args","autoFetch","keepPreviousValue","polling","assertNamedArgs","assertPollingOptions","defaultPollingScheduler","argument","loadingValue","queryEvent","isAbortError","isReadableEmitter","assertPollingInterval","readPollingValue","assertPollingEnabled","intervalMs","callback","delayMs","schedule","handle","cancel","assertPollingSource","fallback","QueryArg","QueryHandler","_args","_options","HttpError","status","RestQueryHandler","normalized","getLocationHref","getGlobalFetch","serializeQuery","url","resolveUrl","serialized","Url","getUrlConstructor","parent","fetchOptions","response","json","key","appendValue","params","baseUrl","location","href","QueryEndpoint","query","assertEndpointQueryOptions","assertEndpointArguments","queryEndpoint","RestEndpoint","handlerOptions","restEndpoint","DerivedEndpoint","DerivedLiveResult","derivedEndpoint","sourceError","sourceValue","argumentValues","caught","label"],"mappings":";;;AAAA,IAAIA,IAAc;AAYX,MAAMC,EAA8B;AAAA,EAavC,YAAYC,IAAgC,IAAI;AAZvC,IAAAC,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,kBAAmC,CAAA;AACnC,IAAAA,EAAA;AACQ,IAAAA,EAAA;AACA,IAAAA,EAAA;AAvBrB,QAAAC;AA0BQ,QAAIF,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,YAAM,IAAI,UAAU,uCAAuC;AAG/D,SAAK,KAAK,SAASF,GAAa,IAChC,KAAK,YAAYE,EAAQ,aAAa,KAAK,IAAA,GAC3C,KAAK,UAAUA,EAAQ,WAAW,eAClC,KAAK,QAAQA,EAAQ,SAAS,MAC9B,KAAK,QAAQA,EAAQ,OACrB,KAAK,SAASA,EAAQ,UAAU,MAChC,KAAK,eAAe,KAAK;AAEzB,UAAMG,IAAQH,EAAQ;AACtB,SAAK,YAAYG,KAAS,OACpB,OACAC,EAAmBD,CAAK,KAAK,OAAOA,GACtCE,EAAsBF,CAAK,KAAK,OAAO,WAAY,cACnD,KAAK,WAAW,IAAI,QAAQA,CAAK,GACjC,KAAK,cAAc,WAEnB,KAAK,WAAW,MAChB,KAAK,cAAcA,KAGvBD,IAAA,KAAK,WAAL,QAAAA,EAAa,cAAc;AAAA,EAC/B;AAAA,EAEA,IAAI,QAAiB;AArDzB,QAAAA;AAsDQ,aAAOA,IAAA,KAAK,aAAL,gBAAAA,EAAe,YAAW,KAAK;AAAA,EAC1C;AAAA,EAEA,cAAcI,GAAmC;AAC7C,QAAI,EAAEA,aAAiBP;AACnB,YAAM,IAAI,UAAU,oDAAoD;AAE5E,IAAK,KAAK,SAAS,SAASO,CAAK,KAAG,KAAK,SAAS,KAAKA,CAAK;AAAA,EAChE;AACJ;AAEA,SAASD,EAAsBE,GAAiC;AAC5D,SAAQ,OAAOA,KAAU,YAAYA,MAAU,QAAS,OAAOA,KAAU;AAC7E;AAEA,SAASH,EAAmBG,GAAmC;AAC3D,QAAMC,IAAc,QAAQ,IAAID,GAAO,aAAa;AACpD,MAAIC,KAAe,QAAS,OAAOA,KAAgB,YAAY,OAAOA,KAAgB;AAClF;AAEJ,QAAMC,IAAO,QAAQ,IAAID,GAAa,MAAM;AAC5C,SAAO,OAAOC,KAAS,WAAWA,IAAO;AAC7C;ACpEA,MAAMC,wBAAgB,IAAA;AAEtB,SAASC,EAAUC,GAAqC;AACpD,MAAI,OAAOA,KAAa;AACpB,UAAM,IAAI,UAAU,wCAAwC;AAGhE,EAAAF,EAAU,IAAIE,CAAQ;AACtB,MAAIC,IAAS;AACb,SAAO,MAAM;AACT,IAAKA,MACLA,IAAS,IACTH,EAAU,OAAOE,CAAQ;AAAA,EAC7B;AACJ;AAEA,SAASE,EAAKC,GAAmC;AAC7C,aAAWH,KAAY,CAAC,GAAGF,CAAS,KAAYK,CAAK;AACzD;AAGO,MAAMC,IAAW,OAAO,OAAO;AAAA,EAClC,WAAAL;AAAA,EACA,MAAAG;AAAA,EACA,YAAYA;AAAA,EACZ,oBAAoBG,GAAgC;AAChD,QAAIA,KAAS,QAAQ,OAAOA,EAAM,aAAc;AAC5C,YAAM,IAAI,UAAU,oDAAoD;AAE5E,WAAON,EAAU,CAACI,MAAUE,EAAM,UAAUF,CAAK,CAAC;AAAA,EACtD;AAAA,EACA,IAAI,iBAA0B;AAC1B,WAAOL,EAAU,OAAO;AAAA,EAC5B;AAAA,EACA,IAAI,kBAA0B;AAC1B,WAAOA,EAAU;AAAA,EACrB;AACJ,CAAC,GC7CYQ,IAAa,OAAO,OAAO;AAAA,EACpC,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AACX,CAAU,GAKGC,wBAA6D,IAAI;AAAA,EAC1E,CAACD,EAAW,OAAO,CAAC;AAAA,EACpB,CAACA,EAAW,SAAS,CAAC;AAAA,EACtB,CAACA,EAAW,SAAS,CAAC;AAAA,EACtB,CAACA,EAAW,OAAO,CAAC;AACxB,CAAC;AAEM,SAASE,EAAmBC,GAAoD;AACnF,MAAIC,IAA4BJ,EAAW;AAE3C,aAAWK,KAASF,GAAQ;AACxB,QAAI,CAACF,EAAiB,IAAII,CAAK;AAC3B,YAAM,IAAI,UAAU,wBAAwB,OAAOA,CAAK,CAAC,EAAE;AAK/D,SAHKJ,EAAiB,IAAII,CAAK,KAAK,MAAMJ,EAAiB,IAAIG,CAAQ,KAAK,OACxEA,IAAWC,IAEXD,MAAaJ,EAAW,MAAO;AAAA,EACvC;AAEA,SAAOI;AACX;AC4CO,MAAME,EAC8B;AAAA,EAavC,YAAYC,GAAsBzB,IAA0C,IAAI;AAZ7D,IAAAC,EAAA,yCAAkB,IAAA;AAG3B,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACS,IAAAA,EAAA;AACT,IAAAA,EAAA,oBAAa;AACd,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AAGL,QAAID,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,YAAM,IAAI,UAAU,mCAAmC;AAW3D,QARA,KAAK,QAAQyB,GACb,KAAK,aAAazB,EAAQ,cAAckB,EAAW,OACnD,KAAK,QAAQlB,EAAQ,SAAS,MAC9B,KAAK,SAASA,EAAQ,UAAU,OAAO,IACvC,KAAK,QAAQA,EAAQ,OACrB,KAAK,UAAUA,EAAQ,WAAW,KAAK,YAAY,MACnD,KAAK,QAAQA,EAAQ,SAAS,IAE1B,OAAO,KAAK,UAAW;AACvB,YAAM,IAAI,UAAU,0CAA0C;AAElE,IAAA0B,EAAiB,KAAK,UAAU;AAAA,EACpC;AAAA,EAEA,UACId,GACAZ,IAA4B,IAClB;AACV,QAAI,KAAK,WAAY,OAAM,IAAI,MAAM,wCAAwC;AAC7E,QAAI,OAAOY,KAAa;AACpB,YAAM,IAAI,UAAU,+BAA+B;AAEvD,QAAIZ,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,YAAM,IAAI,UAAU,qCAAqC;AAG7D,UAAM,EAAC,aAAA2B,IAAc,IAAM,aAAAC,IAAc,SAAQ5B;AAEjD,QADA,KAAK,YAAY,IAAIY,CAAQ,GACzBe,GAAa;AACb,YAAMZ,IAAQ,KAAK,YAAY,cAAca,GAAa,KAAK,KAAK;AACpE,MAAAhB,EAAS,KAAK,aAAaG,CAAK,CAAC;AAAA,IACrC;AAEA,QAAIF,IAAS;AACb,WAAO,MAAM;AACT,MAAKA,MACLA,IAAS,IACT,KAAK,YAAY,OAAOD,CAAQ;AAAA,IACpC;AAAA,EACJ;AAAA,EAEA,sBACIA,GACU;AACV,WAAO,KAAK,UAAUA,GAAU,EAAC,aAAa,IAAM;AAAA,EACxD;AAAA,EAEA,MAAc;AACV,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,WAA0B;AACtB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,gBAAiC;AAC7B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,WAAoB;AACpB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,kBAA0B;AAC1B,WAAO,KAAK,YAAY;AAAA,EAC5B;AAAA,EAEA,IACIiB,GACA7B,IAA+B,IACgC;AAC/D,QAAI,OAAO6B,KAAU,WAAY,OAAM,IAAI,UAAU,yBAAyB;AAC9E,WAAO,IAAIC;AAAA,MACP,CAAC,IAAI;AAAA,MACL,CAAC,CAACvB,CAAK,MAAMsB,EAAMtB,CAAK;AAAA,MACxB;AAAA,QACI,GAAGP;AAAA,QACH,OAAOA,EAAQ,SAAS,KAAK;AAAA,QAC7B,SAASA,EAAQ,WAAW,GAAG,KAAK,OAAO;AAAA,QAC3C,OAAOA,EAAQ,SAAS,KAAK;AAAA,MAAA;AAAA,IACjC;AAAA,EAER;AAAA,EAEA,QAII6B,GACA7B,IAAsD,IACgC;AACtF,QAAI,OAAO6B,KAAU,WAAY,OAAM,IAAI,UAAU,6BAA6B;AAClF,WAAO,IAAIC,EAGT,CAAC,IAAI,GAA6C,CAAC,CAACC,CAAO,MAAM;AAC/D,UAAIA,KAAW,KAAM,QAAOA;AAC5B,UAAI,CAAC,MAAM,QAAQA,CAAO;AACtB,cAAM,IAAI,UAAU,uCAAuC;AAG/D,aADcA,EACD,IAAI,CAACC,GAAMC,MAAUD,KAAQ,OAAOA,IAAOH,EAAMG,GAAMC,CAAK,CAAC;AAAA,IAE9E,GAAG;AAAA,MACC,GAAGjC;AAAA,MACH,SAASA,EAAQ,WAAW,GAAG,KAAK,OAAO;AAAA,IAAA,CAC9C;AAAA,EACL;AAAA,EAEA,UAAgB;AACZ,IAAI,KAAK,eACT,KAAK,aAAa,IAClB,KAAK,YAAY,MAAA;AAAA,EACrB;AAAA,EAEU,aACNe,IAAqC,MACQ;AAC7C,WAAO,OAAO,OAAO;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,OAAAA;AAAA,IAAA,CACH;AAAA,EACL;AAAA,EAEU,OAAOA,IAAqC,MAAY;AAC9D,QAAI,KAAK,WAAY;AACrB,UAAMmB,IAAe,KAAK,aAAanB,CAAK;AAC5C,eAAWH,KAAY,CAAC,GAAG,KAAK,WAAW,KAAYsB,CAAY;AAAA,EACvE;AAAA,EAEU,YAAYC,IAAuC,IAAa;AACtE,QAAI,KAAK,WAAY,QAAO;AAC5B,UAAM5B,IAAQ,OAAO,OAAO4B,GAAM,OAAO,IAAIA,EAAK,QAAkB,KAAK,OACnEC,IAAaD,EAAK,cAAc,KAAK,YACrCE,IAAQ,OAAO,OAAOF,GAAM,OAAO,IAAIA,EAAK,QAAyB,KAAK,OAC1EG,IAAQH,EAAK,SAAS,iBACtBP,IAAcO,EAAK,eAAe;AAMxC,QALAT,EAAiBU,CAAU,GAKvB,EAHY,CAAC,KAAK,OAAO,KAAK,OAAO7B,CAAK,KACvC,KAAK,eAAe6B,KACpB,CAAC,OAAO,GAAG,KAAK,OAAOC,CAAK,GACrB,QAAO;AAErB,SAAK,QAAQ9B,GACb,KAAK,aAAa6B,GAClB,KAAK,QAAQC;AACb,UAAMtB,IAAQ,KAAK,YAAYuB,GAAOV,GAAarB,CAAK;AACxD,gBAAK,OAAOQ,CAAK,GACV;AAAA,EACX;AAAA,EAEU,YACNuB,GACAV,IAA2C,MAC3CrB,IAAqB,KAAK,OACK;AAC/B,QAAI,CAAC,KAAK,SAAS,CAACqB,KAAe,CAACZ,EAAS,eAAgB,QAAO;AAEpE,UAAMD,IAAQ,IAAIhB,EAAY;AAAA,MAC1B,OAAO,KAAK,SAAS;AAAA,MACrB,SAAS,KAAK;AAAA,MACd,OAAAQ;AAAA,MACA,OAAA+B;AAAA,MACA,QAAQV;AAAA,IAAA,CACX;AACD,WAAKA,KAAaZ,EAAS,KAAKD,CAAK,GAC9BA;AAAA,EACX;AACJ;AAOO,MAAMe,UAGHN,EAAmC;AAAA,EAMzC,YACIe,GACAC,GACAxC,IAAyC,CAAA,GAC3C;AACE,UAAM,EAAC,mBAAAyC,IAAoBrB,GAAoB,GAAGsB,MAAkB1C;AAEpE,UAAM,QAAqB;AAAA,MACvB,GAAG0C;AAAA,MACH,YAAYxB,EAAW;AAAA,MACvB,OAAO;AAAA,IAAA,CACV;AAhBG,IAAAjB,EAAA;AACA,IAAAA,EAAA,6BAAyC,CAAA;AACzC,IAAAA,EAAA;AACS,IAAAA,EAAA;AAcb,SAAK,UAAU,CAAA,GACf,KAAK,UAAUuC,GACf,KAAK,oBAAoBC,GACzB,KAAK,qBAAqBF,GAASC,GAAS,EAAC,QAAQ,IAAM;AAAA,EAC/D;AAAA,EAEA,qBACID,GACAC,IAAuD,KAAK,SAC5DxC,IAAyE,IACrE;AACJ,QAAI,KAAK,WAAY,OAAM,IAAI,MAAM,0CAA0C;AAC/E,QAAI,CAAC,MAAM,QAAQuC,CAAO,KAAKA,EAAQ,KAAK,CAACI,MAAW,CAACC,EAAcD,CAAM,CAAC;AAC1E,YAAM,IAAI,UAAU,qDAAqD;AAE7E,QAAI,OAAOH,KAAY;AACnB,YAAM,IAAI,UAAU,2CAA2C;AAGnE,gBAAK,eAAA,GACL,KAAK,UAAU,CAAC,GAAGD,CAAO,GAC1B,KAAK,UAAUC,GACf,KAAK,sBAAsB,KAAK,QAAQ;AAAA,MAAI,CAACG,MACzCA,EAAO,UAAU,CAAC,EAAC,OAAA5B,EAAA,MAAW,KAAK,UAAUA,CAAK,GAAG,EAAC,aAAa,IAAM;AAAA,IAAA,GAE7E,KAAK,UAAUf,EAAQ,eAAe,MAAMA,EAAQ,UAAU,EAAI,GAC3D;AAAA,EACX;AAAA,EAES,UAAgB;AACrB,IAAI,KAAK,eACT,KAAK,eAAA,GACL,MAAM,QAAA;AAAA,EACV;AAAA,EAEQ,iBAAuB;AAC3B,eAAW6C,KAAe,KAAK,oBAAqB,CAAAA,EAAA;AACpD,SAAK,sBAAsB,CAAA;AAAA,EAC/B;AAAA,EAEQ,UAAUjB,IAA2C,MAAMkB,IAAS,IAAY;AAGpF,UAAMC,IAAS,KAAK,QAAQ,IAAI,CAACJ,MAAWA,EAAO,KAAK,GAClDtB,IAAS,KAAK,QAAQ,IAAI,CAACsB,MAAWA,EAAO,eAAe,GAC5DK,IAAoC,KAAK,QAC1C,IAAI,CAACL,GAAQM,OAAiB,EAAC,aAAAA,GAAa,OAAON,EAAO,SAAA,EAAS,EAAG,EACtE,OAAO,CAACO,MAAUA,EAAM,SAAS,IAAI;AAE1C,QAAI3C,GACA4C,IAAwB;AAC5B,QAAI;AACA,MAAA5C,IAAQ,KAAK,QAAQwC,CAAM;AAAA,IAC/B,SAASV,GAAO;AACZ,MAAAc,IAAed,GACf9B,IAAQ;AAAA,IACZ;AAEA,UAAM6C,IAAkCD,KAAgB,OAClDH,IACA,CAAC,GAAGA,GAAc,EAAC,aAAa,MAAM,OAAOG,EAAA,CAAa,GAC1Dd,IAAQgB,EAAgB,KAAK,OAAOD,CAAU;AACpD,QAAIhB,IAAa,KAAK,kBAAkBf,CAAM;AAI9C,QAHAK,EAAiBU,CAAU,IACvBe,KAAgB,QAAQH,EAAa,SAAS,WAAgB9B,EAAW,QAEzE,CAAC4B,GAAQ;AACT,WAAK,QAAQvC,GACb,KAAK,aAAa6B,GAClB,KAAK,QAAQC;AACb;AAAA,IACJ;AAEA,SAAK,YAAY;AAAA,MACb,OAAA9B;AAAA,MACA,YAAA6B;AAAA,MACA,OAAAC;AAAA,MACA,OAAO;AAAA,MACP,aAAAT;AAAA,IAAA,CACH;AAAA,EACL;AACJ;AAEA,SAASyB,EACLC,GACAnB,GACoB;AACpB,SAAIA,EAAK,WAAW,IAAU,OAC1BmB,KAAY,QACTA,EAAS,WAAWnB,EAAK,UACzBmB,EAAS,MAAM,CAACJ,GAAOjB,MAAA;AH/XlC,QAAA/B,GAAAqD;AGgYY,WAAAL,EAAM,kBAAgBhD,IAAAiC,EAAKF,CAAK,MAAV,gBAAA/B,EAAa,gBAChC,OAAO,GAAGgD,EAAM,QAAOK,IAAApB,EAAKF,CAAK,MAAV,gBAAAsB,EAAa,KAAK;AAAA,GAAC,IAC1CD,IAEJ,OAAO,OAAOnB,EAAK,IAAI,CAACe,MAAU,OAAO,OAAOA,CAAK,CAAC,CAAC;AAClE;AAEA,SAASN,EAAcD,GAA8D;AACjF,UAAK,OAAOA,KAAW,YAAYA,MAAW,SAAS,OAAOA,KAAW,aAC9D,KAEJ,OAAO,QAAQ,IAAIA,GAAQ,KAAK,KAAM,cACtC,OAAO,QAAQ,IAAIA,GAAQ,eAAe,KAAM,cAChD,OAAO,QAAQ,IAAIA,GAAQ,UAAU,KAAM,cAC3C,OAAO,QAAQ,IAAIA,GAAQ,WAAW,KAAM;AACvD;AAEA,SAASjB,EAAiBU,GAAmC;AACzD,EAAAhB,EAAmB,CAACgB,CAAU,CAAC;AACnC;AC7YO,MAAMoB,UAA0ChC,EAA4B;AAAA,EAC/E,YAAYC,GAAsBzB,IAA0C,IAAI;AAC5E,UAAMyB,GAAczB,CAAO;AAAA,EAC/B;AAAA,EAEA,aACIO,GACA6B,IAA8BlB,EAAW,OACzCmB,IAAuB,MACvBoB,IAA+C,MACxC;AACP,UAAM7B,IAAc6B,aAAwB1D,IAAc0D,IAAe,MACnEnB,IAAQV,IAAc,eAAgB6B,KAAgB;AAC5D,WAAO,KAAK,YAAY,EAAC,OAAAlD,GAAO,YAAA6B,GAAY,OAAAC,GAAO,OAAAC,GAAO,aAAAV,GAAY;AAAA,EAC1E;AAAA,EAEA,IAAIrB,GAAekD,IAA+C,MAAe;AAC7E,WAAO,KAAK,aAAalD,GAAOW,EAAW,OAAO,MAAMuC,CAAY;AAAA,EACxE;AACJ;ACYO,MAAMC,UAAqC,MAAM;AAAA,EACpD,cAAc;AACV,UAAM,iCAAiC,GACvC,KAAK,OAAO;AAAA,EAChB;AACJ;AAGO,MAAMC,WACDnC,EAAyC;AAAA,EAajD,YAAYxB,GAA2D;AACnE,IAAA4D,EAAc5D,CAAO;AACrB,UAAM;AAAA,MACF,SAAA6D;AAAA,MACA,aAAAC,IAAc;AAAA,MACd,UAAAC,IAAW,CAAC1B,MAAmBA;AAAA,MAC/B,OAAAlC;AAAA,MACA,SAAA6D,IAAU;AAAA,MACV,OAAAC;AAAA,IAAA,IACAjE;AAEJ,QADAkE,EAAkBJ,CAAW,GACzB,OAAOC,KAAa;AACpB,YAAM,IAAI,UAAU,0CAA0C;AAElE,UAAM,QAAW;AAAA,MACb,YAAY7C,EAAW;AAAA,MACvB,OAAO;AAAA,MACP,OAAAf;AAAA,MACA,SAAA6D;AAAA,MACA,GAAIC,MAAU,SAAY,CAAA,IAAK,EAAC,OAAAA,EAAA;AAAA,IAAK,CACxC;AAhCI,IAAAhE,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACQ,IAAAA,EAAA;AACA,IAAAA,EAAA;AACT,IAAAA,EAAA,mBAAY;AACZ,IAAAA,EAAA,yBAA8C;AAC9C,IAAAA,EAAA;AACA,IAAAA,EAAA,4BAAqB;AAE7B;AAAA,IAAAA,EAAA,wBAAsD;AAuBlD,SAAK,UAAU4D,GACf,KAAK,cAAcC,GACnB,KAAK,WAAWC,GAChB,KAAK,iBAAiB,IAAIP,EAAwB,IAAO;AAAA,MACrD,OAAOrD,KAAS;AAAA,MAChB,SAAS,GAAG6D,CAAO;AAAA,MACnB,GAAIC,MAAU,SAAY,CAAA,IAAK,EAAC,OAAAA,EAAA;AAAA,IAAK,CACxC,GACD,KAAK,YAAY,KAAK;AAAA,EAC1B;AAAA,EAEA,IACIE,GACAV,IAA+C,eACnB;AL9FpC,QAAAvD;AK+FQ,QAAI,KAAK,WAAY,QAAO,QAAQ,QAAQ,MAAS;AACrD,QAAI,KAAK,kBAAkB,MAAM;AAC7B,UAAI,KAAK,gBAAgB,SAAU,QAAO,KAAK;AAC/C,UAAI,KAAK,gBAAgB;AACrB,eAAO,QAAQ,OAAO,IAAIwD,GAA8B;AAE5D,OAAAxD,IAAA,KAAK,oBAAL,QAAAA,EAAsB;AAAA,IAC1B;AAEA,UAAMkE,IAAY,EAAE,KAAK,WACnBC,IAAaC,EAAA;AACnB,SAAK,kBAAkBD;AACvB,UAAMzC,IAAc6B,aAAwB1D,IAAc0D,IAAe,MACnEnB,IAAQV,IAAc,6BAA6B6B;AACzD,SAAK,YAAY;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,YAAYvC,EAAW;AAAA,MACvB,OAAO;AAAA,MACP,OAAAoB;AAAA,MACA,aAAAV;AAAA,IAAA,CACH;AACD,UAAM2C,IAAe,KAAK,YAAY,mBAAmB3C,GAAauC,CAAU;AAChF,SAAK,eAAe,IAAI,IAAMI,KAAgBjC,CAAK;AAEnD,UAAMkC,IAAU,QAAQ,QAAA,EACnB,KAAK,MAAM,KAAK,QAAQL,GAAY;AAAA,MACjC,QAAQE,EAAW;AAAA,MACnB,OAAOE;AAAA,IAAA,CACV,CAAC,EACD,KAAK,CAACE,MAAW;AACd,UAAK,KAAK,iBAAiBL,GAAWC,CAAU;AAChD,oBAAK,sBAAsBI,GAC3B,KAAK,qBAAqB,IAC1B,KAAK,YAAY;AAAA,UACb,OAAOA;AAAA,UACP,YAAYvD,EAAW;AAAA,UACvB,OAAO;AAAA,UACP,OAAO;AAAA,UACP,aAAaqD;AAAA,QAAA,CAChB,GACME;AAAA,IACX,CAAC,EACA,MAAM,CAACpC,MAAmB;AACvB,MAAK,KAAK,iBAAiB+B,GAAWC,CAAU,KAChD,KAAK,YAAY;AAAA,QACb,OAAO,KAAK;AAAA,QACZ,YAAYnD,EAAW;AAAA,QACvB,OAAO,KAAK,gBAAgBmB,CAAK;AAAA,QACjC,OAAO;AAAA,QACP,aAAakC;AAAA,MAAA,CAChB;AAAA,IAEL,CAAC,EACA,QAAQ,MAAM;AACX,MAAK,KAAK,iBAAiBH,GAAWC,CAAU,MAChD,KAAK,kBAAkB,MACvB,KAAK,iBAAiB,MACtB,KAAK,eAAe,IAAI,IAAOE,KAAgB,iBAAiB;AAAA,IACpE,CAAC;AAEL,gBAAK,iBAAiBC,GACfA;AAAA,EACX;AAAA,EAEA,MAAMf,IAA+C,mBAA4B;AAC7E,QAAI,KAAK,cAAc,KAAK,mBAAmB,KAAM,QAAO;AAC5D,UAAM7B,IAAc6B,aAAwB1D,IAAc0D,IAAe,MACnEnB,IAAQV,IAAc,2BAA2B6B;AACvD,gBAAK,aAAa,GAClB,KAAK,gBAAgB,MAAA,GACrB,KAAK,kBAAkB,MACvB,KAAK,iBAAiB,MACtB,KAAK,eAAe,IAAI,IAAO7B,KAAeU,CAAK,GACnD,KAAK,YAAY;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK,qBAAqBpB,EAAW,QAAQA,EAAW;AAAA,MACpE,OAAO;AAAA,MACP,OAAAoB;AAAA,MACA,aAAAV;AAAA,IAAA,CACH,GACM;AAAA,EACX;AAAA,EAEA,MAAM6B,IAA+C,iBAAuB;AACxE,QAAI,KAAK,WAAY;AACrB,SAAK,MAAMA,CAAY,GACvB,KAAK,sBAAsB,QAC3B,KAAK,qBAAqB;AAC1B,UAAM7B,IAAc6B,aAAwB1D,IAAc0D,IAAe;AACzE,SAAK,YAAY;AAAA,MACb,OAAO;AAAA,MACP,YAAYvC,EAAW;AAAA,MACvB,OAAO;AAAA,MACP,OAAOU,IAAc,yBAAyB6B;AAAA,MAC9C,aAAA7B;AAAA,IAAA,CACH;AAAA,EACL;AAAA,EAES,UAAgB;ALjM7B,QAAA1B;AKkMQ,IAAI,KAAK,eACT,KAAK,aAAa,IAClBA,IAAA,KAAK,oBAAL,QAAAA,EAAsB,SACtB,KAAK,kBAAkB,MACvB,KAAK,iBAAiB,MACtB,KAAK,eAAe,IAAI,IAAO,kBAAkB,GACjD,KAAK,eAAe,QAAA,GACpB,MAAM,QAAA;AAAA,EACV;AAAA,EAEQ,iBAAiBkE,GAAmBC,GAA0C;AAClF,WAAO,CAAC,KAAK,cACND,MAAc,KAAK,aACnBC,MAAe,KAAK,mBACpB,CAACA,EAAW,OAAO;AAAA,EAC9B;AAAA,EAEQ,gBAAgBhC,GAAwB;AAC5C,QAAI;AACA,aAAO,KAAK,SAASA,CAAK;AAAA,IAC9B,SAASqC,GAAuB;AAC5B,aAAOA;AAAA,IACX;AAAA,EACJ;AACJ;AAEA,SAASd,EACL5D,GACI;AACJ,MAAIA,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,UAAM,IAAI,UAAU,wCAAwC;AAEhE,MAAI,OAAOA,EAAQ,WAAY;AAC3B,UAAM,IAAI,UAAU,yCAAyC;AAErE;AAEA,SAASkE,EAAkB3D,GAAyD;AAChF,MAAIA,MAAU,YAAYA,MAAU,aAAaA,MAAU;AACvD,UAAM,IAAI,UAAU,4CAA4CA,CAAK,EAAE;AAE/E;AAEA,SAAS+D,IAA6C;AAClD,QAAM9D,IAAc,QAAQ,IAAI,YAAY,iBAAiB;AAC7D,MAAI,OAAOA,KAAgB;AACvB,UAAM,IAAI,MAAM,uDAAuD;AAE3E,SAAO,IAAKA,EAAA;AAChB;ACnMO,MAAMmE,UAGHnD,EACqD;AAAA,EAgB3D,YAAYxB,GAAgD;AACxD,QAAIA,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,YAAM,IAAI,UAAU,qCAAqC;AAE7D,UAAM;AAAA,MACF,SAAA4E;AAAA,MACA,MAAAC,IAAO,CAAA;AAAA,MACP,WAAAC,IAAY;AAAA,MACZ,mBAAAC,IAAoB;AAAA,MACpB,SAAAC;AAAA,MACA,OAAA7E;AAAA,MACA,SAAA6D,IAAU;AAAA,MACV,OAAAC;AAAA,IAAA,IACAjE;AACJ,QAAI4E,KAAW,QAAQ,OAAOA,EAAQ,SAAU;AAC5C,YAAM,IAAI,UAAU,0CAA0C;AAElE,IAAAK,EAAgBJ,CAAI,GAChBG,KAAW,QAAME,EAAqBF,CAAO;AAEjD,UAAM,QAAW;AAAA,MACb,YAAY9D,EAAW;AAAA,MACvB,OAAO;AAAA,MACP,OAAAf;AAAA,MACA,SAAA6D;AAAA,MACA,GAAIC,MAAU,SAAY,CAAA,IAAK,EAAC,OAAAA,EAAA;AAAA,IAAK,CACxC;AAzCI,IAAAhE,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACD,IAAAA,EAAA;AACA,IAAAA,EAAA,4BAAqB;AACrB,IAAAA,EAAA;AACA,IAAAA,EAAA,8BAA0C,CAAA;AACjC,IAAAA,EAAA;AACA,IAAAA,EAAA;AACT,IAAAA,EAAA,uBAAyB;AACzB,IAAAA,EAAA,mBAAY;AACZ,IAAAA,EAAA,yBAA8C;AAEtD;AAAA,IAAAA,EAAA,wBAAsD;AA6BlD,SAAK,UAAU2E,GACf,KAAK,OAAO,EAAC,GAAGC,EAAA,GAChB,KAAK,oBAAoBE,GACzB,KAAK,UAAUC,GACf,KAAK,oBAAmBA,KAAA,gBAAAA,EAAS,cAAaG,GAC9C,KAAK,sBAAsB,QAC3B,KAAK,wBAAwB,OAAO,OAAO,KAAK,IAAI,EAAE;AAAA,MAAI,CAACC,MACvDA,EAAS,UAAU,CAAC,EAAC,OAAArE,QAAW;AAC5B,QAAK,KAAK,QAAQA,CAAK;AAAA,MAC3B,GAAG,EAAC,aAAa,GAAA,CAAM;AAAA,IAAA,GAGvBiE,KAAW,QAAM,KAAK,kBAAkBA,CAAO,GAE/CF,MAAW,KAAK,iBAAiB,KAAK,QAAQ,eAAe,IACjE,KAAK,iBAAA;AAAA,EACT;AAAA,EAEA,IAAI,iBAAkD;AAClD,WAAO,OAAO;AAAA,MACV,OAAO,QAAQ,KAAK,IAAI,EAAE,IAAI,CAAC,CAACrE,GAAM2E,CAAQ,MAAM,CAAC3E,GAAM2E,EAAS,IAAA,CAAK,CAAC;AAAA,IAAA;AAAA,EAElF;AAAA,EAEA,QAAQ3B,IAA+C,WAAyC;ANvHpG,QAAAvD;AMwHQ,QAAI,KAAK,WAAY,QAAO,QAAQ,QAAQ,MAAS;AAErD,UAAMkE,IAAY,EAAE,KAAK;AACzB,KAAAlE,IAAA,KAAK,oBAAL,QAAAA,EAAsB;AACtB,UAAMmE,IAAaC,EAAA;AACnB,SAAK,kBAAkBD;AACvB,UAAMzC,IAAc6B,aAAwB1D,IAAc0D,IAAe,MACnEnB,IAAQV,IAAc,4BAA4B6B,GAClD4B,IAAe,KAAK,oBACpB,KAAK,sBACL;AACN,SAAK,YAAY;AAAA,MACb,OAAOA;AAAA,MACP,YAAYnE,EAAW;AAAA,MACvB,OAAO;AAAA,MACP,OAAAoB;AAAA,MACA,aAAAV;AAAA,IAAA,CACH;AACD,UAAM0D,IAAa,KAAK,YAAY,eAAe1D,GAAa,KAAK,cAAc,GAE7E4C,IAAU,QAAQ,QAAA,EACnB,KAAK,MAAM,KAAK,QAAQ,MAAM,KAAK,gBAAgB;AAAA,MAChD,QAAQH,EAAW;AAAA,MACnB,OAAOiB;AAAA,IAAA,CACV,CAAC,EACD,KAAK,CAACb,MAAW;AACd,UAAK,KAAK,iBAAiBL,GAAWC,CAAU;AAChD,oBAAK,sBAAsBI,GAC3B,KAAK,qBAAqB,IAC1B,KAAK,YAAY;AAAA,UACb,OAAOA;AAAA,UACP,YAAYvD,EAAW;AAAA,UACvB,OAAO;AAAA,UACP,OAAO;AAAA,UACP,aAAaoE;AAAA,QAAA,CAChB,GACMb;AAAA,IACX,CAAC,EACA,MAAM,CAACpC,MAAmB;AACvB,MAAI,CAAC,KAAK,iBAAiB+B,GAAWC,CAAU,KAAKkB,EAAalD,CAAK,KAGvE,KAAK,YAAY;AAAA,QACb,OAAO,KAAK,oBAAoB,KAAK,sBAAsB;AAAA,QAC3D,YAAYnB,EAAW;AAAA,QACvB,OAAAmB;AAAA,QACA,OAAO;AAAA,QACP,aAAaiD;AAAA,MAAA,CAChB;AAAA,IAEL,CAAC,EACA,QAAQ,MAAM;AACX,MAAI,KAAK,iBAAiBlB,GAAWC,CAAU,MAC3C,KAAK,kBAAkB,MACvB,KAAK,iBAAiB;AAAA,IAE9B,CAAC;AAEL,gBAAK,iBAAiBG,GACfA;AAAA,EACX;AAAA,EAEA,MAAMf,IAA+C,SAAuC;AACxF,WAAO,KAAK,QAAQA,CAAY;AAAA,EACpC;AAAA,EAEA,MAAMA,IAA+C,iBAAuB;AACxE,QAAI,KAAK,cAAc,KAAK,mBAAmB,KAAM;AACrD,SAAK,aAAa,GAClB,KAAK,gBAAgB,MAAA,GACrB,KAAK,kBAAkB,MACvB,KAAK,iBAAiB;AACtB,UAAM7B,IAAc6B,aAAwB1D,IAAc0D,IAAe;AACzE,SAAK,YAAY;AAAA,MACb,OAAO,KAAK,qBAAqB,KAAK,sBAAsB;AAAA,MAC5D,YAAY,KAAK,qBAAqBvC,EAAW,QAAQA,EAAW;AAAA,MACpE,OAAO;AAAA,MACP,OAAOU,KAAe,OAAO6B,IAAe;AAAA,MAC5C,aAAA7B;AAAA,IAAA,CACH;AAAA,EACL;AAAA,EAES,UAAgB;AN1M7B,QAAA1B;AM2MQ,QAAI,MAAK,YACT;AAAA,WAAK,aAAa,IAClBA,IAAA,KAAK,oBAAL,QAAAA,EAAsB,SACtB,KAAK,kBAAkB,MACvB,KAAK,iBAAiB,MACtB,KAAK,oBAAA;AACL,iBAAW2C,KAAe,KAAK,sBAAuB,CAAAA,EAAA;AACtD,WAAK,wBAAwB,CAAA;AAC7B,iBAAWA,KAAe,KAAK,qBAAsB,CAAAA,EAAA;AACrD,WAAK,uBAAuB,CAAA,GAC5B,MAAM,QAAA;AAAA;AAAA,EACV;AAAA,EAEQ,kBAAkBmC,GAAwC;AAC9D,eAAWrC,KAAU,CAACqC,EAAQ,YAAYA,EAAQ,OAAO;AACrD,MAAKQ,EAAkB7C,CAAM,KAC7B,KAAK,qBAAqB,KAAKA,EAAO,UAAU,MAAM;AAClD,QAAA8C,EAAsBC,EAAiBV,EAAQ,UAAU,CAAC,GAC1DW,EAAqBD,EAAiBV,EAAQ,SAAS,EAAI,CAAC,GAC5D,KAAK,oBAAA,GACL,KAAK,iBAAA;AAAA,MACT,GAAG,EAAC,aAAa,GAAA,CAAM,CAAC;AAAA,EAEhC;AAAA,EAEQ,mBAAyB;AAE7B,QADI,KAAK,cAAc,KAAK,WAAW,QAAQ,KAAK,iBAAiB,QACjE,CAACU,EAAiB,KAAK,QAAQ,SAAS,EAAI,EAAG;AACnD,UAAME,IAAaF,EAAiB,KAAK,QAAQ,UAAU;AAC3D,IAAAD,EAAsBG,CAAU,GAChC,KAAK,gBAAgB,KAAK,iBAAiB,SAAS,MAAM;AACtD,WAAK,gBAAgB,MACrB,KAAK,iBAAA,GACD,KAAK,kBAAkB,QAAW,KAAK,QAAQ,MAAM;AAAA,IAC7D,GAAGA,CAAU;AAAA,EACjB;AAAA,EAEQ,sBAA4B;AAChC,IAAI,KAAK,iBAAiB,SAC1B,KAAK,iBAAiB,OAAO,KAAK,aAAa,GAC/C,KAAK,gBAAgB;AAAA,EACzB;AAAA,EAEQ,iBAAiBxB,GAAmBC,GAA0C;AAClF,WAAO,CAAC,KAAK,cACND,MAAc,KAAK,aACnBC,MAAe,KAAK,mBACpB,CAACA,EAAW,OAAO;AAAA,EAC9B;AACJ;AAEA,MAAMc,IAA4C;AAAA,EAC9C,SAASU,GAAUC,GAAS;AACxB,UAAMC,IAAW,QAAQ,IAAI,YAAY,YAAY;AACrD,QAAI,OAAOA,KAAa;AACpB,YAAM,IAAI,MAAM,kEAAkE;AAEtF,WAAO,QAAQ,MAAMA,GAAU,YAAY,CAACF,GAAUC,CAAO,CAAC;AAAA,EAClE;AAAA,EACA,OAAOE,GAAQ;AACX,UAAMC,IAAS,QAAQ,IAAI,YAAY,cAAc;AACrD,IAAI,OAAOA,KAAW,cAAY,QAAQ,MAAMA,GAAQ,YAAY,CAACD,CAAM,CAAC;AAAA,EAChF;AACJ;AAEA,SAASR,EAAkBjF,GAA0D;AACjF,SAAOA,KAAS,SACR,OAAOA,KAAU,YAAY,OAAOA,KAAU,eAC/C,OAAO,QAAQ,IAAIA,GAAO,KAAK,KAAM,cACrC,OAAO,QAAQ,IAAIA,GAAO,WAAW,KAAM;AACtD;AAEA,SAAS2F,EAAoB3F,GAAgBE,GAAoB;AAC7D,MAAI,OAAOF,KAAU,YAAY,OAAOA,KAAU,aAAa,CAACiF,EAAkBjF,CAAK;AACnF,UAAM,IAAI,UAAU,qBAAqBE,CAAI,6BAA6B;AAElF;AAEA,SAASyE,EAAqBF,GAAwC;AAClE,MAAIA,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,UAAM,IAAI,UAAU,6CAA6C;AAMrE,MAJAkB,EAAoBlB,EAAQ,YAAY,YAAY,GAChDA,EAAQ,YAAY,UAAWkB,EAAoBlB,EAAQ,SAAS,SAAS,GACjFS,EAAsBC,EAAiBV,EAAQ,UAAU,CAAC,GAC1DW,EAAqBD,EAAiBV,EAAQ,SAAS,EAAI,CAAC,GACxDA,EAAQ,aAAa,SACjB,OAAOA,EAAQ,UAAU,YAAa,cACnC,OAAOA,EAAQ,UAAU,UAAW;AAC3C,UAAM,IAAI,UAAU,oEAAoE;AAEhG;AAEA,SAASU,EACLnF,GACA4F,GACM;AACN,SAAI5F,MAAU,SAAkB4F,IAC5BX,EAAkBjF,CAAK,IAAUA,EAAM,IAAA,IACpCA;AACX;AAEA,SAASkF,EAAsBlF,GAAqB;AAChD,MAAI,CAAC,OAAO,SAASA,CAAK,KAAKA,KAAS;AACpC,UAAM,IAAI,WAAW,+DAA+D;AAE5F;AAEA,SAASoF,EAAqBpF,GAAsB;AAChD,MAAI,OAAOA,KAAU;AACjB,UAAM,IAAI,UAAU,6CAA6C;AAEzE;AAEA,SAAS0E,EAAgBJ,GAAsD;AAC3E,MAAIA,KAAQ,QAAQ,OAAOA,KAAS,YAAY,MAAM,QAAQA,CAAI;AAC9D,UAAM,IAAI,UAAU,mDAAmD;AAE3E,aAAW,CAACpE,GAAM2E,CAAQ,KAAK,OAAO,QAAQP,CAAI;AAC9C,QAAIO,KAAY,QACT,OAAO,QAAQ,IAAIA,GAAU,KAAK,KAAM,cACxC,OAAO,QAAQ,IAAIA,GAAU,WAAW,KAAM;AACjD,YAAM,IAAI,UAAU,sBAAsB3E,CAAI,qBAAqB;AAG/E;AAEA,SAAS6D,IAA6C;AAClD,QAAM9D,IAAc,QAAQ,IAAI,YAAY,iBAAiB;AAC7D,MAAI,OAAOA,KAAgB;AACvB,UAAM,IAAI,MAAM,oDAAoD;AAExE,SAAO,IAAKA,EAAA;AAChB;AAEA,SAAS+E,EAAalD,GAAyB;AAC3C,SAAOA,aAAiB,SAASA,EAAM,SAAS;AACpD;AChVO,MAAM+D,WAA2C5C,EAAwB;AAAA,EAI5E,YACI/C,GACAkC,GACA3C,IAA0C,CAAA,GAC5C;AACE,QAAI,OAAOS,KAAS,YAAYA,EAAK,WAAW;AAC5C,YAAM,IAAI,UAAU,0CAA0C;AAElE,QAAIkC,KAAU,QACP,OAAOA,EAAO,OAAQ,cACtB,OAAOA,EAAO,aAAc;AAC/B,YAAM,IAAI,UAAU,oCAAoC;AAG5D,UAAMA,EAAO,OAAO;AAAA,MAChB,GAAG3C;AAAA,MACH,YAAY2C,EAAO,cAAA;AAAA,MACnB,OAAOA,EAAO,SAAA;AAAA,MACd,SAAS3C,EAAQ,WAAW,mBAAmBS,CAAI;AAAA,IAAA,CACtD;AAtBI,IAAAR,EAAA;AACD,IAAAA,EAAA;AAsBJ,SAAK,OAAOQ,GACZ,KAAK,oBAAoBkC,EAAO,UAAU,CAACT,MAAiB;AACxD,WAAK;AAAA,QACDA,EAAa;AAAA,QACbA,EAAa;AAAA,QACbA,EAAa;AAAA,QACbA,EAAa;AAAA,MAAA;AAAA,IAErB,GAAG,EAAC,aAAa,IAAM;AAAA,EAC3B;AAAA,EAES,UAAgB;APvC7B,QAAAhC;AOwCQ,IAAI,KAAK,gBACTA,IAAA,KAAK,sBAAL,QAAAA,EAAA,YACA,KAAK,oBAAoB,MACzB,MAAM,QAAA;AAAA,EACV;AACJ;ACpBO,MAAMmG,GAGsC;AAAA,EAC/C,MAAMC,GAAmBC,IAAgC,IAAoC;AACzF,UAAM,IAAI,MAAM,6BAA6B;AAAA,EACjD;AACJ;ACqBA,MAAMC,WAAkB,MAAM;AAAA,EAG1B,YAAYC,GAA4B;AACpC,UAAM,QAAQA,KAAU,SAAS,EAAE;AAH9B,IAAAxG,EAAA;AAIL,SAAK,OAAO,aACZ,KAAK,SAASwG;AAAA,EAClB;AACJ;AAGO,MAAMC,WAGHL,GAAkC;AAAA,EAQxC,YAAYrG,GAAgE;AACxE,UAAA;AARK,IAAAC,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AAIL,UAAM0G,IAAa,OAAO3G,KAAY,WAAW,EAAC,KAAKA,MAAWA;AAClE,QAAI2G,KAAc,QAAQ,OAAOA,KAAe;AAC5C,YAAM,IAAI,UAAU,mDAAmD;AAE3E,QAAI,OAAOA,EAAW,OAAQ,YAAYA,EAAW,IAAI,WAAW;AAChE,YAAM,IAAI,UAAU,iDAAiD;AAUzE,QAPA,KAAK,MAAMA,EAAW,KACtB,KAAK,UAAUA,EAAW,WAAWC,GAAA,GACrC,KAAK,sBAAsBD,EAAW,SAASE,GAAA,GAC/C,KAAK,YAAYF,EAAW,aAAaG,IACzC,KAAK,cAAcH,EAAW,aAC9B,KAAK,QAAQA,EAAW,SAAS,IAE7B,OAAO,KAAK,uBAAwB;AACpC,YAAM,IAAI,UAAU,4DAA4D;AAEpF,QAAI,OAAO,KAAK,aAAc;AAC1B,YAAM,IAAI,UAAU,+CAA+C;AAEvE,QAAI,KAAK,gBAAgB,UAAa,OAAO,KAAK,eAAgB;AAC9D,YAAM,IAAI,UAAU,iDAAiD;AAAA,EAE7E;AAAA,EAEA,MAAe,MAAM9B,GAAkB7E,IAA+B,IAAsB;AACxF,QAAI6E,KAAQ,QAAQ,OAAOA,KAAS,YAAY,MAAM,QAAQA,CAAI;AAC9D,YAAM,IAAI,UAAU,wCAAwC;AAGhE,UAAMkC,IAAMC,GAAW,KAAK,KAAK,KAAK,OAAO,GACvCC,IAAa,KAAK,UAAUF,GAAKlC,CAAI,KAAKkC,GAC1CG,IAAMC,EAAA;AACZ,QAAI,EAAEF,aAAsBC;AACxB,YAAM,IAAI,UAAU,6CAA6C;AAGrE,UAAME,IAASpH,EAAQ,SAAS;AAChC,QAAI,KAAK,SAASoH,KAAUpG,EAAS,gBAAgB;AACjD,YAAMD,IAAQ,IAAIhB,EAAY;AAAA,QAC1B,OAAO;AAAA,QACP,SAAS;AAAA,QACT,OAAOkH,EAAW,SAAA;AAAA,QAClB,OAAO;AAAA,QACP,QAAAG;AAAA,MAAA,CACH;AACD,MAAKA,KAAQpG,EAAS,KAAKD,CAAK;AAAA,IACpC;AAEA,UAAMsG,IAAerH,EAAQ,WAAW,SAAY,CAAA,IAAK,EAAC,QAAQA,EAAQ,OAAA,GACpEsH,IAAW,MAAM,KAAK,oBAAoBL,EAAW,SAAA,GAAYI,CAAY;AACnF,QAAI,EAACC,KAAA,QAAAA,EAAU,WAAU,IAAId,GAAUc,KAAA,gBAAAA,EAAU,MAAM;AACvD,UAAMC,IAAgB,MAAMD,EAAS,KAAA;AACrC,WAAO,KAAK,eAAe,OAAOC,IAAkB,KAAK,YAAYA,CAAI;AAAA,EAC7E;AACJ;AAEA,SAAST,GACLC,GACAlC,GACO;AACP,aAAW,CAAC2C,GAAKjH,CAAK,KAAK,OAAO,QAAQsE,CAAI;AAC1C,IAAA4C,EAAYV,EAAI,cAAcS,GAAKjH,CAAK;AAE5C,SAAOwG;AACX;AAEA,SAASU,EAAYC,GAA0BF,GAAajH,GAAsB;AAC9E,MAAIA,MAAU,QACd;AAAA,QAAIA,MAAU,MAAM;AAChB,MAAAmH,EAAO,OAAOF,GAAK,EAAE;AACrB;AAAA,IACJ;AACA,QAAI,MAAM,QAAQjH,CAAK,GAAG;AACtB,iBAAWyB,KAAQzB,EAAO,CAAAkH,EAAYC,GAAQF,GAAKxF,CAAI;AACvD;AAAA,IACJ;AACA,QAAI,OAAOzB,KAAU,UAAU;AAC3B,MAAAmH,EAAO,OAAOF,GAAK,KAAK,UAAUjH,CAAK,CAAC;AACxC;AAAA,IACJ;AACA,IAAAmH,EAAO,OAAOF,GAAK,OAAOjH,CAAK,CAAC;AAAA;AACpC;AAEA,SAASyG,GAAWD,GAAaY,GAAsC;AACnE,QAAMT,IAAMC,EAAA;AACZ,MAAI;AACA,WAAO,IAAID,EAAIH,CAAG;AAAA,EACtB,SAAS1E,GAAO;AACZ,QAAIsF,KAAW;AACX,YAAM,IAAI,UAAU,uCAAuCZ,CAAG,IAAI,EAAC,OAAO1E,GAAM;AAEpF,WAAO,IAAI6E,EAAIH,GAAKY,CAAO;AAAA,EAC/B;AACJ;AAEA,SAASR,IAAoC;AACzC,QAAM3G,IAAc,QAAQ,IAAI,YAAY,KAAK;AACjD,MAAI,OAAOA,KAAgB;AACvB,UAAM,IAAI,MAAM,+CAA+C;AAEnE,SAAOA;AACX;AAEA,SAASoG,KAAsC;AAC3C,QAAMgB,IAAW,QAAQ,IAAI,YAAY,UAAU;AACnD,MAAIA,KAAY,QAAS,OAAOA,KAAa,YAAY,OAAOA,KAAa;AACzE;AAEJ,QAAMC,IAAO,QAAQ,IAAID,GAAU,MAAM;AACzC,SAAO,OAAOC,KAAS,WAAWA,IAAO;AAC7C;AAEA,SAAShB,KAA8C;AAEnD,SADuB,QAAQ,IAAI,YAAY,OAAO;AAE1D;AC9JO,MAAMiB,GAGX;AAAA,EAIE,YAAY9H,GAAoD;AAHvD,IAAAC,EAAA;AACA,IAAAA,EAAA;AAGL,QAAID,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,YAAM,IAAI,UAAU,yCAAyC;AAEjE,QAAIA,EAAQ,WAAW,QAAQ,OAAOA,EAAQ,QAAQ,SAAU;AAC5D,YAAM,IAAI,UAAU,8CAA8C;AAEtE,UAAM+H,IAAQ/H,EAAQ,SAAS,CAAA;AAC/B,IAAAgI,EAA2BD,CAAK,GAChC,KAAK,UAAU/H,EAAQ,SACvB,KAAK,eAAe,OAAO,OAAO,EAAC,GAAG+H,GAAM,GAC5C,OAAO,OAAO,IAAI;AAAA,EACtB;AAAA,EAEA,KACIlD,GACA7E,IAAgC,IACH;AAC7B,WAAAiI,EAAwBpD,CAAI,GAC5BmD,EAA2BhI,CAAO,GAC3B,IAAI2E,EAA8B;AAAA,MACrC,SAAS,KAAK;AAAA,MACd,MAAAE;AAAA,MACA,GAAG,KAAK;AAAA,MACR,GAAG7E;AAAA,IAAA,CACN;AAAA,EACL;AACJ;AAEO,SAASkI,GAGdlI,GAAwF;AACtF,SAAO,IAAI8H,GAAc9H,CAAO;AACpC;AAQO,MAAMmI,GAGX;AAAA,EAIE,YAAYnI,GAAmD;AAHtD,IAAAC,EAAA;AACA,IAAAA,EAAA;AAGL,QAAID,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,YAAM,IAAI,UAAU,wCAAwC;AAEhE,UAAM,EAAC,OAAA+H,IAAQ,CAAA,GAAI,GAAGK,MAAkBpI;AACxC,IAAAgI,EAA2BD,GAAO,4BAA4B,GAC9D,KAAK,UAAU,IAAIrB,GAAiB0B,CAAc,GAClD,KAAK,eAAe,OAAO,OAAO,EAAC,GAAGL,GAAM,GAC5C,OAAO,OAAO,IAAI;AAAA,EACtB;AAAA,EAEA,KACIlD,GACA7E,IAAgC,IACH;AAC7B,WAAAiI,EAAwBpD,CAAI,GAC5BmD,EAA2BhI,CAAO,GAC3B,IAAI2E,EAA8B;AAAA,MACrC,SAAS,KAAK;AAAA,MACd,MAAAE;AAAA,MACA,GAAG,KAAK;AAAA,MACR,GAAG7E;AAAA,IAAA,CACN;AAAA,EACL;AACJ;AAEO,SAASqI,GAGdrI,GAAsF;AACpF,SAAO,IAAImI,GAAanI,CAAO;AACnC;AAwBO,MAAMsI,GAIX;AAAA,EAIE,YAAYtI,GAA+D;AAHlE,IAAAC,EAAA;AACA,IAAAA,EAAA;AAGL,QAAID,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,YAAM,IAAI,UAAU,2CAA2C;AAEnE,QAAI,OAAOA,EAAQ,SAAU;AACzB,YAAM,IAAI,UAAU,0CAA0C;AAElE,SAAK,QAAQA,EAAQ,OACrB,KAAK,UAAUA,EAAQ,WAAW,oBAClC,OAAO,OAAO,IAAI;AAAA,EACtB;AAAA,EAEA,KACIA,GAC6D;AAC7D,WAAO,IAAIuI,GAAkB;AAAA,MACzB,GAAGvI;AAAA,MACH,OAAO,KAAK;AAAA,MACZ,SAASA,EAAQ,WAAW,KAAK;AAAA,IAAA,CACpC;AAAA,EACL;AACJ;AAEO,SAASwI,GAIdxI,GAC4C;AAC1C,SAAO,IAAIsI,GAAgBtI,CAAO;AACtC;AAYO,MAAMuI,WAKH/G,EAC8B;AAAA,EAOpC,YAAYxB,GAA+E;AACvF,QAAIA,KAAW,QAAQ,OAAOA,KAAY,YAAY,MAAM,QAAQA,CAAO;AACvE,YAAM,IAAI,UAAU,6CAA6C;AAGrE,QADAiI,EAAwBjI,EAAQ,IAAI,GAChC,CAACwF,EAAkBxF,EAAQ,MAAM;AACjC,YAAM,IAAI,UAAU,6CAA6C;AAErE,QAAI,OAAOA,EAAQ,SAAU;AACzB,YAAM,IAAI,UAAU,4CAA4C;AAEpE,UAAM,QAAsB;AAAA,MACxB,YAAYkB,EAAW;AAAA,MACvB,OAAO;AAAA,MACP,OAAOlB,EAAQ;AAAA,MACf,GAAIA,EAAQ,YAAY,SAAY,CAAA,IAAK,EAAC,SAASA,EAAQ,QAAA;AAAA,MAC3D,GAAIA,EAAQ,UAAU,SAAY,CAAA,IAAK,EAAC,OAAOA,EAAQ,MAAA;AAAA,IAAK,CAC/D;AAvBI,IAAAC,EAAA;AACA,IAAAA,EAAA;AACQ,IAAAA,EAAA;AACT,IAAAA,EAAA,uBAAmC,CAAA;AACnC,IAAAA,EAAA;AAoBJ,SAAK,SAASD,EAAQ,QACtB,KAAK,OAAO,EAAC,GAAGA,EAAQ,KAAA,GACxB,KAAK,QAAQA,EAAQ,OACrB,KAAK,sBAAsB;AAC3B,UAAMuC,IAAoD;AAAA,MACtD,KAAK;AAAA,MACL,GAAG,OAAO,OAAO,KAAK,IAAI;AAAA,IAAA;AAE9B,SAAK,gBAAgBA,EAAQ,IAAI,CAACI,MAAWA,EAAO,UAAU,CAAC,EAAC,OAAA5B,QAAW;AACvE,WAAK,UAAUA,CAAK;AAAA,IACxB,GAAG,EAAC,aAAa,GAAA,CAAM,CAAC,GACxB,KAAK,UAAU,MAAM,EAAK;AAAA,EAC9B;AAAA,EAES,UAAgB;AACrB,QAAI,MAAK,YACT;AAAA,iBAAW8B,KAAe,KAAK,cAAe,CAAAA,EAAA;AAC9C,WAAK,gBAAgB,CAAA,GACrB,MAAM,QAAA;AAAA;AAAA,EACV;AAAA,EAEQ,UAAUjB,GACdkB,IAAS,IAAY;AV1P7B,QAAA5C;AU2PQ,UAAMqC,IAA4D;AAAA,MAC9D,KAAK;AAAA,MACL,GAAG,OAAO,OAAO,KAAK,IAAI;AAAA,IAAA,GAExBkG,MAAcvI,IAAAqC,EAAQ,KAAK,CAACI,MAAWA,EAAO,cAAc,IAAI,MAAlD,gBAAAzC,EAAqD,eAAc;AACvF,QAAIkC,IAA8BhB;AAAA,MAC9BmB,EAAQ,IAAI,CAACI,MAAWA,EAAO,eAAe;AAAA,IAAA;AAElD,UAAM+F,IAAc,KAAK,OAAO,IAAA;AAChC,QAAInI,IAAQ,KAAK,qBACb8B,IAAiBoG;AAErB,QAAI;AACA,YAAME,IAAiB,OAAO;AAAA,QAC1B,OAAO,QAAQ,KAAK,IAAI,EAAE,IAAI,CAAC,CAAClI,GAAM2E,CAAQ,MAAM,CAAC3E,GAAM2E,EAAS,IAAA,CAAK,CAAC;AAAA,MAAA;AAE9E,MAAA7E,IAAQ,KAAK,MAAMmI,GAAaC,CAAc,GAC9C,KAAK,sBAAsBpI;AAAA,IAC/B,SAASqI,GAAQ;AACb,MAAAvG,IAAQuG,GACRxG,IAAalB,EAAW;AAAA,IAC5B;AAMA,QALIuH,KAAe,SACfpG,IAAQoG,GACRrG,IAAalB,EAAW,QAGxB,CAAC4B,GAAQ;AACT,WAAK,QAAQvC,GACb,KAAK,aAAa6B,GAClB,KAAK,QAAQC;AACb;AAAA,IACJ;AACA,SAAK,YAAY;AAAA,MACb,OAAA9B;AAAA,MACA,YAAA6B;AAAA,MACA,OAAAC;AAAA,MACA,OAAO;AAAA,MACP,aAAAT;AAAA,IAAA,CACH;AAAA,EACL;AACJ;AAEA,SAASoG,EACLzH,GACAsI,IAAQ,0BAC6B;AACrC,MAAItI,KAAS,QAAQ,OAAOA,KAAU,YAAY,MAAM,QAAQA,CAAK;AACjE,UAAM,IAAI,UAAU,GAAGsI,CAAK,oBAAoB;AAExD;AAEA,SAASZ,EAAwB1H,GAG/B;AACE,MAAIA,KAAS,QAAQ,OAAOA,KAAU,YAAY,MAAM,QAAQA,CAAK;AACjE,UAAM,IAAI,UAAU,kDAAkD;AAE1E,aAAW,CAACE,GAAM2E,CAAQ,KAAK,OAAO,QAAQ7E,CAAK;AAC/C,QAAI,CAACiF,EAAkBJ,CAAQ;AAC3B,YAAM,IAAI,UAAU,qBAAqB3E,CAAI,qBAAqB;AAG9E;AAEA,SAAS+E,EAAkBjF,GAA4D;AACnF,SAAOA,KAAS,SACR,OAAOA,KAAU,YAAY,OAAOA,KAAU,eAC/C,OAAO,QAAQ,IAAIA,GAAO,KAAK,KAAM,cACrC,OAAO,QAAQ,IAAIA,GAAO,eAAe,KAAM,cAC/C,OAAO,QAAQ,IAAIA,GAAO,UAAU,KAAM,cAC1C,OAAO,QAAQ,IAAIA,GAAO,WAAW,KAAM;AACtD;"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { BaseEmitter } from '../emitters/baseEmitter.js';
|
|
2
|
+
import type { ReadableEmitter } from '../emitters/baseEmitter.js';
|
|
3
|
+
import { LiveQuery } from '../emitters/liveQuery.js';
|
|
4
|
+
import type { LiveQueryPollingOptions } from '../emitters/liveQuery.js';
|
|
5
|
+
import type { LiveResult } from '../emitters/liveResult.js';
|
|
6
|
+
import type { QueryHandlerLike, QueryValues } from './queryHandler.js';
|
|
7
|
+
import { RestQueryHandler } from './restQueryHandler.js';
|
|
8
|
+
import type { RestQueryHandlerOptions } from './restQueryHandler.js';
|
|
9
|
+
export type EndpointArgumentEmitters<TArguments extends QueryValues> = {
|
|
10
|
+
[TName in keyof TArguments]: ReadableEmitter<TArguments[TName], unknown>;
|
|
11
|
+
};
|
|
12
|
+
export interface EndpointQueryOptions {
|
|
13
|
+
autoFetch?: boolean;
|
|
14
|
+
keepPreviousValue?: boolean;
|
|
15
|
+
polling?: LiveQueryPollingOptions;
|
|
16
|
+
owner?: unknown;
|
|
17
|
+
purpose?: string;
|
|
18
|
+
trace?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface QueryEndpointOptions<TArguments extends QueryValues, TResult> {
|
|
21
|
+
handler: QueryHandlerLike<TArguments, TResult>;
|
|
22
|
+
query?: EndpointQueryOptions;
|
|
23
|
+
}
|
|
24
|
+
/** Immutable reusable declaration for a query backed by any QueryHandler. */
|
|
25
|
+
export declare class QueryEndpoint<TArguments extends QueryValues = Record<string, never>, TResult = unknown> {
|
|
26
|
+
readonly handler: QueryHandlerLike<TArguments, TResult>;
|
|
27
|
+
readonly queryOptions: Readonly<EndpointQueryOptions>;
|
|
28
|
+
constructor(options: QueryEndpointOptions<TArguments, TResult>);
|
|
29
|
+
open<TEmitters extends EndpointArgumentEmitters<TArguments>>(args: TEmitters, options?: EndpointQueryOptions): LiveQuery<TResult, TEmitters>;
|
|
30
|
+
}
|
|
31
|
+
export declare function queryEndpoint<TArguments extends QueryValues = Record<string, never>, TResult = unknown>(options: QueryEndpointOptions<TArguments, TResult>): QueryEndpoint<TArguments, TResult>;
|
|
32
|
+
export type RestEndpointOptions<TArguments extends QueryValues, TResult> = RestQueryHandlerOptions<TArguments, TResult> & {
|
|
33
|
+
query?: EndpointQueryOptions;
|
|
34
|
+
};
|
|
35
|
+
/** Immutable reusable declaration for one REST-backed query endpoint. */
|
|
36
|
+
export declare class RestEndpoint<TArguments extends QueryValues = Record<string, never>, TResult = unknown> {
|
|
37
|
+
readonly handler: RestQueryHandler<TArguments, TResult>;
|
|
38
|
+
readonly queryOptions: Readonly<EndpointQueryOptions>;
|
|
39
|
+
constructor(options: RestEndpointOptions<TArguments, TResult>);
|
|
40
|
+
open<TEmitters extends EndpointArgumentEmitters<TArguments>>(args: TEmitters, options?: EndpointQueryOptions): LiveQuery<TResult, TEmitters>;
|
|
41
|
+
}
|
|
42
|
+
export declare function restEndpoint<TArguments extends QueryValues = Record<string, never>, TResult = unknown>(options: RestEndpointOptions<TArguments, TResult>): RestEndpoint<TArguments, TResult>;
|
|
43
|
+
export interface DerivedEndpointOptions<TSource, TArguments extends QueryValues, TResult> {
|
|
44
|
+
apply(source: TSource, args: TArguments): TResult;
|
|
45
|
+
purpose?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface OpenDerivedEndpointOptions<TSource, TArguments extends QueryValues, TSourceError> {
|
|
48
|
+
source: ReadableEmitter<TSource, TSourceError>;
|
|
49
|
+
args: EndpointArgumentEmitters<TArguments>;
|
|
50
|
+
owner?: unknown;
|
|
51
|
+
purpose?: string;
|
|
52
|
+
trace?: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** Immutable declaration for a local live projection over another result. */
|
|
55
|
+
export declare class DerivedEndpoint<TSource, TArguments extends QueryValues, TResult> {
|
|
56
|
+
readonly apply: (source: TSource, args: TArguments) => TResult;
|
|
57
|
+
readonly purpose: string;
|
|
58
|
+
constructor(options: DerivedEndpointOptions<TSource, TArguments, TResult>);
|
|
59
|
+
open<TSourceError = unknown>(options: OpenDerivedEndpointOptions<TSource, TArguments, TSourceError>): DerivedLiveResult<TSource, TArguments, TResult, TSourceError>;
|
|
60
|
+
}
|
|
61
|
+
export declare function derivedEndpoint<TSource, TArguments extends QueryValues, TResult>(options: DerivedEndpointOptions<TSource, TArguments, TResult>): DerivedEndpoint<TSource, TArguments, TResult>;
|
|
62
|
+
interface DerivedLiveResultOptions<TSource, TArguments extends QueryValues, TResult, TSourceError> extends OpenDerivedEndpointOptions<TSource, TArguments, TSourceError> {
|
|
63
|
+
apply(source: TSource, args: TArguments): TResult;
|
|
64
|
+
}
|
|
65
|
+
/** Caller-owned local result produced by a DerivedEndpoint declaration. */
|
|
66
|
+
export declare class DerivedLiveResult<TSource, TArguments extends QueryValues, TResult, TSourceError = unknown> extends BaseEmitter<TResult, unknown> implements LiveResult<TResult, unknown> {
|
|
67
|
+
readonly source: ReadableEmitter<TSource, TSourceError>;
|
|
68
|
+
readonly args: EndpointArgumentEmitters<TArguments>;
|
|
69
|
+
private readonly apply;
|
|
70
|
+
private unsubscribers;
|
|
71
|
+
private lastSuccessfulValue;
|
|
72
|
+
constructor(options: DerivedLiveResultOptions<TSource, TArguments, TResult, TSourceError>);
|
|
73
|
+
dispose(): void;
|
|
74
|
+
private recompute;
|
|
75
|
+
}
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=endpoints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/queryhandling/endpoints.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,11 +19,13 @@ export type FetchLike<TResult> = {
|
|
|
19
19
|
}): JsonResponseLike<TResult> | JsonResponseLike<unknown> | PromiseLike<JsonResponseLike<TResult> | JsonResponseLike<unknown>>;
|
|
20
20
|
}['bivarianceHack'];
|
|
21
21
|
export type QuerySerializer<TArguments extends QueryValues> = (url: UrlLike, args: TArguments) => void | UrlLike;
|
|
22
|
+
export type ResultParser<TResult> = (json: unknown) => TResult;
|
|
22
23
|
export interface RestQueryHandlerOptions<TArguments extends QueryValues, TResult> {
|
|
23
24
|
url: string;
|
|
24
25
|
baseUrl?: string;
|
|
25
26
|
fetch?: FetchLike<TResult>;
|
|
26
27
|
serialize?: QuerySerializer<TArguments>;
|
|
28
|
+
parseResult?: ResultParser<TResult>;
|
|
27
29
|
trace?: boolean;
|
|
28
30
|
}
|
|
29
31
|
/** Fetch-based JSON query adapter with injectable environment capabilities. */
|
|
@@ -32,6 +34,7 @@ export declare class RestQueryHandler<TArguments extends QueryValues = QueryValu
|
|
|
32
34
|
readonly baseUrl: string | undefined;
|
|
33
35
|
readonly fetchImplementation: FetchLike<TResult>;
|
|
34
36
|
readonly serialize: QuerySerializer<TArguments>;
|
|
37
|
+
readonly parseResult: ResultParser<TResult> | undefined;
|
|
35
38
|
readonly trace: boolean;
|
|
36
39
|
constructor(options: string | RestQueryHandlerOptions<TArguments, TResult>);
|
|
37
40
|
fetch(args: TArguments, options?: QueryRequestOptions): Promise<TResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restQueryHandler.d.ts","sourceRoot":"","sources":["../../src/queryhandling/restQueryHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AAC9C,OAAO,KAAK,EAAC,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAC,MAAM,mBAAmB,CAAA;AAExF,MAAM,WAAW,gBAAgB;IAC7B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACzC;AAED,MAAM,WAAW,OAAO;IACpB,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAA;IACvC,QAAQ,IAAI,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO;IACrC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,IAAI,IAAI,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;CACzC;AAED,MAAM,MAAM,SAAS,CAAC,OAAO,IAAI;IAC7B,cAAc,CACV,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;QAAC,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;KAAC,GAC5C,gBAAgB,CAAC,OAAO,CAAC,GACtB,gBAAgB,CAAC,OAAO,CAAC,GACzB,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAA;CAC3E,CAAC,gBAAgB,CAAC,CAAA;AAEnB,MAAM,MAAM,eAAe,CAAC,UAAU,SAAS,WAAW,IAAI,CAC1D,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,UAAU,KACf,IAAI,GAAG,OAAO,CAAA;AAEnB,MAAM,WAAW,uBAAuB,CACpC,UAAU,SAAS,WAAW,EAC9B,OAAO;IAEP,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IACvC,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAgBD,+EAA+E;AAC/E,qBAAa,gBAAgB,CACzB,UAAU,SAAS,WAAW,GAAG,WAAW,EAC5C,OAAO,GAAG,OAAO,CACnB,SAAQ,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,mBAAmB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAChD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IAC/C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;gBAEX,OAAO,EAAE,MAAM,GAAG,uBAAuB,CAAC,UAAU,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"restQueryHandler.d.ts","sourceRoot":"","sources":["../../src/queryhandling/restQueryHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AAC9C,OAAO,KAAK,EAAC,eAAe,EAAE,mBAAmB,EAAE,WAAW,EAAC,MAAM,mBAAmB,CAAA;AAExF,MAAM,WAAW,gBAAgB;IAC7B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACzC;AAED,MAAM,WAAW,OAAO;IACpB,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAA;IACvC,QAAQ,IAAI,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB,CAAC,OAAO;IACrC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,IAAI,IAAI,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;CACzC;AAED,MAAM,MAAM,SAAS,CAAC,OAAO,IAAI;IAC7B,cAAc,CACV,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;QAAC,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;KAAC,GAC5C,gBAAgB,CAAC,OAAO,CAAC,GACtB,gBAAgB,CAAC,OAAO,CAAC,GACzB,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAA;CAC3E,CAAC,gBAAgB,CAAC,CAAA;AAEnB,MAAM,MAAM,eAAe,CAAC,UAAU,SAAS,WAAW,IAAI,CAC1D,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,UAAU,KACf,IAAI,GAAG,OAAO,CAAA;AAEnB,MAAM,MAAM,YAAY,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAA;AAE9D,MAAM,WAAW,uBAAuB,CACpC,UAAU,SAAS,WAAW,EAC9B,OAAO;IAEP,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IACvC,WAAW,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;IACnC,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAgBD,+EAA+E;AAC/E,qBAAa,gBAAgB,CACzB,UAAU,SAAS,WAAW,GAAG,WAAW,EAC5C,OAAO,GAAG,OAAO,CACnB,SAAQ,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,mBAAmB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAChD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,UAAU,CAAC,CAAA;IAC/C,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,SAAS,CAAA;IACvD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;gBAEX,OAAO,EAAE,MAAM,GAAG,uBAAuB,CAAC,UAAU,EAAE,OAAO,CAAC;IA4B3D,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;CA8B9F"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sylwellsoftware/glue",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
5
|
-
"description": "
|
|
4
|
+
"version": "0.4.0",
|
|
5
|
+
"description": "Platform-neutral reactive values, derived state, live queries, and causal tracing.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Sylwell Software",
|
|
@@ -33,15 +33,10 @@
|
|
|
33
33
|
".": {
|
|
34
34
|
"types": "./dist/index.d.ts",
|
|
35
35
|
"import": "./dist/index.js"
|
|
36
|
-
},
|
|
37
|
-
"./experimental": {
|
|
38
|
-
"types": "./dist/experimental.d.ts",
|
|
39
|
-
"import": "./dist/experimental.js"
|
|
40
36
|
}
|
|
41
37
|
},
|
|
42
38
|
"files": [
|
|
43
39
|
"dist",
|
|
44
|
-
"EXPERIMENTAL.md",
|
|
45
40
|
"LICENSE",
|
|
46
41
|
"NOTICE"
|
|
47
42
|
],
|
package/EXPERIMENTAL.md
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Glue experimental APIs
|
|
2
|
-
|
|
3
|
-
Everything imported from `@sylwellsoftware/glue/experimental` is outside Glue's
|
|
4
|
-
stable alpha compatibility surface. It may change in any `0.x` release without
|
|
5
|
-
a deprecation window. The stable package root does not export these symbols.
|
|
6
|
-
|
|
7
|
-
## `AsyncCommand`
|
|
8
|
-
|
|
9
|
-
`AsyncCommand<TArguments, TResult, TError>` owns one abortable asynchronous
|
|
10
|
-
mutation lifecycle. The command itself is a readable emitter whose value is the
|
|
11
|
-
last successful result and whose fetch state/error describe the current or
|
|
12
|
-
latest run. `isRunning` is a read-only boolean emitter for presentation logic.
|
|
13
|
-
|
|
14
|
-
```ts
|
|
15
|
-
import {AsyncCommand} from '@sylwellsoftware/glue/experimental'
|
|
16
|
-
|
|
17
|
-
const save = new AsyncCommand<{id: string}, {saved: boolean}>({
|
|
18
|
-
async execute({id}, {signal}) {
|
|
19
|
-
const response = await fetch(`/api/records/${id}`, {method: 'POST', signal})
|
|
20
|
-
return {saved: response.ok}
|
|
21
|
-
},
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
const result = await save.run({id: 'record-1'})
|
|
25
|
-
save.abort()
|
|
26
|
-
save.reset()
|
|
27
|
-
save.dispose()
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
The default concurrency policy is `ignore`: an overlapping `run()` returns the
|
|
31
|
-
active promise without executing the new arguments. `replace` aborts and
|
|
32
|
-
supersedes the active run; `reject` rejects only the overlapping invocation
|
|
33
|
-
with `AsyncCommandConcurrencyError`. Executors always receive the current
|
|
34
|
-
abort signal and optional causal event.
|
|
35
|
-
|
|
36
|
-
Successful runs resolve their result. Failed, aborted, stale, or disposed runs
|
|
37
|
-
resolve `undefined`; failures remain observable through `getError()` and
|
|
38
|
-
`FetchState.Error`. The last successful result remains visible while loading
|
|
39
|
-
and after an error. `reset()` aborts active work and returns the snapshot to
|
|
40
|
-
`FetchState.Initial`. `dispose()` is idempotent and permanently suppresses
|
|
41
|
-
late settlement.
|
|
42
|
-
|
|
43
|
-
The command does not queue, retry, report notifications, or own DOM behavior.
|
|
44
|
-
Batch progress and partial-result aggregation remain application concerns.
|