@prisma-next/framework-components 0.10.0-dev.9 → 0.11.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.
@@ -1,2 +1,2 @@
1
- import { C as isAuthoringEntityTypeDescriptor, D as resolveAuthoringTemplateValue, E as mergeAuthoringNamespaces, O as validateAuthoringHelperArguments, S as isAuthoringArgRef, T as isAuthoringTypeConstructorDescriptor, _ as assertNoCrossRegistryCollisions, a as AuthoringEntityContext, b as instantiateAuthoringFieldPreset, c as AuthoringEntityTypeNamespace, d as AuthoringFieldPresetDescriptor, f as AuthoringFieldPresetOutput, g as AuthoringTypeNamespace, h as AuthoringTypeConstructorDescriptor, i as AuthoringContributions, l as AuthoringEntityTypeTemplateOutput, m as AuthoringTemplateValue, n as AuthoringArgumentDescriptor, o as AuthoringEntityTypeDescriptor, p as AuthoringStorageTypeTemplate, r as AuthoringColumnDefaultTemplate, s as AuthoringEntityTypeFactoryOutput, t as AuthoringArgRef, u as AuthoringFieldNamespace, v as hasRegisteredFieldNamespace, w as isAuthoringFieldPresetDescriptor, x as instantiateAuthoringTypeConstructor, y as instantiateAuthoringEntityType } from "./framework-authoring-Bb_GEnzj.mjs";
1
+ import { C as isAuthoringEntityTypeDescriptor, D as resolveAuthoringTemplateValue, E as mergeAuthoringNamespaces, O as validateAuthoringHelperArguments, S as isAuthoringArgRef, T as isAuthoringTypeConstructorDescriptor, _ as assertNoCrossRegistryCollisions, a as AuthoringEntityContext, b as instantiateAuthoringFieldPreset, c as AuthoringEntityTypeNamespace, d as AuthoringFieldPresetDescriptor, f as AuthoringFieldPresetOutput, g as AuthoringTypeNamespace, h as AuthoringTypeConstructorDescriptor, i as AuthoringContributions, l as AuthoringEntityTypeTemplateOutput, m as AuthoringTemplateValue, n as AuthoringArgumentDescriptor, o as AuthoringEntityTypeDescriptor, p as AuthoringStorageTypeTemplate, r as AuthoringColumnDefaultTemplate, s as AuthoringEntityTypeFactoryOutput, t as AuthoringArgRef, u as AuthoringFieldNamespace, v as hasRegisteredFieldNamespace, w as isAuthoringFieldPresetDescriptor, x as instantiateAuthoringTypeConstructor, y as instantiateAuthoringEntityType } from "./framework-authoring-BPPe9C9D.mjs";
2
2
  export { type AuthoringArgRef, type AuthoringArgumentDescriptor, type AuthoringColumnDefaultTemplate, type AuthoringContributions, type AuthoringEntityContext, type AuthoringEntityTypeDescriptor, type AuthoringEntityTypeFactoryOutput, type AuthoringEntityTypeNamespace, type AuthoringEntityTypeTemplateOutput, type AuthoringFieldNamespace, type AuthoringFieldPresetDescriptor, type AuthoringFieldPresetOutput, type AuthoringStorageTypeTemplate, type AuthoringTemplateValue, type AuthoringTypeConstructorDescriptor, type AuthoringTypeNamespace, assertNoCrossRegistryCollisions, hasRegisteredFieldNamespace, instantiateAuthoringEntityType, instantiateAuthoringFieldPreset, instantiateAuthoringTypeConstructor, isAuthoringArgRef, isAuthoringEntityTypeDescriptor, isAuthoringFieldPresetDescriptor, isAuthoringTypeConstructorDescriptor, mergeAuthoringNamespaces, resolveAuthoringTemplateValue, validateAuthoringHelperArguments };
@@ -1,2 +1,2 @@
1
- import { S as checkContractComponentRequirements, _ as PackRefBase, a as ComponentMetadata, b as TargetInstance, c as DriverDescriptor, d as ExtensionDescriptor, f as ExtensionInstance, g as FamilyPackRef, h as FamilyInstance, i as ComponentDescriptor, l as DriverInstance, m as FamilyDescriptor, n as AdapterInstance, o as ContractComponentRequirementsCheckInput, p as ExtensionPackRef, r as AdapterPackRef, s as ContractComponentRequirementsCheckResult, t as AdapterDescriptor, u as DriverPackRef, v as TargetBoundComponentDescriptor, x as TargetPackRef, y as TargetDescriptor } from "./framework-components-DHhNhWFR.mjs";
1
+ import { S as checkContractComponentRequirements, _ as PackRefBase, a as ComponentMetadata, b as TargetInstance, c as DriverDescriptor, d as ExtensionDescriptor, f as ExtensionInstance, g as FamilyPackRef, h as FamilyInstance, i as ComponentDescriptor, l as DriverInstance, m as FamilyDescriptor, n as AdapterInstance, o as ContractComponentRequirementsCheckInput, p as ExtensionPackRef, r as AdapterPackRef, s as ContractComponentRequirementsCheckResult, t as AdapterDescriptor, u as DriverPackRef, v as TargetBoundComponentDescriptor, x as TargetPackRef, y as TargetDescriptor } from "./framework-components-CuoUhyB5.mjs";
2
2
  export { type AdapterDescriptor, type AdapterInstance, type AdapterPackRef, type ComponentDescriptor, type ComponentMetadata, type ContractComponentRequirementsCheckInput, type ContractComponentRequirementsCheckResult, type DriverDescriptor, type DriverInstance, type DriverPackRef, type ExtensionDescriptor, type ExtensionInstance, type ExtensionPackRef, type FamilyDescriptor, type FamilyInstance, type FamilyPackRef, type PackRefBase, type TargetBoundComponentDescriptor, type TargetDescriptor, type TargetInstance, type TargetPackRef, checkContractComponentRequirements };
@@ -1,6 +1,6 @@
1
- import { c as AuthoringEntityTypeNamespace, g as AuthoringTypeNamespace, i as AuthoringContributions, u as AuthoringFieldNamespace } from "./framework-authoring-Bb_GEnzj.mjs";
1
+ import { c as AuthoringEntityTypeNamespace, g as AuthoringTypeNamespace, i as AuthoringContributions, u as AuthoringFieldNamespace } from "./framework-authoring-BPPe9C9D.mjs";
2
2
  import { c as CodecLookup } from "./codec-BFOsuHKK.mjs";
3
- import { A as LoweredDefaultResult, C as ControlMutationDefaultEntry, D as DefaultFunctionLoweringHandler, E as DefaultFunctionLoweringContext, F as SourceSpan, M as MutationDefaultGeneratorDescriptor, N as ParsedDefaultFunctionCall, O as DefaultFunctionRegistry, P as SourceDiagnostic, T as ControlMutationDefaults, a as ComponentMetadata, b as TargetInstance, c as DriverDescriptor, d as ExtensionDescriptor, f as ExtensionInstance, h as FamilyInstance, j as LoweredDefaultValue, k as DefaultFunctionRegistryEntry, l as DriverInstance, m as FamilyDescriptor, n as AdapterInstance, t as AdapterDescriptor, v as TargetBoundComponentDescriptor, w as ControlMutationDefaultRegistry, y as TargetDescriptor } from "./framework-components-DHhNhWFR.mjs";
3
+ import { A as LoweredDefaultResult, C as ControlMutationDefaultEntry, D as DefaultFunctionLoweringHandler, E as DefaultFunctionLoweringContext, F as SourceSpan, M as MutationDefaultGeneratorDescriptor, N as ParsedDefaultFunctionCall, O as DefaultFunctionRegistry, P as SourceDiagnostic, T as ControlMutationDefaults, a as ComponentMetadata, b as TargetInstance, c as DriverDescriptor, d as ExtensionDescriptor, f as ExtensionInstance, h as FamilyInstance, j as LoweredDefaultValue, k as DefaultFunctionRegistryEntry, l as DriverInstance, m as FamilyDescriptor, n as AdapterInstance, t as AdapterDescriptor, v as TargetBoundComponentDescriptor, w as ControlMutationDefaultRegistry, y as TargetDescriptor } from "./framework-components-CuoUhyB5.mjs";
4
4
  import { t as TypesImportSpec } from "./types-import-spec-BxI5cSQy.mjs";
5
5
  import { t as EmissionSpi } from "./emission-types-CMv_053d.mjs";
6
6
  import { m as PslDocumentAst } from "./psl-ast-BDXL7iCg.mjs";
@@ -1,4 +1,4 @@
1
- import { b as TargetInstance, c as DriverDescriptor, d as ExtensionDescriptor, f as ExtensionInstance, h as FamilyInstance, l as DriverInstance, m as FamilyDescriptor, n as AdapterInstance, t as AdapterDescriptor, y as TargetDescriptor } from "./framework-components-DHhNhWFR.mjs";
1
+ import { b as TargetInstance, c as DriverDescriptor, d as ExtensionDescriptor, f as ExtensionInstance, h as FamilyInstance, l as DriverInstance, m as FamilyDescriptor, n as AdapterInstance, t as AdapterDescriptor, y as TargetDescriptor } from "./framework-components-CuoUhyB5.mjs";
2
2
 
3
3
  //#region src/execution/execution-instances.d.ts
4
4
  interface RuntimeFamilyInstance<TFamilyId extends string> extends FamilyInstance<TFamilyId> {}
@@ -1,4 +1,5 @@
1
1
  import { ColumnDefault, ExecutionMutationDefaultPhases } from "@prisma-next/contract/types";
2
+ import { Type } from "arktype";
2
3
 
3
4
  //#region src/shared/framework-authoring.d.ts
4
5
  type AuthoringArgRef = {
@@ -103,6 +104,18 @@ interface AuthoringEntityTypeDescriptor<Input = never, Output = unknown> {
103
104
  readonly discriminator: string;
104
105
  readonly args?: readonly AuthoringArgumentDescriptor[];
105
106
  readonly output: AuthoringEntityTypeTemplateOutput | AuthoringEntityTypeFactoryOutput<Input, Output>;
107
+ /**
108
+ * arktype schema fragment for one entry whose envelope `kind` matches
109
+ * this descriptor's {@link discriminator}. The family validator composes
110
+ * contributed fragments into the per-namespace entry schema at
111
+ * validator construction time so the structural check covers
112
+ * pack-introduced kinds without the family core hard-coding the schema.
113
+ *
114
+ * Hydration uses {@link AuthoringEntityTypeFactoryOutput.factory}
115
+ * directly — the wire shape conforms structurally to the factory's
116
+ * `Input` after `validatorSchema` validates it.
117
+ */
118
+ readonly validatorSchema?: Type<unknown>;
106
119
  }
107
120
  type AuthoringEntityTypeNamespace = {
108
121
  readonly [name: string]: AuthoringEntityTypeDescriptor | AuthoringEntityTypeNamespace;
@@ -167,4 +180,4 @@ declare function instantiateAuthoringFieldPreset(descriptor: AuthoringFieldPrese
167
180
  };
168
181
  //#endregion
169
182
  export { isAuthoringEntityTypeDescriptor as C, resolveAuthoringTemplateValue as D, mergeAuthoringNamespaces as E, validateAuthoringHelperArguments as O, isAuthoringArgRef as S, isAuthoringTypeConstructorDescriptor as T, assertNoCrossRegistryCollisions as _, AuthoringEntityContext as a, instantiateAuthoringFieldPreset as b, AuthoringEntityTypeNamespace as c, AuthoringFieldPresetDescriptor as d, AuthoringFieldPresetOutput as f, AuthoringTypeNamespace as g, AuthoringTypeConstructorDescriptor as h, AuthoringContributions as i, AuthoringEntityTypeTemplateOutput as l, AuthoringTemplateValue as m, AuthoringArgumentDescriptor as n, AuthoringEntityTypeDescriptor as o, AuthoringStorageTypeTemplate as p, AuthoringColumnDefaultTemplate as r, AuthoringEntityTypeFactoryOutput as s, AuthoringArgRef as t, AuthoringFieldNamespace as u, hasRegisteredFieldNamespace as v, isAuthoringFieldPresetDescriptor as w, instantiateAuthoringTypeConstructor as x, instantiateAuthoringEntityType as y };
170
- //# sourceMappingURL=framework-authoring-Bb_GEnzj.d.mts.map
183
+ //# sourceMappingURL=framework-authoring-BPPe9C9D.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-authoring-BPPe9C9D.d.mts","names":[],"sources":["../src/shared/framework-authoring.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"framework-authoring-DcEZ5Lin.mjs","names":[],"sources":["../src/shared/framework-authoring.ts"],"sourcesContent":["import type {\n ColumnDefault,\n ExecutionMutationDefaultPhases,\n ExecutionMutationDefaultValue,\n} from '@prisma-next/contract/types';\nimport {\n isColumnDefaultLiteralInputValue,\n isExecutionMutationDefaultValue,\n} from '@prisma-next/contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\nexport type AuthoringArgRef = {\n readonly kind: 'arg';\n readonly index: number;\n readonly path?: readonly string[];\n readonly default?: AuthoringTemplateValue;\n};\n\nexport type AuthoringTemplateValue =\n | string\n | number\n | boolean\n | null\n | AuthoringArgRef\n | readonly AuthoringTemplateValue[]\n | { readonly [key: string]: AuthoringTemplateValue };\n\ninterface AuthoringArgumentDescriptorCommon {\n readonly name?: string;\n readonly optional?: boolean;\n}\n\nexport type AuthoringArgumentDescriptor = AuthoringArgumentDescriptorCommon &\n (\n | { readonly kind: 'string' }\n | { readonly kind: 'boolean' }\n | {\n readonly kind: 'number';\n readonly integer?: boolean;\n readonly minimum?: number;\n readonly maximum?: number;\n }\n | { readonly kind: 'stringArray' }\n | {\n readonly kind: 'object';\n readonly properties: Record<string, AuthoringArgumentDescriptor>;\n }\n );\n\nexport interface AuthoringStorageTypeTemplate {\n readonly codecId: string;\n readonly nativeType: AuthoringTemplateValue;\n readonly typeParams?: Record<string, AuthoringTemplateValue>;\n}\n\nexport interface AuthoringTypeConstructorDescriptor {\n readonly kind: 'typeConstructor';\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output: AuthoringStorageTypeTemplate;\n}\n\nexport interface AuthoringColumnDefaultTemplateLiteral {\n readonly kind: 'literal';\n readonly value: AuthoringTemplateValue;\n}\n\nexport interface AuthoringColumnDefaultTemplateFunction {\n readonly kind: 'function';\n readonly expression: AuthoringTemplateValue;\n}\n\nexport type AuthoringColumnDefaultTemplate =\n | AuthoringColumnDefaultTemplateLiteral\n | AuthoringColumnDefaultTemplateFunction;\n\nexport interface AuthoringExecutionDefaultsTemplate {\n readonly onCreate?: AuthoringTemplateValue;\n readonly onUpdate?: AuthoringTemplateValue;\n}\n\nexport interface AuthoringFieldPresetOutput extends AuthoringStorageTypeTemplate {\n readonly nullable?: boolean;\n readonly default?: AuthoringColumnDefaultTemplate;\n readonly executionDefaults?: AuthoringExecutionDefaultsTemplate;\n readonly id?: boolean;\n readonly unique?: boolean;\n}\n\nexport interface AuthoringFieldPresetDescriptor {\n readonly kind: 'fieldPreset';\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output: AuthoringFieldPresetOutput;\n}\n\nexport type AuthoringTypeNamespace = {\n readonly [name: string]: AuthoringTypeConstructorDescriptor | AuthoringTypeNamespace;\n};\n\nexport type AuthoringFieldNamespace = {\n readonly [name: string]: AuthoringFieldPresetDescriptor | AuthoringFieldNamespace;\n};\n\n/**\n * Context surfaced to entity-type factories at call time. Currently a\n * placeholder — sharpened as concrete consumers (enum, namespace, …)\n * discover what the factory actually needs to read (codec lookup,\n * namespace registry, …).\n */\nexport interface AuthoringEntityContext {\n readonly family: string;\n readonly target: string;\n}\n\nexport interface AuthoringEntityTypeTemplateOutput {\n readonly template: AuthoringTemplateValue;\n}\n\n/**\n * Default `Input = never` is load-bearing for pack-bag-driven type\n * narrowing. Factory parameter positions are contravariant, so a pack\n * literal declaring `factory: (input: DemoEntityInput) => DemoEntity`\n * is only assignable to the base descriptor's factory shape if the\n * base's input is `never` (the bottom of the contravariant position).\n * The concrete input/output types are recovered at the helper-derivation\n * site via `EntityHelperFunction<Descriptor>`'s conditional inference,\n * which reads them from the pack's `as const` literal factory signature\n * — the base widening does not erase the literal because `satisfies`\n * does not widen the declared type.\n */\nexport interface AuthoringEntityTypeFactoryOutput<Input = never, Output = unknown> {\n readonly factory: (input: Input, ctx: AuthoringEntityContext) => Output;\n}\n\nexport interface AuthoringEntityTypeDescriptor<Input = never, Output = unknown> {\n readonly kind: 'entity';\n readonly discriminator: string;\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output:\n | AuthoringEntityTypeTemplateOutput\n | AuthoringEntityTypeFactoryOutput<Input, Output>;\n}\n\nexport type AuthoringEntityTypeNamespace = {\n readonly [name: string]: AuthoringEntityTypeDescriptor | AuthoringEntityTypeNamespace;\n};\n\nexport interface AuthoringContributions {\n readonly type?: AuthoringTypeNamespace;\n readonly field?: AuthoringFieldNamespace;\n readonly entityTypes?: AuthoringEntityTypeNamespace;\n}\n\nexport function isAuthoringArgRef(value: unknown): value is AuthoringArgRef {\n if (typeof value !== 'object' || value === null || (value as { kind?: unknown }).kind !== 'arg') {\n return false;\n }\n const { index, path } = value as { index?: unknown; path?: unknown };\n if (typeof index !== 'number' || !Number.isInteger(index) || index < 0) {\n return false;\n }\n if (path !== undefined && (!Array.isArray(path) || path.some((s) => typeof s !== 'string'))) {\n return false;\n }\n return true;\n}\n\nfunction isAuthoringTemplateRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function isAuthoringTypeConstructorDescriptor(\n value: unknown,\n): value is AuthoringTypeConstructorDescriptor {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { kind?: unknown }).kind === 'typeConstructor' &&\n typeof (value as { output?: unknown }).output === 'object' &&\n (value as { output?: unknown }).output !== null\n );\n}\n\nexport function isAuthoringFieldPresetDescriptor(\n value: unknown,\n): value is AuthoringFieldPresetDescriptor {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { kind?: unknown }).kind === 'fieldPreset' &&\n typeof (value as { output?: unknown }).output === 'object' &&\n (value as { output?: unknown }).output !== null\n );\n}\n\nexport function isAuthoringEntityTypeDescriptor(\n value: unknown,\n): value is AuthoringEntityTypeDescriptor {\n if (\n typeof value !== 'object' ||\n value === null ||\n (value as { kind?: unknown }).kind !== 'entity'\n ) {\n return false;\n }\n const discriminator = (value as { discriminator?: unknown }).discriminator;\n if (typeof discriminator !== 'string' || discriminator.length === 0) {\n return false;\n }\n const output = (value as { output?: unknown }).output;\n if (typeof output !== 'object' || output === null) {\n return false;\n }\n const factory = (output as { factory?: unknown }).factory;\n const template = (output as { template?: unknown }).template;\n return typeof factory === 'function' || template !== undefined;\n}\n\n/**\n * Returns true when `namespace` is a non-leaf key in `contributions.field`.\n *\n * `AuthoringFieldNamespace` permits a leaf descriptor at any depth — including\n * the root — so a top-level `field: { Foo: { kind: 'fieldPreset', ... } }`\n * registration must NOT be treated as a \"namespace\" with sub-paths. Callers\n * use this predicate to gate dot-namespaced lookups (e.g. PSL `@Foo.bar`).\n */\nexport function hasRegisteredFieldNamespace(\n contributions: AuthoringContributions | undefined,\n namespace: string,\n): boolean {\n if (contributions?.field === undefined || !Object.hasOwn(contributions.field, namespace)) {\n return false;\n }\n return !isAuthoringFieldPresetDescriptor(contributions.field[namespace]);\n}\n\nfunction isPlainNamespaceObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Merges `source` into `target` recursively at the descriptor-namespace\n * level. `leafGuard` decides which values are descriptors (terminal\n * merge points; same-path registrations across components are reported\n * as duplicates) versus sub-namespaces (recursion targets).\n *\n * Path segments are validated against prototype-pollution names\n * (`__proto__`, `constructor`, `prototype`). A value that is neither a\n * recognized leaf nor a plain object — e.g. a malformed descriptor\n * where the canonical leaf guard rejected it for missing `output` —\n * is reported as an invalid contribution rather than recursed into,\n * which would either silently mangle state or infinite-loop on\n * primitive properties.\n *\n * Within-registry duplicate detection is this walker's job;\n * cross-registry detection runs separately via\n * `assertNoCrossRegistryCollisions` after merging completes.\n */\nexport function mergeAuthoringNamespaces(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n path: readonly string[],\n leafGuard: (value: unknown) => boolean,\n label: string,\n): void {\n const assertSafePath = (currentPath: readonly string[]) => {\n const blockedSegment = currentPath.find(\n (segment) => segment === '__proto__' || segment === 'constructor' || segment === 'prototype',\n );\n if (blockedSegment) {\n throw new Error(\n `Invalid authoring ${label} helper \"${currentPath.join('.')}\". Helper path segments must not use \"${blockedSegment}\".`,\n );\n }\n };\n\n for (const [key, sourceValue] of Object.entries(source)) {\n const currentPath = [...path, key];\n assertSafePath(currentPath);\n const hasExistingValue = Object.hasOwn(target, key);\n const existingValue = hasExistingValue ? target[key] : undefined;\n\n if (!hasExistingValue) {\n target[key] = sourceValue;\n continue;\n }\n\n const existingIsLeaf = leafGuard(existingValue);\n const sourceIsLeaf = leafGuard(sourceValue);\n\n if (existingIsLeaf || sourceIsLeaf) {\n throw new Error(\n `Duplicate authoring ${label} helper \"${currentPath.join('.')}\". Helper names must be unique across composed packs.`,\n );\n }\n\n if (!isPlainNamespaceObject(existingValue) || !isPlainNamespaceObject(sourceValue)) {\n throw new Error(\n `Invalid authoring ${label} helper \"${currentPath.join('.')}\". Expected a sub-namespace object or a recognized descriptor; received a malformed value.`,\n );\n }\n\n mergeAuthoringNamespaces(existingValue, sourceValue, currentPath, leafGuard, label);\n }\n}\n\nfunction collectAuthoringLeafPaths(\n namespace: Readonly<Record<string, unknown>>,\n isLeaf: (value: unknown) => boolean,\n path: readonly string[] = [],\n): string[] {\n const paths: string[] = [];\n for (const [key, value] of Object.entries(namespace)) {\n const currentPath = [...path, key];\n if (isLeaf(value)) {\n paths.push(currentPath.join('.'));\n continue;\n }\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n paths.push(\n ...collectAuthoringLeafPaths(\n value as Readonly<Record<string, unknown>>,\n isLeaf,\n currentPath,\n ),\n );\n }\n }\n return paths;\n}\n\nexport function assertNoCrossRegistryCollisions(\n typeNamespace: AuthoringTypeNamespace,\n fieldNamespace: AuthoringFieldNamespace,\n entityTypeNamespace: AuthoringEntityTypeNamespace = {},\n): void {\n const typePaths = new Set(\n collectAuthoringLeafPaths(typeNamespace, isAuthoringTypeConstructorDescriptor),\n );\n const fieldPaths = new Set(\n collectAuthoringLeafPaths(fieldNamespace, isAuthoringFieldPresetDescriptor),\n );\n const entityPaths = new Set(\n collectAuthoringLeafPaths(entityTypeNamespace, isAuthoringEntityTypeDescriptor),\n );\n // Within-registry duplicate detection is handled upstream by the merge\n // walker (`mergeAuthoringNamespaces` in control-stack.ts and\n // `mergeHelperNamespaces` in composed-authoring-helpers.ts), which throws\n // on same-path registrations within any single registry before this check\n // runs. This function only handles the cross-registry case.\n for (const fieldPath of fieldPaths) {\n if (typePaths.has(fieldPath)) {\n throw new Error(\n `Ambiguous authoring registry path \"${fieldPath}\". The same path is registered as both a type constructor and a field preset; PSL resolution would be ambiguous. Register each path in only one of authoringContributions.field / authoringContributions.type / authoringContributions.entityTypes.`,\n );\n }\n }\n for (const entityPath of entityPaths) {\n if (typePaths.has(entityPath) || fieldPaths.has(entityPath)) {\n throw new Error(\n `Ambiguous authoring registry path \"${entityPath}\". The same path is registered as an entity contribution AND as a type constructor or field preset; PSL resolution would be ambiguous. Register each path in only one of authoringContributions.field / authoringContributions.type / authoringContributions.entityTypes.`,\n );\n }\n }\n}\n\nexport function resolveAuthoringTemplateValue(\n template: AuthoringTemplateValue,\n args: readonly unknown[],\n): unknown {\n if (isAuthoringArgRef(template)) {\n let value = args[template.index];\n\n for (const segment of template.path ?? []) {\n if (!isAuthoringTemplateRecord(value) || !Object.hasOwn(value, segment)) {\n value = undefined;\n break;\n }\n value = (value as Record<string, unknown>)[segment];\n }\n\n if (value === undefined && template.default !== undefined) {\n return resolveAuthoringTemplateValue(template.default, args);\n }\n\n return value;\n }\n if (Array.isArray(template)) {\n return template.map((value) => resolveAuthoringTemplateValue(value, args));\n }\n if (typeof template === 'object' && template !== null) {\n const resolved: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(template)) {\n const resolvedValue = resolveAuthoringTemplateValue(value, args);\n if (resolvedValue !== undefined) {\n resolved[key] = resolvedValue;\n }\n }\n return resolved;\n }\n return template;\n}\n\nfunction validateAuthoringArgument(\n descriptor: AuthoringArgumentDescriptor,\n value: unknown,\n path: string,\n): void {\n if (value === undefined) {\n if (descriptor.optional) {\n return;\n }\n throw new Error(`Missing required authoring helper argument at ${path}`);\n }\n\n if (descriptor.kind === 'string') {\n if (typeof value !== 'string') {\n throw new Error(`Authoring helper argument at ${path} must be a string`);\n }\n return;\n }\n\n if (descriptor.kind === 'boolean') {\n if (typeof value !== 'boolean') {\n throw new Error(`Authoring helper argument at ${path} must be a boolean`);\n }\n return;\n }\n\n if (descriptor.kind === 'stringArray') {\n if (!Array.isArray(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an array of strings`);\n }\n for (const entry of value) {\n if (typeof entry !== 'string') {\n throw new Error(`Authoring helper argument at ${path} must be an array of strings`);\n }\n }\n return;\n }\n\n if (descriptor.kind === 'object') {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an object`);\n }\n\n const input = value as Record<string, unknown>;\n const expectedKeys = new Set(Object.keys(descriptor.properties));\n\n for (const key of Object.keys(input)) {\n if (!expectedKeys.has(key)) {\n throw new Error(`Authoring helper argument at ${path} contains unknown property \"${key}\"`);\n }\n }\n\n for (const [key, propertyDescriptor] of Object.entries(descriptor.properties)) {\n validateAuthoringArgument(propertyDescriptor, input[key], `${path}.${key}`);\n }\n\n return;\n }\n\n if (typeof value !== 'number' || Number.isNaN(value)) {\n throw new Error(`Authoring helper argument at ${path} must be a number`);\n }\n\n if (descriptor.integer && !Number.isInteger(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an integer`);\n }\n if (descriptor.minimum !== undefined && value < descriptor.minimum) {\n throw new Error(\n `Authoring helper argument at ${path} must be >= ${descriptor.minimum}, received ${value}`,\n );\n }\n if (descriptor.maximum !== undefined && value > descriptor.maximum) {\n throw new Error(\n `Authoring helper argument at ${path} must be <= ${descriptor.maximum}, received ${value}`,\n );\n }\n}\n\nexport function validateAuthoringHelperArguments(\n helperPath: string,\n descriptors: readonly AuthoringArgumentDescriptor[] | undefined,\n args: readonly unknown[],\n): void {\n const expected = descriptors ?? [];\n const minimumArgs = expected.reduce(\n (count, descriptor, index) => (descriptor.optional ? count : index + 1),\n 0,\n );\n if (args.length < minimumArgs || args.length > expected.length) {\n throw new Error(\n `${helperPath} expects ${minimumArgs === expected.length ? expected.length : `${minimumArgs}-${expected.length}`} argument(s), received ${args.length}`,\n );\n }\n\n expected.forEach((descriptor, index) => {\n validateAuthoringArgument(descriptor, args[index], `${helperPath}[${index}]`);\n });\n}\n\nfunction resolveAuthoringStorageTypeTemplate(\n template: AuthoringStorageTypeTemplate,\n args: readonly unknown[],\n): {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n} {\n const nativeType = resolveAuthoringTemplateValue(template.nativeType, args);\n if (typeof nativeType !== 'string') {\n throw new Error(\n `Resolved authoring nativeType must be a string for codec \"${template.codecId}\", received ${String(nativeType)}`,\n );\n }\n const typeParams =\n template.typeParams === undefined\n ? undefined\n : resolveAuthoringTemplateValue(template.typeParams, args);\n if (typeParams !== undefined && !isAuthoringTemplateRecord(typeParams)) {\n throw new Error(\n `Resolved authoring typeParams must be an object for codec \"${template.codecId}\", received ${String(typeParams)}`,\n );\n }\n\n return {\n codecId: template.codecId,\n nativeType,\n ...(typeParams === undefined ? {} : { typeParams }),\n };\n}\n\nfunction resolveAuthoringColumnDefaultTemplate(\n template: AuthoringColumnDefaultTemplate,\n args: readonly unknown[],\n): ColumnDefault {\n if (template.kind === 'literal') {\n const value = resolveAuthoringTemplateValue(template.value, args);\n if (value === undefined) {\n throw new Error('Resolved authoring literal default must not be undefined');\n }\n if (!isColumnDefaultLiteralInputValue(value)) {\n throw new Error(\n `Resolved authoring literal default must be a JSON-serializable value or Date, received ${String(value)}`,\n );\n }\n return {\n kind: 'literal',\n value,\n };\n }\n\n const expression = resolveAuthoringTemplateValue(template.expression, args);\n if (expression === undefined || (typeof expression === 'object' && expression !== null)) {\n throw new Error(\n `Resolved authoring function default expression must resolve to a primitive, received ${String(expression)}`,\n );\n }\n return {\n kind: 'function',\n expression: String(expression),\n };\n}\n\nfunction resolveExecutionMutationDefaultPhase(\n phase: 'onCreate' | 'onUpdate',\n template: AuthoringTemplateValue,\n args: readonly unknown[],\n): ExecutionMutationDefaultValue {\n const value = resolveAuthoringTemplateValue(template, args);\n if (!isExecutionMutationDefaultValue(value)) {\n throw new Error(\n `Authoring preset executionDefaults.${phase} did not resolve to a valid generator descriptor (kind: 'generator', id: string).`,\n );\n }\n return value;\n}\n\nfunction resolveAuthoringExecutionDefaultsTemplate(\n template: AuthoringExecutionDefaultsTemplate,\n args: readonly unknown[],\n): ExecutionMutationDefaultPhases {\n return {\n ...ifDefined(\n 'onCreate',\n template.onCreate !== undefined\n ? resolveExecutionMutationDefaultPhase('onCreate', template.onCreate, args)\n : undefined,\n ),\n ...ifDefined(\n 'onUpdate',\n template.onUpdate !== undefined\n ? resolveExecutionMutationDefaultPhase('onUpdate', template.onUpdate, args)\n : undefined,\n ),\n };\n}\n\nexport function instantiateAuthoringTypeConstructor(\n descriptor: AuthoringTypeConstructorDescriptor,\n args: readonly unknown[],\n): {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n} {\n return resolveAuthoringStorageTypeTemplate(descriptor.output, args);\n}\n\nexport function instantiateAuthoringEntityType(\n helperPath: string,\n descriptor: AuthoringEntityTypeDescriptor,\n args: readonly unknown[],\n ctx: AuthoringEntityContext,\n): unknown {\n // Factory-output entities carry their input contract on the factory\n // signature itself — TypeScript narrows callers via\n // `EntityHelperFunction`'s extracted `input` parameter, and the factory\n // is free to do its own runtime validation (e.g. arktype Type). The\n // descriptor-level `args` validator is reserved for template-output\n // entities (which mirror field/type's declarative argument shape).\n if ('factory' in descriptor.output) {\n const input = args[0];\n // The base `AuthoringEntityTypeDescriptor`'s factory is typed\n // `(input: never, ctx) => unknown` so concrete pack-literal factories\n // with narrower input types remain assignable through the\n // contravariant position (see the type's docstring). The runtime\n // delegates input validation to the pack's factory itself, so we\n // forward the supplied input here without a static input contract.\n const factory = descriptor.output.factory as (\n input: unknown,\n ctx: AuthoringEntityContext,\n ) => unknown;\n return factory(input, ctx);\n }\n validateAuthoringHelperArguments(helperPath, descriptor.args, args);\n return resolveAuthoringTemplateValue(descriptor.output.template, args);\n}\n\nexport function instantiateAuthoringFieldPreset(\n descriptor: AuthoringFieldPresetDescriptor,\n args: readonly unknown[],\n): {\n readonly descriptor: {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n };\n readonly nullable: boolean;\n readonly default?: ColumnDefault;\n readonly executionDefaults?: ExecutionMutationDefaultPhases;\n readonly id: boolean;\n readonly unique: boolean;\n} {\n return {\n descriptor: resolveAuthoringStorageTypeTemplate(descriptor.output, args),\n nullable: descriptor.output.nullable ?? false,\n ...ifDefined(\n 'default',\n descriptor.output.default !== undefined\n ? resolveAuthoringColumnDefaultTemplate(descriptor.output.default, args)\n : undefined,\n ),\n ...ifDefined(\n 'executionDefaults',\n descriptor.output.executionDefaults !== undefined\n ? resolveAuthoringExecutionDefaultsTemplate(descriptor.output.executionDefaults, args)\n : undefined,\n ),\n id: descriptor.output.id ?? false,\n unique: descriptor.output.unique ?? false,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"framework-authoring-DcEZ5Lin.mjs","names":[],"sources":["../src/shared/framework-authoring.ts"],"sourcesContent":["import type {\n ColumnDefault,\n ExecutionMutationDefaultPhases,\n ExecutionMutationDefaultValue,\n} from '@prisma-next/contract/types';\nimport {\n isColumnDefaultLiteralInputValue,\n isExecutionMutationDefaultValue,\n} from '@prisma-next/contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { Type } from 'arktype';\n\nexport type AuthoringArgRef = {\n readonly kind: 'arg';\n readonly index: number;\n readonly path?: readonly string[];\n readonly default?: AuthoringTemplateValue;\n};\n\nexport type AuthoringTemplateValue =\n | string\n | number\n | boolean\n | null\n | AuthoringArgRef\n | readonly AuthoringTemplateValue[]\n | { readonly [key: string]: AuthoringTemplateValue };\n\ninterface AuthoringArgumentDescriptorCommon {\n readonly name?: string;\n readonly optional?: boolean;\n}\n\nexport type AuthoringArgumentDescriptor = AuthoringArgumentDescriptorCommon &\n (\n | { readonly kind: 'string' }\n | { readonly kind: 'boolean' }\n | {\n readonly kind: 'number';\n readonly integer?: boolean;\n readonly minimum?: number;\n readonly maximum?: number;\n }\n | { readonly kind: 'stringArray' }\n | {\n readonly kind: 'object';\n readonly properties: Record<string, AuthoringArgumentDescriptor>;\n }\n );\n\nexport interface AuthoringStorageTypeTemplate {\n readonly codecId: string;\n readonly nativeType: AuthoringTemplateValue;\n readonly typeParams?: Record<string, AuthoringTemplateValue>;\n}\n\nexport interface AuthoringTypeConstructorDescriptor {\n readonly kind: 'typeConstructor';\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output: AuthoringStorageTypeTemplate;\n}\n\nexport interface AuthoringColumnDefaultTemplateLiteral {\n readonly kind: 'literal';\n readonly value: AuthoringTemplateValue;\n}\n\nexport interface AuthoringColumnDefaultTemplateFunction {\n readonly kind: 'function';\n readonly expression: AuthoringTemplateValue;\n}\n\nexport type AuthoringColumnDefaultTemplate =\n | AuthoringColumnDefaultTemplateLiteral\n | AuthoringColumnDefaultTemplateFunction;\n\nexport interface AuthoringExecutionDefaultsTemplate {\n readonly onCreate?: AuthoringTemplateValue;\n readonly onUpdate?: AuthoringTemplateValue;\n}\n\nexport interface AuthoringFieldPresetOutput extends AuthoringStorageTypeTemplate {\n readonly nullable?: boolean;\n readonly default?: AuthoringColumnDefaultTemplate;\n readonly executionDefaults?: AuthoringExecutionDefaultsTemplate;\n readonly id?: boolean;\n readonly unique?: boolean;\n}\n\nexport interface AuthoringFieldPresetDescriptor {\n readonly kind: 'fieldPreset';\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output: AuthoringFieldPresetOutput;\n}\n\nexport type AuthoringTypeNamespace = {\n readonly [name: string]: AuthoringTypeConstructorDescriptor | AuthoringTypeNamespace;\n};\n\nexport type AuthoringFieldNamespace = {\n readonly [name: string]: AuthoringFieldPresetDescriptor | AuthoringFieldNamespace;\n};\n\n/**\n * Context surfaced to entity-type factories at call time. Currently a\n * placeholder — sharpened as concrete consumers (enum, namespace, …)\n * discover what the factory actually needs to read (codec lookup,\n * namespace registry, …).\n */\nexport interface AuthoringEntityContext {\n readonly family: string;\n readonly target: string;\n}\n\nexport interface AuthoringEntityTypeTemplateOutput {\n readonly template: AuthoringTemplateValue;\n}\n\n/**\n * Default `Input = never` is load-bearing for pack-bag-driven type\n * narrowing. Factory parameter positions are contravariant, so a pack\n * literal declaring `factory: (input: DemoEntityInput) => DemoEntity`\n * is only assignable to the base descriptor's factory shape if the\n * base's input is `never` (the bottom of the contravariant position).\n * The concrete input/output types are recovered at the helper-derivation\n * site via `EntityHelperFunction<Descriptor>`'s conditional inference,\n * which reads them from the pack's `as const` literal factory signature\n * — the base widening does not erase the literal because `satisfies`\n * does not widen the declared type.\n */\nexport interface AuthoringEntityTypeFactoryOutput<Input = never, Output = unknown> {\n readonly factory: (input: Input, ctx: AuthoringEntityContext) => Output;\n}\n\nexport interface AuthoringEntityTypeDescriptor<Input = never, Output = unknown> {\n readonly kind: 'entity';\n readonly discriminator: string;\n readonly args?: readonly AuthoringArgumentDescriptor[];\n readonly output:\n | AuthoringEntityTypeTemplateOutput\n | AuthoringEntityTypeFactoryOutput<Input, Output>;\n /**\n * arktype schema fragment for one entry whose envelope `kind` matches\n * this descriptor's {@link discriminator}. The family validator composes\n * contributed fragments into the per-namespace entry schema at\n * validator construction time so the structural check covers\n * pack-introduced kinds without the family core hard-coding the schema.\n *\n * Hydration uses {@link AuthoringEntityTypeFactoryOutput.factory}\n * directly — the wire shape conforms structurally to the factory's\n * `Input` after `validatorSchema` validates it.\n */\n readonly validatorSchema?: Type<unknown>;\n}\n\nexport type AuthoringEntityTypeNamespace = {\n readonly [name: string]: AuthoringEntityTypeDescriptor | AuthoringEntityTypeNamespace;\n};\n\nexport interface AuthoringContributions {\n readonly type?: AuthoringTypeNamespace;\n readonly field?: AuthoringFieldNamespace;\n readonly entityTypes?: AuthoringEntityTypeNamespace;\n}\n\nexport function isAuthoringArgRef(value: unknown): value is AuthoringArgRef {\n if (typeof value !== 'object' || value === null || (value as { kind?: unknown }).kind !== 'arg') {\n return false;\n }\n const { index, path } = value as { index?: unknown; path?: unknown };\n if (typeof index !== 'number' || !Number.isInteger(index) || index < 0) {\n return false;\n }\n if (path !== undefined && (!Array.isArray(path) || path.some((s) => typeof s !== 'string'))) {\n return false;\n }\n return true;\n}\n\nfunction isAuthoringTemplateRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function isAuthoringTypeConstructorDescriptor(\n value: unknown,\n): value is AuthoringTypeConstructorDescriptor {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { kind?: unknown }).kind === 'typeConstructor' &&\n typeof (value as { output?: unknown }).output === 'object' &&\n (value as { output?: unknown }).output !== null\n );\n}\n\nexport function isAuthoringFieldPresetDescriptor(\n value: unknown,\n): value is AuthoringFieldPresetDescriptor {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { kind?: unknown }).kind === 'fieldPreset' &&\n typeof (value as { output?: unknown }).output === 'object' &&\n (value as { output?: unknown }).output !== null\n );\n}\n\nexport function isAuthoringEntityTypeDescriptor(\n value: unknown,\n): value is AuthoringEntityTypeDescriptor {\n if (\n typeof value !== 'object' ||\n value === null ||\n (value as { kind?: unknown }).kind !== 'entity'\n ) {\n return false;\n }\n const discriminator = (value as { discriminator?: unknown }).discriminator;\n if (typeof discriminator !== 'string' || discriminator.length === 0) {\n return false;\n }\n const output = (value as { output?: unknown }).output;\n if (typeof output !== 'object' || output === null) {\n return false;\n }\n const factory = (output as { factory?: unknown }).factory;\n const template = (output as { template?: unknown }).template;\n return typeof factory === 'function' || template !== undefined;\n}\n\n/**\n * Returns true when `namespace` is a non-leaf key in `contributions.field`.\n *\n * `AuthoringFieldNamespace` permits a leaf descriptor at any depth — including\n * the root — so a top-level `field: { Foo: { kind: 'fieldPreset', ... } }`\n * registration must NOT be treated as a \"namespace\" with sub-paths. Callers\n * use this predicate to gate dot-namespaced lookups (e.g. PSL `@Foo.bar`).\n */\nexport function hasRegisteredFieldNamespace(\n contributions: AuthoringContributions | undefined,\n namespace: string,\n): boolean {\n if (contributions?.field === undefined || !Object.hasOwn(contributions.field, namespace)) {\n return false;\n }\n return !isAuthoringFieldPresetDescriptor(contributions.field[namespace]);\n}\n\nfunction isPlainNamespaceObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Merges `source` into `target` recursively at the descriptor-namespace\n * level. `leafGuard` decides which values are descriptors (terminal\n * merge points; same-path registrations across components are reported\n * as duplicates) versus sub-namespaces (recursion targets).\n *\n * Path segments are validated against prototype-pollution names\n * (`__proto__`, `constructor`, `prototype`). A value that is neither a\n * recognized leaf nor a plain object — e.g. a malformed descriptor\n * where the canonical leaf guard rejected it for missing `output` —\n * is reported as an invalid contribution rather than recursed into,\n * which would either silently mangle state or infinite-loop on\n * primitive properties.\n *\n * Within-registry duplicate detection is this walker's job;\n * cross-registry detection runs separately via\n * `assertNoCrossRegistryCollisions` after merging completes.\n */\nexport function mergeAuthoringNamespaces(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n path: readonly string[],\n leafGuard: (value: unknown) => boolean,\n label: string,\n): void {\n const assertSafePath = (currentPath: readonly string[]) => {\n const blockedSegment = currentPath.find(\n (segment) => segment === '__proto__' || segment === 'constructor' || segment === 'prototype',\n );\n if (blockedSegment) {\n throw new Error(\n `Invalid authoring ${label} helper \"${currentPath.join('.')}\". Helper path segments must not use \"${blockedSegment}\".`,\n );\n }\n };\n\n for (const [key, sourceValue] of Object.entries(source)) {\n const currentPath = [...path, key];\n assertSafePath(currentPath);\n const hasExistingValue = Object.hasOwn(target, key);\n const existingValue = hasExistingValue ? target[key] : undefined;\n\n if (!hasExistingValue) {\n target[key] = sourceValue;\n continue;\n }\n\n const existingIsLeaf = leafGuard(existingValue);\n const sourceIsLeaf = leafGuard(sourceValue);\n\n if (existingIsLeaf || sourceIsLeaf) {\n throw new Error(\n `Duplicate authoring ${label} helper \"${currentPath.join('.')}\". Helper names must be unique across composed packs.`,\n );\n }\n\n if (!isPlainNamespaceObject(existingValue) || !isPlainNamespaceObject(sourceValue)) {\n throw new Error(\n `Invalid authoring ${label} helper \"${currentPath.join('.')}\". Expected a sub-namespace object or a recognized descriptor; received a malformed value.`,\n );\n }\n\n mergeAuthoringNamespaces(existingValue, sourceValue, currentPath, leafGuard, label);\n }\n}\n\nfunction collectAuthoringLeafPaths(\n namespace: Readonly<Record<string, unknown>>,\n isLeaf: (value: unknown) => boolean,\n path: readonly string[] = [],\n): string[] {\n const paths: string[] = [];\n for (const [key, value] of Object.entries(namespace)) {\n const currentPath = [...path, key];\n if (isLeaf(value)) {\n paths.push(currentPath.join('.'));\n continue;\n }\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n paths.push(\n ...collectAuthoringLeafPaths(\n value as Readonly<Record<string, unknown>>,\n isLeaf,\n currentPath,\n ),\n );\n }\n }\n return paths;\n}\n\nexport function assertNoCrossRegistryCollisions(\n typeNamespace: AuthoringTypeNamespace,\n fieldNamespace: AuthoringFieldNamespace,\n entityTypeNamespace: AuthoringEntityTypeNamespace = {},\n): void {\n const typePaths = new Set(\n collectAuthoringLeafPaths(typeNamespace, isAuthoringTypeConstructorDescriptor),\n );\n const fieldPaths = new Set(\n collectAuthoringLeafPaths(fieldNamespace, isAuthoringFieldPresetDescriptor),\n );\n const entityPaths = new Set(\n collectAuthoringLeafPaths(entityTypeNamespace, isAuthoringEntityTypeDescriptor),\n );\n // Within-registry duplicate detection is handled upstream by the merge\n // walker (`mergeAuthoringNamespaces` in control-stack.ts and\n // `mergeHelperNamespaces` in composed-authoring-helpers.ts), which throws\n // on same-path registrations within any single registry before this check\n // runs. This function only handles the cross-registry case.\n for (const fieldPath of fieldPaths) {\n if (typePaths.has(fieldPath)) {\n throw new Error(\n `Ambiguous authoring registry path \"${fieldPath}\". The same path is registered as both a type constructor and a field preset; PSL resolution would be ambiguous. Register each path in only one of authoringContributions.field / authoringContributions.type / authoringContributions.entityTypes.`,\n );\n }\n }\n for (const entityPath of entityPaths) {\n if (typePaths.has(entityPath) || fieldPaths.has(entityPath)) {\n throw new Error(\n `Ambiguous authoring registry path \"${entityPath}\". The same path is registered as an entity contribution AND as a type constructor or field preset; PSL resolution would be ambiguous. Register each path in only one of authoringContributions.field / authoringContributions.type / authoringContributions.entityTypes.`,\n );\n }\n }\n}\n\nexport function resolveAuthoringTemplateValue(\n template: AuthoringTemplateValue,\n args: readonly unknown[],\n): unknown {\n if (isAuthoringArgRef(template)) {\n let value = args[template.index];\n\n for (const segment of template.path ?? []) {\n if (!isAuthoringTemplateRecord(value) || !Object.hasOwn(value, segment)) {\n value = undefined;\n break;\n }\n value = (value as Record<string, unknown>)[segment];\n }\n\n if (value === undefined && template.default !== undefined) {\n return resolveAuthoringTemplateValue(template.default, args);\n }\n\n return value;\n }\n if (Array.isArray(template)) {\n return template.map((value) => resolveAuthoringTemplateValue(value, args));\n }\n if (typeof template === 'object' && template !== null) {\n const resolved: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(template)) {\n const resolvedValue = resolveAuthoringTemplateValue(value, args);\n if (resolvedValue !== undefined) {\n resolved[key] = resolvedValue;\n }\n }\n return resolved;\n }\n return template;\n}\n\nfunction validateAuthoringArgument(\n descriptor: AuthoringArgumentDescriptor,\n value: unknown,\n path: string,\n): void {\n if (value === undefined) {\n if (descriptor.optional) {\n return;\n }\n throw new Error(`Missing required authoring helper argument at ${path}`);\n }\n\n if (descriptor.kind === 'string') {\n if (typeof value !== 'string') {\n throw new Error(`Authoring helper argument at ${path} must be a string`);\n }\n return;\n }\n\n if (descriptor.kind === 'boolean') {\n if (typeof value !== 'boolean') {\n throw new Error(`Authoring helper argument at ${path} must be a boolean`);\n }\n return;\n }\n\n if (descriptor.kind === 'stringArray') {\n if (!Array.isArray(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an array of strings`);\n }\n for (const entry of value) {\n if (typeof entry !== 'string') {\n throw new Error(`Authoring helper argument at ${path} must be an array of strings`);\n }\n }\n return;\n }\n\n if (descriptor.kind === 'object') {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an object`);\n }\n\n const input = value as Record<string, unknown>;\n const expectedKeys = new Set(Object.keys(descriptor.properties));\n\n for (const key of Object.keys(input)) {\n if (!expectedKeys.has(key)) {\n throw new Error(`Authoring helper argument at ${path} contains unknown property \"${key}\"`);\n }\n }\n\n for (const [key, propertyDescriptor] of Object.entries(descriptor.properties)) {\n validateAuthoringArgument(propertyDescriptor, input[key], `${path}.${key}`);\n }\n\n return;\n }\n\n if (typeof value !== 'number' || Number.isNaN(value)) {\n throw new Error(`Authoring helper argument at ${path} must be a number`);\n }\n\n if (descriptor.integer && !Number.isInteger(value)) {\n throw new Error(`Authoring helper argument at ${path} must be an integer`);\n }\n if (descriptor.minimum !== undefined && value < descriptor.minimum) {\n throw new Error(\n `Authoring helper argument at ${path} must be >= ${descriptor.minimum}, received ${value}`,\n );\n }\n if (descriptor.maximum !== undefined && value > descriptor.maximum) {\n throw new Error(\n `Authoring helper argument at ${path} must be <= ${descriptor.maximum}, received ${value}`,\n );\n }\n}\n\nexport function validateAuthoringHelperArguments(\n helperPath: string,\n descriptors: readonly AuthoringArgumentDescriptor[] | undefined,\n args: readonly unknown[],\n): void {\n const expected = descriptors ?? [];\n const minimumArgs = expected.reduce(\n (count, descriptor, index) => (descriptor.optional ? count : index + 1),\n 0,\n );\n if (args.length < minimumArgs || args.length > expected.length) {\n throw new Error(\n `${helperPath} expects ${minimumArgs === expected.length ? expected.length : `${minimumArgs}-${expected.length}`} argument(s), received ${args.length}`,\n );\n }\n\n expected.forEach((descriptor, index) => {\n validateAuthoringArgument(descriptor, args[index], `${helperPath}[${index}]`);\n });\n}\n\nfunction resolveAuthoringStorageTypeTemplate(\n template: AuthoringStorageTypeTemplate,\n args: readonly unknown[],\n): {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n} {\n const nativeType = resolveAuthoringTemplateValue(template.nativeType, args);\n if (typeof nativeType !== 'string') {\n throw new Error(\n `Resolved authoring nativeType must be a string for codec \"${template.codecId}\", received ${String(nativeType)}`,\n );\n }\n const typeParams =\n template.typeParams === undefined\n ? undefined\n : resolveAuthoringTemplateValue(template.typeParams, args);\n if (typeParams !== undefined && !isAuthoringTemplateRecord(typeParams)) {\n throw new Error(\n `Resolved authoring typeParams must be an object for codec \"${template.codecId}\", received ${String(typeParams)}`,\n );\n }\n\n return {\n codecId: template.codecId,\n nativeType,\n ...(typeParams === undefined ? {} : { typeParams }),\n };\n}\n\nfunction resolveAuthoringColumnDefaultTemplate(\n template: AuthoringColumnDefaultTemplate,\n args: readonly unknown[],\n): ColumnDefault {\n if (template.kind === 'literal') {\n const value = resolveAuthoringTemplateValue(template.value, args);\n if (value === undefined) {\n throw new Error('Resolved authoring literal default must not be undefined');\n }\n if (!isColumnDefaultLiteralInputValue(value)) {\n throw new Error(\n `Resolved authoring literal default must be a JSON-serializable value or Date, received ${String(value)}`,\n );\n }\n return {\n kind: 'literal',\n value,\n };\n }\n\n const expression = resolveAuthoringTemplateValue(template.expression, args);\n if (expression === undefined || (typeof expression === 'object' && expression !== null)) {\n throw new Error(\n `Resolved authoring function default expression must resolve to a primitive, received ${String(expression)}`,\n );\n }\n return {\n kind: 'function',\n expression: String(expression),\n };\n}\n\nfunction resolveExecutionMutationDefaultPhase(\n phase: 'onCreate' | 'onUpdate',\n template: AuthoringTemplateValue,\n args: readonly unknown[],\n): ExecutionMutationDefaultValue {\n const value = resolveAuthoringTemplateValue(template, args);\n if (!isExecutionMutationDefaultValue(value)) {\n throw new Error(\n `Authoring preset executionDefaults.${phase} did not resolve to a valid generator descriptor (kind: 'generator', id: string).`,\n );\n }\n return value;\n}\n\nfunction resolveAuthoringExecutionDefaultsTemplate(\n template: AuthoringExecutionDefaultsTemplate,\n args: readonly unknown[],\n): ExecutionMutationDefaultPhases {\n return {\n ...ifDefined(\n 'onCreate',\n template.onCreate !== undefined\n ? resolveExecutionMutationDefaultPhase('onCreate', template.onCreate, args)\n : undefined,\n ),\n ...ifDefined(\n 'onUpdate',\n template.onUpdate !== undefined\n ? resolveExecutionMutationDefaultPhase('onUpdate', template.onUpdate, args)\n : undefined,\n ),\n };\n}\n\nexport function instantiateAuthoringTypeConstructor(\n descriptor: AuthoringTypeConstructorDescriptor,\n args: readonly unknown[],\n): {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n} {\n return resolveAuthoringStorageTypeTemplate(descriptor.output, args);\n}\n\nexport function instantiateAuthoringEntityType(\n helperPath: string,\n descriptor: AuthoringEntityTypeDescriptor,\n args: readonly unknown[],\n ctx: AuthoringEntityContext,\n): unknown {\n // Factory-output entities carry their input contract on the factory\n // signature itself — TypeScript narrows callers via\n // `EntityHelperFunction`'s extracted `input` parameter, and the factory\n // is free to do its own runtime validation (e.g. arktype Type). The\n // descriptor-level `args` validator is reserved for template-output\n // entities (which mirror field/type's declarative argument shape).\n if ('factory' in descriptor.output) {\n const input = args[0];\n // The base `AuthoringEntityTypeDescriptor`'s factory is typed\n // `(input: never, ctx) => unknown` so concrete pack-literal factories\n // with narrower input types remain assignable through the\n // contravariant position (see the type's docstring). The runtime\n // delegates input validation to the pack's factory itself, so we\n // forward the supplied input here without a static input contract.\n const factory = descriptor.output.factory as (\n input: unknown,\n ctx: AuthoringEntityContext,\n ) => unknown;\n return factory(input, ctx);\n }\n validateAuthoringHelperArguments(helperPath, descriptor.args, args);\n return resolveAuthoringTemplateValue(descriptor.output.template, args);\n}\n\nexport function instantiateAuthoringFieldPreset(\n descriptor: AuthoringFieldPresetDescriptor,\n args: readonly unknown[],\n): {\n readonly descriptor: {\n readonly codecId: string;\n readonly nativeType: string;\n readonly typeParams?: Record<string, unknown>;\n };\n readonly nullable: boolean;\n readonly default?: ColumnDefault;\n readonly executionDefaults?: ExecutionMutationDefaultPhases;\n readonly id: boolean;\n readonly unique: boolean;\n} {\n return {\n descriptor: resolveAuthoringStorageTypeTemplate(descriptor.output, args),\n nullable: descriptor.output.nullable ?? false,\n ...ifDefined(\n 'default',\n descriptor.output.default !== undefined\n ? resolveAuthoringColumnDefaultTemplate(descriptor.output.default, args)\n : undefined,\n ),\n ...ifDefined(\n 'executionDefaults',\n descriptor.output.executionDefaults !== undefined\n ? resolveAuthoringExecutionDefaultsTemplate(descriptor.output.executionDefaults, args)\n : undefined,\n ),\n id: descriptor.output.id ?? false,\n unique: descriptor.output.unique ?? false,\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { i as AuthoringContributions } from "./framework-authoring-Bb_GEnzj.mjs";
1
+ import { i as AuthoringContributions } from "./framework-authoring-BPPe9C9D.mjs";
2
2
  import { r as AnyCodecDescriptor } from "./codec-BFOsuHKK.mjs";
3
3
  import { t as TypesImportSpec } from "./types-import-spec-BxI5cSQy.mjs";
4
4
  import { ColumnDefault, ExecutionMutationDefaultPhases, ExecutionMutationDefaultValue } from "@prisma-next/contract/types";
@@ -408,4 +408,4 @@ interface ExtensionInstance<TFamilyId extends string, TTargetId extends string>
408
408
  }
409
409
  //#endregion
410
410
  export { LoweredDefaultResult as A, ControlMutationDefaultEntry as C, DefaultFunctionLoweringHandler as D, DefaultFunctionLoweringContext as E, SourceSpan as F, MutationDefaultGeneratorDescriptor as M, ParsedDefaultFunctionCall as N, DefaultFunctionRegistry as O, SourceDiagnostic as P, checkContractComponentRequirements as S, ControlMutationDefaults as T, PackRefBase as _, ComponentMetadata as a, TargetInstance as b, DriverDescriptor as c, ExtensionDescriptor as d, ExtensionInstance as f, FamilyPackRef as g, FamilyInstance as h, ComponentDescriptor as i, LoweredDefaultValue as j, DefaultFunctionRegistryEntry as k, DriverInstance as l, FamilyDescriptor as m, AdapterInstance as n, ContractComponentRequirementsCheckInput as o, ExtensionPackRef as p, AdapterPackRef as r, ContractComponentRequirementsCheckResult as s, AdapterDescriptor as t, DriverPackRef as u, TargetBoundComponentDescriptor as v, ControlMutationDefaultRegistry as w, TargetPackRef as x, TargetDescriptor as y };
411
- //# sourceMappingURL=framework-components-DHhNhWFR.d.mts.map
411
+ //# sourceMappingURL=framework-components-CuoUhyB5.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"framework-components-DHhNhWFR.d.mts","names":[],"sources":["../src/shared/mutation-default-types.ts","../src/shared/framework-components.ts"],"mappings":"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"}
1
+ {"version":3,"file":"framework-components-CuoUhyB5.d.mts","names":[],"sources":["../src/shared/mutation-default-types.ts","../src/shared/framework-components.ts"],"mappings":"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"}
package/dist/ir.d.mts CHANGED
@@ -99,15 +99,65 @@ declare const UNBOUND_NAMESPACE_ID: "__unbound__";
99
99
  * `tables`, Mongo contributes `collections`, future families pick their
100
100
  * own native idiom). Generic consumers walking "all named entries" go
101
101
  * through a family-typed namespace, not the framework `Namespace`.
102
+ *
103
+ * Every namespace concretion (e.g. `SqlNamespacePayload`,
104
+ * `MongoNamespacePayload`, target-promoted namespaces like
105
+ * `PostgresSchema`) carries exactly: `id` (enumerable string), `kind`
106
+ * (non-enumerable string discriminator set via `Object.defineProperty`),
107
+ * and one or more entity-kind slot maps — each an own-enumerable property
108
+ * whose key is the entity kind (`tables`, `types`, `collections`,
109
+ * target-pack-contributed slot names) and whose value is a
110
+ * `Record<entityName, EntityIRClass>`. No other own-enumerable data lives
111
+ * on a namespace; non-entity computed data lives on the surrounding storage
112
+ * or contract IR. The framework's `elementCoordinates(storage)` walk relies
113
+ * on this invariant to enumerate entities structurally without
114
+ * family-specific knowledge.
102
115
  */
103
116
  interface Namespace extends IRNode {
104
117
  readonly id: string;
118
+ readonly kind: string;
105
119
  }
106
120
  declare abstract class NamespaceBase extends IRNodeBase implements Namespace {
107
121
  abstract readonly id: string;
122
+ abstract readonly kind: string;
108
123
  }
109
124
  //#endregion
110
125
  //#region src/ir/storage.d.ts
126
+ /**
127
+ * Canonical address for a named entity in Contract IR / Schema IR.
128
+ *
129
+ * `plane` is `'domain' | 'storage'`: which top-level contract plane the
130
+ * entity lives on. Domain-side walks (once domain content is populated)
131
+ * yield `plane: 'domain'`; {@link elementCoordinates} over storage yields
132
+ * `plane: 'storage'`. A sibling `elementCoordinates(domain)` is not wired
133
+ * yet — domain-plane content lands in S1.C; the sibling walk lands there.
134
+ *
135
+ * Cross-plane references obey a directional invariant: domain → storage is
136
+ * allowed; storage → domain is forbidden. That rule is enforced by a
137
+ * separate validator, not by constraining this coordinate shape — the
138
+ * coordinate carries the axis the validator checks.
139
+ *
140
+ * Iteration order over namespace properties follows `Object.entries` order;
141
+ * consumers that depend on ordering must sort.
142
+ */
143
+ interface EntityCoordinate {
144
+ readonly plane: 'domain' | 'storage';
145
+ readonly namespaceId: string;
146
+ readonly entityKind: string;
147
+ readonly entityName: string;
148
+ }
149
+ /**
150
+ * Lazy walk over every named storage entity in a `Storage`-shaped
151
+ * value, yielded as {@link EntityCoordinate} tuples with
152
+ * `plane: 'storage'` (the parameter type binds the plane).
153
+ *
154
+ * Iterates each namespace's own-enumerable properties structurally.
155
+ * Skips `id` (known scalar); `kind` is non-enumerable on namespace
156
+ * concretions and does not appear in `Object.entries`. For every other
157
+ * property whose value is a non-null object, yields one coordinate per
158
+ * entry key in that map. No family-specific slot vocabulary is required.
159
+ */
160
+ declare function elementCoordinates(storage: Storage): Generator<EntityCoordinate>;
111
161
  /**
112
162
  * Framework-level promise that every Contract IR / Schema IR carries a
113
163
  * collection of namespaces keyed by namespace id. Family storage
@@ -170,5 +220,5 @@ interface StorageType extends IRNode {
170
220
  readonly kind: string;
171
221
  }
172
222
  //#endregion
173
- export { type IRNode, IRNodeBase, type Namespace, NamespaceBase, type Storage, type StorageType, UNBOUND_NAMESPACE_ID, freezeNode };
223
+ export { type EntityCoordinate, type IRNode, IRNodeBase, type Namespace, NamespaceBase, type Storage, type StorageType, UNBOUND_NAMESPACE_ID, elementCoordinates, freezeNode };
174
224
  //# sourceMappingURL=ir.d.mts.map
package/dist/ir.d.mts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/ir/ir-node.ts","../src/ir/namespace.ts","../src/ir/storage.ts","../src/ir/storage-type.ts"],"mappings":";;AAyCA;;;;;AAIA;;;;;AAaA;;;;;;;;;;;;;;;;;;ACjCA;;;;;AAqBA;;;;;AAIA;UDTiB,MAAA;EAAA,SACN,IAAA;AAAA;AAAA,uBAGW,UAAA,YAAsB,MAAA;EAAA,kBACxB,IAAA;AAAA;;;;;;AERpB;;;;iBFoBgB,UAAA,WAAqB,MAAA,CAAA,CAAQ,IAAA,EAAM,CAAA,GAAI,CAAA;;;AAjBvD;;;;;AAIA;;;;;AAaA;;;;;;;;;;;;;AAjBA,cChBa,oBAAA;;;;;AAAb;;;;;AAqBA;;;;;AAIA;;;;;UAJiB,SAAA,SAAkB,MAAA;EAAA,SACxB,EAAA;AAAA;AAAA,uBAGW,aAAA,SAAsB,UAAA,YAAsB,SAAA;EAAA,kBAC9C,EAAA;AAAA;;;;;;;ADNpB;;;;;AAaA;;;;;;;;;;;;;;;;;;ACjCA;;;;;AAqBA;;;UCRiB,OAAA,SAAgB,MAAA;EAAA,SACtB,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,SAAA;AAAA;;;AFE/C;;;;;AAIA;;;;;AAaA;;;;;;;;AAjBA,UGrBiB,WAAA,SAAoB,MAAA;EAAA,SAC1B,IAAA;AAAA"}
1
+ {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/ir/ir-node.ts","../src/ir/namespace.ts","../src/ir/storage.ts","../src/ir/storage-type.ts"],"mappings":";;AAyCA;;;;;AAIA;;;;;AAaA;;;;;;;;;;;;;;;;;;ACjCA;;;;;AAkCA;;;;;;UDlBiB,MAAA;EAAA,SACN,IAAA;AAAA;AAAA,uBAGW,UAAA,YAAsB,MAAA;EAAA,kBACxB,IAAA;AAAA;;;;;;;;;;iBAYJ,UAAA,WAAqB,MAAA,CAAA,CAAQ,IAAA,EAAM,CAAA,GAAI,CAAA;;;AAjBvD;;;;;AAIA;;;;;AAaA;;;;;;;;;;;;;AAjBA,cChBa,oBAAA;;;;;AAAb;;;;;AAkCA;;;;;;;;;AAKA;;;;;;;;;;;;;AC5CA;UDuCiB,SAAA,SAAkB,MAAA;EAAA,SACxB,EAAA;EAAA,SACA,IAAA;AAAA;AAAA,uBAGW,aAAA,SAAsB,UAAA,YAAsB,SAAA;EAAA,kBAC9C,EAAA;EAAA,kBACS,IAAA;AAAA;;;;;;;ADrB7B;;;;;AAaA;;;;;;;;UEtCiB,gBAAA;EAAA,SACN,KAAA;EAAA,SACA,WAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA;AAAA;;;;;ADCX;;;;;AAkCA;;iBCrBiB,kBAAA,CAAmB,OAAA,EAAS,OAAA,GAAU,SAAA,CAAU,gBAAA;;;;;;;AD0BjE;;;;;;;;;;;;;AC5CA;;;;;;;;;;AAkBA;;;;;;UA+CiB,OAAA,SAAgB,MAAA;EAAA,SACtB,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,SAAA;AAAA;;;AF7C/C;;;;;AAIA;;;;;AAaA;;;;;;;;AAjBA,UGrBiB,WAAA,SAAoB,MAAA;EAAA,SAC1B,IAAA;AAAA"}
package/dist/ir.mjs CHANGED
@@ -41,6 +41,31 @@ function freezeNode(node) {
41
41
  const UNBOUND_NAMESPACE_ID = "__unbound__";
42
42
  var NamespaceBase = class extends IRNodeBase {};
43
43
  //#endregion
44
- export { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, freezeNode };
44
+ //#region src/ir/storage.ts
45
+ /**
46
+ * Lazy walk over every named storage entity in a `Storage`-shaped
47
+ * value, yielded as {@link EntityCoordinate} tuples with
48
+ * `plane: 'storage'` (the parameter type binds the plane).
49
+ *
50
+ * Iterates each namespace's own-enumerable properties structurally.
51
+ * Skips `id` (known scalar); `kind` is non-enumerable on namespace
52
+ * concretions and does not appear in `Object.entries`. For every other
53
+ * property whose value is a non-null object, yields one coordinate per
54
+ * entry key in that map. No family-specific slot vocabulary is required.
55
+ */
56
+ function* elementCoordinates(storage) {
57
+ for (const [namespaceId, ns] of Object.entries(storage.namespaces)) for (const [entityKind, slot] of Object.entries(ns)) {
58
+ if (entityKind === "id") continue;
59
+ if (slot === null || typeof slot !== "object") continue;
60
+ for (const entityName of Object.keys(slot)) yield {
61
+ plane: "storage",
62
+ namespaceId,
63
+ entityKind,
64
+ entityName
65
+ };
66
+ }
67
+ }
68
+ //#endregion
69
+ export { IRNodeBase, NamespaceBase, UNBOUND_NAMESPACE_ID, elementCoordinates, freezeNode };
45
70
 
46
71
  //# sourceMappingURL=ir.mjs.map
package/dist/ir.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ir.mjs","names":[],"sources":["../src/ir/ir-node.ts","../src/ir/namespace.ts"],"sourcesContent":["/**\n * Framework-level IR alphabet.\n *\n * The framework's contribution to Contract IR / Schema IR is a common\n * root for the IR class hierarchy and a freeze affordance. Family\n * abstract bases (e.g. `SqlNode`, `MongoSchemaIRNode`) refine the alphabet\n * for their family shape; targets ship the concrete classes.\n *\n * `kind` is an optional discriminator on the base. Families and leaves\n * that benefit from discriminated-union dispatch declare their own\n * literal `kind` at the level that earns it — Mongo leaves carry\n * per-class literals (`readonly kind = 'mongo-collection' as const`)\n * because Mongo IR has polymorphic walkers; SQL declares a single\n * family-level `kind = 'sql'` on `SqlNode` because SQL IR has no\n * polymorphic dispatch today. No framework consumer dispatches on\n * `IRNode.kind` at the BASE type — every dispatch site narrows\n * through a union of leaves where each leaf carries a literal kind, so\n * requiring `kind` at the base would be unearned. Future leaves that\n * earn polymorphic dispatch override with a required literal at that\n * leaf (e.g. `override readonly kind = 'postgres-enum' as const`).\n *\n * `IRNodeBase` carries no methods: the freeze-and-assign affordance\n * lives in the free `freezeNode` helper below. Keeping `freezeNode` out\n * of the class type means an emitted contract literal type\n * (`{ readonly kind: 'mongo-collection', ... }` or an unkeyed literal\n * like `{ nativeType, codecId, nullable }`) is structurally assignable\n * to its class type — a `protected freeze()` instance method would\n * otherwise leak into the public type surface and require the literal\n * to carry it too.\n *\n * Subclasses construct fields then call `freezeNode(this)` to seal the\n * instance. Frozen instances + plain readonly fields keep IR nodes\n * JSON-clean by construction, so `JSON.stringify(node)` produces canonical\n * JSON without a `toJSON()` method. The `ContractSerializer` SPI handles\n * round-trip from canonical JSON back to typed class instances.\n *\n * The name (`IRNode` / `IRNodeBase`) reflects the dual-hierarchy reality:\n * this base is the common root for both Contract IR and Schema IR class\n * hierarchies, not a Schema-IR-specific alphabet.\n */\n\nexport interface IRNode {\n readonly kind?: string;\n}\n\nexport abstract class IRNodeBase implements IRNode {\n abstract readonly kind?: string;\n}\n\n/**\n * Seal an IR class instance after its constructor has assigned all\n * fields. The free-helper form (rather than a `protected freeze()`\n * instance method) keeps the class type structurally narrow so emitted\n * contract literal types remain assignable to their class types.\n *\n * The helper name stays `freezeNode` — it operates on IR nodes\n * regardless of root naming.\n */\nexport function freezeNode<T extends IRNode>(node: T): T {\n Object.freeze(node);\n return node;\n}\n","import { type IRNode, IRNodeBase } from './ir-node';\n\n/**\n * Reserved sentinel namespace id for the late-bound storage slot —\n * the slot whose binding the target resolves at connection time\n * rather than at authoring time. Postgres uses it for `search_path`\n * late binding; SQLite uses it for the trivial singleton; Mongo uses\n * it for the connection's `db` binding.\n *\n * Materialised target-side as a singleton subclass of the target's\n * `NamespaceBase` concretion that overrides the namespace's\n * qualifier-emission methods to elide the prefix entirely. Call sites\n * stay polymorphic and never branch on `id === UNBOUND_NAMESPACE_ID`\n * — the singleton's overrides drop the qualifier so emitted SQL / Mongo\n * commands look unqualified.\n *\n * The double-underscore decoration marks the id as a framework-reserved\n * coordinate when it appears in a JSON envelope (cold-read-as-reserved\n * — no realistic collision with user-declared namespace names).\n *\n * Encoded as an exported const (rather than scattered string literals)\n * so the sentinel-id invariant is single-sourced: any production-source\n * site that constructs an unbound-namespace singleton imports this\n * constant.\n */\nexport const UNBOUND_NAMESPACE_ID = '__unbound__' as const;\n\n/**\n * Framework-level building block for a \"namespace\" — the database-level\n * grouping under which storage objects (tables, collections, enums, …)\n * reside. Each target's namespace concretion maps the framework concept to\n * a target-native binding:\n *\n * - Postgres: a schema (`CREATE SCHEMA …`); rendered as `\"<schema>\"`.\n * - SQLite: the singleton `UNBOUND_NAMESPACE_ID`; emitted SQL has no qualifier.\n * - Mongo: the connection's `db` field; addressed as a database name.\n *\n * See `UNBOUND_NAMESPACE_ID` above for the sentinel id and the\n * singleton-subclass pattern that materialises it.\n *\n * The framework promises only the coordinate (`id`) — the named storage\n * entities a namespace contains are family-typed (SQL contributes\n * `tables`, Mongo contributes `collections`, future families pick their\n * own native idiom). Generic consumers walking \"all named entries\" go\n * through a family-typed namespace, not the framework `Namespace`.\n */\nexport interface Namespace extends IRNode {\n readonly id: string;\n}\n\nexport abstract class NamespaceBase extends IRNodeBase implements Namespace {\n abstract readonly id: string;\n}\n"],"mappings":";AA6CA,IAAsB,aAAtB,MAAmD;;;;;;;;;;AAanD,SAAgB,WAA6B,MAAY;CACvD,OAAO,OAAO,KAAK;CACnB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnCT,MAAa,uBAAuB;AAyBpC,IAAsB,gBAAtB,cAA4C,WAAgC"}
1
+ {"version":3,"file":"ir.mjs","names":[],"sources":["../src/ir/ir-node.ts","../src/ir/namespace.ts","../src/ir/storage.ts"],"sourcesContent":["/**\n * Framework-level IR alphabet.\n *\n * The framework's contribution to Contract IR / Schema IR is a common\n * root for the IR class hierarchy and a freeze affordance. Family\n * abstract bases (e.g. `SqlNode`, `MongoSchemaIRNode`) refine the alphabet\n * for their family shape; targets ship the concrete classes.\n *\n * `kind` is an optional discriminator on the base. Families and leaves\n * that benefit from discriminated-union dispatch declare their own\n * literal `kind` at the level that earns it — Mongo leaves carry\n * per-class literals (`readonly kind = 'mongo-collection' as const`)\n * because Mongo IR has polymorphic walkers; SQL declares a single\n * family-level `kind = 'sql'` on `SqlNode` because SQL IR has no\n * polymorphic dispatch today. No framework consumer dispatches on\n * `IRNode.kind` at the BASE type — every dispatch site narrows\n * through a union of leaves where each leaf carries a literal kind, so\n * requiring `kind` at the base would be unearned. Future leaves that\n * earn polymorphic dispatch override with a required literal at that\n * leaf (e.g. `override readonly kind = 'postgres-enum' as const`).\n *\n * `IRNodeBase` carries no methods: the freeze-and-assign affordance\n * lives in the free `freezeNode` helper below. Keeping `freezeNode` out\n * of the class type means an emitted contract literal type\n * (`{ readonly kind: 'mongo-collection', ... }` or an unkeyed literal\n * like `{ nativeType, codecId, nullable }`) is structurally assignable\n * to its class type — a `protected freeze()` instance method would\n * otherwise leak into the public type surface and require the literal\n * to carry it too.\n *\n * Subclasses construct fields then call `freezeNode(this)` to seal the\n * instance. Frozen instances + plain readonly fields keep IR nodes\n * JSON-clean by construction, so `JSON.stringify(node)` produces canonical\n * JSON without a `toJSON()` method. The `ContractSerializer` SPI handles\n * round-trip from canonical JSON back to typed class instances.\n *\n * The name (`IRNode` / `IRNodeBase`) reflects the dual-hierarchy reality:\n * this base is the common root for both Contract IR and Schema IR class\n * hierarchies, not a Schema-IR-specific alphabet.\n */\n\nexport interface IRNode {\n readonly kind?: string;\n}\n\nexport abstract class IRNodeBase implements IRNode {\n abstract readonly kind?: string;\n}\n\n/**\n * Seal an IR class instance after its constructor has assigned all\n * fields. The free-helper form (rather than a `protected freeze()`\n * instance method) keeps the class type structurally narrow so emitted\n * contract literal types remain assignable to their class types.\n *\n * The helper name stays `freezeNode` — it operates on IR nodes\n * regardless of root naming.\n */\nexport function freezeNode<T extends IRNode>(node: T): T {\n Object.freeze(node);\n return node;\n}\n","import { type IRNode, IRNodeBase } from './ir-node';\n\n/**\n * Reserved sentinel namespace id for the late-bound storage slot —\n * the slot whose binding the target resolves at connection time\n * rather than at authoring time. Postgres uses it for `search_path`\n * late binding; SQLite uses it for the trivial singleton; Mongo uses\n * it for the connection's `db` binding.\n *\n * Materialised target-side as a singleton subclass of the target's\n * `NamespaceBase` concretion that overrides the namespace's\n * qualifier-emission methods to elide the prefix entirely. Call sites\n * stay polymorphic and never branch on `id === UNBOUND_NAMESPACE_ID`\n * — the singleton's overrides drop the qualifier so emitted SQL / Mongo\n * commands look unqualified.\n *\n * The double-underscore decoration marks the id as a framework-reserved\n * coordinate when it appears in a JSON envelope (cold-read-as-reserved\n * — no realistic collision with user-declared namespace names).\n *\n * Encoded as an exported const (rather than scattered string literals)\n * so the sentinel-id invariant is single-sourced: any production-source\n * site that constructs an unbound-namespace singleton imports this\n * constant.\n */\nexport const UNBOUND_NAMESPACE_ID = '__unbound__' as const;\n\n/**\n * Framework-level building block for a \"namespace\" — the database-level\n * grouping under which storage objects (tables, collections, enums, …)\n * reside. Each target's namespace concretion maps the framework concept to\n * a target-native binding:\n *\n * - Postgres: a schema (`CREATE SCHEMA …`); rendered as `\"<schema>\"`.\n * - SQLite: the singleton `UNBOUND_NAMESPACE_ID`; emitted SQL has no qualifier.\n * - Mongo: the connection's `db` field; addressed as a database name.\n *\n * See `UNBOUND_NAMESPACE_ID` above for the sentinel id and the\n * singleton-subclass pattern that materialises it.\n *\n * The framework promises only the coordinate (`id`) — the named storage\n * entities a namespace contains are family-typed (SQL contributes\n * `tables`, Mongo contributes `collections`, future families pick their\n * own native idiom). Generic consumers walking \"all named entries\" go\n * through a family-typed namespace, not the framework `Namespace`.\n *\n * Every namespace concretion (e.g. `SqlNamespacePayload`,\n * `MongoNamespacePayload`, target-promoted namespaces like\n * `PostgresSchema`) carries exactly: `id` (enumerable string), `kind`\n * (non-enumerable string discriminator set via `Object.defineProperty`),\n * and one or more entity-kind slot maps — each an own-enumerable property\n * whose key is the entity kind (`tables`, `types`, `collections`,\n * target-pack-contributed slot names) and whose value is a\n * `Record<entityName, EntityIRClass>`. No other own-enumerable data lives\n * on a namespace; non-entity computed data lives on the surrounding storage\n * or contract IR. The framework's `elementCoordinates(storage)` walk relies\n * on this invariant to enumerate entities structurally without\n * family-specific knowledge.\n */\nexport interface Namespace extends IRNode {\n readonly id: string;\n readonly kind: string;\n}\n\nexport abstract class NamespaceBase extends IRNodeBase implements Namespace {\n abstract readonly id: string;\n abstract override readonly kind: string;\n}\n","import type { IRNode } from './ir-node';\nimport type { Namespace } from './namespace';\n\n/**\n * Canonical address for a named entity in Contract IR / Schema IR.\n *\n * `plane` is `'domain' | 'storage'`: which top-level contract plane the\n * entity lives on. Domain-side walks (once domain content is populated)\n * yield `plane: 'domain'`; {@link elementCoordinates} over storage yields\n * `plane: 'storage'`. A sibling `elementCoordinates(domain)` is not wired\n * yet — domain-plane content lands in S1.C; the sibling walk lands there.\n *\n * Cross-plane references obey a directional invariant: domain → storage is\n * allowed; storage → domain is forbidden. That rule is enforced by a\n * separate validator, not by constraining this coordinate shape — the\n * coordinate carries the axis the validator checks.\n *\n * Iteration order over namespace properties follows `Object.entries` order;\n * consumers that depend on ordering must sort.\n */\nexport interface EntityCoordinate {\n readonly plane: 'domain' | 'storage';\n readonly namespaceId: string;\n readonly entityKind: string;\n readonly entityName: string;\n}\n\n/**\n * Lazy walk over every named storage entity in a `Storage`-shaped\n * value, yielded as {@link EntityCoordinate} tuples with\n * `plane: 'storage'` (the parameter type binds the plane).\n *\n * Iterates each namespace's own-enumerable properties structurally.\n * Skips `id` (known scalar); `kind` is non-enumerable on namespace\n * concretions and does not appear in `Object.entries`. For every other\n * property whose value is a non-null object, yields one coordinate per\n * entry key in that map. No family-specific slot vocabulary is required.\n */\nexport function* elementCoordinates(storage: Storage): Generator<EntityCoordinate> {\n for (const [namespaceId, ns] of Object.entries(storage.namespaces)) {\n for (const [entityKind, slot] of Object.entries(ns)) {\n if (entityKind === 'id') continue;\n if (slot === null || typeof slot !== 'object') continue;\n for (const entityName of Object.keys(slot)) {\n yield { plane: 'storage', namespaceId, entityKind, entityName };\n }\n }\n }\n}\n\n/**\n * Framework-level promise that every Contract IR / Schema IR carries a\n * collection of namespaces keyed by namespace id. Family storage\n * concretions (`SqlStorage`, `MongoStorage`) refine the shape with\n * family-specific fields (tables, collections, enums, …); target\n * concretions add target fields where the family vocabulary doesn't\n * reach.\n *\n * Keeping `namespaces` at the framework layer enforces that every storage\n * object — across any target — is namespace-scoped. The framework can\n * therefore walk the namespace map without knowing the family alphabet, and\n * the `(namespace.id, name)` keying that the verifier and planner depend on\n * is honest at every layer.\n *\n * Extends `IRNode` so the framework's IR-walking surfaces (verifiers,\n * serializers) can dispatch on `Storage`-typed slots through the same\n * IR-node alphabet as every other node — the structural dual already\n * holds in code (every concrete storage class extends an IR-node base);\n * the interface promotion makes the typing honest.\n *\n * **Persisted envelope shape is target-owned, not framework-promised.**\n * Whether the `namespaces` map appears in the on-disk JSON envelope is\n * a per-target decision made by `ContractSerializer.serializeContract`.\n * Some targets emit a JSON-clean namespace shape that round-trips\n * through `JSON.stringify` cleanly (SQL today via the family-layer\n * identity serializer); others ship runtime-only fields on their\n * namespace concretions and override `serializeContract` to strip\n * them (Mongo). Future open (F16): extend the per-target\n * `ContractSerializer` integration-test surface with an explicit\n * envelope-shape assertion for each target, so the strip-vs-pass-through\n * choice is locked at test time rather than implied by the override\n * presence/absence. Earned by PR2's per-target namespace lift, when\n * `PostgresSchema` / `SqliteUnboundDatabase` start carrying\n * target-specific fields.\n */\nexport interface Storage extends IRNode {\n readonly namespaces: Readonly<Record<string, Namespace>>;\n}\n"],"mappings":";AA6CA,IAAsB,aAAtB,MAAmD;;;;;;;;;;AAanD,SAAgB,WAA6B,MAAY;CACvD,OAAO,OAAO,KAAK;CACnB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnCT,MAAa,uBAAuB;AAuCpC,IAAsB,gBAAtB,cAA4C,WAAgC;;;;;;;;;;;;;;AC1B5E,UAAiB,mBAAmB,SAA+C;CACjF,KAAK,MAAM,CAAC,aAAa,OAAO,OAAO,QAAQ,QAAQ,WAAW,EAChE,KAAK,MAAM,CAAC,YAAY,SAAS,OAAO,QAAQ,GAAG,EAAE;EACnD,IAAI,eAAe,MAAM;EACzB,IAAI,SAAS,QAAQ,OAAO,SAAS,UAAU;EAC/C,KAAK,MAAM,cAAc,OAAO,KAAK,KAAK,EACxC,MAAM;GAAE,OAAO;GAAW;GAAa;GAAY;GAAY"}
@@ -186,7 +186,7 @@ declare function defineAnnotation<Payload>(): <const Kinds extends OperationKind
186
186
  * db.users.select('id').annotate(cacheAnnotation({ ttl: 60 }));
187
187
  * // ✓ cacheAnnotation declares 'read'; SelectQuery.annotate requires 'read'.
188
188
  *
189
- * db.users.insert({ name: 'Alice' }).annotate(cacheAnnotation({ ttl: 60 }));
189
+ * db.users.insert([{ name: 'Alice' }]).annotate(cacheAnnotation({ ttl: 60 }));
190
190
  * // ✗ cacheAnnotation declares 'read'; InsertQuery.annotate requires 'write'.
191
191
  * // Element resolves to `never` → tuple unassignable → type error.
192
192
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":["candidate","#kind","#terminalName","#annotations"],"sources":["../src/execution/runtime-error.ts","../src/annotations.ts","../src/execution/async-iterable-result.ts","../src/execution/race-against-abort.ts","../src/execution/before-execute-chain.ts","../src/execution/run-with-middleware.ts","../src/execution/runtime-core.ts","../src/execution/runtime-middleware.ts","../src/meta-builder.ts"],"sourcesContent":["export interface RuntimeErrorEnvelope extends Error {\n readonly code: string;\n readonly category: 'PLAN' | 'CONTRACT' | 'LINT' | 'BUDGET' | 'RUNTIME';\n readonly severity: 'error';\n readonly details?: Record<string, unknown>;\n}\n\n/**\n * Stable code emitted by the runtime when an in-flight `execute()`\n * is cancelled via the per-query `AbortSignal`. The envelope's\n * `details.phase` distinguishes where the abort was observed:\n *\n * - `'encode'` — abort fired during `encodeParams` (SQL) or\n * `resolveValue` (Mongo).\n * - `'decode'` — abort fired during `decodeRow` / `decodeField`.\n * - `'stream'` — abort fired between rows or before any codec call\n * (already-aborted at entry).\n * - `'beforeExecute'` / `'afterExecute'` / `'onRow'` — abort fired\n * on entry to or during the corresponding middleware phase\n * (cooperative cancellation per the param-transform seam).\n */\nexport const RUNTIME_ABORTED = 'RUNTIME.ABORTED' as const;\n\n/** Discriminator placed in `details.phase` of a `RUNTIME.ABORTED` envelope. */\nexport type RuntimeAbortedPhase =\n | 'encode'\n | 'decode'\n | 'stream'\n | 'beforeExecute'\n | 'afterExecute'\n | 'onRow';\n\n/**\n * Type guard for the runtime-error envelope produced by `runtimeError`.\n *\n * Prefer this over duck-typing on `error.code` directly so consumers stay\n * insulated from the envelope's internal shape.\n */\nexport function isRuntimeError(error: unknown): error is RuntimeErrorEnvelope {\n return (\n error instanceof Error &&\n 'code' in error &&\n typeof (error as { code?: unknown }).code === 'string' &&\n 'category' in error &&\n 'severity' in error\n );\n}\n\nexport function runtimeError(\n code: string,\n message: string,\n details?: Record<string, unknown>,\n): RuntimeErrorEnvelope {\n const error = new Error(message) as RuntimeErrorEnvelope;\n Object.defineProperty(error, 'name', {\n value: 'RuntimeError',\n configurable: true,\n });\n\n return Object.assign(error, {\n code,\n category: resolveCategory(code),\n severity: 'error' as const,\n message,\n details,\n });\n}\n\nfunction resolveCategory(code: string): RuntimeErrorEnvelope['category'] {\n const prefix = code.split('.')[0] ?? 'RUNTIME';\n switch (prefix) {\n case 'PLAN':\n case 'CONTRACT':\n case 'LINT':\n case 'BUDGET':\n return prefix;\n default:\n return 'RUNTIME';\n }\n}\n\n/**\n * Construct a `RUNTIME.ABORTED` envelope. Phase distinguishes where the\n * abort was observed — codec call sites (`encode` / `decode` / `stream`)\n * or middleware seams (`beforeExecute` / `afterExecute` / `onRow`), as\n * enumerated on {@link RuntimeAbortedPhase}. Cause carries\n * `signal.reason` verbatim from the platform — native abort produces a\n * `DOMException`, explicit `controller.abort(reason)` produces whatever\n * the caller passed. No synthesis happens here.\n */\nexport function runtimeAborted(phase: RuntimeAbortedPhase, cause?: unknown): RuntimeErrorEnvelope {\n const envelope = runtimeError(RUNTIME_ABORTED, `Operation aborted during ${phase}`, { phase });\n return Object.assign(envelope, { cause });\n}\n","import { runtimeError } from './execution/runtime-error';\n\n/**\n * The kinds of operations an annotation may apply to.\n *\n * - `'read'` — `SELECT` / `find` / `first` / `all` / `count` / aggregates.\n * - `'write'` — `INSERT` / `UPDATE` / `DELETE` / `create` / `update` / `delete` / `upsert`.\n *\n * Annotations declare which kinds they apply to via `defineAnnotation`'s\n * `applicableTo` option; lane terminals enforce the constraint at both the\n * type level (via `ValidAnnotations`) and at runtime (via\n * `assertAnnotationsApplicable`).\n *\n * Finer-grained kinds (`'select' | 'insert' | 'update' | 'delete' | 'upsert'`)\n * are deliberately deferred. The binary covers the common case (the cache\n * middleware applies to reads; an audit annotation would apply to writes;\n * tracing/OTel applies to both). When a real annotation surfaces that needs\n * a finer split, the union widens and existing handles remain typecheckable.\n */\nexport type OperationKind = 'read' | 'write';\n\n/**\n * An applied annotation. Carries the namespace, the typed payload, and the\n * `applicableTo` set the underlying handle declared. The `__annotation`\n * brand lets `read` distinguish branded user annotations from arbitrary\n * data that may happen to live under the same namespace key in\n * `plan.meta.annotations` (e.g. framework-internal metadata such as\n * `meta.annotations.codecs`).\n *\n * Constructed by calling an `AnnotationHandle` directly (e.g.\n * `cacheAnnotation({ ttl: 60 })`); never instantiated by hand.\n */\nexport interface AnnotationValue<Payload, Kinds extends OperationKind> {\n readonly __annotation: true;\n readonly namespace: string;\n readonly value: Payload;\n readonly applicableTo: ReadonlySet<Kinds>;\n}\n\n/**\n * Handle returned by `defineAnnotation`. The handle is **callable**: the\n * call signature wraps a `Payload` into an `AnnotationValue` ready to\n * pass to a lane terminal's variadic `annotations` argument. The handle\n * also carries static metadata as own properties:\n *\n * - `namespace` — the namespace string the handle was declared with.\n * - `applicableTo` — the frozen `ReadonlySet<Kinds>` consumed by both\n * the type-level `ValidAnnotations` gate and the runtime\n * `assertAnnotationsApplicable` gate.\n * - `read(plan)` — extract the `Payload` from a plan's `meta.annotations`\n * if a value was previously written under this handle's namespace.\n * Returns `undefined` when the annotation is absent or when the stored\n * value is not a branded `AnnotationValue` (e.g. framework-internal\n * metadata under the same namespace key).\n *\n * Handles are the only supported public entry point for reading and\n * writing annotations. Direct mutation of `plan.meta.annotations` is not\n * part of the public API.\n *\n * ```typescript\n * const cacheAnnotation = defineAnnotation<{ ttl: number }>()({\n * namespace: 'cache',\n * applicableTo: ['read'],\n * });\n *\n * // Call the handle to construct a value:\n * const applied = cacheAnnotation({ ttl: 60 });\n *\n * // Read a stored value off a plan:\n * const payload = cacheAnnotation.read(plan);\n * ```\n *\n * Note on the inherited `Function.prototype.apply`: because the handle is\n * a function, the property name `apply` resolves to JavaScript's built-in\n * `Function.prototype.apply` (which lets you invoke a function with an\n * array of arguments). This is **not** the construction entry point — to\n * build an `AnnotationValue`, call the handle directly. The\n * `AnnotationHandle` interface deliberately does not declare an `apply`\n * member of its own.\n */\nexport interface AnnotationHandle<Payload, Kinds extends OperationKind> {\n (value: Payload): AnnotationValue<Payload, Kinds>;\n readonly namespace: string;\n readonly applicableTo: ReadonlySet<Kinds>;\n read(plan: {\n readonly meta: { readonly annotations?: Record<string, unknown> };\n }): Payload | undefined;\n}\n\n/**\n * Options accepted by `defineAnnotation`.\n *\n * `namespace` is the string key under which the annotation is stored in\n * `plan.meta.annotations`. **Reserved namespaces** include framework-\n * internal metadata keys; user handles must not use them:\n *\n * - `codecs` — used by the SQL emitter to record per-alias codec ids\n * (`meta.annotations.codecs[alias] = 'pg/text@1'`); the SQL runtime's\n * `decodeRow` reads from this key. A user `defineAnnotation('codecs')`\n * handle is not structurally prevented, but its behavior with the\n * emitter and the runtime is undefined and we make no compatibility\n * guarantees about it.\n * - Target-specific keys such as `pg` (and equivalents on other\n * targets) are similarly reserved for adapter / target use.\n *\n * `applicableTo` declares which operation kinds the annotation may attach\n * to. The lane terminals' type-level `ValidAnnotations<K, As>` gate rejects\n * annotations whose `Kinds` does not include the terminal's `K`; the\n * runtime helper `assertAnnotationsApplicable` does the equivalent at\n * runtime so casts and `any` cannot bypass the gate.\n */\nexport interface DefineAnnotationOptions<Kinds extends OperationKind> {\n readonly namespace: string;\n readonly applicableTo: readonly Kinds[];\n}\n\n/**\n * Defines a typed annotation handle.\n *\n * Two-step call form. The first step takes the `Payload` type argument\n * (TypeScript cannot infer `Payload` from anything in the options, so it\n * must be supplied explicitly); the second step takes the runtime options\n * and infers `Kinds` from the `applicableTo` array via a `const` type\n * parameter, so the operation kinds appear exactly once at the call site.\n *\n * @example\n * ```typescript\n * // Read-only annotation. Lane terminals like `db.User.first(...)` accept\n * // it; `db.User.create(...)` rejects it at the type level.\n * const cacheAnnotation = defineAnnotation<{ ttl?: number; skip?: boolean }>()({\n * namespace: 'cache',\n * applicableTo: ['read'],\n * }); // Kinds inferred as 'read'\n *\n * // Write-only annotation. Mirror image.\n * const auditAnnotation = defineAnnotation<{ actor: string }>()({\n * namespace: 'audit',\n * applicableTo: ['write'],\n * }); // Kinds inferred as 'write'\n *\n * // Annotation applicable to both kinds (e.g. tracing).\n * const otelAnnotation = defineAnnotation<{ traceId: string }>()({\n * namespace: 'otel',\n * applicableTo: ['read', 'write'],\n * }); // Kinds inferred as 'read' | 'write'\n * ```\n *\n * **Reserved namespaces.** See `DefineAnnotationOptions.namespace` for the\n * list of framework-internal namespaces (`codecs`, target-specific keys).\n * `defineAnnotation` does not structurally prevent a user from naming a\n * reserved namespace, but the framework makes no compatibility guarantee\n * about handles that do.\n */\nexport function defineAnnotation<Payload>(): <const Kinds extends OperationKind>(\n options: DefineAnnotationOptions<Kinds>,\n) => AnnotationHandle<Payload, Kinds> {\n return <const Kinds extends OperationKind>(\n options: DefineAnnotationOptions<Kinds>,\n ): AnnotationHandle<Payload, Kinds> => {\n const namespace = options.namespace;\n const applicableTo: ReadonlySet<Kinds> = Object.freeze(new Set(options.applicableTo));\n\n function handle(value: Payload): AnnotationValue<Payload, Kinds> {\n return Object.freeze({\n __annotation: true as const,\n namespace,\n value,\n applicableTo,\n });\n }\n\n function read(plan: {\n readonly meta: { readonly annotations?: Record<string, unknown> };\n }): Payload | undefined {\n const stored = plan.meta.annotations?.[namespace];\n if (!isAnnotationValue(stored)) {\n return undefined;\n }\n if (stored.namespace !== namespace) {\n // Defensive: a different handle wrote under our namespace key.\n return undefined;\n }\n return stored.value as Payload;\n }\n\n return Object.freeze(\n Object.assign(handle, {\n namespace,\n applicableTo,\n read,\n }),\n );\n };\n}\n\n/**\n * Type-level applicability gate consumed by lane terminals.\n *\n * Maps a tuple of `AnnotationValue`s to a tuple where each element either\n * keeps its annotation type (when the annotation's declared `Kinds`\n * includes the terminal's operation kind `K`) or resolves to `never`\n * (when the kinds are incompatible). A `never` element makes the entire\n * tuple unassignable, surfacing the mismatch as a type error at the call\n * site of the terminal.\n *\n * The SQL DSL builders constrain their variadic `...annotations`\n * parameter via `As & ValidAnnotations<K, As>`. **The intersection is\n * load-bearing** — see the note below. The ORM terminals deliberately\n * sidestep this trick by taking one annotation per `meta.annotate(...)`\n * call (no variadic-tuple inference involved), so `ValidAnnotations` is\n * consumed only by the SQL DSL today.\n *\n * @example\n * ```typescript\n * class SelectQuery<Row> {\n * annotate<As extends readonly AnnotationValue<unknown, OperationKind>[]>(\n * ...annotations: As & ValidAnnotations<'read', As>\n * ): SelectQuery<Row>;\n * }\n *\n * class InsertQuery<Row> {\n * annotate<As extends readonly AnnotationValue<unknown, OperationKind>[]>(\n * ...annotations: As & ValidAnnotations<'write', As>\n * ): InsertQuery<Row>;\n * }\n *\n * db.users.select('id').annotate(cacheAnnotation({ ttl: 60 }));\n * // ✓ cacheAnnotation declares 'read'; SelectQuery.annotate requires 'read'.\n *\n * db.users.insert({ name: 'Alice' }).annotate(cacheAnnotation({ ttl: 60 }));\n * // ✗ cacheAnnotation declares 'read'; InsertQuery.annotate requires 'write'.\n * // Element resolves to `never` → tuple unassignable → type error.\n * ```\n *\n * **Why `As & ValidAnnotations<K, As>` and not `ValidAnnotations<K, As>`\n * alone.** TypeScript's variadic-tuple inference is too forgiving when\n * the parameter type refers to `As` only through `ValidAnnotations`: it\n * will pick an `As` that makes the call valid even when the gated tuple\n * would contain `never` for an inapplicable element. The intersection\n * pins `As` to the actual call-site tuple AND requires it to be\n * assignable to the gated form. A `never` element in the gated tuple\n * then collapses the corresponding intersection position to `never`,\n * and the inapplicable argument fails to assign — surfacing the mismatch\n * as a type error at the call site.\n *\n * The runtime helper `assertAnnotationsApplicable` covers the equivalent\n * check at runtime so casts and `any` cannot bypass this gate.\n */\nexport type ValidAnnotations<\n K extends OperationKind,\n As extends readonly AnnotationValue<unknown, OperationKind>[],\n> = {\n readonly [I in keyof As]: As[I] extends AnnotationValue<infer P, infer Kinds>\n ? K extends Kinds\n ? AnnotationValue<P, Kinds>\n : never\n : never;\n};\n\n/**\n * Runtime applicability gate. Throws `RUNTIME.ANNOTATION_INAPPLICABLE` if\n * any annotation in `annotations` declares an `applicableTo` set that does\n * not include `kind`. Used by lane terminals (SQL DSL builders' `.build()`,\n * ORM `Collection` terminals) to fail closed when the type-level\n * `ValidAnnotations` gate is bypassed via cast / `any` / dynamic\n * invocation.\n *\n * Passes silently on:\n * - empty arrays\n * - annotations whose `applicableTo` includes `kind`\n *\n * Throws on:\n * - any annotation whose `applicableTo` does not include `kind`. The\n * error names the offending annotation's `namespace` and the\n * `terminalName` so users can locate the misuse.\n *\n * @example\n * ```typescript\n * // Inside an ORM read terminal:\n * assertAnnotationsApplicable(annotations, 'read', 'first');\n * ```\n */\nexport function assertAnnotationsApplicable(\n annotations: readonly AnnotationValue<unknown, OperationKind>[],\n kind: OperationKind,\n terminalName: string,\n): void {\n for (const annotation of annotations) {\n if (!annotation.applicableTo.has(kind)) {\n throw runtimeError(\n 'RUNTIME.ANNOTATION_INAPPLICABLE',\n `Annotation '${annotation.namespace}' is not applicable to '${kind}' operations (terminal: '${terminalName}'). The annotation declares applicableTo = [${Array.from(\n annotation.applicableTo,\n )\n .map((k) => `'${k}'`)\n .join(', ')}].`,\n {\n namespace: annotation.namespace,\n terminalName,\n kind,\n applicableTo: Array.from(annotation.applicableTo),\n },\n );\n }\n }\n}\n\n/**\n * Type guard for branded annotation values stored in `plan.meta.annotations`.\n *\n * Internal — used by `AnnotationHandle.read` to distinguish user\n * annotations (created by calling a handle returned from\n * `defineAnnotation(...)`) from framework-internal metadata that may\n * happen to live under the same namespace key.\n */\nfunction isAnnotationValue(value: unknown): value is AnnotationValue<unknown, OperationKind> {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n const candidate = value as { readonly __annotation?: unknown };\n return candidate.__annotation === true;\n}\n","import { runtimeError } from './runtime-error';\n\nexport class AsyncIterableResult<Row> implements AsyncIterable<Row>, PromiseLike<Row[]> {\n private readonly generator: AsyncGenerator<Row, void, unknown>;\n private consumed = false;\n private consumedBy: 'bufferedArray' | 'iterator' | undefined;\n private bufferedArrayPromise: Promise<Row[]> | undefined;\n\n constructor(generator: AsyncGenerator<Row, void, unknown>) {\n this.generator = generator;\n }\n\n [Symbol.asyncIterator](): AsyncIterator<Row> {\n if (this.consumed) {\n throw runtimeError(\n 'RUNTIME.ITERATOR_CONSUMED',\n `AsyncIterableResult iterator has already been consumed via ${this.consumedBy === 'bufferedArray' ? 'toArray()/then()' : 'for-await loop'}. Each AsyncIterableResult can only be iterated once.`,\n {\n consumedBy: this.consumedBy,\n suggestion:\n this.consumedBy === 'bufferedArray'\n ? 'If you need to iterate multiple times, store the results from toArray() in a variable and reuse that.'\n : 'If you need to iterate multiple times, use toArray() to collect all results first.',\n },\n );\n }\n this.consumed = true;\n this.consumedBy = 'iterator';\n return this.generator;\n }\n\n toArray(): Promise<Row[]> {\n if (this.consumedBy === 'iterator') {\n return Promise.reject(\n runtimeError(\n 'RUNTIME.ITERATOR_CONSUMED',\n 'AsyncIterableResult iterator has already been consumed via for-await loop. Each AsyncIterableResult can only be iterated once.',\n {\n consumedBy: this.consumedBy,\n suggestion:\n 'The iterator was already consumed by a for-await loop. Use toArray() or await the result before iterating.',\n },\n ),\n );\n }\n\n if (this.bufferedArrayPromise) {\n return this.bufferedArrayPromise;\n }\n\n this.consumed = true;\n this.consumedBy = 'bufferedArray';\n this.bufferedArrayPromise = (async () => {\n const out: Row[] = [];\n for await (const item of this.generator) {\n out.push(item);\n }\n return out;\n })();\n return this.bufferedArrayPromise;\n }\n\n async first(): Promise<Row | null> {\n const rows = await this.toArray();\n return rows[0] ?? null;\n }\n\n async firstOrThrow(): Promise<Row> {\n const row = await this.first();\n if (row === null)\n throw runtimeError(\n 'RUNTIME.NO_ROWS',\n 'Expected at least one row, but none were returned',\n {},\n );\n return row;\n }\n\n // biome-ignore lint/suspicious/noThenProperty: PromiseLike implementation is intentional for await support.\n then<TResult1 = Row[], TResult2 = never>(\n onfulfilled?: ((value: Row[]) => TResult1 | PromiseLike<TResult1>) | undefined | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | undefined | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.toArray().then(onfulfilled, onrejected);\n }\n}\n","import type { RuntimeAbortedPhase } from './runtime-error';\nimport { runtimeAborted } from './runtime-error';\n\n/**\n * Throw a phase-tagged `RUNTIME.ABORTED` envelope if the supplied\n * context is already aborted at the precheck site. Centralises the\n * `if (ctx.signal?.aborted) throw runtimeAborted(...)` pattern that\n * every codec dispatch site (and the `beforeExecute` middleware phase)\n * repeats. Accepts both the framework `CodecCallContext` and the\n * `RuntimeMiddlewareContext`; both expose `signal?: AbortSignal`.\n */\nexport function checkAborted(\n ctx: { readonly signal?: AbortSignal },\n phase: RuntimeAbortedPhase,\n): void {\n if (ctx.signal?.aborted) {\n throw runtimeAborted(phase, ctx.signal.reason);\n }\n}\n\n/**\n * Race a per-cell `Promise.all` (or any other in-flight work promise) against\n * the supplied abort signal so the runtime returns `RUNTIME.ABORTED` promptly\n * even when codec bodies ignore the signal. In-flight bodies that ignore the\n * signal are abandoned and run to completion in the background — the\n * cooperative-cancellation contract documented in ADR 204.\n *\n * Call sites still SHOULD pre-check `signal.aborted` and short-circuit with\n * a phase-tagged `RUNTIME.ABORTED` envelope before invoking this helper —\n * that path is the canonical \"aborted at entry\" surface and avoids\n * scheduling the work promise. As a defensive belt-and-braces, this helper\n * also handles the already-aborted case internally: `AbortSignal` does not\n * replay past abort events to listeners registered after the abort, so we\n * inspect `signal.aborted` synchronously and reject with the sentinel\n * before installing the listener. The rejection is still attributed to the\n * abort path via the sentinel-identity check.\n *\n * Distinguishing the rejection source is load-bearing for AC-ERR4\n * (`RUNTIME.ENCODE_FAILED` / `RUNTIME.DECODE_FAILED` pass through unchanged).\n * The semantically equivalent `abortable(signal)` helper in\n * `@prisma-next/utils` rejects with `signal.reason ?? new DOMException(...)`,\n * which is not stably distinguishable from a codec-thrown error by identity\n * alone (a fresh fallback DOMException is allocated per call). We instead\n * track abort attribution with a unique sentinel: only the `onAbort` listener\n * installed here ever rejects with the sentinel, so an `error === sentinel`\n * identity check after the race is unambiguous.\n *\n * Lives in `framework-components` (rather than the SQL family, where it\n * originated in m2) so every family runtime that needs cooperative\n * cancellation around a codec-dispatch `Promise.all` (SQL encode + decode\n * today, Mongo encode in m3) shares the same attribution logic.\n */\nexport async function raceAgainstAbort<T>(\n work: Promise<T>,\n signal: AbortSignal | undefined,\n phase: RuntimeAbortedPhase,\n): Promise<T> {\n if (signal === undefined) {\n return await work;\n }\n const sentinel: { reason: unknown } = { reason: undefined };\n let onAbort: (() => void) | undefined;\n\n const abortPromise = new Promise<never>((_, reject) => {\n if (signal.aborted) {\n sentinel.reason = signal.reason;\n reject(sentinel);\n return;\n }\n onAbort = () => {\n sentinel.reason = signal.reason;\n reject(sentinel);\n };\n signal.addEventListener('abort', onAbort, { once: true });\n });\n\n try {\n return await Promise.race([work, abortPromise]);\n } catch (error) {\n if (error === sentinel) {\n throw runtimeAborted(phase, sentinel.reason);\n }\n throw error;\n } finally {\n if (onAbort) {\n signal.removeEventListener('abort', onAbort);\n }\n }\n}\n","import type { ExecutionPlan } from './query-plan';\nimport { checkAborted, raceAgainstAbort } from './race-against-abort';\nimport type {\n ParamRefMutator,\n RuntimeMiddleware,\n RuntimeMiddlewareContext,\n} from './runtime-middleware';\n\n/**\n * Runs every middleware's `beforeExecute` hook in registration order,\n * threading through the (optional) family-specific `paramsMutator`.\n *\n * Why this lives outside {@link runWithMiddleware}: middleware that\n * mutates parameter values (e.g. cipherstash's bulk-encrypt SDK\n * round-trip) must run *before* the family runtime encodes those\n * parameters to driver wire format. Family runtimes call\n * `runBeforeExecuteChain` between the AST → plan lowering step and\n * the parameter encode step; the encode then observes the mutator's\n * `currentParams()` view. `runWithMiddleware` retains the rest of\n * the lifecycle (`intercept`, driver/row source loop, `onRow`,\n * `afterExecute`) but no longer fires `beforeExecute` itself.\n *\n * Lifecycle within this helper:\n *\n * 1. For each middleware in registration order, if `beforeExecute`\n * is implemented:\n * - `checkAborted(ctx, 'beforeExecute')` short-circuits if the\n * caller already aborted at entry.\n * - The hook is invoked with `(plan, ctx, paramsMutator)`. A\n * middleware body that ignores the mutator stays compatible —\n * JavaScript allows extra positional arguments.\n * - If the hook returns a Promise, it is raced against\n * `ctx.signal` via {@link raceAgainstAbort} so cooperative\n * cancellation surfaces a `RUNTIME.ABORTED { phase:\n * 'beforeExecute' }` envelope even when the body itself\n * ignores the signal.\n *\n * Error propagation: any error thrown by a `beforeExecute` body\n * (or surfaced by the abort race) propagates out of this helper\n * unchanged. The family runtime is responsible for converting it\n * into the appropriate `afterExecute(completed: false)` notification\n * once `runWithMiddleware` runs.\n *\n * Relationship to {@link runWithMiddleware}: the framework's\n * `RuntimeCore.execute` template calls this helper between\n * `lower(plan)` and `runWithMiddleware(...)`. Family runtimes that\n * override `execute` (e.g. SQL, which inlines lower + encode for\n * direct mutator threading) call this helper themselves at the\n * equivalent point — between the family's AST → draft-plan\n * lowering and the parameter-encode step.\n *\n * Intercept ordering: this helper fires unconditionally before\n * `runWithMiddleware`. `intercept` (inside `runWithMiddleware`)\n * therefore observes the post-`beforeExecute` plan — mutator\n * mutations are visible in the params interceptors see. The\n * trade-off is documented on `RuntimeMiddleware.intercept`.\n */\nexport async function runBeforeExecuteChain<\n TExec extends ExecutionPlan,\n TMutator extends ParamRefMutator = ParamRefMutator,\n>(\n plan: TExec,\n middleware: ReadonlyArray<RuntimeMiddleware<TExec, TMutator>>,\n ctx: RuntimeMiddlewareContext,\n paramsMutator?: TMutator,\n): Promise<void> {\n for (const mw of middleware) {\n if (!mw.beforeExecute) {\n continue;\n }\n checkAborted(ctx, 'beforeExecute');\n const work = mw.beforeExecute(plan, ctx, paramsMutator as TMutator);\n if (work !== undefined) {\n await raceAgainstAbort(Promise.resolve(work), ctx.signal, 'beforeExecute');\n }\n }\n}\n","import { AsyncIterableResult } from './async-iterable-result';\nimport type { ExecutionPlan } from './query-plan';\nimport type { RuntimeMiddleware, RuntimeMiddlewareContext } from './runtime-middleware';\n\n/**\n * Drives a single execution of `runDriver()` through the middleware\n * lifecycle's intercept + row-source + termination phases.\n *\n * Lifecycle, in order:\n * 1. For each middleware in registration order: `intercept(exec, ctx)`. The\n * first non-`undefined` result wins; subsequent middleware's `intercept`\n * does not fire. On a hit, the runtime emits a `middleware.intercept`\n * debug event naming the winning middleware, switches the row source to\n * the intercepted rows, and proceeds with `source: 'middleware'`. On\n * all-passthrough (every `intercept` returns `undefined` or is omitted),\n * `source: 'driver'` is used and the row source is `runDriver()`.\n * 2. Iterate the row source. On the driver path, for each row, for each\n * middleware in registration order: `onRow(row, exec, ctx)`; then yield\n * the row. On the intercepted hit path, `onRow` is skipped — intercepted\n * rows did not originate from a driver row stream — but rows are still\n * yielded to the consumer in order.\n * 3. On successful completion: for each middleware in registration order:\n * `afterExecute(exec, { rowCount, latencyMs, completed: true, source },\n * ctx)`.\n * 4. On any error thrown during steps 1–2: for each middleware in\n * registration order: `afterExecute(exec, { rowCount, latencyMs,\n * completed: false, source }, ctx)`. Errors thrown by `afterExecute`\n * during the error path are swallowed so they do not mask the original\n * error. The original error is then rethrown.\n *\n * `beforeExecute` is **not** fired here — see\n * {@link runBeforeExecuteChain} in `before-execute-chain.ts`. Family\n * runtimes call that helper between the AST → plan lowering step and\n * the parameter encode step so middleware that mutates ParamRef\n * values (e.g. cipherstash bulk-encrypt) can have its mutations\n * visible to encode. `runWithMiddleware` operates on the fully-\n * encoded plan; interceptors therefore observe a fully-mutated,\n * encoded plan.\n *\n * The `source` field on `AfterExecuteResult` lets observers (telemetry,\n * lints, budgets) distinguish driver-served from middleware-served\n * executions without needing their own out-of-band signal.\n *\n * This helper is the single canonical implementation of the\n * intercept-and-row-source loop; family runtimes should not\n * reimplement it.\n */\nexport function runWithMiddleware<TExec extends ExecutionPlan, Row>(\n exec: TExec,\n middleware: ReadonlyArray<RuntimeMiddleware<TExec>>,\n ctx: RuntimeMiddlewareContext,\n runDriver: () => AsyncIterable<Row>,\n): AsyncIterableResult<Row> {\n const iterator = async function* (): AsyncGenerator<Row, void, unknown> {\n const startedAt = Date.now();\n let rowCount = 0;\n let completed = false;\n let source: 'driver' | 'middleware' = 'driver';\n // Deferred so a winning interceptor can skip `runDriver()` entirely.\n // For factories that lazily produce async generators this is a no-op,\n // but factories that do eager work (e.g. acquiring a connection,\n // sending a query) must not run on the intercepted hit path.\n let rowSource: AsyncIterable<Row> | Iterable<Row> | undefined;\n\n try {\n for (const mw of middleware) {\n if (!mw.intercept) {\n continue;\n }\n // Mark the lifecycle as middleware-driven *before* awaiting the\n // hook. If `intercept` throws, the catch block reports the failure\n // as `source: 'middleware'` — the failure originated in the\n // intercept chain, not in the driver. If `intercept` returns\n // `undefined` (passthrough), we revert to `'driver'` and continue.\n source = 'middleware';\n const result = await mw.intercept(exec, ctx);\n if (result === undefined) {\n source = 'driver';\n continue;\n }\n ctx.log.debug?.({ event: 'middleware.intercept', middleware: mw.name });\n // The intercepted rows are typed as `Record<string, unknown>` at\n // the SPI level; the consumer's `Row` type parameter is enforced by\n // the caller (via the plan's phantom `_row`) the same way driver\n // rows are. Cast through unknown to bridge the SPI shape to the\n // caller-supplied Row.\n rowSource = result.rows as unknown as AsyncIterable<Row> | Iterable<Row>;\n break;\n }\n\n if (source === 'driver') {\n rowSource = runDriver();\n }\n\n // `rowSource` is always assigned by this point: either the intercepted\n // rows (on a hit) or `runDriver()` (on the driver path).\n for await (const row of rowSource as AsyncIterable<Row> | Iterable<Row>) {\n if (source === 'driver') {\n for (const mw of middleware) {\n if (mw.onRow) {\n await mw.onRow(row as Record<string, unknown>, exec, ctx);\n }\n }\n }\n rowCount++;\n yield row;\n }\n\n completed = true;\n } catch (error) {\n const latencyMs = Date.now() - startedAt;\n for (const mw of middleware) {\n if (mw.afterExecute) {\n try {\n await mw.afterExecute(exec, { rowCount, latencyMs, completed, source }, ctx);\n } catch {\n // Swallow afterExecute errors during the error path so they do not\n // mask the original error.\n }\n }\n }\n\n throw error;\n }\n\n const latencyMs = Date.now() - startedAt;\n for (const mw of middleware) {\n if (mw.afterExecute) {\n await mw.afterExecute(exec, { rowCount, latencyMs, completed, source }, ctx);\n }\n }\n };\n\n return new AsyncIterableResult(iterator());\n}\n","import type { CodecCallContext } from '../shared/codec-types';\nimport { AsyncIterableResult } from './async-iterable-result';\nimport { runBeforeExecuteChain } from './before-execute-chain';\nimport type { ExecutionPlan, QueryPlan } from './query-plan';\nimport { checkAborted } from './race-against-abort';\nimport { runWithMiddleware } from './run-with-middleware';\nimport type {\n RuntimeExecuteOptions,\n RuntimeExecutor,\n RuntimeMiddleware,\n RuntimeMiddlewareContext,\n} from './runtime-middleware';\n\n/**\n * Constructor options shared by every concrete `RuntimeCore` subclass.\n *\n * Family runtimes typically build the middleware list and the\n * `RuntimeMiddlewareContext` themselves (running compatibility checks,\n * narrowing the context's `contract` field, etc.) before calling `super`.\n */\nexport interface RuntimeCoreOptions<TMiddleware extends RuntimeMiddleware<ExecutionPlan>> {\n readonly middleware: ReadonlyArray<TMiddleware>;\n readonly ctx: RuntimeMiddlewareContext;\n}\n\n/**\n * Family-agnostic abstract runtime base.\n *\n * Defines the entire `execute(plan)` template in one place:\n *\n * 1. `runBeforeCompile(plan)` — concrete; defaults to identity. SQL overrides\n * this to run its `beforeCompile` middleware-hook chain.\n * 2. `lower(plan)` — abstract. Each family produces its `*ExecutionPlan`\n * (SQL via `lowerSqlPlan`, Mongo via `adapter.lower`).\n * 3. `runBeforeExecuteChain(exec, this.middleware, this.ctx)` — concrete;\n * runs every middleware's `beforeExecute` hook after lowering but\n * before the row source is opened. Family runtimes that need a\n * params mutator visible to a downstream encode step (SQL) override\n * `execute` and call this helper themselves at the equivalent\n * pre-encode point.\n * 4. `runWithMiddleware(exec, this.middleware, this.ctx,\n * () => runDriver(exec))` — concrete; runs the intercept chain,\n * drives the row source, fires `onRow` / `afterExecute`. Does\n * **not** fire `beforeExecute` — see step 3.\n *\n * Concrete subclasses must implement `lower`, `runDriver`, and `close`.\n *\n * The class is generic over:\n * - `TPlan` — the family's pre-lowering plan type.\n * - `TExec` — the family's post-lowering (executable) plan type.\n * - `TMiddleware` — the family's middleware type. Constrained to\n * `RuntimeMiddleware<TExec>` because `runWithMiddleware` invokes the\n * `beforeExecute` / `onRow` / `afterExecute` hooks with the lowered\n * `TExec`. (The spec/plan wording \"RuntimeMiddleware<TPlan>\" is\n * tightened to `<TExec>` here so the helper call typechecks; the\n * intent is unchanged — middleware sees the post-lowering plan.)\n */\nexport abstract class RuntimeCore<\n TPlan extends QueryPlan,\n TExec extends ExecutionPlan,\n TMiddleware extends RuntimeMiddleware<TExec>,\n> implements RuntimeExecutor<TPlan>\n{\n protected readonly middleware: ReadonlyArray<TMiddleware>;\n protected readonly ctx: RuntimeMiddlewareContext;\n\n constructor(options: RuntimeCoreOptions<TMiddleware>) {\n this.middleware = options.middleware;\n this.ctx = options.ctx;\n }\n\n /**\n * Pre-lowering hook for plan rewriting. Defaults to identity. Subclasses\n * may override to run a `beforeCompile` middleware chain (SQL does this\n * to support typed AST rewrites — see `before-compile-chain.ts`).\n */\n protected runBeforeCompile(plan: TPlan): TPlan | Promise<TPlan> {\n return plan;\n }\n\n /**\n * Lower a pre-lowering `TPlan` into the family's executable `TExec`.\n * Family-specific: SQL produces `{ sql, params, ast?, ... }`; Mongo\n * produces `{ command, ... }`.\n *\n * `ctx` carries per-query cancellation (and any future fields on\n * `CodecCallContext`); concrete subclasses forward it to the\n * encode-side codec dispatch site (e.g. SQL's `encodeParams` in m2,\n * Mongo's `resolveValue` in m3). The runtime allocates one ctx per\n * `execute()` call and threads the same reference everywhere; the\n * `signal` field inside may be `undefined`, but the ctx object itself\n * is always present.\n */\n protected abstract lower(plan: TPlan, ctx: CodecCallContext): TExec | Promise<TExec>;\n\n /**\n * Drive the underlying transport for a lowered `TExec`. Yields raw rows\n * directly from the driver as `Record<string, unknown>`; codec decoding\n * (if any) is the subclass's responsibility, applied by wrapping\n * `execute()` rather than living inside this hook.\n *\n * The `Row` type parameter on `execute()` is satisfied by the caller via\n * the plan's phantom `_row`; the runtime treats rows as opaque records\n * here and trusts the caller's row typing.\n */\n protected abstract runDriver(exec: TExec): AsyncIterable<Record<string, unknown>>;\n\n abstract close(): Promise<void>;\n\n execute<Row>(\n plan: TPlan & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n const self = this;\n const signal = options?.signal;\n // One ctx per execute() call. The ctx object is always allocated; the\n // `signal` field is only included when a signal was supplied (required\n // under exactOptionalPropertyTypes — `{ signal: undefined }` would not\n // satisfy `signal?: AbortSignal`).\n const codecCtx: CodecCallContext = signal === undefined ? {} : { signal };\n\n async function* generator(): AsyncGenerator<Row, void, unknown> {\n // Pre-check the signal at entry so an already-aborted caller observes\n // RUNTIME.ABORTED on the first `next()` without any work being done.\n checkAborted(codecCtx, 'stream');\n\n const compiled = await self.runBeforeCompile(plan);\n const exec = await self.lower(compiled, codecCtx);\n // Fire the framework-level `beforeExecute` chain on the lowered\n // plan before opening the row source. Families that need\n // pre-encode mutator visibility (SQL) override `execute` to\n // inject the same chain at the equivalent point.\n await runBeforeExecuteChain<TExec>(exec, self.middleware, self.ctx);\n // The driver yields raw `Record<string, unknown>`; we cast to `Row` here.\n // The Row contract is enforced by the caller via `plan._row`.\n yield* runWithMiddleware<TExec, Row>(\n exec,\n self.middleware,\n self.ctx,\n () => self.runDriver(exec) as AsyncIterable<Row>,\n );\n }\n\n return new AsyncIterableResult(generator());\n }\n}\n","import type { AsyncIterableResult } from './async-iterable-result';\nimport type { ExecutionPlan, QueryPlan } from './query-plan';\nimport { runtimeError } from './runtime-error';\n\nexport interface RuntimeLog {\n info(event: unknown): void;\n warn(event: unknown): void;\n error(event: unknown): void;\n debug?(event: unknown): void;\n}\n\n/**\n * Per-execute context threaded through every middleware phase\n * (`beforeExecute`, `onRow`, `afterExecute`). Allocated once per\n * `runtime.execute()` call and shared by reference across all\n * middleware in the chain.\n *\n * - `signal` carries the per-query `AbortSignal` -- the same\n * reference that `runtime.execute(plan, { signal })` was invoked\n * with, and the same reference threaded into the per-call\n * `CodecCallContext` (ADR 207). Middleware that wraps a\n * network-backed SDK forwards `ctx.signal` into that SDK to\n * propagate caller cancellation; pure-CPU middleware ignores it.\n *\n * Symmetric plumbing across all middleware phases (rather than only\n * `beforeExecute`) is a deliberate choice: a middleware that wraps a\n * downstream observability hook or post-processor in `afterExecute` /\n * `onRow` needs the same cancellation reach as its `beforeExecute`\n * counterpart.\n */\nexport interface RuntimeMiddlewareContext {\n readonly contract: unknown;\n readonly mode: 'strict' | 'permissive';\n readonly now: () => number;\n readonly log: RuntimeLog;\n /**\n * Returns a stable string identifying the (storage, statement, params)\n * tuple of an execution. Two semantically equivalent executions return\n * the same string. Used by middleware that need per-execution identity\n * (caching, request coalescing).\n *\n * The family runtime owns the implementation:\n * - SQL: `meta.storageHash` + `exec.sql` + `canonicalStringify(exec.params)`\n * - Mongo: `meta.storageHash` + `canonicalStringify({ ...exec.command })`\n *\n * The method is `async` because the underlying digest helper\n * (`hashContent`) uses the WebCrypto API, whose `crypto.subtle.digest`\n * primitive is asynchronous by design.\n *\n * The returned string is intended to be consumed directly as a `Map` key\n * — it is not (and should not be) further hashed by callers.\n */\n contentHash(exec: ExecutionPlan): Promise<string>;\n /**\n * Per-execute cancellation signal threaded through every middleware\n * phase. Middleware that wraps async work or downstream cancellable\n * primitives should observe this and abort early when the consumer\n * cancels.\n */\n readonly signal?: AbortSignal;\n /**\n * Identifies the queryable scope this execution is running under.\n *\n * - `'runtime'` — top-level `runtime.execute(plan)`. The default scope\n * used by the standard read/write paths.\n * - `'connection'` — `connection.execute(plan)` after\n * `runtime.connection()` checked out a connection from the pool.\n * - `'transaction'` — `transaction.execute(plan)` inside an explicit\n * transaction, or a query routed through `withTransaction`.\n *\n * Middleware that should only act at the top level read this field to\n * bypass non-runtime scopes. The cache middleware uses it to skip\n * caching inside transactions (where read-after-write coherence is the\n * caller's expectation) and dedicated connections (where the user has\n * explicitly stepped outside the shared cache surface). Observers that\n * don't care about the scope can ignore the field.\n *\n * Family runtimes populate this at context-construction time per\n * scope. Existing middleware that ignore the field are unaffected.\n */\n readonly scope: 'runtime' | 'connection' | 'transaction';\n}\n\nexport interface AfterExecuteResult {\n readonly rowCount: number;\n readonly latencyMs: number;\n readonly completed: boolean;\n /**\n * Indicates where the rows observed during this execution came from.\n *\n * - `'driver'` — the default. Rows came from the underlying driver via\n * `runDriver` / `runWithMiddleware`'s normal path.\n * - `'middleware'` — a `RuntimeMiddleware.intercept` hook short-circuited\n * execution and supplied the rows directly. The driver was not invoked.\n *\n * Observers (telemetry, lints, budgets) that need to distinguish between\n * driver-served and middleware-served executions read this field.\n * Observers that don't care can ignore it.\n */\n readonly source: 'driver' | 'middleware';\n}\n\n/**\n * Result of a successful `RuntimeMiddleware.intercept` hook.\n *\n * Carries the rows that the middleware wishes to return in place of\n * invoking the driver. The runtime iterates `rows` in order and yields\n * each row to the consumer; `beforeExecute`, `runDriver`, and `onRow` are\n * all skipped on the hit path. `afterExecute` still fires with\n * `source: 'middleware'`.\n *\n * `rows` accepts both `Iterable` (arrays, sync generators) and\n * `AsyncIterable` (async generators). `for await` natively handles both\n * via `Symbol.asyncIterator` / `Symbol.iterator` fallback, so the\n * orchestrator does not need to branch on the variant. Cached arrays in\n * the cache middleware are the common case; streaming variants support\n * future use cases like mock layers replaying recordings.\n *\n * Row shape is `Record<string, unknown>` — the same untyped shape\n * `onRow` receives. The SQL runtime decodes intercepted rows through its\n * normal codec pass, so interceptors cache and return raw (undecoded)\n * rows.\n */\nexport interface InterceptResult {\n readonly rows: AsyncIterable<Record<string, unknown>> | Iterable<Record<string, unknown>>;\n}\n\n/**\n * Marker interface for family-specific param-ref mutators threaded into\n * `beforeExecute` as the third argument. The framework treats the mutator\n * opaquely — it allocates and forwards the family's mutator instance so\n * `runWithMiddleware` can stay family-agnostic. SQL extends this with\n * `SqlParamRefMutator` (over `ParamRef`); Mongo extends with\n * `MongoParamRefMutator` (over `MongoParamRef`).\n *\n * Extension authors target the family-specific mutator type, not this\n * marker.\n */\ndeclare const PARAM_REF_MUTATOR_BRAND: unique symbol;\nexport type ParamRefMutator = { readonly [PARAM_REF_MUTATOR_BRAND]?: never };\n\n/**\n * Family-agnostic middleware SPI parameterized over the plan marker.\n *\n * `TPlan` defaults to the framework `QueryPlan` marker so a generic\n * middleware (e.g. cross-family telemetry) can be authored without\n * naming a family. Family-specific middleware (`SqlMiddleware`,\n * `MongoMiddleware`) narrow `TPlan` to their concrete plan type.\n *\n * `TMutator` is the family-specific {@link ParamRefMutator} the runtime\n * threads into `beforeExecute(plan, ctx, params)` as a third argument.\n * Existing `(plan)` / `(plan, ctx)` middleware bodies continue to compile\n * — TypeScript permits assigning a function with fewer parameters to a\n * function-typed slot that declares more. The third arg is additive.\n */\nexport interface RuntimeMiddleware<\n TPlan extends QueryPlan = QueryPlan,\n TMutator extends ParamRefMutator = ParamRefMutator,\n> {\n readonly name: string;\n readonly familyId?: string;\n readonly targetId?: string;\n /**\n * Optional short-circuit hook. Runs inside `runWithMiddleware`, after\n * the orchestrator receives the lowered plan and before any\n * `beforeExecute` hook fires. Middleware run in registration order; the\n * first to return a non-`undefined` `InterceptResult` wins, and\n * subsequent middleware's `intercept` does not fire.\n *\n * On a hit, `beforeExecute`, `runDriver`, and `onRow` are all skipped.\n * `afterExecute` still fires with `source: 'middleware'`.\n *\n * Returning `undefined` (or omitting the hook entirely) signals\n * passthrough — execution proceeds through the normal driver path.\n *\n * Errors thrown inside `intercept` are rethrown by `runWithMiddleware`\n * as the original `Error` — no envelope is guaranteed at this layer.\n * Before rethrowing, `afterExecute` fires with `completed: false` and\n * `source: 'middleware'`. Errors thrown by `afterExecute` during the\n * error path remain swallowed (existing semantics, unchanged).\n *\n * Used by middleware that need to short-circuit execution and supply\n * rows directly: caching, mocks, rate limiting, circuit breaking.\n */\n intercept?(plan: TPlan, ctx: RuntimeMiddlewareContext): Promise<InterceptResult | undefined>;\n /**\n * Fires after the family runtime has produced a draft execution\n * plan from the AST, but before the family encodes parameter values\n * to driver wire format. Mutations applied via the\n * family-specific `params` mutator are visible to the subsequent\n * encode step.\n *\n * Lifecycle position (SQL example):\n * `runBeforeCompile → lowerSqlPlan → beforeExecute → encodeParams → intercept → driver`.\n *\n * The `params` argument is a family-specific {@link ParamRefMutator}\n * scoped to the value slots of `ParamRef` nodes in the plan's AST.\n * Middleware that doesn't need to mutate params can ignore the\n * argument; existing `(plan)` / `(plan, ctx)` bodies stay compatible.\n *\n * `ctx.signal` carries the per-query `AbortSignal`; middleware that\n * wraps a network SDK forwards it. Cooperative cancellation\n * surfaces a `RUNTIME.ABORTED { phase: 'beforeExecute' }` envelope\n * promptly even when the body ignores the signal.\n *\n * Intercept ordering: `intercept` runs *after* this hook; an\n * interceptor that short-circuits the driver path still observes\n * the post-`beforeExecute`, fully-encoded plan. The trade-off is\n * that any `beforeExecute` SDK round-trips happen even when a\n * downstream interceptor would have skipped the driver entirely.\n */\n beforeExecute?(\n plan: TPlan,\n ctx: RuntimeMiddlewareContext,\n params?: TMutator,\n ): void | Promise<void>;\n onRow?(row: Record<string, unknown>, plan: TPlan, ctx: RuntimeMiddlewareContext): Promise<void>;\n afterExecute?(\n plan: TPlan,\n result: AfterExecuteResult,\n ctx: RuntimeMiddlewareContext,\n ): Promise<void>;\n}\n\n/**\n * Cross-family middleware — one that doesn't constrain `familyId` or\n * `targetId` and is therefore compatible with any family runtime's\n * middleware array (`SqlMiddleware[]`, `MongoMiddleware[]`, etc.).\n *\n * The intersection `RuntimeMiddleware & { familyId?: undefined; targetId?: undefined }`\n * pins both optional properties to exactly `undefined` (intersecting\n * `string | undefined` with `undefined` collapses to `undefined`). Under\n * `exactOptionalPropertyTypes: true`, the plain `RuntimeMiddleware` shape\n * — with `familyId?: string` — is *not* assignable to `SqlMiddleware`\n * (which narrows `familyId?: 'sql'`) because `string` is wider than\n * `'sql'`. Pinning the property to `undefined` makes the value a subtype\n * of every narrowed variant: `undefined` extends both `'sql' | undefined`\n * and `'mongo' | undefined`, so a `CrossFamilyMiddleware` value drops\n * into a SQL or Mongo middleware slot without a cast.\n *\n * Cross-family middleware factories (`createCacheMiddleware`, future\n * `audit` / OTel middleware) declare this as their return type so the\n * cross-family typing is named once rather than re-spelled at every call\n * site.\n */\nexport type CrossFamilyMiddleware<TPlan extends QueryPlan = QueryPlan> =\n RuntimeMiddleware<TPlan> & {\n readonly familyId?: undefined;\n readonly targetId?: undefined;\n };\n\n/**\n * Optional per-`execute` options accepted by every family runtime.\n *\n * `signal` is the per-query cancellation signal. The runtime threads the\n * signal through to every codec call for the query and uses it to short-\n * circuit the row stream with `RUNTIME.ABORTED` when the caller aborts.\n * Omitting the option (or passing `undefined`) preserves today's behavior\n * bit-for-bit.\n */\nexport interface RuntimeExecuteOptions {\n readonly signal?: AbortSignal;\n readonly scope?: 'runtime' | 'connection' | 'transaction';\n}\n\n/**\n * Cross-family SPI for any runtime that can execute plans and be shut down.\n * Each family runtime (SQL, Mongo) satisfies this interface — SQL nominally,\n * Mongo structurally (due to its phantom Row parameter using a unique symbol).\n *\n * The `_row` intersection on `execute` connects the `Row` type parameter to the\n * plan, mirroring how `QueryPlan<Row>` carries a phantom `_row?: Row`.\n */\nexport interface RuntimeExecutor<TPlan extends QueryPlan> {\n execute<Row>(\n plan: TPlan & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row>;\n close(): Promise<void>;\n}\n\nexport function checkMiddlewareCompatibility(\n middleware: RuntimeMiddleware,\n runtimeFamilyId: string,\n runtimeTargetId: string,\n): void {\n if (middleware.targetId !== undefined && middleware.familyId === undefined) {\n throw runtimeError(\n 'RUNTIME.MIDDLEWARE_INCOMPATIBLE',\n `Middleware '${middleware.name}' specifies targetId '${middleware.targetId}' without familyId`,\n { middleware: middleware.name, targetId: middleware.targetId },\n );\n }\n\n if (middleware.familyId !== undefined && middleware.familyId !== runtimeFamilyId) {\n throw runtimeError(\n 'RUNTIME.MIDDLEWARE_FAMILY_MISMATCH',\n `Middleware '${middleware.name}' requires family '${middleware.familyId}' but the runtime is configured for family '${runtimeFamilyId}'`,\n { middleware: middleware.name, middlewareFamilyId: middleware.familyId, runtimeFamilyId },\n );\n }\n\n if (middleware.targetId !== undefined && middleware.targetId !== runtimeTargetId) {\n throw runtimeError(\n 'RUNTIME.MIDDLEWARE_TARGET_MISMATCH',\n `Middleware '${middleware.name}' requires target '${middleware.targetId}' but the runtime is configured for target '${runtimeTargetId}'`,\n { middleware: middleware.name, middlewareTargetId: middleware.targetId, runtimeTargetId },\n );\n }\n}\n","import {\n type AnnotationValue,\n assertAnnotationsApplicable,\n type OperationKind,\n} from './annotations';\n\n/**\n * Per-terminal meta configurator handed to user callbacks. The terminal's\n * operation kind `K` is fixed by the terminal that constructed the builder;\n * `annotate(...)` accepts only annotations whose declared `Kinds` include\n * `K`.\n *\n * The conditional parameter type\n * `K extends Kinds ? AnnotationValue<P, Kinds> : never` collapses to `never`\n * for inapplicable annotations, surfacing the mismatch as a type error at\n * the call site of `meta.annotate(...)`. No variadic-tuple inference is\n * involved — TypeScript infers `Kinds` from the annotation argument and\n * checks the conditional directly.\n *\n * The runtime gate inside `annotate` (via\n * `assertAnnotationsApplicable`) catches cast / `any` / dynamic bypasses\n * and throws `RUNTIME.ANNOTATION_INAPPLICABLE`.\n *\n * `annotate` returns the builder for chaining; the return value of the\n * configurator callback is unused, so both block-body and expression-body\n * callbacks compile.\n *\n * @example\n * ```typescript\n * await db.User.find({ id }, (meta) => meta.annotate(cacheAnnotation({ ttl: 60 })));\n * await db.User.create(input, (meta) => {\n * meta.annotate(auditAnnotation({ actor: 'system' }));\n * meta.annotate(otelAnnotation({ traceId }));\n * });\n * ```\n */\nexport interface MetaBuilder<K extends OperationKind> {\n annotate<P, Kinds extends OperationKind>(\n annotation: K extends Kinds ? AnnotationValue<P, Kinds> : never,\n ): this;\n}\n\n/**\n * Lane-side view of a meta builder. Extends the public `MetaBuilder<K>`\n * surface with `annotations` so lane terminals can read the recorded map\n * after invoking the user configurator.\n *\n * Lane terminals construct one of these via `createMetaBuilder(kind, terminalName)`,\n * pass it to the user callback as `MetaBuilder<K>` (the narrower public\n * view), then read `meta.annotations` to thread the recorded values into\n * `plan.meta.annotations`.\n */\nexport interface LaneMetaBuilder<K extends OperationKind> extends MetaBuilder<K> {\n readonly annotations: ReadonlyMap<string, AnnotationValue<unknown, OperationKind>>;\n}\n\nclass MetaBuilderImpl<K extends OperationKind> implements LaneMetaBuilder<K> {\n readonly #kind: K;\n readonly #terminalName: string;\n readonly #annotations = new Map<string, AnnotationValue<unknown, OperationKind>>();\n\n constructor(kind: K, terminalName: string) {\n this.#kind = kind;\n this.#terminalName = terminalName;\n }\n\n get annotations(): ReadonlyMap<string, AnnotationValue<unknown, OperationKind>> {\n return this.#annotations;\n }\n\n annotate<P, Kinds extends OperationKind>(\n annotation: K extends Kinds ? AnnotationValue<P, Kinds> : never,\n ): this {\n // Inside the body, the conditional `K extends Kinds ? AnnotationValue<P, Kinds> : never`\n // is opaque to TypeScript — it can't pick a branch without a concrete\n // K. Widen to the structural shape so we can call into the runtime\n // gate. The runtime gate (assertAnnotationsApplicable) is what\n // catches cast bypasses where the conditional would have resolved to\n // `never` had the type checker been allowed to specialise.\n const value = annotation as AnnotationValue<unknown, OperationKind>;\n assertAnnotationsApplicable([value], this.#kind, this.#terminalName);\n this.#annotations.set(value.namespace, value);\n return this;\n }\n}\n\n/**\n * Construct a lane-side meta builder for a terminal of operation kind `K`.\n *\n * Lane terminals call this with their `kind` (`'read'` or `'write'`) and a\n * `terminalName` for error messages, hand the resulting builder to the\n * user-supplied configurator callback (typed as `MetaBuilder<K>`, the\n * narrower public view), and read `meta.annotations` afterwards to thread\n * the recorded values into `plan.meta.annotations`.\n */\nexport function createMetaBuilder<K extends OperationKind>(\n kind: K,\n terminalName: string,\n): LaneMetaBuilder<K> {\n return new MetaBuilderImpl(kind, terminalName);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runtime.mjs","names":["candidate","#kind","#terminalName","#annotations"],"sources":["../src/execution/runtime-error.ts","../src/annotations.ts","../src/execution/async-iterable-result.ts","../src/execution/race-against-abort.ts","../src/execution/before-execute-chain.ts","../src/execution/run-with-middleware.ts","../src/execution/runtime-core.ts","../src/execution/runtime-middleware.ts","../src/meta-builder.ts"],"sourcesContent":["export interface RuntimeErrorEnvelope extends Error {\n readonly code: string;\n readonly category: 'PLAN' | 'CONTRACT' | 'LINT' | 'BUDGET' | 'RUNTIME';\n readonly severity: 'error';\n readonly details?: Record<string, unknown>;\n}\n\n/**\n * Stable code emitted by the runtime when an in-flight `execute()`\n * is cancelled via the per-query `AbortSignal`. The envelope's\n * `details.phase` distinguishes where the abort was observed:\n *\n * - `'encode'` — abort fired during `encodeParams` (SQL) or\n * `resolveValue` (Mongo).\n * - `'decode'` — abort fired during `decodeRow` / `decodeField`.\n * - `'stream'` — abort fired between rows or before any codec call\n * (already-aborted at entry).\n * - `'beforeExecute'` / `'afterExecute'` / `'onRow'` — abort fired\n * on entry to or during the corresponding middleware phase\n * (cooperative cancellation per the param-transform seam).\n */\nexport const RUNTIME_ABORTED = 'RUNTIME.ABORTED' as const;\n\n/** Discriminator placed in `details.phase` of a `RUNTIME.ABORTED` envelope. */\nexport type RuntimeAbortedPhase =\n | 'encode'\n | 'decode'\n | 'stream'\n | 'beforeExecute'\n | 'afterExecute'\n | 'onRow';\n\n/**\n * Type guard for the runtime-error envelope produced by `runtimeError`.\n *\n * Prefer this over duck-typing on `error.code` directly so consumers stay\n * insulated from the envelope's internal shape.\n */\nexport function isRuntimeError(error: unknown): error is RuntimeErrorEnvelope {\n return (\n error instanceof Error &&\n 'code' in error &&\n typeof (error as { code?: unknown }).code === 'string' &&\n 'category' in error &&\n 'severity' in error\n );\n}\n\nexport function runtimeError(\n code: string,\n message: string,\n details?: Record<string, unknown>,\n): RuntimeErrorEnvelope {\n const error = new Error(message) as RuntimeErrorEnvelope;\n Object.defineProperty(error, 'name', {\n value: 'RuntimeError',\n configurable: true,\n });\n\n return Object.assign(error, {\n code,\n category: resolveCategory(code),\n severity: 'error' as const,\n message,\n details,\n });\n}\n\nfunction resolveCategory(code: string): RuntimeErrorEnvelope['category'] {\n const prefix = code.split('.')[0] ?? 'RUNTIME';\n switch (prefix) {\n case 'PLAN':\n case 'CONTRACT':\n case 'LINT':\n case 'BUDGET':\n return prefix;\n default:\n return 'RUNTIME';\n }\n}\n\n/**\n * Construct a `RUNTIME.ABORTED` envelope. Phase distinguishes where the\n * abort was observed — codec call sites (`encode` / `decode` / `stream`)\n * or middleware seams (`beforeExecute` / `afterExecute` / `onRow`), as\n * enumerated on {@link RuntimeAbortedPhase}. Cause carries\n * `signal.reason` verbatim from the platform — native abort produces a\n * `DOMException`, explicit `controller.abort(reason)` produces whatever\n * the caller passed. No synthesis happens here.\n */\nexport function runtimeAborted(phase: RuntimeAbortedPhase, cause?: unknown): RuntimeErrorEnvelope {\n const envelope = runtimeError(RUNTIME_ABORTED, `Operation aborted during ${phase}`, { phase });\n return Object.assign(envelope, { cause });\n}\n","import { runtimeError } from './execution/runtime-error';\n\n/**\n * The kinds of operations an annotation may apply to.\n *\n * - `'read'` — `SELECT` / `find` / `first` / `all` / `count` / aggregates.\n * - `'write'` — `INSERT` / `UPDATE` / `DELETE` / `create` / `update` / `delete` / `upsert`.\n *\n * Annotations declare which kinds they apply to via `defineAnnotation`'s\n * `applicableTo` option; lane terminals enforce the constraint at both the\n * type level (via `ValidAnnotations`) and at runtime (via\n * `assertAnnotationsApplicable`).\n *\n * Finer-grained kinds (`'select' | 'insert' | 'update' | 'delete' | 'upsert'`)\n * are deliberately deferred. The binary covers the common case (the cache\n * middleware applies to reads; an audit annotation would apply to writes;\n * tracing/OTel applies to both). When a real annotation surfaces that needs\n * a finer split, the union widens and existing handles remain typecheckable.\n */\nexport type OperationKind = 'read' | 'write';\n\n/**\n * An applied annotation. Carries the namespace, the typed payload, and the\n * `applicableTo` set the underlying handle declared. The `__annotation`\n * brand lets `read` distinguish branded user annotations from arbitrary\n * data that may happen to live under the same namespace key in\n * `plan.meta.annotations` (e.g. framework-internal metadata such as\n * `meta.annotations.codecs`).\n *\n * Constructed by calling an `AnnotationHandle` directly (e.g.\n * `cacheAnnotation({ ttl: 60 })`); never instantiated by hand.\n */\nexport interface AnnotationValue<Payload, Kinds extends OperationKind> {\n readonly __annotation: true;\n readonly namespace: string;\n readonly value: Payload;\n readonly applicableTo: ReadonlySet<Kinds>;\n}\n\n/**\n * Handle returned by `defineAnnotation`. The handle is **callable**: the\n * call signature wraps a `Payload` into an `AnnotationValue` ready to\n * pass to a lane terminal's variadic `annotations` argument. The handle\n * also carries static metadata as own properties:\n *\n * - `namespace` — the namespace string the handle was declared with.\n * - `applicableTo` — the frozen `ReadonlySet<Kinds>` consumed by both\n * the type-level `ValidAnnotations` gate and the runtime\n * `assertAnnotationsApplicable` gate.\n * - `read(plan)` — extract the `Payload` from a plan's `meta.annotations`\n * if a value was previously written under this handle's namespace.\n * Returns `undefined` when the annotation is absent or when the stored\n * value is not a branded `AnnotationValue` (e.g. framework-internal\n * metadata under the same namespace key).\n *\n * Handles are the only supported public entry point for reading and\n * writing annotations. Direct mutation of `plan.meta.annotations` is not\n * part of the public API.\n *\n * ```typescript\n * const cacheAnnotation = defineAnnotation<{ ttl: number }>()({\n * namespace: 'cache',\n * applicableTo: ['read'],\n * });\n *\n * // Call the handle to construct a value:\n * const applied = cacheAnnotation({ ttl: 60 });\n *\n * // Read a stored value off a plan:\n * const payload = cacheAnnotation.read(plan);\n * ```\n *\n * Note on the inherited `Function.prototype.apply`: because the handle is\n * a function, the property name `apply` resolves to JavaScript's built-in\n * `Function.prototype.apply` (which lets you invoke a function with an\n * array of arguments). This is **not** the construction entry point — to\n * build an `AnnotationValue`, call the handle directly. The\n * `AnnotationHandle` interface deliberately does not declare an `apply`\n * member of its own.\n */\nexport interface AnnotationHandle<Payload, Kinds extends OperationKind> {\n (value: Payload): AnnotationValue<Payload, Kinds>;\n readonly namespace: string;\n readonly applicableTo: ReadonlySet<Kinds>;\n read(plan: {\n readonly meta: { readonly annotations?: Record<string, unknown> };\n }): Payload | undefined;\n}\n\n/**\n * Options accepted by `defineAnnotation`.\n *\n * `namespace` is the string key under which the annotation is stored in\n * `plan.meta.annotations`. **Reserved namespaces** include framework-\n * internal metadata keys; user handles must not use them:\n *\n * - `codecs` — used by the SQL emitter to record per-alias codec ids\n * (`meta.annotations.codecs[alias] = 'pg/text@1'`); the SQL runtime's\n * `decodeRow` reads from this key. A user `defineAnnotation('codecs')`\n * handle is not structurally prevented, but its behavior with the\n * emitter and the runtime is undefined and we make no compatibility\n * guarantees about it.\n * - Target-specific keys such as `pg` (and equivalents on other\n * targets) are similarly reserved for adapter / target use.\n *\n * `applicableTo` declares which operation kinds the annotation may attach\n * to. The lane terminals' type-level `ValidAnnotations<K, As>` gate rejects\n * annotations whose `Kinds` does not include the terminal's `K`; the\n * runtime helper `assertAnnotationsApplicable` does the equivalent at\n * runtime so casts and `any` cannot bypass the gate.\n */\nexport interface DefineAnnotationOptions<Kinds extends OperationKind> {\n readonly namespace: string;\n readonly applicableTo: readonly Kinds[];\n}\n\n/**\n * Defines a typed annotation handle.\n *\n * Two-step call form. The first step takes the `Payload` type argument\n * (TypeScript cannot infer `Payload` from anything in the options, so it\n * must be supplied explicitly); the second step takes the runtime options\n * and infers `Kinds` from the `applicableTo` array via a `const` type\n * parameter, so the operation kinds appear exactly once at the call site.\n *\n * @example\n * ```typescript\n * // Read-only annotation. Lane terminals like `db.User.first(...)` accept\n * // it; `db.User.create(...)` rejects it at the type level.\n * const cacheAnnotation = defineAnnotation<{ ttl?: number; skip?: boolean }>()({\n * namespace: 'cache',\n * applicableTo: ['read'],\n * }); // Kinds inferred as 'read'\n *\n * // Write-only annotation. Mirror image.\n * const auditAnnotation = defineAnnotation<{ actor: string }>()({\n * namespace: 'audit',\n * applicableTo: ['write'],\n * }); // Kinds inferred as 'write'\n *\n * // Annotation applicable to both kinds (e.g. tracing).\n * const otelAnnotation = defineAnnotation<{ traceId: string }>()({\n * namespace: 'otel',\n * applicableTo: ['read', 'write'],\n * }); // Kinds inferred as 'read' | 'write'\n * ```\n *\n * **Reserved namespaces.** See `DefineAnnotationOptions.namespace` for the\n * list of framework-internal namespaces (`codecs`, target-specific keys).\n * `defineAnnotation` does not structurally prevent a user from naming a\n * reserved namespace, but the framework makes no compatibility guarantee\n * about handles that do.\n */\nexport function defineAnnotation<Payload>(): <const Kinds extends OperationKind>(\n options: DefineAnnotationOptions<Kinds>,\n) => AnnotationHandle<Payload, Kinds> {\n return <const Kinds extends OperationKind>(\n options: DefineAnnotationOptions<Kinds>,\n ): AnnotationHandle<Payload, Kinds> => {\n const namespace = options.namespace;\n const applicableTo: ReadonlySet<Kinds> = Object.freeze(new Set(options.applicableTo));\n\n function handle(value: Payload): AnnotationValue<Payload, Kinds> {\n return Object.freeze({\n __annotation: true as const,\n namespace,\n value,\n applicableTo,\n });\n }\n\n function read(plan: {\n readonly meta: { readonly annotations?: Record<string, unknown> };\n }): Payload | undefined {\n const stored = plan.meta.annotations?.[namespace];\n if (!isAnnotationValue(stored)) {\n return undefined;\n }\n if (stored.namespace !== namespace) {\n // Defensive: a different handle wrote under our namespace key.\n return undefined;\n }\n return stored.value as Payload;\n }\n\n return Object.freeze(\n Object.assign(handle, {\n namespace,\n applicableTo,\n read,\n }),\n );\n };\n}\n\n/**\n * Type-level applicability gate consumed by lane terminals.\n *\n * Maps a tuple of `AnnotationValue`s to a tuple where each element either\n * keeps its annotation type (when the annotation's declared `Kinds`\n * includes the terminal's operation kind `K`) or resolves to `never`\n * (when the kinds are incompatible). A `never` element makes the entire\n * tuple unassignable, surfacing the mismatch as a type error at the call\n * site of the terminal.\n *\n * The SQL DSL builders constrain their variadic `...annotations`\n * parameter via `As & ValidAnnotations<K, As>`. **The intersection is\n * load-bearing** — see the note below. The ORM terminals deliberately\n * sidestep this trick by taking one annotation per `meta.annotate(...)`\n * call (no variadic-tuple inference involved), so `ValidAnnotations` is\n * consumed only by the SQL DSL today.\n *\n * @example\n * ```typescript\n * class SelectQuery<Row> {\n * annotate<As extends readonly AnnotationValue<unknown, OperationKind>[]>(\n * ...annotations: As & ValidAnnotations<'read', As>\n * ): SelectQuery<Row>;\n * }\n *\n * class InsertQuery<Row> {\n * annotate<As extends readonly AnnotationValue<unknown, OperationKind>[]>(\n * ...annotations: As & ValidAnnotations<'write', As>\n * ): InsertQuery<Row>;\n * }\n *\n * db.users.select('id').annotate(cacheAnnotation({ ttl: 60 }));\n * // ✓ cacheAnnotation declares 'read'; SelectQuery.annotate requires 'read'.\n *\n * db.users.insert([{ name: 'Alice' }]).annotate(cacheAnnotation({ ttl: 60 }));\n * // ✗ cacheAnnotation declares 'read'; InsertQuery.annotate requires 'write'.\n * // Element resolves to `never` → tuple unassignable → type error.\n * ```\n *\n * **Why `As & ValidAnnotations<K, As>` and not `ValidAnnotations<K, As>`\n * alone.** TypeScript's variadic-tuple inference is too forgiving when\n * the parameter type refers to `As` only through `ValidAnnotations`: it\n * will pick an `As` that makes the call valid even when the gated tuple\n * would contain `never` for an inapplicable element. The intersection\n * pins `As` to the actual call-site tuple AND requires it to be\n * assignable to the gated form. A `never` element in the gated tuple\n * then collapses the corresponding intersection position to `never`,\n * and the inapplicable argument fails to assign — surfacing the mismatch\n * as a type error at the call site.\n *\n * The runtime helper `assertAnnotationsApplicable` covers the equivalent\n * check at runtime so casts and `any` cannot bypass this gate.\n */\nexport type ValidAnnotations<\n K extends OperationKind,\n As extends readonly AnnotationValue<unknown, OperationKind>[],\n> = {\n readonly [I in keyof As]: As[I] extends AnnotationValue<infer P, infer Kinds>\n ? K extends Kinds\n ? AnnotationValue<P, Kinds>\n : never\n : never;\n};\n\n/**\n * Runtime applicability gate. Throws `RUNTIME.ANNOTATION_INAPPLICABLE` if\n * any annotation in `annotations` declares an `applicableTo` set that does\n * not include `kind`. Used by lane terminals (SQL DSL builders' `.build()`,\n * ORM `Collection` terminals) to fail closed when the type-level\n * `ValidAnnotations` gate is bypassed via cast / `any` / dynamic\n * invocation.\n *\n * Passes silently on:\n * - empty arrays\n * - annotations whose `applicableTo` includes `kind`\n *\n * Throws on:\n * - any annotation whose `applicableTo` does not include `kind`. The\n * error names the offending annotation's `namespace` and the\n * `terminalName` so users can locate the misuse.\n *\n * @example\n * ```typescript\n * // Inside an ORM read terminal:\n * assertAnnotationsApplicable(annotations, 'read', 'first');\n * ```\n */\nexport function assertAnnotationsApplicable(\n annotations: readonly AnnotationValue<unknown, OperationKind>[],\n kind: OperationKind,\n terminalName: string,\n): void {\n for (const annotation of annotations) {\n if (!annotation.applicableTo.has(kind)) {\n throw runtimeError(\n 'RUNTIME.ANNOTATION_INAPPLICABLE',\n `Annotation '${annotation.namespace}' is not applicable to '${kind}' operations (terminal: '${terminalName}'). The annotation declares applicableTo = [${Array.from(\n annotation.applicableTo,\n )\n .map((k) => `'${k}'`)\n .join(', ')}].`,\n {\n namespace: annotation.namespace,\n terminalName,\n kind,\n applicableTo: Array.from(annotation.applicableTo),\n },\n );\n }\n }\n}\n\n/**\n * Type guard for branded annotation values stored in `plan.meta.annotations`.\n *\n * Internal — used by `AnnotationHandle.read` to distinguish user\n * annotations (created by calling a handle returned from\n * `defineAnnotation(...)`) from framework-internal metadata that may\n * happen to live under the same namespace key.\n */\nfunction isAnnotationValue(value: unknown): value is AnnotationValue<unknown, OperationKind> {\n if (value === null || typeof value !== 'object') {\n return false;\n }\n const candidate = value as { readonly __annotation?: unknown };\n return candidate.__annotation === true;\n}\n","import { runtimeError } from './runtime-error';\n\nexport class AsyncIterableResult<Row> implements AsyncIterable<Row>, PromiseLike<Row[]> {\n private readonly generator: AsyncGenerator<Row, void, unknown>;\n private consumed = false;\n private consumedBy: 'bufferedArray' | 'iterator' | undefined;\n private bufferedArrayPromise: Promise<Row[]> | undefined;\n\n constructor(generator: AsyncGenerator<Row, void, unknown>) {\n this.generator = generator;\n }\n\n [Symbol.asyncIterator](): AsyncIterator<Row> {\n if (this.consumed) {\n throw runtimeError(\n 'RUNTIME.ITERATOR_CONSUMED',\n `AsyncIterableResult iterator has already been consumed via ${this.consumedBy === 'bufferedArray' ? 'toArray()/then()' : 'for-await loop'}. Each AsyncIterableResult can only be iterated once.`,\n {\n consumedBy: this.consumedBy,\n suggestion:\n this.consumedBy === 'bufferedArray'\n ? 'If you need to iterate multiple times, store the results from toArray() in a variable and reuse that.'\n : 'If you need to iterate multiple times, use toArray() to collect all results first.',\n },\n );\n }\n this.consumed = true;\n this.consumedBy = 'iterator';\n return this.generator;\n }\n\n toArray(): Promise<Row[]> {\n if (this.consumedBy === 'iterator') {\n return Promise.reject(\n runtimeError(\n 'RUNTIME.ITERATOR_CONSUMED',\n 'AsyncIterableResult iterator has already been consumed via for-await loop. Each AsyncIterableResult can only be iterated once.',\n {\n consumedBy: this.consumedBy,\n suggestion:\n 'The iterator was already consumed by a for-await loop. Use toArray() or await the result before iterating.',\n },\n ),\n );\n }\n\n if (this.bufferedArrayPromise) {\n return this.bufferedArrayPromise;\n }\n\n this.consumed = true;\n this.consumedBy = 'bufferedArray';\n this.bufferedArrayPromise = (async () => {\n const out: Row[] = [];\n for await (const item of this.generator) {\n out.push(item);\n }\n return out;\n })();\n return this.bufferedArrayPromise;\n }\n\n async first(): Promise<Row | null> {\n const rows = await this.toArray();\n return rows[0] ?? null;\n }\n\n async firstOrThrow(): Promise<Row> {\n const row = await this.first();\n if (row === null)\n throw runtimeError(\n 'RUNTIME.NO_ROWS',\n 'Expected at least one row, but none were returned',\n {},\n );\n return row;\n }\n\n // biome-ignore lint/suspicious/noThenProperty: PromiseLike implementation is intentional for await support.\n then<TResult1 = Row[], TResult2 = never>(\n onfulfilled?: ((value: Row[]) => TResult1 | PromiseLike<TResult1>) | undefined | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | undefined | null,\n ): PromiseLike<TResult1 | TResult2> {\n return this.toArray().then(onfulfilled, onrejected);\n }\n}\n","import type { RuntimeAbortedPhase } from './runtime-error';\nimport { runtimeAborted } from './runtime-error';\n\n/**\n * Throw a phase-tagged `RUNTIME.ABORTED` envelope if the supplied\n * context is already aborted at the precheck site. Centralises the\n * `if (ctx.signal?.aborted) throw runtimeAborted(...)` pattern that\n * every codec dispatch site (and the `beforeExecute` middleware phase)\n * repeats. Accepts both the framework `CodecCallContext` and the\n * `RuntimeMiddlewareContext`; both expose `signal?: AbortSignal`.\n */\nexport function checkAborted(\n ctx: { readonly signal?: AbortSignal },\n phase: RuntimeAbortedPhase,\n): void {\n if (ctx.signal?.aborted) {\n throw runtimeAborted(phase, ctx.signal.reason);\n }\n}\n\n/**\n * Race a per-cell `Promise.all` (or any other in-flight work promise) against\n * the supplied abort signal so the runtime returns `RUNTIME.ABORTED` promptly\n * even when codec bodies ignore the signal. In-flight bodies that ignore the\n * signal are abandoned and run to completion in the background — the\n * cooperative-cancellation contract documented in ADR 204.\n *\n * Call sites still SHOULD pre-check `signal.aborted` and short-circuit with\n * a phase-tagged `RUNTIME.ABORTED` envelope before invoking this helper —\n * that path is the canonical \"aborted at entry\" surface and avoids\n * scheduling the work promise. As a defensive belt-and-braces, this helper\n * also handles the already-aborted case internally: `AbortSignal` does not\n * replay past abort events to listeners registered after the abort, so we\n * inspect `signal.aborted` synchronously and reject with the sentinel\n * before installing the listener. The rejection is still attributed to the\n * abort path via the sentinel-identity check.\n *\n * Distinguishing the rejection source is load-bearing for AC-ERR4\n * (`RUNTIME.ENCODE_FAILED` / `RUNTIME.DECODE_FAILED` pass through unchanged).\n * The semantically equivalent `abortable(signal)` helper in\n * `@prisma-next/utils` rejects with `signal.reason ?? new DOMException(...)`,\n * which is not stably distinguishable from a codec-thrown error by identity\n * alone (a fresh fallback DOMException is allocated per call). We instead\n * track abort attribution with a unique sentinel: only the `onAbort` listener\n * installed here ever rejects with the sentinel, so an `error === sentinel`\n * identity check after the race is unambiguous.\n *\n * Lives in `framework-components` (rather than the SQL family, where it\n * originated in m2) so every family runtime that needs cooperative\n * cancellation around a codec-dispatch `Promise.all` (SQL encode + decode\n * today, Mongo encode in m3) shares the same attribution logic.\n */\nexport async function raceAgainstAbort<T>(\n work: Promise<T>,\n signal: AbortSignal | undefined,\n phase: RuntimeAbortedPhase,\n): Promise<T> {\n if (signal === undefined) {\n return await work;\n }\n const sentinel: { reason: unknown } = { reason: undefined };\n let onAbort: (() => void) | undefined;\n\n const abortPromise = new Promise<never>((_, reject) => {\n if (signal.aborted) {\n sentinel.reason = signal.reason;\n reject(sentinel);\n return;\n }\n onAbort = () => {\n sentinel.reason = signal.reason;\n reject(sentinel);\n };\n signal.addEventListener('abort', onAbort, { once: true });\n });\n\n try {\n return await Promise.race([work, abortPromise]);\n } catch (error) {\n if (error === sentinel) {\n throw runtimeAborted(phase, sentinel.reason);\n }\n throw error;\n } finally {\n if (onAbort) {\n signal.removeEventListener('abort', onAbort);\n }\n }\n}\n","import type { ExecutionPlan } from './query-plan';\nimport { checkAborted, raceAgainstAbort } from './race-against-abort';\nimport type {\n ParamRefMutator,\n RuntimeMiddleware,\n RuntimeMiddlewareContext,\n} from './runtime-middleware';\n\n/**\n * Runs every middleware's `beforeExecute` hook in registration order,\n * threading through the (optional) family-specific `paramsMutator`.\n *\n * Why this lives outside {@link runWithMiddleware}: middleware that\n * mutates parameter values (e.g. cipherstash's bulk-encrypt SDK\n * round-trip) must run *before* the family runtime encodes those\n * parameters to driver wire format. Family runtimes call\n * `runBeforeExecuteChain` between the AST → plan lowering step and\n * the parameter encode step; the encode then observes the mutator's\n * `currentParams()` view. `runWithMiddleware` retains the rest of\n * the lifecycle (`intercept`, driver/row source loop, `onRow`,\n * `afterExecute`) but no longer fires `beforeExecute` itself.\n *\n * Lifecycle within this helper:\n *\n * 1. For each middleware in registration order, if `beforeExecute`\n * is implemented:\n * - `checkAborted(ctx, 'beforeExecute')` short-circuits if the\n * caller already aborted at entry.\n * - The hook is invoked with `(plan, ctx, paramsMutator)`. A\n * middleware body that ignores the mutator stays compatible —\n * JavaScript allows extra positional arguments.\n * - If the hook returns a Promise, it is raced against\n * `ctx.signal` via {@link raceAgainstAbort} so cooperative\n * cancellation surfaces a `RUNTIME.ABORTED { phase:\n * 'beforeExecute' }` envelope even when the body itself\n * ignores the signal.\n *\n * Error propagation: any error thrown by a `beforeExecute` body\n * (or surfaced by the abort race) propagates out of this helper\n * unchanged. The family runtime is responsible for converting it\n * into the appropriate `afterExecute(completed: false)` notification\n * once `runWithMiddleware` runs.\n *\n * Relationship to {@link runWithMiddleware}: the framework's\n * `RuntimeCore.execute` template calls this helper between\n * `lower(plan)` and `runWithMiddleware(...)`. Family runtimes that\n * override `execute` (e.g. SQL, which inlines lower + encode for\n * direct mutator threading) call this helper themselves at the\n * equivalent point — between the family's AST → draft-plan\n * lowering and the parameter-encode step.\n *\n * Intercept ordering: this helper fires unconditionally before\n * `runWithMiddleware`. `intercept` (inside `runWithMiddleware`)\n * therefore observes the post-`beforeExecute` plan — mutator\n * mutations are visible in the params interceptors see. The\n * trade-off is documented on `RuntimeMiddleware.intercept`.\n */\nexport async function runBeforeExecuteChain<\n TExec extends ExecutionPlan,\n TMutator extends ParamRefMutator = ParamRefMutator,\n>(\n plan: TExec,\n middleware: ReadonlyArray<RuntimeMiddleware<TExec, TMutator>>,\n ctx: RuntimeMiddlewareContext,\n paramsMutator?: TMutator,\n): Promise<void> {\n for (const mw of middleware) {\n if (!mw.beforeExecute) {\n continue;\n }\n checkAborted(ctx, 'beforeExecute');\n const work = mw.beforeExecute(plan, ctx, paramsMutator as TMutator);\n if (work !== undefined) {\n await raceAgainstAbort(Promise.resolve(work), ctx.signal, 'beforeExecute');\n }\n }\n}\n","import { AsyncIterableResult } from './async-iterable-result';\nimport type { ExecutionPlan } from './query-plan';\nimport type { RuntimeMiddleware, RuntimeMiddlewareContext } from './runtime-middleware';\n\n/**\n * Drives a single execution of `runDriver()` through the middleware\n * lifecycle's intercept + row-source + termination phases.\n *\n * Lifecycle, in order:\n * 1. For each middleware in registration order: `intercept(exec, ctx)`. The\n * first non-`undefined` result wins; subsequent middleware's `intercept`\n * does not fire. On a hit, the runtime emits a `middleware.intercept`\n * debug event naming the winning middleware, switches the row source to\n * the intercepted rows, and proceeds with `source: 'middleware'`. On\n * all-passthrough (every `intercept` returns `undefined` or is omitted),\n * `source: 'driver'` is used and the row source is `runDriver()`.\n * 2. Iterate the row source. On the driver path, for each row, for each\n * middleware in registration order: `onRow(row, exec, ctx)`; then yield\n * the row. On the intercepted hit path, `onRow` is skipped — intercepted\n * rows did not originate from a driver row stream — but rows are still\n * yielded to the consumer in order.\n * 3. On successful completion: for each middleware in registration order:\n * `afterExecute(exec, { rowCount, latencyMs, completed: true, source },\n * ctx)`.\n * 4. On any error thrown during steps 1–2: for each middleware in\n * registration order: `afterExecute(exec, { rowCount, latencyMs,\n * completed: false, source }, ctx)`. Errors thrown by `afterExecute`\n * during the error path are swallowed so they do not mask the original\n * error. The original error is then rethrown.\n *\n * `beforeExecute` is **not** fired here — see\n * {@link runBeforeExecuteChain} in `before-execute-chain.ts`. Family\n * runtimes call that helper between the AST → plan lowering step and\n * the parameter encode step so middleware that mutates ParamRef\n * values (e.g. cipherstash bulk-encrypt) can have its mutations\n * visible to encode. `runWithMiddleware` operates on the fully-\n * encoded plan; interceptors therefore observe a fully-mutated,\n * encoded plan.\n *\n * The `source` field on `AfterExecuteResult` lets observers (telemetry,\n * lints, budgets) distinguish driver-served from middleware-served\n * executions without needing their own out-of-band signal.\n *\n * This helper is the single canonical implementation of the\n * intercept-and-row-source loop; family runtimes should not\n * reimplement it.\n */\nexport function runWithMiddleware<TExec extends ExecutionPlan, Row>(\n exec: TExec,\n middleware: ReadonlyArray<RuntimeMiddleware<TExec>>,\n ctx: RuntimeMiddlewareContext,\n runDriver: () => AsyncIterable<Row>,\n): AsyncIterableResult<Row> {\n const iterator = async function* (): AsyncGenerator<Row, void, unknown> {\n const startedAt = Date.now();\n let rowCount = 0;\n let completed = false;\n let source: 'driver' | 'middleware' = 'driver';\n // Deferred so a winning interceptor can skip `runDriver()` entirely.\n // For factories that lazily produce async generators this is a no-op,\n // but factories that do eager work (e.g. acquiring a connection,\n // sending a query) must not run on the intercepted hit path.\n let rowSource: AsyncIterable<Row> | Iterable<Row> | undefined;\n\n try {\n for (const mw of middleware) {\n if (!mw.intercept) {\n continue;\n }\n // Mark the lifecycle as middleware-driven *before* awaiting the\n // hook. If `intercept` throws, the catch block reports the failure\n // as `source: 'middleware'` — the failure originated in the\n // intercept chain, not in the driver. If `intercept` returns\n // `undefined` (passthrough), we revert to `'driver'` and continue.\n source = 'middleware';\n const result = await mw.intercept(exec, ctx);\n if (result === undefined) {\n source = 'driver';\n continue;\n }\n ctx.log.debug?.({ event: 'middleware.intercept', middleware: mw.name });\n // The intercepted rows are typed as `Record<string, unknown>` at\n // the SPI level; the consumer's `Row` type parameter is enforced by\n // the caller (via the plan's phantom `_row`) the same way driver\n // rows are. Cast through unknown to bridge the SPI shape to the\n // caller-supplied Row.\n rowSource = result.rows as unknown as AsyncIterable<Row> | Iterable<Row>;\n break;\n }\n\n if (source === 'driver') {\n rowSource = runDriver();\n }\n\n // `rowSource` is always assigned by this point: either the intercepted\n // rows (on a hit) or `runDriver()` (on the driver path).\n for await (const row of rowSource as AsyncIterable<Row> | Iterable<Row>) {\n if (source === 'driver') {\n for (const mw of middleware) {\n if (mw.onRow) {\n await mw.onRow(row as Record<string, unknown>, exec, ctx);\n }\n }\n }\n rowCount++;\n yield row;\n }\n\n completed = true;\n } catch (error) {\n const latencyMs = Date.now() - startedAt;\n for (const mw of middleware) {\n if (mw.afterExecute) {\n try {\n await mw.afterExecute(exec, { rowCount, latencyMs, completed, source }, ctx);\n } catch {\n // Swallow afterExecute errors during the error path so they do not\n // mask the original error.\n }\n }\n }\n\n throw error;\n }\n\n const latencyMs = Date.now() - startedAt;\n for (const mw of middleware) {\n if (mw.afterExecute) {\n await mw.afterExecute(exec, { rowCount, latencyMs, completed, source }, ctx);\n }\n }\n };\n\n return new AsyncIterableResult(iterator());\n}\n","import type { CodecCallContext } from '../shared/codec-types';\nimport { AsyncIterableResult } from './async-iterable-result';\nimport { runBeforeExecuteChain } from './before-execute-chain';\nimport type { ExecutionPlan, QueryPlan } from './query-plan';\nimport { checkAborted } from './race-against-abort';\nimport { runWithMiddleware } from './run-with-middleware';\nimport type {\n RuntimeExecuteOptions,\n RuntimeExecutor,\n RuntimeMiddleware,\n RuntimeMiddlewareContext,\n} from './runtime-middleware';\n\n/**\n * Constructor options shared by every concrete `RuntimeCore` subclass.\n *\n * Family runtimes typically build the middleware list and the\n * `RuntimeMiddlewareContext` themselves (running compatibility checks,\n * narrowing the context's `contract` field, etc.) before calling `super`.\n */\nexport interface RuntimeCoreOptions<TMiddleware extends RuntimeMiddleware<ExecutionPlan>> {\n readonly middleware: ReadonlyArray<TMiddleware>;\n readonly ctx: RuntimeMiddlewareContext;\n}\n\n/**\n * Family-agnostic abstract runtime base.\n *\n * Defines the entire `execute(plan)` template in one place:\n *\n * 1. `runBeforeCompile(plan)` — concrete; defaults to identity. SQL overrides\n * this to run its `beforeCompile` middleware-hook chain.\n * 2. `lower(plan)` — abstract. Each family produces its `*ExecutionPlan`\n * (SQL via `lowerSqlPlan`, Mongo via `adapter.lower`).\n * 3. `runBeforeExecuteChain(exec, this.middleware, this.ctx)` — concrete;\n * runs every middleware's `beforeExecute` hook after lowering but\n * before the row source is opened. Family runtimes that need a\n * params mutator visible to a downstream encode step (SQL) override\n * `execute` and call this helper themselves at the equivalent\n * pre-encode point.\n * 4. `runWithMiddleware(exec, this.middleware, this.ctx,\n * () => runDriver(exec))` — concrete; runs the intercept chain,\n * drives the row source, fires `onRow` / `afterExecute`. Does\n * **not** fire `beforeExecute` — see step 3.\n *\n * Concrete subclasses must implement `lower`, `runDriver`, and `close`.\n *\n * The class is generic over:\n * - `TPlan` — the family's pre-lowering plan type.\n * - `TExec` — the family's post-lowering (executable) plan type.\n * - `TMiddleware` — the family's middleware type. Constrained to\n * `RuntimeMiddleware<TExec>` because `runWithMiddleware` invokes the\n * `beforeExecute` / `onRow` / `afterExecute` hooks with the lowered\n * `TExec`. (The spec/plan wording \"RuntimeMiddleware<TPlan>\" is\n * tightened to `<TExec>` here so the helper call typechecks; the\n * intent is unchanged — middleware sees the post-lowering plan.)\n */\nexport abstract class RuntimeCore<\n TPlan extends QueryPlan,\n TExec extends ExecutionPlan,\n TMiddleware extends RuntimeMiddleware<TExec>,\n> implements RuntimeExecutor<TPlan>\n{\n protected readonly middleware: ReadonlyArray<TMiddleware>;\n protected readonly ctx: RuntimeMiddlewareContext;\n\n constructor(options: RuntimeCoreOptions<TMiddleware>) {\n this.middleware = options.middleware;\n this.ctx = options.ctx;\n }\n\n /**\n * Pre-lowering hook for plan rewriting. Defaults to identity. Subclasses\n * may override to run a `beforeCompile` middleware chain (SQL does this\n * to support typed AST rewrites — see `before-compile-chain.ts`).\n */\n protected runBeforeCompile(plan: TPlan): TPlan | Promise<TPlan> {\n return plan;\n }\n\n /**\n * Lower a pre-lowering `TPlan` into the family's executable `TExec`.\n * Family-specific: SQL produces `{ sql, params, ast?, ... }`; Mongo\n * produces `{ command, ... }`.\n *\n * `ctx` carries per-query cancellation (and any future fields on\n * `CodecCallContext`); concrete subclasses forward it to the\n * encode-side codec dispatch site (e.g. SQL's `encodeParams` in m2,\n * Mongo's `resolveValue` in m3). The runtime allocates one ctx per\n * `execute()` call and threads the same reference everywhere; the\n * `signal` field inside may be `undefined`, but the ctx object itself\n * is always present.\n */\n protected abstract lower(plan: TPlan, ctx: CodecCallContext): TExec | Promise<TExec>;\n\n /**\n * Drive the underlying transport for a lowered `TExec`. Yields raw rows\n * directly from the driver as `Record<string, unknown>`; codec decoding\n * (if any) is the subclass's responsibility, applied by wrapping\n * `execute()` rather than living inside this hook.\n *\n * The `Row` type parameter on `execute()` is satisfied by the caller via\n * the plan's phantom `_row`; the runtime treats rows as opaque records\n * here and trusts the caller's row typing.\n */\n protected abstract runDriver(exec: TExec): AsyncIterable<Record<string, unknown>>;\n\n abstract close(): Promise<void>;\n\n execute<Row>(\n plan: TPlan & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row> {\n const self = this;\n const signal = options?.signal;\n // One ctx per execute() call. The ctx object is always allocated; the\n // `signal` field is only included when a signal was supplied (required\n // under exactOptionalPropertyTypes — `{ signal: undefined }` would not\n // satisfy `signal?: AbortSignal`).\n const codecCtx: CodecCallContext = signal === undefined ? {} : { signal };\n\n async function* generator(): AsyncGenerator<Row, void, unknown> {\n // Pre-check the signal at entry so an already-aborted caller observes\n // RUNTIME.ABORTED on the first `next()` without any work being done.\n checkAborted(codecCtx, 'stream');\n\n const compiled = await self.runBeforeCompile(plan);\n const exec = await self.lower(compiled, codecCtx);\n // Fire the framework-level `beforeExecute` chain on the lowered\n // plan before opening the row source. Families that need\n // pre-encode mutator visibility (SQL) override `execute` to\n // inject the same chain at the equivalent point.\n await runBeforeExecuteChain<TExec>(exec, self.middleware, self.ctx);\n // The driver yields raw `Record<string, unknown>`; we cast to `Row` here.\n // The Row contract is enforced by the caller via `plan._row`.\n yield* runWithMiddleware<TExec, Row>(\n exec,\n self.middleware,\n self.ctx,\n () => self.runDriver(exec) as AsyncIterable<Row>,\n );\n }\n\n return new AsyncIterableResult(generator());\n }\n}\n","import type { AsyncIterableResult } from './async-iterable-result';\nimport type { ExecutionPlan, QueryPlan } from './query-plan';\nimport { runtimeError } from './runtime-error';\n\nexport interface RuntimeLog {\n info(event: unknown): void;\n warn(event: unknown): void;\n error(event: unknown): void;\n debug?(event: unknown): void;\n}\n\n/**\n * Per-execute context threaded through every middleware phase\n * (`beforeExecute`, `onRow`, `afterExecute`). Allocated once per\n * `runtime.execute()` call and shared by reference across all\n * middleware in the chain.\n *\n * - `signal` carries the per-query `AbortSignal` -- the same\n * reference that `runtime.execute(plan, { signal })` was invoked\n * with, and the same reference threaded into the per-call\n * `CodecCallContext` (ADR 207). Middleware that wraps a\n * network-backed SDK forwards `ctx.signal` into that SDK to\n * propagate caller cancellation; pure-CPU middleware ignores it.\n *\n * Symmetric plumbing across all middleware phases (rather than only\n * `beforeExecute`) is a deliberate choice: a middleware that wraps a\n * downstream observability hook or post-processor in `afterExecute` /\n * `onRow` needs the same cancellation reach as its `beforeExecute`\n * counterpart.\n */\nexport interface RuntimeMiddlewareContext {\n readonly contract: unknown;\n readonly mode: 'strict' | 'permissive';\n readonly now: () => number;\n readonly log: RuntimeLog;\n /**\n * Returns a stable string identifying the (storage, statement, params)\n * tuple of an execution. Two semantically equivalent executions return\n * the same string. Used by middleware that need per-execution identity\n * (caching, request coalescing).\n *\n * The family runtime owns the implementation:\n * - SQL: `meta.storageHash` + `exec.sql` + `canonicalStringify(exec.params)`\n * - Mongo: `meta.storageHash` + `canonicalStringify({ ...exec.command })`\n *\n * The method is `async` because the underlying digest helper\n * (`hashContent`) uses the WebCrypto API, whose `crypto.subtle.digest`\n * primitive is asynchronous by design.\n *\n * The returned string is intended to be consumed directly as a `Map` key\n * — it is not (and should not be) further hashed by callers.\n */\n contentHash(exec: ExecutionPlan): Promise<string>;\n /**\n * Per-execute cancellation signal threaded through every middleware\n * phase. Middleware that wraps async work or downstream cancellable\n * primitives should observe this and abort early when the consumer\n * cancels.\n */\n readonly signal?: AbortSignal;\n /**\n * Identifies the queryable scope this execution is running under.\n *\n * - `'runtime'` — top-level `runtime.execute(plan)`. The default scope\n * used by the standard read/write paths.\n * - `'connection'` — `connection.execute(plan)` after\n * `runtime.connection()` checked out a connection from the pool.\n * - `'transaction'` — `transaction.execute(plan)` inside an explicit\n * transaction, or a query routed through `withTransaction`.\n *\n * Middleware that should only act at the top level read this field to\n * bypass non-runtime scopes. The cache middleware uses it to skip\n * caching inside transactions (where read-after-write coherence is the\n * caller's expectation) and dedicated connections (where the user has\n * explicitly stepped outside the shared cache surface). Observers that\n * don't care about the scope can ignore the field.\n *\n * Family runtimes populate this at context-construction time per\n * scope. Existing middleware that ignore the field are unaffected.\n */\n readonly scope: 'runtime' | 'connection' | 'transaction';\n}\n\nexport interface AfterExecuteResult {\n readonly rowCount: number;\n readonly latencyMs: number;\n readonly completed: boolean;\n /**\n * Indicates where the rows observed during this execution came from.\n *\n * - `'driver'` — the default. Rows came from the underlying driver via\n * `runDriver` / `runWithMiddleware`'s normal path.\n * - `'middleware'` — a `RuntimeMiddleware.intercept` hook short-circuited\n * execution and supplied the rows directly. The driver was not invoked.\n *\n * Observers (telemetry, lints, budgets) that need to distinguish between\n * driver-served and middleware-served executions read this field.\n * Observers that don't care can ignore it.\n */\n readonly source: 'driver' | 'middleware';\n}\n\n/**\n * Result of a successful `RuntimeMiddleware.intercept` hook.\n *\n * Carries the rows that the middleware wishes to return in place of\n * invoking the driver. The runtime iterates `rows` in order and yields\n * each row to the consumer; `beforeExecute`, `runDriver`, and `onRow` are\n * all skipped on the hit path. `afterExecute` still fires with\n * `source: 'middleware'`.\n *\n * `rows` accepts both `Iterable` (arrays, sync generators) and\n * `AsyncIterable` (async generators). `for await` natively handles both\n * via `Symbol.asyncIterator` / `Symbol.iterator` fallback, so the\n * orchestrator does not need to branch on the variant. Cached arrays in\n * the cache middleware are the common case; streaming variants support\n * future use cases like mock layers replaying recordings.\n *\n * Row shape is `Record<string, unknown>` — the same untyped shape\n * `onRow` receives. The SQL runtime decodes intercepted rows through its\n * normal codec pass, so interceptors cache and return raw (undecoded)\n * rows.\n */\nexport interface InterceptResult {\n readonly rows: AsyncIterable<Record<string, unknown>> | Iterable<Record<string, unknown>>;\n}\n\n/**\n * Marker interface for family-specific param-ref mutators threaded into\n * `beforeExecute` as the third argument. The framework treats the mutator\n * opaquely — it allocates and forwards the family's mutator instance so\n * `runWithMiddleware` can stay family-agnostic. SQL extends this with\n * `SqlParamRefMutator` (over `ParamRef`); Mongo extends with\n * `MongoParamRefMutator` (over `MongoParamRef`).\n *\n * Extension authors target the family-specific mutator type, not this\n * marker.\n */\ndeclare const PARAM_REF_MUTATOR_BRAND: unique symbol;\nexport type ParamRefMutator = { readonly [PARAM_REF_MUTATOR_BRAND]?: never };\n\n/**\n * Family-agnostic middleware SPI parameterized over the plan marker.\n *\n * `TPlan` defaults to the framework `QueryPlan` marker so a generic\n * middleware (e.g. cross-family telemetry) can be authored without\n * naming a family. Family-specific middleware (`SqlMiddleware`,\n * `MongoMiddleware`) narrow `TPlan` to their concrete plan type.\n *\n * `TMutator` is the family-specific {@link ParamRefMutator} the runtime\n * threads into `beforeExecute(plan, ctx, params)` as a third argument.\n * Existing `(plan)` / `(plan, ctx)` middleware bodies continue to compile\n * — TypeScript permits assigning a function with fewer parameters to a\n * function-typed slot that declares more. The third arg is additive.\n */\nexport interface RuntimeMiddleware<\n TPlan extends QueryPlan = QueryPlan,\n TMutator extends ParamRefMutator = ParamRefMutator,\n> {\n readonly name: string;\n readonly familyId?: string;\n readonly targetId?: string;\n /**\n * Optional short-circuit hook. Runs inside `runWithMiddleware`, after\n * the orchestrator receives the lowered plan and before any\n * `beforeExecute` hook fires. Middleware run in registration order; the\n * first to return a non-`undefined` `InterceptResult` wins, and\n * subsequent middleware's `intercept` does not fire.\n *\n * On a hit, `beforeExecute`, `runDriver`, and `onRow` are all skipped.\n * `afterExecute` still fires with `source: 'middleware'`.\n *\n * Returning `undefined` (or omitting the hook entirely) signals\n * passthrough — execution proceeds through the normal driver path.\n *\n * Errors thrown inside `intercept` are rethrown by `runWithMiddleware`\n * as the original `Error` — no envelope is guaranteed at this layer.\n * Before rethrowing, `afterExecute` fires with `completed: false` and\n * `source: 'middleware'`. Errors thrown by `afterExecute` during the\n * error path remain swallowed (existing semantics, unchanged).\n *\n * Used by middleware that need to short-circuit execution and supply\n * rows directly: caching, mocks, rate limiting, circuit breaking.\n */\n intercept?(plan: TPlan, ctx: RuntimeMiddlewareContext): Promise<InterceptResult | undefined>;\n /**\n * Fires after the family runtime has produced a draft execution\n * plan from the AST, but before the family encodes parameter values\n * to driver wire format. Mutations applied via the\n * family-specific `params` mutator are visible to the subsequent\n * encode step.\n *\n * Lifecycle position (SQL example):\n * `runBeforeCompile → lowerSqlPlan → beforeExecute → encodeParams → intercept → driver`.\n *\n * The `params` argument is a family-specific {@link ParamRefMutator}\n * scoped to the value slots of `ParamRef` nodes in the plan's AST.\n * Middleware that doesn't need to mutate params can ignore the\n * argument; existing `(plan)` / `(plan, ctx)` bodies stay compatible.\n *\n * `ctx.signal` carries the per-query `AbortSignal`; middleware that\n * wraps a network SDK forwards it. Cooperative cancellation\n * surfaces a `RUNTIME.ABORTED { phase: 'beforeExecute' }` envelope\n * promptly even when the body ignores the signal.\n *\n * Intercept ordering: `intercept` runs *after* this hook; an\n * interceptor that short-circuits the driver path still observes\n * the post-`beforeExecute`, fully-encoded plan. The trade-off is\n * that any `beforeExecute` SDK round-trips happen even when a\n * downstream interceptor would have skipped the driver entirely.\n */\n beforeExecute?(\n plan: TPlan,\n ctx: RuntimeMiddlewareContext,\n params?: TMutator,\n ): void | Promise<void>;\n onRow?(row: Record<string, unknown>, plan: TPlan, ctx: RuntimeMiddlewareContext): Promise<void>;\n afterExecute?(\n plan: TPlan,\n result: AfterExecuteResult,\n ctx: RuntimeMiddlewareContext,\n ): Promise<void>;\n}\n\n/**\n * Cross-family middleware — one that doesn't constrain `familyId` or\n * `targetId` and is therefore compatible with any family runtime's\n * middleware array (`SqlMiddleware[]`, `MongoMiddleware[]`, etc.).\n *\n * The intersection `RuntimeMiddleware & { familyId?: undefined; targetId?: undefined }`\n * pins both optional properties to exactly `undefined` (intersecting\n * `string | undefined` with `undefined` collapses to `undefined`). Under\n * `exactOptionalPropertyTypes: true`, the plain `RuntimeMiddleware` shape\n * — with `familyId?: string` — is *not* assignable to `SqlMiddleware`\n * (which narrows `familyId?: 'sql'`) because `string` is wider than\n * `'sql'`. Pinning the property to `undefined` makes the value a subtype\n * of every narrowed variant: `undefined` extends both `'sql' | undefined`\n * and `'mongo' | undefined`, so a `CrossFamilyMiddleware` value drops\n * into a SQL or Mongo middleware slot without a cast.\n *\n * Cross-family middleware factories (`createCacheMiddleware`, future\n * `audit` / OTel middleware) declare this as their return type so the\n * cross-family typing is named once rather than re-spelled at every call\n * site.\n */\nexport type CrossFamilyMiddleware<TPlan extends QueryPlan = QueryPlan> =\n RuntimeMiddleware<TPlan> & {\n readonly familyId?: undefined;\n readonly targetId?: undefined;\n };\n\n/**\n * Optional per-`execute` options accepted by every family runtime.\n *\n * `signal` is the per-query cancellation signal. The runtime threads the\n * signal through to every codec call for the query and uses it to short-\n * circuit the row stream with `RUNTIME.ABORTED` when the caller aborts.\n * Omitting the option (or passing `undefined`) preserves today's behavior\n * bit-for-bit.\n */\nexport interface RuntimeExecuteOptions {\n readonly signal?: AbortSignal;\n readonly scope?: 'runtime' | 'connection' | 'transaction';\n}\n\n/**\n * Cross-family SPI for any runtime that can execute plans and be shut down.\n * Each family runtime (SQL, Mongo) satisfies this interface — SQL nominally,\n * Mongo structurally (due to its phantom Row parameter using a unique symbol).\n *\n * The `_row` intersection on `execute` connects the `Row` type parameter to the\n * plan, mirroring how `QueryPlan<Row>` carries a phantom `_row?: Row`.\n */\nexport interface RuntimeExecutor<TPlan extends QueryPlan> {\n execute<Row>(\n plan: TPlan & { readonly _row?: Row },\n options?: RuntimeExecuteOptions,\n ): AsyncIterableResult<Row>;\n close(): Promise<void>;\n}\n\nexport function checkMiddlewareCompatibility(\n middleware: RuntimeMiddleware,\n runtimeFamilyId: string,\n runtimeTargetId: string,\n): void {\n if (middleware.targetId !== undefined && middleware.familyId === undefined) {\n throw runtimeError(\n 'RUNTIME.MIDDLEWARE_INCOMPATIBLE',\n `Middleware '${middleware.name}' specifies targetId '${middleware.targetId}' without familyId`,\n { middleware: middleware.name, targetId: middleware.targetId },\n );\n }\n\n if (middleware.familyId !== undefined && middleware.familyId !== runtimeFamilyId) {\n throw runtimeError(\n 'RUNTIME.MIDDLEWARE_FAMILY_MISMATCH',\n `Middleware '${middleware.name}' requires family '${middleware.familyId}' but the runtime is configured for family '${runtimeFamilyId}'`,\n { middleware: middleware.name, middlewareFamilyId: middleware.familyId, runtimeFamilyId },\n );\n }\n\n if (middleware.targetId !== undefined && middleware.targetId !== runtimeTargetId) {\n throw runtimeError(\n 'RUNTIME.MIDDLEWARE_TARGET_MISMATCH',\n `Middleware '${middleware.name}' requires target '${middleware.targetId}' but the runtime is configured for target '${runtimeTargetId}'`,\n { middleware: middleware.name, middlewareTargetId: middleware.targetId, runtimeTargetId },\n );\n }\n}\n","import {\n type AnnotationValue,\n assertAnnotationsApplicable,\n type OperationKind,\n} from './annotations';\n\n/**\n * Per-terminal meta configurator handed to user callbacks. The terminal's\n * operation kind `K` is fixed by the terminal that constructed the builder;\n * `annotate(...)` accepts only annotations whose declared `Kinds` include\n * `K`.\n *\n * The conditional parameter type\n * `K extends Kinds ? AnnotationValue<P, Kinds> : never` collapses to `never`\n * for inapplicable annotations, surfacing the mismatch as a type error at\n * the call site of `meta.annotate(...)`. No variadic-tuple inference is\n * involved — TypeScript infers `Kinds` from the annotation argument and\n * checks the conditional directly.\n *\n * The runtime gate inside `annotate` (via\n * `assertAnnotationsApplicable`) catches cast / `any` / dynamic bypasses\n * and throws `RUNTIME.ANNOTATION_INAPPLICABLE`.\n *\n * `annotate` returns the builder for chaining; the return value of the\n * configurator callback is unused, so both block-body and expression-body\n * callbacks compile.\n *\n * @example\n * ```typescript\n * await db.User.find({ id }, (meta) => meta.annotate(cacheAnnotation({ ttl: 60 })));\n * await db.User.create(input, (meta) => {\n * meta.annotate(auditAnnotation({ actor: 'system' }));\n * meta.annotate(otelAnnotation({ traceId }));\n * });\n * ```\n */\nexport interface MetaBuilder<K extends OperationKind> {\n annotate<P, Kinds extends OperationKind>(\n annotation: K extends Kinds ? AnnotationValue<P, Kinds> : never,\n ): this;\n}\n\n/**\n * Lane-side view of a meta builder. Extends the public `MetaBuilder<K>`\n * surface with `annotations` so lane terminals can read the recorded map\n * after invoking the user configurator.\n *\n * Lane terminals construct one of these via `createMetaBuilder(kind, terminalName)`,\n * pass it to the user callback as `MetaBuilder<K>` (the narrower public\n * view), then read `meta.annotations` to thread the recorded values into\n * `plan.meta.annotations`.\n */\nexport interface LaneMetaBuilder<K extends OperationKind> extends MetaBuilder<K> {\n readonly annotations: ReadonlyMap<string, AnnotationValue<unknown, OperationKind>>;\n}\n\nclass MetaBuilderImpl<K extends OperationKind> implements LaneMetaBuilder<K> {\n readonly #kind: K;\n readonly #terminalName: string;\n readonly #annotations = new Map<string, AnnotationValue<unknown, OperationKind>>();\n\n constructor(kind: K, terminalName: string) {\n this.#kind = kind;\n this.#terminalName = terminalName;\n }\n\n get annotations(): ReadonlyMap<string, AnnotationValue<unknown, OperationKind>> {\n return this.#annotations;\n }\n\n annotate<P, Kinds extends OperationKind>(\n annotation: K extends Kinds ? AnnotationValue<P, Kinds> : never,\n ): this {\n // Inside the body, the conditional `K extends Kinds ? AnnotationValue<P, Kinds> : never`\n // is opaque to TypeScript — it can't pick a branch without a concrete\n // K. Widen to the structural shape so we can call into the runtime\n // gate. The runtime gate (assertAnnotationsApplicable) is what\n // catches cast bypasses where the conditional would have resolved to\n // `never` had the type checker been allowed to specialise.\n const value = annotation as AnnotationValue<unknown, OperationKind>;\n assertAnnotationsApplicable([value], this.#kind, this.#terminalName);\n this.#annotations.set(value.namespace, value);\n return this;\n }\n}\n\n/**\n * Construct a lane-side meta builder for a terminal of operation kind `K`.\n *\n * Lane terminals call this with their `kind` (`'read'` or `'write'`) and a\n * `terminalName` for error messages, hand the resulting builder to the\n * user-supplied configurator callback (typed as `MetaBuilder<K>`, the\n * narrower public view), and read `meta.annotations` afterwards to thread\n * the recorded values into `plan.meta.annotations`.\n */\nexport function createMetaBuilder<K extends OperationKind>(\n kind: K,\n terminalName: string,\n): LaneMetaBuilder<K> {\n return new MetaBuilderImpl(kind, terminalName);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,20 +1,21 @@
1
1
  {
2
2
  "name": "@prisma-next/framework-components",
3
- "version": "0.10.0-dev.9",
3
+ "version": "0.11.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "Framework component types, assembly logic, and stack creation for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/contract": "0.10.0-dev.9",
10
- "@prisma-next/operations": "0.10.0-dev.9",
11
- "@prisma-next/ts-render": "0.10.0-dev.9",
12
- "@prisma-next/utils": "0.10.0-dev.9",
13
- "@standard-schema/spec": "^1.1.0"
9
+ "@prisma-next/contract": "0.11.0",
10
+ "@prisma-next/operations": "0.11.0",
11
+ "@prisma-next/ts-render": "0.11.0",
12
+ "@prisma-next/utils": "0.11.0",
13
+ "@standard-schema/spec": "^1.1.0",
14
+ "arktype": "^2.2.0"
14
15
  },
15
16
  "devDependencies": {
16
- "@prisma-next/tsconfig": "0.10.0-dev.9",
17
- "@prisma-next/tsdown": "0.10.0-dev.9",
17
+ "@prisma-next/tsconfig": "0.11.0",
18
+ "@prisma-next/tsdown": "0.11.0",
18
19
  "tsdown": "0.22.0",
19
20
  "typescript": "5.9.3",
20
21
  "vitest": "4.1.6"
@@ -227,7 +227,7 @@ export function defineAnnotation<Payload>(): <const Kinds extends OperationKind>
227
227
  * db.users.select('id').annotate(cacheAnnotation({ ttl: 60 }));
228
228
  * // ✓ cacheAnnotation declares 'read'; SelectQuery.annotate requires 'read'.
229
229
  *
230
- * db.users.insert({ name: 'Alice' }).annotate(cacheAnnotation({ ttl: 60 }));
230
+ * db.users.insert([{ name: 'Alice' }]).annotate(cacheAnnotation({ ttl: 60 }));
231
231
  * // ✗ cacheAnnotation declares 'read'; InsertQuery.annotate requires 'write'.
232
232
  * // Element resolves to `never` → tuple unassignable → type error.
233
233
  * ```
package/src/exports/ir.ts CHANGED
@@ -2,5 +2,6 @@ export type { IRNode } from '../ir/ir-node';
2
2
  export { freezeNode, IRNodeBase } from '../ir/ir-node';
3
3
  export type { Namespace } from '../ir/namespace';
4
4
  export { NamespaceBase, UNBOUND_NAMESPACE_ID } from '../ir/namespace';
5
- export type { Storage } from '../ir/storage';
5
+ export type { EntityCoordinate, Storage } from '../ir/storage';
6
+ export { elementCoordinates } from '../ir/storage';
6
7
  export type { StorageType } from '../ir/storage-type';
@@ -43,11 +43,26 @@ export const UNBOUND_NAMESPACE_ID = '__unbound__' as const;
43
43
  * `tables`, Mongo contributes `collections`, future families pick their
44
44
  * own native idiom). Generic consumers walking "all named entries" go
45
45
  * through a family-typed namespace, not the framework `Namespace`.
46
+ *
47
+ * Every namespace concretion (e.g. `SqlNamespacePayload`,
48
+ * `MongoNamespacePayload`, target-promoted namespaces like
49
+ * `PostgresSchema`) carries exactly: `id` (enumerable string), `kind`
50
+ * (non-enumerable string discriminator set via `Object.defineProperty`),
51
+ * and one or more entity-kind slot maps — each an own-enumerable property
52
+ * whose key is the entity kind (`tables`, `types`, `collections`,
53
+ * target-pack-contributed slot names) and whose value is a
54
+ * `Record<entityName, EntityIRClass>`. No other own-enumerable data lives
55
+ * on a namespace; non-entity computed data lives on the surrounding storage
56
+ * or contract IR. The framework's `elementCoordinates(storage)` walk relies
57
+ * on this invariant to enumerate entities structurally without
58
+ * family-specific knowledge.
46
59
  */
47
60
  export interface Namespace extends IRNode {
48
61
  readonly id: string;
62
+ readonly kind: string;
49
63
  }
50
64
 
51
65
  export abstract class NamespaceBase extends IRNodeBase implements Namespace {
52
66
  abstract readonly id: string;
67
+ abstract override readonly kind: string;
53
68
  }
package/src/ir/storage.ts CHANGED
@@ -1,6 +1,53 @@
1
1
  import type { IRNode } from './ir-node';
2
2
  import type { Namespace } from './namespace';
3
3
 
4
+ /**
5
+ * Canonical address for a named entity in Contract IR / Schema IR.
6
+ *
7
+ * `plane` is `'domain' | 'storage'`: which top-level contract plane the
8
+ * entity lives on. Domain-side walks (once domain content is populated)
9
+ * yield `plane: 'domain'`; {@link elementCoordinates} over storage yields
10
+ * `plane: 'storage'`. A sibling `elementCoordinates(domain)` is not wired
11
+ * yet — domain-plane content lands in S1.C; the sibling walk lands there.
12
+ *
13
+ * Cross-plane references obey a directional invariant: domain → storage is
14
+ * allowed; storage → domain is forbidden. That rule is enforced by a
15
+ * separate validator, not by constraining this coordinate shape — the
16
+ * coordinate carries the axis the validator checks.
17
+ *
18
+ * Iteration order over namespace properties follows `Object.entries` order;
19
+ * consumers that depend on ordering must sort.
20
+ */
21
+ export interface EntityCoordinate {
22
+ readonly plane: 'domain' | 'storage';
23
+ readonly namespaceId: string;
24
+ readonly entityKind: string;
25
+ readonly entityName: string;
26
+ }
27
+
28
+ /**
29
+ * Lazy walk over every named storage entity in a `Storage`-shaped
30
+ * value, yielded as {@link EntityCoordinate} tuples with
31
+ * `plane: 'storage'` (the parameter type binds the plane).
32
+ *
33
+ * Iterates each namespace's own-enumerable properties structurally.
34
+ * Skips `id` (known scalar); `kind` is non-enumerable on namespace
35
+ * concretions and does not appear in `Object.entries`. For every other
36
+ * property whose value is a non-null object, yields one coordinate per
37
+ * entry key in that map. No family-specific slot vocabulary is required.
38
+ */
39
+ export function* elementCoordinates(storage: Storage): Generator<EntityCoordinate> {
40
+ for (const [namespaceId, ns] of Object.entries(storage.namespaces)) {
41
+ for (const [entityKind, slot] of Object.entries(ns)) {
42
+ if (entityKind === 'id') continue;
43
+ if (slot === null || typeof slot !== 'object') continue;
44
+ for (const entityName of Object.keys(slot)) {
45
+ yield { plane: 'storage', namespaceId, entityKind, entityName };
46
+ }
47
+ }
48
+ }
49
+ }
50
+
4
51
  /**
5
52
  * Framework-level promise that every Contract IR / Schema IR carries a
6
53
  * collection of namespaces keyed by namespace id. Family storage
@@ -8,6 +8,7 @@ import {
8
8
  isExecutionMutationDefaultValue,
9
9
  } from '@prisma-next/contract/types';
10
10
  import { ifDefined } from '@prisma-next/utils/defined';
11
+ import type { Type } from 'arktype';
11
12
 
12
13
  export type AuthoringArgRef = {
13
14
  readonly kind: 'arg';
@@ -138,6 +139,18 @@ export interface AuthoringEntityTypeDescriptor<Input = never, Output = unknown>
138
139
  readonly output:
139
140
  | AuthoringEntityTypeTemplateOutput
140
141
  | AuthoringEntityTypeFactoryOutput<Input, Output>;
142
+ /**
143
+ * arktype schema fragment for one entry whose envelope `kind` matches
144
+ * this descriptor's {@link discriminator}. The family validator composes
145
+ * contributed fragments into the per-namespace entry schema at
146
+ * validator construction time so the structural check covers
147
+ * pack-introduced kinds without the family core hard-coding the schema.
148
+ *
149
+ * Hydration uses {@link AuthoringEntityTypeFactoryOutput.factory}
150
+ * directly — the wire shape conforms structurally to the factory's
151
+ * `Input` after `validatorSchema` validates it.
152
+ */
153
+ readonly validatorSchema?: Type<unknown>;
141
154
  }
142
155
 
143
156
  export type AuthoringEntityTypeNamespace = {
@@ -1 +0,0 @@
1
- {"version":3,"file":"framework-authoring-Bb_GEnzj.d.mts","names":[],"sources":["../src/shared/framework-authoring.ts"],"mappings":"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"}