@fitzzero/quickdraw-core 5.1.0 → 5.1.2

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 (107) hide show
  1. package/README.md +533 -180
  2. package/dist/{admin-DKwkIh5i.d.ts → admin-DWWrT1h6.d.ts} +2 -2
  3. package/dist/{adminSchemas-2DUA_hZ8.d.ts → adminSchemas-D4bFKsrb.d.ts} +6 -4
  4. package/dist/{auth-BhWqdyb-.d.ts → auth-DXiSJZaf.d.ts} +42 -16
  5. package/dist/{caller-CXTFswBO.d.ts → caller-BT-Mv4bD.d.ts} +117 -22
  6. package/dist/{chunk-RT6OILOI.js → chunk-4D2DOGAW.js} +2 -14
  7. package/dist/chunk-4D2DOGAW.js.map +1 -0
  8. package/dist/chunk-5CGO426C.js +15 -0
  9. package/dist/chunk-5CGO426C.js.map +1 -0
  10. package/dist/{chunk-A6DJBGOG.js → chunk-6K5BY47X.js} +4594 -3481
  11. package/dist/chunk-6K5BY47X.js.map +1 -0
  12. package/dist/{chunk-VJTFXHOK.js → chunk-753VJIUP.js} +13 -15
  13. package/dist/chunk-753VJIUP.js.map +1 -0
  14. package/dist/{chunk-JZBCLNDU.js → chunk-7QCUX4TK.js} +4 -4
  15. package/dist/chunk-7QCUX4TK.js.map +1 -0
  16. package/dist/chunk-AK23XSWD.js +16 -0
  17. package/dist/chunk-AK23XSWD.js.map +1 -0
  18. package/dist/{chunk-3674EIRT.js → chunk-AONAFOYU.js} +14 -5
  19. package/dist/{chunk-3674EIRT.js.map → chunk-AONAFOYU.js.map} +1 -1
  20. package/dist/chunk-DKE6QO26.js +136 -0
  21. package/dist/chunk-DKE6QO26.js.map +1 -0
  22. package/dist/{chunk-H23KEFBA.js → chunk-DUBU3BB3.js} +30 -1
  23. package/dist/chunk-DUBU3BB3.js.map +1 -0
  24. package/dist/{chunk-CDKG4TFA.js → chunk-GKH3LJ7N.js} +1 -1
  25. package/dist/chunk-GKH3LJ7N.js.map +1 -0
  26. package/dist/{chunk-KNDDCVQJ.js → chunk-GSIPUNJL.js} +49 -9
  27. package/dist/chunk-GSIPUNJL.js.map +1 -0
  28. package/dist/{chunk-DD4SKCNO.js → chunk-LCC7HNFP.js} +12 -1
  29. package/dist/chunk-LCC7HNFP.js.map +1 -0
  30. package/dist/{chunk-2PWMUVC7.js → chunk-MBH6IDSM.js} +480 -12
  31. package/dist/chunk-MBH6IDSM.js.map +1 -0
  32. package/dist/{chunk-2UELNHDD.js → chunk-NMXYENH4.js} +10 -10
  33. package/dist/{chunk-2UELNHDD.js.map → chunk-NMXYENH4.js.map} +1 -1
  34. package/dist/chunk-NO4M6PO5.js +101 -0
  35. package/dist/chunk-NO4M6PO5.js.map +1 -0
  36. package/dist/{chunk-TBMKJ26R.js → chunk-NW6U45HX.js} +3 -1
  37. package/dist/chunk-NW6U45HX.js.map +1 -0
  38. package/dist/{chunk-REX5YPHX.js → chunk-RJ5I2VO3.js} +74 -19
  39. package/dist/chunk-RJ5I2VO3.js.map +1 -0
  40. package/dist/{chunk-QEKVYG5F.js → chunk-RL4VKLBX.js} +1 -1
  41. package/dist/{chunk-QEKVYG5F.js.map → chunk-RL4VKLBX.js.map} +1 -1
  42. package/dist/chunk-XH2IZVLT.js +62 -0
  43. package/dist/chunk-XH2IZVLT.js.map +1 -0
  44. package/dist/{chunk-4DIQHASK.js → chunk-Z5ILULF2.js} +26 -7
  45. package/dist/chunk-Z5ILULF2.js.map +1 -0
  46. package/dist/cli/quickdraw-docs.js +5 -3
  47. package/dist/cli/quickdraw-docs.js.map +1 -1
  48. package/dist/client/index.d.ts +30 -18
  49. package/dist/client/index.js +8 -6
  50. package/dist/client/index.js.map +1 -1
  51. package/dist/{clientTypes-Bc-G8n-U.d.ts → clientTypes-hWcPUVS9.d.ts} +3 -3
  52. package/dist/{connection-Cr1BU07W.d.ts → connection-CgijdGpT.d.ts} +8 -4
  53. package/dist/{createServer-CP9eDHZZ.d.ts → createServer-Cp-Wk500.d.ts} +36 -14
  54. package/dist/{createTestApp-UKVGEmOf.d.ts → createTestApp-BB_PkqQ7.d.ts} +16 -10
  55. package/dist/{envelope-Cp3YcVxC.d.ts → envelope-DzWyIXjj.d.ts} +18 -4
  56. package/dist/{http-Djj2Inuu.d.ts → http-DotQ5bj8.d.ts} +68 -17
  57. package/dist/index.d.ts +7 -7
  58. package/dist/index.js +37 -13
  59. package/dist/index.js.map +1 -1
  60. package/dist/{infer-Teo1xpsd.d.ts → infer-BmoZsL9a.d.ts} +43 -10
  61. package/dist/logger-Yz93KzdV.d.ts +30 -0
  62. package/dist/{metrics-BdBu5o8G.d.ts → metrics-DW80Exve.d.ts} +2 -2
  63. package/dist/origins-kvpxnVcW.d.ts +8 -0
  64. package/dist/prisma/index.d.ts +5 -5
  65. package/dist/prisma/index.js +130 -67
  66. package/dist/prisma/index.js.map +1 -1
  67. package/dist/{rateLimit-ZMIZJUZF.js → rateLimit-5RKBFLUR.js} +2 -2
  68. package/dist/server/auth/index.d.ts +82 -33
  69. package/dist/server/auth/index.js +273 -268
  70. package/dist/server/auth/index.js.map +1 -1
  71. package/dist/server/express/index.d.ts +9 -2
  72. package/dist/server/express/index.js +1 -1
  73. package/dist/server/index.d.ts +147 -67
  74. package/dist/server/index.js +520 -381
  75. package/dist/server/index.js.map +1 -1
  76. package/dist/server/mcp/index.d.ts +63 -17
  77. package/dist/server/mcp/index.js +256 -54
  78. package/dist/server/mcp/index.js.map +1 -1
  79. package/dist/server/otel.d.ts +3 -3
  80. package/dist/{sharing-DVa8W-yR.d.ts → sharing-UDLn1049.d.ts} +3 -3
  81. package/dist/testing/client.d.ts +14 -14
  82. package/dist/testing/client.js +9 -7
  83. package/dist/testing/client.js.map +1 -1
  84. package/dist/testing/index.d.ts +12 -12
  85. package/dist/testing/index.js +21 -12
  86. package/dist/testing/index.js.map +1 -1
  87. package/dist/testing/mock.d.ts +5 -5
  88. package/dist/testing/mock.js +8 -6
  89. package/dist/{types-Cu0vmx7c.d.ts → types-CYliTP65.d.ts} +1 -1
  90. package/dist/utils/index.d.ts +1 -1
  91. package/package.json +1 -1
  92. package/dist/chunk-2PWMUVC7.js.map +0 -1
  93. package/dist/chunk-4DIQHASK.js.map +0 -1
  94. package/dist/chunk-A6DJBGOG.js.map +0 -1
  95. package/dist/chunk-CDKG4TFA.js.map +0 -1
  96. package/dist/chunk-DD4SKCNO.js.map +0 -1
  97. package/dist/chunk-H23KEFBA.js.map +0 -1
  98. package/dist/chunk-JZBCLNDU.js.map +0 -1
  99. package/dist/chunk-KNDDCVQJ.js.map +0 -1
  100. package/dist/chunk-REX5YPHX.js.map +0 -1
  101. package/dist/chunk-RT6OILOI.js.map +0 -1
  102. package/dist/chunk-TBMKJ26R.js.map +0 -1
  103. package/dist/chunk-VJTFXHOK.js.map +0 -1
  104. package/dist/chunk-YSWH776Y.js +0 -13
  105. package/dist/chunk-YSWH776Y.js.map +0 -1
  106. package/dist/logger-BY28acW-.d.ts +0 -16
  107. /package/dist/{rateLimit-ZMIZJUZF.js.map → rateLimit-5RKBFLUR.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/devWarnings.ts","../src/server/rev.ts","../src/server/uow/unitOfWork.ts","../src/server/uow/flush.ts","../src/server/uow/flushSink.ts","../src/server/uow/records.ts","../src/server/uow/statementChecks.ts"],"sourcesContent":["// Development warnings (RFC 0003 section 13): the slow or untracked patterns\n// a lint rule cannot see, because they only show while the code runs,\n// reported as they happen. Every warning has one format, names the call it\n// happened in, and is logged once per kind, service, method and subject:\n//\n// [quickdraw:n-plus-one] taskService.board: task.findUnique by id ran 10 times in one call...\n//\n// | Kind | Raised when | Subject |\n// |----------------------|--------------------------------------------------------------------|--------------------------|\n// | `n-plus-one` | a call ran 10 statements of one shape (model, operation, `where` | none |\n// | | keys), outside an array-form `$transaction` | |\n// | `unbounded-read` | a call ran `findMany` with neither `take` nor ids to read (`id`, | none |\n// | | `{ in }`, `{ equals }`) | |\n// | `oversized-response` | a reply was larger than `maxResponseBytes` | none |\n// | `nested-write` | a write's `data` wrote a related row, which is not tracked | model, field, operation |\n// | `ambient-write` | a tracked write ran outside any unit of work | model |\n// | `batch-read` | a write in an array-form `$transaction` read its rows outside it | model, operation |\n// | `batch-create-many` | a `createMany` in an array-form `$transaction` could not be traced | model |\n// | `repeated-call` | one connection called a method with the same input more than 10 | connection |\n// | | times within a second, or was refused `RATE_LIMITED` more than 30 | (`refused <connection>`) |\n// | | times within a minute: a client in a loop (`createLoopWatch`) | |\n// | `tiered-field-in- | a method's own output schema declares a field the contract tiers, | the field |\n// | output` | at any depth, which such an output never strips | |\n// | | (`emit/tieredOutputs.ts`); raised when a dispatcher is made, so a | |\n// | | strict test app fails to start; for an output without JSON Schema, | |\n// | | raised by the first reply that carries the field | |\n// | `resolver-without- | a service with a model has a `resolver` policy (alone or in | none (once per service) |\n// | reads` | `anyOf`) that declares no `reads`, so no tracked write re-checks | |\n// | | it (`access/resolverReads.ts`); raised when a dispatcher is made, | |\n// | | so a strict test app fails to start | |\n// | `untracked-access- | a model an access policy, a membership table or a `via` junction | the model |\n// | model` | depends on has no `id` the write tracker can key its rows by, so | |\n// | | no write to it revokes (`access/trackedModels.ts`); checked by | |\n// | | `createServer` at start, logged as an error in every environment, | |\n// | | and a strict test app fails to start | |\n// | `shared-principal` | the handler of a `share: \"all\"` run (an app's, not a kit's) read | the member |\n// | | `ctx.principal`, `ctx.services` or `ctx.mcp`: the run has the | (`principal`, `services`,|\n// | | first caller's, and every caller gets its result | `mcp`) |\n// | `channel-without- | a channel's contract declares no `requires` and its service no | the channel |\n// | requires` | `access`, so every signed-in user may send it | |\n// | | (`realtime/channelWarnings.ts`); raised when a dispatcher is made, | |\n// | | so a strict test app fails to start | |\n//\n// `nested-write`, `ambient-write`, `batch-read` and `batch-create-many` are\n// the write tracker's (`uow/unitOfWork.ts`), raised exactly where they were\n// before; they gained the format and the call. Only an app's\n// own statements are checked for the first two: the framework's reads through\n// the storage adapter, the tracker's own reads and the kits' handlers run\n// `quietly`, while the app's callbacks a kit calls (`prepare`, `onChange`,\n// `resolveUser`, a search strategy) run `checked`. A query by an `id` list\n// (`{ id: { in: ids } }`) is one query per list, not per row, so it never\n// counts toward an N+1. Warnings are off when NODE_ENV is \"production\". In a test app\n// made with `strictWarnings` (under vitest or jest) every warning raised in\n// one of its method calls throws a `DevWarningError` where it is raised\n// instead, so the test fails; warnings outside its calls (an ambient write\n// while seeding, say) are logged as usual.\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createHash } from \"node:crypto\";\nimport { consoleLogger, type Logger } from \"../contract/logger\";\nimport type { CallOutcome } from \"./pipeline/metrics\";\n\n/** What a development warning is about. */\nexport type DevWarningKind =\n | \"n-plus-one\"\n | \"unbounded-read\"\n | \"oversized-response\"\n | \"nested-write\"\n | \"ambient-write\"\n | \"batch-read\"\n | \"batch-create-many\"\n | \"repeated-call\"\n | \"tiered-field-in-output\"\n | \"resolver-without-reads\"\n | \"untracked-access-model\"\n | \"shared-principal\"\n | \"channel-without-requires\";\n\n/** One development warning. */\nexport interface DevWarning {\n readonly kind: DevWarningKind;\n /** The service whose method call raised it; absent outside a call (a job, a script). */\n readonly service?: string;\n readonly method?: string;\n /**\n * What the warning is about within its call, for the once-only rule: the\n * model of an ambient write, the model, field and operation of a nested\n * write, the connection of a repeated call, the `ctx` member a shared run\n * read. Empty for the kinds that are once per call site.\n */\n readonly subject?: string;\n /** What happened and what to do instead. */\n readonly message: string;\n /** Logged with the warning. */\n readonly meta?: Readonly<Record<string, unknown>>;\n}\n\n/** The statements of one shape a call may run before it is an N+1. */\nexport const N_PLUS_ONE_STATEMENTS = 10;\n\n/** The text a warning is logged and thrown with: `[quickdraw:<kind>] <service>.<method>: <message>`. */\nexport function formatDevWarning(warning: DevWarning): string {\n const where =\n warning.service === undefined || warning.method === undefined\n ? \"\"\n : ` ${warning.service}.${warning.method}:`;\n return `[quickdraw:${warning.kind}]${where} ${warning.message}`;\n}\n\n/** A development warning, thrown instead of logged by a test app made with `strictWarnings`. */\nexport class DevWarningError extends Error {\n override readonly name = \"DevWarningError\";\n readonly warning: DevWarning;\n\n constructor(warning: DevWarning) {\n super(formatDevWarning(warning));\n this.warning = warning;\n }\n}\n\n/**\n * Where development warnings go: one per dispatcher, which the write tracker\n * reports a call's warnings to as well.\n */\nexport interface DevWarnings {\n /** False when warnings are off: NODE_ENV is \"production\" and nothing made them strict. */\n readonly enabled: boolean;\n /** True when every warning throws: a strict test app's dispatcher. */\n readonly strict: boolean;\n /** Logs `warning` the first time its kind, service, method and subject come up; strict, throws it every time. */\n warn(warning: DevWarning): void;\n}\n\n/** Options of {@link createDevWarnings}. */\nexport interface DevWarningsOptions {\n readonly logger?: Logger;\n /** Default: on unless NODE_ENV is \"production\". */\n readonly development?: boolean;\n /** Throw every warning as a `DevWarningError` instead of logging it. */\n readonly strict?: boolean;\n}\n\nfunction onceKey(warning: DevWarning): string {\n return [warning.kind, warning.service ?? \"\", warning.method ?? \"\", warning.subject ?? \"\"].join(\n \"\\u0000\",\n );\n}\n\n/** Creates the development warnings of one dispatcher (or of a write tracker before one attaches). */\nexport function createDevWarnings(options: DevWarningsOptions = {}): DevWarnings {\n const logger = options.logger ?? consoleLogger;\n const strict = options.strict === true;\n const enabled = strict || (options.development ?? process.env.NODE_ENV !== \"production\");\n const warned = new Set<string>();\n return Object.freeze({\n enabled,\n strict,\n warn(warning: DevWarning): void {\n if (strict) {\n throw new DevWarningError(warning);\n }\n const key = onceKey(warning);\n if (!enabled || warned.has(key)) {\n return;\n }\n warned.add(key);\n logger.warn(formatDevWarning(warning), {\n category: \"quickdraw.dev\",\n warning: warning.kind,\n ...(warning.service === undefined ? {} : { service: warning.service }),\n ...(warning.method === undefined ? {} : { method: warning.method }),\n ...warning.meta,\n });\n },\n });\n}\n\n/**\n * The option `createTestApp({ strictWarnings })` sets on the server options\n * it passes on, so the dispatcher makes its warnings strict. A symbol, so it\n * survives the options being copied and is no option of the public types.\n */\nexport const STRICT_WARNINGS: unique symbol = Symbol(\"quickdraw.strictWarnings\");\n\n/** Whether `options` carry {@link STRICT_WARNINGS}. */\nexport function strictWarningsOf(options: object): boolean {\n return Reflect.get(options, STRICT_WARNINGS) === true;\n}\n\nconst QUIET = new AsyncLocalStorage<boolean>();\n\n/**\n * Runs `fn` with the development checks of statements off, awaiting its\n * result inside (a Prisma promise runs where it is awaited): the framework's\n * own reads and the kits' handlers, which an app cannot change.\n */\nexport async function quietly<T>(fn: () => T | PromiseLike<T>): Promise<T> {\n return await QUIET.run(true, async () => await fn());\n}\n\n/**\n * Runs `fn` with the development checks of statements on again, inside a\n * kit's quiet handler: the app's own callbacks a kit calls (`prepare`,\n * `onChange`, `resolveUser`, a search strategy) are the app's code, checked\n * like a handler's.\n */\nexport async function checked<T>(fn: () => T | PromiseLike<T>): Promise<T> {\n return await QUIET.run(false, async () => await fn());\n}\n\n/** True inside {@link quietly}, and not inside a {@link checked} within it. */\nexport function isQuiet(): boolean {\n return QUIET.getStore() === true;\n}\n\n// Loop warnings (`repeated-call`). Without them, a client re-issuing one\n// call (a mutation fired from an effect that its own result re-runs, a\n// refetch that triggers itself) is seen only as `RATE_LIMITED` once the\n// socket's 600-per-minute limiter trips, which says nothing about why. The\n// dispatcher's loop watch says it instead:\n//\n// - one connection (a socket, an MCP session) calls the same method with an\n// identical input more than 10 times within a second: once per\n// connection, service and method;\n// - one connection is refused `RATE_LIMITED` more than 30 times within a\n// minute, by the socket rate limiter or by a full query queue: once per\n// connection, at warn where a refusal on its own logs at debug.\n//\n// A test app made with `strictWarnings` throws them from the call that\n// crossed the line, once its reply was sent; a refusal outside any call is\n// logged even there. Calls without a connection (in-process, HTTP) are not\n// counted. Memory is bounded: the 10,000 most recently seen keys are kept.\n\n/** Identical calls one connection may make within {@link REPEATED_CALL_WINDOW_MS}. */\nexport const REPEATED_CALL_LIMIT = 10;\nexport const REPEATED_CALL_WINDOW_MS = 1_000;\n\n/** `RATE_LIMITED` refusals one connection may get within {@link REFUSAL_WINDOW_MS}. */\nexport const REFUSAL_LIMIT = 30;\nexport const REFUSAL_WINDOW_MS = 60_000;\n\nconst MAX_KEYS = 10_000;\n\n/** Inputs longer than this are keyed by their hash. */\nconst MAX_INPUT_KEY = 256;\n\n/** What a finished call is counted by. */\nexport interface CountedCall {\n readonly service: string;\n readonly method: string;\n readonly input: unknown;\n readonly connectionId?: string;\n}\n\n/** Counts each connection's calls and refusals, and warns when they look like a loop. */\nexport interface LoopWatch {\n /**\n * Counts one finished call and how it ended. Throws the warning in a test\n * app made with `strictWarnings`; call it once the reply was sent.\n */\n call(call: CountedCall, outcome: CallOutcome): void;\n /** Counts an event the socket rate limiter refused; never throws. */\n refused(connectionId: string, event: string): void;\n}\n\n/**\n * Counts events per key: returns how many fell within `windowMs` up to now,\n * once that is more than `limit`, else `undefined`. Keeps at most `limit + 1`\n * times per key and drops the least recently seen key past `MAX_KEYS`.\n */\nfunction createCounter(\n limit: number,\n windowMs: number,\n now: () => number,\n): (key: string) => number | undefined {\n const times = new Map<string, number[]>();\n return (key) => {\n const at = now();\n const recent = (times.get(key) ?? []).filter((time) => at - time < windowMs);\n recent.push(at);\n if (recent.length > limit + 1) {\n recent.shift();\n }\n times.delete(key);\n times.set(key, recent);\n if (times.size > MAX_KEYS) {\n const [oldest] = times.keys();\n times.delete(oldest ?? key);\n }\n return recent.length > limit ? recent.length : undefined;\n };\n}\n\n/** The input as a key: its JSON, hashed when long; `undefined` for an input JSON cannot write. */\nfunction inputKey(input: unknown): string | undefined {\n let text: string | undefined;\n try {\n text = JSON.stringify(input) ?? \"undefined\";\n } catch {\n return undefined;\n }\n return text.length <= MAX_INPUT_KEY ? text : createHash(\"sha1\").update(text).digest(\"base64url\");\n}\n\nconst OFF: LoopWatch = Object.freeze({\n call: () => undefined,\n refused: () => undefined,\n});\n\n/**\n * The loop watch of one dispatcher: it raises its `repeated-call` warnings\n * through `warnings`, and through a lenient copy logging to `logger` for\n * refusals outside any call.\n */\nexport function createLoopWatch(\n warnings: DevWarnings,\n logger: Logger,\n now: () => number = Date.now,\n): LoopWatch {\n if (!warnings.enabled) {\n return OFF;\n }\n const repeats = createCounter(REPEATED_CALL_LIMIT, REPEATED_CALL_WINDOW_MS, now);\n const refusals = createCounter(REFUSAL_LIMIT, REFUSAL_WINDOW_MS, now);\n const outside = warnings.strict ? createDevWarnings({ logger, development: true }) : warnings;\n const refusal = (sink: DevWarnings, connectionId: string, what: string): void => {\n const count = refusals(connectionId);\n if (count !== undefined) {\n sink.warn({\n kind: \"repeated-call\",\n subject: `refused ${connectionId}`,\n message:\n `connection ${connectionId} was refused RATE_LIMITED ${String(count)} times within a minute (the last: ${what}): ` +\n \"its client keeps calling while it is rate limited, as a loop does. The quickdraw client backs off on RATE_LIMITED; \" +\n \"find the call that repeats (a repeated-call warning names it) and stop the loop\",\n meta: { connectionId, refusals: count, windowMs: REFUSAL_WINDOW_MS },\n });\n }\n };\n return Object.freeze({\n call(call: CountedCall, outcome: CallOutcome): void {\n const { connectionId } = call;\n if (connectionId === undefined) {\n return;\n }\n if (outcome === \"RATE_LIMITED\") {\n refusal(warnings, connectionId, `${call.service}.${call.method}`);\n }\n const key = inputKey(call.input);\n const count =\n key === undefined\n ? undefined\n : repeats([connectionId, call.service, call.method, key].join(\"\\u0000\"));\n if (count === undefined) {\n return;\n }\n warnings.warn({\n kind: \"repeated-call\",\n service: call.service,\n method: call.method,\n subject: connectionId,\n message:\n `called ${String(count)} times within a second with the same input, on one connection (${connectionId}): ` +\n \"the client calls it in a loop, as a mutation fired from an effect or from render does, or a refetch that triggers itself. \" +\n \"Call it from an event handler, or guard the effect so it runs once per change\",\n meta: { connectionId, calls: count, windowMs: REPEATED_CALL_WINDOW_MS },\n });\n },\n refused(connectionId: string, event: string): void {\n refusal(outside, connectionId, event);\n },\n });\n}\n","// Revisions (RFC 0003 section 5.3, step 2): one per flush, per-process\n// monotonic, `max(Date.now() * 1000, last + 1)`: microseconds since the\n// epoch. A revision is taken before any row is read, so a payload is never\n// older than the revision it carries. Clients drop frames older than what\n// they hold, so two flushes in one millisecond must still get different\n// revisions, and a clock that steps back must not reuse one. In\n// microseconds a process takes a thousand revisions a millisecond and stays\n// on the clock, which `versionColumn` times are compared with (a time is its\n// milliseconds times 1,000: `emit/hub.ts`); revisions stay safe integers\n// (about 1.8e15, under 2^53).\n//\n// Behind a cluster adapter with a shared counter (`cluster/revisions.ts`),\n// flushes take their revisions from the counter instead, which keeps to\n// Valkey's clock in microseconds; the revisions it hands out are observed\n// here, so a revision this process takes later is never below one it\n// already sent.\n\nimport type { Revision } from \"../protocol/envelope\";\n\n/** Microseconds per millisecond: a revision is a time in microseconds. */\nexport const MICROS_PER_MS = 1000;\n\nlet last = 0;\n\n/** The clock as a revision: `Date.now()` in microseconds. */\nexport function clockRev(): Revision {\n return Date.now() * MICROS_PER_MS;\n}\n\n/** The next revision: the current time in microseconds, or one more than the last revision when that is later. */\nexport function nextRev(): Revision {\n last = Math.max(clockRev(), last + 1);\n return last;\n}\n\n/**\n * The revision a read made from now on is no older than, without taking a\n * new one: the last revision taken (one is taken when none was yet). Every\n * write whose flush took a revision up to it had committed before that\n * revision was taken, and any later flush takes a greater one. A read that\n * is not a flush (a subscription's rows) claims it rather than taking its\n * own, so reads do not push revisions ahead of the clock that\n * `versionColumn` times are compared with.\n */\nexport function currentRev(): Revision {\n return last === 0 ? nextRev() : last;\n}\n\n/** Records a revision taken elsewhere (the cluster's counter): later ones taken here are above it. */\nexport function observeRev(rev: Revision): void {\n last = Math.max(last, rev);\n}\n\n/**\n * The time a version column holds as a revision (microseconds since the\n * epoch: its milliseconds times 1,000), or `undefined` when it holds none. A\n * column holds a `Date`, a date string, or a number of milliseconds since\n * the epoch.\n */\nexport function versionTime(value: unknown): Revision | undefined {\n if (value instanceof Date) {\n const time = value.getTime();\n return Number.isNaN(time) ? undefined : time * MICROS_PER_MS;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value * MICROS_PER_MS;\n }\n if (typeof value === \"string\") {\n const time = Date.parse(value);\n return Number.isNaN(time) ? undefined : time * MICROS_PER_MS;\n }\n return undefined;\n}\n","// The tracked unit of work (RFC 0003 section 5.1). A write tracker holds the\n// writes of every unit of work in `AsyncLocalStorage` frames: a database\n// adapter (`trackPrisma` on `./prisma`) records each write into the frame\n// that is active where the write runs, and the dispatcher opens a unit per\n// handler run and flushes it after the response.\n//\n// Frames nest:\n//\n// - a unit's frame buffers the unit's writes until it flushes;\n// - a transaction's frame buffers its writes separately, and they join the\n// enclosing buffer only when the transaction commits; a rollback discards\n// them; an interactive transaction's frame also holds its transaction\n// client, so the adapter's own reads see the transaction's writes;\n// - a unit begun inside another open frame (an in-process call made from a\n// handler, `qd.run` inside a transaction) joins it: its writes go where\n// the enclosing frame's go, and its own flush does nothing; a detached\n// unit (`qd.run(fn, { detached: true })`, a handler's background work)\n// never joins: it starts a stack of its own and flushes on its own;\n// - `countStatements` frames only count.\n//\n// A write with no open buffer above it (a job that did not use `qd.run`, or\n// a handler's background work that outlived its unit's flush) is ambient: it\n// flushes on its own on the next tick, with a development warning.\n//\n// In development a method call's unit also checks the statements run in it\n// for N+1 shapes and unbounded reads (`statementChecks.ts`), and every\n// warning goes out in the shared format of `../devWarnings.ts`, naming the\n// call it happened in. A warning raised inside a method call goes to the\n// warnings of the dispatcher that runs the call (a strict test app's throw);\n// one raised elsewhere goes to the attached dispatcher's, never strictly.\n//\n// Dispatchers attach to the tracker as a stack: the last one attached\n// receives ambient writes and the warnings outside calls, and detaching it\n// (a server's `close()`) restores the one attached before.\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { randomUUID } from \"node:crypto\";\nimport { consoleLogger, errorText, type Logger } from \"../../contract/logger\";\nimport type { RunContext, RunOptions, TouchOptions } from \"../context\";\nimport { createDevWarnings, isQuiet, type DevWarning, type DevWarnings } from \"../devWarnings\";\nimport { flushWrites } from \"./flush\";\nimport { noFlushSink, type FlushSink } from \"./flushSink\";\nimport {\n createStatementChecks,\n type CallSite,\n type Statement,\n type StatementCheck,\n type StatementPlace,\n} from \"./statementChecks\";\nimport {\n ANY_FIELD,\n type UnitOfWork,\n type UnitOfWorkFactory,\n type UnitOfWorkScope,\n type WriteRecord,\n} from \"./types\";\n\n/** One level of the frame stack. Mutable flags close it once its unit flushed or its transaction settled. */\ninterface Frame {\n readonly parent: Frame | undefined;\n /** Where writes made here go; a frame without a buffer passes them up. */\n readonly buffer: WriteRecord[] | undefined;\n /** Writes in a unit's buffer are durable; a transaction's wait for its commit. */\n readonly durable: boolean;\n /** An interactive transaction's client, for the adapter's own reads. */\n tx: unknown;\n /** An array-form transaction: no client, and its operations cannot be rewritten. */\n readonly batch: boolean;\n /** Counts the statements issued in this frame and every frame inside it. */\n readonly count: ((statements: number) => void) | undefined;\n /** A method call's unit: the call warnings made inside it are about. */\n readonly call: CallSite | undefined;\n /** A method call's unit: its dispatcher's warnings, which those warnings go to. */\n readonly warnings: DevWarnings | undefined;\n /** A method call's unit in development: checks the statements run inside it. */\n readonly check: StatementCheck | undefined;\n open: boolean;\n}\n\n/** A warning the tracker raises; it adds the call it was raised in. */\nexport type TrackerWarning = Omit<DevWarning, \"service\" | \"method\">;\n\n/** An open transaction, from {@link WriteTracker.openTransaction}. */\nexport interface TrackedTransaction {\n /** Sets the interactive transaction's client, once the database has opened it. */\n setClient(tx: unknown): void;\n /** Runs `fn` inside the transaction's frame, awaiting its result there. */\n run<T>(fn: () => T | PromiseLike<T>): Promise<T>;\n /** The transaction committed: its writes join the enclosing buffer. */\n commit(): void;\n /** The transaction rolled back: its writes are dropped. */\n rollback(): void;\n}\n\n/** A statement count, from {@link WriteTracker.countStatements}. */\nexport interface StatementCount<T> {\n readonly value: T;\n readonly statements: number;\n}\n\n/** Options of {@link createWriteTracker}. */\nexport interface WriteTrackerOptions {\n /** Receives warnings until a dispatcher attaches its logger. Default: the console logger. */\n readonly logger?: Logger;\n /**\n * Raise development warnings: ambient, nested and batched writes, and the\n * checks of each method call's statements. Default: on unless `NODE_ENV`\n * is `\"production\"`.\n */\n readonly development?: boolean;\n}\n\n/**\n * Where a database adapter records writes, and the unit of work factory the\n * dispatcher opens units with. One tracker belongs to one tracked client.\n */\nexport interface WriteTracker {\n /** The units of work of handler runs and `qd.run` blocks: give it to the dispatcher. */\n readonly unitOfWork: UnitOfWorkFactory;\n /** Records writes where they ran: an open transaction, a unit of work, or the next tick's ambient flush. */\n record(writes: readonly WriteRecord[]): void;\n /** Records `ids` of `model` as changed, or as deleted with `removed`: `ctx.touch`. */\n touch(model: string, ids: readonly string[], options?: TouchOptions): void;\n /** Counts one statement in every open frame where it runs. */\n countStatement(): void;\n /** Opens a transaction frame inside the active one. */\n openTransaction(kind: \"interactive\" | \"batch\"): TrackedTransaction;\n /** The client of the open interactive transaction where this runs, or `undefined`. */\n transactionClient(): unknown;\n /** True inside an array-form transaction. */\n inBatch(): boolean;\n /** Runs `fn` and counts the statements it issued. */\n countStatements<T>(fn: () => T | PromiseLike<T>): Promise<StatementCount<T>>;\n /** Calls `listener` with each write once it is durable: in a unit of work, or flushing on its own. */\n onWrite(listener: (write: WriteRecord) => void): () => void;\n /**\n * Raises a development warning about the method call this runs in (none\n * outside a call): logged once, in the shared format, by the attached\n * dispatcher's warnings. Nothing outside development.\n */\n warn(warning: TrackerWarning): void;\n /**\n * Hands a statement the database client is about to run to the checks of\n * the method call it runs in (development only; nothing outside a call,\n * nor inside `quietly`).\n */\n observe(statement: Statement): void;\n /** The logger warnings go to: the attached dispatcher's, or the one given at creation. */\n readonly logger: Logger;\n}\n\n/** Where ambient writes flush and warnings outside a call go: the attached dispatcher's. */\ninterface Attachment {\n readonly sink: FlushSink;\n readonly logger: Logger;\n /** Never strict: warnings outside a method call only log. */\n readonly warnings: DevWarnings;\n}\n\ninterface TrackerState {\n readonly als: AsyncLocalStorage<Frame>;\n readonly listeners: Set<(write: WriteRecord) => void>;\n readonly development: boolean;\n /** Before any dispatcher attaches, and once every one detached. */\n readonly base: Attachment;\n /** The dispatchers attached, the current one last. */\n readonly attached: Attachment[];\n logger: Logger;\n warnings: DevWarnings;\n sink: FlushSink;\n ambient: WriteRecord[];\n /** Every statement counted since the tracker was created, wherever it ran. */\n issued: number;\n}\n\nconst ISSUED = new WeakMap<object, () => number>();\n\n/**\n * How many statements the tracked client of `unitOfWork` (a tracker's\n * `unitOfWork`, as `storage.unitOfWork` carries it) has counted since it was\n * created, in every async context: what `expectBudget` measures a test step\n * with. `undefined` for units of work no tracker made.\n */\nexport function statementsIssued(unitOfWork: object): number | undefined {\n return ISSUED.get(unitOfWork)?.();\n}\n\nfunction frameWhere(state: TrackerState, test: (frame: Frame) => boolean): Frame | undefined {\n for (let frame = state.als.getStore(); frame !== undefined; frame = frame.parent) {\n if (frame.open && test(frame)) {\n return frame;\n }\n }\n return undefined;\n}\n\nfunction warn(state: TrackerState, warning: TrackerWarning): void {\n if (!state.development) {\n return;\n }\n const frame = frameWhere(state, (candidate) => candidate.call !== undefined);\n if (frame?.call === undefined) {\n state.warnings.warn(warning);\n return;\n }\n (frame.warnings ?? state.warnings).warn({ ...warning, ...frame.call });\n}\n\n/** Where a statement runs: the innermost open buffer is a unit's, a batch's or an interactive transaction's. */\nfunction placeOf(state: TrackerState): StatementPlace {\n const open = frameWhere(state, (candidate) => candidate.buffer !== undefined);\n if (open?.batch === true) {\n return \"batch\";\n }\n return open?.tx === undefined ? \"unit\" : \"interactive\";\n}\n\nfunction observe(state: TrackerState, statement: Statement): void {\n if (!state.development || isQuiet()) {\n return;\n }\n const frame = frameWhere(state, (candidate) => candidate.check !== undefined);\n frame?.check?.(statement, placeOf(state));\n}\n\nfunction notify(state: TrackerState, writes: readonly WriteRecord[]): void {\n for (const listener of state.listeners) {\n for (const write of writes) {\n try {\n listener(write);\n } catch (error) {\n state.logger.error(\"An onWrite listener threw\", {\n category: \"quickdraw.writes\",\n error: errorText(error),\n });\n }\n }\n }\n}\n\nfunction flushAmbient(state: TrackerState): void {\n const writes = state.ambient;\n state.ambient = [];\n const scope: UnitOfWorkScope = {\n requestId: randomUUID(),\n transport: \"internal\",\n sink: state.sink,\n };\n void flushWrites(writes, scope, state.logger);\n}\n\nfunction recordAmbient(state: TrackerState, writes: readonly WriteRecord[]): void {\n for (const model of new Set(writes.map((write) => write.model))) {\n warn(state, {\n kind: \"ambient-write\",\n subject: model,\n message: `A tracked write to ${model} ran outside any unit of work, so it flushes on its own; run jobs and scripts inside qd.run(...)`,\n meta: { model },\n });\n }\n if (state.ambient.length === 0) {\n setImmediate(() => flushAmbient(state));\n }\n state.ambient.push(...writes);\n notify(state, writes);\n}\n\n/**\n * `qd.run(fn)` made before any dispatcher exists (a boot-time seed written\n * before `createServer`): a unit of work no dispatcher opened, shared by\n * every tracked client. The writes each client makes in it are kept apart\n * from ambient writes (so they raise no warning) and flush once `fn`\n * settles, to the dispatcher that client is attached to by then: none\n * before any server exists, so they reach no one, as no socket could be\n * subscribed yet.\n */\ninterface LooseRun {\n /** The writes of each tracked client, until the run settles. */\n readonly writes: Map<TrackerState, WriteRecord[]>;\n /** False once the run settled: work it started and did not await writes as ambient then. */\n open: boolean;\n}\n\nconst looseRuns = new AsyncLocalStorage<LooseRun>();\n\n/** Keeps `writes` in the loose run this runs in, if any; false outside one. */\nfunction keptLoose(state: TrackerState, writes: readonly WriteRecord[]): boolean {\n const run = looseRuns.getStore();\n if (run === undefined || !run.open) {\n return false;\n }\n run.writes.set(state, [...(run.writes.get(state) ?? []), ...writes]);\n notify(state, writes);\n return true;\n}\n\n/**\n * `qd.run(fn)` before its instance created any dispatcher: `fn` runs in a\n * unit of work no dispatcher opened, with a context that records nothing\n * (no tracked client is known to `ctx.touch`) and logs to the console.\n */\nexport async function runBeforeAnyDispatcher<R>(\n fn: (ctx: RunContext) => R | PromiseLike<R>,\n options?: RunOptions,\n): Promise<R> {\n if (typeof fn !== \"function\") {\n throw new TypeError(\"run: pass the function to run inside a unit of work\");\n }\n if (options !== undefined && (typeof options !== \"object\" || options === null)) {\n throw new TypeError(\"run: options must be an object, { detached?: boolean }\");\n }\n const ctx: RunContext = Object.freeze({\n touch: () => undefined,\n log: consoleLogger.child({ requestId: randomUUID() }),\n principal: null,\n });\n return await runLoose(() => fn(ctx));\n}\n\n/**\n * Runs `fn` in a unit of work no dispatcher opened (`qd.run` before any\n * exists): every tracked client's writes in it flush once `fn` settles,\n * whether it resolved or threw, each to the dispatcher its client is\n * attached to then, which before any server is none.\n */\nasync function runLoose<T>(fn: () => T | PromiseLike<T>): Promise<T> {\n const run: LooseRun = { writes: new Map(), open: true };\n try {\n return await looseRuns.run(run, async () => await fn());\n } finally {\n run.open = false;\n const flushed = [...run.writes].map(async ([state, writes]) => {\n const scope: UnitOfWorkScope = {\n requestId: randomUUID(),\n transport: \"internal\",\n sink: state.sink,\n };\n await flushWrites(writes, scope, state.logger);\n });\n run.writes.clear();\n await Promise.all(flushed);\n }\n}\n\n/** Puts `writes` in the first open buffer at or above `from`, or flushes them on their own. */\nfunction deliver(\n state: TrackerState,\n writes: readonly WriteRecord[],\n from: Frame | undefined,\n): void {\n if (writes.length === 0) {\n return;\n }\n for (let frame = from; frame !== undefined; frame = frame.parent) {\n if (frame.open && frame.buffer !== undefined) {\n frame.buffer.push(...writes);\n if (frame.durable) {\n notify(state, writes);\n }\n return;\n }\n }\n if (!keptLoose(state, writes)) {\n recordAmbient(state, writes);\n }\n}\n\nfunction openTransaction(state: TrackerState, kind: \"interactive\" | \"batch\"): TrackedTransaction {\n const parent = state.als.getStore();\n const frame: Frame = {\n parent,\n buffer: [],\n durable: false,\n tx: undefined,\n batch: kind === \"batch\",\n count: undefined,\n call: undefined,\n warnings: undefined,\n check: undefined,\n open: true,\n };\n return {\n setClient: (tx) => {\n frame.tx = tx;\n },\n run: (fn) => state.als.run(frame, async () => await fn()),\n commit: () => {\n frame.open = false;\n deliver(state, frame.buffer ?? [], parent);\n },\n rollback: () => {\n frame.open = false;\n },\n };\n}\n\nasync function countStatements<T>(\n state: TrackerState,\n fn: () => T | PromiseLike<T>,\n): Promise<StatementCount<T>> {\n let statements = 0;\n const frame: Frame = {\n parent: state.als.getStore(),\n buffer: undefined,\n durable: false,\n tx: undefined,\n batch: false,\n count: (n) => {\n statements += n;\n },\n call: undefined,\n warnings: undefined,\n check: undefined,\n open: true,\n };\n try {\n const value = await state.als.run(frame, async () => await fn());\n return { value, statements };\n } finally {\n frame.open = false;\n }\n}\n\n/**\n * The method call a unit's scope names, the warnings of the dispatcher that\n * runs it (the tracker's own when that dispatcher's are off, as for a\n * production dispatcher over a development tracker), and in development the\n * checks of its statements.\n */\nfunction callOf(\n state: TrackerState,\n scope: UnitOfWorkScope,\n): Pick<Frame, \"call\" | \"warnings\" | \"check\"> {\n if (scope.service === undefined || scope.method === undefined) {\n return { call: undefined, warnings: undefined, check: undefined };\n }\n const call: CallSite = { service: scope.service, method: scope.method };\n const warnings = scope.warnings?.enabled === true ? scope.warnings : state.warnings;\n if (!state.development) {\n return { call, warnings, check: undefined };\n }\n return {\n call,\n warnings,\n check: createStatementChecks((warning) => warnings.warn({ ...warning, ...call })),\n };\n}\n\n/** A unit of work over the tracker's frames. */\nfunction createUnit(state: TrackerState, scope: UnitOfWorkScope): UnitOfWork {\n let statements = 0;\n let frame: Frame | undefined;\n let flushed = false;\n const writes: WriteRecord[] = [];\n return {\n get sqlStatements() {\n return statements;\n },\n run<T>(fn: () => T | PromiseLike<T>): Promise<T> {\n // Inside an open buffer (a transaction, another unit), this unit joins it, unless it is\n // detached: then it stands alone, outside every frame open where it was begun.\n const detached = scope.detached === true;\n const joins =\n !detached && frameWhere(state, (candidate) => candidate.buffer !== undefined) !== undefined;\n const own: Frame = {\n parent: detached ? undefined : state.als.getStore(),\n buffer: joins ? undefined : writes,\n durable: true,\n tx: undefined,\n batch: false,\n count: (n) => {\n statements += n;\n },\n ...callOf(state, scope),\n open: true,\n };\n frame = own;\n return state.als.run(own, async () => await fn());\n },\n async flush(): Promise<void> {\n if (flushed) {\n return;\n }\n flushed = true;\n if (frame !== undefined) {\n frame.open = false;\n }\n await flushWrites(writes.splice(0), scope, state.logger);\n },\n };\n}\n\nfunction touchWrites(\n model: string,\n ids: readonly string[],\n options: TouchOptions | undefined,\n): WriteRecord[] {\n const removed = options?.removed === true;\n return [...new Set(ids)].map((id) => ({\n model,\n id,\n op: removed ? \"delete\" : \"update\",\n fields: removed ? [] : [ANY_FIELD],\n }));\n}\n\n/**\n * The warnings an attaching dispatcher's give the tracker for warnings\n * outside its calls: its own, unless they are off (a tracker made with\n * `development: true` keeps warning under a production dispatcher, as it\n * always did) or strict (only a strict dispatcher's calls throw).\n */\nfunction outsideCalls(\n state: TrackerState,\n logger: Logger,\n warnings: DevWarnings | undefined,\n): DevWarnings {\n return warnings?.enabled === true && !warnings.strict\n ? warnings\n : createDevWarnings({ logger, development: state.development });\n}\n\n/** Makes `attachment` the current one, until the returned function detaches it. */\nfunction attach(state: TrackerState, attachment: Attachment): () => void {\n const follow = (): void => {\n const current = state.attached.at(-1) ?? state.base;\n state.sink = current.sink;\n state.logger = current.logger;\n state.warnings = current.warnings;\n };\n state.attached.push(attachment);\n follow();\n return () => {\n const index = state.attached.indexOf(attachment);\n if (index !== -1) {\n state.attached.splice(index, 1);\n follow();\n }\n };\n}\n\n/** Creates the write tracker of one tracked database client. */\nexport function createWriteTracker(options: WriteTrackerOptions = {}): WriteTracker {\n const development = options.development ?? process.env.NODE_ENV !== \"production\";\n const logger = options.logger ?? consoleLogger;\n const base: Attachment = {\n sink: noFlushSink,\n logger,\n warnings: createDevWarnings({ logger, development }),\n };\n const state: TrackerState = {\n als: new AsyncLocalStorage<Frame>(),\n listeners: new Set(),\n development,\n base,\n attached: [],\n ...base,\n ambient: [],\n issued: 0,\n };\n const touch = (model: string, ids: readonly string[], touchOptions?: TouchOptions): void =>\n deliver(state, touchWrites(model, ids, touchOptions), state.als.getStore());\n const unitOfWork: UnitOfWorkFactory = Object.freeze({\n begin: (scope: UnitOfWorkScope) => createUnit(state, scope),\n touch,\n attach: (sink: FlushSink, attached: Logger, warnings?: DevWarnings) =>\n attach(state, { sink, logger: attached, warnings: outsideCalls(state, attached, warnings) }),\n });\n ISSUED.set(unitOfWork, () => state.issued);\n return Object.freeze({\n unitOfWork,\n record: (writes: readonly WriteRecord[]) => deliver(state, writes, state.als.getStore()),\n touch,\n countStatement(): void {\n state.issued += 1;\n for (let frame = state.als.getStore(); frame !== undefined; frame = frame.parent) {\n if (frame.open) {\n frame.count?.(1);\n }\n }\n },\n openTransaction: (kind: \"interactive\" | \"batch\") => openTransaction(state, kind),\n transactionClient: () => frameWhere(state, (frame) => frame.tx !== undefined)?.tx,\n inBatch: () => frameWhere(state, (frame) => frame.buffer !== undefined)?.batch === true,\n countStatements: <T>(fn: () => T | PromiseLike<T>) => countStatements(state, fn),\n onWrite(listener: (write: WriteRecord) => void): () => void {\n state.listeners.add(listener);\n return () => {\n state.listeners.delete(listener);\n };\n },\n warn: (warning: TrackerWarning) => warn(state, warning),\n observe: (statement: Statement) => observe(state, statement),\n get logger() {\n return state.logger;\n },\n });\n}\n","// The flush (RFC 0003 section 5.3): once a handler has settled and its\n// response was sent, its unit of work merges the recorded writes per row,\n// takes one revision, and hands the batch to the dispatcher's sinks in the\n// order they were given. A sink that throws is logged with the rows it\n// failed on; every other sink then hears about it through `onFlushError`.\n// Nothing here rejects: the caller's response was already sent.\n//\n// A dispatcher runs its flushes one after another, in revision order\n// (`inRevisionOrder`): a flush's sinks run once every flush with a lower\n// revision has finished its own, so frames leave in revision order and a\n// client that merges a patch only \"when rev is newer\" never drops one.\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { Logger } from \"../../contract/logger\";\nimport { describeError } from \"../pipeline/metrics\";\nimport { nextRev } from \"../rev\";\nimport { noFlushSink, type FlushInfo, type FlushSink } from \"./flushSink\";\nimport { mergeRecords } from \"./records\";\nimport type { UnitOfWorkScope, WriteRecord } from \"./types\";\n\n/** How many rows a failure's log entry names. */\nconst LOGGED_ROWS = 20;\n\nfunction logFailure(\n logger: Logger,\n message: string,\n writes: readonly WriteRecord[],\n info: FlushInfo,\n error: unknown,\n): void {\n logger.error(message, {\n category: \"quickdraw.flush\",\n requestId: info.requestId,\n service: info.service,\n method: info.method,\n rev: info.rev,\n rowCount: writes.length,\n rows: writes.slice(0, LOGGED_ROWS).map((write) => `${write.op} ${write.model} ${write.id}`),\n error: describeError(error),\n });\n}\n\n/**\n * Merges `records`, takes one revision and hands the batch to `scope.sink`.\n * With nothing recorded, or nothing left once merged (rows the unit created\n * and deleted again), no revision is taken and the sink is not called.\n * Never rejects; a sink's failure is logged.\n */\nexport async function flushWrites(\n records: readonly WriteRecord[],\n scope: UnitOfWorkScope,\n logger: Logger,\n): Promise<void> {\n const writes = mergeRecords(records);\n if (writes.length === 0) {\n return;\n }\n // The call's warnings stay with the unit: sinks see where the writes came from.\n const { sink, warnings: _warnings, detached: _detached, ...origin } = scope;\n const info: FlushInfo = { ...origin, rev: nextRev() };\n try {\n await sink.flush(writes, info);\n } catch (error) {\n logFailure(\n logger,\n \"Flushing writes failed; the response was already sent\",\n writes,\n info,\n error,\n );\n }\n}\n\ninterface Failure {\n readonly sink: FlushSink;\n readonly error: unknown;\n}\n\n/** Tells every sink but the one that failed, after all of them ran. */\nasync function reportFailures(\n sinks: readonly FlushSink[],\n failures: readonly Failure[],\n writes: readonly WriteRecord[],\n info: FlushInfo,\n logger: Logger,\n): Promise<void> {\n for (const sink of sinks) {\n const failure = failures.find((candidate) => candidate.sink !== sink);\n if (failure === undefined || sink.onFlushError === undefined) {\n continue;\n }\n try {\n await sink.onFlushError(writes, info, failure.error);\n } catch (error) {\n logFailure(\n logger,\n \"A flush sink failed to handle another sink's failure\",\n writes,\n info,\n error,\n );\n }\n }\n}\n\n/**\n * Where a dispatcher's flushes take their revision when it is not the one\n * `flushWrites` took: a cluster's shared counter (`../cluster/revisions.ts`).\n */\nexport interface FlushRevisions {\n /**\n * Called when a flush arrives: `undefined` to keep the flush's own\n * revision, or a function that resolves with the revision to use instead,\n * called when the flush's turn comes.\n */\n forFlush(): (() => Promise<number>) | undefined;\n}\n\n/**\n * A sink that runs the flushes it receives one at a time, in the order they\n * arrive, which is revision order: `flushWrites` takes a flush's revision\n * and hands the batch over in one synchronous step. A flush waits until the\n * flush before it has finished every sink; one that fails does not hold up\n * the next. A flush started from inside one of these runs (a sink that\n * writes through `qd.run`) runs at once instead: waiting for the run that\n * started it would never end.\n *\n * With `revisions` that hand out their own (a cluster's shared counter), a\n * flush asks for its revision when it arrives, and its sinks run with it\n * once its turn comes and the answer is in: still in arrival order, which\n * the revisions keep increasing.\n */\nexport function inRevisionOrder(sink: FlushSink, revisions?: FlushRevisions): FlushSink {\n const running = new AsyncLocalStorage<true>();\n let last: Promise<void> = Promise.resolve();\n return Object.freeze({\n flush(writes: readonly WriteRecord[], info: FlushInfo): Promise<void> {\n const shared = revisions?.forFlush();\n const flushOne =\n shared === undefined\n ? () => sink.flush(writes, info)\n : async () => await sink.flush(writes, { ...info, rev: await shared() });\n if (running.getStore() === true) {\n return flushOne();\n }\n const run = last.then(() => running.run(true, flushOne));\n last = run.catch(() => undefined);\n return run;\n },\n });\n}\n\n/**\n * One sink made of several: each batch goes to every sink in order, a sink\n * that throws is logged and the others still run, and once all have run\n * every sink but a failed one receives `onFlushError`. It never rejects. A\n * lone sink is returned as it is, and no sinks make one that does nothing.\n */\nexport function combineSinks(sinks: readonly FlushSink[], logger: Logger): FlushSink {\n const all = [...sinks];\n if (all.length === 0) {\n return noFlushSink;\n }\n if (all.length === 1 && all[0] !== undefined) {\n return all[0];\n }\n return Object.freeze({\n async flush(writes: readonly WriteRecord[], info: FlushInfo): Promise<void> {\n const failures: Failure[] = [];\n for (const sink of all) {\n try {\n await sink.flush(writes, info);\n } catch (error) {\n failures.push({ sink, error });\n logFailure(\n logger,\n \"A flush sink failed; the response was already sent\",\n writes,\n info,\n error,\n );\n }\n }\n if (failures.length > 0) {\n await reportFailures(all, failures, writes, info, logger);\n }\n },\n });\n}\n","// The flush sink seam (RFC 0003 section 5.3): where a unit of work's writes\n// go once the response is sent. The unit merges its writes per row and takes\n// one revision (`flush.ts`); each sink then turns the batch into what it\n// emits: entity frames, collection deltas, change signals, cache evictions.\n\nimport type { Revision } from \"../../protocol/envelope\";\nimport type { UnitOfWorkScope, WriteRecord } from \"./types\";\n\n/** What a sink learns about a flush besides its writes: where they came from, and the flush's revision. */\nexport interface FlushInfo extends Omit<UnitOfWorkScope, \"sink\" | \"warnings\" | \"detached\"> {\n /**\n * The flush's revision (RFC 0003 section 5.3, step 2), taken once for the\n * whole batch before any sink runs, so before any row is read.\n */\n readonly rev: Revision;\n}\n\n/**\n * Receives the writes of one unit of work after the response has been sent:\n * one record per row, merged. A failure is logged with the affected rows and\n * never fails the response.\n */\nexport interface FlushSink {\n flush(writes: readonly WriteRecord[], info: FlushInfo): Promise<void>;\n /**\n * Called when another sink failed to flush this batch, after every sink\n * ran, so this one can make up for what that one did not send (the\n * collections sink sends a `reset`). Its own failure is logged.\n */\n onFlushError?(\n writes: readonly WriteRecord[],\n info: FlushInfo,\n error: unknown,\n ): void | Promise<void>;\n}\n\n/** The default sink: there is nothing to emit until writes are tracked. */\nexport const noFlushSink: FlushSink = Object.freeze({\n flush: (): Promise<void> => Promise.resolve(),\n});\n","// Merging a unit of work's writes per row (RFC 0003 section 5.3, step 1).\n// A handler that updates one row ten times flushes one record, so a sink\n// reads that row once and a subscriber receives one frame.\n//\n// Per row, in the order the writes happened:\n//\n// - A row the unit created and then deleted is dropped: it never existed\n// outside the unit, so no sink, change log or topic hears of it. Its create\n// must be certain: an `upsert` that read nothing (`mayHaveExisted`) may\n// have updated a row that existed, whose delete is kept, with the values\n// the writes carry.\n// - Otherwise `delete` beats `create` beats `update`, read as \"the row's\n// final state\": a row whose last write deleted it is a `delete`; a row\n// that was created, or deleted and created again, is a `create`, which\n// sinks send whole; anything else is an `update`.\n// - `fields` are unioned.\n// - `before` keeps the earliest value of each column: the row as subscribers\n// last saw it, since nothing was emitted during the unit. A row the unit\n// created has none.\n// - `after` keeps the latest value of each column written since the row was\n// last deleted; a deleted row has none.\n// - A row whose merged write is a `delete` carries the junction `links` its\n// delete records read, per junction, concatenated; none unless every one\n// of them read that junction's.\n\nimport { ANY_FIELD, type WriteRecord } from \"./types\";\n\ntype Values = Readonly<Record<string, unknown>>;\n\n/** One row's writes, oldest first. */\ntype History = readonly [WriteRecord, ...WriteRecord[]];\n\nfunction mergeFields(history: History): readonly string[] {\n const fields = new Set<string>();\n for (const record of history) {\n for (const field of record.fields) {\n fields.add(field);\n }\n }\n return fields.has(ANY_FIELD) ? [ANY_FIELD] : [...fields];\n}\n\n/** Merges value maps; with `keepFirst`, the first value of a key wins, otherwise the last. */\nfunction mergeValues(\n maps: readonly (Values | undefined)[],\n keepFirst: boolean,\n): Values | undefined {\n let merged: Record<string, unknown> | undefined;\n for (const values of maps) {\n if (values === undefined) {\n continue;\n }\n merged ??= {};\n for (const [key, value] of Object.entries(values)) {\n if (!keepFirst || !Object.hasOwn(merged, key)) {\n merged[key] = value;\n }\n }\n }\n return merged;\n}\n\nfunction finalOp(history: History): WriteRecord[\"op\"] {\n if (history[history.length - 1]?.op === \"delete\") {\n return \"delete\";\n }\n return history.some((record) => record.op === \"create\") ? \"create\" : \"update\";\n}\n\n/** The writes since the row was last deleted: what its `after` values describe. */\nfunction sinceLastDelete(history: History): readonly WriteRecord[] {\n let start = 0;\n history.forEach((record, index) => {\n if (record.op === \"delete\") {\n start = index + 1;\n }\n });\n return history.slice(start);\n}\n\n/** True when the row's first write certainly created it: not an upsert that read nothing. */\nfunction created(first: WriteRecord): boolean {\n return first.op === \"create\" && first.mayHaveExisted !== true;\n}\n\n/** The `links` of a row merged into a delete: every delete record's, per junction each read. */\nfunction mergeLinks(history: History): WriteRecord[\"links\"] {\n const deletes = history.filter((record) => record.op === \"delete\");\n const [first] = deletes;\n if (first?.links === undefined || deletes.some((record) => record.links === undefined)) {\n return undefined;\n }\n const junctions = Object.keys(first.links).filter((junction) =>\n deletes.every((record) => record.links !== undefined && Object.hasOwn(record.links, junction)),\n );\n return Object.fromEntries(\n junctions.map((junction) => [\n junction,\n deletes.flatMap((record) => record.links?.[junction] ?? []),\n ]),\n );\n}\n\n/** The row's one merged record, or `undefined` for a row the unit created and deleted again. */\nfunction mergeRow(history: History): WriteRecord | undefined {\n const [first] = history;\n if (created(first) && history[history.length - 1]?.op === \"delete\") {\n return undefined;\n }\n if (history.length === 1) {\n return first;\n }\n const op = finalOp(history);\n const before = created(first)\n ? undefined\n : mergeValues(\n history.map((record) => record.before),\n true,\n );\n const after =\n op === \"delete\"\n ? undefined\n : mergeValues(\n sinceLastDelete(history).map((record) => record.after),\n false,\n );\n const links = op === \"delete\" ? mergeLinks(history) : undefined;\n return {\n model: first.model,\n id: first.id,\n op,\n fields: mergeFields(history),\n ...(before === undefined ? {} : { before }),\n ...(after === undefined ? {} : { after }),\n ...(links === undefined ? {} : { links }),\n };\n}\n\n/**\n * Merges a unit of work's writes into one record per row, in the order each\n * row was first written; a row the unit created and deleted again has none.\n * See the rules at the top of this file.\n */\nexport function mergeRecords(records: readonly WriteRecord[]): WriteRecord[] {\n const rows = new Map<string, [WriteRecord, ...WriteRecord[]]>();\n for (const record of records) {\n const key = `${record.model}\\u0000${record.id}`;\n const history = rows.get(key);\n if (history === undefined) {\n rows.set(key, [record]);\n } else {\n history.push(record);\n }\n }\n return [...rows.values()].flatMap((history) => mergeRow(history) ?? []);\n}\n","// The development checks of a method call's statements (`../devWarnings.ts`):\n// N+1 statements and unbounded reads. The tracked database client tells the\n// write tracker about each statement before it runs (`trackPrisma`'s hook),\n// and the tracker hands it to the checks of the innermost method call it\n// runs in. A statement outside a method call (a `qd.run` job, a flush, a\n// subscription) is not checked, and neither is one the framework runs\n// `quietly`.\n\nimport { N_PLUS_ONE_STATEMENTS, type DevWarning } from \"../devWarnings\";\n\n/** One statement the tracked database client is about to run. */\nexport interface Statement {\n /** The model, named as the client names it: `\"task\"`. */\n readonly model: string;\n /** The client operation: `\"findMany\"`. */\n readonly operation: string;\n readonly args: Readonly<Record<string, unknown>> | undefined;\n}\n\n/** The method call a unit of work runs. */\nexport interface CallSite {\n readonly service: string;\n readonly method: string;\n}\n\n/**\n * Where a statement runs: in the call's unit, inside an array-form\n * `$transaction([...])` (`\"batch\"`), or inside an interactive\n * `$transaction(async (tx) => ...)` (`\"interactive\"`).\n */\nexport type StatementPlace = \"unit\" | \"batch\" | \"interactive\";\n\n/** Checks one statement of a call, run at `place`. */\nexport type StatementCheck = (statement: Statement, place: StatementPlace) => void;\n\n/** Raises a warning about the call the checks belong to. */\nexport type RaiseWarning = (warning: Omit<DevWarning, \"service\" | \"method\">) => void;\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** The keys a statement filters by, sorted: its shape besides the model and operation. */\nfunction whereKeys(statement: Statement): string[] {\n const where = statement.args?.where;\n return isRecord(where) ? Object.keys(where).sort() : [];\n}\n\n/**\n * Whether an `id` filter names the rows it reads: a value (equality), or\n * `{ in }` or `{ equals }`. `{ not }`, `{ notIn }` and comparisons leave\n * every other row.\n */\nfunction namesIds(filter: unknown): boolean {\n if (filter === undefined) {\n return false;\n }\n if (!isRecord(filter)) {\n return true;\n }\n return filter.in !== undefined || filter.equals !== undefined;\n}\n\n/**\n * A `findMany` that can return every row of its table: no `take`, and no\n * `id` filter that names its rows (a read by ids is bounded by the ids it\n * names). The same test as the lint rule `no-unbounded-read`, made on the\n * arguments the statement actually ran with.\n */\nexport function isUnboundedRead(statement: Statement): boolean {\n if (statement.operation !== \"findMany\") {\n return false;\n }\n const { take, where } = statement.args ?? {};\n if (take !== undefined && take !== null) {\n return false;\n }\n return !(isRecord(where) && namesIds(where.id));\n}\n\n/**\n * An update or delete of one row by its id inside an interactive\n * transaction: the sanctioned form of per-row writes whose data differs per\n * row (one that moves a row or changes who may see it must read the row\n * first, which an array-form `$transaction` cannot do inside the batch).\n */\nfunction isRowWriteInTransaction(statement: Statement, place: StatementPlace): boolean {\n if (place !== \"interactive\") {\n return false;\n }\n if (statement.operation !== \"update\" && statement.operation !== \"delete\") {\n return false;\n }\n const keys = whereKeys(statement);\n return keys.length === 1 && keys[0] === \"id\";\n}\n\n/**\n * A statement filtered by an `id` list (`{ id: { in: ids } }`): one query\n * per list, as in a loop over chunks of ids, so never an N+1. The lint rule\n * `no-db-call-in-loop` makes the same exception.\n */\nfunction readsIdList(statement: Statement): boolean {\n const where = statement.args?.where;\n const id = isRecord(where) ? where.id : undefined;\n return isRecord(id) && Array.isArray(id.in);\n}\n\nfunction nPlusOne(\n statement: Statement,\n keys: readonly string[],\n): Omit<DevWarning, \"service\" | \"method\"> {\n const label = `${statement.model}.${statement.operation}${keys.length === 0 ? \"\" : ` by ${keys.join(\", \")}`}`;\n return {\n kind: \"n-plus-one\",\n message:\n `${label} ran ${N_PLUS_ONE_STATEMENTS} times in one call, once per item (N+1); ` +\n \"read the rows in one query (findMany({ where: { id: { in: ids } } })), write them in one when every row gets the same data \" +\n \"(updateMany, createMany), or write each row by id inside an interactive transaction (db.$transaction(async (tx) => ...))\",\n meta: { model: statement.model, operation: statement.operation, where: keys },\n };\n}\n\nfunction unboundedRead(statement: Statement): Omit<DevWarning, \"service\" | \"method\"> {\n return {\n kind: \"unbounded-read\",\n message:\n `${statement.model}.findMany() without take reads every matching row, however many there are; ` +\n \"add take (with a cursor to page), or serve the list as a collection or the read/write kit's list\",\n meta: { model: statement.model },\n };\n}\n\n/**\n * The checks of one method call: warns once its statements of one shape\n * (model, operation and `where` keys) reach {@link N_PLUS_ONE_STATEMENTS}, and\n * at an unbounded read. Statements batched in an array-form `$transaction`\n * are sent together, which is the fix for an N+1, so they are not counted;\n * neither are updates and deletes by id inside an interactive transaction,\n * the form per-row writes take when each row's data differs, nor statements\n * filtered by an `id` list (one per chunk of ids).\n */\nexport function createStatementChecks(raise: RaiseWarning): StatementCheck {\n const shapes = new Map<string, number>();\n return (statement, place) => {\n if (isUnboundedRead(statement)) {\n raise(unboundedRead(statement));\n }\n if (place === \"batch\" || isRowWriteInTransaction(statement, place) || readsIdList(statement)) {\n return;\n }\n const keys = whereKeys(statement);\n const shape = `${statement.model}.${statement.operation}(${keys.join(\",\")})`;\n const seen = (shapes.get(shape) ?? 0) + 1;\n shapes.set(shape, seen);\n if (seen === N_PLUS_ONE_STATEMENTS) {\n raise(nPlusOne(statement, keys));\n }\n };\n}\n"],"mappings":"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","names":["AsyncLocalStorage","AsyncLocalStorage","AsyncLocalStorage","last","AsyncLocalStorage"]}
@@ -4,10 +4,12 @@ import {
4
4
  } from "../chunk-XNLWBZIG.js";
5
5
  import {
6
6
  CHANNEL_DEFAULT_RATE,
7
- DEFAULT_COLLECTION_LIMIT,
8
- DEFAULT_COLLECTION_MAX_LIMIT,
9
7
  isScopedStream
10
- } from "../chunk-RT6OILOI.js";
8
+ } from "../chunk-5CGO426C.js";
9
+ import {
10
+ DEFAULT_COLLECTION_LIMIT,
11
+ DEFAULT_COLLECTION_MAX_LIMIT
12
+ } from "../chunk-4D2DOGAW.js";
11
13
  import {
12
14
  hasJsonSchema,
13
15
  isStandardSchema