import { DocumentApiSurface } from '../index.js'; import { InsertInput } from '../insert/insert.js'; import { ReplaceInput, TrackedReplaceMutationOptions } from '../replace/replace.js'; import { BodyStoryLocator } from '../types/story.types.js'; import { OperationCancellation } from '../write/operation-cancellation.js'; import { TrackedRichContentMutationOptions } from '../write/write.js'; import { OPERATION_DEFINITIONS } from './operation-definitions.js'; import { OperationId } from './types.js'; type ResolveMemberPath = Path extends `${infer Head}.${infer Tail}` ? Head extends keyof T ? ResolveMemberPath : never : Path extends keyof T ? T[Path] : never; type MethodArguments = T extends (...args: infer Arguments) => unknown ? Arguments : never; type MethodInput = MethodArguments extends readonly [] ? undefined : MethodArguments[0]; type MethodOptions = 2 extends MethodArguments['length'] ? Exclude[1], undefined> : never; type MethodReturn = T extends (...args: never[]) => infer Output ? Output : never; /** * Canonical type-level mapping used by `invoke()` and its dispatch table. * Promise-returning mutation-plan operations store their resolved payload so * `InvokeResult` can retain the established async call shape. */ export type OperationRegistry = { [Id in OperationId]: ResolveMemberPath extends infer Method ? { input: MethodInput; options: MethodOptions; output: Id extends 'mutations.preview' | 'mutations.apply' | 'plan.execute' ? Awaited> : MethodReturn; } : never; }; type MethodInvokeRequest = OperationRegistry[T]['options'] extends never ? { operationId: T; input: OperationRegistry[T]['input']; options?: never; } : { operationId: T; input: OperationRegistry[T]['input']; options?: OperationRegistry[T]['options']; }; type AttributedInvokeRequest = T extends 'insert' ? { operationId: T; input: InsertInput; options: TrackedRichContentMutationOptions & OperationCancellation; } : T extends 'replace' ? { operationId: T; input: Exclude; options: TrackedReplaceMutationOptions; } : never; /** Typed invoke request narrowed by `operationId` and supported content shape. */ export type InvokeRequest = MethodInvokeRequest | AttributedInvokeRequest; /** Typed invoke result narrowed by `operationId`. */ export type InvokeResult = T extends 'mutations.preview' | 'mutations.apply' ? Promise : T extends 'plan.execute' ? OperationRegistry[T]['output'] | Promise : OperationRegistry[T]['output']; export type OperationCall = InvokeRequest extends infer Request ? (Request extends unknown ? Omit : never) : never; export type OperationInput = InvokeRequest['input']; export type OperationOptions = Exclude['options'], undefined>; export type OperationOutput = Awaited>; /** Loose request for callers that resolve operation identity at runtime. */ export type DynamicInvokeRequest = { operationId: OperationId; input: unknown; options?: unknown; }; export {};