@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,729 @@
1
+ /// <reference types="bun" />
2
+ /**
3
+ * bun:test integration for LMAO trace-testing.
4
+ *
5
+ * Transparently wraps bun:test's it()/test() via mock.module so every test
6
+ * automatically creates a trace span — no import changes needed in test files.
7
+ *
8
+ * Architecture:
9
+ * - initTraceTestRun() in preload sets up a lifecycle tracer pipeline
10
+ * - mock.module('bun:test', ...) in preload patches it()/test() with trace spans
11
+ * - One root trace per test run (tracer.trace('test-run', ...))
12
+ * - Each it()/test() creates a child span of the root (rootCtx.span(name, fn))
13
+ * - describe() is wrapped to track nesting — path written to `describe` schema column
14
+ * - After all tests: flush tracer outputs (SQLite, stdio, or both)
15
+ *
16
+ * mock.module MUST be called from the preload file itself — bun only intercepts
17
+ * subsequent imports when the mock is registered from the entry module context.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // test-setup.ts (preload)
22
+ * import { mock } from 'bun:test';
23
+ * import * as bunTest from 'bun:test';
24
+ * import { initTraceTestRun, createBunTestMock } from '@smoothbricks/lmao/testing/bun';
25
+ * import { myOpContext } from './src/opContext.js';
26
+ *
27
+ * initTraceTestRun(myOpContext, { sqlite: { dbPath: '.trace-results.db' } });
28
+ * mock.module('bun:test', () => createBunTestMock(bunTest));
29
+ *
30
+ * // my-test.test.ts — uses bun:test directly, no import changes needed
31
+ * import { describe, it, expect } from 'bun:test';
32
+ *
33
+ * describe('Order Processing', () => {
34
+ * it('validates order', () => {
35
+ * // This it() is automatically wrapped in a child span of the root
36
+ * });
37
+ * });
38
+ * ```
39
+ *
40
+ * @module testing/bun
41
+ */
42
+ import { Database } from 'bun:sqlite';
43
+ import * as bunTest from 'bun:test';
44
+ import { afterAll as _afterAll, afterEach as _afterEach, beforeAll as _beforeAll, beforeEach as _beforeEach, describe as _describe, expect as _expect, it as _it, mock, } from 'bun:test';
45
+ import { AsyncLocalStorage } from 'node:async_hooks';
46
+ import { defineOpContext } from '../defineOpContext.js';
47
+ import { JsBufferStrategy } from '../JsBufferStrategy.js';
48
+ import { S } from '../schema/builder.js';
49
+ import { LogSchema } from '../schema/LogSchema.js';
50
+ import { isSpanContext } from '../spanContext.js';
51
+ import { createTraceRoot } from '../traceRoot.universal.js';
52
+ import { CompositeTracer } from '../tracers/CompositeTracer.js';
53
+ import { SQLiteTracer } from '../tracers/SQLiteTracer.js';
54
+ import { StdioTracer } from '../tracers/StdioTracer.js';
55
+ import { TestTracer as InMemoryTestTracer } from '../tracers/TestTracer.js';
56
+ /** bun:test expect() errors start with 'expect(received).' — distinguishes assertion failures from other throws */
57
+ function isExpectError(error) {
58
+ return error instanceof Error && error.message.startsWith('expect(');
59
+ }
60
+ function writeDescribeTag(tag, describePath) {
61
+ if (!describePath || typeof tag !== 'object' || tag === null) {
62
+ return;
63
+ }
64
+ const describeWriter = Reflect.get(tag, 'describe');
65
+ if (typeof describeWriter === 'function') {
66
+ describeWriter.call(tag, describePath);
67
+ return;
68
+ }
69
+ const batchWriter = Reflect.get(tag, 'with');
70
+ if (typeof batchWriter === 'function') {
71
+ batchWriter.call(tag, { describe: describePath });
72
+ }
73
+ }
74
+ const ciOnlyDisabledMessage = '.only is disabled in CI environments to prevent accidentally skipping tests. To override, set the environment variable CI=false.';
75
+ // WHY: Package-local `nx test` runs Bun from that package directory, so the
76
+ // shared preload must not eagerly import unrelated packages' tracer modules just
77
+ // to find one opContext. A tiny fallback binding keeps tracing active for
78
+ // packages that only need SQLite-backed test spans and do not define their own
79
+ // `src/test-suite-tracer.ts`.
80
+ const defaultAutoSetupOpContext = defineOpContext({ logSchema: new LogSchema({}) });
81
+ function buildHarnessSchemaExtensions(binding, extraTestColumns) {
82
+ const extensionBase = { describe: S.category() };
83
+ const baseColumnNames = new Set(binding.logBinding.logSchema._columnNames);
84
+ for (const fieldName of Object.keys(extraTestColumns ?? {})) {
85
+ if (baseColumnNames.has(fieldName)) {
86
+ throw new Error(`Test harness schema column '${fieldName}' already exists in the bound log schema`);
87
+ }
88
+ }
89
+ return extraTestColumns ? { ...extensionBase, ...extraTestColumns } : extensionBase;
90
+ }
91
+ function extendBindingLogSchema(binding, extension) {
92
+ const extendedBinding = {
93
+ logBinding: {
94
+ ...binding.logBinding,
95
+ logSchema: binding.logBinding.logSchema.extend(extension),
96
+ },
97
+ flags: binding.flags,
98
+ ctxDefaults: binding.ctxDefaults,
99
+ deps: binding.deps,
100
+ };
101
+ return extendedBinding;
102
+ }
103
+ function isTruthyEnvFlag(value) {
104
+ return value === true || value === '1' || value === 'true';
105
+ }
106
+ function isSchemaFieldsRecord(value) {
107
+ return typeof value === 'object' && value !== null;
108
+ }
109
+ function isOpContextBindingLike(value) {
110
+ return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'logBinding') === 'object';
111
+ }
112
+ function isSpanContextForBinding(value, binding) {
113
+ return isSpanContext(value) && Reflect.get(value, '_schema') === binding.logBinding.logSchema;
114
+ }
115
+ function isTracerForBinding(value, binding) {
116
+ const logBinding = typeof value === 'object' && value !== null ? Reflect.get(value, 'logBinding') : null;
117
+ return (typeof logBinding === 'object' &&
118
+ logBinding !== null &&
119
+ Reflect.get(logBinding, 'logSchema') === binding.logBinding.logSchema);
120
+ }
121
+ function isVerboseTraceEnabled(explicitVerbose) {
122
+ if (explicitVerbose !== undefined) {
123
+ return explicitVerbose;
124
+ }
125
+ const globalVerbose = Reflect.get(globalThis, '__LMAO_TEST_TRACE_VERBOSE__');
126
+ if (isTruthyEnvFlag(globalVerbose)) {
127
+ return true;
128
+ }
129
+ return isTruthyEnvFlag(process.env.LMAO_TEST_TRACE_VERBOSE);
130
+ }
131
+ function createRootTracer({ binding, sqlite, verbose, }) {
132
+ const tracerOptions = {
133
+ bufferStrategy: new JsBufferStrategy(),
134
+ createTraceRoot,
135
+ };
136
+ if (sqlite) {
137
+ const db = new Database(sqlite.dbPath ?? '.trace-results.db');
138
+ const sqliteTracer = new SQLiteTracer(binding, {
139
+ ...tracerOptions,
140
+ db,
141
+ });
142
+ if (verbose) {
143
+ const stdioTracer = new StdioTracer(binding, {
144
+ ...tracerOptions,
145
+ });
146
+ return new CompositeTracer(binding, {
147
+ ...tracerOptions,
148
+ delegates: [stdioTracer, sqliteTracer],
149
+ });
150
+ }
151
+ return sqliteTracer;
152
+ }
153
+ if (verbose) {
154
+ return new StdioTracer(binding, {
155
+ ...tracerOptions,
156
+ });
157
+ }
158
+ return new InMemoryTestTracer(binding, {
159
+ ...tracerOptions,
160
+ });
161
+ }
162
+ async function closeTracer(tracer) {
163
+ const close = Reflect.get(tracer, 'close');
164
+ if (typeof close === 'function') {
165
+ await close.call(tracer);
166
+ }
167
+ }
168
+ let _activeSuiteTracer = null;
169
+ /** Returns the active suite tracer set by installBunTestTracing(), or null if none is active. */
170
+ export function getActiveSuiteTracer() {
171
+ return _activeSuiteTracer;
172
+ }
173
+ export function installBunTestTracing(tracer) {
174
+ _activeSuiteTracer = tracer;
175
+ tracer.setup();
176
+ mock.module('bun:test', () => tracer.createBunTestMock(bunTest));
177
+ }
178
+ export function makeBunTestSuiteTracer(binding, options) {
179
+ const useTestTracer = createTestTracerInstance(binding, options);
180
+ return {
181
+ useTestTracer,
182
+ useTestSpan: () => useTestTracer.useTestSpan(),
183
+ setupBunTestSuiteTracing: () => installBunTestTracing(useTestTracer),
184
+ };
185
+ }
186
+ /**
187
+ * Define a per-package test tracer — metadata for preload discovery + typed span accessor.
188
+ *
189
+ * Returns plain data that `autoSetupBunTestTracing` reads at discovery time, plus a
190
+ * `useTestSpan()` that threads the package-local binding through the generic
191
+ * `useTestSpan<B>()` helper.
192
+ *
193
+ * WHY generic threading: `autoSetupBunTestTracing` creates the active tracer from the
194
+ * same `opContext` binding passed here, so the exported helper can preserve the real
195
+ * span type without a local assertion bridge.
196
+ */
197
+ export function defineTestTracer(binding, options) {
198
+ return {
199
+ opContext: binding,
200
+ extraTestColumns: options?.extraTestColumns,
201
+ // WHY no re-validation: the global useTestSpan() already validates against
202
+ // the active suite tracer's (extended) binding. Re-checking against the
203
+ // original binding fails when extraTestColumns extend the schema, because
204
+ // the span's _schema is the extended LogSchema, not the original.
205
+ // 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
206
+ useTestSpan: () => useTestSpan(),
207
+ };
208
+ }
209
+ export function makeTestTracer(binding, options) {
210
+ return createTestTracerInstance(binding, options);
211
+ }
212
+ function createTestTracerInstance(binding, options) {
213
+ let activeBinding = null;
214
+ let tracer = null;
215
+ let verboseTrace = false;
216
+ let rootCtx = null;
217
+ let resolveTestRun = null;
218
+ let rootTracePromise = null;
219
+ let isSetup = false;
220
+ const als = new AsyncLocalStorage();
221
+ function assertRootCtx() {
222
+ if (!rootCtx || !activeBinding || !isSpanContextForBinding(rootCtx, activeBinding)) {
223
+ throw new Error('Call setup() before wiring bun:test wrappers');
224
+ }
225
+ return rootCtx;
226
+ }
227
+ function assertTracer() {
228
+ if (!tracer || !activeBinding || !isTracerForBinding(tracer, activeBinding)) {
229
+ throw new Error('Call setup() in preload before tests');
230
+ }
231
+ return tracer;
232
+ }
233
+ function runTracedTest(name, fn, describePath) {
234
+ const currentRoot = assertRootCtx();
235
+ return currentRoot.span(name, async (ctx) => {
236
+ writeDescribeTag(ctx.tag, describePath);
237
+ try {
238
+ await als.run(ctx, () => fn(() => undefined));
239
+ return ctx.ok(undefined); // pass -> span-ok
240
+ }
241
+ catch (error) {
242
+ if (isExpectError(error)) {
243
+ ctx.err(error); // record assertion failure in span
244
+ throw error; // re-throw so bun:test sees the failure
245
+ }
246
+ throw error; // other throw -> span-exception
247
+ }
248
+ });
249
+ }
250
+ function createWrappedDescribe(origDescribe, describeStack) {
251
+ function wrappedDescribeBase(nameOrFn, fn) {
252
+ if (fn === undefined && typeof nameOrFn === 'function') {
253
+ origDescribe(() => nameOrFn());
254
+ return;
255
+ }
256
+ const describeFn = fn;
257
+ if (!describeFn) {
258
+ throw new TypeError('describe callback is required');
259
+ }
260
+ origDescribe(nameOrFn, () => {
261
+ describeStack.push(String(nameOrFn));
262
+ try {
263
+ describeFn();
264
+ }
265
+ finally {
266
+ describeStack.pop();
267
+ }
268
+ });
269
+ }
270
+ const wrappedDescribe = Object.assign(wrappedDescribeBase, {
271
+ skip: origDescribe.skip,
272
+ only: process.env.CI ? createDisabledDescribe(origDescribe) : origDescribe.only,
273
+ todo: origDescribe.todo,
274
+ concurrent: origDescribe.concurrent,
275
+ serial: origDescribe.serial,
276
+ if: origDescribe.if,
277
+ skipIf: origDescribe.skipIf,
278
+ todoIf: origDescribe.todoIf,
279
+ each: origDescribe.each,
280
+ });
281
+ assignOnly(wrappedDescribe, origDescribe, origDescribe);
282
+ assignOptionalBoundTestFunction(wrappedDescribe, 'each', origDescribe, origDescribe);
283
+ wrappedDescribe.skipIf = (condition) => (condition ? origDescribe.skip : wrappedDescribe);
284
+ wrappedDescribe.if = (condition) => (condition ? wrappedDescribe : origDescribe.skip);
285
+ return wrappedDescribe;
286
+ }
287
+ function createWrappedIt(origIt, describeStack) {
288
+ function wrappedItBase(name, fn, options) {
289
+ const describePath = describeStack.length > 0 ? describeStack.join(' > ') : null;
290
+ origIt(name, () => runTracedTest(name, fn, describePath), options);
291
+ }
292
+ const wrappedIt = Object.assign(wrappedItBase, {
293
+ skip: origIt.skip,
294
+ only: process.env.CI ? createDisabledIt(origIt) : origIt.only,
295
+ todo: origIt.todo?.bind(origIt),
296
+ failing: origIt.failing,
297
+ concurrent: origIt.concurrent,
298
+ serial: origIt.serial,
299
+ if: origIt.if,
300
+ skipIf: origIt.skipIf,
301
+ todoIf: origIt.todoIf,
302
+ failingIf: origIt.failingIf,
303
+ concurrentIf: origIt.concurrentIf,
304
+ serialIf: origIt.serialIf,
305
+ each: origIt.each,
306
+ });
307
+ assignOnly(wrappedIt, origIt, origIt);
308
+ assignOptionalBoundTestFunction(wrappedIt, 'each', origIt, origIt);
309
+ wrappedIt.skipIf = (condition) => (condition ? origIt.skip : wrappedIt);
310
+ wrappedIt.if = (condition) => (condition ? wrappedIt : origIt.skip);
311
+ return wrappedIt;
312
+ }
313
+ return {
314
+ setup() {
315
+ if (isSetup) {
316
+ return;
317
+ }
318
+ isSetup = true;
319
+ const harnessSchema = options?.extraTestColumns === undefined
320
+ ? buildHarnessSchemaExtensions(binding, undefined)
321
+ : buildHarnessSchemaExtensions(binding, options.extraTestColumns);
322
+ const extendedBinding = extendBindingLogSchema(binding, harnessSchema);
323
+ activeBinding = extendedBinding;
324
+ verboseTrace = isVerboseTraceEnabled(options?.verbose);
325
+ const activeTracer = createRootTracer({
326
+ binding: extendedBinding,
327
+ sqlite: options?.sqlite,
328
+ verbose: verboseTrace,
329
+ });
330
+ tracer = activeTracer;
331
+ rootTracePromise = activeTracer.trace('test-run', (ctx) => {
332
+ rootCtx = ctx;
333
+ return new Promise((resolve) => {
334
+ resolveTestRun = resolve;
335
+ });
336
+ });
337
+ _afterAll(async () => {
338
+ if (resolveTestRun) {
339
+ resolveTestRun();
340
+ resolveTestRun = null;
341
+ }
342
+ if (rootTracePromise) {
343
+ await rootTracePromise;
344
+ rootTracePromise = null;
345
+ }
346
+ if (tracer) {
347
+ try {
348
+ await tracer.flush();
349
+ if (options?.sqlite && rootCtx) {
350
+ const traceId = rootCtx.buffer.trace_id;
351
+ const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
352
+ console.log(`\n[trace] trace_id: ${traceId} -> ${dbPath}`);
353
+ }
354
+ }
355
+ catch (e) {
356
+ console.error('[lmao/testing] SQLite flush error:', e);
357
+ }
358
+ finally {
359
+ await closeTracer(tracer);
360
+ }
361
+ }
362
+ });
363
+ },
364
+ useTestSpan() {
365
+ const ctx = als.getStore();
366
+ if (!ctx || !activeBinding || !isSpanContextForBinding(ctx, activeBinding)) {
367
+ throw new Error('useTestSpan() called outside of a traced it()');
368
+ }
369
+ return ctx;
370
+ },
371
+ getTracer() {
372
+ return assertTracer();
373
+ },
374
+ createBunTestMock(bunTestModule) {
375
+ const origIt = bunTestModule.it;
376
+ const origDescribe = bunTestModule.describe;
377
+ const describeStack = [];
378
+ const wrappedDescribe = createWrappedDescribe(origDescribe, describeStack);
379
+ const wrappedIt = createWrappedIt(origIt, describeStack);
380
+ return {
381
+ ...bunTestModule,
382
+ describe: wrappedDescribe,
383
+ it: wrappedIt,
384
+ test: wrappedIt,
385
+ };
386
+ },
387
+ };
388
+ }
389
+ // Global singleton — one root tracer for the entire bun test run
390
+ let _tracer = null;
391
+ let _verboseTrace = false;
392
+ // Root span context, its resolver, and the trace promise — one root per test run
393
+ let _rootCtx = null;
394
+ let _resolveTestRun = null;
395
+ let _rootTracePromise = null;
396
+ // AsyncLocalStorage for propagating SpanContext to test bodies.
397
+ // Each it() runs in its own async context so concurrent tests don't collide.
398
+ const _als = new AsyncLocalStorage();
399
+ /** Initialize the root tracer for the entire bun test run. Call once in preload. */
400
+ export function initTraceTestRun(opContext, options) {
401
+ _activeSuiteTracer = null;
402
+ // Extend user's schema with `describe` column for test grouping
403
+ const harnessSchema = options?.extraTestColumns === undefined
404
+ ? buildHarnessSchemaExtensions(opContext, undefined)
405
+ : buildHarnessSchemaExtensions(opContext, options.extraTestColumns);
406
+ const extendedSchema = opContext.logBinding.logSchema.extend(harnessSchema);
407
+ const extendedBinding = {
408
+ ...opContext,
409
+ logBinding: { ...opContext.logBinding, logSchema: extendedSchema },
410
+ };
411
+ _verboseTrace = isVerboseTraceEnabled(options?.verbose);
412
+ _tracer = createRootTracer({
413
+ binding: extendedBinding,
414
+ sqlite: options?.sqlite,
415
+ verbose: _verboseTrace,
416
+ });
417
+ // Create the single root trace — a long-lived promise keeps it alive
418
+ const tracer = _tracer;
419
+ _rootTracePromise = tracer.trace('test-run', (ctx) => {
420
+ _rootCtx = ctx;
421
+ return new Promise((resolve) => {
422
+ _resolveTestRun = resolve;
423
+ });
424
+ });
425
+ // Register global teardown — resolve root, wait for span-end, then flush tracer outputs
426
+ _afterAll(async () => {
427
+ // Resolve the root promise — triggers span-end write via _executeWithContext .then()
428
+ if (_resolveTestRun) {
429
+ _resolveTestRun();
430
+ _resolveTestRun = null;
431
+ }
432
+ // Await the trace promise so span-end is written to the buffer before flushing
433
+ if (_rootTracePromise) {
434
+ await _rootTracePromise;
435
+ _rootTracePromise = null;
436
+ }
437
+ if (_tracer) {
438
+ try {
439
+ await _tracer.flush();
440
+ if (options?.sqlite && _rootCtx) {
441
+ const traceId = _rootCtx.buffer.trace_id;
442
+ const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
443
+ console.log(`\n[trace] trace_id: ${traceId} → ${dbPath}`);
444
+ }
445
+ }
446
+ catch (e) {
447
+ console.error('[lmao/testing] SQLite flush error:', e);
448
+ }
449
+ finally {
450
+ await closeTracer(_tracer);
451
+ }
452
+ }
453
+ });
454
+ }
455
+ /**
456
+ * Create a bun:test mock replacement that wraps it()/test() in trace spans.
457
+ *
458
+ * Call this from the preload file and pass the result to mock.module:
459
+ * ```typescript
460
+ * mock.module('bun:test', () => createBunTestMock(bunTest));
461
+ * ```
462
+ *
463
+ * @param bunTestModule - The original bun:test namespace (`import * as bunTest from 'bun:test'`)
464
+ */
465
+ export function createBunTestMock(bunTestModule) {
466
+ if (!_rootCtx) {
467
+ if (_activeSuiteTracer) {
468
+ return _activeSuiteTracer.createBunTestMock(bunTestModule);
469
+ }
470
+ throw new Error('Call initTraceTestRun() before createBunTestMock()');
471
+ }
472
+ const origIt = bunTestModule.it;
473
+ const origDescribe = bunTestModule.describe;
474
+ const rootCtx = _rootCtx;
475
+ const als = _als;
476
+ const describeStack = [];
477
+ // describe() callbacks run synchronously (just registering tests)
478
+ function wrappedDescribe(name, fn) {
479
+ return origDescribe(name, () => {
480
+ describeStack.push(name);
481
+ try {
482
+ fn();
483
+ }
484
+ finally {
485
+ describeStack.pop();
486
+ }
487
+ });
488
+ }
489
+ // skipIf/if must return wrappedDescribe (not origDescribe) when the suite should run,
490
+ // so that describe-path tracking stays active for nested it() calls.
491
+ Object.assign(wrappedDescribe, {
492
+ skip: origDescribe.skip,
493
+ todo: origDescribe.todo,
494
+ skipIf: (condition) => (condition ? origDescribe.skip : wrappedDescribe),
495
+ if: (condition) => (condition ? wrappedDescribe : origDescribe.skip),
496
+ });
497
+ assignOnly(wrappedDescribe, origDescribe, origDescribe);
498
+ assignOptionalBoundTestFunction(wrappedDescribe, 'each', origDescribe, origDescribe);
499
+ function wrappedIt(name, fn) {
500
+ // Capture describe path at registration time (synchronous)
501
+ const describePath = describeStack.length > 0 ? describeStack.join(' > ') : null;
502
+ return origIt(name, () => rootCtx.span(name, async (ctx) => {
503
+ writeDescribeTag(ctx.tag, describePath);
504
+ try {
505
+ await als.run(ctx, fn);
506
+ return ctx.ok(undefined); // pass → span-ok
507
+ }
508
+ catch (error) {
509
+ if (isExpectError(error)) {
510
+ ctx.err(error); // record assertion failure in span
511
+ throw error; // re-throw so bun:test sees the failure
512
+ }
513
+ throw error; // other throw → span-exception
514
+ }
515
+ }));
516
+ }
517
+ // skipIf/if must return wrappedIt (not origIt) when the test should run,
518
+ // so the ALS context is set up and useTestSpan() works inside the test body.
519
+ Object.assign(wrappedIt, {
520
+ skip: origIt.skip,
521
+ todo: origIt.todo,
522
+ skipIf: (condition) => (condition ? origIt.skip : wrappedIt),
523
+ if: (condition) => (condition ? wrappedIt : origIt.skip),
524
+ });
525
+ assignOnly(wrappedIt, origIt, origIt);
526
+ assignOptionalBoundTestFunction(wrappedIt, 'each', origIt, origIt);
527
+ return {
528
+ ...bunTestModule,
529
+ describe: wrappedDescribe,
530
+ it: wrappedIt,
531
+ test: wrappedIt,
532
+ };
533
+ }
534
+ export function useTestSpan() {
535
+ if (_activeSuiteTracer) {
536
+ return _activeSuiteTracer.useTestSpan();
537
+ }
538
+ const ctx = _als.getStore();
539
+ if (!ctx)
540
+ throw new Error('useTestSpan() called outside of a traced it()');
541
+ return ctx;
542
+ }
543
+ /**
544
+ * Get the root tracer instance.
545
+ *
546
+ * The optional type parameter narrows the return type for consumers that know
547
+ * the concrete binding (e.g. `getTracer<typeof opContext>()`). The underlying
548
+ * tracer is always the one created by `installBunTestTracing()` or `initTraceTestRun()`.
549
+ */
550
+ export function getTracer() {
551
+ if (_activeSuiteTracer) {
552
+ return _activeSuiteTracer.getTracer();
553
+ }
554
+ if (!_tracer)
555
+ throw new Error('Call initTraceTestRun() in preload before tests');
556
+ return _tracer;
557
+ }
558
+ /**
559
+ * Wrapped describe — tracks describe nesting for the standalone export path.
560
+ * describe() callbacks run synchronously (just registering tests).
561
+ */
562
+ export function describe(name, fn) {
563
+ return _describe(name, () => {
564
+ _standaloneDescribeStack.push(name);
565
+ try {
566
+ fn();
567
+ }
568
+ finally {
569
+ _standaloneDescribeStack.pop();
570
+ }
571
+ });
572
+ }
573
+ // Describe stack for standalone exports (non-mock-module path)
574
+ const _standaloneDescribeStack = [];
575
+ function assignOptionalBoundTestFunction(target, key, source, thisArg) {
576
+ const value = Reflect.get(source, key);
577
+ if (typeof value === 'function') {
578
+ Reflect.set(target, key, value.bind(thisArg));
579
+ }
580
+ }
581
+ function disabledOnly() {
582
+ throw new Error(ciOnlyDisabledMessage);
583
+ }
584
+ function createDisabledDescribe(source) {
585
+ const disabledDescribe = Object.assign((_label, _fn) => disabledOnly(), {
586
+ skip: source.skip,
587
+ only: source.skip,
588
+ todo: source.todo,
589
+ concurrent: source.concurrent,
590
+ serial: source.serial,
591
+ if: source.if,
592
+ skipIf: source.skipIf,
593
+ todoIf: source.todoIf,
594
+ each: source.each,
595
+ });
596
+ disabledDescribe.only = disabledDescribe;
597
+ return disabledDescribe;
598
+ }
599
+ function createDisabledIt(source) {
600
+ const disabledIt = Object.assign((_label, _fn, _options) => disabledOnly(), {
601
+ skip: source.skip,
602
+ only: source.skip,
603
+ todo: source.todo,
604
+ failing: source.failing,
605
+ concurrent: source.concurrent,
606
+ serial: source.serial,
607
+ if: source.if,
608
+ skipIf: source.skipIf,
609
+ todoIf: source.todoIf,
610
+ failingIf: source.failingIf,
611
+ concurrentIf: source.concurrentIf,
612
+ serialIf: source.serialIf,
613
+ each: source.each,
614
+ });
615
+ disabledIt.only = disabledIt;
616
+ return disabledIt;
617
+ }
618
+ function assignOnly(target, source, thisArg) {
619
+ if (process.env.CI) {
620
+ Reflect.set(target, 'only', disabledOnly);
621
+ return;
622
+ }
623
+ assignOptionalBoundTestFunction(target, 'only', source, thisArg);
624
+ }
625
+ describe.skip = _describe.skip;
626
+ assignOnly(describe, _describe, _describe);
627
+ describe.todo = _describe.todo;
628
+ assignOptionalBoundTestFunction(describe, 'each', _describe, _describe);
629
+ assignOptionalBoundTestFunction(describe, 'skipIf', _describe, _describe);
630
+ assignOptionalBoundTestFunction(describe, 'if', _describe, _describe);
631
+ /** Wrapped it — creates a child span of the root trace for the test case */
632
+ export function it(name, fn) {
633
+ const describePath = _standaloneDescribeStack.length > 0 ? _standaloneDescribeStack.join(' > ') : null;
634
+ _it(name, () => {
635
+ if (!_rootCtx)
636
+ throw new Error('Call initTraceTestRun() in preload before tests');
637
+ return _rootCtx.span(name, async (ctx) => {
638
+ writeDescribeTag(ctx.tag, describePath);
639
+ try {
640
+ await _als.run(ctx, fn);
641
+ return ctx.ok(undefined); // pass → span-ok
642
+ }
643
+ catch (error) {
644
+ if (isExpectError(error))
645
+ return ctx.err(error); // expect() fail → span-err
646
+ throw error; // other throw → span-exception
647
+ }
648
+ });
649
+ });
650
+ }
651
+ it.skip = _it.skip;
652
+ assignOnly(it, _it, _it);
653
+ it.todo = _it.todo;
654
+ assignOptionalBoundTestFunction(it, 'each', _it, _it);
655
+ assignOptionalBoundTestFunction(it, 'skipIf', _it, _it);
656
+ assignOptionalBoundTestFunction(it, 'if', _it, _it);
657
+ // Re-export everything else unchanged
658
+ export { _afterAll as afterAll, _afterEach as afterEach, _beforeAll as beforeAll, _beforeEach as beforeEach, _expect as expect, };
659
+ /**
660
+ * Auto-discover package test-suite-tracers and create the root tracer for the
661
+ * current bun test run.
662
+ *
663
+ * When Bun is running from inside `packages/<name>`, prefer that package's own
664
+ * `src/test-suite-tracer.ts` and avoid importing unrelated packages. Repo-root
665
+ * runs still fall back to the full scan so cross-package test runs keep the
666
+ * merged-schema behavior.
667
+ *
668
+ * Per-package `useTestSpan()` delegates to the global `useTestSpan()` from this
669
+ * module which checks `_activeSuiteTracer` — set by the root preload via
670
+ * `installBunTestTracing()`.
671
+ *
672
+ * @example
673
+ * ```ts
674
+ * // test-trace-preload.ts (monorepo root)
675
+ * import { autoSetupBunTestTracing } from './packages/lmao/src/lib/testing/bun-harness.js';
676
+ * await autoSetupBunTestTracing({ packagesDir: './packages' });
677
+ * ```
678
+ */
679
+ export async function autoSetupBunTestTracing(options) {
680
+ const { join, relative, resolve, sep } = await import('node:path');
681
+ const { existsSync, readdirSync } = await import('node:fs');
682
+ const packagesDir = resolve(options.packagesDir);
683
+ if (!existsSync(packagesDir))
684
+ return false;
685
+ const installSuite = (opContext, mergedSchema) => {
686
+ const hasCustomSchema = Object.keys(mergedSchema).length > 0;
687
+ const suite = makeBunTestSuiteTracer(opContext, {
688
+ sqlite: { dbPath: '.trace-results.db' },
689
+ extraTestColumns: hasCustomSchema && isSchemaFieldsRecord(mergedSchema) ? mergedSchema : undefined,
690
+ });
691
+ suite.setupBunTestSuiteTracing();
692
+ return true;
693
+ };
694
+ const cwd = resolve(process.cwd());
695
+ const relativeToPackagesDir = relative(packagesDir, cwd);
696
+ const isPackageLocalRun = relativeToPackagesDir !== '' &&
697
+ !relativeToPackagesDir.startsWith('..') &&
698
+ !relativeToPackagesDir.startsWith(`.${sep}`);
699
+ if (isPackageLocalRun) {
700
+ const [packageName] = relativeToPackagesDir.split(sep);
701
+ const tracerPath = join(packagesDir, packageName, 'src', 'test-suite-tracer.ts');
702
+ if (!existsSync(tracerPath)) {
703
+ return installSuite(defaultAutoSetupOpContext, {});
704
+ }
705
+ const mod = await import(tracerPath);
706
+ const mergedSchema = isSchemaFieldsRecord(mod.extraTestColumns) ? mod.extraTestColumns : {};
707
+ const opContext = isOpContextBindingLike(mod.opContext) ? mod.opContext : defaultAutoSetupOpContext;
708
+ return installSuite(opContext, mergedSchema);
709
+ }
710
+ const mergedSchema = {};
711
+ let opContext = null;
712
+ for (const entry of readdirSync(packagesDir, { withFileTypes: true })) {
713
+ if (!entry.isDirectory())
714
+ continue;
715
+ const tracerPath = join(packagesDir, entry.name, 'src', 'test-suite-tracer.ts');
716
+ if (!existsSync(tracerPath))
717
+ continue;
718
+ const mod = await import(tracerPath);
719
+ // Collect custom schema columns from each package
720
+ if (mod.extraTestColumns && typeof mod.extraTestColumns === 'object') {
721
+ Object.assign(mergedSchema, mod.extraTestColumns);
722
+ }
723
+ // Use the first available opContext (they all bind the same opContext)
724
+ if (!opContext && isOpContextBindingLike(mod.opContext)) {
725
+ opContext = mod.opContext;
726
+ }
727
+ }
728
+ return installSuite(opContext ?? defaultAutoSetupOpContext, mergedSchema);
729
+ }