import type { DataTag } from "./dataTag"; import type { Layer } from "./layer"; import type { LayerClient } from "./layerClient"; import type { LayerStack } from "./layerStack"; import type { CancelQueuedArgs, DefaultLayerError, HandleDismissArgs, LayerKey, LayerOptions, PayloadArg, } from "./types"; import { keySignature } from "./utils"; import type { InferValidatorOutput, OpenValidatePayload, Validator, } from "./validators"; interface OpenOpts
{
key: LayerKey;
payload: P;
component?: unknown;
enteringDelay?: number;
exitingDelay?: number;
upsert?: boolean;
loadFn?: (ctx: { payload: P; signal: AbortSignal }) => Promise ;
}
/** Prevents validated options from falling through to the unvalidated overload. */
type NoValidateOptions {
open: (payload: PayloadArg ["payload"]) => Promise ["payload"]) => Promise , opts?: { id?: string }) => void;
/**
* Resolves and removes a serially queued layer without mounting (skips blockers).
* No `id` → FIFO head for this key; `{ id }` → exact queued match.
* Response may be omitted when `undefined extends R` ({@link CancelQueuedArgs} /
* {@link EndArgs} gate).
*/
cancelQueued: (...args: CancelQueuedArgs ;
readonly options: LayerOptions & {
key: DataTag | null;
}
/**
* Validated handle: `open`/`upsert` take schema **input** ({@link OpenValidatePayload});
* `current`/`update` use parsed **output**.
*/
export interface ValidatedLayerHandle<
V extends Validator ;
export function createLayer<
P,
R,
E = DefaultLayerError,
D = unknown,
RP = unknown,
>(
options: LayerOptions & { key: LayerKey },
client: LayerClient,
): LayerHandle {
const stackId = options.stack ?? "default";
const stack = client.getStack(stackId) as unknown as LayerStack ;
const opts = options as LayerOptions & {
key: DataTag | undefined;
const toOpenOpts = (payload: P): OpenOpts => ({
key: opts.key,
payload,
component: opts.component,
enteringDelay: opts.enteringDelay,
exitingDelay: opts.exitingDelay,
upsert: opts.upsert,
loadFn: opts.loadFn,
validate: opts.validate,
});
const target = (id?: string): Layer | undefined => {
if (id) {
const l = stack.getLayer(id);
return l && keySignature(l.key) === sig ? l : undefined;
}
return stack.find(opts.key);
};
return {
open: (payload) => {
mine = stack.open(toOpenOpts(payload as P));
return mine.promise.promise as Promise | null {
return (mine ? (stack.getLayer(mine.id) ?? null) : null) as Layer<
P,
R,
E,
D
> | null;
},
};
}