@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,404 @@
1
+ import type { Schema, SchemaWithMetadata } from '@smoothbricks/arrow-builder';
2
+ import { createEvaluatorClass, type GeneratedEvaluatorInstance } from '../codegen/evaluatorGenerator.js';
3
+ import type { FluentLogEntry } from '../codegen/spanLoggerGenerator.js';
4
+ import type { OpContext } from '../opContext/types.js';
5
+ import type { SpanContext } from '../spanContext.js';
6
+ import type { FeatureFlagSchema } from './defineFeatureFlags.js';
7
+ import type { LogSchema } from './LogSchema.js';
8
+ import { ENTRY_TYPE_FF_ACCESS } from './systemSchema.js';
9
+
10
+ /**
11
+ * Extended schema shape for flag validation — covers refine(), enum membership,
12
+ * SchemaType union.
13
+ */
14
+ interface ExtendedFlagSchema extends Omit<SchemaWithMetadata, '__schema_type'> {
15
+ __schema_type?: string;
16
+ __refiner?: (value: unknown, fail: { fail(msg: string): never }) => unknown;
17
+ }
18
+
19
+ /**
20
+ * Type guard to validate flag value matches schema.
21
+ * Uses __schema_type metadata for type-based validation instead of Sury.
22
+ *
23
+ * For feature flags the types are limited (string, number, boolean, enum, bigint).
24
+ * Schemas with __refiner (from refine()) invoke the refiner — on failure, return default.
25
+ * Schemas with __enum_values check membership.
26
+ *
27
+ * The runtime guard only knows the schema metadata, so the implementation returns
28
+ * `unknown` and lets the overloads carry the caller's concrete schema type.
29
+ */
30
+ function validateFlagValue<T>(value: unknown, schema: Schema<T>, defaultValue: T): T;
31
+ function validateFlagValue(value: unknown, schema: Schema<unknown>, defaultValue: unknown): unknown {
32
+ const meta = schema as ExtendedFlagSchema;
33
+
34
+ // Handle refine() schemas — invoke the stored refiner, fall back to default on failure
35
+ if (meta.__refiner) {
36
+ try {
37
+ return meta.__refiner(value, {
38
+ fail(msg: string): never {
39
+ throw new Error(msg);
40
+ },
41
+ });
42
+ } catch {
43
+ return defaultValue;
44
+ }
45
+ }
46
+
47
+ switch (meta.__schema_type) {
48
+ case 'number':
49
+ return typeof value === 'number' ? value : defaultValue;
50
+ case 'boolean':
51
+ return typeof value === 'boolean' ? value : defaultValue;
52
+ case 'text':
53
+ case 'category':
54
+ return typeof value === 'string' ? value : defaultValue;
55
+ case 'enum':
56
+ if (typeof value !== 'string') return defaultValue;
57
+ if (meta.__enum_values && !meta.__enum_values.includes(value)) return defaultValue;
58
+ return value;
59
+ case 'bigUint64':
60
+ return typeof value === 'bigint' ? value : defaultValue;
61
+ case 'key':
62
+ // Key schema in feature flags — validate it's a string
63
+ return typeof value === 'string' ? value : defaultValue;
64
+ default:
65
+ // Unknown schema type — reject by returning the default value.
66
+ // This prevents silently accepting invalid data for unhandled schema types.
67
+ return defaultValue;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Serializable flag value types
73
+ */
74
+ export type FlagValue = string | number | boolean | null;
75
+
76
+ /**
77
+ * SpanContext without 'ff' field - prevents infinite recursion in evaluators
78
+ */
79
+ export type SpanContextWithoutFf<Ctx extends OpContext> = Omit<SpanContext<Ctx>, 'ff'>;
80
+
81
+ /**
82
+ * Feature flag evaluator interface (backend implementation)
83
+ *
84
+ * This is implemented by the backend (database, LaunchDarkly, etc.)
85
+ * and provides the actual flag values.
86
+ *
87
+ * ## Stateless Design - ctx is a parameter
88
+ *
89
+ * The evaluator receives `Omit<SpanContext, 'ff'>` as a PARAMETER (not stored state).
90
+ * This allows the evaluator to:
91
+ * - Be stateless (CAN be a singleton, but doesn't have to be)
92
+ * - Access full context (ctx.log, ctx.span, ctx.scope, ctx.deps, user properties)
93
+ * - Prevent infinite recursion (can't access ctx.ff which would call evaluator again)
94
+ *
95
+ * ## forContext() - Flexible Wrapper Creation
96
+ *
97
+ * The evaluator decides how to create the per-span wrapper:
98
+ * - Return a new wrapper with `this` as the evaluator (most common - reuse evaluator)
99
+ * - Return `this` if the evaluator itself implements the wrapper interface
100
+ * - Return a completely different evaluator/wrapper (e.g., per-span caching)
101
+ *
102
+ * The wrapper (FeatureFlagEvaluator) holds a ctx reference to enable fluent getters.
103
+ *
104
+ * @template Ctx - OpContext bundle (contains flags via Ctx['flags'])
105
+ */
106
+ export interface FlagEvaluator<Ctx extends OpContext = OpContext> {
107
+ /**
108
+ * Get a flag value synchronously (for cached/static flags)
109
+ *
110
+ * The evaluator receives ctx as a parameter (stateless design).
111
+ * Can use ctx.log/ctx.span for tracing, ctx.scope for targeting.
112
+ *
113
+ * @param ctx - SpanContext without 'ff' (can log, create spans, access scope)
114
+ * @param flag - Flag name to evaluate
115
+ */
116
+ getSync<K extends string>(ctx: SpanContextWithoutFf<Ctx>, flag: K): FlagValue;
117
+
118
+ /**
119
+ * Get a flag value asynchronously (for dynamic flags)
120
+ *
121
+ * The evaluator receives ctx as a parameter (stateless design).
122
+ * Can use ctx.log/ctx.span for tracing external calls.
123
+ *
124
+ * @param ctx - SpanContext without 'ff' (can log, create spans, access scope)
125
+ * @param flag - Flag name to evaluate
126
+ */
127
+ getAsync<K extends string>(ctx: SpanContextWithoutFf<Ctx>, flag: K): Promise<FlagValue>;
128
+
129
+ /**
130
+ * Factory method: Create per-span wrapper from span context.
131
+ *
132
+ * Returns a FeatureFlagEvaluator (per-span wrapper) with typed getters for each flag.
133
+ *
134
+ * ## Implementation Choices
135
+ *
136
+ * Common pattern: Return a new wrapper that holds `this` as the evaluator
137
+ * ```typescript
138
+ * forContext(ctx) {
139
+ * return new FeatureFlagEvaluator(schema, ctx, this); // Reuse evaluator, new wrapper
140
+ * }
141
+ * ```
142
+ *
143
+ * Alternative: Return `this` if evaluator implements the wrapper interface
144
+ * ```typescript
145
+ * forContext(ctx) {
146
+ * return this; // Evaluator itself is the wrapper (uncommon)
147
+ * }
148
+ * ```
149
+ *
150
+ * Alternative: Return different evaluator (e.g., per-span caching layer)
151
+ * ```typescript
152
+ * forContext(ctx) {
153
+ * return new CachedEvaluator(ctx, this); // Different wrapper with caching
154
+ * }
155
+ * ```
156
+ *
157
+ * The wrapper MUST store ctx because JS getters (`get darkMode()`) cannot receive parameters.
158
+ *
159
+ * Receives `Omit<SpanContext, 'ff'>` to prevent infinite recursion.
160
+ */
161
+ forContext(ctx: SpanContextWithoutFf<Ctx>): FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
162
+ }
163
+
164
+ /**
165
+ * Column writers interface (to be implemented in buffer phase)
166
+ *
167
+ * Used for logging flag access and usage to span buffers.
168
+ */
169
+ export interface FlagColumnWriters {
170
+ writeEntryType(type: 'ff-access' | 'ff-usage'): void;
171
+ writeFfName(name: string): void;
172
+ writeFfValue(value: FlagValue): void;
173
+ writeAction(action?: string): void;
174
+ writeOutcome(outcome?: string): void;
175
+ writeContextAttributes(context: Record<string, unknown>): void;
176
+ }
177
+
178
+ // ============================================================================
179
+ // Flag Context Types - returned when flag is enabled
180
+ // ============================================================================
181
+
182
+ /**
183
+ * Track context for feature flag usage analytics
184
+ */
185
+ export interface FlagTrackContext {
186
+ action?: string;
187
+ outcome?: string;
188
+ }
189
+
190
+ /**
191
+ * Boolean flag context - returned when boolean flag is true
192
+ */
193
+ export interface BooleanFlagContext<TLog extends LogSchema = LogSchema> {
194
+ readonly value: true;
195
+ track(context?: FlagTrackContext): FluentLogEntry<TLog>;
196
+ }
197
+
198
+ /**
199
+ * Variant flag context - returned when variant flag is enabled
200
+ */
201
+ export interface VariantFlagContext<V extends string, TLog extends LogSchema = LogSchema> {
202
+ readonly value: V;
203
+ track(context?: FlagTrackContext): FluentLogEntry<TLog>;
204
+ }
205
+
206
+ /**
207
+ * Config flag context - returned when config flag is enabled
208
+ * Spreads the config object and adds track() method
209
+ */
210
+ export type ConfigFlagContext<T extends Record<string, unknown>, TLog extends LogSchema = LogSchema> = T & {
211
+ track(context?: FlagTrackContext): FluentLogEntry<TLog>;
212
+ };
213
+
214
+ // ============================================================================
215
+ // Type Inference for Feature Flags
216
+ // ============================================================================
217
+
218
+ /**
219
+ * Infer the flag context type for a single flag definition
220
+ */
221
+ type InferFlagContextType<Ctx extends OpContext, T> = T extends boolean
222
+ ? BooleanFlagContext<Ctx['logSchema']>
223
+ : T extends string
224
+ ? VariantFlagContext<T, Ctx['logSchema']>
225
+ : T extends Record<string, unknown>
226
+ ? ConfigFlagContext<T, Ctx['logSchema']>
227
+ : { value: T; track(context?: FlagTrackContext): FluentLogEntry<Ctx['logSchema']> };
228
+
229
+ /**
230
+ * Infer feature flag types from OpContext - returns FlagContext | undefined for each flag
231
+ *
232
+ * - Returns undefined when flag is false/disabled
233
+ * - Returns FlagContext wrapper when flag is truthy/enabled
234
+ */
235
+ export type InferFeatureFlagsWithContext<Ctx extends OpContext> = Ctx['flags'] extends FeatureFlagSchema
236
+ ? {
237
+ readonly [K in keyof Ctx['flags']]:
238
+ | InferFlagContextType<Ctx, import('@smoothbricks/arrow-builder').Output<Ctx['flags'][K]['schema']>>
239
+ | undefined;
240
+ }
241
+ : Record<string, never>;
242
+
243
+ // ============================================================================
244
+ // Feature Flag Evaluator Class
245
+ // ============================================================================
246
+
247
+ /**
248
+ * Get or create a generated evaluator class for a schema.
249
+ *
250
+ * The worker-safe constructor cache lives in `evaluatorGenerator.ts`.
251
+ */
252
+ function getOrCreateEvaluatorClass<Ctx extends OpContext>(
253
+ schema: Ctx['flags'],
254
+ ): new (
255
+ spanContext: SpanContextWithoutFf<Ctx>,
256
+ evaluator: FlagEvaluator<Ctx>,
257
+ ) => GeneratedEvaluatorInstance<Ctx> {
258
+ return createEvaluatorClass(schema, validateFlagValue, ENTRY_TYPE_FF_ACCESS);
259
+ }
260
+
261
+ /**
262
+ * Feature flag evaluator with undefined/truthy semantics (PER-SPAN WRAPPER)
263
+ *
264
+ * ## Architecture: Stateless Evaluator + Per-Span Wrapper
265
+ *
266
+ * ```
267
+ * ┌─────────────────────────────────────────────────────────────┐
268
+ * │ FlagEvaluator (backend - CAN be singleton) │
269
+ * │ - getSync(ctx, flag) → FlagValue │
270
+ * │ - getAsync(ctx, flag) → Promise<FlagValue> │
271
+ * │ - forContext(ctx) → new FeatureFlagEvaluator(ctx, this) │
272
+ * └─────────────────────────────────────────────────────────────┘
273
+ * ▲
274
+ * │ reference (can be reused or new)
275
+ * │
276
+ * ┌─────────────────────────────────────────────────────────────┐
277
+ * │ FeatureFlagEvaluator (PER-SPAN - holds ctx reference) │
278
+ * │ #spanContext = ctx │
279
+ * │ #evaluator = backend evaluator │
280
+ * │ │
281
+ * │ get darkMode() { │
282
+ * │ return this.#getFlag('darkMode'); │
283
+ * │ // calls this.#evaluator.getSync(this.#spanContext, 'x') │
284
+ * │ } │
285
+ * │ │
286
+ * │ forContext(childCtx) { │
287
+ * │ // Reuse same evaluator, new wrapper with childCtx │
288
+ * │ return new FeatureFlagEvaluator(childCtx, this.#evaluator)│
289
+ * │ } │
290
+ * └─────────────────────────────────────────────────────────────┘
291
+ * ```
292
+ *
293
+ * ## Why Per-Span Wrapper?
294
+ *
295
+ * JS getters (`get darkMode()`) cannot receive parameters. To provide the fluent
296
+ * API `ctx.ff.darkMode`, we need to store the ctx reference in the wrapper instance.
297
+ *
298
+ * The backend evaluator (FlagEvaluator) receives ctx as a parameter, so it CAN be
299
+ * stateless/singleton. The wrapper is created per-span to bind ctx to getters.
300
+ *
301
+ * ## Behavior
302
+ *
303
+ * - Returns undefined when flag is false/disabled
304
+ * - Returns FlagContext wrapper when flag is truthy/enabled
305
+ * - First access logs ff-access entry
306
+ * - Subsequent access in same span returns cached value (no duplicate log)
307
+ * - track() always logs ff-usage entry
308
+ *
309
+ * ## V8 Optimization Benefits
310
+ *
311
+ * - Stable hidden class (all instances have same shape)
312
+ * - Monomorphic property access (getters are real properties)
313
+ * - No Proxy trap overhead
314
+ * - Inline caching works properly
315
+ *
316
+ * ## Generated Class Pattern
317
+ *
318
+ * The class constructor returns a generated class instance rather than this instance.
319
+ * This is a valid JavaScript pattern for creating optimized instances with schema-specific properties.
320
+ *
321
+ * @template Ctx - OpContext bundle (contains flags via Ctx['flags'])
322
+ */
323
+ export abstract class FeatureFlagEvaluator<Ctx extends OpContext = OpContext> {
324
+ /**
325
+ * Get async flag value
326
+ * Returns undefined when false, FlagContext when truthy
327
+ */
328
+ abstract get<K extends keyof InferFeatureFlagsWithContext<Ctx> & string>(
329
+ flag: K,
330
+ ): Promise<InferFeatureFlagsWithContext<Ctx>[K]>;
331
+ abstract get(flag: string): Promise<unknown>;
332
+
333
+ /**
334
+ * Create a new wrapper for a child span context.
335
+ *
336
+ * The implementation can reuse the same evaluator (singleton pattern),
337
+ * create a new evaluator, or return `this` if the evaluator itself
338
+ * implements the wrapper interface.
339
+ */
340
+ abstract forContext(ctx: SpanContext<Ctx>): FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
341
+ }
342
+
343
+ /**
344
+ * Create a FeatureFlagEvaluator instance using the generated class
345
+ */
346
+ export function createFeatureFlagEvaluator<Ctx extends OpContext>(
347
+ schema: Ctx['flags'],
348
+ spanContext: SpanContextWithoutFf<Ctx>,
349
+ evaluator: FlagEvaluator<Ctx>,
350
+ ): FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx> {
351
+ const GeneratedClass = getOrCreateEvaluatorClass<Ctx>(schema);
352
+ const instance: GeneratedEvaluatorInstance<Ctx> = new GeneratedClass(spanContext, evaluator);
353
+ return instance;
354
+ }
355
+
356
+ /**
357
+ * Simple in-memory flag evaluator for testing
358
+ *
359
+ * Demonstrates the simplest evaluator pattern:
360
+ * - getSync/getAsync receive ctx first, enabling evaluators to use ctx.log, ctx.scope
361
+ * - forContext bootstraps the generated FeatureFlagEvaluator class (creates per-span wrapper)
362
+ * - Generated class has typed getters (ff.darkMode) and calls this.getSync(ctx, flag)
363
+ */
364
+ export class InMemoryFlagEvaluator<Ctx extends OpContext = OpContext> implements FlagEvaluator<Ctx> {
365
+ private flags: Record<string, FlagValue> = {};
366
+ private ffSchema: Ctx['flags'];
367
+
368
+ constructor(ffSchema: Ctx['flags'], initialFlags: Record<string, FlagValue> = {}) {
369
+ this.ffSchema = ffSchema;
370
+ this.flags = initialFlags;
371
+ }
372
+
373
+ /**
374
+ * Get flag value synchronously.
375
+ * Simple evaluator ignores ctx - just returns stored value.
376
+ * Advanced evaluators can use ctx.log, ctx.span, ctx.scope, etc.
377
+ */
378
+ getSync<K extends string>(_ctx: SpanContextWithoutFf<Ctx>, flag: K): FlagValue {
379
+ return this.flags[flag] ?? null;
380
+ }
381
+
382
+ /**
383
+ * Get flag value asynchronously.
384
+ * Simple evaluator ignores ctx - just returns stored value.
385
+ * Advanced evaluators can use ctx.log, ctx.span for tracing external calls.
386
+ */
387
+ async getAsync<K extends string>(_ctx: SpanContextWithoutFf<Ctx>, flag: K): Promise<FlagValue> {
388
+ return this.flags[flag] ?? null;
389
+ }
390
+
391
+ setFlag(flag: string, value: FlagValue): void {
392
+ this.flags[flag] = value;
393
+ }
394
+
395
+ /**
396
+ * Create span-bound FeatureFlagEvaluator with typed getters.
397
+ *
398
+ * Returns a per-span wrapper that holds ctx reference and reuses this evaluator.
399
+ * The generated class has typed getters (ff.darkMode) and calls this.getSync(ctx, flag).
400
+ */
401
+ forContext(ctx: SpanContextWithoutFf<Ctx>): FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx> {
402
+ return createFeatureFlagEvaluator(this.ffSchema, ctx, this);
403
+ }
404
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Schema extension utilities for composing tag attribute schemas
3
+ *
4
+ * This enables building complex schemas from smaller, reusable pieces:
5
+ * - Base attributes (requestId, userId, etc.)
6
+ * - HTTP-specific attributes (httpStatus, httpMethod, etc.)
7
+ * - Database-specific attributes (dbQuery, dbDuration, etc.)
8
+ * - Custom domain attributes
9
+ */
10
+
11
+ import { LogSchema } from './LogSchema.js';
12
+ import type { SchemaFields } from './types.js';
13
+
14
+ export function extendSchema<T extends SchemaFields, U extends SchemaFields>(
15
+ base: LogSchema<T>,
16
+ extension: U,
17
+ ): LogSchema<T & U>;
18
+ export function extendSchema<T extends SchemaFields, U extends SchemaFields>(base: T, extension: U): T & U;
19
+
20
+ /**
21
+ * Merge two log schemas with conflict detection
22
+ *
23
+ * This performs shallow merge and validates:
24
+ * - No conflicting field names
25
+ * - No reserved names in extension
26
+ *
27
+ * Example:
28
+ * ```typescript
29
+ * const base = { requestId: S.category() };
30
+ * const httpAttrs = { httpStatus: S.number(), httpMethod: S.enum(['GET', 'POST']) };
31
+ * const combined = extendSchema(base, httpAttrs);
32
+ * // Result: { requestId, httpStatus, httpMethod }
33
+ * ```
34
+ *
35
+ * @param base - Base log schema (LogSchema or plain object)
36
+ * @param extension - Additional attributes to add
37
+ * @returns Merged schema
38
+ * @throws Error if field names conflict
39
+ */
40
+ export function extendSchema<U extends SchemaFields>(
41
+ base: LogSchema | SchemaFields,
42
+ extension: U,
43
+ ): LogSchema | SchemaFields {
44
+ // Extract base fields (from LogSchema.fields or plain object)
45
+ const baseFields = base instanceof LogSchema ? base.fields : base;
46
+ const baseKeys = new Set(Object.keys(baseFields));
47
+
48
+ // Check for field name conflicts
49
+ for (const key of Object.keys(extension)) {
50
+ if (baseKeys.has(key)) {
51
+ throw new Error(
52
+ `Schema conflict: attribute '${key}' already exists in base schema. ` +
53
+ `Base schema has: ${Object.keys(baseFields).join(', ')}`,
54
+ );
55
+ }
56
+ }
57
+
58
+ // Assert extension doesn't use reserved names
59
+ LogSchema.assertUserFieldNames(Object.keys(extension));
60
+
61
+ // Perform shallow merge
62
+ const merged = { ...baseFields, ...extension };
63
+
64
+ // If base was LogSchema, return LogSchema; otherwise return plain object
65
+ if (base instanceof LogSchema) {
66
+ return new LogSchema(merged);
67
+ }
68
+ return merged;
69
+ }