@prisma-next/framework-components 0.5.0-dev.3 → 0.5.0-dev.31

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.
Files changed (85) hide show
  1. package/README.md +61 -0
  2. package/dist/authoring.d.mts +1 -1
  3. package/dist/authoring.mjs +1 -1
  4. package/dist/authoring.mjs.map +1 -1
  5. package/dist/codec-types-CB0jWeHU.d.mts +207 -0
  6. package/dist/codec-types-CB0jWeHU.d.mts.map +1 -0
  7. package/dist/codec.d.mts +2 -2
  8. package/dist/codec.mjs +38 -2
  9. package/dist/codec.mjs.map +1 -1
  10. package/dist/components.d.mts +1 -1
  11. package/dist/components.mjs +1 -1
  12. package/dist/control.d.mts +80 -27
  13. package/dist/control.d.mts.map +1 -1
  14. package/dist/control.mjs +11 -5
  15. package/dist/control.mjs.map +1 -1
  16. package/dist/emission-types-D6t3_a0x.d.mts +39 -0
  17. package/dist/emission-types-D6t3_a0x.d.mts.map +1 -0
  18. package/dist/emission.d.mts +2 -2
  19. package/dist/execution.d.mts +5 -5
  20. package/dist/execution.d.mts.map +1 -1
  21. package/dist/execution.mjs +3 -3
  22. package/dist/execution.mjs.map +1 -1
  23. package/dist/{framework-authoring-D1-JZ37B.d.mts → framework-authoring-BdrFDx4x.d.mts} +2 -2
  24. package/dist/framework-authoring-BdrFDx4x.d.mts.map +1 -0
  25. package/dist/{framework-components-EJXe-pum.d.mts → framework-components-AHI6V96G.d.mts} +6 -6
  26. package/dist/framework-components-AHI6V96G.d.mts.map +1 -0
  27. package/dist/{framework-components-C8ZhSwXe.mjs → framework-components-BsWST1Rn.mjs} +2 -2
  28. package/dist/framework-components-BsWST1Rn.mjs.map +1 -0
  29. package/dist/psl-ast-9X5rwo98.d.mts +159 -0
  30. package/dist/psl-ast-9X5rwo98.d.mts.map +1 -0
  31. package/dist/psl-ast.d.mts +2 -0
  32. package/dist/psl-ast.mjs +1 -0
  33. package/dist/runtime.d.mts +251 -19
  34. package/dist/runtime.d.mts.map +1 -1
  35. package/dist/runtime.mjs +215 -4
  36. package/dist/runtime.mjs.map +1 -1
  37. package/dist/{types-import-spec-C4sc7wbb.d.mts → types-import-spec-D-O6GotH.d.mts} +2 -2
  38. package/dist/types-import-spec-D-O6GotH.d.mts.map +1 -0
  39. package/package.json +8 -6
  40. package/src/control/control-capabilities.ts +71 -0
  41. package/src/{control-descriptors.ts → control/control-descriptors.ts} +7 -7
  42. package/src/{control-instances.ts → control/control-instances.ts} +6 -6
  43. package/src/{control-migration-types.ts → control/control-migration-types.ts} +27 -15
  44. package/src/control/control-operation-preview.ts +23 -0
  45. package/src/{control-stack.ts → control/control-stack.ts} +13 -13
  46. package/src/control/emission-types.ts +49 -0
  47. package/src/control/psl-ast.ts +193 -0
  48. package/src/{execution-descriptors.ts → execution/execution-descriptors.ts} +7 -7
  49. package/src/{execution-instances.ts → execution/execution-instances.ts} +1 -1
  50. package/src/{execution-requirements.ts → execution/execution-requirements.ts} +1 -1
  51. package/src/execution/query-plan.ts +53 -0
  52. package/src/execution/race-against-abort.ts +85 -0
  53. package/src/execution/run-with-middleware.ts +77 -0
  54. package/src/execution/runtime-core.ts +133 -0
  55. package/src/execution/runtime-error.ts +83 -0
  56. package/src/{runtime-middleware.ts → execution/runtime-middleware.ts} +32 -12
  57. package/src/exports/authoring.ts +2 -2
  58. package/src/exports/codec.ts +14 -2
  59. package/src/exports/components.ts +2 -2
  60. package/src/exports/control.ts +26 -12
  61. package/src/exports/emission.ts +2 -2
  62. package/src/exports/execution.ts +5 -5
  63. package/src/exports/psl-ast.ts +1 -0
  64. package/src/exports/runtime.ts +16 -5
  65. package/src/shared/codec-types.ts +261 -0
  66. package/dist/codec-types-B58nCJiu.d.mts +0 -40
  67. package/dist/codec-types-B58nCJiu.d.mts.map +0 -1
  68. package/dist/emission-types-BPAALJbF.d.mts +0 -24
  69. package/dist/emission-types-BPAALJbF.d.mts.map +0 -1
  70. package/dist/framework-authoring-D1-JZ37B.d.mts.map +0 -1
  71. package/dist/framework-components-C8ZhSwXe.mjs.map +0 -1
  72. package/dist/framework-components-EJXe-pum.d.mts.map +0 -1
  73. package/dist/types-import-spec-C4sc7wbb.d.mts.map +0 -1
  74. package/src/codec-types.ts +0 -46
  75. package/src/control-capabilities.ts +0 -34
  76. package/src/emission-types.ts +0 -28
  77. package/src/runtime-error.ts +0 -39
  78. /package/src/{control-result-types.ts → control/control-result-types.ts} +0 -0
  79. /package/src/{control-schema-view.ts → control/control-schema-view.ts} +0 -0
  80. /package/src/{async-iterable-result.ts → execution/async-iterable-result.ts} +0 -0
  81. /package/src/{execution-stack.ts → execution/execution-stack.ts} +0 -0
  82. /package/src/{framework-authoring.ts → shared/framework-authoring.ts} +0 -0
  83. /package/src/{framework-components.ts → shared/framework-components.ts} +0 -0
  84. /package/src/{mutation-default-types.ts → shared/mutation-default-types.ts} +0 -0
  85. /package/src/{types-import-spec.ts → shared/types-import-spec.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/async-iterable-result.ts","../src/runtime-error.ts","../src/runtime-middleware.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/execution/async-iterable-result.ts","../src/execution/query-plan.ts","../src/execution/runtime-error.ts","../src/execution/race-against-abort.ts","../src/execution/runtime-middleware.ts","../src/execution/run-with-middleware.ts","../src/execution/runtime-core.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/runtime.mjs CHANGED
@@ -1,4 +1,25 @@
1
- //#region src/runtime-error.ts
1
+ //#region src/execution/runtime-error.ts
2
+ /**
3
+ * Stable code emitted by the runtime when an in-flight `execute()`
4
+ * is cancelled via the per-query `AbortSignal`. The envelope's
5
+ * `details.phase` distinguishes where the abort was observed:
6
+ *
7
+ * - `'encode'` — abort fired during `encodeParams` (SQL) or
8
+ * `resolveValue` (Mongo).
9
+ * - `'decode'` — abort fired during `decodeRow` / `decodeField`.
10
+ * - `'stream'` — abort fired between rows or before any codec call
11
+ * (already-aborted at entry).
12
+ */
13
+ const RUNTIME_ABORTED = "RUNTIME.ABORTED";
14
+ /**
15
+ * Type guard for the runtime-error envelope produced by `runtimeError`.
16
+ *
17
+ * Prefer this over duck-typing on `error.code` directly so consumers stay
18
+ * insulated from the envelope's internal shape.
19
+ */
20
+ function isRuntimeError(error) {
21
+ return error instanceof Error && "code" in error && typeof error.code === "string" && "category" in error && "severity" in error;
22
+ }
2
23
  function runtimeError(code, message, details) {
3
24
  const error = new Error(message);
4
25
  Object.defineProperty(error, "name", {
@@ -23,9 +44,20 @@ function resolveCategory(code) {
23
44
  default: return "RUNTIME";
24
45
  }
25
46
  }
47
+ /**
48
+ * Construct a `RUNTIME.ABORTED` envelope. Phase distinguishes where the
49
+ * abort was observed (encode / decode / stream); cause carries `signal.reason`
50
+ * verbatim from the platform — native abort produces a `DOMException`,
51
+ * explicit `controller.abort(reason)` produces whatever the caller passed.
52
+ * No synthesis happens here.
53
+ */
54
+ function runtimeAborted(phase, cause) {
55
+ const envelope = runtimeError(RUNTIME_ABORTED, `Operation aborted during ${phase}`, { phase });
56
+ return Object.assign(envelope, { cause });
57
+ }
26
58
 
27
59
  //#endregion
28
- //#region src/async-iterable-result.ts
60
+ //#region src/execution/async-iterable-result.ts
29
61
  var AsyncIterableResult = class {
30
62
  generator;
31
63
  consumed = false;
@@ -72,7 +104,186 @@ var AsyncIterableResult = class {
72
104
  };
73
105
 
74
106
  //#endregion
75
- //#region src/runtime-middleware.ts
107
+ //#region src/execution/race-against-abort.ts
108
+ /**
109
+ * Throw a phase-tagged `RUNTIME.ABORTED` envelope if the supplied
110
+ * codec-call context is already aborted at the precheck site. Centralises
111
+ * the `if (ctx.signal?.aborted) throw runtimeAborted(...)` pattern that
112
+ * every codec dispatch site repeats.
113
+ */
114
+ function checkAborted(ctx, phase) {
115
+ if (ctx.signal?.aborted) throw runtimeAborted(phase, ctx.signal.reason);
116
+ }
117
+ /**
118
+ * Race a per-cell `Promise.all` (or any other in-flight work promise) against
119
+ * the supplied abort signal so the runtime returns `RUNTIME.ABORTED` promptly
120
+ * even when codec bodies ignore the signal. In-flight bodies that ignore the
121
+ * signal are abandoned and run to completion in the background — the
122
+ * cooperative-cancellation contract documented in ADR 204.
123
+ *
124
+ * Call sites still SHOULD pre-check `signal.aborted` and short-circuit with
125
+ * a phase-tagged `RUNTIME.ABORTED` envelope before invoking this helper —
126
+ * that path is the canonical "aborted at entry" surface and avoids
127
+ * scheduling the work promise. As a defensive belt-and-braces, this helper
128
+ * also handles the already-aborted case internally: `AbortSignal` does not
129
+ * replay past abort events to listeners registered after the abort, so we
130
+ * inspect `signal.aborted` synchronously and reject with the sentinel
131
+ * before installing the listener. The rejection is still attributed to the
132
+ * abort path via the sentinel-identity check.
133
+ *
134
+ * Distinguishing the rejection source is load-bearing for AC-ERR4
135
+ * (`RUNTIME.ENCODE_FAILED` / `RUNTIME.DECODE_FAILED` pass through unchanged).
136
+ * The semantically equivalent `abortable(signal)` helper in
137
+ * `@prisma-next/utils` rejects with `signal.reason ?? new DOMException(...)`,
138
+ * which is not stably distinguishable from a codec-thrown error by identity
139
+ * alone (a fresh fallback DOMException is allocated per call). We instead
140
+ * track abort attribution with a unique sentinel: only the `onAbort` listener
141
+ * installed here ever rejects with the sentinel, so an `error === sentinel`
142
+ * identity check after the race is unambiguous.
143
+ *
144
+ * Lives in `framework-components` (rather than the SQL family, where it
145
+ * originated in m2) so every family runtime that needs cooperative
146
+ * cancellation around a codec-dispatch `Promise.all` (SQL encode + decode
147
+ * today, Mongo encode in m3) shares the same attribution logic.
148
+ */
149
+ async function raceAgainstAbort(work, signal, phase) {
150
+ if (signal === void 0) return await work;
151
+ const sentinel = { reason: void 0 };
152
+ let onAbort;
153
+ const abortPromise = new Promise((_, reject) => {
154
+ if (signal.aborted) {
155
+ sentinel.reason = signal.reason;
156
+ reject(sentinel);
157
+ return;
158
+ }
159
+ onAbort = () => {
160
+ sentinel.reason = signal.reason;
161
+ reject(sentinel);
162
+ };
163
+ signal.addEventListener("abort", onAbort, { once: true });
164
+ });
165
+ try {
166
+ return await Promise.race([work, abortPromise]);
167
+ } catch (error) {
168
+ if (error === sentinel) throw runtimeAborted(phase, sentinel.reason);
169
+ throw error;
170
+ } finally {
171
+ if (onAbort) signal.removeEventListener("abort", onAbort);
172
+ }
173
+ }
174
+
175
+ //#endregion
176
+ //#region src/execution/run-with-middleware.ts
177
+ /**
178
+ * Drives a single execution of `runDriver()` through the middleware lifecycle.
179
+ *
180
+ * Lifecycle, in order:
181
+ * 1. For each middleware in registration order: `beforeExecute(exec, ctx)`.
182
+ * 2. For each row yielded by `runDriver()`: for each middleware in registration
183
+ * order: `onRow(row, exec, ctx)`; then yield the row to the consumer.
184
+ * 3. On successful completion: for each middleware in registration order:
185
+ * `afterExecute(exec, { rowCount, latencyMs, completed: true }, ctx)`.
186
+ * 4. On any error thrown by the driver loop: for each middleware in
187
+ * registration order: `afterExecute(exec, { rowCount, latencyMs,
188
+ * completed: false }, ctx)`. Errors thrown by `afterExecute` during the
189
+ * error path are swallowed so they do not mask the original driver error.
190
+ * The original error is then rethrown.
191
+ *
192
+ * This helper is the single canonical implementation of the middleware
193
+ * orchestration loop; family runtimes should not reimplement it.
194
+ */
195
+ function runWithMiddleware(exec, middleware, ctx, runDriver) {
196
+ const iterator = async function* () {
197
+ const startedAt = Date.now();
198
+ let rowCount = 0;
199
+ let completed = false;
200
+ try {
201
+ for (const mw of middleware) if (mw.beforeExecute) await mw.beforeExecute(exec, ctx);
202
+ for await (const row of runDriver()) {
203
+ for (const mw of middleware) if (mw.onRow) await mw.onRow(row, exec, ctx);
204
+ rowCount++;
205
+ yield row;
206
+ }
207
+ completed = true;
208
+ } catch (error) {
209
+ const latencyMs$1 = Date.now() - startedAt;
210
+ for (const mw of middleware) if (mw.afterExecute) try {
211
+ await mw.afterExecute(exec, {
212
+ rowCount,
213
+ latencyMs: latencyMs$1,
214
+ completed
215
+ }, ctx);
216
+ } catch {}
217
+ throw error;
218
+ }
219
+ const latencyMs = Date.now() - startedAt;
220
+ for (const mw of middleware) if (mw.afterExecute) await mw.afterExecute(exec, {
221
+ rowCount,
222
+ latencyMs,
223
+ completed
224
+ }, ctx);
225
+ };
226
+ return new AsyncIterableResult(iterator());
227
+ }
228
+
229
+ //#endregion
230
+ //#region src/execution/runtime-core.ts
231
+ /**
232
+ * Family-agnostic abstract runtime base.
233
+ *
234
+ * Defines the entire `execute(plan)` template in one place:
235
+ *
236
+ * 1. `runBeforeCompile(plan)` — concrete; defaults to identity. SQL overrides
237
+ * this to run its `beforeCompile` middleware-hook chain.
238
+ * 2. `lower(plan)` — abstract. Each family produces its `*ExecutionPlan`
239
+ * (SQL via `lowerSqlPlan`, Mongo via `adapter.lower`).
240
+ * 3. `runWithMiddleware(exec, this.middleware, this.ctx,
241
+ * () => runDriver(exec))` — concrete; lifts the middleware lifecycle
242
+ * out of the family runtimes into the canonical helper.
243
+ *
244
+ * Concrete subclasses must implement `lower`, `runDriver`, and `close`.
245
+ *
246
+ * The class is generic over:
247
+ * - `TPlan` — the family's pre-lowering plan type.
248
+ * - `TExec` — the family's post-lowering (executable) plan type.
249
+ * - `TMiddleware` — the family's middleware type. Constrained to
250
+ * `RuntimeMiddleware<TExec>` because `runWithMiddleware` invokes the
251
+ * `beforeExecute` / `onRow` / `afterExecute` hooks with the lowered
252
+ * `TExec`. (The spec/plan wording "RuntimeMiddleware<TPlan>" is
253
+ * tightened to `<TExec>` here so the helper call typechecks; the
254
+ * intent is unchanged — middleware sees the post-lowering plan.)
255
+ */
256
+ var RuntimeCore = class {
257
+ middleware;
258
+ ctx;
259
+ constructor(options) {
260
+ this.middleware = options.middleware;
261
+ this.ctx = options.ctx;
262
+ }
263
+ /**
264
+ * Pre-lowering hook for plan rewriting. Defaults to identity. Subclasses
265
+ * may override to run a `beforeCompile` middleware chain (SQL does this
266
+ * to support typed AST rewrites — see `before-compile-chain.ts`).
267
+ */
268
+ runBeforeCompile(plan) {
269
+ return plan;
270
+ }
271
+ execute(plan, options) {
272
+ const self = this;
273
+ const signal = options?.signal;
274
+ const codecCtx = signal === void 0 ? {} : { signal };
275
+ async function* generator() {
276
+ checkAborted(codecCtx, "stream");
277
+ const compiled = await self.runBeforeCompile(plan);
278
+ const exec = await self.lower(compiled, codecCtx);
279
+ yield* runWithMiddleware(exec, self.middleware, self.ctx, () => self.runDriver(exec));
280
+ }
281
+ return new AsyncIterableResult(generator());
282
+ }
283
+ };
284
+
285
+ //#endregion
286
+ //#region src/execution/runtime-middleware.ts
76
287
  function checkMiddlewareCompatibility(middleware, runtimeFamilyId, runtimeTargetId) {
77
288
  if (middleware.targetId !== void 0 && middleware.familyId === void 0) throw runtimeError("RUNTIME.MIDDLEWARE_INCOMPATIBLE", `Middleware '${middleware.name}' specifies targetId '${middleware.targetId}' without familyId`, {
78
289
  middleware: middleware.name,
@@ -91,5 +302,5 @@ function checkMiddlewareCompatibility(middleware, runtimeFamilyId, runtimeTarget
91
302
  }
92
303
 
93
304
  //#endregion
94
- export { AsyncIterableResult, checkMiddlewareCompatibility, runtimeError };
305
+ export { AsyncIterableResult, RUNTIME_ABORTED, RuntimeCore, checkAborted, checkMiddlewareCompatibility, isRuntimeError, raceAgainstAbort, runWithMiddleware, runtimeAborted, runtimeError };
95
306
  //# sourceMappingURL=runtime.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":["out: Row[]"],"sources":["../src/runtime-error.ts","../src/async-iterable-result.ts","../src/runtime-middleware.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\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","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 { PlanMeta } from '@prisma-next/contract/types';\nimport type { AsyncIterableResult } from './async-iterable-result';\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\nexport interface RuntimeMiddlewareContext {\n readonly contract: unknown;\n readonly mode: 'strict' | 'permissive';\n readonly now: () => number;\n readonly log: RuntimeLog;\n}\n\nexport interface AfterExecuteResult {\n readonly rowCount: number;\n readonly latencyMs: number;\n readonly completed: boolean;\n}\n\nexport interface RuntimeMiddleware {\n readonly name: string;\n readonly familyId?: string;\n readonly targetId?: string;\n beforeExecute?(plan: { readonly meta: PlanMeta }, ctx: RuntimeMiddlewareContext): Promise<void>;\n onRow?(\n row: Record<string, unknown>,\n plan: { readonly meta: PlanMeta },\n ctx: RuntimeMiddlewareContext,\n ): Promise<void>;\n afterExecute?(\n plan: { readonly meta: PlanMeta },\n result: AfterExecuteResult,\n ctx: RuntimeMiddlewareContext,\n ): Promise<void>;\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 `ExecutionPlan<Row>` carries a phantom `_row?: Row`.\n */\nexport interface RuntimeExecutor<TPlan extends { readonly meta: PlanMeta }> {\n execute<Row>(plan: TPlan & { readonly _row?: Row }): 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"],"mappings":";AAOA,SAAgB,aACd,MACA,SACA,SACsB;CACtB,MAAM,QAAQ,IAAI,MAAM,QAAQ;AAChC,QAAO,eAAe,OAAO,QAAQ;EACnC,OAAO;EACP,cAAc;EACf,CAAC;AAEF,QAAO,OAAO,OAAO,OAAO;EAC1B;EACA,UAAU,gBAAgB,KAAK;EAC/B,UAAU;EACV;EACA;EACD,CAAC;;AAGJ,SAAS,gBAAgB,MAAgD;CACvE,MAAM,SAAS,KAAK,MAAM,IAAI,CAAC,MAAM;AACrC,SAAQ,QAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,QAAO;EACT,QACE,QAAO;;;;;;AClCb,IAAa,sBAAb,MAAwF;CACtF,AAAiB;CACjB,AAAQ,WAAW;CACnB,AAAQ;CACR,AAAQ;CAER,YAAY,WAA+C;AACzD,OAAK,YAAY;;CAGnB,CAAC,OAAO,iBAAqC;AAC3C,MAAI,KAAK,SACP,OAAM,aACJ,6BACA,8DAA8D,KAAK,eAAe,kBAAkB,qBAAqB,iBAAiB,wDAC1I;GACE,YAAY,KAAK;GACjB,YACE,KAAK,eAAe,kBAChB,0GACA;GACP,CACF;AAEH,OAAK,WAAW;AAChB,OAAK,aAAa;AAClB,SAAO,KAAK;;CAGd,UAA0B;AACxB,MAAI,KAAK,eAAe,WACtB,QAAO,QAAQ,OACb,aACE,6BACA,kIACA;GACE,YAAY,KAAK;GACjB,YACE;GACH,CACF,CACF;AAGH,MAAI,KAAK,qBACP,QAAO,KAAK;AAGd,OAAK,WAAW;AAChB,OAAK,aAAa;AAClB,OAAK,wBAAwB,YAAY;GACvC,MAAMA,MAAa,EAAE;AACrB,cAAW,MAAM,QAAQ,KAAK,UAC5B,KAAI,KAAK,KAAK;AAEhB,UAAO;MACL;AACJ,SAAO,KAAK;;CAGd,MAAM,QAA6B;AAEjC,UADa,MAAM,KAAK,SAAS,EACrB,MAAM;;CAGpB,MAAM,eAA6B;EACjC,MAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,MAAI,QAAQ,KACV,OAAM,aACJ,mBACA,qDACA,EAAE,CACH;AACH,SAAO;;CAIT,KACE,aACA,YACkC;AAClC,SAAO,KAAK,SAAS,CAAC,KAAK,aAAa,WAAW;;;;;;AC7BvD,SAAgB,6BACd,YACA,iBACA,iBACM;AACN,KAAI,WAAW,aAAa,UAAa,WAAW,aAAa,OAC/D,OAAM,aACJ,mCACA,eAAe,WAAW,KAAK,wBAAwB,WAAW,SAAS,qBAC3E;EAAE,YAAY,WAAW;EAAM,UAAU,WAAW;EAAU,CAC/D;AAGH,KAAI,WAAW,aAAa,UAAa,WAAW,aAAa,gBAC/D,OAAM,aACJ,sCACA,eAAe,WAAW,KAAK,qBAAqB,WAAW,SAAS,8CAA8C,gBAAgB,IACtI;EAAE,YAAY,WAAW;EAAM,oBAAoB,WAAW;EAAU;EAAiB,CAC1F;AAGH,KAAI,WAAW,aAAa,UAAa,WAAW,aAAa,gBAC/D,OAAM,aACJ,sCACA,eAAe,WAAW,KAAK,qBAAqB,WAAW,SAAS,8CAA8C,gBAAgB,IACtI;EAAE,YAAY,WAAW;EAAM,oBAAoB,WAAW;EAAU;EAAiB,CAC1F"}
1
+ {"version":3,"file":"runtime.mjs","names":["out: Row[]","sentinel: { reason: unknown }","onAbort: (() => void) | undefined","latencyMs","codecCtx: CodecCallContext"],"sources":["../src/execution/runtime-error.ts","../src/execution/async-iterable-result.ts","../src/execution/race-against-abort.ts","../src/execution/run-with-middleware.ts","../src/execution/runtime-core.ts","../src/execution/runtime-middleware.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 */\nexport const RUNTIME_ABORTED = 'RUNTIME.ABORTED' as const;\n\n/** Discriminator placed in `details.phase` of a `RUNTIME.ABORTED` envelope. */\nexport type RuntimeAbortedPhase = 'encode' | 'decode' | 'stream';\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 (encode / decode / stream); cause carries `signal.reason`\n * verbatim from the platform — native abort produces a `DOMException`,\n * explicit `controller.abort(reason)` produces whatever the caller passed.\n * 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 './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 { CodecCallContext } from '../shared/codec-types';\nimport type { RuntimeAbortedPhase } from './runtime-error';\nimport { runtimeAborted } from './runtime-error';\n\n/**\n * Throw a phase-tagged `RUNTIME.ABORTED` envelope if the supplied\n * codec-call context is already aborted at the precheck site. Centralises\n * the `if (ctx.signal?.aborted) throw runtimeAborted(...)` pattern that\n * every codec dispatch site repeats.\n */\nexport function checkAborted(ctx: CodecCallContext, phase: RuntimeAbortedPhase): 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 { 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 lifecycle.\n *\n * Lifecycle, in order:\n * 1. For each middleware in registration order: `beforeExecute(exec, ctx)`.\n * 2. For each row yielded by `runDriver()`: for each middleware in registration\n * order: `onRow(row, exec, ctx)`; then yield the row to the consumer.\n * 3. On successful completion: for each middleware in registration order:\n * `afterExecute(exec, { rowCount, latencyMs, completed: true }, ctx)`.\n * 4. On any error thrown by the driver loop: for each middleware in\n * registration order: `afterExecute(exec, { rowCount, latencyMs,\n * completed: false }, ctx)`. Errors thrown by `afterExecute` during the\n * error path are swallowed so they do not mask the original driver error.\n * The original error is then rethrown.\n *\n * This helper is the single canonical implementation of the middleware\n * orchestration loop; family runtimes should not 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\n try {\n for (const mw of middleware) {\n if (mw.beforeExecute) {\n await mw.beforeExecute(exec, ctx);\n }\n }\n\n for await (const row of runDriver()) {\n for (const mw of middleware) {\n if (mw.onRow) {\n await mw.onRow(row as Record<string, unknown>, exec, ctx);\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 }, ctx);\n } catch {\n // Swallow afterExecute errors during the error path so they do not\n // mask the original driver 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 }, 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 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. `runWithMiddleware(exec, this.middleware, this.ctx,\n * () => runDriver(exec))` — concrete; lifts the middleware lifecycle\n * out of the family runtimes into the canonical helper.\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 // 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 { 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\nexport interface RuntimeMiddlewareContext {\n readonly contract: unknown;\n readonly mode: 'strict' | 'permissive';\n readonly now: () => number;\n readonly log: RuntimeLog;\n}\n\nexport interface AfterExecuteResult {\n readonly rowCount: number;\n readonly latencyMs: number;\n readonly completed: boolean;\n}\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 */\nexport interface RuntimeMiddleware<TPlan extends QueryPlan = QueryPlan> {\n readonly name: string;\n readonly familyId?: string;\n readonly targetId?: string;\n beforeExecute?(plan: TPlan, ctx: RuntimeMiddlewareContext): 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 * 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}\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"],"mappings":";;;;;;;;;;;;AAkBA,MAAa,kBAAkB;;;;;;;AAW/B,SAAgB,eAAe,OAA+C;AAC5E,QACE,iBAAiB,SACjB,UAAU,SACV,OAAQ,MAA6B,SAAS,YAC9C,cAAc,SACd,cAAc;;AAIlB,SAAgB,aACd,MACA,SACA,SACsB;CACtB,MAAM,QAAQ,IAAI,MAAM,QAAQ;AAChC,QAAO,eAAe,OAAO,QAAQ;EACnC,OAAO;EACP,cAAc;EACf,CAAC;AAEF,QAAO,OAAO,OAAO,OAAO;EAC1B;EACA,UAAU,gBAAgB,KAAK;EAC/B,UAAU;EACV;EACA;EACD,CAAC;;AAGJ,SAAS,gBAAgB,MAAgD;CACvE,MAAM,SAAS,KAAK,MAAM,IAAI,CAAC,MAAM;AACrC,SAAQ,QAAR;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,SACH,QAAO;EACT,QACE,QAAO;;;;;;;;;;AAWb,SAAgB,eAAe,OAA4B,OAAuC;CAChG,MAAM,WAAW,aAAa,iBAAiB,4BAA4B,SAAS,EAAE,OAAO,CAAC;AAC9F,QAAO,OAAO,OAAO,UAAU,EAAE,OAAO,CAAC;;;;;AC/E3C,IAAa,sBAAb,MAAwF;CACtF,AAAiB;CACjB,AAAQ,WAAW;CACnB,AAAQ;CACR,AAAQ;CAER,YAAY,WAA+C;AACzD,OAAK,YAAY;;CAGnB,CAAC,OAAO,iBAAqC;AAC3C,MAAI,KAAK,SACP,OAAM,aACJ,6BACA,8DAA8D,KAAK,eAAe,kBAAkB,qBAAqB,iBAAiB,wDAC1I;GACE,YAAY,KAAK;GACjB,YACE,KAAK,eAAe,kBAChB,0GACA;GACP,CACF;AAEH,OAAK,WAAW;AAChB,OAAK,aAAa;AAClB,SAAO,KAAK;;CAGd,UAA0B;AACxB,MAAI,KAAK,eAAe,WACtB,QAAO,QAAQ,OACb,aACE,6BACA,kIACA;GACE,YAAY,KAAK;GACjB,YACE;GACH,CACF,CACF;AAGH,MAAI,KAAK,qBACP,QAAO,KAAK;AAGd,OAAK,WAAW;AAChB,OAAK,aAAa;AAClB,OAAK,wBAAwB,YAAY;GACvC,MAAMA,MAAa,EAAE;AACrB,cAAW,MAAM,QAAQ,KAAK,UAC5B,KAAI,KAAK,KAAK;AAEhB,UAAO;MACL;AACJ,SAAO,KAAK;;CAGd,MAAM,QAA6B;AAEjC,UADa,MAAM,KAAK,SAAS,EACrB,MAAM;;CAGpB,MAAM,eAA6B;EACjC,MAAM,MAAM,MAAM,KAAK,OAAO;AAC9B,MAAI,QAAQ,KACV,OAAM,aACJ,mBACA,qDACA,EAAE,CACH;AACH,SAAO;;CAIT,KACE,aACA,YACkC;AAClC,SAAO,KAAK,SAAS,CAAC,KAAK,aAAa,WAAW;;;;;;;;;;;;ACzEvD,SAAgB,aAAa,KAAuB,OAAkC;AACpF,KAAI,IAAI,QAAQ,QACd,OAAM,eAAe,OAAO,IAAI,OAAO,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoClD,eAAsB,iBACpB,MACA,QACA,OACY;AACZ,KAAI,WAAW,OACb,QAAO,MAAM;CAEf,MAAMC,WAAgC,EAAE,QAAQ,QAAW;CAC3D,IAAIC;CAEJ,MAAM,eAAe,IAAI,SAAgB,GAAG,WAAW;AACrD,MAAI,OAAO,SAAS;AAClB,YAAS,SAAS,OAAO;AACzB,UAAO,SAAS;AAChB;;AAEF,kBAAgB;AACd,YAAS,SAAS,OAAO;AACzB,UAAO,SAAS;;AAElB,SAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;GACzD;AAEF,KAAI;AACF,SAAO,MAAM,QAAQ,KAAK,CAAC,MAAM,aAAa,CAAC;UACxC,OAAO;AACd,MAAI,UAAU,SACZ,OAAM,eAAe,OAAO,SAAS,OAAO;AAE9C,QAAM;WACE;AACR,MAAI,QACF,QAAO,oBAAoB,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;AC3DlD,SAAgB,kBACd,MACA,YACA,KACA,WAC0B;CAC1B,MAAM,WAAW,mBAAuD;EACtE,MAAM,YAAY,KAAK,KAAK;EAC5B,IAAI,WAAW;EACf,IAAI,YAAY;AAEhB,MAAI;AACF,QAAK,MAAM,MAAM,WACf,KAAI,GAAG,cACL,OAAM,GAAG,cAAc,MAAM,IAAI;AAIrC,cAAW,MAAM,OAAO,WAAW,EAAE;AACnC,SAAK,MAAM,MAAM,WACf,KAAI,GAAG,MACL,OAAM,GAAG,MAAM,KAAgC,MAAM,IAAI;AAG7D;AACA,UAAM;;AAGR,eAAY;WACL,OAAO;GACd,MAAMC,cAAY,KAAK,KAAK,GAAG;AAC/B,QAAK,MAAM,MAAM,WACf,KAAI,GAAG,aACL,KAAI;AACF,UAAM,GAAG,aAAa,MAAM;KAAE;KAAU;KAAW;KAAW,EAAE,IAAI;WAC9D;AAOZ,SAAM;;EAGR,MAAM,YAAY,KAAK,KAAK,GAAG;AAC/B,OAAK,MAAM,MAAM,WACf,KAAI,GAAG,aACL,OAAM,GAAG,aAAa,MAAM;GAAE;GAAU;GAAW;GAAW,EAAE,IAAI;;AAK1E,QAAO,IAAI,oBAAoB,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1B5C,IAAsB,cAAtB,MAKA;CACE,AAAmB;CACnB,AAAmB;CAEnB,YAAY,SAA0C;AACpD,OAAK,aAAa,QAAQ;AAC1B,OAAK,MAAM,QAAQ;;;;;;;CAQrB,AAAU,iBAAiB,MAAqC;AAC9D,SAAO;;CAgCT,QACE,MACA,SAC0B;EAC1B,MAAM,OAAO;EACb,MAAM,SAAS,SAAS;EAKxB,MAAMC,WAA6B,WAAW,SAAY,EAAE,GAAG,EAAE,QAAQ;EAEzE,gBAAgB,YAAgD;AAG9D,gBAAa,UAAU,SAAS;GAEhC,MAAM,WAAW,MAAM,KAAK,iBAAiB,KAAK;GAClD,MAAM,OAAO,MAAM,KAAK,MAAM,UAAU,SAAS;AAGjD,UAAO,kBACL,MACA,KAAK,YACL,KAAK,WACC,KAAK,UAAU,KAAK,CAC3B;;AAGH,SAAO,IAAI,oBAAoB,WAAW,CAAC;;;;;;ACxD/C,SAAgB,6BACd,YACA,iBACA,iBACM;AACN,KAAI,WAAW,aAAa,UAAa,WAAW,aAAa,OAC/D,OAAM,aACJ,mCACA,eAAe,WAAW,KAAK,wBAAwB,WAAW,SAAS,qBAC3E;EAAE,YAAY,WAAW;EAAM,UAAU,WAAW;EAAU,CAC/D;AAGH,KAAI,WAAW,aAAa,UAAa,WAAW,aAAa,gBAC/D,OAAM,aACJ,sCACA,eAAe,WAAW,KAAK,qBAAqB,WAAW,SAAS,8CAA8C,gBAAgB,IACtI;EAAE,YAAY,WAAW;EAAM,oBAAoB,WAAW;EAAU;EAAiB,CAC1F;AAGH,KAAI,WAAW,aAAa,UAAa,WAAW,aAAa,gBAC/D,OAAM,aACJ,sCACA,eAAe,WAAW,KAAK,qBAAqB,WAAW,SAAS,8CAA8C,gBAAgB,IACtI;EAAE,YAAY,WAAW;EAAM,oBAAoB,WAAW;EAAU;EAAiB,CAC1F"}
@@ -1,4 +1,4 @@
1
- //#region src/types-import-spec.d.ts
1
+ //#region src/shared/types-import-spec.d.ts
2
2
  /**
3
3
  * Specifies how to import TypeScript types from a package.
4
4
  * Used in extension pack manifests to declare codec and operation type imports.
@@ -10,4 +10,4 @@ interface TypesImportSpec {
10
10
  }
11
11
  //#endregion
12
12
  export { TypesImportSpec as t };
13
- //# sourceMappingURL=types-import-spec-C4sc7wbb.d.mts.map
13
+ //# sourceMappingURL=types-import-spec-D-O6GotH.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-import-spec-D-O6GotH.d.mts","names":[],"sources":["../src/shared/types-import-spec.ts"],"sourcesContent":[],"mappings":";;AAIA;;;UAAiB,eAAA"}
package/package.json CHANGED
@@ -1,20 +1,21 @@
1
1
  {
2
2
  "name": "@prisma-next/framework-components",
3
- "version": "0.5.0-dev.3",
3
+ "version": "0.5.0-dev.31",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Framework component types, assembly logic, and stack creation for Prisma Next",
7
7
  "dependencies": {
8
- "@prisma-next/utils": "0.5.0-dev.3",
9
- "@prisma-next/operations": "0.5.0-dev.3",
10
- "@prisma-next/contract": "0.5.0-dev.3"
8
+ "@standard-schema/spec": "^1.1.0",
9
+ "@prisma-next/operations": "0.5.0-dev.31",
10
+ "@prisma-next/utils": "0.5.0-dev.31",
11
+ "@prisma-next/contract": "0.5.0-dev.31"
11
12
  },
12
13
  "devDependencies": {
13
14
  "tsdown": "0.18.4",
14
15
  "typescript": "5.9.3",
15
16
  "vitest": "4.0.17",
16
- "@prisma-next/tsconfig": "0.0.0",
17
- "@prisma-next/tsdown": "0.0.0"
17
+ "@prisma-next/tsdown": "0.0.0",
18
+ "@prisma-next/tsconfig": "0.0.0"
18
19
  },
19
20
  "files": [
20
21
  "dist",
@@ -27,6 +28,7 @@
27
28
  "./control": "./dist/control.mjs",
28
29
  "./emission": "./dist/emission.mjs",
29
30
  "./execution": "./dist/execution.mjs",
31
+ "./psl-ast": "./dist/psl-ast.mjs",
30
32
  "./runtime": "./dist/runtime.mjs",
31
33
  "./package.json": "./package.json"
32
34
  },
@@ -0,0 +1,71 @@
1
+ import type { ControlTargetDescriptor } from './control-descriptors';
2
+ import type { ControlFamilyInstance } from './control-instances';
3
+ import type { MigrationPlanOperation, TargetMigrationsCapability } from './control-migration-types';
4
+ import type { OperationPreview } from './control-operation-preview';
5
+ import type { CoreSchemaView } from './control-schema-view';
6
+ import type { PslDocumentAst } from './psl-ast';
7
+
8
+ export interface MigratableTargetDescriptor<
9
+ TFamilyId extends string,
10
+ TTargetId extends string,
11
+ TFamilyInstance extends ControlFamilyInstance<TFamilyId, unknown> = ControlFamilyInstance<
12
+ TFamilyId,
13
+ unknown
14
+ >,
15
+ > extends ControlTargetDescriptor<TFamilyId, TTargetId> {
16
+ readonly migrations: TargetMigrationsCapability<TFamilyId, TTargetId, TFamilyInstance>;
17
+ }
18
+
19
+ export function hasMigrations<TFamilyId extends string, TTargetId extends string>(
20
+ target: ControlTargetDescriptor<TFamilyId, TTargetId>,
21
+ ): target is MigratableTargetDescriptor<TFamilyId, TTargetId> {
22
+ return 'migrations' in target && !!(target as Record<string, unknown>)['migrations'];
23
+ }
24
+
25
+ export interface SchemaViewCapable<TSchemaIR = unknown> {
26
+ toSchemaView(schema: TSchemaIR): CoreSchemaView;
27
+ }
28
+
29
+ export function hasSchemaView<TFamilyId extends string, TSchemaIR>(
30
+ instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,
31
+ ): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & SchemaViewCapable<TSchemaIR> {
32
+ return (
33
+ 'toSchemaView' in instance &&
34
+ typeof (instance as Record<string, unknown>)['toSchemaView'] === 'function'
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Capability declaring that a family can infer a PSL contract AST from its
40
+ * opaque introspected schema IR. Consumed by `prisma-next contract infer`.
41
+ */
42
+ export interface PslContractInferCapable<TSchemaIR = unknown> {
43
+ inferPslContract(schemaIR: TSchemaIR): PslDocumentAst;
44
+ }
45
+
46
+ export function hasPslContractInfer<TFamilyId extends string, TSchemaIR>(
47
+ instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,
48
+ ): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & PslContractInferCapable<TSchemaIR> {
49
+ return (
50
+ 'inferPslContract' in instance &&
51
+ typeof (instance as Record<string, unknown>)['inferPslContract'] === 'function'
52
+ );
53
+ }
54
+
55
+ /**
56
+ * Capability declaring that a family can render a textual preview of migration
57
+ * operations for the CLI's "DDL preview" output. SQL families emit
58
+ * `language: 'sql'` statements; Mongo families emit `language: 'mongodb-shell'`.
59
+ */
60
+ export interface OperationPreviewCapable {
61
+ toOperationPreview(operations: readonly MigrationPlanOperation[]): OperationPreview;
62
+ }
63
+
64
+ export function hasOperationPreview<TFamilyId extends string, TSchemaIR>(
65
+ instance: ControlFamilyInstance<TFamilyId, TSchemaIR>,
66
+ ): instance is ControlFamilyInstance<TFamilyId, TSchemaIR> & OperationPreviewCapable {
67
+ return (
68
+ 'toOperationPreview' in instance &&
69
+ typeof (instance as Record<string, unknown>)['toOperationPreview'] === 'function'
70
+ );
71
+ }
@@ -1,3 +1,10 @@
1
+ import type {
2
+ AdapterDescriptor,
3
+ DriverDescriptor,
4
+ ExtensionDescriptor,
5
+ FamilyDescriptor,
6
+ TargetDescriptor,
7
+ } from '../shared/framework-components';
1
8
  import type {
2
9
  ControlAdapterInstance,
3
10
  ControlDriverInstance,
@@ -7,13 +14,6 @@ import type {
7
14
  } from './control-instances';
8
15
  import type { ControlStack } from './control-stack';
9
16
  import type { EmissionSpi } from './emission-types';
10
- import type {
11
- AdapterDescriptor,
12
- DriverDescriptor,
13
- ExtensionDescriptor,
14
- FamilyDescriptor,
15
- TargetDescriptor,
16
- } from './framework-components';
17
17
 
18
18
  export interface ControlFamilyDescriptor<
19
19
  TFamilyId extends string,
@@ -1,9 +1,4 @@
1
1
  import type { Contract, ContractMarkerRecord } from '@prisma-next/contract/types';
2
- import type {
3
- SignDatabaseResult,
4
- VerifyDatabaseResult,
5
- VerifyDatabaseSchemaResult,
6
- } from './control-result-types';
7
2
  import type {
8
3
  AdapterInstance,
9
4
  DriverInstance,
@@ -11,7 +6,12 @@ import type {
11
6
  FamilyInstance,
12
7
  TargetBoundComponentDescriptor,
13
8
  TargetInstance,
14
- } from './framework-components';
9
+ } from '../shared/framework-components';
10
+ import type {
11
+ SignDatabaseResult,
12
+ VerifyDatabaseResult,
13
+ VerifyDatabaseSchemaResult,
14
+ } from './control-result-types';
15
15
 
16
16
  export interface ControlFamilyInstance<TFamilyId extends string, TSchemaIR>
17
17
  extends FamilyInstance<TFamilyId> {
@@ -11,8 +11,8 @@
11
11
 
12
12
  import type { Contract } from '@prisma-next/contract/types';
13
13
  import type { Result } from '@prisma-next/utils/result';
14
+ import type { TargetBoundComponentDescriptor } from '../shared/framework-components';
14
15
  import type { ControlDriverInstance, ControlFamilyInstance } from './control-instances';
15
- import type { TargetBoundComponentDescriptor } from './framework-components';
16
16
 
17
17
  // ============================================================================
18
18
  // Operation Classes and Policy
@@ -48,20 +48,21 @@ export interface SerializedQueryPlan {
48
48
  * serialized to JSON ASTs at verification time, and rendered to SQL
49
49
  * by the target adapter at apply time.
50
50
  *
51
- * The `name` serves as the invariant identity — it's recorded in the
52
- * ledger and used for invariant-aware routing via environment refs.
53
- *
54
51
  * In draft state (before verification), `check` and `run` are null.
55
52
  * After verification, they contain the serialized query ASTs.
56
53
  */
57
54
  export interface DataTransformOperation extends MigrationPlanOperation {
58
55
  readonly operationClass: 'data';
59
56
  /**
60
- * The invariant name for this data transform.
61
- * Recorded in the ledger on successful edge completion.
62
- * Used by environment refs to declare required invariants.
57
+ * Human-readable label for this data transform.
63
58
  */
64
59
  readonly name: string;
60
+ /**
61
+ * Optional opt-in routing identity. Presence opts the transform into
62
+ * invariant-aware routing; absence means it is path-dependent and
63
+ * not referenceable from refs.
64
+ */
65
+ readonly invariantId?: string;
65
66
  /**
66
67
  * Path to the TypeScript source file that produced this operation.
67
68
  * Not part of edgeId computation — for traceability only.
@@ -291,11 +292,11 @@ export interface MigrationPlanner<
291
292
  readonly policy: MigrationOperationPolicy;
292
293
  /**
293
294
  * Storage hash of the "from" contract (the state the planner assumes the
294
- * database starts at). Planners use this to populate `describe()` on the
295
- * produced plan so the rendered `migration.ts` has correct `from`/`to`
296
- * metadata.
295
+ * database starts at), or `null` for a baseline plan with no prior state.
296
+ * Planners use this to populate `describe()` on the produced plan so the
297
+ * rendered `migration.ts` has correct `from`/`to` metadata.
297
298
  */
298
- readonly fromHash: string;
299
+ readonly fromHash: string | null;
299
300
  /**
300
301
  * The "from" contract (the state the planner assumes the database starts
301
302
  * at). Planners pass this to data-safety strategies so they can compare
@@ -335,6 +336,16 @@ export interface MigrationRunner<
335
336
  TFamilyId extends string = string,
336
337
  TTargetId extends string = string,
337
338
  > {
339
+ /**
340
+ * Execute a migration plan against the configured driver.
341
+ *
342
+ * The `plan` parameter is trusted input. Callers are responsible for
343
+ * upstream verification of the originating migration package — typically
344
+ * by obtaining the package via `readMigrationPackage` from
345
+ * `@prisma-next/migration-tools/io`, which performs hash-integrity checks
346
+ * at the load boundary. Runners do not re-verify the plan and assume the
347
+ * `(metadata, ops)` pair on disk has not been tampered with since emit.
348
+ */
338
349
  execute(options: {
339
350
  readonly plan: MigrationPlan;
340
351
  readonly driver: ControlDriverInstance<TFamilyId, TTargetId>;
@@ -414,11 +425,12 @@ export interface MigrationScaffoldContext {
414
425
  /** Absolute path to the contract.json file, if one exists. Used by targets that emit typed-contract imports. */
415
426
  readonly contractJsonPath?: string;
416
427
  /**
417
- * Storage hash of the "from" contract. Targets use this to populate
418
- * `describe()` on the rendered empty migration so that identity metadata
419
- * is correctly populated.
428
+ * Storage hash of the "from" contract, or `null` for a baseline scaffold
429
+ * with no prior state. Targets use this to populate `describe()` on the
430
+ * rendered empty migration so that identity metadata is correctly
431
+ * populated.
420
432
  */
421
- readonly fromHash: string;
433
+ readonly fromHash: string | null;
422
434
  /**
423
435
  * Storage hash of the "to" contract. Same purpose as `fromHash` — threaded
424
436
  * through so the rendered class's `describe()` declares the correct
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Family-agnostic textual preview of a migration plan, used by the CLI to
3
+ * render a "DDL preview" section for `db init` / `db update` / `migration plan`
4
+ * / `migration show`. Each statement carries a free-form `language` tag so
5
+ * formatters can suffix `;` for SQL but render Mongo shell lines verbatim.
6
+ *
7
+ * Producers are family-specific: SQL emits `language: 'sql'` (existing DDL
8
+ * extraction); Mongo emits `language: 'mongodb-shell'` via the
9
+ * `MongoDdlCommandFormatter` visitor.
10
+ *
11
+ * The capability `OperationPreviewCapable` (declared in
12
+ * `./control-capabilities`) is how a family announces it can produce these.
13
+ */
14
+
15
+ export interface OperationPreviewStatement {
16
+ readonly text: string;
17
+ /** Dialect identifier, e.g. `'sql'`, `'mongodb-shell'`. Free-form by design (OQ-3). */
18
+ readonly language: string;
19
+ }
20
+
21
+ export interface OperationPreview {
22
+ readonly statements: readonly OperationPreviewStatement[];
23
+ }