UNPKG

storybook

Version:

Storybook: Develop, document, and test UI components in isolation

1,125 lines (1,120 loc) 164 kB
import * as storybook_open_service from 'storybook/open-service'; import * as storybook_internal_types from 'storybook/internal/types'; import { NormalizedProjectAnnotations, ProjectAnnotations, ComposedStoryFn, StrictArgTypes as StrictArgTypes$1 } from 'storybook/internal/types'; import { StrictArgTypes } from 'storybook/internal/csf'; /** The Standard Typed interface. This is a base type extended by other specs. */ interface StandardTypedV1<Input = unknown, Output = Input> { /** The Standard properties. */ readonly "~standard": StandardTypedV1.Props<Input, Output>; } declare namespace StandardTypedV1 { /** The Standard Typed properties interface. */ interface Props<Input = unknown, Output = Input> { /** The version number of the standard. */ readonly version: 1; /** The vendor name of the schema library. */ readonly vendor: string; /** Inferred types associated with the schema. */ readonly types?: Types<Input, Output> | undefined; } /** The Standard Typed types interface. */ interface Types<Input = unknown, Output = Input> { /** The input type of the schema. */ readonly input: Input; /** The output type of the schema. */ readonly output: Output; } /** Infers the input type of a Standard Typed. */ type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["input"]; /** Infers the output type of a Standard Typed. */ type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["output"]; } /** The Standard Schema interface. */ interface StandardSchemaV1<Input = unknown, Output = Input> { /** The Standard Schema properties. */ readonly "~standard": StandardSchemaV1.Props<Input, Output>; } declare namespace StandardSchemaV1 { /** The Standard Schema properties interface. */ interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> { /** Validates unknown input values. */ readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>; } /** The result interface of the validate function. */ type Result<Output> = SuccessResult<Output> | FailureResult; /** The result interface if validation succeeds. */ interface SuccessResult<Output> { /** The typed output value. */ readonly value: Output; /** A falsy value for `issues` indicates success. */ readonly issues?: undefined; } interface Options { /** Explicit support for additional vendor-specific parameters, if needed. */ readonly libraryOptions?: Record<string, unknown> | undefined; } /** The result interface if validation fails. */ interface FailureResult { /** The issues of failed validation. */ readonly issues: ReadonlyArray<Issue>; } /** The issue interface of the failure output. */ interface Issue { /** The error message of the issue. */ readonly message: string; /** The path of the issue, if any. */ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined; } /** The path segment interface of the issue. */ interface PathSegment { /** The key representing a path segment. */ readonly key: PropertyKey; } /** The Standard types interface. */ interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> { } /** Infers the input type of a Standard. */ type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>; /** Infers the output type of a Standard. */ type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>; } /** File map used by static snapshot building. Each key represents one serialized state snapshot. */ type StaticStore = Record<string, unknown>; /** Generic Standard Schema constraint used across open-service definitions. */ type AnySchema = StandardSchemaV1<unknown, unknown>; /** Stable alias for service identifiers across definition, runtime, and registration APIs. */ type ServiceId = string; /** * Constrains a service's state to a plain object — the only shape the architecture supports. * * This is not an arbitrary restriction; two layers require it: * * 1. State is wrapped in a `deepSignal` proxy for fine-grained per-field reactivity, and `deepSignal` * throws ("this object can't be observed") on primitives, `null`, and `undefined` — there are no * fields to track on a scalar. * 2. Cross-peer sync (`applyStatePatch` in `service-sync.ts`) merges state by walking object keys; * it has no notion of replacing a whole scalar, so the wire protocol only carries keyed objects. * * Arrays are technically observable by `deepSignal` but are still rejected here: `applyStatePatch` * replaces arrays wholesale rather than merging by key, so a *top-level* array state would silently * fail to sync between peers. Wrap collections in a field instead (`{ items: [...] }`). * * Authoring helpers pair this with an `extends object` bound (which rejects primitives, `null`, and * `undefined` while still accepting both `interface` and `type` declarations). The naked `TState` in * the intersection keeps it transparent to inference; only an array collapses to the branded error. */ type ServiceState<TState> = TState & (TState extends readonly unknown[] ? { __openServiceStateError: 'Service state must be a plain object, not an array.'; } : unknown); /** Public schema shape exposed when describing a schema-backed service contract. */ type SchemaDescriptor = AnySchema; /** Raw caller-facing value type accepted by a schema-backed operation. */ type InferSchemaInput<TSchema extends AnySchema> = StandardSchemaV1.InferInput<TSchema>; /** Parsed value type produced by a schema after validation. */ type InferSchemaOutput<TSchema extends AnySchema> = StandardSchemaV1.InferOutput<TSchema>; /** * Named schema maps are the core inference surface for inline open-service authoring. * * `defineService()` infers one input-schema map and one output-schema map per operation family * (queries and commands). Keeping those maps separate gives TypeScript a place to correlate the * `input` and `output` properties of each inline object before it contextually types sibling * callbacks like `handler`, `load`, `staticPath`, and `staticInputs`. */ type OperationInputSchemas = Record<string, AnySchema>; /** * Output-schema maps must stay key-aligned with their input-schema map. * * The authoring helper uses this alias instead of a plain `Record<string, AnySchema>` so each * operation key retains its own input/output schema pair during inference. */ type MatchingOutputSchemas<TInputSchemas extends OperationInputSchemas> = { [TKey in keyof TInputSchemas]: AnySchema; }; /** * Internal utility used to keep handler maps assignable without collapsing everything to `unknown`. */ type BivariantCallback<TArgs extends unknown[], TResult> = { bivarianceHack(...args: TArgs): TResult; }['bivarianceHack']; /** Runtime shape shared by all command collections after they are built. */ type Command = Record<string, (input: unknown) => Promise<unknown>>; /** * Runtime command map derived directly from the inferred command schema maps. * * Queries only need command-call typing, not the full command definition objects, so this helper * keeps query contexts readable while still preserving exact input/output types per command. */ type CommandFunctions<TCommandInputSchemas extends OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas>> = { [TKey in keyof TCommandInputSchemas]: BivariantCallback<[ input: InferSchemaInput<TCommandInputSchemas[TKey]> ], Promise<InferSchemaOutput<TCommandOutputSchemas[TKey]>>>; }; /** * Coarse lifecycle of a query's `load`, modeled after TanStack Query's `status`. * * - `pending` — no successful load has completed yet (and none has failed). The query may still * expose `data` (the synchronous "current best" handler result), but nothing has been loaded. * - `error` — the most recent attempt (load rejection, or a synchronous handler / validation throw) * failed. `data` keeps the last successful value, if any. * - `success` — a load has completed (or the query has no `load`, so there is nothing to load). */ type QueryStatus = 'pending' | 'error' | 'success'; /** * Whether a `load` is currently running, modeled after TanStack Query's `fetchStatus` — but named * with our own `load` vocabulary because open-service "loads" are any slow async work (computation, * extraction, I/O), not specifically remote fetching. * * - `loading` — a `load` is in flight (the first load, or a reactive background re-load). * - `idle` — no `load` is currently running. */ type LoadStatus = 'loading' | 'idle'; /** * The reactive state of a subscribed query: its current `data` plus the lifecycle of its `load`. * * `data` and `status` are independent. `data` is the synchronous handler result ("current best * effort") and holds the last successful value (or `undefined` before the first success / when a * handler throws), while `status`/`loadStatus`/`error` describe the asynchronous `load` lifecycle * tracked per subscription. A query with no `load` is `success`/`idle` from its first emission. * * `isLoading` is intentionally "any load in flight" (TanStack's `isFetching`), and * `isInitialLoading` is "a load is in flight and there is nothing to show yet"; the names follow our * `load` vocabulary rather than TanStack's `fetch`/`load` split. Unlike TanStack Query, a * subscription here can attach to a query whose `data` is already cached in service state, so * `isInitialLoading` additionally requires `data === undefined` — it never flags over cached data. */ type QueryState<TData> = { /** Last successfully produced value; `undefined` before the first success. */ data: TData | undefined; /** The failure that produced `status: 'error'`, otherwise `undefined`. */ error: Error | undefined; status: QueryStatus; loadStatus: LoadStatus; /** `status === 'pending'`. */ isPending: boolean; /** `status === 'success'`. */ isSuccess: boolean; /** `status === 'error'`. */ isError: boolean; /** `loadStatus === 'loading'` — any load in flight, foreground or background. */ isLoading: boolean; /** `isPending && isLoading && data === undefined` — a first load with nothing to show yet. */ isInitialLoading: boolean; /** `isLoading && !isPending` — a background re-load while data is already shown. */ isRefreshing: boolean; }; /** * Public runtime shape of a query. * * - `.get(input)` reads synchronously: it validates input, runs the handler against current state, * and returns the validated result. It does **not** fire the query's `load` — it is a pure * "current best effort" read. (Reads of *other* queries from inside a handler or `load` body still * participate in dependency tracking, so `.loaded()` and subscriptions trigger those dependency * loads; a bare consumer `.get()` does not.) * - `.loaded(input)` awaits the full load — this query's `load` plus every transitively read * dependency — before resolving with the validated result. * - `.subscribe(input, callback)` invokes `callback` synchronously with the current {@link QueryState} * and again whenever tracked state or the load lifecycle changes (deduped on the whole state). * Subscribing is what fires the query's reactive `load`. * * There is intentionally no bare-call form: a previous `query(input)` that returned synchronously * *and* fired the `load` behind the scenes was removed because the implicit background load was * confusing. Read with `.get(input)`, await with `.loaded(input)`, observe with `.subscribe(...)`. * * Queries whose input schema resolves to `undefined` (for example `v.void()`) may be called with * zero arguments: `query.get()`, `query.loaded()`. */ type InputQuery<TInput, TOutput> = { get(input: TInput): TOutput; loaded(input: TInput): Promise<TOutput>; subscribe(input: TInput, callback: (state: QueryState<TOutput>) => void): () => void; subscribe<TSelected>(input: TInput, selector: (value: TOutput) => TSelected, callback: (state: QueryState<TSelected>) => void): () => void; }; /** Zero-argument overloads merged into {@link Query} when the input schema is void. */ type VoidQuery<TOutput> = { get(): TOutput; loaded(): Promise<TOutput>; subscribe(callback: (state: QueryState<TOutput>) => void): () => void; subscribe<TSelected>(selector: (value: TOutput) => TSelected, callback: (state: QueryState<TSelected>) => void): () => void; }; type Query<TInput, TOutput> = undefined extends TInput ? VoidQuery<TOutput> & InputQuery<TInput, TOutput> : InputQuery<TInput, TOutput>; /** * Runtime query map derived directly from the inferred query schema maps. * * The query counterpart to {@link CommandFunctions}: it preserves each sibling query's exact * input/output types on the read-only `self.queries` handle, so a handler or `load` can call * `self.queries.someQuery.get(input)` without manual casts. `defineService` computes this map from * the inferred query schema maps and threads it into the handler/load contexts as their `TQueries`; * the erased {@link AnyQueryFunctions} bound is used everywhere the concrete map is not known. */ type QueryFunctions<TQueryInputSchemas extends OperationInputSchemas, TQueryOutputSchemas extends MatchingOutputSchemas<TQueryInputSchemas>> = { [TKey in keyof TQueryInputSchemas]: Query<InferSchemaInput<TQueryInputSchemas[TKey]>, InferSchemaOutput<TQueryOutputSchemas[TKey]>>; }; /** * Permissive bound for a `self.queries` handle. * * Every {@link Query} — input or void — structurally satisfies {@link InputQuery} (the void * overloads are additive), so this is the supertype that any concrete {@link QueryFunctions} map is * assignable to. It is the bound (and erased default) for the `TQueries` parameter below, which lets * the precise per-service map flow into handler contexts while still erasing cleanly into the * structural `AnyQueryDefinition` storage constraint. Using `Query<unknown, unknown>` here instead * would wrongly demand the void zero-arg overloads from input queries. */ type AnyQueryFunctions = Record<string, InputQuery<unknown, unknown>>; /** * Read-only service handle exposed to query handlers. * * Query handlers are strict readers: they can read state and call sibling queries, but they cannot * mutate state and cannot invoke commands. Mutations belong in commands; load-side preparation * belongs in `load`. */ type QuerySelf<TState = unknown, TQueries extends AnyQueryFunctions = AnyQueryFunctions> = { readonly state: TState; queries: TQueries; }; /** * Load handle exposed to `load` functions. * * `load` may read state and queries, and may invoke declared commands to mutate state. It does * not receive `setState` directly — all writes must flow through commands so authors keep one * documented mutation surface per service. */ type LoadSelf<TState = unknown, TCommandInputSchemas extends OperationInputSchemas = OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas> = MatchingOutputSchemas<TCommandInputSchemas>, TQueries extends AnyQueryFunctions = AnyQueryFunctions> = QuerySelf<TState, TQueries> & { commands: CommandFunctions<TCommandInputSchemas, TCommandOutputSchemas>; }; /** * Mutable service handle exposed to command handlers. * * Commands receive both `setState` for direct state mutation and `commands` so one command can * delegate to another within the same service. */ type CommandSelf<TState = unknown, TCommandInputSchemas extends OperationInputSchemas = OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas> = MatchingOutputSchemas<TCommandInputSchemas>, TQueries extends AnyQueryFunctions = AnyQueryFunctions> = LoadSelf<TState, TCommandInputSchemas, TCommandOutputSchemas, TQueries> & { setState(mutate: (state: TState) => void): void; }; type ServiceSummary = { id: ServiceId; description?: string; queryNames: string[]; commandNames: string[]; }; type OperationDescriptor = { name: string; description?: string; input: SchemaDescriptor; output: SchemaDescriptor; /** Present when the query declares `staticPath` at definition time. */ staticPath?: true; }; type ServiceDescriptor = { id: ServiceId; description?: string; queries: Record<string, OperationDescriptor>; commands: Record<string, OperationDescriptor>; }; /** Context passed to query handlers. */ type QueryCtx<TState, TQueries extends AnyQueryFunctions = AnyQueryFunctions> = { self: QuerySelf<TState, TQueries>; getService: ServiceRegistryApi['getService']; }; /** Context passed to `load` functions and static-input enumerators. */ type LoadCtx<TState, TCommandInputSchemas extends OperationInputSchemas = OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas> = MatchingOutputSchemas<TCommandInputSchemas>, TQueries extends AnyQueryFunctions = AnyQueryFunctions> = { self: LoadSelf<TState, TCommandInputSchemas, TCommandOutputSchemas, TQueries>; getService: ServiceRegistryApi['getService']; }; /** Static input enumerator stored on registered definitions; always receives load context. */ type RegisteredStaticInputs<TState> = BivariantCallback<[ ctx: LoadCtx<TState> ], unknown[] | Promise<unknown[]>>; /** Context passed to command handlers. */ type CommandCtx<TState, TCommandInputSchemas extends OperationInputSchemas = OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas> = MatchingOutputSchemas<TCommandInputSchemas>, TQueries extends AnyQueryFunctions = AnyQueryFunctions> = { self: CommandSelf<TState, TCommandInputSchemas, TCommandOutputSchemas, TQueries>; getService: ServiceRegistryApi['getService']; }; /** * Declarative definition for one query. * * Queries validate caller input synchronously, run a synchronous read-only handler, and validate * the resolved output. The optional `load` hook is fired by subscriptions (reactively) and by * `.loaded()` callers (drained to completion), deduped per `(service, query, input)` while one is * already in flight — a bare `.get()` read never fires it. * * Queries that participate in static JSON generation declare `staticPath` at definition time. * `staticInputs` may also be declared here when the input list has no runtime dependencies; inputs * that need registry or story-index context belong in server registration instead. */ type QueryDefinition<TState, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TCommandInputSchemas extends OperationInputSchemas = OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas> = MatchingOutputSchemas<TCommandInputSchemas>, TQueries extends AnyQueryFunctions = AnyQueryFunctions> = { description?: string; /** * When true, hides this query from `describeService()` output. Defaults to false. Does not disable * the query at runtime — callers with a service handle can still invoke it. */ internal?: boolean; input: TInputSchema; output: TOutputSchema; /** Logical path for the serialized state snapshot, relative to this service's output folder. */ staticPath?: BivariantCallback<[input: InferSchemaOutput<TInputSchema>], string>; /** Dependency-free static build inputs declared alongside the public contract. */ staticInputs?: BivariantCallback<[ ], InferSchemaInput<TInputSchema>[] | Promise<InferSchemaInput<TInputSchema>[]>>; handler?: BivariantCallback<[ input: InferSchemaOutput<TInputSchema>, ctx: QueryCtx<TState, TQueries> ], InferSchemaInput<TOutputSchema>>; load?: BivariantCallback<[ input: InferSchemaOutput<TInputSchema>, ctx: LoadCtx<TState, TCommandInputSchemas, TCommandOutputSchemas, TQueries> ], void | Promise<void>>; }; /** * Declarative definition for one command. * * Commands validate caller input, run against a mutable context, and validate the resolved output. */ type CommandDefinition<TState, TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TCommandInputSchemas extends OperationInputSchemas = OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas> = MatchingOutputSchemas<TCommandInputSchemas>, TQueries extends AnyQueryFunctions = AnyQueryFunctions> = { description?: string; /** * When true, hides this command from `describeService()` output. Defaults to false. Does not * disable the command at runtime — callers with a service handle can still invoke it. */ internal?: boolean; input: TInputSchema; output: TOutputSchema; handler?: BivariantCallback<[ input: InferSchemaOutput<TInputSchema>, ctx: CommandCtx<TState, TCommandInputSchemas, TCommandOutputSchemas, TQueries> ], InferSchemaInput<TOutputSchema> | Promise<InferSchemaInput<TOutputSchema>>>; }; /** Internal structural constraint used to store any query definition in a record. */ type AnyQueryDefinition<TState> = { description?: string; internal?: boolean; input: AnySchema; output: AnySchema; staticPath?: BivariantCallback<[input: unknown], string>; staticInputs?: RegisteredStaticInputs<TState>; handler?: BivariantCallback<[input: unknown, ctx: QueryCtx<TState>], unknown>; load?: BivariantCallback<[input: unknown, ctx: LoadCtx<TState>], void | Promise<void>>; }; /** Internal structural constraint used to store any command definition in a record. */ type AnyCommandDefinition<TState> = { description?: string; internal?: boolean; input: AnySchema; output: AnySchema; handler?: BivariantCallback<[ input: unknown, ctx: CommandCtx<TState> ], unknown | Promise<unknown>>; }; /** Named query map attached to a service definition. */ type Queries<TState> = Record<string, AnyQueryDefinition<TState>>; /** Named command map attached to a service definition. */ type Commands<TState> = Record<string, AnyCommandDefinition<TState>>; /** Top-level description of a service: identity, initial state, queries, and commands. */ type ServiceDefinition<TState, TQueries extends Queries<TState>, TCommands extends Commands<TState>, TId extends ServiceId = ServiceId> = { id: TId; description?: string; /** * When true, hides this service from `listServices()` output. Defaults to false. Does not disable * the service at runtime — callers can still resolve it through `getService()`. */ internal?: boolean; /** * Initial state for the service. Must be a plain object (not a primitive, `null`, or array) — see * {@link ServiceState} for why. The authoring boundary (`defineService`) enforces this; the runtime * type stays `TState` so already-constructed definitions flow through the registry unchanged. */ initialState: TState; queries: TQueries; commands: TCommands; }; /** Structural constraint for any service definition stored in the registry. */ type AnyServiceDefinition = ServiceDefinition<unknown, Queries<unknown>, Commands<unknown>>; /** Runtime service instance derived from a `ServiceDefinition`. */ type ServiceInstance<TState, TQueries extends Queries<TState>, TCommands extends Commands<TState>> = { queries: { [TKey in keyof TQueries]: TQueries[TKey] extends { input: infer TInputSchema extends AnySchema; output: infer TOutputSchema extends AnySchema; } ? Query<InferSchemaInput<TInputSchema>, InferSchemaOutput<TOutputSchema>> : never; }; commands: { [TKey in keyof TCommands]: TCommands[TKey] extends { input: infer TInputSchema extends AnySchema; output: infer TOutputSchema extends AnySchema; } ? (input: InferSchemaInput<TInputSchema>) => Promise<InferSchemaOutput<TOutputSchema>> : never; }; }; /** Runtime instance type recovered from one authored service definition. */ type ServiceInstanceOf<TDefinition extends AnyServiceDefinition> = TDefinition extends ServiceDefinition<infer TState, infer TQueries, infer TCommands> ? ServiceInstance<TState, TQueries, TCommands> : never; interface ServiceRegistryApi { listServices(): Promise<ServiceSummary[]>; describeService(serviceId: ServiceId): Promise<ServiceDescriptor>; getService<TInstance = RuntimeService>(serviceId: ServiceId): TInstance; } type RuntimeService = ServiceInstance<unknown, Queries<unknown>, Commands<unknown>> & ServiceRegistryApi; type ServiceQueryRegistration<TState> = { /** Static build inputs that may depend on registry or other server context. */ staticInputs?: RegisteredStaticInputs<TState>; }; type ServiceCommandRegistration<TState, TCommand extends AnyCommandDefinition<TState>> = Pick<TCommand, 'handler'>; type ServiceRegistrationOptions<TState, TQueries extends Queries<TState>, TCommands extends Commands<TState>> = { queries?: { [TKey in keyof TQueries]?: ServiceQueryRegistration<TState>; }; commands?: { [TKey in keyof TCommands]?: ServiceCommandRegistration<TState, TCommands[TKey]>; }; }; type ServerServiceRegistration<TState, TQueries extends Queries<TState>, TCommands extends Commands<TState>> = { definition: ServiceDefinition<TState, TQueries, TCommands>; } & ServiceRegistrationOptions<TState, TQueries, TCommands>; type InvalidInternalOperationName<TName extends string> = { __internal_naming_error: `Operation "${TName}" has internal: true but must be prefixed with "_"`; }; type InvalidUnderscoreWithoutInternal<TName extends string> = { __internal_naming_error: `Operation "${TName}" is prefixed with "_" and must set internal: true`; }; type InternalOperationNaming<TKey> = TKey extends string ? TKey extends `_${string}` ? { internal: true; } | InvalidUnderscoreWithoutInternal<TKey> : { internal?: false; } | InvalidInternalOperationName<TKey> : {}; /** * Authoring-side query map derived from separate query input/output schema maps. * * The second mapped-type intersection is deliberate. During experiments, TypeScript would infer * the `input` schema for each inline query, but then lose the corresponding `output` schema before * it contextually typed sibling callbacks. Repeating the output map through a keyed `output` view * keeps each query key's input and output schemas correlated while handlers, load hooks, and * static callbacks are being typed. */ type DefinedQueries<TState, TQueryInputSchemas extends OperationInputSchemas, TQueryOutputSchemas extends MatchingOutputSchemas<TQueryInputSchemas>, TCommandInputSchemas extends OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas>> = { [TKey in keyof TQueryInputSchemas]: QueryDefinition<TState, TQueryInputSchemas[TKey], TQueryOutputSchemas[TKey], TCommandInputSchemas, TCommandOutputSchemas, QueryFunctions<TQueryInputSchemas, TQueryOutputSchemas>> & InternalOperationNaming<TKey>; } & { [TKey in keyof TQueryOutputSchemas]: { output: TQueryOutputSchemas[TKey]; }; }; /** * Authoring-side command map derived from separate command input/output schema maps. * * Commands do not need access to the command schema maps in their own context, but they still * benefit from the same key-correlation trick as queries so TypeScript preserves each inline * command object's `output` schema while typing its `handler`. */ type DefinedCommands<TState, TCommandInputSchemas extends OperationInputSchemas, TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas>, TQueryInputSchemas extends OperationInputSchemas, TQueryOutputSchemas extends MatchingOutputSchemas<TQueryInputSchemas>> = { [TKey in keyof TCommandInputSchemas]: CommandDefinition<TState, TCommandInputSchemas[TKey], TCommandOutputSchemas[TKey], TCommandInputSchemas, TCommandOutputSchemas, QueryFunctions<TQueryInputSchemas, TQueryOutputSchemas>> & InternalOperationNaming<TKey>; } & { [TKey in keyof TCommandOutputSchemas]: { output: TCommandOutputSchemas[TKey]; }; }; /** * Finalizes a service definition while preserving inline query and command inference. * * The generic order matters here. We infer the per-operation schema maps first, then derive the * concrete query/command definition maps from those schemas. If we instead ask TypeScript to infer * the full runtime `ServiceDefinition` maps directly, it widens callback parameters to `unknown` * before it has correlated each inline object's `input` and `output` properties. */ declare const defineService: <TState extends object, const TQueryInputSchemas extends OperationInputSchemas, const TQueryOutputSchemas extends MatchingOutputSchemas<TQueryInputSchemas>, const TCommandInputSchemas extends OperationInputSchemas, const TCommandOutputSchemas extends MatchingOutputSchemas<TCommandInputSchemas>, const TId extends ServiceId = ServiceId>(def: { id: TId; description?: string; internal?: boolean; initialState: ServiceState<TState>; queries: DefinedQueries<TState, TQueryInputSchemas, TQueryOutputSchemas, TCommandInputSchemas, TCommandOutputSchemas>; commands: DefinedCommands<TState, TCommandInputSchemas, TCommandOutputSchemas, TQueryInputSchemas, TQueryOutputSchemas>; }) => ServiceDefinition<TState, DefinedQueries<TState, TQueryInputSchemas, TQueryOutputSchemas, TCommandInputSchemas, TCommandOutputSchemas>, DefinedCommands<TState, TCommandInputSchemas, TCommandOutputSchemas, TQueryInputSchemas, TQueryOutputSchemas>, TId>; /** * Builds the synthetic first-render {@link QueryState} for a subscription hook, from a pure * `query.get(input)` read. * * Subscription hooks must return a {@link QueryState} on their very first render, before the * subscription's first emission has delivered the real lifecycle (`useSyncExternalStore` reads the * snapshot during render; the React 16-compatible preview hooks read it synchronously too). `get()` * returns only data (no lifecycle, no load), so we pair it with a `pending`/`loading` status as a * placeholder until the subscription delivers the real lifecycle moments later. A throw from * `get()` (e.g. input validation) becomes an `error` state — mirroring what the subscription would * emit — so the hook never throws during render. * * Shared by the manager-side `useServiceQuery` and the preview-side docs hooks so their first-render * seeds can never drift apart. * * Only the query's `get` method is needed, so the parameter is narrowed to that shape: `TOutput` then * infers purely (and reliably) from `get`'s return type, rather than through the contravariant * positions of the full `Query` type — which would widen `TOutput` and break callers that pass a * query with a hand-written payload type. */ declare function seedQueryState<TInput, TOutput>(query: { get(input: TInput): TOutput; }, input: TInput): QueryState<TOutput>; declare function seedQueryState<TInput, TOutput, TSelected>(query: { get(input: TInput): TOutput; }, input: TInput, selector: (value: TOutput) => TSelected): QueryState<TSelected>; //#endregion //#region src/methods/fallback/fallback.d.ts /** * Fallback type. */ type Fallback<TSchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>>> = MaybeDeepReadonly<InferOutput<TSchema>> | ((dataset?: OutputDataset<InferOutput<TSchema>, InferIssue<TSchema>>, config?: Config<InferIssue<TSchema>>) => MaybeDeepReadonly<InferOutput<TSchema>>); /** * Schema with fallback type. */ type SchemaWithFallback<TSchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>>, TFallback$1 extends Fallback<TSchema>> = TSchema & { /** * The fallback value. */ readonly fallback: TFallback$1; }; //#endregion //#region src/methods/fallback/fallbackAsync.d.ts /** * Fallback async type. */ type FallbackAsync<TSchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>> = MaybeDeepReadonly<InferOutput<TSchema>> | ((dataset?: OutputDataset<InferOutput<TSchema>, InferIssue<TSchema>>, config?: Config<InferIssue<TSchema>>) => MaybePromise<MaybeDeepReadonly<InferOutput<TSchema>>>); /** * Schema with fallback async type. */ type SchemaWithFallbackAsync<TSchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>, TFallback$1 extends FallbackAsync<TSchema>> = Omit<TSchema, "async" | "~standard" | "~run"> & { /** * The fallback value. */ readonly fallback: TFallback$1; /** * Whether it's async. */ readonly async: true; /** * The Standard Schema properties. * * @internal */ readonly "~standard": StandardProps<InferInput<TSchema>, InferOutput<TSchema>>; /** * Parses unknown input values. * * @param dataset The input dataset. * @param config The configuration. * * @returns The output dataset. * * @internal */ readonly "~run": (dataset: UnknownDataset, config: Config<BaseIssue<unknown>>) => Promise<OutputDataset<InferOutput<TSchema>, InferIssue<TSchema>>>; }; //#endregion //#region src/types/metadata.d.ts /** * Base metadata interface. */ interface BaseMetadata<TInput$1> { /** * The object kind. */ readonly kind: "metadata"; /** * The metadata type. */ readonly type: string; /** * The metadata reference. */ readonly reference: (...args: any[]) => BaseMetadata<any>; /** * The input, output and issue type. * * @internal */ readonly "~types"?: { readonly input: TInput$1; readonly output: TInput$1; readonly issue: never; } | undefined; } //#endregion //#region src/types/dataset.d.ts /** * Unknown dataset interface. */ interface UnknownDataset { /** * Whether is's typed. */ typed?: false; /** * The dataset value. */ value: unknown; /** * The dataset issues. */ issues?: undefined; } /** * Success dataset interface. */ interface SuccessDataset<TValue$1> { /** * Whether is's typed. */ typed: true; /** * The dataset value. */ value: TValue$1; /** * The dataset issues. */ issues?: undefined; } /** * Partial dataset interface. */ interface PartialDataset<TValue$1, TIssue extends BaseIssue<unknown>> { /** * Whether is's typed. */ typed: true; /** * The dataset value. */ value: TValue$1; /** * The dataset issues. */ issues: [TIssue, ...TIssue[]]; } /** * Failure dataset interface. */ interface FailureDataset<TIssue extends BaseIssue<unknown>> { /** * Whether is's typed. */ typed: false; /** * The dataset value. */ value: unknown; /** * The dataset issues. */ issues: [TIssue, ...TIssue[]]; } /** * Output dataset type. */ type OutputDataset<TValue$1, TIssue extends BaseIssue<unknown>> = SuccessDataset<TValue$1> | PartialDataset<TValue$1, TIssue> | FailureDataset<TIssue>; //#endregion //#region src/types/standard.d.ts /** * The Standard Schema properties interface. */ interface StandardProps<TInput$1, TOutput$1> { /** * The version number of the standard. */ readonly version: 1; /** * The vendor name of the schema library. */ readonly vendor: "valibot"; /** * Validates unknown input values. */ readonly validate: (value: unknown) => StandardResult<TOutput$1> | Promise<StandardResult<TOutput$1>>; /** * Inferred types associated with the schema. */ readonly types?: StandardTypes<TInput$1, TOutput$1> | undefined; } /** * The result interface of the validate function. */ type StandardResult<TOutput$1> = StandardSuccessResult<TOutput$1> | StandardFailureResult; /** * The result interface if validation succeeds. */ interface StandardSuccessResult<TOutput$1> { /** * The typed output value. */ readonly value: TOutput$1; /** * The non-existent issues. */ readonly issues?: undefined; } /** * The result interface if validation fails. */ interface StandardFailureResult { /** * The issues of failed validation. */ readonly issues: readonly StandardIssue[]; } /** * The issue interface of the failure output. */ interface StandardIssue { /** * The error message of the issue. */ readonly message: string; /** * The path of the issue, if any. */ readonly path?: readonly (PropertyKey | StandardPathItem)[] | undefined; } /** * The path item interface of the issue. */ interface StandardPathItem { /** * The key of the path item. */ readonly key: PropertyKey; } /** * The Standard Schema types interface. */ interface StandardTypes<TInput$1, TOutput$1> { /** * The input type of the schema. */ readonly input: TInput$1; /** * The output type of the schema. */ readonly output: TOutput$1; } //#endregion //#region src/types/schema.d.ts /** * Base schema interface. */ interface BaseSchema<TInput$1, TOutput$1, TIssue extends BaseIssue<unknown>> { /** * The object kind. */ readonly kind: "schema"; /** * The schema type. */ readonly type: string; /** * The schema reference. */ readonly reference: (...args: any[]) => BaseSchema<unknown, unknown, BaseIssue<unknown>>; /** * The expected property. */ readonly expects: string; /** * Whether it's async. */ readonly async: false; /** * The Standard Schema properties. * * @internal */ readonly "~standard": StandardProps<TInput$1, TOutput$1>; /** * Parses unknown input values. * * @param dataset The input dataset. * @param config The configuration. * * @returns The output dataset. * * @internal */ readonly "~run": (dataset: UnknownDataset, config: Config<BaseIssue<unknown>>) => OutputDataset<TOutput$1, TIssue>; /** * The input, output and issue type. * * @internal */ readonly "~types"?: { readonly input: TInput$1; readonly output: TOutput$1; readonly issue: TIssue; } | undefined; } /** * Base schema async interface. */ interface BaseSchemaAsync<TInput$1, TOutput$1, TIssue extends BaseIssue<unknown>> extends Omit<BaseSchema<TInput$1, TOutput$1, TIssue>, "reference" | "async" | "~run"> { /** * The schema reference. */ readonly reference: (...args: any[]) => BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>; /** * Whether it's async. */ readonly async: true; /** * Parses unknown input values. * * @param dataset The input dataset. * @param config The configuration. * * @returns The output dataset. * * @internal */ readonly "~run": (dataset: UnknownDataset, config: Config<BaseIssue<unknown>>) => Promise<OutputDataset<TOutput$1, TIssue>>; } //#endregion //#region src/types/transformation.d.ts /** * Base transformation interface. */ interface BaseTransformation<TInput$1, TOutput$1, TIssue extends BaseIssue<unknown>> { /** * The object kind. */ readonly kind: "transformation"; /** * The transformation type. */ readonly type: string; /** * The transformation reference. */ readonly reference: (...args: any[]) => BaseTransformation<any, any, BaseIssue<unknown>>; /** * Whether it's async. */ readonly async: false; /** * Transforms known input values. * * @param dataset The input dataset. * @param config The configuration. * * @returns The output dataset. * * @internal */ readonly "~run": (dataset: SuccessDataset<TInput$1>, config: Config<BaseIssue<unknown>>) => OutputDataset<TOutput$1, BaseIssue<unknown> | TIssue>; /** * The input, output and issue type. * * @internal */ readonly "~types"?: { readonly input: TInput$1; readonly output: TOutput$1; readonly issue: TIssue; } | undefined; } /** * Base transformation async interface. */ interface BaseTransformationAsync<TInput$1, TOutput$1, TIssue extends BaseIssue<unknown>> extends Omit<BaseTransformation<TInput$1, TOutput$1, TIssue>, "reference" | "async" | "~run"> { /** * The transformation reference. */ readonly reference: (...args: any[]) => BaseTransformation<any, any, BaseIssue<unknown>> | BaseTransformationAsync<any, any, BaseIssue<unknown>>; /** * Whether it's async. */ readonly async: true; /** * Transforms known input values. * * @param dataset The input dataset. * @param config The configuration. * * @returns The output dataset. * * @internal */ readonly "~run": (dataset: SuccessDataset<TInput$1>, config: Config<BaseIssue<unknown>>) => Promise<OutputDataset<TOutput$1, BaseIssue<unknown> | TIssue>>; } //#endregion //#region src/types/validation.d.ts /** * Base validation interface. */ interface BaseValidation<TInput$1, TOutput$1, TIssue extends BaseIssue<unknown>> { /** * The object kind. */ readonly kind: "validation"; /** * The validation type. */ readonly type: string; /** * The validation reference. */ readonly reference: (...args: any[]) => BaseValidation<any, any, BaseIssue<unknown>>; /** * The expected property. */ readonly expects: string | null; /** * Whether it's async. */ readonly async: false; /** * Validates known input values. * * @param dataset The input dataset. * @param config The configuration. * * @returns The output dataset. * * @internal */ readonly "~run": (dataset: OutputDataset<TInput$1, BaseIssue<unknown>>, config: Config<BaseIssue<unknown>>) => OutputDataset<TOutput$1, BaseIssue<unknown> | TIssue>; /** * The input, output and issue type. * * @internal */ readonly "~types"?: { readonly input: TInput$1; readonly output: TOutput$1; readonly issue: TIssue; } | undefined; } /** * Base validation async interface. */ interface BaseValidationAsync<TInput$1, TOutput$1, TIssue extends BaseIssue<unknown>> extends Omit<BaseValidation<TInput$1, TOutput$1, TIssue>, "reference" | "async" | "~run"> { /** * The validation reference. */ readonly reference: (...args: any[]) => BaseValidation<any, any, BaseIssue<unknown>> | BaseValidationAsync<any, any, BaseIssue<unknown>>; /** * Whether it's async. */ readonly async: true; /** * Validates known input values. * * @param dataset The input dataset. * @param config The configuration. * * @returns The output dataset. * * @internal */ readonly "~run": (dataset: OutputDataset<TInput$1, BaseIssue<unknown>>, config: Config<BaseIssue<unknown>>) => Promise<OutputDataset<TOutput$1, BaseIssue<unknown> | TIssue>>; } //#endregion //#region src/types/infer.d.ts /** * Infer input type. */ type InferInput<TItem$1 extends BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>> | BaseValidation<any, unknown, BaseIssue<unknown>> | BaseValidationAsync<any, unknown, BaseIssue<unknown>> | BaseTransformation<any, unknown, BaseIssue<unknown>> | BaseTransformationAsync<any, unknown, BaseIssue<unknown>> | BaseMetadata<any>> = NonNullable<TItem$1["~types"]>["input"]; /** * Infer output type. */ type InferOutput<TItem$1 extends BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>> | BaseValidation<any, unknown, BaseIssue<unknown>> | BaseValidationAsync<any, unknown, BaseIssue<unknown>> | BaseTransformation<any, unknown, BaseIssue<unknown>> | BaseTransformationAsync<any, unknown, BaseIssue<unknown>> | BaseMetadata<any>> = NonNullable<TItem$1["~types"]>["output"]; /** * Infer issue type. */ type InferIssue<TItem$1 extends BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>> | BaseValidation<any, unknown, BaseIssue<unknown>> | BaseValidationAsync<any, unknown, BaseIssue<unknown>> | BaseTransformation<any, unknown, BaseIssue<unknown>> | BaseTransformationAsync<any, unknown, BaseIssue<unknown>> | BaseMetadata<any>> = NonNullable<TItem$1["~types"]>["issue"]; /** * Constructs a type that is maybe readonly. */ type MaybeReadonly<TValue$1> = TValue$1 | Readonly<TValue$1>; /** * Constructs a type that is deeply readonly. */ type DeepReadonly<TValue$1> = TValue$1 extends Record<string, unknown> | readonly unknown[] ? { readonly [TKey in keyof TValue$1]: DeepReadonly<TValue$1[TKey]> } : TValue$1; /** * Constructs a type that is maybe deeply readonly. */ type MaybeDeepReadonly<TValue$1> = TValue$1 | DeepReadonly<TValue$1>; /** * Constructs a type that is maybe a promise. */ type MaybePromise<TValue$1> = TValue$1 | Promise<TValue$1>; /** * Prettifies a type for better readability. * * Hint: This type has no effect and is only used so that TypeScript displays * the final type in the preview instead of the utility types used. */ type Prettify<TObject> = { [TKey in keyof TObject]: TObject[TKey] } & {}; /** * Marks specific keys as optional. */ type MarkOptional<TObject, TKeys extends keyof TObject> = { [TKey in keyof TObject]?: unknown } & Omit<TObject, TKeys> & Partial<Pick<TObject, TKeys>>; //#endregion //#region src/types/other.d.ts /** * Error message type. */ type ErrorMessage<TIssue extends BaseIssue<unknown>> = ((issue: TIssue) => string) | string; /** * Default type. */ type Default<TWrapped$1 extends BaseSchema<unknown, unknown, BaseIssue<unknown>>, TInput$1 extends null | undefined> = MaybeDeepReadonly<InferInput<TWrapped$1> | TInput$1> | ((dataset?: UnknownDataset, config?: Config<InferIssue<TWrapped$1>>) => MaybeDeepReadonly<InferInput<TWrapped$1> | TInput$1>) | undefined; /** * Default async type. */ type DefaultAsync<TWrapped$1 extends BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>, TInput$1 extends null | undefined> = MaybeDeepReadonly<InferInput<TWrapped$1> | TInput$1> | ((dataset?: UnknownDataset, config?: Config<InferIssue<TWrapped$1>>) => MaybePromise<MaybeDeepReadonly<InferInput<TWrapped$1> | TInput$1>>) | undefined; /** * Default value type. */ type DefaultValue<TDefault extends Default<BaseSchema<unknown, unknown, BaseIssue<unknown>>, null | undefined> | DefaultAsync<BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>, null | undefined>> = TDefault extends DefaultAsync<infer TWrapped extends BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>, infer TInput> ? TDefault extends ((dataset?: UnknownDataset, config?: Config<InferIssue<TWrapped>>) => MaybePromise<MaybeDeepReadonly<InferInput<TWrapped> | TInput>>) ? Awaited<ReturnType<TDefault>> : TDefault : never; //#endregion //#region src/types/object.d.ts /** * Optional entry schema type. */ type OptionalEntrySchema = ExactOptionalSchema<BaseSchema<unknown, unknown, BaseIssue<unknown>>, unknown> | NullishSchema<BaseSchema<unknown, unknown, BaseIssue<unknown>>, unknown> | OptionalSchema<BaseSchema<unknown, unknown, BaseIssue<unknown>>, unknown>; /** * Optional entry schema async type. */ type OptionalEntrySchemaAsync = ExactOptionalSchemaAsync<BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>, unknown> | NullishSchemaAsync<BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>, unknown> | OptionalSchemaAsync<BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>, unknown>; /** * Object entries interface. */ interface ObjectEntries { [key: string]: BaseSchema<unknown, unknown, BaseIssue<unknown>> | SchemaWithFallback<BaseSchema<unknown, unknown, BaseIssue<unknown>>, unknown> | OptionalEntrySchema; } /** * Object entries async interface. */ interface ObjectEntriesAsync { [key: string]: BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>> | SchemaWithFallback<BaseSchema<unknown, unknown, BaseIssue<unknown>>, unknown> | SchemaWithFallbackAsync<BaseSchema<unknown, unknown, BaseIssue<unknown>> | BaseSchemaAsync<unknown, unknown, BaseIssue<unknown>>, unknown> | OptionalEntrySchema | OptionalEntrySchemaAsync; } /** * Infer entries input type. */ type InferEntriesInput<TEntries$1 extends ObjectEntries | ObjectEntriesAsync> = { -readonly [TKey in keyof TEntries$1]: InferInput<TEntries$1[TKey]> }; /** * Infer entries output type. */ type InferEntriesOutput<TEntries$1 extends ObjectEntries | ObjectEntriesAsync> = { -readonly [TKey in keyof TEntries$1]: InferOutput<TEntries$1[TKey]> }; /** * Optional input keys type. */ type OptionalInputKeys<TEntries$1 extends ObjectEntries | ObjectEntriesAsync> = { [TKey in keyof TEntries$1]: TEntries$1[TKey] extends OptionalEntrySchema | OptionalEntrySchemaAsync ? TKey : never }[keyof TEntries$1]; /** * Optional output keys type. */ type OptionalOutputKeys<TEntries$1 extends ObjectEntries | ObjectEntriesAsync> = { [TKey in keyof TEntries$1]: TEntries$1[TKey] extends OptionalEntrySchema | OptionalEntrySchemaAsync ? undefined extends TEntries$1[TKey]["default"] ? TKey : never : never }[keyof TEntries$1]; /** * Input with question marks type. */ type InputWithQuestionMarks<TEntries$1 extends ObjectEntries | ObjectEntriesAsync, TObject extends InferEntriesInput<TEntries$1>> = MarkOptional<TObject, OptionalInputKeys<TEntries$1>>; /** * Output with question marks type. */ type OutputWithQuestionMarks<TEntries$1 extends ObjectEntries | ObjectEntriesAsync, TObject extends InferEntriesOutput<TEntries$1>> = MarkOptional<TObject, OptionalOutputKeys<TEntries$1>>; /** * Readonly output keys type. */ type ReadonlyOutputKeys<TEntries$1 extends ObjectEntries | ObjectEntriesAsync> = { [TKey in keyof TEntries$1]: TEntries$1[TKey] extends { readonly pipe: readonly unknown[]; } ? ReadonlyAction<any> e