@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,612 @@
1
+ import { beforeEach, describe, expect, it } from 'bun:test';
2
+ import { DEFAULT_BUFFER_CAPACITY } from '@smoothbricks/arrow-builder';
3
+ import fc from 'fast-check';
4
+ import { createSpanLogger } from '../codegen/spanLoggerGenerator.js';
5
+ import { DEFAULT_METADATA } from '../opContext/defineOp.js';
6
+ import { S } from '../schema/builder.js';
7
+ import { LogSchema } from '../schema/LogSchema.js';
8
+ import { mergeWithSystemSchema } from '../schema/systemSchema.js';
9
+ import { createSpanBuffer, getSpanBufferClass, type SpanBufferConstructor } from '../spanBuffer.js';
10
+
11
+ import type { AnySpanBuffer } from '../types.js';
12
+ import { createBuffer, createTestTraceRoot } from './test-helpers.js';
13
+
14
+ /**
15
+ * Property-based tests for buffer overflow handling.
16
+ *
17
+ * Core properties verified:
18
+ * 1. Entry Preservation: All N entries exist across the buffer chain
19
+ * 2. Buffer Count Formula: Exact number of buffers matches mathematical expectation
20
+ * 3. Chain Integrity: Linked list is properly formed
21
+ * 4. Data Correctness: Each entry has expected attribute values
22
+ * 5. Overflow Counter: logBinding.sb_overflows === bufferCount - 1
23
+ */
24
+
25
+ // Schema for testing - includes various column types and system fields
26
+ const testSchema = new LogSchema(
27
+ mergeWithSystemSchema({
28
+ requestId: S.category(),
29
+ userId: S.category(),
30
+ operation: S.enum(['SELECT', 'INSERT', 'UPDATE', 'DELETE']),
31
+ duration: S.number(),
32
+ success: S.boolean(),
33
+ }),
34
+ );
35
+
36
+ /**
37
+ * SpanLogger reserves rows 0-1 for span-start and span-end.
38
+ * User entries start at row 2. So with capacity C, we can write (C-2) entries
39
+ * before overflow in the first buffer.
40
+ */
41
+ const RESERVED_ROWS = 2;
42
+ const DB_OPERATIONS = ['SELECT', 'INSERT', 'UPDATE', 'DELETE'] as const;
43
+
44
+ type BufferChainAnalysis = {
45
+ bufferCount: number;
46
+ totalEntries: number;
47
+ writeIndices: number[];
48
+ };
49
+
50
+ /**
51
+ * Helper: Get SpanBufferClass and reset stats for testing
52
+ */
53
+ function getTestSpanBufferClass(capacity?: number): SpanBufferConstructor {
54
+ const SpanBufferClass = getSpanBufferClass(testSchema);
55
+ // Reset stats for clean test state
56
+ SpanBufferClass.stats.capacity = capacity ?? DEFAULT_BUFFER_CAPACITY;
57
+ SpanBufferClass.stats.totalWrites = 0;
58
+ SpanBufferClass.stats.spansCreated = 0;
59
+ return SpanBufferClass;
60
+ }
61
+
62
+ /**
63
+ * Helper: Count overflows by walking buffer chain
64
+ */
65
+ function countOverflows(buffer: AnySpanBuffer): number {
66
+ let count = 0;
67
+ let curr: AnySpanBuffer | undefined = buffer;
68
+ while (curr?._overflow) {
69
+ count++;
70
+ curr = curr._overflow;
71
+ }
72
+ return count;
73
+ }
74
+
75
+ /**
76
+ * Helper: Count buffers in chain and collect total entries
77
+ */
78
+ function analyzeBufferChain(rootBuffer: AnySpanBuffer): BufferChainAnalysis {
79
+ const writeIndices: number[] = [];
80
+ let bufferCount = 0;
81
+ let totalEntries = 0;
82
+ let current: AnySpanBuffer | undefined = rootBuffer;
83
+
84
+ while (current) {
85
+ bufferCount++;
86
+ writeIndices.push(current._writeIndex);
87
+ totalEntries += current._writeIndex;
88
+ current = current._overflow as AnySpanBuffer | undefined;
89
+ }
90
+
91
+ return { bufferCount, totalEntries, writeIndices };
92
+ }
93
+
94
+ type LazyColumnProbe = {
95
+ _requestId_values?: unknown;
96
+ _userId_values?: unknown;
97
+ _operation_values?: unknown;
98
+ _duration_values?: unknown;
99
+ _success_values?: unknown;
100
+ };
101
+
102
+ function requireOverflowBuffer(buffer: AnySpanBuffer, label: string): AnySpanBuffer {
103
+ if (!buffer._overflow) {
104
+ throw new Error(`Expected overflow buffer for ${label}`);
105
+ }
106
+ return buffer._overflow;
107
+ }
108
+
109
+ /**
110
+ * Helper: Collect all entries from buffer chain
111
+ */
112
+ function collectEntries(
113
+ rootBuffer: AnySpanBuffer,
114
+ startRow = 0,
115
+ ): Array<{
116
+ bufferIndex: number;
117
+ rowIndex: number;
118
+ requestId: string | undefined;
119
+ userId: string | undefined;
120
+ operation: number | undefined;
121
+ duration: number | undefined;
122
+ }> {
123
+ const entries: Array<{
124
+ bufferIndex: number;
125
+ rowIndex: number;
126
+ requestId: string | undefined;
127
+ userId: string | undefined;
128
+ operation: number | undefined;
129
+ duration: number | undefined;
130
+ }> = [];
131
+
132
+ let bufferIndex = 0;
133
+ let current: AnySpanBuffer | undefined = rootBuffer;
134
+
135
+ while (current) {
136
+ // First buffer starts at startRow, subsequent buffers start at 0
137
+ const start = bufferIndex === 0 ? startRow : 0;
138
+ const end = current._writeIndex;
139
+
140
+ const requestIdValues = current.getColumnIfAllocated('requestId');
141
+ const userIdValues = current.getColumnIfAllocated('userId');
142
+ const operationValues = current.getColumnIfAllocated('operation');
143
+ const durationValues = current.getColumnIfAllocated('duration');
144
+
145
+ for (let row = start; row < end; row++) {
146
+ const requestIdValue = Array.isArray(requestIdValues) ? requestIdValues[row] : undefined;
147
+ const userIdValue = Array.isArray(userIdValues) ? userIdValues[row] : undefined;
148
+ entries.push({
149
+ bufferIndex,
150
+ rowIndex: row,
151
+ requestId: typeof requestIdValue === 'string' ? requestIdValue : undefined,
152
+ userId: typeof userIdValue === 'string' ? userIdValue : undefined,
153
+ operation: operationValues instanceof Uint8Array ? operationValues[row] : undefined,
154
+ duration: durationValues instanceof Float64Array ? durationValues[row] : undefined,
155
+ });
156
+ }
157
+
158
+ bufferIndex++;
159
+ current = current._overflow as AnySpanBuffer | undefined;
160
+ }
161
+
162
+ return entries;
163
+ }
164
+
165
+ /**
166
+ * Calculate expected buffer count for N entries.
167
+ *
168
+ * With capacity C and R reserved rows in first buffer:
169
+ * - First buffer holds (C - R) entries
170
+ * - Each subsequent buffer holds C entries
171
+ *
172
+ * Formula: 1 + ceil(max(0, N - (C - R)) / C)
173
+ */
174
+ function expectedBufferCount(numEntries: number, capacity: number, reservedRows: number): number {
175
+ const firstBufferCapacity = capacity - reservedRows;
176
+ if (numEntries <= firstBufferCapacity) {
177
+ return 1;
178
+ }
179
+ const remaining = numEntries - firstBufferCapacity;
180
+ return 1 + Math.ceil(remaining / capacity);
181
+ }
182
+
183
+ describe('Buffer Overflow Property Tests', () => {
184
+ let SpanBufferClass: SpanBufferConstructor;
185
+
186
+ beforeEach(() => {
187
+ SpanBufferClass = getTestSpanBufferClass();
188
+ });
189
+
190
+ describe('Property: Entry Preservation', () => {
191
+ it('all entries are preserved across buffer chain for any entry count', () => {
192
+ fc.assert(
193
+ fc.property(
194
+ // Generate entry count from 1 to 200 (enough to trigger many overflows)
195
+ fc.integer({ min: 1, max: 200 }),
196
+ (numEntries) => {
197
+ // Reset counters for each test run
198
+ SpanBufferClass.stats.spansCreated = 0;
199
+
200
+ const buffer = createBuffer(testSchema);
201
+ const logger = createSpanLogger(testSchema, buffer);
202
+
203
+ // Write entries
204
+ for (let i = 0; i < numEntries; i++) {
205
+ logger
206
+ .info(`msg-${i}`)
207
+ .requestId(`req-${i}`)
208
+ .userId(`user-${i}`)
209
+ .operation(DB_OPERATIONS[i % 4])
210
+ .duration(i * 10);
211
+ }
212
+
213
+ // Collect entries starting from row RESERVED_ROWS (rows 0-1 are span lifecycle)
214
+ const entries = collectEntries(buffer, RESERVED_ROWS);
215
+
216
+ // Property: exactly numEntries entries exist
217
+ expect(entries.length).toBe(numEntries);
218
+ },
219
+ ),
220
+ { numRuns: 100 },
221
+ );
222
+ });
223
+ });
224
+
225
+ describe('Property: Buffer Count Formula', () => {
226
+ it('buffer count matches mathematical formula for any entry count', () => {
227
+ fc.assert(
228
+ // Limit to 90 entries to stay below capacity tuning threshold (100 writes)
229
+ // This ensures capacity stays constant throughout the test run
230
+ fc.property(fc.integer({ min: 1, max: 90 }), (numEntries) => {
231
+ // Reset all stats including capacity before each run
232
+ const capacity = DEFAULT_BUFFER_CAPACITY; // 8
233
+ SpanBufferClass.stats.capacity = capacity;
234
+ SpanBufferClass.stats.totalWrites = 0;
235
+ SpanBufferClass.stats.spansCreated = 0;
236
+
237
+ const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
238
+ const logger = createSpanLogger(testSchema, buffer);
239
+
240
+ // Write entries
241
+ for (let i = 0; i < numEntries; i++) {
242
+ logger.info(`msg-${i}`);
243
+ }
244
+
245
+ const { bufferCount } = analyzeBufferChain(buffer);
246
+ // SpanLogger reserves 2 rows (span-start, span-end)
247
+ const expected = expectedBufferCount(numEntries, capacity, RESERVED_ROWS);
248
+
249
+ expect(bufferCount).toBe(expected);
250
+ }),
251
+ { numRuns: 100 },
252
+ );
253
+ });
254
+ });
255
+
256
+ describe('Property: Chain Integrity', () => {
257
+ it('buffer chain is properly linked', () => {
258
+ fc.assert(
259
+ fc.property(fc.integer({ min: 1, max: 100 }), (numEntries) => {
260
+ SpanBufferClass.stats.spansCreated = 0;
261
+
262
+ const buffer = createBuffer(testSchema);
263
+ const logger = createSpanLogger(testSchema, buffer);
264
+
265
+ for (let i = 0; i < numEntries; i++) {
266
+ logger.info(`msg-${i}`);
267
+ }
268
+
269
+ // Walk the chain and verify each link
270
+ const buffers: AnySpanBuffer[] = [];
271
+ let current: AnySpanBuffer | undefined = buffer;
272
+ while (current) {
273
+ buffers.push(current);
274
+ current = current._overflow as AnySpanBuffer | undefined;
275
+ }
276
+
277
+ // Property: each buffer (except last) has next pointing to following buffer
278
+ for (let i = 0; i < buffers.length - 1; i++) {
279
+ expect(buffers[i]._overflow).toBe(buffers[i + 1]);
280
+ }
281
+
282
+ // Property: last buffer has no next
283
+ expect(buffers[buffers.length - 1]._overflow).toBeUndefined();
284
+
285
+ // Property: all buffers share same spanId and traceId
286
+ const spanId = buffer.span_id;
287
+ const traceId = buffer.trace_id;
288
+ for (const buf of buffers) {
289
+ expect(buf.span_id).toBe(spanId);
290
+ expect(buf.trace_id).toBe(traceId);
291
+ }
292
+ }),
293
+ { numRuns: 50 },
294
+ );
295
+ });
296
+ });
297
+
298
+ describe('Property: Data Correctness', () => {
299
+ it('each entry has correct attribute values', () => {
300
+ fc.assert(
301
+ fc.property(fc.integer({ min: 1, max: 100 }), (numEntries) => {
302
+ SpanBufferClass.stats.spansCreated = 0;
303
+
304
+ const buffer = createBuffer(testSchema);
305
+ const logger = createSpanLogger(testSchema, buffer);
306
+
307
+ const operations = ['SELECT', 'INSERT', 'UPDATE', 'DELETE'] as const;
308
+
309
+ // Write entries with predictable values
310
+ for (let i = 0; i < numEntries; i++) {
311
+ logger
312
+ .info(`msg-${i}`)
313
+ .requestId(`req-${i}`)
314
+ .userId(`user-${i}`)
315
+ .operation(operations[i % 4])
316
+ .duration(i * 10.5);
317
+ }
318
+
319
+ // Collect starting from RESERVED_ROWS
320
+ const entries = collectEntries(buffer, RESERVED_ROWS);
321
+
322
+ // Property: each entry has expected values
323
+ for (let i = 0; i < numEntries; i++) {
324
+ const entry = entries[i];
325
+ expect(entry.requestId).toBe(`req-${i}`);
326
+ expect(entry.userId).toBe(`user-${i}`);
327
+ // Enum stored as index
328
+ expect(entry.operation).toBe(i % 4);
329
+ expect(entry.duration).toBe(i * 10.5);
330
+ }
331
+ }),
332
+ { numRuns: 50 },
333
+ );
334
+ });
335
+ });
336
+
337
+ describe('Property: Overflow Counter Consistency', () => {
338
+ it('sb_overflows equals bufferCount - 1', () => {
339
+ fc.assert(
340
+ fc.property(fc.integer({ min: 1, max: 150 }), (numEntries) => {
341
+ // Reset counters
342
+ SpanBufferClass.stats.spansCreated = 0;
343
+
344
+ const buffer = createBuffer(testSchema);
345
+ const logger = createSpanLogger(testSchema, buffer);
346
+
347
+ for (let i = 0; i < numEntries; i++) {
348
+ logger.info(`msg-${i}`);
349
+ }
350
+
351
+ const { bufferCount } = analyzeBufferChain(buffer);
352
+
353
+ // Property: overflow events = bufferCount - 1 (one per chain link)
354
+ expect(countOverflows(buffer)).toBe(bufferCount - 1);
355
+ }),
356
+ { numRuns: 100 },
357
+ );
358
+ });
359
+ });
360
+
361
+ describe('Property: WriteIndex Bounds', () => {
362
+ it('each buffer writeIndex is within capacity', () => {
363
+ fc.assert(
364
+ fc.property(fc.integer({ min: 1, max: 200 }), (numEntries) => {
365
+ SpanBufferClass.stats.spansCreated = 0;
366
+
367
+ const buffer = createBuffer(testSchema);
368
+ const logger = createSpanLogger(testSchema, buffer);
369
+
370
+ for (let i = 0; i < numEntries; i++) {
371
+ logger.info(`msg-${i}`);
372
+ }
373
+
374
+ // Walk chain and check each buffer
375
+ let current: AnySpanBuffer | undefined = buffer;
376
+ while (current) {
377
+ // Property: writeIndex <= capacity
378
+ expect(current._writeIndex).toBeLessThanOrEqual(current._capacity);
379
+ // Property: writeIndex >= 0
380
+ expect(current._writeIndex).toBeGreaterThanOrEqual(0);
381
+ current = current._overflow as AnySpanBuffer | undefined;
382
+ }
383
+ }),
384
+ { numRuns: 100 },
385
+ );
386
+ });
387
+ });
388
+
389
+ describe('Edge Cases', () => {
390
+ it('exact usable capacity: no overflow when entries fit in first buffer', () => {
391
+ const capacity = DEFAULT_BUFFER_CAPACITY; // 8
392
+ const usableCapacity = capacity - RESERVED_ROWS; // 6 entries fit
393
+
394
+ const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
395
+ const logger = createSpanLogger(testSchema, buffer);
396
+
397
+ // Write exactly usable capacity entries (6 with capacity=8, reserved=2)
398
+ for (let i = 0; i < usableCapacity; i++) {
399
+ logger.info(`msg-${i}`);
400
+ }
401
+
402
+ // Should be exactly 1 buffer (no overflow)
403
+ expect(buffer._overflow).toBeUndefined();
404
+ expect(countOverflows(buffer)).toBe(0);
405
+ // writeIndex = RESERVED_ROWS + usableCapacity = 2 + 6 = 8 = capacity
406
+ expect(buffer._writeIndex).toBe(capacity);
407
+ });
408
+
409
+ it('usable capacity + 1: triggers exactly one overflow', () => {
410
+ const capacity = DEFAULT_BUFFER_CAPACITY; // 8
411
+ const usableCapacity = capacity - RESERVED_ROWS; // 6
412
+
413
+ const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
414
+ const logger = createSpanLogger(testSchema, buffer);
415
+
416
+ // Write usable capacity + 1 entries (7 entries)
417
+ for (let i = 0; i < usableCapacity + 1; i++) {
418
+ logger.info(`msg-${i}`);
419
+ }
420
+
421
+ // Should be exactly 2 buffers
422
+ expect(buffer._overflow).toBeDefined();
423
+ expect(buffer._overflow?._overflow).toBeUndefined();
424
+ expect(countOverflows(buffer)).toBe(1);
425
+
426
+ // First buffer full, second has 1 entry
427
+ expect(buffer._writeIndex).toBe(capacity);
428
+ expect(buffer._overflow?._writeIndex).toBe(1);
429
+ });
430
+
431
+ it('zero entries: single buffer with just reserved space', () => {
432
+ const buffer = createBuffer(testSchema);
433
+ // Create logger but don't write anything
434
+ createSpanLogger(testSchema, buffer);
435
+
436
+ expect(buffer._overflow).toBeUndefined();
437
+ // Logger constructor sets writeIndex to 2 (after reserved rows)
438
+ expect(buffer._writeIndex).toBe(RESERVED_ROWS);
439
+ expect(countOverflows(buffer)).toBe(0);
440
+ });
441
+ });
442
+
443
+ describe('Varying Capacity', () => {
444
+ it('property holds for different buffer capacities', () => {
445
+ fc.assert(
446
+ fc.property(
447
+ fc.integer({ min: 1, max: 100 }), // entries
448
+ fc.integer({ min: 8, max: 64 }).map((n) => (n + 7) & ~7), // capacity aligned to 8
449
+ (numEntries, capacity) => {
450
+ // Reset all stats to prevent capacity tuning from modifying them mid-test
451
+ SpanBufferClass.stats.capacity = capacity; // Set for chained buffers
452
+ SpanBufferClass.stats.totalWrites = 0;
453
+ SpanBufferClass.stats.spansCreated = 0;
454
+
455
+ const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
456
+ const logger = createSpanLogger(testSchema, buffer);
457
+
458
+ for (let i = 0; i < numEntries; i++) {
459
+ logger.info(`msg-${i}`).requestId(`req-${i}`);
460
+ }
461
+
462
+ const { bufferCount } = analyzeBufferChain(buffer);
463
+
464
+ // Property: buffer count matches formula (with reserved rows)
465
+ const expected = expectedBufferCount(numEntries, capacity, RESERVED_ROWS);
466
+ expect(bufferCount).toBe(expected);
467
+
468
+ // Property: overflow count matches
469
+ expect(countOverflows(buffer)).toBe(bufferCount - 1);
470
+ },
471
+ ),
472
+ { numRuns: 100 },
473
+ );
474
+ });
475
+ });
476
+
477
+ describe('Scoped Attributes in Overflow Buffers', () => {
478
+ it('should prefill scoped attributes in overflow buffer from row 0 (not row 2)', () => {
479
+ const capacity = 8;
480
+ const usableCapacity = capacity - RESERVED_ROWS; // 6
481
+
482
+ const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
483
+ const logger = createSpanLogger(testSchema, buffer);
484
+
485
+ // Set scope values that should be prefilled
486
+ buffer._scopeValues = Object.freeze({
487
+ requestId: 'req-123',
488
+ userId: 'user-456',
489
+ });
490
+
491
+ // Write enough entries to trigger overflow (usableCapacity + 1)
492
+ for (let i = 0; i < usableCapacity + 1; i++) {
493
+ logger.info(`msg-${i}`);
494
+ }
495
+
496
+ // Verify overflow happened
497
+ expect(buffer._overflow).toBeDefined();
498
+ const overflowBuffer = requireOverflowBuffer(buffer, 'prefill-row0');
499
+ const overflowProbe = overflowBuffer as AnySpanBuffer & LazyColumnProbe;
500
+
501
+ // CRITICAL: Overflow buffer starts at _writeIndex=0, not 2
502
+ // The bug was that _prefillScopedAttributesOn used startIdx=2, skipping rows 0-1
503
+ expect(overflowBuffer._writeIndex).toBe(1); // One entry written
504
+
505
+ // CRITICAL: Columns in scope but never written to directly are NOT allocated
506
+ // Prefill checks _requestId_values (private) to avoid triggering lazy allocation
507
+ // These columns stay unallocated until Arrow conversion time
508
+ expect(overflowProbe._requestId_values).toBeUndefined();
509
+ expect(overflowProbe._userId_values).toBeUndefined();
510
+
511
+ // Row 0 has the actual entry (message IS allocated because .info() writes to it)
512
+ expect(overflowBuffer.message_values[0]).toBe('msg-6');
513
+ });
514
+
515
+ it('should prefill scoped attributes across multiple overflow buffers', () => {
516
+ const capacity = 8;
517
+ const usableCapacity = capacity - RESERVED_ROWS; // 6
518
+
519
+ const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
520
+ const logger = createSpanLogger(testSchema, buffer);
521
+
522
+ buffer._scopeValues = Object.freeze({
523
+ requestId: 'req-xyz',
524
+ });
525
+
526
+ // Write enough to create 2 overflow buffers
527
+ // First buffer: 6 entries (usableCapacity), overflow 1: 8 entries (full capacity), overflow 2: 1 entry
528
+ const entriesToWrite = usableCapacity + capacity + 1; // 6 + 8 + 1 = 15
529
+ for (let i = 0; i < entriesToWrite; i++) {
530
+ logger.info(`msg-${i}`);
531
+ }
532
+
533
+ expect(buffer._overflow).toBeDefined();
534
+ expect(buffer._overflow?._overflow).toBeDefined();
535
+
536
+ const overflow1 = requireOverflowBuffer(buffer, 'multiple-overflow-1');
537
+ const overflow2 = requireOverflowBuffer(overflow1, 'multiple-overflow-2');
538
+ const overflow1Probe = overflow1 as AnySpanBuffer & LazyColumnProbe;
539
+ const overflow2Probe = overflow2 as AnySpanBuffer & LazyColumnProbe;
540
+
541
+ // Columns in scope but never written directly stay unallocated (lazy)
542
+ expect(overflow1Probe._requestId_values).toBeUndefined();
543
+ expect(overflow2Probe._requestId_values).toBeUndefined();
544
+ });
545
+
546
+ it('only prefills columns present in _scopeValues, not all schema columns', () => {
547
+ const capacity = 8;
548
+ const usableCapacity = capacity - RESERVED_ROWS; // 6
549
+
550
+ const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
551
+ const logger = createSpanLogger(testSchema, buffer);
552
+
553
+ // Set scope for ONLY userId and requestId, NOT operation or duration or success
554
+ buffer._scopeValues = Object.freeze({
555
+ userId: 'user-789',
556
+ requestId: 'req-abc',
557
+ });
558
+
559
+ // Trigger overflow
560
+ for (let i = 0; i < usableCapacity + 1; i++) {
561
+ logger.info(`msg-${i}`);
562
+ }
563
+
564
+ const overflowBuffer = requireOverflowBuffer(buffer, 'scope-columns');
565
+ const overflowProbe = overflowBuffer as AnySpanBuffer & LazyColumnProbe;
566
+
567
+ // Columns in _scopeValues but NEVER written to directly stay unallocated (lazy)
568
+ expect(overflowProbe._userId_values).toBeUndefined();
569
+ expect(overflowProbe._requestId_values).toBeUndefined();
570
+
571
+ // Columns NOT in _scopeValues also stay unallocated (lazy)
572
+ expect(overflowProbe._operation_values).toBeUndefined();
573
+ expect(overflowProbe._duration_values).toBeUndefined();
574
+ expect(overflowProbe._success_values).toBeUndefined();
575
+ });
576
+
577
+ it('does not allocate columns that are only in scope (lazy allocation)', () => {
578
+ const capacity = 8;
579
+ const usableCapacity = capacity - RESERVED_ROWS;
580
+
581
+ const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
582
+ const logger = createSpanLogger(testSchema, buffer);
583
+
584
+ // Set scope for userId but NEVER call .userId() directly
585
+ buffer._scopeValues = Object.freeze({
586
+ userId: 'scope-only-user',
587
+ });
588
+
589
+ // Write entries without touching userId column
590
+ for (let i = 0; i < usableCapacity + 1; i++) {
591
+ logger.info(`msg-${i}`);
592
+ }
593
+
594
+ // Verify overflow happened
595
+ expect(buffer._overflow).toBeDefined();
596
+ const overflowBuffer = requireOverflowBuffer(buffer, 'lazy-scope-only');
597
+ const rootProbe = buffer as AnySpanBuffer & LazyColumnProbe;
598
+ const overflowProbe = overflowBuffer as AnySpanBuffer & LazyColumnProbe;
599
+
600
+ // CRITICAL: prefill checks the PRIVATE property _userId_values
601
+ // This prevents triggering the lazy getter and allocating memory
602
+ // Since userId was only in scope (never written directly), it stays unallocated
603
+
604
+ // Verify column was NOT allocated (lazy allocation preserved)
605
+ expect(rootProbe._userId_values).toBeUndefined();
606
+ expect(overflowProbe._userId_values).toBeUndefined();
607
+
608
+ // Accessing via the public getter would trigger allocation
609
+ // (but we verify it's undefined before triggering the getter)
610
+ });
611
+ });
612
+ });