@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,443 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ // Must import test-helpers first to initialize timestamp implementation
3
+ import '../../__tests__/test-helpers.js';
4
+ import { createTestTracerOptions } from '../../__tests__/test-helpers.js';
5
+ import { defineOpContext } from '../../defineOpContext.js';
6
+ import { TestTracer } from '../../tracers/TestTracer.js';
7
+ import type { AnySpanBuffer } from '../../types.js';
8
+ import { S } from '../builder.js';
9
+ import { defineFeatureFlags } from '../defineFeatureFlags.js';
10
+ import { defineLogSchema } from '../defineLogSchema.js';
11
+ import { InMemoryFlagEvaluator } from '../evaluator.js';
12
+ import { ENTRY_TYPE_FF_ACCESS, ENTRY_TYPE_FF_USAGE } from '../systemSchema.js';
13
+
14
+ /**
15
+ * Helper to count entries of a specific type in the buffer
16
+ */
17
+ function countEntryType(buffer: AnySpanBuffer, entryType: number): number {
18
+ let count = 0;
19
+ let current: AnySpanBuffer | undefined = buffer;
20
+ while (current) {
21
+ const writeIndex = current._writeIndex;
22
+ for (let i = 0; i < writeIndex; i++) {
23
+ if (current.entry_type[i] === entryType) {
24
+ count++;
25
+ }
26
+ }
27
+ current = current._overflow;
28
+ }
29
+ return count;
30
+ }
31
+
32
+ describe('Feature Flags', () => {
33
+ // Define a minimal log schema for tests
34
+ const testLogSchema = defineLogSchema({});
35
+
36
+ test('defines feature flags with sync/async markers', () => {
37
+ const flags = defineFeatureFlags({
38
+ debugMode: S.boolean().default(false).sync(),
39
+ maxRetries: S.number().default(3).sync(),
40
+ userSpecificLimit: S.number().default(100).async(),
41
+ });
42
+
43
+ expect(flags.schema).toBeDefined();
44
+ expect(flags.syncFlags).toContain('debugMode');
45
+ expect(flags.syncFlags).toContain('maxRetries');
46
+ expect(flags.asyncFlags).toContain('userSpecificLimit');
47
+ });
48
+
49
+ test('evaluator returns FlagContext for truthy flags', async () => {
50
+ const flags = defineFeatureFlags({
51
+ debugMode: S.boolean().default(false).sync(),
52
+ maxRetries: S.number().default(3).sync(),
53
+ });
54
+
55
+ const ctx = defineOpContext({
56
+ logSchema: testLogSchema,
57
+ flags: flags.schema,
58
+ });
59
+
60
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, {
61
+ debugMode: true,
62
+ maxRetries: 5,
63
+ });
64
+
65
+ const { trace } = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
66
+ const result = await trace('test-span', async (ctx) => {
67
+ const ff = ctx.ff;
68
+
69
+ expect(ff.debugMode).toBeDefined();
70
+ expect(ff.debugMode?.value).toBe(true);
71
+ expect(typeof ff.debugMode?.track).toBe('function');
72
+
73
+ expect(ff.maxRetries).toBeDefined();
74
+ expect(ff.maxRetries?.value).toBe(5);
75
+ expect(typeof ff.maxRetries?.track).toBe('function');
76
+
77
+ return ctx.ok(null);
78
+ });
79
+
80
+ expect(result.success).toBe(true);
81
+ });
82
+
83
+ test('feature-flag runtime stays worker-safe', async () => {
84
+ const flags = defineFeatureFlags({
85
+ debugMode: S.boolean().default(false).sync(),
86
+ });
87
+
88
+ const ctx = defineOpContext({
89
+ logSchema: testLogSchema,
90
+ flags: flags.schema,
91
+ });
92
+
93
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, { debugMode: true });
94
+ const tracer = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
95
+
96
+ await tracer.trace('worker-safe-evaluator', async (spanCtx) => {
97
+ expect(spanCtx.ff.debugMode?.value).toBe(true);
98
+ expect(spanCtx.ff.constructor.toString()).not.toContain('new Function');
99
+ return spanCtx.ok(null);
100
+ });
101
+ });
102
+
103
+ test('evaluator returns undefined for falsy flags', async () => {
104
+ const flags = defineFeatureFlags({
105
+ debugMode: S.boolean().default(false).sync(),
106
+ userLimit: S.number().default(100).async(),
107
+ });
108
+
109
+ const ctx = defineOpContext({
110
+ logSchema: testLogSchema,
111
+ flags: flags.schema,
112
+ });
113
+
114
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, {}); // No flags set → null values
115
+
116
+ const { trace } = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
117
+ await trace('test-span', async (ctx) => {
118
+ const ff = ctx.ff;
119
+ expect(ff.debugMode).toBeUndefined();
120
+ return ctx.ok(null);
121
+ });
122
+ });
123
+
124
+ test('async flags return FlagContext via get method', async () => {
125
+ const flags = defineFeatureFlags({
126
+ userSpecificLimit: S.number().default(100).async(),
127
+ dynamicProvider: S.enum(['stripe', 'paypal']).default('stripe').async(),
128
+ });
129
+
130
+ const ctx = defineOpContext({
131
+ logSchema: testLogSchema,
132
+ flags: flags.schema,
133
+ });
134
+
135
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, {
136
+ userSpecificLimit: 200,
137
+ dynamicProvider: 'paypal',
138
+ });
139
+
140
+ const { trace } = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
141
+ await trace('test-span', async (ctx) => {
142
+ // Async flags accessed via get() return FlagContext
143
+ const limit = await ctx.ff.get('userSpecificLimit');
144
+ expect(limit).toBeDefined();
145
+ expect(limit?.value).toBe(200);
146
+
147
+ const provider = await ctx.ff.get('dynamicProvider');
148
+ expect(provider).toBeDefined();
149
+ expect(provider?.value).toBe('paypal');
150
+
151
+ return ctx.ok(null);
152
+ });
153
+ });
154
+
155
+ test('track() on FlagContext logs usage events', async () => {
156
+ const flags = defineFeatureFlags({
157
+ advancedValidation: S.boolean().default(false).sync(),
158
+ });
159
+
160
+ const ctx = defineOpContext({
161
+ logSchema: testLogSchema,
162
+ flags: flags.schema,
163
+ });
164
+
165
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, {
166
+ advancedValidation: true,
167
+ });
168
+
169
+ const { trace } = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
170
+ await trace('test-span', async (ctx) => {
171
+ const flag = ctx.ff.advancedValidation;
172
+
173
+ // track() returns fluent log entry so additional fields can be tagged
174
+ flag?.track({ action: 'validation_performed', outcome: 'success' }).ff_value('used').line(123);
175
+
176
+ // Check buffer for ff-usage entry
177
+ const usageCount = countEntryType(ctx.buffer, ENTRY_TYPE_FF_USAGE);
178
+ expect(usageCount).toBe(1);
179
+
180
+ return ctx.ok(null);
181
+ });
182
+ });
183
+
184
+ test('sync flag access is logged only once per span', async () => {
185
+ const flags = defineFeatureFlags({
186
+ debugMode: S.boolean().default(false).sync(),
187
+ });
188
+
189
+ const ctx = defineOpContext({
190
+ logSchema: testLogSchema,
191
+ flags: flags.schema,
192
+ });
193
+
194
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, { debugMode: true });
195
+
196
+ const { trace } = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
197
+ await trace('test-span', async (ctx) => {
198
+ // Access the flag multiple times
199
+ const value1 = ctx.ff.debugMode;
200
+ const value2 = ctx.ff.debugMode;
201
+ const value3 = ctx.ff.debugMode;
202
+
203
+ // All accesses should return same value (flag is truthy)
204
+ expect(value1?.value).toBe(true);
205
+ expect(value2?.value).toBe(true);
206
+ expect(value3?.value).toBe(true);
207
+
208
+ // Only ONE ff-access log should be written (deduplication via buffer scan)
209
+ const accessCount = countEntryType(ctx.buffer, ENTRY_TYPE_FF_ACCESS);
210
+ expect(accessCount).toBe(1);
211
+
212
+ return ctx.ok(null);
213
+ });
214
+ });
215
+
216
+ test('async flag access is logged', async () => {
217
+ const flags = defineFeatureFlags({
218
+ userLimit: S.number().default(100).async(),
219
+ });
220
+
221
+ const ctx = defineOpContext({
222
+ logSchema: testLogSchema,
223
+ flags: flags.schema,
224
+ });
225
+
226
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, { userLimit: 200 });
227
+
228
+ const { trace } = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
229
+ await trace('test-span', async (ctx) => {
230
+ const value = await ctx.ff.get('userLimit');
231
+ expect(value?.value).toBe(200);
232
+
233
+ // Check buffer for ff-access entry
234
+ const accessCount = countEntryType(ctx.buffer, ENTRY_TYPE_FF_ACCESS);
235
+ expect(accessCount).toBe(1);
236
+
237
+ return ctx.ok(null);
238
+ });
239
+ });
240
+
241
+ test('S.enum validates enum values', () => {
242
+ const schema = defineFeatureFlags({
243
+ environment: S.enum(['dev', 'staging', 'prod'] as const)
244
+ .default('dev')
245
+ .sync(),
246
+ });
247
+
248
+ expect(schema.schema.environment).toBeDefined();
249
+ expect(schema.schema.environment.defaultValue).toBe('dev');
250
+ expect(schema.schema.environment.evaluationType).toBe('sync');
251
+ });
252
+
253
+ test('S.enum throws on empty values', () => {
254
+ expect(() => {
255
+ S.enum([]);
256
+ }).toThrow('Enum must have at least one value');
257
+ });
258
+
259
+ test('multiple sync and async flags work together', async () => {
260
+ const flags = defineFeatureFlags({
261
+ // Sync flags
262
+ enableFeatureX: S.boolean().default(false).sync(),
263
+ maxConnectionPool: S.number().default(10).sync(),
264
+ logLevel: S.enum(['debug', 'info', 'warn', 'error'] as const)
265
+ .default('info')
266
+ .sync(),
267
+
268
+ // Async flags
269
+ userTier: S.category().default('free').async(),
270
+ customLimit: S.number().default(100).async(),
271
+ });
272
+
273
+ const ctx = defineOpContext({
274
+ logSchema: testLogSchema,
275
+ flags: flags.schema,
276
+ });
277
+
278
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, {
279
+ enableFeatureX: true,
280
+ maxConnectionPool: 20,
281
+ logLevel: 'debug',
282
+ userTier: 'premium',
283
+ customLimit: 500,
284
+ });
285
+
286
+ const { trace } = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
287
+ await trace('test-span', async (ctx) => {
288
+ // Test sync flags
289
+ expect(ctx.ff.enableFeatureX?.value).toBe(true);
290
+ expect(ctx.ff.maxConnectionPool?.value).toBe(20);
291
+ expect(ctx.ff.logLevel?.value).toBe('debug');
292
+
293
+ // Test async flags
294
+ const userTier = await ctx.ff.get('userTier');
295
+ expect(userTier?.value).toBe('premium');
296
+
297
+ const customLimit = await ctx.ff.get('customLimit');
298
+ expect(customLimit?.value).toBe(500);
299
+
300
+ return ctx.ok(null);
301
+ });
302
+ });
303
+
304
+ test('InMemoryFlagEvaluator setFlag updates values', async () => {
305
+ const schema = defineFeatureFlags({
306
+ testFlag: S.category().default('initial').sync(),
307
+ });
308
+ const evaluator = new InMemoryFlagEvaluator(schema.schema, {
309
+ testFlag: 'initial',
310
+ });
311
+
312
+ // getSync receives ctx as first param (can be empty object for simple evaluator)
313
+ const { trace } = new TestTracer(
314
+ defineOpContext({
315
+ logSchema: testLogSchema,
316
+ flags: schema.schema,
317
+ }),
318
+ { ...createTestTracerOptions(), flagEvaluator: evaluator },
319
+ );
320
+ await trace('sync-read-initial', async (ctx) => {
321
+ expect(evaluator.getSync(ctx, 'testFlag')).toBe('initial');
322
+ return ctx.ok(null);
323
+ });
324
+
325
+ evaluator.setFlag('testFlag', 'updated');
326
+
327
+ await trace('sync-read-updated', async (ctx) => {
328
+ expect(evaluator.getSync(ctx, 'testFlag')).toBe('updated');
329
+ return ctx.ok(null);
330
+ });
331
+ });
332
+
333
+ test('InMemoryFlagEvaluator works with async', async () => {
334
+ const schema = defineFeatureFlags({
335
+ asyncFlag: S.number().default(0).async(),
336
+ });
337
+ const evaluator = new InMemoryFlagEvaluator(schema.schema, {
338
+ asyncFlag: 42,
339
+ });
340
+
341
+ const { trace } = new TestTracer(
342
+ defineOpContext({
343
+ logSchema: testLogSchema,
344
+ flags: schema.schema,
345
+ }),
346
+ { ...createTestTracerOptions(), flagEvaluator: evaluator },
347
+ );
348
+ await trace('async-read', async (ctx) => {
349
+ expect(await evaluator.getAsync(ctx, 'asyncFlag')).toBe(42);
350
+ return ctx.ok(null);
351
+ });
352
+ });
353
+
354
+ test('forContext creates child evaluator bound to child SpanContext', async () => {
355
+ const flags = defineFeatureFlags({
356
+ debugMode: S.boolean().default(false).sync(),
357
+ });
358
+
359
+ const ctx = defineOpContext({
360
+ logSchema: testLogSchema,
361
+ flags: flags.schema,
362
+ });
363
+
364
+ const flagEvaluator = new InMemoryFlagEvaluator(flags.schema, { debugMode: true });
365
+
366
+ const { trace } = new TestTracer(ctx, { ...createTestTracerOptions(), flagEvaluator });
367
+ await trace('parent-span', async (parentCtx) => {
368
+ // Access flag in parent
369
+ expect(parentCtx.ff.debugMode?.value).toBe(true);
370
+
371
+ const parentAccessCount = countEntryType(parentCtx.buffer, ENTRY_TYPE_FF_ACCESS);
372
+ expect(parentAccessCount).toBe(1);
373
+
374
+ // Create child span - child gets its own ff evaluator via forContext
375
+ await parentCtx.span('child-span', async (childCtx) => {
376
+ expect(childCtx.ff.debugMode?.value).toBe(true);
377
+
378
+ // Access in child should log to child buffer
379
+ const childAccessCount = countEntryType(childCtx.buffer, ENTRY_TYPE_FF_ACCESS);
380
+ expect(childAccessCount).toBe(1);
381
+
382
+ return childCtx.ok(null);
383
+ });
384
+
385
+ return parentCtx.ok(null);
386
+ });
387
+ });
388
+
389
+ test('usage example from spec: undefined/truthy pattern', async () => {
390
+ const flags = defineFeatureFlags({
391
+ darkMode: S.boolean().default(false).sync(),
392
+ advancedSearch: S.boolean().default(false).sync(),
393
+ });
394
+
395
+ // Scenario 1: darkMode is enabled
396
+ const enabledCtx = defineOpContext({
397
+ logSchema: testLogSchema,
398
+ flags: flags.schema,
399
+ });
400
+
401
+ const enabledFlagEvaluator = new InMemoryFlagEvaluator(flags.schema, { darkMode: true });
402
+ const { trace: enabledTrace } = new TestTracer(enabledCtx, {
403
+ ...createTestTracerOptions(),
404
+ flagEvaluator: enabledFlagEvaluator,
405
+ });
406
+
407
+ await enabledTrace('test-enabled', async (ctx) => {
408
+ const darkMode = ctx.ff.darkMode;
409
+
410
+ // Truthy check works naturally with undefined/truthy semantics
411
+ if (darkMode) {
412
+ expect(darkMode.value).toBe(true);
413
+ darkMode.track({ action: 'applied' });
414
+ }
415
+
416
+ return ctx.ok(null);
417
+ });
418
+
419
+ // Scenario 2: darkMode is disabled
420
+ const disabledCtx = defineOpContext({
421
+ logSchema: testLogSchema,
422
+ flags: flags.schema,
423
+ });
424
+
425
+ const disabledFlagEvaluator = new InMemoryFlagEvaluator(flags.schema, { darkMode: false });
426
+ const { trace: disabledTrace } = new TestTracer(disabledCtx, {
427
+ ...createTestTracerOptions(),
428
+ flagEvaluator: disabledFlagEvaluator,
429
+ });
430
+
431
+ await disabledTrace('test-disabled', async (ctx) => {
432
+ const darkModeDisabled = ctx.ff.darkMode;
433
+
434
+ // Falsy check works - undefined is falsy
435
+ expect(darkModeDisabled).toBeUndefined();
436
+ if (!darkModeDisabled) {
437
+ expect(true).toBe(true);
438
+ }
439
+
440
+ return ctx.ok(null);
441
+ });
442
+ });
443
+ });
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Schema builder for lmao - extends arrow-builder's schema builder with feature flags, masking, and binary sugar
3
+ *
4
+ * This module re-exports the S object from arrow-builder and adds:
5
+ * - Feature flag support via .default().sync()/.async() pattern
6
+ * - Masking transformations for sensitive data
7
+ * - S.unknown() and S.object<T>() sugar for msgpack-encoded binary columns
8
+ * - S.binary() passthrough to arrow-builder's S.binary()
9
+ */
10
+
11
+ import { encode } from '@msgpack/msgpack';
12
+ import {
13
+ S as ArrowS,
14
+ type BinaryEncoder,
15
+ type LazyBinarySchema,
16
+ type LazyCategorySchema,
17
+ type LazyEnumSchema,
18
+ type LazyTextSchema,
19
+ type Schema,
20
+ } from '@smoothbricks/arrow-builder';
21
+ import type { FeatureFlagDefinition, FlagBuilderWithDefault, SchemaBuilder, SchemaOrFlagBuilder } from './types.js';
22
+
23
+ /**
24
+ * Msgpack encoder singleton -- per-value, synchronous.
25
+ * Encodes at flush time (cold path), not on the hot write path.
26
+ * @msgpack/msgpack already handles most types; functions/symbols become undefined (dropped silently).
27
+ *
28
+ * Both wrap @msgpack/msgpack's encode(). This encoder is private to the schema builder;
29
+ */
30
+ const msgpackEncoder: BinaryEncoder = {
31
+ encode(value: unknown): Uint8Array {
32
+ return encode(value) as Uint8Array;
33
+ },
34
+ };
35
+
36
+ /**
37
+ * Create a flag builder that wraps a schema object
38
+ * This allows schemas to be used for both tag attributes and feature flags
39
+ */
40
+ type SchemaWithFlagBuilder<TSchema extends Schema<Value>, Value> = TSchema & SchemaOrFlagBuilder<Value>;
41
+
42
+ function createSchemaWithFlagBuilder<Value, TSchema extends Schema<Value>>(
43
+ schema: TSchema,
44
+ ): SchemaWithFlagBuilder<TSchema, Value> {
45
+ const schemaWithBuilder: SchemaWithFlagBuilder<TSchema, Value> = Object.assign(schema, {
46
+ default(defaultValue: Value): FlagBuilderWithDefault<Value> {
47
+ return {
48
+ sync(): FeatureFlagDefinition<Value, 'sync'> {
49
+ return {
50
+ schema,
51
+ defaultValue,
52
+ evaluationType: 'sync' as const,
53
+ };
54
+ },
55
+ async(): FeatureFlagDefinition<Value, 'async'> {
56
+ return {
57
+ schema,
58
+ defaultValue,
59
+ evaluationType: 'async' as const,
60
+ };
61
+ },
62
+ };
63
+ },
64
+ });
65
+
66
+ return schemaWithBuilder;
67
+ }
68
+
69
+ /**
70
+ * Schema builder that wraps arrow-builder's S with feature flag support
71
+ *
72
+ * STRING TYPE SYSTEM (See specs/lmao/01a_trace_schema_system.md):
73
+ * Three distinct string types, each with different storage strategies:
74
+ * - S.enum(['A', 'B', 'C']) - Known values at compile time (Uint8Array, 1 byte)
75
+ * - S.category() - Repeated values (raw string storage, dictionary built at Arrow conversion)
76
+ * - S.text() - Unique values (no dictionary overhead)
77
+ */
78
+ const schemaBuilderImpl: SchemaBuilder = {
79
+ /**
80
+ * Create number schema
81
+ *
82
+ * Usage:
83
+ * - S.number() - any number for tag attributes
84
+ * - S.number().default(0).sync() - feature flag
85
+ */
86
+ number: () => {
87
+ const schema = ArrowS.number();
88
+ return createSchemaWithFlagBuilder(schema);
89
+ },
90
+
91
+ /**
92
+ * Create boolean schema
93
+ *
94
+ * Usage:
95
+ * - S.boolean() - for tag attributes
96
+ * - S.boolean().default(false).sync() - feature flag
97
+ */
98
+ boolean: () => {
99
+ const schema = ArrowS.boolean();
100
+ return createSchemaWithFlagBuilder(schema);
101
+ },
102
+
103
+ /**
104
+ * Wrap schema to make it optional
105
+ *
106
+ * Usage:
107
+ * - SchemaBuilder.optional(SchemaBuilder.string()) - string | undefined
108
+ */
109
+ optional: <T>(schema: Schema<T>): Schema<T | undefined, T | undefined> => {
110
+ return ArrowS.optional(schema);
111
+ },
112
+
113
+ /**
114
+ * Create union of multiple schemas
115
+ *
116
+ * Usage:
117
+ * - SchemaBuilder.union([SchemaBuilder.string(), SchemaBuilder.number()]) - string | number
118
+ */
119
+ union: <T extends readonly [Schema, ...Schema[]]>(schemas: T) => {
120
+ return ArrowS.union(schemas);
121
+ },
122
+
123
+ /**
124
+ * Enum - Known values at compile time
125
+ *
126
+ * Storage: Uint8Array (1 byte) with compile-time mapping
127
+ * Arrow: Dictionary with pre-defined values (UTF-8 pre-computed at definition time)
128
+ * Use for: Operations, HTTP methods, entry types, status enums
129
+ *
130
+ * Usage:
131
+ * - S.enum(['CREATE', 'READ', 'UPDATE', 'DELETE']) - for tag attributes
132
+ * - S.enum(['dev', 'staging', 'prod']).default('dev').sync() - feature flag
133
+ */
134
+ enum: <T extends readonly string[]>(values: T): SchemaOrFlagBuilder<T[number]> & LazyEnumSchema<T[number]> => {
135
+ const schema = ArrowS.enum(values);
136
+ return createSchemaWithFlagBuilder(schema);
137
+ },
138
+
139
+ /**
140
+ * Category - Values that often repeat (limited cardinality)
141
+ *
142
+ * Storage: Raw strings (no hot-path interning)
143
+ * Arrow: Dictionary built dynamically from values at Arrow conversion
144
+ * Use for: userIds, sessionIds, moduleNames, spanNames, table names
145
+ */
146
+ category: (): SchemaOrFlagBuilder<string> & LazyCategorySchema => {
147
+ const schema = ArrowS.category();
148
+ return createSchemaWithFlagBuilder(schema);
149
+ },
150
+
151
+ /**
152
+ * Text - Unique values that rarely repeat
153
+ *
154
+ * Storage: Raw strings without interning
155
+ * Arrow: Plain string column (no dictionary overhead)
156
+ * Use for: Unique error messages, URLs, request bodies, masked queries
157
+ */
158
+ text: (): SchemaOrFlagBuilder<string> & LazyTextSchema => {
159
+ const schema = ArrowS.text();
160
+ return createSchemaWithFlagBuilder(schema);
161
+ },
162
+
163
+ /**
164
+ * Binary - Raw bytes or encoder-wrapped values
165
+ *
166
+ * Passthrough to arrow-builder's S.binary().
167
+ * Without encoder: accepts Uint8Array (raw binary).
168
+ * With encoder: accepts any value T (encoded to bytes at flush time).
169
+ */
170
+ binary: ((options?: { encoder: BinaryEncoder }): LazyBinarySchema => {
171
+ if (options?.encoder) {
172
+ return ArrowS.binary(options);
173
+ }
174
+ return ArrowS.binary();
175
+ }) as SchemaBuilder['binary'],
176
+
177
+ /**
178
+ * Unknown - accepts any value, msgpack-encoded at flush time
179
+ *
180
+ * Sugar for S.binary({ encoder: msgpackEncoder }).
181
+ * Use for: arbitrary objects, request bodies, error context, unknown-shape data.
182
+ * Hot path stores frozen object reference; flush path encodes via @msgpack/msgpack.
183
+ */
184
+ unknown: (): LazyBinarySchema<unknown> => {
185
+ return ArrowS.binary({ encoder: msgpackEncoder });
186
+ },
187
+
188
+ /**
189
+ * Object<T> - typed variant of unknown, same underlying binary storage with msgpack encoding
190
+ *
191
+ * TypeScript enforces shape at compile time; no runtime validation on hot path.
192
+ * Sugar for S.binary<T>({ encoder: msgpackEncoder }).
193
+ */
194
+ object: <T extends object>(): LazyBinarySchema<T> => {
195
+ return ArrowS.binary<T>({ encoder: msgpackEncoder });
196
+ },
197
+ };
198
+
199
+ // Export as S for convenience
200
+ // Note: The SchemaBuilder type is exported from types.ts
201
+ export const S = schemaBuilderImpl;