@prisma-next/framework-components 0.5.1 → 0.6.0-dev.10
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.
- package/dist/{codec-m_-FAyQn.d.mts → codec-DcjlJbcO.d.mts} +18 -5
- package/dist/codec-DcjlJbcO.d.mts.map +1 -0
- package/dist/codec.d.mts +2 -2
- package/dist/codec.mjs +1 -1
- package/dist/codec.mjs.map +1 -1
- package/dist/components.d.mts +1 -1
- package/dist/control.d.mts +2 -2
- package/dist/execution.d.mts +1 -1
- package/dist/{framework-components-CHuBHXQN.d.mts → framework-components-DwkHnl-e.d.mts} +2 -2
- package/dist/{framework-components-CHuBHXQN.d.mts.map → framework-components-DwkHnl-e.d.mts.map} +1 -1
- package/dist/runtime.d.mts +197 -104
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +90 -22
- package/dist/runtime.mjs.map +1 -1
- package/dist/utils.d.mts +10 -0
- package/dist/utils.d.mts.map +1 -0
- package/dist/utils.mjs +20 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +8 -7
- package/src/execution/before-execute-chain.ts +77 -0
- package/src/execution/run-with-middleware.ts +20 -38
- package/src/execution/runtime-core.ts +16 -3
- package/src/execution/runtime-middleware.ts +26 -0
- package/src/exports/codec.ts +1 -0
- package/src/exports/runtime.ts +1 -0
- package/src/exports/utils.ts +5 -0
- package/src/shared/codec-descriptor.ts +2 -2
- package/src/shared/codec-types.ts +16 -1
- package/src/utils/canonicalize-json.ts +22 -0
- package/dist/codec-m_-FAyQn.d.mts.map +0 -1
package/dist/runtime.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as CodecCallContext } from "./codec-
|
|
1
|
+
import { o as CodecCallContext } from "./codec-DcjlJbcO.mjs";
|
|
2
2
|
import { PlanMeta } from "@prisma-next/contract/types";
|
|
3
3
|
|
|
4
4
|
//#region src/execution/async-iterable-result.d.ts
|
|
@@ -64,95 +64,6 @@ type ResultType<P> = '_row' extends keyof P ? P extends {
|
|
|
64
64
|
readonly _row?: infer R;
|
|
65
65
|
} ? R : never : never;
|
|
66
66
|
//#endregion
|
|
67
|
-
//#region src/execution/runtime-error.d.ts
|
|
68
|
-
interface RuntimeErrorEnvelope extends Error {
|
|
69
|
-
readonly code: string;
|
|
70
|
-
readonly category: 'PLAN' | 'CONTRACT' | 'LINT' | 'BUDGET' | 'RUNTIME';
|
|
71
|
-
readonly severity: 'error';
|
|
72
|
-
readonly details?: Record<string, unknown>;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Stable code emitted by the runtime when an in-flight `execute()`
|
|
76
|
-
* is cancelled via the per-query `AbortSignal`. The envelope's
|
|
77
|
-
* `details.phase` distinguishes where the abort was observed:
|
|
78
|
-
*
|
|
79
|
-
* - `'encode'` — abort fired during `encodeParams` (SQL) or
|
|
80
|
-
* `resolveValue` (Mongo).
|
|
81
|
-
* - `'decode'` — abort fired during `decodeRow` / `decodeField`.
|
|
82
|
-
* - `'stream'` — abort fired between rows or before any codec call
|
|
83
|
-
* (already-aborted at entry).
|
|
84
|
-
* - `'beforeExecute'` / `'afterExecute'` / `'onRow'` — abort fired
|
|
85
|
-
* on entry to or during the corresponding middleware phase
|
|
86
|
-
* (cooperative cancellation per the param-transform seam).
|
|
87
|
-
*/
|
|
88
|
-
declare const RUNTIME_ABORTED: "RUNTIME.ABORTED";
|
|
89
|
-
/** Discriminator placed in `details.phase` of a `RUNTIME.ABORTED` envelope. */
|
|
90
|
-
type RuntimeAbortedPhase = 'encode' | 'decode' | 'stream' | 'beforeExecute' | 'afterExecute' | 'onRow';
|
|
91
|
-
/**
|
|
92
|
-
* Type guard for the runtime-error envelope produced by `runtimeError`.
|
|
93
|
-
*
|
|
94
|
-
* Prefer this over duck-typing on `error.code` directly so consumers stay
|
|
95
|
-
* insulated from the envelope's internal shape.
|
|
96
|
-
*/
|
|
97
|
-
declare function isRuntimeError(error: unknown): error is RuntimeErrorEnvelope;
|
|
98
|
-
declare function runtimeError(code: string, message: string, details?: Record<string, unknown>): RuntimeErrorEnvelope;
|
|
99
|
-
/**
|
|
100
|
-
* Construct a `RUNTIME.ABORTED` envelope. Phase distinguishes where the
|
|
101
|
-
* abort was observed — codec call sites (`encode` / `decode` / `stream`)
|
|
102
|
-
* or middleware seams (`beforeExecute` / `afterExecute` / `onRow`), as
|
|
103
|
-
* enumerated on {@link RuntimeAbortedPhase}. Cause carries
|
|
104
|
-
* `signal.reason` verbatim from the platform — native abort produces a
|
|
105
|
-
* `DOMException`, explicit `controller.abort(reason)` produces whatever
|
|
106
|
-
* the caller passed. No synthesis happens here.
|
|
107
|
-
*/
|
|
108
|
-
declare function runtimeAborted(phase: RuntimeAbortedPhase, cause?: unknown): RuntimeErrorEnvelope;
|
|
109
|
-
//#endregion
|
|
110
|
-
//#region src/execution/race-against-abort.d.ts
|
|
111
|
-
/**
|
|
112
|
-
* Throw a phase-tagged `RUNTIME.ABORTED` envelope if the supplied
|
|
113
|
-
* context is already aborted at the precheck site. Centralises the
|
|
114
|
-
* `if (ctx.signal?.aborted) throw runtimeAborted(...)` pattern that
|
|
115
|
-
* every codec dispatch site (and the `beforeExecute` middleware phase)
|
|
116
|
-
* repeats. Accepts both the framework `CodecCallContext` and the
|
|
117
|
-
* `RuntimeMiddlewareContext`; both expose `signal?: AbortSignal`.
|
|
118
|
-
*/
|
|
119
|
-
declare function checkAborted(ctx: {
|
|
120
|
-
readonly signal?: AbortSignal;
|
|
121
|
-
}, phase: RuntimeAbortedPhase): void;
|
|
122
|
-
/**
|
|
123
|
-
* Race a per-cell `Promise.all` (or any other in-flight work promise) against
|
|
124
|
-
* the supplied abort signal so the runtime returns `RUNTIME.ABORTED` promptly
|
|
125
|
-
* even when codec bodies ignore the signal. In-flight bodies that ignore the
|
|
126
|
-
* signal are abandoned and run to completion in the background — the
|
|
127
|
-
* cooperative-cancellation contract documented in ADR 204.
|
|
128
|
-
*
|
|
129
|
-
* Call sites still SHOULD pre-check `signal.aborted` and short-circuit with
|
|
130
|
-
* a phase-tagged `RUNTIME.ABORTED` envelope before invoking this helper —
|
|
131
|
-
* that path is the canonical "aborted at entry" surface and avoids
|
|
132
|
-
* scheduling the work promise. As a defensive belt-and-braces, this helper
|
|
133
|
-
* also handles the already-aborted case internally: `AbortSignal` does not
|
|
134
|
-
* replay past abort events to listeners registered after the abort, so we
|
|
135
|
-
* inspect `signal.aborted` synchronously and reject with the sentinel
|
|
136
|
-
* before installing the listener. The rejection is still attributed to the
|
|
137
|
-
* abort path via the sentinel-identity check.
|
|
138
|
-
*
|
|
139
|
-
* Distinguishing the rejection source is load-bearing for AC-ERR4
|
|
140
|
-
* (`RUNTIME.ENCODE_FAILED` / `RUNTIME.DECODE_FAILED` pass through unchanged).
|
|
141
|
-
* The semantically equivalent `abortable(signal)` helper in
|
|
142
|
-
* `@prisma-next/utils` rejects with `signal.reason ?? new DOMException(...)`,
|
|
143
|
-
* which is not stably distinguishable from a codec-thrown error by identity
|
|
144
|
-
* alone (a fresh fallback DOMException is allocated per call). We instead
|
|
145
|
-
* track abort attribution with a unique sentinel: only the `onAbort` listener
|
|
146
|
-
* installed here ever rejects with the sentinel, so an `error === sentinel`
|
|
147
|
-
* identity check after the race is unambiguous.
|
|
148
|
-
*
|
|
149
|
-
* Lives in `framework-components` (rather than the SQL family, where it
|
|
150
|
-
* originated in m2) so every family runtime that needs cooperative
|
|
151
|
-
* cancellation around a codec-dispatch `Promise.all` (SQL encode + decode
|
|
152
|
-
* today, Mongo encode in m3) shares the same attribution logic.
|
|
153
|
-
*/
|
|
154
|
-
declare function raceAgainstAbort<T>(work: Promise<T>, signal: AbortSignal | undefined, phase: RuntimeAbortedPhase): Promise<T>;
|
|
155
|
-
//#endregion
|
|
156
67
|
//#region src/execution/runtime-middleware.d.ts
|
|
157
68
|
interface RuntimeLog {
|
|
158
69
|
info(event: unknown): void;
|
|
@@ -308,6 +219,32 @@ interface RuntimeMiddleware<TPlan extends QueryPlan = QueryPlan, TMutator extend
|
|
|
308
219
|
* rows directly: caching, mocks, rate limiting, circuit breaking.
|
|
309
220
|
*/
|
|
310
221
|
intercept?(plan: TPlan, ctx: RuntimeMiddlewareContext): Promise<InterceptResult | undefined>;
|
|
222
|
+
/**
|
|
223
|
+
* Fires after the family runtime has produced a draft execution
|
|
224
|
+
* plan from the AST, but before the family encodes parameter values
|
|
225
|
+
* to driver wire format. Mutations applied via the
|
|
226
|
+
* family-specific `params` mutator are visible to the subsequent
|
|
227
|
+
* encode step.
|
|
228
|
+
*
|
|
229
|
+
* Lifecycle position (SQL example):
|
|
230
|
+
* `runBeforeCompile → lowerSqlPlan → beforeExecute → encodeParams → intercept → driver`.
|
|
231
|
+
*
|
|
232
|
+
* The `params` argument is a family-specific {@link ParamRefMutator}
|
|
233
|
+
* scoped to the value slots of `ParamRef` nodes in the plan's AST.
|
|
234
|
+
* Middleware that doesn't need to mutate params can ignore the
|
|
235
|
+
* argument; existing `(plan)` / `(plan, ctx)` bodies stay compatible.
|
|
236
|
+
*
|
|
237
|
+
* `ctx.signal` carries the per-query `AbortSignal`; middleware that
|
|
238
|
+
* wraps a network SDK forwards it. Cooperative cancellation
|
|
239
|
+
* surfaces a `RUNTIME.ABORTED { phase: 'beforeExecute' }` envelope
|
|
240
|
+
* promptly even when the body ignores the signal.
|
|
241
|
+
*
|
|
242
|
+
* Intercept ordering: `intercept` runs *after* this hook; an
|
|
243
|
+
* interceptor that short-circuits the driver path still observes
|
|
244
|
+
* the post-`beforeExecute`, fully-encoded plan. The trade-off is
|
|
245
|
+
* that any `beforeExecute` SDK round-trips happen even when a
|
|
246
|
+
* downstream interceptor would have skipped the driver entirely.
|
|
247
|
+
*/
|
|
311
248
|
beforeExecute?(plan: TPlan, ctx: RuntimeMiddlewareContext, params?: TMutator): void | Promise<void>;
|
|
312
249
|
onRow?(row: Record<string, unknown>, plan: TPlan, ctx: RuntimeMiddlewareContext): Promise<void>;
|
|
313
250
|
afterExecute?(plan: TPlan, result: AfterExecuteResult, ctx: RuntimeMiddlewareContext): Promise<void>;
|
|
@@ -340,9 +277,151 @@ interface RuntimeExecutor<TPlan extends QueryPlan> {
|
|
|
340
277
|
}
|
|
341
278
|
declare function checkMiddlewareCompatibility(middleware: RuntimeMiddleware, runtimeFamilyId: string, runtimeTargetId: string): void;
|
|
342
279
|
//#endregion
|
|
280
|
+
//#region src/execution/before-execute-chain.d.ts
|
|
281
|
+
/**
|
|
282
|
+
* Runs every middleware's `beforeExecute` hook in registration order,
|
|
283
|
+
* threading through the (optional) family-specific `paramsMutator`.
|
|
284
|
+
*
|
|
285
|
+
* Why this lives outside {@link runWithMiddleware}: middleware that
|
|
286
|
+
* mutates parameter values (e.g. cipherstash's bulk-encrypt SDK
|
|
287
|
+
* round-trip) must run *before* the family runtime encodes those
|
|
288
|
+
* parameters to driver wire format. Family runtimes call
|
|
289
|
+
* `runBeforeExecuteChain` between the AST → plan lowering step and
|
|
290
|
+
* the parameter encode step; the encode then observes the mutator's
|
|
291
|
+
* `currentParams()` view. `runWithMiddleware` retains the rest of
|
|
292
|
+
* the lifecycle (`intercept`, driver/row source loop, `onRow`,
|
|
293
|
+
* `afterExecute`) but no longer fires `beforeExecute` itself.
|
|
294
|
+
*
|
|
295
|
+
* Lifecycle within this helper:
|
|
296
|
+
*
|
|
297
|
+
* 1. For each middleware in registration order, if `beforeExecute`
|
|
298
|
+
* is implemented:
|
|
299
|
+
* - `checkAborted(ctx, 'beforeExecute')` short-circuits if the
|
|
300
|
+
* caller already aborted at entry.
|
|
301
|
+
* - The hook is invoked with `(plan, ctx, paramsMutator)`. A
|
|
302
|
+
* middleware body that ignores the mutator stays compatible —
|
|
303
|
+
* JavaScript allows extra positional arguments.
|
|
304
|
+
* - If the hook returns a Promise, it is raced against
|
|
305
|
+
* `ctx.signal` via {@link raceAgainstAbort} so cooperative
|
|
306
|
+
* cancellation surfaces a `RUNTIME.ABORTED { phase:
|
|
307
|
+
* 'beforeExecute' }` envelope even when the body itself
|
|
308
|
+
* ignores the signal.
|
|
309
|
+
*
|
|
310
|
+
* Error propagation: any error thrown by a `beforeExecute` body
|
|
311
|
+
* (or surfaced by the abort race) propagates out of this helper
|
|
312
|
+
* unchanged. The family runtime is responsible for converting it
|
|
313
|
+
* into the appropriate `afterExecute(completed: false)` notification
|
|
314
|
+
* once `runWithMiddleware` runs.
|
|
315
|
+
*
|
|
316
|
+
* Relationship to {@link runWithMiddleware}: the framework's
|
|
317
|
+
* `RuntimeCore.execute` template calls this helper between
|
|
318
|
+
* `lower(plan)` and `runWithMiddleware(...)`. Family runtimes that
|
|
319
|
+
* override `execute` (e.g. SQL, which inlines lower + encode for
|
|
320
|
+
* direct mutator threading) call this helper themselves at the
|
|
321
|
+
* equivalent point — between the family's AST → draft-plan
|
|
322
|
+
* lowering and the parameter-encode step.
|
|
323
|
+
*
|
|
324
|
+
* Intercept ordering: this helper fires unconditionally before
|
|
325
|
+
* `runWithMiddleware`. `intercept` (inside `runWithMiddleware`)
|
|
326
|
+
* therefore observes the post-`beforeExecute` plan — mutator
|
|
327
|
+
* mutations are visible in the params interceptors see. The
|
|
328
|
+
* trade-off is documented on `RuntimeMiddleware.intercept`.
|
|
329
|
+
*/
|
|
330
|
+
declare function runBeforeExecuteChain<TExec extends ExecutionPlan, TMutator extends ParamRefMutator = ParamRefMutator>(plan: TExec, middleware: ReadonlyArray<RuntimeMiddleware<TExec, TMutator>>, ctx: RuntimeMiddlewareContext, paramsMutator?: TMutator): Promise<void>;
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/execution/runtime-error.d.ts
|
|
333
|
+
interface RuntimeErrorEnvelope extends Error {
|
|
334
|
+
readonly code: string;
|
|
335
|
+
readonly category: 'PLAN' | 'CONTRACT' | 'LINT' | 'BUDGET' | 'RUNTIME';
|
|
336
|
+
readonly severity: 'error';
|
|
337
|
+
readonly details?: Record<string, unknown>;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Stable code emitted by the runtime when an in-flight `execute()`
|
|
341
|
+
* is cancelled via the per-query `AbortSignal`. The envelope's
|
|
342
|
+
* `details.phase` distinguishes where the abort was observed:
|
|
343
|
+
*
|
|
344
|
+
* - `'encode'` — abort fired during `encodeParams` (SQL) or
|
|
345
|
+
* `resolveValue` (Mongo).
|
|
346
|
+
* - `'decode'` — abort fired during `decodeRow` / `decodeField`.
|
|
347
|
+
* - `'stream'` — abort fired between rows or before any codec call
|
|
348
|
+
* (already-aborted at entry).
|
|
349
|
+
* - `'beforeExecute'` / `'afterExecute'` / `'onRow'` — abort fired
|
|
350
|
+
* on entry to or during the corresponding middleware phase
|
|
351
|
+
* (cooperative cancellation per the param-transform seam).
|
|
352
|
+
*/
|
|
353
|
+
declare const RUNTIME_ABORTED: "RUNTIME.ABORTED";
|
|
354
|
+
/** Discriminator placed in `details.phase` of a `RUNTIME.ABORTED` envelope. */
|
|
355
|
+
type RuntimeAbortedPhase = 'encode' | 'decode' | 'stream' | 'beforeExecute' | 'afterExecute' | 'onRow';
|
|
356
|
+
/**
|
|
357
|
+
* Type guard for the runtime-error envelope produced by `runtimeError`.
|
|
358
|
+
*
|
|
359
|
+
* Prefer this over duck-typing on `error.code` directly so consumers stay
|
|
360
|
+
* insulated from the envelope's internal shape.
|
|
361
|
+
*/
|
|
362
|
+
declare function isRuntimeError(error: unknown): error is RuntimeErrorEnvelope;
|
|
363
|
+
declare function runtimeError(code: string, message: string, details?: Record<string, unknown>): RuntimeErrorEnvelope;
|
|
364
|
+
/**
|
|
365
|
+
* Construct a `RUNTIME.ABORTED` envelope. Phase distinguishes where the
|
|
366
|
+
* abort was observed — codec call sites (`encode` / `decode` / `stream`)
|
|
367
|
+
* or middleware seams (`beforeExecute` / `afterExecute` / `onRow`), as
|
|
368
|
+
* enumerated on {@link RuntimeAbortedPhase}. Cause carries
|
|
369
|
+
* `signal.reason` verbatim from the platform — native abort produces a
|
|
370
|
+
* `DOMException`, explicit `controller.abort(reason)` produces whatever
|
|
371
|
+
* the caller passed. No synthesis happens here.
|
|
372
|
+
*/
|
|
373
|
+
declare function runtimeAborted(phase: RuntimeAbortedPhase, cause?: unknown): RuntimeErrorEnvelope;
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region src/execution/race-against-abort.d.ts
|
|
376
|
+
/**
|
|
377
|
+
* Throw a phase-tagged `RUNTIME.ABORTED` envelope if the supplied
|
|
378
|
+
* context is already aborted at the precheck site. Centralises the
|
|
379
|
+
* `if (ctx.signal?.aborted) throw runtimeAborted(...)` pattern that
|
|
380
|
+
* every codec dispatch site (and the `beforeExecute` middleware phase)
|
|
381
|
+
* repeats. Accepts both the framework `CodecCallContext` and the
|
|
382
|
+
* `RuntimeMiddlewareContext`; both expose `signal?: AbortSignal`.
|
|
383
|
+
*/
|
|
384
|
+
declare function checkAborted(ctx: {
|
|
385
|
+
readonly signal?: AbortSignal;
|
|
386
|
+
}, phase: RuntimeAbortedPhase): void;
|
|
387
|
+
/**
|
|
388
|
+
* Race a per-cell `Promise.all` (or any other in-flight work promise) against
|
|
389
|
+
* the supplied abort signal so the runtime returns `RUNTIME.ABORTED` promptly
|
|
390
|
+
* even when codec bodies ignore the signal. In-flight bodies that ignore the
|
|
391
|
+
* signal are abandoned and run to completion in the background — the
|
|
392
|
+
* cooperative-cancellation contract documented in ADR 204.
|
|
393
|
+
*
|
|
394
|
+
* Call sites still SHOULD pre-check `signal.aborted` and short-circuit with
|
|
395
|
+
* a phase-tagged `RUNTIME.ABORTED` envelope before invoking this helper —
|
|
396
|
+
* that path is the canonical "aborted at entry" surface and avoids
|
|
397
|
+
* scheduling the work promise. As a defensive belt-and-braces, this helper
|
|
398
|
+
* also handles the already-aborted case internally: `AbortSignal` does not
|
|
399
|
+
* replay past abort events to listeners registered after the abort, so we
|
|
400
|
+
* inspect `signal.aborted` synchronously and reject with the sentinel
|
|
401
|
+
* before installing the listener. The rejection is still attributed to the
|
|
402
|
+
* abort path via the sentinel-identity check.
|
|
403
|
+
*
|
|
404
|
+
* Distinguishing the rejection source is load-bearing for AC-ERR4
|
|
405
|
+
* (`RUNTIME.ENCODE_FAILED` / `RUNTIME.DECODE_FAILED` pass through unchanged).
|
|
406
|
+
* The semantically equivalent `abortable(signal)` helper in
|
|
407
|
+
* `@prisma-next/utils` rejects with `signal.reason ?? new DOMException(...)`,
|
|
408
|
+
* which is not stably distinguishable from a codec-thrown error by identity
|
|
409
|
+
* alone (a fresh fallback DOMException is allocated per call). We instead
|
|
410
|
+
* track abort attribution with a unique sentinel: only the `onAbort` listener
|
|
411
|
+
* installed here ever rejects with the sentinel, so an `error === sentinel`
|
|
412
|
+
* identity check after the race is unambiguous.
|
|
413
|
+
*
|
|
414
|
+
* Lives in `framework-components` (rather than the SQL family, where it
|
|
415
|
+
* originated in m2) so every family runtime that needs cooperative
|
|
416
|
+
* cancellation around a codec-dispatch `Promise.all` (SQL encode + decode
|
|
417
|
+
* today, Mongo encode in m3) shares the same attribution logic.
|
|
418
|
+
*/
|
|
419
|
+
declare function raceAgainstAbort<T>(work: Promise<T>, signal: AbortSignal | undefined, phase: RuntimeAbortedPhase): Promise<T>;
|
|
420
|
+
//#endregion
|
|
343
421
|
//#region src/execution/run-with-middleware.d.ts
|
|
344
422
|
/**
|
|
345
|
-
* Drives a single execution of `runDriver()` through the middleware
|
|
423
|
+
* Drives a single execution of `runDriver()` through the middleware
|
|
424
|
+
* lifecycle's intercept + row-source + termination phases.
|
|
346
425
|
*
|
|
347
426
|
* Lifecycle, in order:
|
|
348
427
|
* 1. For each middleware in registration order: `intercept(exec, ctx)`. The
|
|
@@ -352,31 +431,38 @@ declare function checkMiddlewareCompatibility(middleware: RuntimeMiddleware, run
|
|
|
352
431
|
* the intercepted rows, and proceeds with `source: 'middleware'`. On
|
|
353
432
|
* all-passthrough (every `intercept` returns `undefined` or is omitted),
|
|
354
433
|
* `source: 'driver'` is used and the row source is `runDriver()`.
|
|
355
|
-
* 2.
|
|
356
|
-
* `beforeExecute(exec, ctx)`. Skipped on the intercepted hit path —
|
|
357
|
-
* `beforeExecute` semantically means "about to hit the driver".
|
|
358
|
-
* 3. Iterate the row source. On the driver path, for each row, for each
|
|
434
|
+
* 2. Iterate the row source. On the driver path, for each row, for each
|
|
359
435
|
* middleware in registration order: `onRow(row, exec, ctx)`; then yield
|
|
360
436
|
* the row. On the intercepted hit path, `onRow` is skipped — intercepted
|
|
361
437
|
* rows did not originate from a driver row stream — but rows are still
|
|
362
438
|
* yielded to the consumer in order.
|
|
363
|
-
*
|
|
439
|
+
* 3. On successful completion: for each middleware in registration order:
|
|
364
440
|
* `afterExecute(exec, { rowCount, latencyMs, completed: true, source },
|
|
365
441
|
* ctx)`.
|
|
366
|
-
*
|
|
442
|
+
* 4. On any error thrown during steps 1–2: for each middleware in
|
|
367
443
|
* registration order: `afterExecute(exec, { rowCount, latencyMs,
|
|
368
444
|
* completed: false, source }, ctx)`. Errors thrown by `afterExecute`
|
|
369
445
|
* during the error path are swallowed so they do not mask the original
|
|
370
446
|
* error. The original error is then rethrown.
|
|
371
447
|
*
|
|
448
|
+
* `beforeExecute` is **not** fired here — see
|
|
449
|
+
* {@link runBeforeExecuteChain} in `before-execute-chain.ts`. Family
|
|
450
|
+
* runtimes call that helper between the AST → plan lowering step and
|
|
451
|
+
* the parameter encode step so middleware that mutates ParamRef
|
|
452
|
+
* values (e.g. cipherstash bulk-encrypt) can have its mutations
|
|
453
|
+
* visible to encode. `runWithMiddleware` operates on the fully-
|
|
454
|
+
* encoded plan; interceptors therefore observe a fully-mutated,
|
|
455
|
+
* encoded plan.
|
|
456
|
+
*
|
|
372
457
|
* The `source` field on `AfterExecuteResult` lets observers (telemetry,
|
|
373
458
|
* lints, budgets) distinguish driver-served from middleware-served
|
|
374
459
|
* executions without needing their own out-of-band signal.
|
|
375
460
|
*
|
|
376
|
-
* This helper is the single canonical implementation of the
|
|
377
|
-
*
|
|
461
|
+
* This helper is the single canonical implementation of the
|
|
462
|
+
* intercept-and-row-source loop; family runtimes should not
|
|
463
|
+
* reimplement it.
|
|
378
464
|
*/
|
|
379
|
-
declare function runWithMiddleware<TExec extends ExecutionPlan, Row
|
|
465
|
+
declare function runWithMiddleware<TExec extends ExecutionPlan, Row>(exec: TExec, middleware: ReadonlyArray<RuntimeMiddleware<TExec>>, ctx: RuntimeMiddlewareContext, runDriver: () => AsyncIterable<Row>): AsyncIterableResult<Row>;
|
|
380
466
|
//#endregion
|
|
381
467
|
//#region src/execution/runtime-core.d.ts
|
|
382
468
|
/**
|
|
@@ -399,9 +485,16 @@ interface RuntimeCoreOptions<TMiddleware extends RuntimeMiddleware<ExecutionPlan
|
|
|
399
485
|
* this to run its `beforeCompile` middleware-hook chain.
|
|
400
486
|
* 2. `lower(plan)` — abstract. Each family produces its `*ExecutionPlan`
|
|
401
487
|
* (SQL via `lowerSqlPlan`, Mongo via `adapter.lower`).
|
|
402
|
-
* 3. `
|
|
403
|
-
*
|
|
404
|
-
*
|
|
488
|
+
* 3. `runBeforeExecuteChain(exec, this.middleware, this.ctx)` — concrete;
|
|
489
|
+
* runs every middleware's `beforeExecute` hook after lowering but
|
|
490
|
+
* before the row source is opened. Family runtimes that need a
|
|
491
|
+
* params mutator visible to a downstream encode step (SQL) override
|
|
492
|
+
* `execute` and call this helper themselves at the equivalent
|
|
493
|
+
* pre-encode point.
|
|
494
|
+
* 4. `runWithMiddleware(exec, this.middleware, this.ctx,
|
|
495
|
+
* () => runDriver(exec))` — concrete; runs the intercept chain,
|
|
496
|
+
* drives the row source, fires `onRow` / `afterExecute`. Does
|
|
497
|
+
* **not** fire `beforeExecute` — see step 3.
|
|
405
498
|
*
|
|
406
499
|
* Concrete subclasses must implement `lower`, `runDriver`, and `close`.
|
|
407
500
|
*
|
|
@@ -456,5 +549,5 @@ declare abstract class RuntimeCore<TPlan extends QueryPlan, TExec extends Execut
|
|
|
456
549
|
}, options?: RuntimeExecuteOptions): AsyncIterableResult<Row>;
|
|
457
550
|
}
|
|
458
551
|
//#endregion
|
|
459
|
-
export { type AfterExecuteResult, AsyncIterableResult, type ExecutionPlan, type InterceptResult, type ParamRefMutator, type QueryPlan, RUNTIME_ABORTED, type ResultType, type RuntimeAbortedPhase, RuntimeCore, type RuntimeCoreOptions, type RuntimeErrorEnvelope, type RuntimeExecuteOptions, type RuntimeExecutor, type RuntimeLog, type RuntimeMiddleware, type RuntimeMiddlewareContext, checkAborted, checkMiddlewareCompatibility, isRuntimeError, raceAgainstAbort, runWithMiddleware, runtimeAborted, runtimeError };
|
|
552
|
+
export { type AfterExecuteResult, AsyncIterableResult, type ExecutionPlan, type InterceptResult, type ParamRefMutator, type QueryPlan, RUNTIME_ABORTED, type ResultType, type RuntimeAbortedPhase, RuntimeCore, type RuntimeCoreOptions, type RuntimeErrorEnvelope, type RuntimeExecuteOptions, type RuntimeExecutor, type RuntimeLog, type RuntimeMiddleware, type RuntimeMiddlewareContext, checkAborted, checkMiddlewareCompatibility, isRuntimeError, raceAgainstAbort, runBeforeExecuteChain, runWithMiddleware, runtimeAborted, runtimeError };
|
|
460
553
|
//# sourceMappingURL=runtime.d.mts.map
|
package/dist/runtime.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/execution/async-iterable-result.ts","../src/execution/query-plan.ts","../src/execution/runtime-
|
|
1
|
+
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/execution/async-iterable-result.ts","../src/execution/query-plan.ts","../src/execution/runtime-middleware.ts","../src/execution/before-execute-chain.ts","../src/execution/runtime-error.ts","../src/execution/race-against-abort.ts","../src/execution/run-with-middleware.ts","../src/execution/runtime-core.ts"],"mappings":"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"}
|
package/dist/runtime.mjs
CHANGED
|
@@ -177,9 +177,69 @@ async function raceAgainstAbort(work, signal, phase) {
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
//#endregion
|
|
180
|
+
//#region src/execution/before-execute-chain.ts
|
|
181
|
+
/**
|
|
182
|
+
* Runs every middleware's `beforeExecute` hook in registration order,
|
|
183
|
+
* threading through the (optional) family-specific `paramsMutator`.
|
|
184
|
+
*
|
|
185
|
+
* Why this lives outside {@link runWithMiddleware}: middleware that
|
|
186
|
+
* mutates parameter values (e.g. cipherstash's bulk-encrypt SDK
|
|
187
|
+
* round-trip) must run *before* the family runtime encodes those
|
|
188
|
+
* parameters to driver wire format. Family runtimes call
|
|
189
|
+
* `runBeforeExecuteChain` between the AST → plan lowering step and
|
|
190
|
+
* the parameter encode step; the encode then observes the mutator's
|
|
191
|
+
* `currentParams()` view. `runWithMiddleware` retains the rest of
|
|
192
|
+
* the lifecycle (`intercept`, driver/row source loop, `onRow`,
|
|
193
|
+
* `afterExecute`) but no longer fires `beforeExecute` itself.
|
|
194
|
+
*
|
|
195
|
+
* Lifecycle within this helper:
|
|
196
|
+
*
|
|
197
|
+
* 1. For each middleware in registration order, if `beforeExecute`
|
|
198
|
+
* is implemented:
|
|
199
|
+
* - `checkAborted(ctx, 'beforeExecute')` short-circuits if the
|
|
200
|
+
* caller already aborted at entry.
|
|
201
|
+
* - The hook is invoked with `(plan, ctx, paramsMutator)`. A
|
|
202
|
+
* middleware body that ignores the mutator stays compatible —
|
|
203
|
+
* JavaScript allows extra positional arguments.
|
|
204
|
+
* - If the hook returns a Promise, it is raced against
|
|
205
|
+
* `ctx.signal` via {@link raceAgainstAbort} so cooperative
|
|
206
|
+
* cancellation surfaces a `RUNTIME.ABORTED { phase:
|
|
207
|
+
* 'beforeExecute' }` envelope even when the body itself
|
|
208
|
+
* ignores the signal.
|
|
209
|
+
*
|
|
210
|
+
* Error propagation: any error thrown by a `beforeExecute` body
|
|
211
|
+
* (or surfaced by the abort race) propagates out of this helper
|
|
212
|
+
* unchanged. The family runtime is responsible for converting it
|
|
213
|
+
* into the appropriate `afterExecute(completed: false)` notification
|
|
214
|
+
* once `runWithMiddleware` runs.
|
|
215
|
+
*
|
|
216
|
+
* Relationship to {@link runWithMiddleware}: the framework's
|
|
217
|
+
* `RuntimeCore.execute` template calls this helper between
|
|
218
|
+
* `lower(plan)` and `runWithMiddleware(...)`. Family runtimes that
|
|
219
|
+
* override `execute` (e.g. SQL, which inlines lower + encode for
|
|
220
|
+
* direct mutator threading) call this helper themselves at the
|
|
221
|
+
* equivalent point — between the family's AST → draft-plan
|
|
222
|
+
* lowering and the parameter-encode step.
|
|
223
|
+
*
|
|
224
|
+
* Intercept ordering: this helper fires unconditionally before
|
|
225
|
+
* `runWithMiddleware`. `intercept` (inside `runWithMiddleware`)
|
|
226
|
+
* therefore observes the post-`beforeExecute` plan — mutator
|
|
227
|
+
* mutations are visible in the params interceptors see. The
|
|
228
|
+
* trade-off is documented on `RuntimeMiddleware.intercept`.
|
|
229
|
+
*/
|
|
230
|
+
async function runBeforeExecuteChain(plan, middleware, ctx, paramsMutator) {
|
|
231
|
+
for (const mw of middleware) {
|
|
232
|
+
if (!mw.beforeExecute) continue;
|
|
233
|
+
checkAborted(ctx, "beforeExecute");
|
|
234
|
+
const work = mw.beforeExecute(plan, ctx, paramsMutator);
|
|
235
|
+
if (work !== void 0) await raceAgainstAbort(Promise.resolve(work), ctx.signal, "beforeExecute");
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
//#endregion
|
|
180
239
|
//#region src/execution/run-with-middleware.ts
|
|
181
240
|
/**
|
|
182
|
-
* Drives a single execution of `runDriver()` through the middleware
|
|
241
|
+
* Drives a single execution of `runDriver()` through the middleware
|
|
242
|
+
* lifecycle's intercept + row-source + termination phases.
|
|
183
243
|
*
|
|
184
244
|
* Lifecycle, in order:
|
|
185
245
|
* 1. For each middleware in registration order: `intercept(exec, ctx)`. The
|
|
@@ -189,31 +249,38 @@ async function raceAgainstAbort(work, signal, phase) {
|
|
|
189
249
|
* the intercepted rows, and proceeds with `source: 'middleware'`. On
|
|
190
250
|
* all-passthrough (every `intercept` returns `undefined` or is omitted),
|
|
191
251
|
* `source: 'driver'` is used and the row source is `runDriver()`.
|
|
192
|
-
* 2.
|
|
193
|
-
* `beforeExecute(exec, ctx)`. Skipped on the intercepted hit path —
|
|
194
|
-
* `beforeExecute` semantically means "about to hit the driver".
|
|
195
|
-
* 3. Iterate the row source. On the driver path, for each row, for each
|
|
252
|
+
* 2. Iterate the row source. On the driver path, for each row, for each
|
|
196
253
|
* middleware in registration order: `onRow(row, exec, ctx)`; then yield
|
|
197
254
|
* the row. On the intercepted hit path, `onRow` is skipped — intercepted
|
|
198
255
|
* rows did not originate from a driver row stream — but rows are still
|
|
199
256
|
* yielded to the consumer in order.
|
|
200
|
-
*
|
|
257
|
+
* 3. On successful completion: for each middleware in registration order:
|
|
201
258
|
* `afterExecute(exec, { rowCount, latencyMs, completed: true, source },
|
|
202
259
|
* ctx)`.
|
|
203
|
-
*
|
|
260
|
+
* 4. On any error thrown during steps 1–2: for each middleware in
|
|
204
261
|
* registration order: `afterExecute(exec, { rowCount, latencyMs,
|
|
205
262
|
* completed: false, source }, ctx)`. Errors thrown by `afterExecute`
|
|
206
263
|
* during the error path are swallowed so they do not mask the original
|
|
207
264
|
* error. The original error is then rethrown.
|
|
208
265
|
*
|
|
266
|
+
* `beforeExecute` is **not** fired here — see
|
|
267
|
+
* {@link runBeforeExecuteChain} in `before-execute-chain.ts`. Family
|
|
268
|
+
* runtimes call that helper between the AST → plan lowering step and
|
|
269
|
+
* the parameter encode step so middleware that mutates ParamRef
|
|
270
|
+
* values (e.g. cipherstash bulk-encrypt) can have its mutations
|
|
271
|
+
* visible to encode. `runWithMiddleware` operates on the fully-
|
|
272
|
+
* encoded plan; interceptors therefore observe a fully-mutated,
|
|
273
|
+
* encoded plan.
|
|
274
|
+
*
|
|
209
275
|
* The `source` field on `AfterExecuteResult` lets observers (telemetry,
|
|
210
276
|
* lints, budgets) distinguish driver-served from middleware-served
|
|
211
277
|
* executions without needing their own out-of-band signal.
|
|
212
278
|
*
|
|
213
|
-
* This helper is the single canonical implementation of the
|
|
214
|
-
*
|
|
279
|
+
* This helper is the single canonical implementation of the
|
|
280
|
+
* intercept-and-row-source loop; family runtimes should not
|
|
281
|
+
* reimplement it.
|
|
215
282
|
*/
|
|
216
|
-
function runWithMiddleware(exec, middleware, ctx, runDriver
|
|
283
|
+
function runWithMiddleware(exec, middleware, ctx, runDriver) {
|
|
217
284
|
const iterator = async function* () {
|
|
218
285
|
const startedAt = Date.now();
|
|
219
286
|
let rowCount = 0;
|
|
@@ -236,14 +303,7 @@ function runWithMiddleware(exec, middleware, ctx, runDriver, paramsMutator) {
|
|
|
236
303
|
rowSource = result.rows;
|
|
237
304
|
break;
|
|
238
305
|
}
|
|
239
|
-
if (source === "driver")
|
|
240
|
-
for (const mw of middleware) if (mw.beforeExecute) {
|
|
241
|
-
checkAborted(ctx, "beforeExecute");
|
|
242
|
-
const work = mw.beforeExecute(exec, ctx, paramsMutator);
|
|
243
|
-
if (work !== void 0) await raceAgainstAbort(Promise.resolve(work), ctx.signal, "beforeExecute");
|
|
244
|
-
}
|
|
245
|
-
rowSource = runDriver();
|
|
246
|
-
}
|
|
306
|
+
if (source === "driver") rowSource = runDriver();
|
|
247
307
|
for await (const row of rowSource) {
|
|
248
308
|
if (source === "driver") {
|
|
249
309
|
for (const mw of middleware) if (mw.onRow) await mw.onRow(row, exec, ctx);
|
|
@@ -285,9 +345,16 @@ function runWithMiddleware(exec, middleware, ctx, runDriver, paramsMutator) {
|
|
|
285
345
|
* this to run its `beforeCompile` middleware-hook chain.
|
|
286
346
|
* 2. `lower(plan)` — abstract. Each family produces its `*ExecutionPlan`
|
|
287
347
|
* (SQL via `lowerSqlPlan`, Mongo via `adapter.lower`).
|
|
288
|
-
* 3. `
|
|
289
|
-
*
|
|
290
|
-
*
|
|
348
|
+
* 3. `runBeforeExecuteChain(exec, this.middleware, this.ctx)` — concrete;
|
|
349
|
+
* runs every middleware's `beforeExecute` hook after lowering but
|
|
350
|
+
* before the row source is opened. Family runtimes that need a
|
|
351
|
+
* params mutator visible to a downstream encode step (SQL) override
|
|
352
|
+
* `execute` and call this helper themselves at the equivalent
|
|
353
|
+
* pre-encode point.
|
|
354
|
+
* 4. `runWithMiddleware(exec, this.middleware, this.ctx,
|
|
355
|
+
* () => runDriver(exec))` — concrete; runs the intercept chain,
|
|
356
|
+
* drives the row source, fires `onRow` / `afterExecute`. Does
|
|
357
|
+
* **not** fire `beforeExecute` — see step 3.
|
|
291
358
|
*
|
|
292
359
|
* Concrete subclasses must implement `lower`, `runDriver`, and `close`.
|
|
293
360
|
*
|
|
@@ -324,6 +391,7 @@ var RuntimeCore = class {
|
|
|
324
391
|
checkAborted(codecCtx, "stream");
|
|
325
392
|
const compiled = await self.runBeforeCompile(plan);
|
|
326
393
|
const exec = await self.lower(compiled, codecCtx);
|
|
394
|
+
await runBeforeExecuteChain(exec, self.middleware, self.ctx);
|
|
327
395
|
yield* runWithMiddleware(exec, self.middleware, self.ctx, () => self.runDriver(exec));
|
|
328
396
|
}
|
|
329
397
|
return new AsyncIterableResult(generator());
|
|
@@ -348,6 +416,6 @@ function checkMiddlewareCompatibility(middleware, runtimeFamilyId, runtimeTarget
|
|
|
348
416
|
});
|
|
349
417
|
}
|
|
350
418
|
//#endregion
|
|
351
|
-
export { AsyncIterableResult, RUNTIME_ABORTED, RuntimeCore, checkAborted, checkMiddlewareCompatibility, isRuntimeError, raceAgainstAbort, runWithMiddleware, runtimeAborted, runtimeError };
|
|
419
|
+
export { AsyncIterableResult, RUNTIME_ABORTED, RuntimeCore, checkAborted, checkMiddlewareCompatibility, isRuntimeError, raceAgainstAbort, runBeforeExecuteChain, runWithMiddleware, runtimeAborted, runtimeError };
|
|
352
420
|
|
|
353
421
|
//# sourceMappingURL=runtime.mjs.map
|