pipework 0.8.2 → 0.8.5

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 (355) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/async/jobs/execute.d.ts +2 -0
  3. package/dist/async/jobs/execute.d.ts.map +1 -1
  4. package/dist/async/jobs/execute.js +17 -2
  5. package/dist/async/jobs/execute.js.map +1 -1
  6. package/dist/audit/query/cursor.d.ts +7 -0
  7. package/dist/audit/query/cursor.d.ts.map +1 -0
  8. package/dist/audit/query/cursor.js +25 -0
  9. package/dist/audit/query/cursor.js.map +1 -0
  10. package/dist/audit/query/index.d.ts +5 -0
  11. package/dist/audit/query/index.d.ts.map +1 -0
  12. package/dist/audit/query/index.js +3 -0
  13. package/dist/audit/query/index.js.map +1 -0
  14. package/dist/audit/query/query.d.ts +49 -0
  15. package/dist/audit/query/query.d.ts.map +1 -0
  16. package/dist/audit/query/query.js +119 -0
  17. package/dist/audit/query/query.js.map +1 -0
  18. package/dist/audit/schema/audit-record-fields.d.ts +15 -0
  19. package/dist/audit/schema/audit-record-fields.d.ts.map +1 -0
  20. package/dist/audit/schema/audit-record-fields.js +50 -0
  21. package/dist/audit/schema/audit-record-fields.js.map +1 -0
  22. package/dist/audit/schema/audit-record.d.ts +15 -0
  23. package/dist/audit/schema/audit-record.d.ts.map +1 -0
  24. package/dist/audit/schema/audit-record.js +12 -0
  25. package/dist/audit/schema/audit-record.js.map +1 -0
  26. package/dist/auth/tenant/scope.js +1 -1
  27. package/dist/auth/tenant/scope.js.map +1 -1
  28. package/dist/auth/tenant/scoped-db.d.ts.map +1 -1
  29. package/dist/auth/tenant/scoped-db.js +1 -2
  30. package/dist/auth/tenant/scoped-db.js.map +1 -1
  31. package/dist/cli/commands/check.d.ts +4 -0
  32. package/dist/cli/commands/check.d.ts.map +1 -1
  33. package/dist/cli/commands/check.js +181 -14
  34. package/dist/cli/commands/check.js.map +1 -1
  35. package/dist/cli/commands/codemod.d.ts +6 -0
  36. package/dist/cli/commands/codemod.d.ts.map +1 -0
  37. package/dist/cli/commands/codemod.js +63 -0
  38. package/dist/cli/commands/codemod.js.map +1 -0
  39. package/dist/cli/index.d.ts.map +1 -1
  40. package/dist/cli/index.js +9 -0
  41. package/dist/cli/index.js.map +1 -1
  42. package/dist/core/config/load.d.ts +23 -0
  43. package/dist/core/config/load.d.ts.map +1 -1
  44. package/dist/core/config/load.js +8 -0
  45. package/dist/core/config/load.js.map +1 -1
  46. package/dist/core/config/namespace.d.ts +19 -0
  47. package/dist/core/config/namespace.d.ts.map +1 -1
  48. package/dist/core/config/schema.d.ts +41 -0
  49. package/dist/core/config/schema.d.ts.map +1 -1
  50. package/dist/core/config/schema.js +27 -0
  51. package/dist/core/config/schema.js.map +1 -1
  52. package/dist/core/logging/logger.d.ts +3 -1
  53. package/dist/core/logging/logger.d.ts.map +1 -1
  54. package/dist/core/logging/logger.js +2 -2
  55. package/dist/core/logging/logger.js.map +1 -1
  56. package/dist/core/pipework.d.ts +2 -2
  57. package/dist/core/pipework.d.ts.map +1 -1
  58. package/dist/data/db/bulk-set.js +1 -1
  59. package/dist/data/db/bulk-set.js.map +1 -1
  60. package/dist/data/db/composed.js +1 -1
  61. package/dist/data/db/composed.js.map +1 -1
  62. package/dist/data/db/db.d.ts +10 -0
  63. package/dist/data/db/db.d.ts.map +1 -1
  64. package/dist/data/db/db.js +12 -0
  65. package/dist/data/db/db.js.map +1 -1
  66. package/dist/data/db/filter.d.ts +42 -43
  67. package/dist/data/db/filter.d.ts.map +1 -1
  68. package/dist/data/db/filter.js +7 -6
  69. package/dist/data/db/filter.js.map +1 -1
  70. package/dist/data/db/namespace.d.ts +90 -82
  71. package/dist/data/db/namespace.d.ts.map +1 -1
  72. package/dist/data/db/namespace.js +21 -5
  73. package/dist/data/db/namespace.js.map +1 -1
  74. package/dist/data/migrate/post-process.d.ts +2 -1
  75. package/dist/data/migrate/post-process.d.ts.map +1 -1
  76. package/dist/data/migrate/post-process.js +2 -1
  77. package/dist/data/migrate/post-process.js.map +1 -1
  78. package/dist/data/temporal/definition-queries.js +1 -1
  79. package/dist/data/temporal/definition-queries.js.map +1 -1
  80. package/dist/data/temporal/query.js +1 -1
  81. package/dist/data/temporal/query.js.map +1 -1
  82. package/dist/data/temporal/resolve.js +1 -1
  83. package/dist/data/temporal/resolve.js.map +1 -1
  84. package/dist/data/write/audit/actor.d.ts +3 -0
  85. package/dist/data/write/audit/actor.d.ts.map +1 -0
  86. package/dist/data/write/audit/actor.js +15 -0
  87. package/dist/data/write/audit/actor.js.map +1 -0
  88. package/dist/data/write/audit/audit-columns.d.ts +6 -0
  89. package/dist/data/write/audit/audit-columns.d.ts.map +1 -0
  90. package/dist/data/write/audit/audit-columns.js +15 -0
  91. package/dist/data/write/audit/audit-columns.js.map +1 -0
  92. package/dist/data/write/audit/audit-select.d.ts +28 -0
  93. package/dist/data/write/audit/audit-select.d.ts.map +1 -0
  94. package/dist/data/write/audit/audit-select.js +49 -0
  95. package/dist/data/write/audit/audit-select.js.map +1 -0
  96. package/dist/data/write/audit/cte-compile.d.ts +7 -0
  97. package/dist/data/write/audit/cte-compile.d.ts.map +1 -0
  98. package/dist/data/write/audit/cte-compile.js +23 -0
  99. package/dist/data/write/audit/cte-compile.js.map +1 -0
  100. package/dist/data/write/audit/final-select.d.ts +4 -0
  101. package/dist/data/write/audit/final-select.d.ts.map +1 -0
  102. package/dist/data/write/audit/final-select.js +28 -0
  103. package/dist/data/write/audit/final-select.js.map +1 -0
  104. package/dist/data/write/audit/primary-key.d.ts +7 -0
  105. package/dist/data/write/audit/primary-key.d.ts.map +1 -0
  106. package/dist/data/write/audit/primary-key.js +32 -0
  107. package/dist/data/write/audit/primary-key.js.map +1 -0
  108. package/dist/data/write/audit/projection.d.ts +11 -0
  109. package/dist/data/write/audit/projection.d.ts.map +1 -0
  110. package/dist/data/write/audit/projection.js +37 -0
  111. package/dist/data/write/audit/projection.js.map +1 -0
  112. package/dist/data/write/audit/read-touches.d.ts +10 -0
  113. package/dist/data/write/audit/read-touches.d.ts.map +1 -0
  114. package/dist/data/write/audit/read-touches.js +63 -0
  115. package/dist/data/write/audit/read-touches.js.map +1 -0
  116. package/dist/data/write/audit/verb-delete.d.ts +7 -0
  117. package/dist/data/write/audit/verb-delete.d.ts.map +1 -0
  118. package/dist/data/write/audit/verb-delete.js +53 -0
  119. package/dist/data/write/audit/verb-delete.js.map +1 -0
  120. package/dist/data/write/audit/verb-insert.d.ts +7 -0
  121. package/dist/data/write/audit/verb-insert.d.ts.map +1 -0
  122. package/dist/data/write/audit/verb-insert.js +28 -0
  123. package/dist/data/write/audit/verb-insert.js.map +1 -0
  124. package/dist/data/write/audit/verb-update.d.ts +7 -0
  125. package/dist/data/write/audit/verb-update.d.ts.map +1 -0
  126. package/dist/data/write/audit/verb-update.js +52 -0
  127. package/dist/data/write/audit/verb-update.js.map +1 -0
  128. package/dist/data/write/audit/verb-upsert.d.ts +7 -0
  129. package/dist/data/write/audit/verb-upsert.d.ts.map +1 -0
  130. package/dist/data/write/audit/verb-upsert.js +81 -0
  131. package/dist/data/write/audit/verb-upsert.js.map +1 -0
  132. package/dist/data/write/delete.d.ts +15 -0
  133. package/dist/data/write/delete.d.ts.map +1 -0
  134. package/dist/data/write/delete.js +25 -0
  135. package/dist/data/write/delete.js.map +1 -0
  136. package/dist/data/write/execute.d.ts +3 -0
  137. package/dist/data/write/execute.d.ts.map +1 -0
  138. package/dist/data/write/execute.js +162 -0
  139. package/dist/data/write/execute.js.map +1 -0
  140. package/dist/data/write/index.d.ts +6 -0
  141. package/dist/data/write/index.d.ts.map +1 -0
  142. package/dist/data/write/index.js +10 -0
  143. package/dist/data/write/index.js.map +1 -0
  144. package/dist/data/write/insert.d.ts +18 -0
  145. package/dist/data/write/insert.d.ts.map +1 -0
  146. package/dist/data/write/insert.js +29 -0
  147. package/dist/data/write/insert.js.map +1 -0
  148. package/dist/data/write/state.d.ts +29 -0
  149. package/dist/data/write/state.d.ts.map +1 -0
  150. package/dist/data/write/state.js +9 -0
  151. package/dist/data/write/state.js.map +1 -0
  152. package/dist/data/write/update.d.ts +17 -0
  153. package/dist/data/write/update.d.ts.map +1 -0
  154. package/dist/data/write/update.js +39 -0
  155. package/dist/data/write/update.js.map +1 -0
  156. package/dist/data/write/upsert.d.ts +21 -0
  157. package/dist/data/write/upsert.d.ts.map +1 -0
  158. package/dist/data/write/upsert.js +42 -0
  159. package/dist/data/write/upsert.js.map +1 -0
  160. package/dist/index.d.ts +3 -0
  161. package/dist/index.d.ts.map +1 -1
  162. package/dist/index.js +1 -0
  163. package/dist/index.js.map +1 -1
  164. package/dist/infra/audit/namespace.d.ts +3 -0
  165. package/dist/infra/audit/namespace.d.ts.map +1 -1
  166. package/dist/infra/audit/namespace.js +3 -0
  167. package/dist/infra/audit/namespace.js.map +1 -1
  168. package/dist/lint/config.d.ts +4 -2
  169. package/dist/lint/config.d.ts.map +1 -1
  170. package/dist/lint/config.js +9 -5
  171. package/dist/lint/config.js.map +1 -1
  172. package/dist/lint/index.d.ts +2 -1
  173. package/dist/lint/index.d.ts.map +1 -1
  174. package/dist/lint/index.js +1 -0
  175. package/dist/lint/index.js.map +1 -1
  176. package/dist/lint/resolver.d.ts +16 -0
  177. package/dist/lint/resolver.d.ts.map +1 -0
  178. package/dist/lint/resolver.js +61 -0
  179. package/dist/lint/resolver.js.map +1 -0
  180. package/dist/request/context/create.d.ts +4 -0
  181. package/dist/request/context/create.d.ts.map +1 -1
  182. package/dist/request/context/create.js +3 -0
  183. package/dist/request/context/create.js.map +1 -1
  184. package/dist/request/context/types.d.ts +3 -0
  185. package/dist/request/context/types.d.ts.map +1 -1
  186. package/dist/request/http/middleware.d.ts.map +1 -1
  187. package/dist/request/http/middleware.js +30 -0
  188. package/dist/request/http/middleware.js.map +1 -1
  189. package/dist/request/http/server.d.ts.map +1 -1
  190. package/dist/request/http/server.js +6 -1
  191. package/dist/request/http/server.js.map +1 -1
  192. package/dist/test/context.d.ts.map +1 -1
  193. package/dist/test/context.js +43 -2
  194. package/dist/test/context.js.map +1 -1
  195. package/dist/test/index.d.ts +1 -1
  196. package/dist/test/index.d.ts.map +1 -1
  197. package/dist/test/index.js +1 -1
  198. package/dist/test/index.js.map +1 -1
  199. package/dist/test/vitest-workspace.d.ts +15 -2
  200. package/dist/test/vitest-workspace.d.ts.map +1 -1
  201. package/dist/test/vitest-workspace.js +60 -7
  202. package/dist/test/vitest-workspace.js.map +1 -1
  203. package/dist/trace/cardinality/analyze.d.ts +26 -0
  204. package/dist/trace/cardinality/analyze.d.ts.map +1 -0
  205. package/dist/trace/cardinality/analyze.js +129 -0
  206. package/dist/trace/cardinality/analyze.js.map +1 -0
  207. package/dist/trace/cardinality/branch-context.d.ts +13 -0
  208. package/dist/trace/cardinality/branch-context.d.ts.map +1 -0
  209. package/dist/trace/cardinality/branch-context.js +182 -0
  210. package/dist/trace/cardinality/branch-context.js.map +1 -0
  211. package/dist/trace/cardinality/check.d.ts +4 -0
  212. package/dist/trace/cardinality/check.d.ts.map +1 -0
  213. package/dist/trace/cardinality/check.js +29 -0
  214. package/dist/trace/cardinality/check.js.map +1 -0
  215. package/dist/trace/cardinality/classify-edge.d.ts +31 -0
  216. package/dist/trace/cardinality/classify-edge.d.ts.map +1 -0
  217. package/dist/trace/cardinality/classify-edge.js +27 -0
  218. package/dist/trace/cardinality/classify-edge.js.map +1 -0
  219. package/dist/trace/cardinality/structural-max.d.ts +14 -0
  220. package/dist/trace/cardinality/structural-max.d.ts.map +1 -0
  221. package/dist/trace/cardinality/structural-max.js +83 -0
  222. package/dist/trace/cardinality/structural-max.js.map +1 -0
  223. package/dist/trace/check/coverage-check.d.ts +20 -0
  224. package/dist/trace/check/coverage-check.d.ts.map +1 -0
  225. package/dist/trace/check/coverage-check.js +146 -0
  226. package/dist/trace/check/coverage-check.js.map +1 -0
  227. package/dist/trace/check/flow-check.d.ts +13 -0
  228. package/dist/trace/check/flow-check.d.ts.map +1 -0
  229. package/dist/trace/check/flow-check.js +82 -0
  230. package/dist/trace/check/flow-check.js.map +1 -0
  231. package/dist/trace/check/flow-step-site.d.ts +62 -0
  232. package/dist/trace/check/flow-step-site.d.ts.map +1 -0
  233. package/dist/trace/check/flow-step-site.js +142 -0
  234. package/dist/trace/check/flow-step-site.js.map +1 -0
  235. package/dist/trace/check/io-pattern.d.ts +14 -0
  236. package/dist/trace/check/io-pattern.d.ts.map +1 -0
  237. package/dist/trace/check/io-pattern.js +113 -0
  238. package/dist/trace/check/io-pattern.js.map +1 -0
  239. package/dist/trace/codemod/add-cardinality.d.ts +38 -0
  240. package/dist/trace/codemod/add-cardinality.d.ts.map +1 -0
  241. package/dist/trace/codemod/add-cardinality.js +106 -0
  242. package/dist/trace/codemod/add-cardinality.js.map +1 -0
  243. package/dist/trace/codemod/run.d.ts +25 -0
  244. package/dist/trace/codemod/run.d.ts.map +1 -0
  245. package/dist/trace/codemod/run.js +47 -0
  246. package/dist/trace/codemod/run.js.map +1 -0
  247. package/dist/trace/entry/close-trace.d.ts +7 -0
  248. package/dist/trace/entry/close-trace.d.ts.map +1 -0
  249. package/dist/trace/entry/close-trace.js +54 -0
  250. package/dist/trace/entry/close-trace.js.map +1 -0
  251. package/dist/trace/entry/finalize-trace.d.ts +5 -0
  252. package/dist/trace/entry/finalize-trace.d.ts.map +1 -0
  253. package/dist/trace/entry/finalize-trace.js +23 -0
  254. package/dist/trace/entry/finalize-trace.js.map +1 -0
  255. package/dist/trace/entry/open-trace.d.ts +26 -0
  256. package/dist/trace/entry/open-trace.d.ts.map +1 -0
  257. package/dist/trace/entry/open-trace.js +75 -0
  258. package/dist/trace/entry/open-trace.js.map +1 -0
  259. package/dist/trace/entry/parent-trace.d.ts +4 -0
  260. package/dist/trace/entry/parent-trace.d.ts.map +1 -0
  261. package/dist/trace/entry/parent-trace.js +10 -0
  262. package/dist/trace/entry/parent-trace.js.map +1 -0
  263. package/dist/trace/entry/parse-traceparent.d.ts +8 -0
  264. package/dist/trace/entry/parse-traceparent.d.ts.map +1 -0
  265. package/dist/trace/entry/parse-traceparent.js +37 -0
  266. package/dist/trace/entry/parse-traceparent.js.map +1 -0
  267. package/dist/trace/entry/trace-context.d.ts +19 -0
  268. package/dist/trace/entry/trace-context.d.ts.map +1 -0
  269. package/dist/trace/entry/trace-context.js +5 -0
  270. package/dist/trace/entry/trace-context.js.map +1 -0
  271. package/dist/trace/entry/tracing-enabled.d.ts +4 -0
  272. package/dist/trace/entry/tracing-enabled.d.ts.map +1 -0
  273. package/dist/trace/entry/tracing-enabled.js +8 -0
  274. package/dist/trace/entry/tracing-enabled.js.map +1 -0
  275. package/dist/trace/partition/plan.d.ts +2 -0
  276. package/dist/trace/partition/plan.d.ts.map +1 -1
  277. package/dist/trace/partition/plan.js +8 -1
  278. package/dist/trace/partition/plan.js.map +1 -1
  279. package/dist/trace/partition/schedule.d.ts.map +1 -1
  280. package/dist/trace/partition/schedule.js +6 -4
  281. package/dist/trace/partition/schedule.js.map +1 -1
  282. package/dist/trace/partition/startup-hook.d.ts.map +1 -1
  283. package/dist/trace/partition/startup-hook.js +6 -2
  284. package/dist/trace/partition/startup-hook.js.map +1 -1
  285. package/dist/trace/partition/tables.d.ts +1 -1
  286. package/dist/trace/partition/tables.d.ts.map +1 -1
  287. package/dist/trace/partition/tables.js +13 -5
  288. package/dist/trace/partition/tables.js.map +1 -1
  289. package/dist/trace/runtime/expire-stale-traces.d.ts +10 -0
  290. package/dist/trace/runtime/expire-stale-traces.d.ts.map +1 -0
  291. package/dist/trace/runtime/expire-stale-traces.js +36 -0
  292. package/dist/trace/runtime/expire-stale-traces.js.map +1 -0
  293. package/dist/trace/runtime/flow-step.d.ts +6 -0
  294. package/dist/trace/runtime/flow-step.d.ts.map +1 -0
  295. package/dist/trace/runtime/flow-step.js +122 -0
  296. package/dist/trace/runtime/flow-step.js.map +1 -0
  297. package/dist/trace/runtime/flush-steps.d.ts +5 -0
  298. package/dist/trace/runtime/flush-steps.d.ts.map +1 -0
  299. package/dist/trace/runtime/flush-steps.js +23 -0
  300. package/dist/trace/runtime/flush-steps.js.map +1 -0
  301. package/dist/trace/runtime/step-buffer.d.ts +139 -0
  302. package/dist/trace/runtime/step-buffer.d.ts.map +1 -0
  303. package/dist/trace/runtime/step-buffer.js +140 -0
  304. package/dist/trace/runtime/step-buffer.js.map +1 -0
  305. package/dist/trace/runtime/step-error.d.ts +8 -0
  306. package/dist/trace/runtime/step-error.d.ts.map +1 -0
  307. package/dist/trace/runtime/step-error.js +13 -0
  308. package/dist/trace/runtime/step-error.js.map +1 -0
  309. package/dist/trace/runtime/step-meta.d.ts +48 -0
  310. package/dist/trace/runtime/step-meta.d.ts.map +1 -0
  311. package/dist/trace/runtime/step-meta.js +6 -0
  312. package/dist/trace/runtime/step-meta.js.map +1 -0
  313. package/dist/trace/runtime/thenable.d.ts +3 -0
  314. package/dist/trace/runtime/thenable.d.ts.map +1 -0
  315. package/dist/trace/runtime/thenable.js +12 -0
  316. package/dist/trace/runtime/thenable.js.map +1 -0
  317. package/dist/trace/runtime/truncate-trace.d.ts +5 -0
  318. package/dist/trace/runtime/truncate-trace.d.ts.map +1 -0
  319. package/dist/trace/runtime/truncate-trace.js +44 -0
  320. package/dist/trace/runtime/truncate-trace.js.map +1 -0
  321. package/dist/trace/schema/trace-fields.d.ts +1 -1
  322. package/dist/trace/schema/trace-retained.d.ts +1 -1
  323. package/dist/trace/schema/trace.d.ts +1 -1
  324. package/dist/trace/transformer/build-meta-literal.d.ts +3 -0
  325. package/dist/trace/transformer/build-meta-literal.d.ts.map +1 -0
  326. package/dist/trace/transformer/build-meta-literal.js +8 -0
  327. package/dist/trace/transformer/build-meta-literal.js.map +1 -0
  328. package/dist/trace/transformer/find-flow-step-sites.d.ts +24 -0
  329. package/dist/trace/transformer/find-flow-step-sites.d.ts.map +1 -0
  330. package/dist/trace/transformer/find-flow-step-sites.js +69 -0
  331. package/dist/trace/transformer/find-flow-step-sites.js.map +1 -0
  332. package/dist/trace/transformer/inject-flow-step-import.d.ts +3 -0
  333. package/dist/trace/transformer/inject-flow-step-import.d.ts.map +1 -0
  334. package/dist/trace/transformer/inject-flow-step-import.js +28 -0
  335. package/dist/trace/transformer/inject-flow-step-import.js.map +1 -0
  336. package/dist/trace/transformer/transform-error.d.ts +8 -0
  337. package/dist/trace/transformer/transform-error.d.ts.map +1 -0
  338. package/dist/trace/transformer/transform-error.js +5 -0
  339. package/dist/trace/transformer/transform-error.js.map +1 -0
  340. package/dist/trace/transformer/transform-flow-steps.d.ts +12 -0
  341. package/dist/trace/transformer/transform-flow-steps.d.ts.map +1 -0
  342. package/dist/trace/transformer/transform-flow-steps.js +85 -0
  343. package/dist/trace/transformer/transform-flow-steps.js.map +1 -0
  344. package/dist/trace/transformer/wrap-function-declaration.d.ts +3 -0
  345. package/dist/trace/transformer/wrap-function-declaration.d.ts.map +1 -0
  346. package/dist/trace/transformer/wrap-function-declaration.js +28 -0
  347. package/dist/trace/transformer/wrap-function-declaration.js.map +1 -0
  348. package/dist/trace/transformer/wrap-variable-declaration.d.ts +3 -0
  349. package/dist/trace/transformer/wrap-variable-declaration.d.ts.map +1 -0
  350. package/dist/trace/transformer/wrap-variable-declaration.js +30 -0
  351. package/dist/trace/transformer/wrap-variable-declaration.js.map +1 -0
  352. package/dist/workspace/generate.d.ts.map +1 -1
  353. package/dist/workspace/generate.js +5 -8
  354. package/dist/workspace/generate.js.map +1 -1
  355. package/package.json +21 -6
@@ -0,0 +1,14 @@
1
+ import { type AstNode } from './flow-step-site.js';
2
+ export type IoKind = 'read' | 'write';
3
+ /**
4
+ * Classify `call` against the stock I/O registry and the optional consumer
5
+ * `extras` registry, or return `null` if the call is not I/O. `extras` is the
6
+ * `Record` shape `config.trace.io` resolves to — keys are lexical patterns
7
+ * (`"fetch"` or `"cache.get"`), values are `'read' | 'write'`.
8
+ *
9
+ * `call` must be a `CallExpression`; callers walk the AST and hand each one
10
+ * over. This function is pure over the node — no parent lookups, no type
11
+ * resolution. Lexical match only.
12
+ */
13
+ export declare function classifyIo(call: AstNode, extras?: Readonly<Record<string, IoKind>>): IoKind | null;
14
+ //# sourceMappingURL=io-pattern.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io-pattern.d.ts","sourceRoot":"","sources":["../../../src/trace/check/io-pattern.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAE1D,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAIrC;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,OAAO,EACb,MAAM,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,GAC5C,MAAM,GAAG,IAAI,CASf"}
@@ -0,0 +1,113 @@
1
+ // The I/O call-target registry consumed by the Tier-2 coverage check. Given a
2
+ // `CallExpression`, classifies it as a read, a write, or not-I/O.
3
+ //
4
+ // Stock list (pipework-owned, lexical):
5
+ // - Writes: `pipe.insert / pipe.update / pipe.delete / pipe.upsert /
6
+ // pipe.bulkSet`. These are the locked write entrypoints from Q8; the
7
+ // raw-write lint rule (component 13) backs them up.
8
+ // - Reads: any call whose callee chains off `pipe(...)` — e.g.
9
+ // `pipe('db').execute(...)`, `pipe(name).select(...)`,
10
+ // `pipe('db').query.users.findMany(...)`. The `pipe(name)` accessor only
11
+ // exists to perform I/O, so any method called on its result counts.
12
+ //
13
+ // Consumer extension (Q9): cache, external HTTP, queue publishes — anything
14
+ // outside the stock list — is registered through `pipework.config.ts` under
15
+ // `trace.io`. The registry is a `Record<string, 'read' | 'write'>` where the
16
+ // key is a lexical call pattern: a bare identifier (`"fetch"`) matches an
17
+ // identifier callee; an `"object.method"` pattern matches a single-level
18
+ // member-access callee. The schema validator rejects anything more elaborate —
19
+ // type resolution is out of scope, lexical matching is the contract.
20
+ import { isNode } from './flow-step-site.js';
21
+ const PIPE_WRITE_METHODS = new Set(['insert', 'update', 'delete', 'upsert', 'bulkSet']);
22
+ /**
23
+ * Classify `call` against the stock I/O registry and the optional consumer
24
+ * `extras` registry, or return `null` if the call is not I/O. `extras` is the
25
+ * `Record` shape `config.trace.io` resolves to — keys are lexical patterns
26
+ * (`"fetch"` or `"cache.get"`), values are `'read' | 'write'`.
27
+ *
28
+ * `call` must be a `CallExpression`; callers walk the AST and hand each one
29
+ * over. This function is pure over the node — no parent lookups, no type
30
+ * resolution. Lexical match only.
31
+ */
32
+ export function classifyIo(call, extras = {}) {
33
+ if (call.type !== 'CallExpression')
34
+ return null;
35
+ const callee = call['callee'];
36
+ if (!isNode(callee))
37
+ return null;
38
+ if (isPipeWriteCallee(callee))
39
+ return 'write';
40
+ if (chainsOffPipeAccessor(callee))
41
+ return 'read';
42
+ return matchExtras(callee, extras);
43
+ }
44
+ /** `pipe.<verb>` where `<verb>` is one of the locked write entrypoints. */
45
+ function isPipeWriteCallee(callee) {
46
+ if (callee.type !== 'MemberExpression')
47
+ return false;
48
+ if (callee['computed'] === true)
49
+ return false;
50
+ const object = callee['object'];
51
+ const property = callee['property'];
52
+ if (!isNode(object) || object.type !== 'Identifier' || object['name'] !== 'pipe')
53
+ return false;
54
+ if (!isNode(property) || property.type !== 'Identifier')
55
+ return false;
56
+ const name = property['name'];
57
+ return typeof name === 'string' && PIPE_WRITE_METHODS.has(name);
58
+ }
59
+ /**
60
+ * The callee is a chain off `pipe(...)` — anywhere up the member-expression
61
+ * spine. `pipe('db').execute(sql)` matches; `pipe('db').query.users.findMany()`
62
+ * matches; `pipe.update(t)` (no call on `pipe`) does not.
63
+ */
64
+ function chainsOffPipeAccessor(callee) {
65
+ let cursor = callee;
66
+ while (cursor.type === 'MemberExpression') {
67
+ const object = cursor['object'];
68
+ if (!isNode(object))
69
+ return false;
70
+ if (isPipeInvocation(object))
71
+ return true;
72
+ cursor = object;
73
+ }
74
+ return false;
75
+ }
76
+ /** `pipe(...)` — a call expression whose callee is the identifier `pipe`. */
77
+ function isPipeInvocation(node) {
78
+ if (node.type !== 'CallExpression')
79
+ return false;
80
+ const callee = node['callee'];
81
+ return isNode(callee) && callee.type === 'Identifier' && callee['name'] === 'pipe';
82
+ }
83
+ /**
84
+ * Looks up `callee` against the consumer registry. Two shapes match:
85
+ * - Identifier `foo` → key `"foo"`
86
+ * - Non-computed MemberExpression `obj.method` (Identifier object,
87
+ * Identifier property) → key `"obj.method"`
88
+ * Anything else falls through (returns `null`) — the stock registry has
89
+ * already exited above, so this is the not-I/O bucket.
90
+ */
91
+ function matchExtras(callee, extras) {
92
+ if (callee.type === 'Identifier') {
93
+ const name = callee['name'];
94
+ if (typeof name !== 'string')
95
+ return null;
96
+ return extras[name] ?? null;
97
+ }
98
+ if (callee.type === 'MemberExpression' && callee['computed'] !== true) {
99
+ const object = callee['object'];
100
+ const property = callee['property'];
101
+ if (!isNode(object) || object.type !== 'Identifier')
102
+ return null;
103
+ if (!isNode(property) || property.type !== 'Identifier')
104
+ return null;
105
+ const objectName = object['name'];
106
+ const propertyName = property['name'];
107
+ if (typeof objectName !== 'string' || typeof propertyName !== 'string')
108
+ return null;
109
+ return extras[`${objectName}.${propertyName}`] ?? null;
110
+ }
111
+ return null;
112
+ }
113
+ //# sourceMappingURL=io-pattern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io-pattern.js","sourceRoot":"","sources":["../../../src/trace/check/io-pattern.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ export interface CardinalityFill {
2
+ /** 1-based file line of the `@downstream` tag the codemod filled. */
3
+ readonly line: number;
4
+ /** `path:symbol` target of the edge that received a cardinality. */
5
+ readonly target: string;
6
+ /** The cardinality that was appended. */
7
+ readonly kind: 'step' | 'branch';
8
+ }
9
+ export interface UnresolvedEdge {
10
+ /** 1-based file line of the `@downstream` tag the codemod left untouched. */
11
+ readonly line: number;
12
+ /** `path:symbol` target the codemod could not fill. */
13
+ readonly target: string;
14
+ /**
15
+ * - `ambiguous` — analyzer could not classify the edge; needs a human.
16
+ * - `non-trivial-form` — the `@downstream` declaration spans lines or
17
+ * carries trailing text the codemod won't blindly rewrite.
18
+ */
19
+ readonly reason: 'ambiguous' | 'non-trivial-form';
20
+ }
21
+ export interface RewriteResult {
22
+ /** The rewritten source — strictly equal to the input when nothing changed. */
23
+ readonly text: string;
24
+ /** Every edge whose cardinality the codemod filled in. */
25
+ readonly fills: readonly CardinalityFill[];
26
+ /** Every edge the codemod left untouched but a human still needs to address. */
27
+ readonly unresolved: readonly UnresolvedEdge[];
28
+ }
29
+ /**
30
+ * Walks `source` for `@flow_step` sites, classifies each `@downstream` edge
31
+ * whose cardinality is missing, and returns the rewritten text plus a record
32
+ * of what was filled and what remains for the user.
33
+ *
34
+ * `source` must be parseable TypeScript. Files whose parse fails are the
35
+ * caller's concern — the codemod surfaces `collectFlowStepSites`'s throw.
36
+ */
37
+ export declare function rewriteFlowCardinality(source: string): RewriteResult;
38
+ //# sourceMappingURL=add-cardinality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-cardinality.d.ts","sourceRoot":"","sources":["../../../src/trace/codemod/add-cardinality.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAA;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,kBAAkB,CAAA;CAClD;AAED,MAAM,WAAW,aAAa;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAA;IAC1C,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAA;CAC/C;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAoBpE"}
@@ -0,0 +1,106 @@
1
+ // The cardinality codemod (component 4). For every `@downstream path:symbol`
2
+ // JSDoc line that omits its cardinality, classify the edge structurally and
3
+ // append `step` or `branch`. Edges the analyzer cannot classify (indirection)
4
+ // and edges declared on non-trivial textual forms (continuation lines) are
5
+ // left untouched and reported as `unresolved` for the user to address by hand.
6
+ //
7
+ // Scope is deliberately narrow: the codemod only *fills blanks*. It never
8
+ // rewrites an existing cardinality, never touches a method flow step (those
9
+ // are banned by the `flow` check), and never re-flows the surrounding JSDoc.
10
+ // Minimal churn — one token per line, in place.
11
+ import { collectFlowStepSites } from '../check/flow-step-site.js';
12
+ import { classifyEdge } from '../cardinality/classify-edge.js';
13
+ /**
14
+ * Walks `source` for `@flow_step` sites, classifies each `@downstream` edge
15
+ * whose cardinality is missing, and returns the rewritten text plus a record
16
+ * of what was filled and what remains for the user.
17
+ *
18
+ * `source` must be parseable TypeScript. Files whose parse fails are the
19
+ * caller's concern — the codemod surfaces `collectFlowStepSites`'s throw.
20
+ */
21
+ export function rewriteFlowCardinality(source) {
22
+ const sites = collectFlowStepSites(source);
23
+ if (sites.length === 0) {
24
+ return { text: source, fills: [], unresolved: [] };
25
+ }
26
+ const lineEnding = detectLineEnding(source);
27
+ const lines = source.split(/\r?\n/);
28
+ const replacements = new Map();
29
+ const fills = [];
30
+ const unresolved = [];
31
+ for (const site of sites) {
32
+ processSite(site, lines, replacements, fills, unresolved);
33
+ }
34
+ if (replacements.size === 0)
35
+ return { text: source, fills: [], unresolved };
36
+ const rewritten = lines.map((line, i) => replacements.get(i) ?? line);
37
+ return { text: rewritten.join(lineEnding), fills, unresolved };
38
+ }
39
+ function processSite(site, lines, replacements, fills, unresolved) {
40
+ // The `flow` check rejects invalid annotations, method shapes, and orphans
41
+ // as their own diagnostics — fixing them is the user's job. The codemod's
42
+ // only job is to fill missing cardinality on legal flow-step functions.
43
+ if (site.annotation.kind !== 'annotation')
44
+ return;
45
+ if (site.subject.shape !== 'function')
46
+ return;
47
+ const edges = site.annotation.annotation.downstream;
48
+ if (edges.length === 0)
49
+ return;
50
+ const blockStart = site.commentLine - 1;
51
+ const blockEnd = findBlockEnd(lines, blockStart);
52
+ // The parser produces one `DownstreamEdge` per `@downstream` tag in source
53
+ // order; scanning the JSDoc lines in the same order keeps the two streams
54
+ // aligned, so the Nth `@downstream` line corresponds to `edges[N]`.
55
+ let edgeIndex = -1;
56
+ for (let i = blockStart; i <= blockEnd; i++) {
57
+ const raw = lines[i];
58
+ if (raw === undefined)
59
+ continue;
60
+ if (!isDownstreamLine(raw))
61
+ continue;
62
+ edgeIndex++;
63
+ const edge = edges[edgeIndex];
64
+ if (edge === undefined)
65
+ continue;
66
+ if (edge.cardinality !== null)
67
+ continue;
68
+ const target = `${edge.path}:${edge.symbol}`;
69
+ const match = BARE_DOWNSTREAM.exec(raw);
70
+ if (match === null) {
71
+ unresolved.push({ line: i + 1, target, reason: 'non-trivial-form' });
72
+ continue;
73
+ }
74
+ const classification = classifyEdge('', site, edge);
75
+ if (classification.structural === 'ambiguous') {
76
+ unresolved.push({ line: i + 1, target, reason: 'ambiguous' });
77
+ continue;
78
+ }
79
+ const prefix = match[1] ?? '';
80
+ const targetText = match[2] ?? '';
81
+ replacements.set(i, `${prefix}${targetText} ${classification.structural}`);
82
+ fills.push({ line: i + 1, target, kind: classification.structural });
83
+ }
84
+ }
85
+ function findBlockEnd(lines, start) {
86
+ for (let i = start; i < lines.length; i++) {
87
+ if ((lines[i] ?? '').includes('*/'))
88
+ return i;
89
+ }
90
+ return lines.length - 1;
91
+ }
92
+ function detectLineEnding(source) {
93
+ return source.includes('\r\n') ? '\r\n' : '\n';
94
+ }
95
+ // Matches `@downstream path:symbol` on a line by itself (with optional JSDoc
96
+ // leader and trailing whitespace). The capture groups preserve the prefix and
97
+ // the target verbatim so the rebuilt line differs from the original only by a
98
+ // trailing ` step` or ` branch`.
99
+ const BARE_DOWNSTREAM = /^(\s*\*?\s*@downstream\s+)(\S+:\S+)\s*$/;
100
+ // A weaker match used only to count `@downstream` lines so the codemod's
101
+ // scanner stays aligned with the parser's edge ordering.
102
+ const DOWNSTREAM_TAG = /^\s*\*?\s*@downstream\b/;
103
+ function isDownstreamLine(text) {
104
+ return DOWNSTREAM_TAG.test(text);
105
+ }
106
+ //# sourceMappingURL=add-cardinality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-cardinality.js","sourceRoot":"","sources":["../../../src/trace/codemod/add-cardinality.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;AAC9E,2EAA2E;AAC3E,+EAA+E;AAC/E,EAAE;AACF,0EAA0E;AAC1E,4EAA4E;AAC5E,6EAA6E;AAC7E,gDAAgD;AAEhD,OAAO,EAAE,oBAAoB,EAAqB,MAAM,4BAA4B,CAAA;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAiC9D;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,MAAM,KAAK,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAA;IAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAA;IACpD,CAAC;IAED,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC9C,MAAM,KAAK,GAAsB,EAAE,CAAA;IACnC,MAAM,UAAU,GAAqB,EAAE,CAAA;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,CAAC,CAAA;IAC3D,CAAC;IAED,IAAI,YAAY,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAA;IAE3E,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAA;IACrE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;AAChE,CAAC;AAED,SAAS,WAAW,CAClB,IAAkB,EAClB,KAAwB,EACxB,YAAiC,EACjC,KAAwB,EACxB,UAA4B;IAE5B,2EAA2E;IAC3E,0EAA0E;IAC1E,wEAAwE;IACxE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,YAAY;QAAE,OAAM;IACjD,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU;QAAE,OAAM;IAE7C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAA;IACnD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAE9B,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;IACvC,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IAEhD,2EAA2E;IAC3E,0EAA0E;IAC1E,oEAAoE;IACpE,IAAI,SAAS,GAAG,CAAC,CAAC,CAAA;IAClB,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACpB,IAAI,GAAG,KAAK,SAAS;YAAE,SAAQ;QAC/B,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;YAAE,SAAQ;QACpC,SAAS,EAAE,CAAA;QAEX,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAA;QAC7B,IAAI,IAAI,KAAK,SAAS;YAAE,SAAQ;QAChC,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI;YAAE,SAAQ;QAEvC,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAA;QAC5C,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAA;YACpE,SAAQ;QACV,CAAC;QAED,MAAM,cAAc,GAAG,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QACnD,IAAI,cAAc,CAAC,UAAU,KAAK,WAAW,EAAE,CAAC;YAC9C,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAA;YAC7D,SAAQ;QACV,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAC7B,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QACjC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,GAAG,UAAU,IAAI,cAAc,CAAC,UAAU,EAAE,CAAC,CAAA;QAC1E,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,CAAA;IACtE,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAwB,EAAE,KAAa;IAC3D,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAA;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;AACzB,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAc;IACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;AAChD,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,iCAAiC;AACjC,MAAM,eAAe,GAAG,yCAAyC,CAAA;AAEjE,yEAAyE;AACzE,yDAAyD;AACzD,MAAM,cAAc,GAAG,yBAAyB,CAAA;AAEhD,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAClC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type CardinalityFill, type UnresolvedEdge } from './add-cardinality.js';
2
+ export interface CodemodRunOptions {
3
+ readonly cwd: string;
4
+ readonly files: readonly string[];
5
+ /** When true, compute everything but do not write to disk. */
6
+ readonly dryRun: boolean;
7
+ }
8
+ export interface FileResult {
9
+ /** Source path relative to `cwd`. */
10
+ readonly file: string;
11
+ readonly fills: readonly CardinalityFill[];
12
+ readonly unresolved: readonly UnresolvedEdge[];
13
+ /** True when the codemod produced a different text than the input. */
14
+ readonly changed: boolean;
15
+ }
16
+ export interface CodemodRunResult {
17
+ /** One entry per file that had at least one fill or unresolved edge. */
18
+ readonly files: readonly FileResult[];
19
+ readonly totalFills: number;
20
+ readonly totalUnresolved: number;
21
+ readonly filesChanged: number;
22
+ }
23
+ /** Runs the cardinality codemod across `files`. Missing or unparseable files are skipped. */
24
+ export declare function runFlowCardinalityCodemod(opts: CodemodRunOptions): CodemodRunResult;
25
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/trace/codemod/run.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAA;AAE7B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAA;IAC1C,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAA;IAC9C,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAA;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAC9B;AAED,6FAA6F;AAC7F,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,CAwCnF"}
@@ -0,0 +1,47 @@
1
+ // File-scanning wrapper around the cardinality codemod: reads each source
2
+ // file, applies `rewriteFlowCardinality`, and writes the result back unless
3
+ // `dryRun` is set. Mirrors `flow-check.ts`'s shape — file I/O lives here, the
4
+ // rewrite logic stays pure in add-cardinality.ts.
5
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { rewriteFlowCardinality, } from './add-cardinality.js';
8
+ /** Runs the cardinality codemod across `files`. Missing or unparseable files are skipped. */
9
+ export function runFlowCardinalityCodemod(opts) {
10
+ const fileResults = [];
11
+ let totalFills = 0;
12
+ let totalUnresolved = 0;
13
+ let filesChanged = 0;
14
+ for (const file of opts.files) {
15
+ const abs = join(opts.cwd, file);
16
+ if (!existsSync(abs))
17
+ continue;
18
+ const source = readFileSync(abs, 'utf-8');
19
+ let rewrite;
20
+ try {
21
+ rewrite = rewriteFlowCardinality(source);
22
+ }
23
+ catch {
24
+ // A file the AST parser cannot read — leave its syntax errors to the
25
+ // type checker, exactly as `flow-check.ts` does.
26
+ continue;
27
+ }
28
+ if (rewrite.fills.length === 0 && rewrite.unresolved.length === 0)
29
+ continue;
30
+ const changed = rewrite.text !== source;
31
+ if (changed && !opts.dryRun) {
32
+ writeFileSync(abs, rewrite.text, 'utf-8');
33
+ }
34
+ fileResults.push({
35
+ file,
36
+ fills: rewrite.fills,
37
+ unresolved: rewrite.unresolved,
38
+ changed,
39
+ });
40
+ totalFills += rewrite.fills.length;
41
+ totalUnresolved += rewrite.unresolved.length;
42
+ if (changed)
43
+ filesChanged++;
44
+ }
45
+ return { files: fileResults, totalFills, totalUnresolved, filesChanged };
46
+ }
47
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/trace/codemod/run.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,8EAA8E;AAC9E,kDAAkD;AAElD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EACL,sBAAsB,GAGvB,MAAM,sBAAsB,CAAA;AA0B7B,6FAA6F;AAC7F,MAAM,UAAU,yBAAyB,CAAC,IAAuB;IAC/D,MAAM,WAAW,GAAiB,EAAE,CAAA;IACpC,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,eAAe,GAAG,CAAC,CAAA;IACvB,IAAI,YAAY,GAAG,CAAC,CAAA;IAEpB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QAE9B,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAEzC,IAAI,OAAO,CAAA;QACX,IAAI,CAAC;YACH,OAAO,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAA;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,qEAAqE;YACrE,iDAAiD;YACjD,SAAQ;QACV,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,SAAQ;QAE3E,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAA;QACvC,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5B,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC3C,CAAC;QAED,WAAW,CAAC,IAAI,CAAC;YACf,IAAI;YACJ,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,OAAO;SACR,CAAC,CAAA;QACF,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAA;QAClC,eAAe,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAA;QAC5C,IAAI,OAAO;YAAE,YAAY,EAAE,CAAA;IAC7B,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,CAAA;AAC1E,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Manifold } from '../../core/pipework.js';
2
+ import type { TraceContext } from './trace-context.js';
3
+ /** How an entry ended — a clean return, or a thrown error. */
4
+ export type TraceOutcome = 'closed' | 'error';
5
+ /** Closes `ctx`'s trace row with `outcome` and flushes its step buffer. No-op when the entry ran untraced. */
6
+ export declare function closeTrace(instance: Manifold, ctx: TraceContext | null, outcome: TraceOutcome): Promise<void>;
7
+ //# sourceMappingURL=close-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close-trace.d.ts","sourceRoot":"","sources":["../../../src/trace/entry/close-trace.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAOtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,8DAA8D;AAC9D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE7C,8GAA8G;AAC9G,wBAAgB,UAAU,CACxB,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,YAAY,GAAG,IAAI,EACxB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAiCf"}
@@ -0,0 +1,54 @@
1
+ // Closes the `trace` row an entry opened: stamps the final status and the
2
+ // close time, and flushes the in-memory `trace_step` buffer in the same beat.
3
+ // Like the open, the write is fire-and-forget and never throws — but it first
4
+ // waits on `persisted`, so neither the closing `UPDATE` nor the step `INSERT`s
5
+ // can outrun the opening `INSERT` and miss the row.
6
+ //
7
+ // A truncated trace (Q7) keeps its `truncated` status here: `truncateTrace`
8
+ // already settled the cap-blowing path, and `closeTrace` running last must not
9
+ // downgrade a casualty to `closed` / `error`. The buffer drain is still safe —
10
+ // `truncateTrace` already drained it, and `__flowStep` records nothing after
11
+ // truncation, so `drain()` returns the empty array.
12
+ //
13
+ // The returned promise settles once the `UPDATE` and the step `INSERT` have —
14
+ // callers on the hot path ignore it (the close must not block the entry's
15
+ // response), but it gives a test a handle to await before asserting on rows.
16
+ import { getBaseLogger } from '../../core/logging/index.js';
17
+ import { eq, and, getTableColumns } from '../../data/query/index.js';
18
+ import { trace } from '../schema/trace.js';
19
+ import { flushSteps } from '../runtime/flush-steps.js';
20
+ import { copyTraceOnError } from '../retain/copy-on-error.js';
21
+ /** Closes `ctx`'s trace row with `outcome` and flushes its step buffer. No-op when the entry ran untraced. */
22
+ export function closeTrace(instance, ctx, outcome) {
23
+ if (ctx === null)
24
+ return Promise.resolve();
25
+ const closedAt = new Date();
26
+ return ctx.persisted
27
+ .then(async () => {
28
+ const status = ctx.buffer.truncated ? 'truncated' : outcome;
29
+ const stepFlush = flushSteps(instance, ctx.buffer.drain());
30
+ const db = instance.pool.getOrCreate(instance.config.database()).drizzle;
31
+ const table = trace.table();
32
+ // The composite primary key is `[id, openedDay]` — both are matched so the
33
+ // UPDATE targets exactly one partition's one row.
34
+ const cols = getTableColumns(table);
35
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Drizzle's update needs the concrete runtime table type
36
+ const traceUpdate = db.update(table)
37
+ .set({ status, closedAt })
38
+ .where(and(eq(cols.id, ctx.id), eq(cols.openedDay, ctx.openedDay)));
39
+ await Promise.all([stepFlush, traceUpdate]);
40
+ // Copy errored / truncated traces to the cold set before their hot
41
+ // partition retires (Q4). For a truncated trace, `truncationDone` is the
42
+ // settle handle from `truncateTrace`; awaiting it ensures the cold row
43
+ // reflects `truncated_at_seq`. For a normal error close the handle is
44
+ // `null`, and `await null` is a no-op — no branch needed.
45
+ if (status !== 'closed') {
46
+ await ctx.buffer.truncationDone;
47
+ await copyTraceOnError(db, ctx.id);
48
+ }
49
+ })
50
+ .catch((err) => {
51
+ getBaseLogger().error({ err, traceId: ctx.id }, 'Failed to persist trace close — the trace row is stuck open');
52
+ });
53
+ }
54
+ //# sourceMappingURL=close-trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"close-trace.js","sourceRoot":"","sources":["../../../src/trace/entry/close-trace.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,8EAA8E;AAC9E,8EAA8E;AAC9E,+EAA+E;AAC/E,oDAAoD;AACpD,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,+EAA+E;AAC/E,6EAA6E;AAC7E,oDAAoD;AACpD,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,6EAA6E;AAG7E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEpE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAM7D,8GAA8G;AAC9G,MAAM,UAAU,UAAU,CACxB,QAAkB,EAClB,GAAwB,EACxB,OAAqB;IAErB,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC1C,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAA;IAC3B,OAAO,GAAG,CAAC,SAAS;SACjB,IAAI,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,MAAM,GAAqC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAA;QAC7F,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;QAC1D,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAA;QACxE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAA;QAC3B,2EAA2E;QAC3E,kDAAkD;QAClD,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAuC,CAAA;QACzE,wHAAwH;QACxH,MAAM,WAAW,GAAI,EAAU,CAAC,MAAM,CAAC,KAAK,CAAC;aAC1C,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;aACzB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;QACrE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAA;QAC3C,mEAAmE;QACnE,yEAAyE;QACzE,uEAAuE;QACvE,sEAAsE;QACtE,0DAA0D;QAC1D,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,MAAM,GAAG,CAAC,MAAM,CAAC,cAAc,CAAA;YAC/B,MAAM,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QACpC,CAAC;IACH,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACtB,aAAa,EAAE,CAAC,KAAK,CACnB,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,EACxB,6DAA6D,CAC9D,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Manifold } from '../../core/pipework.js';
2
+ import type { TraceContext } from './trace-context.js';
3
+ /** Wraps `result`, closing `ctx`'s trace when it settles. Returns `result` unchanged. */
4
+ export declare function finalizeTrace<T>(instance: Manifold, ctx: TraceContext | null, result: T): T;
5
+ //# sourceMappingURL=finalize-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalize-trace.d.ts","sourceRoot":"","sources":["../../../src/trace/entry/finalize-trace.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAGtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,YAAY,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAgB3F"}
@@ -0,0 +1,23 @@
1
+ // Ties a trace's close to the settling of the entry's work: `closed` on a
2
+ // clean return, `error` on a throw. An entry's work may be synchronous or a
3
+ // promise — this handles both and hands the result straight back, so an
4
+ // ingress can wrap its return value inline without restructuring.
5
+ import { closeTrace } from './close-trace.js';
6
+ import { isThenable } from '../runtime/thenable.js';
7
+ /** Wraps `result`, closing `ctx`'s trace when it settles. Returns `result` unchanged. */
8
+ export function finalizeTrace(instance, ctx, result) {
9
+ if (ctx === null)
10
+ return result;
11
+ if (isThenable(result)) {
12
+ return result.then((value) => {
13
+ void closeTrace(instance, ctx, 'closed');
14
+ return value;
15
+ }, (err) => {
16
+ void closeTrace(instance, ctx, 'error');
17
+ throw err;
18
+ });
19
+ }
20
+ void closeTrace(instance, ctx, 'closed');
21
+ return result;
22
+ }
23
+ //# sourceMappingURL=finalize-trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalize-trace.js","sourceRoot":"","sources":["../../../src/trace/entry/finalize-trace.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,wEAAwE;AACxE,kEAAkE;AAGlE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAGnD,yFAAyF;AACzF,MAAM,UAAU,aAAa,CAAI,QAAkB,EAAE,GAAwB,EAAE,MAAS;IACtF,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,MAAM,CAAA;IAC/B,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,OAAO,MAAM,CAAC,IAAI,CAChB,CAAC,KAAc,EAAE,EAAE;YACjB,KAAK,UAAU,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;YACxC,OAAO,KAAK,CAAA;QACd,CAAC,EACD,CAAC,GAAY,EAAE,EAAE;YACf,KAAK,UAAU,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;YACvC,MAAM,GAAG,CAAA;QACX,CAAC,CACG,CAAA;IACR,CAAC;IACD,KAAK,UAAU,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;IACxC,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { Manifold } from '../../core/pipework.js';
2
+ import type { TraceContext, TraceEntryKind } from './trace-context.js';
3
+ /**
4
+ * The parent reference openTrace actually consumes. Two shapes satisfy it:
5
+ * an in-process `TraceContext` (the active trace on the surrounding Flow) and
6
+ * a synthesized `{ id, rootId }` derived from an ingested W3C `traceparent`
7
+ * header. Either way, only the two fields are needed to wire the trace tree.
8
+ */
9
+ export interface ParentTraceRef {
10
+ readonly id: string;
11
+ readonly rootId: string;
12
+ }
13
+ export interface OpenTraceParams {
14
+ readonly instance: Manifold;
15
+ readonly entryKind: TraceEntryKind;
16
+ /** The parent trace, or `null` for a root entry. */
17
+ readonly parent: ParentTraceRef | null;
18
+ readonly tenant: string | null;
19
+ /** The entry's auth principal — `userId` is read off it when present. */
20
+ readonly auth: unknown;
21
+ readonly requestId: string | null;
22
+ readonly sessionId: string | null;
23
+ }
24
+ /** Generates a trace id, wires it into the tree, and kicks off the opening `INSERT`. */
25
+ export declare function openTrace(params: OpenTraceParams): TraceContext;
26
+ //# sourceMappingURL=open-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-trace.d.ts","sourceRoot":"","sources":["../../../src/trace/entry/open-trace.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAKtD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAItE;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;IAClC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,YAAY,CA6C/D"}
@@ -0,0 +1,75 @@
1
+ // Opens the `trace` row for an entry. The row is written eagerly — a trace
2
+ // exists the moment an entry is reached — but the write itself is fire-and-
3
+ // forget: the id and the tree wiring are computed synchronously, so the entry
4
+ // pays no latency, and the `INSERT` runs in the background. Failure to persist
5
+ // is logged, never thrown: a broken trace table must not break the request.
6
+ //
7
+ // The write goes through `instance.pool` directly, not the request transaction
8
+ // — an errored request rolls back, but its trace must survive to be inspected.
9
+ import { randomUUID } from 'node:crypto';
10
+ import { getBaseLogger } from '../../core/logging/index.js';
11
+ import { trace } from '../schema/trace.js';
12
+ import { toDay } from '../partition/day.js';
13
+ import { StepBuffer } from '../runtime/step-buffer.js';
14
+ const MS_PER_DAY = 86_400_000;
15
+ /** Generates a trace id, wires it into the tree, and kicks off the opening `INSERT`. */
16
+ export function openTrace(params) {
17
+ const id = randomUUID();
18
+ const openedAt = new Date();
19
+ const openedDay = toDay(openedAt);
20
+ const rootId = params.parent?.rootId ?? id;
21
+ const expiresAt = new Date(openedAt.getTime() + params.instance.config.trace.hotRetentionDays * MS_PER_DAY);
22
+ const persisted = insertTraceRow(params.instance, {
23
+ id,
24
+ openedDay,
25
+ rootId,
26
+ parentId: params.parent?.id ?? null,
27
+ parentStepId: null,
28
+ entryKind: params.entryKind,
29
+ status: 'open',
30
+ tenantId: params.tenant,
31
+ requestId: params.requestId,
32
+ sessionId: params.sessionId,
33
+ userId: extractUserId(params.auth),
34
+ openedAt,
35
+ closedAt: null,
36
+ expiresAt,
37
+ truncatedAtSeq: null,
38
+ });
39
+ // The step cap is `structuralMax × safetyFactor` (Q7). `structuralMax` is the
40
+ // longest chain of `step` edges through the flow graph, derived by
41
+ // `pipework check` from the `@downstream` annotations and pinned in
42
+ // `config.trace.structuralMax`. Unset → no cap; the truncation mechanism is
43
+ // live but never fires. The cap firing is a bug signal — DAG analysis was
44
+ // wrong, or unannotated recursion slipped validation — not a load condition.
45
+ const traceConfig = params.instance.config.trace;
46
+ const cap = traceConfig.structuralMax !== undefined
47
+ ? traceConfig.structuralMax * traceConfig.safetyFactor
48
+ : Infinity;
49
+ const buffer = new StepBuffer({
50
+ traceId: id,
51
+ traceDay: openedDay,
52
+ cap,
53
+ captureInputs: traceConfig.captureInputs,
54
+ });
55
+ return { id, rootId, openedDay, persisted, buffer };
56
+ }
57
+ function insertTraceRow(instance, row) {
58
+ const db = instance.pool.getOrCreate(instance.config.database()).drizzle;
59
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Drizzle's insert needs the concrete runtime table type
60
+ return db.insert(trace.table()).values(row)
61
+ .then(() => undefined)
62
+ .catch((err) => {
63
+ getBaseLogger().error({ err, traceId: row.id }, 'Failed to persist trace open — the trace row is missing');
64
+ });
65
+ }
66
+ /** Reads `userId` off the auth principal, following the same convention the logger uses. */
67
+ function extractUserId(auth) {
68
+ if (auth !== null && typeof auth === 'object' && 'userId' in auth) {
69
+ const userId = auth.userId;
70
+ if (typeof userId === 'string')
71
+ return userId;
72
+ }
73
+ return null;
74
+ }
75
+ //# sourceMappingURL=open-trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-trace.js","sourceRoot":"","sources":["../../../src/trace/entry/open-trace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { TraceContext } from './trace-context.js';
2
+ /** The trace on the active Flow, or `null` when there is none — the new entry's parent. */
3
+ export declare function parentTrace(): TraceContext | null;
4
+ //# sourceMappingURL=parent-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-trace.d.ts","sourceRoot":"","sources":["../../../src/trace/entry/parent-trace.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,2FAA2F;AAC3F,wBAAgB,WAAW,IAAI,YAAY,GAAG,IAAI,CAEjD"}
@@ -0,0 +1,10 @@
1
+ // Traces form a tree. A new entry's parent is the trace already running on the
2
+ // active Flow — a job enqueued and awaited inside a request, a nested test
3
+ // context. With no active Flow (the common case for an inbound HTTP request or
4
+ // a worker-claimed job), the new entry is a root.
5
+ import { getContext } from '../../request/context/store.js';
6
+ /** The trace on the active Flow, or `null` when there is none — the new entry's parent. */
7
+ export function parentTrace() {
8
+ return getContext()?.trace ?? null;
9
+ }
10
+ //# sourceMappingURL=parent-trace.js.map