@smoothbricks/lmao 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/README.md +269 -0
  2. package/dist/allocator.wasm +0 -0
  3. package/dist/bun/preload.d.ts +11 -0
  4. package/dist/bun/preload.d.ts.map +1 -0
  5. package/dist/bun/preload.js +10 -0
  6. package/dist/bun/trace-preload.d.ts +8 -0
  7. package/dist/bun/trace-preload.d.ts.map +1 -0
  8. package/dist/bun/trace-preload.js +12 -0
  9. package/dist/es.d.ts +8 -0
  10. package/dist/es.d.ts.map +1 -0
  11. package/dist/es.js +9 -0
  12. package/dist/index.d.ts +41 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +84 -0
  15. package/dist/lib/JsBufferStrategy.d.ts +49 -0
  16. package/dist/lib/JsBufferStrategy.d.ts.map +1 -0
  17. package/dist/lib/JsBufferStrategy.js +60 -0
  18. package/dist/lib/archive/chunkCompaction.d.ts +15 -0
  19. package/dist/lib/archive/chunkCompaction.d.ts.map +1 -0
  20. package/dist/lib/archive/chunkCompaction.js +24 -0
  21. package/dist/lib/archive/chunkEnvelope.d.ts +21 -0
  22. package/dist/lib/archive/chunkEnvelope.d.ts.map +1 -0
  23. package/dist/lib/archive/chunkEnvelope.js +55 -0
  24. package/dist/lib/archive/chunkRouting.d.ts +10 -0
  25. package/dist/lib/archive/chunkRouting.d.ts.map +1 -0
  26. package/dist/lib/archive/chunkRouting.js +47 -0
  27. package/dist/lib/archive/chunkStats.d.ts +12 -0
  28. package/dist/lib/archive/chunkStats.d.ts.map +1 -0
  29. package/dist/lib/archive/chunkStats.js +10 -0
  30. package/dist/lib/archive/index.d.ts +5 -0
  31. package/dist/lib/archive/index.d.ts.map +1 -0
  32. package/dist/lib/archive/index.js +4 -0
  33. package/dist/lib/arrow/capacityStats.d.ts +9 -0
  34. package/dist/lib/arrow/capacityStats.d.ts.map +1 -0
  35. package/dist/lib/arrow/capacityStats.js +231 -0
  36. package/dist/lib/arrow/dictionaries.d.ts +27 -0
  37. package/dist/lib/arrow/dictionaries.d.ts.map +1 -0
  38. package/dist/lib/arrow/dictionaries.js +135 -0
  39. package/dist/lib/arrow/flechette.d.ts +40 -0
  40. package/dist/lib/arrow/flechette.d.ts.map +1 -0
  41. package/dist/lib/arrow/flechette.js +67 -0
  42. package/dist/lib/arrow/utils.d.ts +38 -0
  43. package/dist/lib/arrow/utils.d.ts.map +1 -0
  44. package/dist/lib/arrow/utils.js +112 -0
  45. package/dist/lib/buffer/Nanoseconds.d.ts +109 -0
  46. package/dist/lib/buffer/Nanoseconds.d.ts.map +1 -0
  47. package/dist/lib/buffer/Nanoseconds.js +86 -0
  48. package/dist/lib/bufferStrategy.d.ts +95 -0
  49. package/dist/lib/bufferStrategy.d.ts.map +1 -0
  50. package/dist/lib/bufferStrategy.js +1 -0
  51. package/dist/lib/capacityTuning.d.ts +50 -0
  52. package/dist/lib/capacityTuning.d.ts.map +1 -0
  53. package/dist/lib/capacityTuning.js +65 -0
  54. package/dist/lib/codegen/evaluatorGenerator.d.ts +35 -0
  55. package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -0
  56. package/dist/lib/codegen/evaluatorGenerator.js +199 -0
  57. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +139 -0
  58. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -0
  59. package/dist/lib/codegen/fixedPositionWriterGenerator.js +289 -0
  60. package/dist/lib/codegen/spanLoggerGenerator.d.ts +115 -0
  61. package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -0
  62. package/dist/lib/codegen/spanLoggerGenerator.js +575 -0
  63. package/dist/lib/convertToArrow.d.ts +40 -0
  64. package/dist/lib/convertToArrow.d.ts.map +1 -0
  65. package/dist/lib/convertToArrow.js +1467 -0
  66. package/dist/lib/defineOpContext.d.ts +96 -0
  67. package/dist/lib/defineOpContext.d.ts.map +1 -0
  68. package/dist/lib/defineOpContext.js +227 -0
  69. package/dist/lib/errors/Blocked.d.ts +113 -0
  70. package/dist/lib/errors/Blocked.d.ts.map +1 -0
  71. package/dist/lib/errors/Blocked.js +68 -0
  72. package/dist/lib/errors/CodeError.d.ts +101 -0
  73. package/dist/lib/errors/CodeError.d.ts.map +1 -0
  74. package/dist/lib/errors/CodeError.js +42 -0
  75. package/dist/lib/errors/RetriesExhausted.d.ts +67 -0
  76. package/dist/lib/errors/RetriesExhausted.d.ts.map +1 -0
  77. package/dist/lib/errors/RetriesExhausted.js +31 -0
  78. package/dist/lib/errors/Transient.d.ts +115 -0
  79. package/dist/lib/errors/Transient.d.ts.map +1 -0
  80. package/dist/lib/errors/Transient.js +54 -0
  81. package/dist/lib/errors/index.d.ts +14 -0
  82. package/dist/lib/errors/index.d.ts.map +1 -0
  83. package/dist/lib/errors/index.js +16 -0
  84. package/dist/lib/errors/retry-policy.d.ts +60 -0
  85. package/dist/lib/errors/retry-policy.d.ts.map +1 -0
  86. package/dist/lib/errors/retry-policy.js +54 -0
  87. package/dist/lib/flushScheduler.d.ts +162 -0
  88. package/dist/lib/flushScheduler.d.ts.map +1 -0
  89. package/dist/lib/flushScheduler.js +388 -0
  90. package/dist/lib/library.d.ts +149 -0
  91. package/dist/lib/library.d.ts.map +1 -0
  92. package/dist/lib/library.js +588 -0
  93. package/dist/lib/logApi.d.ts +61 -0
  94. package/dist/lib/logApi.d.ts.map +1 -0
  95. package/dist/lib/logApi.js +12 -0
  96. package/dist/lib/logBinding.d.ts +63 -0
  97. package/dist/lib/logBinding.d.ts.map +1 -0
  98. package/dist/lib/logBinding.js +1 -0
  99. package/dist/lib/op.d.ts +105 -0
  100. package/dist/lib/op.d.ts.map +1 -0
  101. package/dist/lib/op.js +59 -0
  102. package/dist/lib/opContext/contextTypes.d.ts +88 -0
  103. package/dist/lib/opContext/contextTypes.d.ts.map +1 -0
  104. package/dist/lib/opContext/contextTypes.js +34 -0
  105. package/dist/lib/opContext/createOpGroup.d.ts +57 -0
  106. package/dist/lib/opContext/createOpGroup.d.ts.map +1 -0
  107. package/dist/lib/opContext/createOpGroup.js +341 -0
  108. package/dist/lib/opContext/defineOp.d.ts +83 -0
  109. package/dist/lib/opContext/defineOp.d.ts.map +1 -0
  110. package/dist/lib/opContext/defineOp.js +197 -0
  111. package/dist/lib/opContext/featureFlagTypes.d.ts +58 -0
  112. package/dist/lib/opContext/featureFlagTypes.d.ts.map +1 -0
  113. package/dist/lib/opContext/featureFlagTypes.js +1 -0
  114. package/dist/lib/opContext/index.d.ts +13 -0
  115. package/dist/lib/opContext/index.d.ts.map +1 -0
  116. package/dist/lib/opContext/index.js +15 -0
  117. package/dist/lib/opContext/opGroupTypes.d.ts +250 -0
  118. package/dist/lib/opContext/opGroupTypes.d.ts.map +1 -0
  119. package/dist/lib/opContext/opGroupTypes.js +31 -0
  120. package/dist/lib/opContext/opTypes.d.ts +48 -0
  121. package/dist/lib/opContext/opTypes.d.ts.map +1 -0
  122. package/dist/lib/opContext/opTypes.js +7 -0
  123. package/dist/lib/opContext/spanContextTypes.d.ts +347 -0
  124. package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -0
  125. package/dist/lib/opContext/spanContextTypes.js +1 -0
  126. package/dist/lib/opContext/types.d.ts +297 -0
  127. package/dist/lib/opContext/types.d.ts.map +1 -0
  128. package/dist/lib/opContext/types.js +16 -0
  129. package/dist/lib/result.d.ts +308 -0
  130. package/dist/lib/result.d.ts.map +1 -0
  131. package/dist/lib/result.js +359 -0
  132. package/dist/lib/schema/LogSchema.d.ts +62 -0
  133. package/dist/lib/schema/LogSchema.d.ts.map +1 -0
  134. package/dist/lib/schema/LogSchema.js +134 -0
  135. package/dist/lib/schema/builder.d.ts +12 -0
  136. package/dist/lib/schema/builder.d.ts.map +1 -0
  137. package/dist/lib/schema/builder.js +169 -0
  138. package/dist/lib/schema/defineFeatureFlags.d.ts +60 -0
  139. package/dist/lib/schema/defineFeatureFlags.d.ts.map +1 -0
  140. package/dist/lib/schema/defineFeatureFlags.js +29 -0
  141. package/dist/lib/schema/defineLogSchema.d.ts +87 -0
  142. package/dist/lib/schema/defineLogSchema.d.ts.map +1 -0
  143. package/dist/lib/schema/defineLogSchema.js +171 -0
  144. package/dist/lib/schema/evaluator.d.ts +267 -0
  145. package/dist/lib/schema/evaluator.d.ts.map +1 -0
  146. package/dist/lib/schema/evaluator.js +169 -0
  147. package/dist/lib/schema/extend.d.ts +14 -0
  148. package/dist/lib/schema/extend.d.ts.map +1 -0
  149. package/dist/lib/schema/extend.js +51 -0
  150. package/dist/lib/schema/systemSchema.d.ts +112 -0
  151. package/dist/lib/schema/systemSchema.d.ts.map +1 -0
  152. package/dist/lib/schema/systemSchema.js +260 -0
  153. package/dist/lib/schema/typeGuards.d.ts +52 -0
  154. package/dist/lib/schema/typeGuards.d.ts.map +1 -0
  155. package/dist/lib/schema/typeGuards.js +127 -0
  156. package/dist/lib/schema/types.d.ts +156 -0
  157. package/dist/lib/schema/types.d.ts.map +1 -0
  158. package/dist/lib/schema/types.js +4 -0
  159. package/dist/lib/spanBuffer.d.ts +133 -0
  160. package/dist/lib/spanBuffer.d.ts.map +1 -0
  161. package/dist/lib/spanBuffer.js +442 -0
  162. package/dist/lib/spanBufferHelpers.d.ts +53 -0
  163. package/dist/lib/spanBufferHelpers.d.ts.map +1 -0
  164. package/dist/lib/spanBufferHelpers.js +65 -0
  165. package/dist/lib/spanBufferStats.d.ts +38 -0
  166. package/dist/lib/spanBufferStats.d.ts.map +1 -0
  167. package/dist/lib/spanBufferStats.js +1 -0
  168. package/dist/lib/spanContext.d.ts +141 -0
  169. package/dist/lib/spanContext.d.ts.map +1 -0
  170. package/dist/lib/spanContext.js +763 -0
  171. package/dist/lib/sqlite/index.d.ts +14 -0
  172. package/dist/lib/sqlite/index.d.ts.map +1 -0
  173. package/dist/lib/sqlite/index.js +12 -0
  174. package/dist/lib/sqlite/sqlite-async-writer.d.ts +24 -0
  175. package/dist/lib/sqlite/sqlite-async-writer.d.ts.map +1 -0
  176. package/dist/lib/sqlite/sqlite-async-writer.js +65 -0
  177. package/dist/lib/sqlite/sqlite-common.d.ts +37 -0
  178. package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -0
  179. package/dist/lib/sqlite/sqlite-common.js +207 -0
  180. package/dist/lib/sqlite/sqlite-d1.d.ts +25 -0
  181. package/dist/lib/sqlite/sqlite-d1.d.ts.map +1 -0
  182. package/dist/lib/sqlite/sqlite-d1.js +67 -0
  183. package/dist/lib/sqlite/sqlite-db.d.ts +29 -0
  184. package/dist/lib/sqlite/sqlite-db.d.ts.map +1 -0
  185. package/dist/lib/sqlite/sqlite-db.js +1 -0
  186. package/dist/lib/sqlite/sqlite-node.d.ts +16 -0
  187. package/dist/lib/sqlite/sqlite-node.d.ts.map +1 -0
  188. package/dist/lib/sqlite/sqlite-node.js +68 -0
  189. package/dist/lib/sqlite/sqlite-writer.d.ts +39 -0
  190. package/dist/lib/sqlite/sqlite-writer.d.ts.map +1 -0
  191. package/dist/lib/sqlite/sqlite-writer.js +78 -0
  192. package/dist/lib/testing/bun-harness.d.ts +150 -0
  193. package/dist/lib/testing/bun-harness.d.ts.map +1 -0
  194. package/dist/lib/testing/bun-harness.js +729 -0
  195. package/dist/lib/testing/extractFacts.d.ts +73 -0
  196. package/dist/lib/testing/extractFacts.d.ts.map +1 -0
  197. package/dist/lib/testing/extractFacts.js +237 -0
  198. package/dist/lib/testing/facts.d.ts +235 -0
  199. package/dist/lib/testing/facts.d.ts.map +1 -0
  200. package/dist/lib/testing/facts.js +209 -0
  201. package/dist/lib/testing/index.d.ts +58 -0
  202. package/dist/lib/testing/index.d.ts.map +1 -0
  203. package/dist/lib/testing/index.js +74 -0
  204. package/dist/lib/testing/queryable-span.d.ts +39 -0
  205. package/dist/lib/testing/queryable-span.d.ts.map +1 -0
  206. package/dist/lib/testing/queryable-span.js +58 -0
  207. package/dist/lib/testing/span-query.d.ts +21 -0
  208. package/dist/lib/testing/span-query.d.ts.map +1 -0
  209. package/dist/lib/testing/span-query.js +47 -0
  210. package/dist/lib/testing/stdio-replay.d.ts +4 -0
  211. package/dist/lib/testing/stdio-replay.d.ts.map +1 -0
  212. package/dist/lib/testing/stdio-replay.js +42 -0
  213. package/dist/lib/testing/trace-query.d.ts +59 -0
  214. package/dist/lib/testing/trace-query.d.ts.map +1 -0
  215. package/dist/lib/testing/trace-query.js +462 -0
  216. package/dist/lib/testing/vitest-harness.d.ts +135 -0
  217. package/dist/lib/testing/vitest-harness.d.ts.map +1 -0
  218. package/dist/lib/testing/vitest-harness.js +486 -0
  219. package/dist/lib/threadId.d.ts +58 -0
  220. package/dist/lib/threadId.d.ts.map +1 -0
  221. package/dist/lib/threadId.js +123 -0
  222. package/dist/lib/traceContext.d.ts +116 -0
  223. package/dist/lib/traceContext.d.ts.map +1 -0
  224. package/dist/lib/traceContext.js +37 -0
  225. package/dist/lib/traceId.d.ts +78 -0
  226. package/dist/lib/traceId.d.ts.map +1 -0
  227. package/dist/lib/traceId.js +87 -0
  228. package/dist/lib/traceRoot.d.ts +133 -0
  229. package/dist/lib/traceRoot.d.ts.map +1 -0
  230. package/dist/lib/traceRoot.es.d.ts +75 -0
  231. package/dist/lib/traceRoot.es.d.ts.map +1 -0
  232. package/dist/lib/traceRoot.es.js +129 -0
  233. package/dist/lib/traceRoot.js +19 -0
  234. package/dist/lib/traceRoot.node.d.ts +77 -0
  235. package/dist/lib/traceRoot.node.d.ts.map +1 -0
  236. package/dist/lib/traceRoot.node.js +133 -0
  237. package/dist/lib/traceRoot.universal.d.ts +3 -0
  238. package/dist/lib/traceRoot.universal.d.ts.map +1 -0
  239. package/dist/lib/traceRoot.universal.js +17 -0
  240. package/dist/lib/tracer.d.ts +296 -0
  241. package/dist/lib/tracer.d.ts.map +1 -0
  242. package/dist/lib/tracer.js +346 -0
  243. package/dist/lib/tracers/ArrayQueueTracer.d.ts +56 -0
  244. package/dist/lib/tracers/ArrayQueueTracer.d.ts.map +1 -0
  245. package/dist/lib/tracers/ArrayQueueTracer.js +67 -0
  246. package/dist/lib/tracers/CompositeTracer.d.ts +24 -0
  247. package/dist/lib/tracers/CompositeTracer.d.ts.map +1 -0
  248. package/dist/lib/tracers/CompositeTracer.js +57 -0
  249. package/dist/lib/tracers/NoOpTracer.d.ts +58 -0
  250. package/dist/lib/tracers/NoOpTracer.d.ts.map +1 -0
  251. package/dist/lib/tracers/NoOpTracer.js +41 -0
  252. package/dist/lib/tracers/SQLiteTracer.d.ts +42 -0
  253. package/dist/lib/tracers/SQLiteTracer.d.ts.map +1 -0
  254. package/dist/lib/tracers/SQLiteTracer.js +84 -0
  255. package/dist/lib/tracers/StdioTracer.d.ts +83 -0
  256. package/dist/lib/tracers/StdioTracer.d.ts.map +1 -0
  257. package/dist/lib/tracers/StdioTracer.js +270 -0
  258. package/dist/lib/tracers/TestTracer.d.ts +95 -0
  259. package/dist/lib/tracers/TestTracer.d.ts.map +1 -0
  260. package/dist/lib/tracers/TestTracer.js +87 -0
  261. package/dist/lib/tracers/index.d.ts +12 -0
  262. package/dist/lib/tracers/index.d.ts.map +1 -0
  263. package/dist/lib/tracers/index.js +11 -0
  264. package/dist/lib/types.d.ts +366 -0
  265. package/dist/lib/types.d.ts.map +1 -0
  266. package/dist/lib/types.js +1 -0
  267. package/dist/lib/utf8Cache.d.ts +111 -0
  268. package/dist/lib/utf8Cache.d.ts.map +1 -0
  269. package/dist/lib/utf8Cache.js +177 -0
  270. package/dist/lib/wasm/WasmBufferStrategy.d.ts +88 -0
  271. package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -0
  272. package/dist/lib/wasm/WasmBufferStrategy.js +138 -0
  273. package/dist/lib/wasm/wasmAllocator.d.ts +109 -0
  274. package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -0
  275. package/dist/lib/wasm/wasmAllocator.js +227 -0
  276. package/dist/lib/wasm/wasmSpanBuffer.d.ts +123 -0
  277. package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -0
  278. package/dist/lib/wasm/wasmSpanBuffer.js +772 -0
  279. package/dist/lib/wasm/wasmTraceRoot.d.ts +167 -0
  280. package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -0
  281. package/dist/lib/wasm/wasmTraceRoot.js +264 -0
  282. package/dist/node.d.ts +7 -0
  283. package/dist/node.d.ts.map +1 -0
  284. package/dist/node.js +8 -0
  285. package/dist/testing.d.ts +18 -0
  286. package/dist/testing.d.ts.map +1 -0
  287. package/dist/testing.js +17 -0
  288. package/package.json +193 -0
  289. package/src/bun/preload.ts +11 -0
  290. package/src/bun/trace-preload.ts +14 -0
  291. package/src/es.ts +11 -0
  292. package/src/index.ts +194 -0
  293. package/src/lib/JsBufferStrategy.ts +102 -0
  294. package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +485 -0
  295. package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +390 -0
  296. package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +647 -0
  297. package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +292 -0
  298. package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +354 -0
  299. package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +127 -0
  300. package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +392 -0
  301. package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +389 -0
  302. package/src/lib/__tests__/arrow-conversion-algorithms.test.ts +54 -0
  303. package/src/lib/__tests__/arrow-test-helpers.ts +71 -0
  304. package/src/lib/__tests__/binary-e2e.test.ts +203 -0
  305. package/src/lib/__tests__/buffer-overflow-op-api.test.ts +608 -0
  306. package/src/lib/__tests__/buffer-overflow.test.ts +612 -0
  307. package/src/lib/__tests__/capacity-tuning.test.ts +544 -0
  308. package/src/lib/__tests__/effective-schema.test.ts +439 -0
  309. package/src/lib/__tests__/flechette.test.ts +42 -0
  310. package/src/lib/__tests__/flushScheduler.test.ts +537 -0
  311. package/src/lib/__tests__/integration.test.ts +600 -0
  312. package/src/lib/__tests__/library.test.ts +934 -0
  313. package/src/lib/__tests__/nested-library-tasks.test.ts +849 -0
  314. package/src/lib/__tests__/op-context-binding.test.ts +135 -0
  315. package/src/lib/__tests__/op-metadata.test.ts +198 -0
  316. package/src/lib/__tests__/op-type-safety.test.ts +71 -0
  317. package/src/lib/__tests__/package-exports.test.ts +57 -0
  318. package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +319 -0
  319. package/src/lib/__tests__/remapped-buffer-view.test.ts +635 -0
  320. package/src/lib/__tests__/scope-attributes.test.ts +348 -0
  321. package/src/lib/__tests__/span-lifecycle.test.ts +680 -0
  322. package/src/lib/__tests__/sync-async-trace.test.ts +435 -0
  323. package/src/lib/__tests__/test-helpers.ts +318 -0
  324. package/src/lib/__tests__/timestamp.test.ts +259 -0
  325. package/src/lib/__tests__/trace-archive-primitives.test.ts +98 -0
  326. package/src/lib/__tests__/traceContext-type-enforcement.test.ts +271 -0
  327. package/src/lib/__tests__/tracer.test.ts +211 -0
  328. package/src/lib/__tests__/type-narrowing.test.ts +137 -0
  329. package/src/lib/archive/chunkCompaction.ts +44 -0
  330. package/src/lib/archive/chunkEnvelope.ts +79 -0
  331. package/src/lib/archive/chunkRouting.ts +70 -0
  332. package/src/lib/archive/chunkStats.ts +25 -0
  333. package/src/lib/archive/index.ts +4 -0
  334. package/src/lib/arrow/capacityStats.ts +340 -0
  335. package/src/lib/arrow/dictionaries.ts +159 -0
  336. package/src/lib/arrow/flechette.ts +114 -0
  337. package/src/lib/arrow/utils.ts +126 -0
  338. package/src/lib/buffer/Nanoseconds.ts +131 -0
  339. package/src/lib/bufferStrategy.ts +106 -0
  340. package/src/lib/capacityTuning.ts +102 -0
  341. package/src/lib/codegen/__tests__/__snapshots__/evaluatorGenerator.test.ts.snap +160 -0
  342. package/src/lib/codegen/__tests__/__snapshots__/scopeGenerator.test.ts.snap +196 -0
  343. package/src/lib/codegen/__tests__/__snapshots__/spanLoggerGenerator.test.ts.snap +1965 -0
  344. package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +516 -0
  345. package/src/lib/codegen/__tests__/nullBitmap.test.ts +207 -0
  346. package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +237 -0
  347. package/src/lib/codegen/evaluatorGenerator.ts +309 -0
  348. package/src/lib/codegen/fixedPositionWriterGenerator.ts +444 -0
  349. package/src/lib/codegen/spanLoggerGenerator.ts +715 -0
  350. package/src/lib/convertToArrow.ts +1805 -0
  351. package/src/lib/defineOpContext.ts +398 -0
  352. package/src/lib/errors/Blocked.ts +165 -0
  353. package/src/lib/errors/CodeError.ts +132 -0
  354. package/src/lib/errors/RetriesExhausted.ts +78 -0
  355. package/src/lib/errors/Transient.ts +168 -0
  356. package/src/lib/errors/__tests__/Blocked-config.test.ts +152 -0
  357. package/src/lib/errors/__tests__/Transient.test.ts +129 -0
  358. package/src/lib/errors/__tests__/retry-policy.test.ts +85 -0
  359. package/src/lib/errors/index.ts +24 -0
  360. package/src/lib/errors/retry-policy.ts +87 -0
  361. package/src/lib/flushScheduler.ts +509 -0
  362. package/src/lib/library.ts +682 -0
  363. package/src/lib/logApi.ts +70 -0
  364. package/src/lib/logBinding.ts +67 -0
  365. package/src/lib/op.ts +103 -0
  366. package/src/lib/opContext/__tests__/retry.test.ts +764 -0
  367. package/src/lib/opContext/contextTypes.ts +130 -0
  368. package/src/lib/opContext/createOpGroup.ts +456 -0
  369. package/src/lib/opContext/defineOp.ts +281 -0
  370. package/src/lib/opContext/featureFlagTypes.ts +54 -0
  371. package/src/lib/opContext/index.ts +16 -0
  372. package/src/lib/opContext/opGroupTypes.ts +342 -0
  373. package/src/lib/opContext/opTypes.ts +80 -0
  374. package/src/lib/opContext/spanContextTypes.ts +398 -0
  375. package/src/lib/opContext/types.ts +403 -0
  376. package/src/lib/result.ts +550 -0
  377. package/src/lib/schema/LogSchema.ts +153 -0
  378. package/src/lib/schema/__tests__/defineLogSchema.test.ts +342 -0
  379. package/src/lib/schema/__tests__/featureFlags.test.ts +443 -0
  380. package/src/lib/schema/builder.ts +201 -0
  381. package/src/lib/schema/defineFeatureFlags.ts +91 -0
  382. package/src/lib/schema/defineLogSchema.ts +291 -0
  383. package/src/lib/schema/evaluator.ts +404 -0
  384. package/src/lib/schema/extend.ts +69 -0
  385. package/src/lib/schema/systemSchema.ts +339 -0
  386. package/src/lib/schema/typeGuards.ts +163 -0
  387. package/src/lib/schema/types.ts +265 -0
  388. package/src/lib/spanBuffer.ts +571 -0
  389. package/src/lib/spanBufferHelpers.ts +73 -0
  390. package/src/lib/spanBufferStats.ts +40 -0
  391. package/src/lib/spanContext.ts +1566 -0
  392. package/src/lib/sqlite/__tests__/sqlite-common.test.ts +89 -0
  393. package/src/lib/sqlite/index.ts +26 -0
  394. package/src/lib/sqlite/sqlite-async-writer.ts +101 -0
  395. package/src/lib/sqlite/sqlite-common.ts +309 -0
  396. package/src/lib/sqlite/sqlite-d1.ts +104 -0
  397. package/src/lib/sqlite/sqlite-db.ts +32 -0
  398. package/src/lib/sqlite/sqlite-node.ts +83 -0
  399. package/src/lib/sqlite/sqlite-writer.ts +128 -0
  400. package/src/lib/testing/TRACE-TESTING.md +100 -0
  401. package/src/lib/testing/__tests__/bun-harness.test.ts +108 -0
  402. package/src/lib/testing/__tests__/extractFacts.test.ts +279 -0
  403. package/src/lib/testing/__tests__/facts.test.ts +324 -0
  404. package/src/lib/testing/__tests__/vitest-harness.test.ts +32 -0
  405. package/src/lib/testing/bun-harness.ts +990 -0
  406. package/src/lib/testing/extractFacts.ts +362 -0
  407. package/src/lib/testing/facts.ts +470 -0
  408. package/src/lib/testing/index.ts +141 -0
  409. package/src/lib/testing/queryable-span.ts +108 -0
  410. package/src/lib/testing/span-query.ts +65 -0
  411. package/src/lib/testing/stdio-replay.ts +50 -0
  412. package/src/lib/testing/trace-query.ts +329 -0
  413. package/src/lib/testing/vitest-harness.ts +691 -0
  414. package/src/lib/threadId.ts +135 -0
  415. package/src/lib/traceContext.ts +182 -0
  416. package/src/lib/traceId.ts +142 -0
  417. package/src/lib/traceRoot.es.ts +157 -0
  418. package/src/lib/traceRoot.node.ts +170 -0
  419. package/src/lib/traceRoot.ts +154 -0
  420. package/src/lib/traceRoot.universal.ts +22 -0
  421. package/src/lib/tracer.ts +896 -0
  422. package/src/lib/tracers/ArrayQueueTracer.ts +76 -0
  423. package/src/lib/tracers/CompositeTracer.ts +76 -0
  424. package/src/lib/tracers/NoOpTracer.ts +73 -0
  425. package/src/lib/tracers/SQLiteTracer.ts +115 -0
  426. package/src/lib/tracers/StdioTracer.ts +380 -0
  427. package/src/lib/tracers/TestTracer.ts +146 -0
  428. package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +184 -0
  429. package/src/lib/tracers/__tests__/NoOpTracer.test.ts +204 -0
  430. package/src/lib/tracers/__tests__/StdioTracer.test.ts +313 -0
  431. package/src/lib/tracers/__tests__/TestTracer.test.ts +200 -0
  432. package/src/lib/tracers/index.ts +12 -0
  433. package/src/lib/types.ts +498 -0
  434. package/src/lib/utf8Cache.ts +201 -0
  435. package/src/lib/wasm/WasmBufferStrategy.ts +219 -0
  436. package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +256 -0
  437. package/src/lib/wasm/__tests__/wasm-integration.test.ts +476 -0
  438. package/src/lib/wasm/__tests__/wasmAllocator.test.ts +699 -0
  439. package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +449 -0
  440. package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +390 -0
  441. package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +444 -0
  442. package/src/lib/wasm/allocator.zig +945 -0
  443. package/src/lib/wasm/wasmAllocator.ts +469 -0
  444. package/src/lib/wasm/wasmSpanBuffer.ts +1014 -0
  445. package/src/lib/wasm/wasmTraceRoot.ts +315 -0
  446. package/src/node.ts +10 -0
  447. package/src/testing.ts +18 -0
@@ -0,0 +1,990 @@
1
+ /// <reference types="bun" />
2
+
3
+ /**
4
+ * bun:test integration for LMAO trace-testing.
5
+ *
6
+ * Transparently wraps bun:test's it()/test() via mock.module so every test
7
+ * automatically creates a trace span — no import changes needed in test files.
8
+ *
9
+ * Architecture:
10
+ * - initTraceTestRun() in preload sets up a lifecycle tracer pipeline
11
+ * - mock.module('bun:test', ...) in preload patches it()/test() with trace spans
12
+ * - One root trace per test run (tracer.trace('test-run', ...))
13
+ * - Each it()/test() creates a child span of the root (rootCtx.span(name, fn))
14
+ * - describe() is wrapped to track nesting — path written to `describe` schema column
15
+ * - After all tests: flush tracer outputs (SQLite, stdio, or both)
16
+ *
17
+ * mock.module MUST be called from the preload file itself — bun only intercepts
18
+ * subsequent imports when the mock is registered from the entry module context.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * // test-setup.ts (preload)
23
+ * import { mock } from 'bun:test';
24
+ * import * as bunTest from 'bun:test';
25
+ * import { initTraceTestRun, createBunTestMock } from '@smoothbricks/lmao/testing/bun';
26
+ * import { myOpContext } from './src/opContext.js';
27
+ *
28
+ * initTraceTestRun(myOpContext, { sqlite: { dbPath: '.trace-results.db' } });
29
+ * mock.module('bun:test', () => createBunTestMock(bunTest));
30
+ *
31
+ * // my-test.test.ts — uses bun:test directly, no import changes needed
32
+ * import { describe, it, expect } from 'bun:test';
33
+ *
34
+ * describe('Order Processing', () => {
35
+ * it('validates order', () => {
36
+ * // This it() is automatically wrapped in a child span of the root
37
+ * });
38
+ * });
39
+ * ```
40
+ *
41
+ * @module testing/bun
42
+ */
43
+
44
+ import { Database } from 'bun:sqlite';
45
+ import * as bunTest from 'bun:test';
46
+ import {
47
+ afterAll as _afterAll,
48
+ afterEach as _afterEach,
49
+ beforeAll as _beforeAll,
50
+ beforeEach as _beforeEach,
51
+ describe as _describe,
52
+ expect as _expect,
53
+ it as _it,
54
+ mock,
55
+ } from 'bun:test';
56
+ import { AsyncLocalStorage } from 'node:async_hooks';
57
+ import { defineOpContext } from '../defineOpContext.js';
58
+ import { JsBufferStrategy } from '../JsBufferStrategy.js';
59
+ import type { SpanContext } from '../opContext/spanContextTypes.js';
60
+ import type { DepsConfig, FeatureFlagSchema, OpContext, OpContextBinding, OpContextOf } from '../opContext/types.js';
61
+ import { S } from '../schema/builder.js';
62
+ import { LogSchema } from '../schema/LogSchema.js';
63
+ import type { SchemaFields } from '../schema/types.js';
64
+ import { isSpanContext } from '../spanContext.js';
65
+ import type { SQLiteWriterConfig } from '../sqlite/sqlite-writer.js';
66
+ import { createTraceRoot } from '../traceRoot.universal.js';
67
+ import type { Tracer } from '../tracer.js';
68
+ import { CompositeTracer } from '../tracers/CompositeTracer.js';
69
+ import { SQLiteTracer } from '../tracers/SQLiteTracer.js';
70
+ import { StdioTracer } from '../tracers/StdioTracer.js';
71
+ import { TestTracer as InMemoryTestTracer } from '../tracers/TestTracer.js';
72
+
73
+ /** bun:test expect() errors start with 'expect(received).' — distinguishes assertion failures from other throws */
74
+ function isExpectError(error: unknown): boolean {
75
+ return error instanceof Error && error.message.startsWith('expect(');
76
+ }
77
+
78
+ function writeDescribeTag(tag: unknown, describePath: string | null): void {
79
+ if (!describePath || typeof tag !== 'object' || tag === null) {
80
+ return;
81
+ }
82
+
83
+ const describeWriter = Reflect.get(tag, 'describe');
84
+ if (typeof describeWriter === 'function') {
85
+ describeWriter.call(tag, describePath);
86
+ return;
87
+ }
88
+
89
+ const batchWriter = Reflect.get(tag, 'with');
90
+ if (typeof batchWriter === 'function') {
91
+ batchWriter.call(tag, { describe: describePath });
92
+ }
93
+ }
94
+
95
+ type TestBody = () => unknown | Promise<unknown>;
96
+ type DoneTestBody = (done: (err?: unknown) => void) => unknown | Promise<unknown>;
97
+ type HarnessSpanContext<B extends OpContextBinding> = SpanContext<OpContextOf<B>>;
98
+ type BunTestHarnessBuiltins = { describe: ReturnType<typeof S.category> };
99
+ type HarnessSchema<TExt extends SchemaFields> = BunTestHarnessBuiltins & TExt;
100
+ type BunDescribe = typeof _describe;
101
+ type BunIt = typeof _it;
102
+ type BunDescribeLabel = Parameters<BunDescribe>[0];
103
+ type BunTestOptions = Parameters<BunIt>[2];
104
+
105
+ const ciOnlyDisabledMessage =
106
+ '.only is disabled in CI environments to prevent accidentally skipping tests. To override, set the environment variable CI=false.';
107
+
108
+ export interface BunTestModuleShape {
109
+ describe: BunDescribe;
110
+ it: BunIt;
111
+ test: BunIt;
112
+ [key: string]: unknown;
113
+ }
114
+
115
+ // WHY: Package-local `nx test` runs Bun from that package directory, so the
116
+ // shared preload must not eagerly import unrelated packages' tracer modules just
117
+ // to find one opContext. A tiny fallback binding keeps tracing active for
118
+ // packages that only need SQLite-backed test spans and do not define their own
119
+ // `src/test-suite-tracer.ts`.
120
+ const defaultAutoSetupOpContext = defineOpContext({ logSchema: new LogSchema({}) });
121
+
122
+ type ExtendBindingLogSchema<B extends OpContextBinding, TExt extends SchemaFields> =
123
+ B extends OpContextBinding<infer T, infer FF, infer Deps, infer UserCtx>
124
+ ? OpContextBinding<T extends LogSchema<infer Fields> ? LogSchema<Fields & TExt> : never, FF, Deps, UserCtx>
125
+ : never;
126
+
127
+ export type BunTestSetupOptions<TExt extends SchemaFields = Record<never, never>> = {
128
+ /**
129
+ * Optional SQLite output path.
130
+ *
131
+ * Omit this to run traced tests without DB persistence.
132
+ */
133
+ sqlite?: SQLiteWriterConfig;
134
+ /** Optional verbose stdout tracing; defaults to env flag detection. */
135
+ verbose?: boolean;
136
+ /** Optional test-only schema columns merged into span tag/log methods. */
137
+ extraTestColumns?: TExt;
138
+ };
139
+
140
+ function buildHarnessSchemaExtensions(binding: OpContextBinding, extraTestColumns: undefined): BunTestHarnessBuiltins;
141
+ function buildHarnessSchemaExtensions<TExt extends SchemaFields>(
142
+ binding: OpContextBinding,
143
+ extraTestColumns: TExt,
144
+ ): HarnessSchema<TExt>;
145
+ function buildHarnessSchemaExtensions<TExt extends SchemaFields>(
146
+ binding: OpContextBinding,
147
+ extraTestColumns: TExt | undefined,
148
+ ): BunTestHarnessBuiltins | HarnessSchema<TExt> {
149
+ const extensionBase: BunTestHarnessBuiltins = { describe: S.category() };
150
+ const baseColumnNames = new Set(binding.logBinding.logSchema._columnNames);
151
+ for (const fieldName of Object.keys(extraTestColumns ?? {})) {
152
+ if (baseColumnNames.has(fieldName)) {
153
+ throw new Error(`Test harness schema column '${fieldName}' already exists in the bound log schema`);
154
+ }
155
+ }
156
+
157
+ return extraTestColumns ? { ...extensionBase, ...extraTestColumns } : extensionBase;
158
+ }
159
+
160
+ function extendBindingLogSchema<
161
+ B extends OpContextBinding<LogSchema<TFields>, FF, Deps, UserCtx>,
162
+ TFields extends SchemaFields,
163
+ FF extends FeatureFlagSchema,
164
+ Deps extends DepsConfig,
165
+ UserCtx extends Record<string, unknown>,
166
+ TExt extends SchemaFields,
167
+ >(binding: B, extension: TExt): OpContextBinding<LogSchema<TFields & TExt>, FF, Deps, UserCtx> {
168
+ const extendedBinding: OpContextBinding<LogSchema<TFields & TExt>, FF, Deps, UserCtx> = {
169
+ logBinding: {
170
+ ...binding.logBinding,
171
+ logSchema: binding.logBinding.logSchema.extend(extension),
172
+ },
173
+ flags: binding.flags,
174
+ ctxDefaults: binding.ctxDefaults,
175
+ deps: binding.deps,
176
+ };
177
+
178
+ return extendedBinding;
179
+ }
180
+
181
+ function isTruthyEnvFlag(value: unknown): boolean {
182
+ return value === true || value === '1' || value === 'true';
183
+ }
184
+
185
+ function isSchemaFieldsRecord(value: unknown): value is SchemaFields {
186
+ return typeof value === 'object' && value !== null;
187
+ }
188
+
189
+ function isOpContextBindingLike(value: unknown): value is OpContextBinding {
190
+ return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'logBinding') === 'object';
191
+ }
192
+
193
+ function isSpanContextForBinding<B extends OpContextBinding>(
194
+ value: unknown,
195
+ binding: B,
196
+ ): value is SpanContext<OpContextOf<B>> {
197
+ return isSpanContext<OpContextOf<B>>(value) && Reflect.get(value, '_schema') === binding.logBinding.logSchema;
198
+ }
199
+
200
+ function isTracerForBinding<B extends OpContextBinding>(value: unknown, binding: B): value is Tracer<B> {
201
+ const logBinding = typeof value === 'object' && value !== null ? Reflect.get(value, 'logBinding') : null;
202
+ return (
203
+ typeof logBinding === 'object' &&
204
+ logBinding !== null &&
205
+ Reflect.get(logBinding, 'logSchema') === binding.logBinding.logSchema
206
+ );
207
+ }
208
+
209
+ function isVerboseTraceEnabled(explicitVerbose: boolean | undefined): boolean {
210
+ if (explicitVerbose !== undefined) {
211
+ return explicitVerbose;
212
+ }
213
+
214
+ const globalVerbose = Reflect.get(globalThis, '__LMAO_TEST_TRACE_VERBOSE__');
215
+ if (isTruthyEnvFlag(globalVerbose)) {
216
+ return true;
217
+ }
218
+
219
+ return isTruthyEnvFlag(process.env.LMAO_TEST_TRACE_VERBOSE);
220
+ }
221
+
222
+ type TracerFactoryOptions<B extends OpContextBinding> = {
223
+ binding: B;
224
+ sqlite: SQLiteWriterConfig | undefined;
225
+ verbose: boolean;
226
+ };
227
+
228
+ function createRootTracer<B extends OpContextBinding>({
229
+ binding,
230
+ sqlite,
231
+ verbose,
232
+ }: TracerFactoryOptions<B>): Tracer<B> {
233
+ const tracerOptions = {
234
+ bufferStrategy: new JsBufferStrategy<B['logBinding']['logSchema']>(),
235
+ createTraceRoot,
236
+ } as const;
237
+
238
+ if (sqlite) {
239
+ const db = new Database(sqlite.dbPath ?? '.trace-results.db');
240
+ const sqliteTracer = new SQLiteTracer(binding, {
241
+ ...tracerOptions,
242
+ db,
243
+ });
244
+
245
+ if (verbose) {
246
+ const stdioTracer = new StdioTracer(binding, {
247
+ ...tracerOptions,
248
+ });
249
+
250
+ return new CompositeTracer(binding, {
251
+ ...tracerOptions,
252
+ delegates: [stdioTracer, sqliteTracer],
253
+ });
254
+ }
255
+
256
+ return sqliteTracer;
257
+ }
258
+
259
+ if (verbose) {
260
+ return new StdioTracer(binding, {
261
+ ...tracerOptions,
262
+ });
263
+ }
264
+
265
+ return new InMemoryTestTracer(binding, {
266
+ ...tracerOptions,
267
+ });
268
+ }
269
+
270
+ async function closeTracer<B extends OpContextBinding>(tracer: Tracer<B>): Promise<void> {
271
+ const close = Reflect.get(tracer, 'close');
272
+ if (typeof close === 'function') {
273
+ await close.call(tracer);
274
+ }
275
+ }
276
+
277
+ export interface BunTestTracerInstance<B extends OpContextBinding> {
278
+ setup(): void;
279
+ useTestSpan(): HarnessSpanContext<B>;
280
+ getTracer(): Tracer<B>;
281
+ createBunTestMock<TModule extends BunTestModuleShape>(bunTestModule: TModule): TModule;
282
+ }
283
+
284
+ export interface BunTestSuiteTracer<B extends OpContextBinding> {
285
+ useTestTracer: BunTestTracerInstance<B>;
286
+ useTestSpan(): HarnessSpanContext<B>;
287
+ setupBunTestSuiteTracing(): void;
288
+ }
289
+
290
+ export type BunTestSuiteUseTestTracer<
291
+ B extends OpContextBinding,
292
+ TExt extends SchemaFields = Record<never, never>,
293
+ > = ReturnType<typeof makeBunTestSuiteTracer<B, TExt>>['useTestTracer'];
294
+
295
+ export type TestTracer<
296
+ B extends OpContextBinding,
297
+ TExt extends SchemaFields = Record<never, never>,
298
+ > = BunTestSuiteUseTestTracer<B, TExt>;
299
+
300
+ type ActiveBunTestTracer = BunTestTracerInstance<OpContextBinding>;
301
+
302
+ let _activeSuiteTracer: ActiveBunTestTracer | null = null;
303
+
304
+ /** Returns the active suite tracer set by installBunTestTracing(), or null if none is active. */
305
+ export function getActiveSuiteTracer(): ActiveBunTestTracer | null {
306
+ return _activeSuiteTracer;
307
+ }
308
+
309
+ export function installBunTestTracing(tracer: ActiveBunTestTracer): void {
310
+ _activeSuiteTracer = tracer;
311
+ tracer.setup();
312
+ mock.module('bun:test', () => tracer.createBunTestMock(bunTest));
313
+ }
314
+
315
+ export function makeBunTestSuiteTracer<B extends OpContextBinding>(
316
+ binding: B,
317
+ options?: Omit<BunTestSetupOptions, 'extraTestColumns'>,
318
+ ): BunTestSuiteTracer<ExtendBindingLogSchema<B, BunTestHarnessBuiltins>>;
319
+ export function makeBunTestSuiteTracer<B extends OpContextBinding, TExt extends SchemaFields = Record<never, never>>(
320
+ binding: B,
321
+ options?: BunTestSetupOptions<TExt>,
322
+ ): BunTestSuiteTracer<ExtendBindingLogSchema<B, HarnessSchema<TExt>>>;
323
+ export function makeBunTestSuiteTracer<B extends OpContextBinding, TExt extends SchemaFields = Record<never, never>>(
324
+ binding: B,
325
+ options?: BunTestSetupOptions<TExt>,
326
+ ): BunTestSuiteTracer<OpContextBinding> {
327
+ const useTestTracer = createTestTracerInstance(binding, options);
328
+ return {
329
+ useTestTracer,
330
+ useTestSpan: () => useTestTracer.useTestSpan(),
331
+ setupBunTestSuiteTracing: () => installBunTestTracing(useTestTracer),
332
+ };
333
+ }
334
+
335
+ /**
336
+ * Define a per-package test tracer — metadata for preload discovery + typed span accessor.
337
+ *
338
+ * Returns plain data that `autoSetupBunTestTracing` reads at discovery time, plus a
339
+ * `useTestSpan()` that threads the package-local binding through the generic
340
+ * `useTestSpan<B>()` helper.
341
+ *
342
+ * WHY generic threading: `autoSetupBunTestTracing` creates the active tracer from the
343
+ * same `opContext` binding passed here, so the exported helper can preserve the real
344
+ * span type without a local assertion bridge.
345
+ */
346
+ export function defineTestTracer<B extends OpContextBinding>(
347
+ binding: B,
348
+ options?: { extraTestColumns?: SchemaFields },
349
+ ): {
350
+ useTestSpan: () => SpanContext<OpContextOf<B>>;
351
+ opContext: B;
352
+ extraTestColumns: SchemaFields | undefined;
353
+ } {
354
+ return {
355
+ opContext: binding,
356
+ extraTestColumns: options?.extraTestColumns,
357
+ // WHY no re-validation: the global useTestSpan() already validates against
358
+ // the active suite tracer's (extended) binding. Re-checking against the
359
+ // original binding fails when extraTestColumns extend the schema, because
360
+ // the span's _schema is the extended LogSchema, not the original.
361
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WHY: useTestSpan() returns SpanContext typed to the suite binding; narrowing to OpContextOf<B> is safe because initTraceTestRun validates the binding matches
362
+ useTestSpan: () => useTestSpan() as SpanContext<OpContextOf<B>>,
363
+ };
364
+ }
365
+
366
+ /**
367
+ * Create an instance-scoped Bun test tracer harness.
368
+ *
369
+ * Unlike initTraceTestRun(), this keeps tracer/root/ALS state isolated per instance.
370
+ */
371
+ export function makeTestTracer<B extends OpContextBinding>(
372
+ binding: B,
373
+ options?: Omit<BunTestSetupOptions, 'extraTestColumns'>,
374
+ ): BunTestTracerInstance<ExtendBindingLogSchema<B, BunTestHarnessBuiltins>>;
375
+ export function makeTestTracer<B extends OpContextBinding, TExt extends SchemaFields = Record<never, never>>(
376
+ binding: B,
377
+ options?: BunTestSetupOptions<TExt>,
378
+ ): BunTestTracerInstance<ExtendBindingLogSchema<B, HarnessSchema<TExt>>>;
379
+ export function makeTestTracer<B extends OpContextBinding, TExt extends SchemaFields = Record<never, never>>(
380
+ binding: B,
381
+ options?: BunTestSetupOptions<TExt>,
382
+ ): BunTestTracerInstance<OpContextBinding> {
383
+ return createTestTracerInstance(binding, options);
384
+ }
385
+ function createTestTracerInstance<B extends OpContextBinding, TExt extends SchemaFields = Record<never, never>>(
386
+ binding: B,
387
+ options?: BunTestSetupOptions<TExt>,
388
+ ): BunTestTracerInstance<OpContextBinding> {
389
+ let activeBinding: OpContextBinding | null = null;
390
+ let tracer: Tracer<OpContextBinding> | null = null;
391
+ let verboseTrace = false;
392
+ let rootCtx: SpanContext<OpContext> | null = null;
393
+ let resolveTestRun: (() => void) | null = null;
394
+ let rootTracePromise: Promise<unknown> | null = null;
395
+ let isSetup = false;
396
+
397
+ const als = new AsyncLocalStorage<SpanContext<OpContext>>();
398
+
399
+ function assertRootCtx(): SpanContext<OpContext> {
400
+ if (!rootCtx || !activeBinding || !isSpanContextForBinding(rootCtx, activeBinding)) {
401
+ throw new Error('Call setup() before wiring bun:test wrappers');
402
+ }
403
+ return rootCtx;
404
+ }
405
+
406
+ function assertTracer(): Tracer<OpContextBinding> {
407
+ if (!tracer || !activeBinding || !isTracerForBinding(tracer, activeBinding)) {
408
+ throw new Error('Call setup() in preload before tests');
409
+ }
410
+ return tracer;
411
+ }
412
+
413
+ function runTracedTest(name: string, fn: TestBody | DoneTestBody, describePath: string | null): Promise<unknown> {
414
+ const currentRoot = assertRootCtx();
415
+ return currentRoot.span(name, async (ctx) => {
416
+ writeDescribeTag(ctx.tag, describePath);
417
+ try {
418
+ await als.run(ctx, () => fn(() => undefined));
419
+ return ctx.ok(undefined); // pass -> span-ok
420
+ } catch (error) {
421
+ if (isExpectError(error)) {
422
+ ctx.err(error); // record assertion failure in span
423
+ throw error; // re-throw so bun:test sees the failure
424
+ }
425
+ throw error; // other throw -> span-exception
426
+ }
427
+ });
428
+ }
429
+
430
+ function createWrappedDescribe(origDescribe: typeof _describe, describeStack: string[]) {
431
+ function wrappedDescribeBase(fn: () => void): void;
432
+ function wrappedDescribeBase(name: BunDescribeLabel, fn: () => void): void;
433
+ function wrappedDescribeBase(nameOrFn: BunDescribeLabel | (() => void), fn?: () => void): void {
434
+ if (fn === undefined && typeof nameOrFn === 'function') {
435
+ origDescribe(() => nameOrFn());
436
+ return;
437
+ }
438
+ const describeFn = fn;
439
+ if (!describeFn) {
440
+ throw new TypeError('describe callback is required');
441
+ }
442
+
443
+ origDescribe(nameOrFn, () => {
444
+ describeStack.push(String(nameOrFn));
445
+ try {
446
+ describeFn();
447
+ } finally {
448
+ describeStack.pop();
449
+ }
450
+ });
451
+ }
452
+
453
+ const wrappedDescribe = Object.assign(wrappedDescribeBase, {
454
+ skip: origDescribe.skip,
455
+ only: process.env.CI ? createDisabledDescribe(origDescribe) : origDescribe.only,
456
+ todo: origDescribe.todo,
457
+ concurrent: origDescribe.concurrent,
458
+ serial: origDescribe.serial,
459
+ if: origDescribe.if,
460
+ skipIf: origDescribe.skipIf,
461
+ todoIf: origDescribe.todoIf,
462
+ each: origDescribe.each,
463
+ });
464
+ assignOnly(wrappedDescribe, origDescribe, origDescribe);
465
+ assignOptionalBoundTestFunction(wrappedDescribe, 'each', origDescribe, origDescribe);
466
+ wrappedDescribe.skipIf = (condition: boolean) => (condition ? origDescribe.skip : wrappedDescribe);
467
+ wrappedDescribe.if = (condition: boolean) => (condition ? wrappedDescribe : origDescribe.skip);
468
+
469
+ return wrappedDescribe;
470
+ }
471
+
472
+ function createWrappedIt(origIt: typeof _it, describeStack: string[]) {
473
+ function wrappedItBase(name: string, fn: TestBody, options?: BunTestOptions): void;
474
+ function wrappedItBase(name: string, fn: DoneTestBody, options?: BunTestOptions): void;
475
+ function wrappedItBase(name: string, fn: TestBody | DoneTestBody, options?: BunTestOptions): void {
476
+ const describePath = describeStack.length > 0 ? describeStack.join(' > ') : null;
477
+ origIt(name, () => runTracedTest(name, fn, describePath), options);
478
+ }
479
+
480
+ const wrappedIt = Object.assign(wrappedItBase, {
481
+ skip: origIt.skip,
482
+ only: process.env.CI ? createDisabledIt(origIt) : origIt.only,
483
+ todo: origIt.todo?.bind(origIt),
484
+ failing: origIt.failing,
485
+ concurrent: origIt.concurrent,
486
+ serial: origIt.serial,
487
+ if: origIt.if,
488
+ skipIf: origIt.skipIf,
489
+ todoIf: origIt.todoIf,
490
+ failingIf: origIt.failingIf,
491
+ concurrentIf: origIt.concurrentIf,
492
+ serialIf: origIt.serialIf,
493
+ each: origIt.each,
494
+ });
495
+ assignOnly(wrappedIt, origIt, origIt);
496
+ assignOptionalBoundTestFunction(wrappedIt, 'each', origIt, origIt);
497
+ wrappedIt.skipIf = (condition: boolean) => (condition ? origIt.skip : wrappedIt);
498
+ wrappedIt.if = (condition: boolean) => (condition ? wrappedIt : origIt.skip);
499
+
500
+ return wrappedIt;
501
+ }
502
+
503
+ return {
504
+ setup(): void {
505
+ if (isSetup) {
506
+ return;
507
+ }
508
+ isSetup = true;
509
+
510
+ const harnessSchema =
511
+ options?.extraTestColumns === undefined
512
+ ? buildHarnessSchemaExtensions(binding, undefined)
513
+ : buildHarnessSchemaExtensions(binding, options.extraTestColumns);
514
+ const extendedBinding = extendBindingLogSchema(binding, harnessSchema);
515
+ activeBinding = extendedBinding;
516
+
517
+ verboseTrace = isVerboseTraceEnabled(options?.verbose);
518
+
519
+ const activeTracer = createRootTracer({
520
+ binding: extendedBinding,
521
+ sqlite: options?.sqlite,
522
+ verbose: verboseTrace,
523
+ });
524
+
525
+ tracer = activeTracer;
526
+ rootTracePromise = activeTracer.trace('test-run', (ctx: SpanContext<OpContext>) => {
527
+ rootCtx = ctx;
528
+ return new Promise<void>((resolve) => {
529
+ resolveTestRun = resolve;
530
+ });
531
+ });
532
+
533
+ _afterAll(async () => {
534
+ if (resolveTestRun) {
535
+ resolveTestRun();
536
+ resolveTestRun = null;
537
+ }
538
+
539
+ if (rootTracePromise) {
540
+ await rootTracePromise;
541
+ rootTracePromise = null;
542
+ }
543
+
544
+ if (tracer) {
545
+ try {
546
+ await tracer.flush();
547
+ if (options?.sqlite && rootCtx) {
548
+ const traceId = rootCtx.buffer.trace_id;
549
+ const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
550
+ console.log(`\n[trace] trace_id: ${traceId} -> ${dbPath}`);
551
+ }
552
+ } catch (e) {
553
+ console.error('[lmao/testing] SQLite flush error:', e);
554
+ } finally {
555
+ await closeTracer(tracer);
556
+ }
557
+ }
558
+ });
559
+ },
560
+
561
+ useTestSpan(): SpanContext<OpContext> {
562
+ const ctx = als.getStore();
563
+ if (!ctx || !activeBinding || !isSpanContextForBinding(ctx, activeBinding)) {
564
+ throw new Error('useTestSpan() called outside of a traced it()');
565
+ }
566
+ return ctx;
567
+ },
568
+
569
+ getTracer(): Tracer<OpContextBinding> {
570
+ return assertTracer();
571
+ },
572
+
573
+ createBunTestMock<TModule extends BunTestModuleShape>(bunTestModule: TModule): TModule {
574
+ const origIt = bunTestModule.it;
575
+ const origDescribe = bunTestModule.describe;
576
+ const describeStack: string[] = [];
577
+
578
+ const wrappedDescribe = createWrappedDescribe(origDescribe, describeStack);
579
+ const wrappedIt = createWrappedIt(origIt, describeStack);
580
+
581
+ return {
582
+ ...bunTestModule,
583
+ describe: wrappedDescribe,
584
+ it: wrappedIt,
585
+ test: wrappedIt,
586
+ };
587
+ },
588
+ };
589
+ }
590
+
591
+ // Global singleton — one root tracer for the entire bun test run
592
+ let _tracer: Tracer<OpContextBinding> | null = null;
593
+ let _verboseTrace = false;
594
+
595
+ // Root span context, its resolver, and the trace promise — one root per test run
596
+ let _rootCtx: SpanContext<OpContext> | null = null;
597
+ let _resolveTestRun: (() => void) | null = null;
598
+ let _rootTracePromise: Promise<unknown> | null = null;
599
+
600
+ // AsyncLocalStorage for propagating SpanContext to test bodies.
601
+ // Each it() runs in its own async context so concurrent tests don't collide.
602
+ const _als = new AsyncLocalStorage<SpanContext<OpContext>>();
603
+
604
+ /** Initialize the root tracer for the entire bun test run. Call once in preload. */
605
+ export function initTraceTestRun<B extends OpContextBinding>(opContext: B, options?: BunTestSetupOptions): void {
606
+ _activeSuiteTracer = null;
607
+
608
+ // Extend user's schema with `describe` column for test grouping
609
+ const harnessSchema =
610
+ options?.extraTestColumns === undefined
611
+ ? buildHarnessSchemaExtensions(opContext, undefined)
612
+ : buildHarnessSchemaExtensions(opContext, options.extraTestColumns);
613
+ const extendedSchema = opContext.logBinding.logSchema.extend(harnessSchema);
614
+ const extendedBinding = {
615
+ ...opContext,
616
+ logBinding: { ...opContext.logBinding, logSchema: extendedSchema },
617
+ };
618
+
619
+ _verboseTrace = isVerboseTraceEnabled(options?.verbose);
620
+
621
+ _tracer = createRootTracer({
622
+ binding: extendedBinding,
623
+ sqlite: options?.sqlite,
624
+ verbose: _verboseTrace,
625
+ });
626
+
627
+ // Create the single root trace — a long-lived promise keeps it alive
628
+ const tracer = _tracer;
629
+ _rootTracePromise = tracer.trace('test-run', (ctx: SpanContext<OpContext>) => {
630
+ _rootCtx = ctx;
631
+ return new Promise<void>((resolve) => {
632
+ _resolveTestRun = resolve;
633
+ });
634
+ }) as Promise<unknown>;
635
+
636
+ // Register global teardown — resolve root, wait for span-end, then flush tracer outputs
637
+ _afterAll(async () => {
638
+ // Resolve the root promise — triggers span-end write via _executeWithContext .then()
639
+ if (_resolveTestRun) {
640
+ _resolveTestRun();
641
+ _resolveTestRun = null;
642
+ }
643
+ // Await the trace promise so span-end is written to the buffer before flushing
644
+ if (_rootTracePromise) {
645
+ await _rootTracePromise;
646
+ _rootTracePromise = null;
647
+ }
648
+
649
+ if (_tracer) {
650
+ try {
651
+ await _tracer.flush();
652
+ if (options?.sqlite && _rootCtx) {
653
+ const traceId = _rootCtx.buffer.trace_id;
654
+ const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
655
+ console.log(`\n[trace] trace_id: ${traceId} → ${dbPath}`);
656
+ }
657
+ } catch (e) {
658
+ console.error('[lmao/testing] SQLite flush error:', e);
659
+ } finally {
660
+ await closeTracer(_tracer);
661
+ }
662
+ }
663
+ });
664
+ }
665
+
666
+ /**
667
+ * Create a bun:test mock replacement that wraps it()/test() in trace spans.
668
+ *
669
+ * Call this from the preload file and pass the result to mock.module:
670
+ * ```typescript
671
+ * mock.module('bun:test', () => createBunTestMock(bunTest));
672
+ * ```
673
+ *
674
+ * @param bunTestModule - The original bun:test namespace (`import * as bunTest from 'bun:test'`)
675
+ */
676
+ export function createBunTestMock<TModule extends BunTestModuleShape>(bunTestModule: TModule): TModule {
677
+ if (!_rootCtx) {
678
+ if (_activeSuiteTracer) {
679
+ return _activeSuiteTracer.createBunTestMock(bunTestModule);
680
+ }
681
+ throw new Error('Call initTraceTestRun() before createBunTestMock()');
682
+ }
683
+
684
+ const origIt = bunTestModule.it;
685
+ const origDescribe = bunTestModule.describe;
686
+ const rootCtx = _rootCtx;
687
+ const als = _als;
688
+ const describeStack: string[] = [];
689
+
690
+ // describe() callbacks run synchronously (just registering tests)
691
+ function wrappedDescribe(name: string, fn: () => void) {
692
+ return origDescribe(name, () => {
693
+ describeStack.push(name);
694
+ try {
695
+ fn();
696
+ } finally {
697
+ describeStack.pop();
698
+ }
699
+ });
700
+ }
701
+ // skipIf/if must return wrappedDescribe (not origDescribe) when the suite should run,
702
+ // so that describe-path tracking stays active for nested it() calls.
703
+ Object.assign(wrappedDescribe, {
704
+ skip: origDescribe.skip,
705
+ todo: origDescribe.todo,
706
+ skipIf: (condition: boolean) => (condition ? origDescribe.skip : wrappedDescribe),
707
+ if: (condition: boolean) => (condition ? wrappedDescribe : origDescribe.skip),
708
+ });
709
+ assignOnly(wrappedDescribe, origDescribe, origDescribe);
710
+ assignOptionalBoundTestFunction(wrappedDescribe, 'each', origDescribe, origDescribe);
711
+
712
+ function wrappedIt(name: string, fn: TestBody) {
713
+ // Capture describe path at registration time (synchronous)
714
+ const describePath = describeStack.length > 0 ? describeStack.join(' > ') : null;
715
+ return origIt(name, () =>
716
+ rootCtx.span(name, async (ctx: SpanContext<OpContext>) => {
717
+ writeDescribeTag(ctx.tag, describePath);
718
+ try {
719
+ await als.run(ctx, fn);
720
+ return ctx.ok(undefined); // pass → span-ok
721
+ } catch (error) {
722
+ if (isExpectError(error)) {
723
+ ctx.err(error); // record assertion failure in span
724
+ throw error; // re-throw so bun:test sees the failure
725
+ }
726
+ throw error; // other throw → span-exception
727
+ }
728
+ }),
729
+ );
730
+ }
731
+ // skipIf/if must return wrappedIt (not origIt) when the test should run,
732
+ // so the ALS context is set up and useTestSpan() works inside the test body.
733
+ Object.assign(wrappedIt, {
734
+ skip: origIt.skip,
735
+ todo: origIt.todo,
736
+ skipIf: (condition: boolean) => (condition ? origIt.skip : wrappedIt),
737
+ if: (condition: boolean) => (condition ? wrappedIt : origIt.skip),
738
+ });
739
+ assignOnly(wrappedIt, origIt, origIt);
740
+ assignOptionalBoundTestFunction(wrappedIt, 'each', origIt, origIt);
741
+
742
+ return {
743
+ ...bunTestModule,
744
+ describe: wrappedDescribe,
745
+ it: wrappedIt,
746
+ test: wrappedIt,
747
+ };
748
+ }
749
+
750
+ /**
751
+ * Get the current span context from AsyncLocalStorage (inside an it() block).
752
+ *
753
+ * Package-local tracer modules pass their own exported span-context type here so
754
+ * `useTestSpan()` preserves the suite-local schema extension instead of falling
755
+ * back to the erased global singleton shape.
756
+ */
757
+ export function useTestSpan<TCtx extends SpanContext<OpContextOf<OpContextBinding>>>(): TCtx;
758
+ export function useTestSpan(): SpanContext<OpContextOf<OpContextBinding>> {
759
+ if (_activeSuiteTracer) {
760
+ return _activeSuiteTracer.useTestSpan();
761
+ }
762
+
763
+ const ctx = _als.getStore();
764
+ if (!ctx) throw new Error('useTestSpan() called outside of a traced it()');
765
+ return ctx;
766
+ }
767
+
768
+ /**
769
+ * Get the root tracer instance.
770
+ *
771
+ * The optional type parameter narrows the return type for consumers that know
772
+ * the concrete binding (e.g. `getTracer<typeof opContext>()`). The underlying
773
+ * tracer is always the one created by `installBunTestTracing()` or `initTraceTestRun()`.
774
+ */
775
+ export function getTracer(): Tracer<OpContextBinding> {
776
+ if (_activeSuiteTracer) {
777
+ return _activeSuiteTracer.getTracer();
778
+ }
779
+
780
+ if (!_tracer) throw new Error('Call initTraceTestRun() in preload before tests');
781
+ return _tracer;
782
+ }
783
+
784
+ /**
785
+ * Wrapped describe — tracks describe nesting for the standalone export path.
786
+ * describe() callbacks run synchronously (just registering tests).
787
+ */
788
+ export function describe(name: string, fn: () => void) {
789
+ return _describe(name, () => {
790
+ _standaloneDescribeStack.push(name);
791
+ try {
792
+ fn();
793
+ } finally {
794
+ _standaloneDescribeStack.pop();
795
+ }
796
+ });
797
+ }
798
+
799
+ // Describe stack for standalone exports (non-mock-module path)
800
+ const _standaloneDescribeStack: string[] = [];
801
+
802
+ function assignOptionalBoundTestFunction(target: object, key: string, source: object, thisArg: unknown): void {
803
+ const value = Reflect.get(source, key);
804
+ if (typeof value === 'function') {
805
+ Reflect.set(target, key, value.bind(thisArg));
806
+ }
807
+ }
808
+
809
+ function disabledOnly(): never {
810
+ throw new Error(ciOnlyDisabledMessage);
811
+ }
812
+
813
+ function createDisabledDescribe(source: typeof _describe): typeof _describe {
814
+ const disabledDescribe: typeof _describe = Object.assign((_label: unknown, _fn?: unknown) => disabledOnly(), {
815
+ skip: source.skip,
816
+ only: source.skip,
817
+ todo: source.todo,
818
+ concurrent: source.concurrent,
819
+ serial: source.serial,
820
+ if: source.if,
821
+ skipIf: source.skipIf,
822
+ todoIf: source.todoIf,
823
+ each: source.each,
824
+ });
825
+ disabledDescribe.only = disabledDescribe;
826
+ return disabledDescribe;
827
+ }
828
+
829
+ function createDisabledIt(source: typeof _it): typeof _it {
830
+ const disabledIt: typeof _it = Object.assign((_label: string, _fn?: unknown, _options?: unknown) => disabledOnly(), {
831
+ skip: source.skip,
832
+ only: source.skip,
833
+ todo: source.todo,
834
+ failing: source.failing,
835
+ concurrent: source.concurrent,
836
+ serial: source.serial,
837
+ if: source.if,
838
+ skipIf: source.skipIf,
839
+ todoIf: source.todoIf,
840
+ failingIf: source.failingIf,
841
+ concurrentIf: source.concurrentIf,
842
+ serialIf: source.serialIf,
843
+ each: source.each,
844
+ });
845
+ disabledIt.only = disabledIt;
846
+ return disabledIt;
847
+ }
848
+
849
+ function assignOnly(target: object, source: object, thisArg: unknown): void {
850
+ if (process.env.CI) {
851
+ Reflect.set(target, 'only', disabledOnly);
852
+ return;
853
+ }
854
+
855
+ assignOptionalBoundTestFunction(target, 'only', source, thisArg);
856
+ }
857
+
858
+ describe.skip = _describe.skip;
859
+ assignOnly(describe, _describe, _describe);
860
+ describe.todo = _describe.todo;
861
+ assignOptionalBoundTestFunction(describe, 'each', _describe, _describe);
862
+ assignOptionalBoundTestFunction(describe, 'skipIf', _describe, _describe);
863
+ assignOptionalBoundTestFunction(describe, 'if', _describe, _describe);
864
+
865
+ /** Wrapped it — creates a child span of the root trace for the test case */
866
+ export function it(name: string, fn: () => void | Promise<void>): void {
867
+ const describePath = _standaloneDescribeStack.length > 0 ? _standaloneDescribeStack.join(' > ') : null;
868
+ _it(name, () => {
869
+ if (!_rootCtx) throw new Error('Call initTraceTestRun() in preload before tests');
870
+ return _rootCtx.span(name, async (ctx: SpanContext<OpContext>) => {
871
+ writeDescribeTag(ctx.tag, describePath);
872
+ try {
873
+ await _als.run(ctx, fn);
874
+ return ctx.ok(undefined); // pass → span-ok
875
+ } catch (error) {
876
+ if (isExpectError(error)) return ctx.err(error); // expect() fail → span-err
877
+ throw error; // other throw → span-exception
878
+ }
879
+ });
880
+ });
881
+ }
882
+
883
+ it.skip = _it.skip;
884
+ assignOnly(it, _it, _it);
885
+ it.todo = _it.todo;
886
+ assignOptionalBoundTestFunction(it, 'each', _it, _it);
887
+ assignOptionalBoundTestFunction(it, 'skipIf', _it, _it);
888
+ assignOptionalBoundTestFunction(it, 'if', _it, _it);
889
+
890
+ // Re-export everything else unchanged
891
+ export {
892
+ _afterAll as afterAll,
893
+ _afterEach as afterEach,
894
+ _beforeAll as beforeAll,
895
+ _beforeEach as beforeEach,
896
+ _expect as expect,
897
+ };
898
+
899
+ // =============================================================================
900
+ // Auto-discovery preload
901
+ // =============================================================================
902
+
903
+ export type AutoSetupOptions = {
904
+ /** Absolute path to the packages directory to scan for test-suite-tracer.ts files. */
905
+ packagesDir: string;
906
+ };
907
+
908
+ /**
909
+ * Auto-discover package test-suite-tracers and create the root tracer for the
910
+ * current bun test run.
911
+ *
912
+ * When Bun is running from inside `packages/<name>`, prefer that package's own
913
+ * `src/test-suite-tracer.ts` and avoid importing unrelated packages. Repo-root
914
+ * runs still fall back to the full scan so cross-package test runs keep the
915
+ * merged-schema behavior.
916
+ *
917
+ * Per-package `useTestSpan()` delegates to the global `useTestSpan()` from this
918
+ * module which checks `_activeSuiteTracer` — set by the root preload via
919
+ * `installBunTestTracing()`.
920
+ *
921
+ * @example
922
+ * ```ts
923
+ * // test-trace-preload.ts (monorepo root)
924
+ * import { autoSetupBunTestTracing } from './packages/lmao/src/lib/testing/bun-harness.js';
925
+ * await autoSetupBunTestTracing({ packagesDir: './packages' });
926
+ * ```
927
+ */
928
+ export async function autoSetupBunTestTracing(options: AutoSetupOptions): Promise<boolean> {
929
+ const { join, relative, resolve, sep } = await import('node:path');
930
+ const { existsSync, readdirSync } = await import('node:fs');
931
+
932
+ const packagesDir = resolve(options.packagesDir);
933
+ if (!existsSync(packagesDir)) return false;
934
+
935
+ const installSuite = (opContext: OpContextBinding, mergedSchema: Record<string, unknown>): boolean => {
936
+ const hasCustomSchema = Object.keys(mergedSchema).length > 0;
937
+ const suite = makeBunTestSuiteTracer(opContext, {
938
+ sqlite: { dbPath: '.trace-results.db' },
939
+ extraTestColumns: hasCustomSchema && isSchemaFieldsRecord(mergedSchema) ? mergedSchema : undefined,
940
+ });
941
+
942
+ suite.setupBunTestSuiteTracing();
943
+ return true;
944
+ };
945
+
946
+ const cwd = resolve(process.cwd());
947
+ const relativeToPackagesDir = relative(packagesDir, cwd);
948
+ const isPackageLocalRun =
949
+ relativeToPackagesDir !== '' &&
950
+ !relativeToPackagesDir.startsWith('..') &&
951
+ !relativeToPackagesDir.startsWith(`.${sep}`);
952
+
953
+ if (isPackageLocalRun) {
954
+ const [packageName] = relativeToPackagesDir.split(sep);
955
+ const tracerPath = join(packagesDir, packageName, 'src', 'test-suite-tracer.ts');
956
+
957
+ if (!existsSync(tracerPath)) {
958
+ return installSuite(defaultAutoSetupOpContext, {});
959
+ }
960
+
961
+ const mod = await import(tracerPath);
962
+ const mergedSchema = isSchemaFieldsRecord(mod.extraTestColumns) ? mod.extraTestColumns : {};
963
+ const opContext = isOpContextBindingLike(mod.opContext) ? mod.opContext : defaultAutoSetupOpContext;
964
+
965
+ return installSuite(opContext, mergedSchema);
966
+ }
967
+
968
+ const mergedSchema: Record<string, unknown> = {};
969
+ let opContext: OpContextBinding | null = null;
970
+
971
+ for (const entry of readdirSync(packagesDir, { withFileTypes: true })) {
972
+ if (!entry.isDirectory()) continue;
973
+ const tracerPath = join(packagesDir, entry.name, 'src', 'test-suite-tracer.ts');
974
+ if (!existsSync(tracerPath)) continue;
975
+
976
+ const mod = await import(tracerPath);
977
+
978
+ // Collect custom schema columns from each package
979
+ if (mod.extraTestColumns && typeof mod.extraTestColumns === 'object') {
980
+ Object.assign(mergedSchema, mod.extraTestColumns);
981
+ }
982
+
983
+ // Use the first available opContext (they all bind the same opContext)
984
+ if (!opContext && isOpContextBindingLike(mod.opContext)) {
985
+ opContext = mod.opContext;
986
+ }
987
+ }
988
+
989
+ return installSuite(opContext ?? defaultAutoSetupOpContext, mergedSchema);
990
+ }