@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,945 @@
1
+ // =============================================================================
2
+ // Freelist Allocator for SpanBuffer Storage
3
+ // =============================================================================
4
+ //
5
+ // Implements spec 01q: WASM Memory Architecture for SpanBuffer Storage
6
+ //
7
+ // Memory Layout:
8
+ // ┌─────────────────────────────────────────────────────────────────────────────┐
9
+ // │ Header (64 bytes, cache-aligned) │
10
+ // ├─────────────────────────────────────────────────────────────────────────────┤
11
+ // │ Allocated Blocks (spans + columns) │
12
+ // ├─────────────────────────────────────────────────────────────────────────────┤
13
+ // │ Free Space (bump allocation area) ↑ bump_ptr │
14
+ // └─────────────────────────────────────────────────────────────────────────────┘
15
+ //
16
+ // Size Classes:
17
+ // - Span System: capacity × 9 bytes (timestamp + entry_type)
18
+ // - Identity: 128 bytes (writeIndex + span_id + trace_id)
19
+ // - 1B Column: ceil(capacity/8) + capacity × 1 (nulls + uint8/bool values)
20
+ // - 4B Column: ceil(capacity/8) + capacity × 4 (nulls + uint32/float32 values)
21
+ // - 8B Column: ceil(capacity/8) + capacity × 8 (nulls + float64/bigint64 values)
22
+ //
23
+ // Freelist: Zero-overhead, uses block's memory for next pointer + cascading stats when free.
24
+ //
25
+
26
+ const std = @import("std");
27
+
28
+ // =============================================================================
29
+ // Packed Structs for Memory Layout
30
+ // =============================================================================
31
+
32
+ // =============================================================================
33
+ // Capacity Tiers for Buddy Allocation
34
+ // =============================================================================
35
+ // Tiers: 8, 16, 32, 64, 128, 256, 512 (7 tiers, index 0-6)
36
+ // Buddy relationship: tier[i] can split into 2× tier[i-1], merge into tier[i+1]
37
+
38
+ const MIN_CAPACITY: u32 = 8;
39
+ const MAX_CAPACITY: u32 = 512;
40
+ const NUM_TIERS: usize = 7; // log2(512/8) + 1 = 7
41
+ const NUM_SIZE_CLASSES: usize = 4;
42
+ const NUM_FREELISTS: usize = NUM_SIZE_CLASSES * NUM_TIERS; // 28
43
+
44
+ /// Convert capacity to tier index (0=8, 1=16, 2=32, 3=64, 4=128, 5=256, 6=512)
45
+ inline fn capacityToTier(capacity: u32) usize {
46
+ // capacity must be power of 2 between 8 and 512
47
+ return @ctz(capacity) - @ctz(MIN_CAPACITY);
48
+ }
49
+
50
+ /// Convert tier index to capacity
51
+ inline fn tierToCapacity(tier: usize) u32 {
52
+ return MIN_CAPACITY << @intCast(tier);
53
+ }
54
+
55
+ /// Header at offset 0 of WASM memory (192 bytes, 3 cache lines)
56
+ /// Uses extern struct for stable ABI layout
57
+ /// Hot fields in first cache line (64 bytes)
58
+ const Header = extern struct {
59
+ // === First cache line (hot) ===
60
+ bump_ptr: u32, // offset 0: Next free byte for bump allocation
61
+ span_id_counter: u32, // offset 4: Global span ID counter
62
+ alloc_count: u32, // offset 8: Total allocations
63
+ free_count: u32, // offset 12: Total frees
64
+ freelist_identity: u32, // offset 16: Identity freelist head
65
+ _pad0: u32, // offset 20: Align thread_id to 8 bytes
66
+ thread_id: u64, // offset 24: Process/worker thread ID
67
+
68
+ // Freelists start at offset 32 (inside first cache line)
69
+ // 4 size classes × 7 tiers = 28 freelists (112 bytes)
70
+ // Index: size_class * NUM_TIERS + tier
71
+ // Size classes: 0=span_system, 1=col_1b, 2=col_4b, 3=col_8b
72
+ freelists: [NUM_FREELISTS]u32, // offset 32-143
73
+
74
+ // === Cold fields ===
75
+ thread_id_set: u8, // offset 144: 1 if thread_id has been set
76
+
77
+ // Padding to 192 bytes (192 - 145 = 47 bytes)
78
+ _reserved: [47]u8,
79
+
80
+ comptime {
81
+ std.debug.assert(@sizeOf(Header) == 192);
82
+ }
83
+ };
84
+
85
+ /// Identity block (128 bytes fixed) - per-span metadata
86
+ /// Uses extern struct for stable ABI layout with array field
87
+ const Identity = extern struct {
88
+ write_index: u32, // Current write position (hot path, at offset 0)
89
+ span_id: u32, // Unique span ID (from global counter)
90
+ trace_id_len: u8, // Length of trace_id (0 for child buffers)
91
+ trace_id: [119]u8, // UTF-8 trace_id bytes (only for root buffers)
92
+
93
+ comptime {
94
+ std.debug.assert(@sizeOf(Identity) == 128);
95
+ }
96
+ };
97
+
98
+ /// TraceRoot timing data (16 bytes)
99
+ /// Uses extern struct for stable ABI layout
100
+ const TraceRoot = extern struct {
101
+ wall_clock_nanos: i64, // Wall clock start time in nanoseconds
102
+ monotonic_ms: f64, // Monotonic start time in milliseconds
103
+
104
+ comptime {
105
+ std.debug.assert(@sizeOf(TraceRoot) == 16);
106
+ }
107
+ };
108
+
109
+ /// Freelist block header - overlays the first 20 bytes of any freed block
110
+ /// Stores cascading statistics that aggregate as blocks are pushed/popped
111
+ /// Uses extern struct for stable ABI layout
112
+ const FreeBlock = extern struct {
113
+ next_ptr: u32, // Pointer to next free block (0 = end of list)
114
+ freelist_len: u32, // Number of blocks in freelist (cascading sum)
115
+ reuse_count: u32, // Times allocated from freelist (cascading sum)
116
+ split_count: u32, // Times this size class was split (cascading)
117
+ merge_count: u32, // Times blocks merged (cascading)
118
+
119
+ comptime {
120
+ std.debug.assert(@sizeOf(FreeBlock) == 20);
121
+ }
122
+ };
123
+
124
+ // =============================================================================
125
+ // Size Classes
126
+ // =============================================================================
127
+
128
+ const SizeClass = enum(u8) {
129
+ span_system = 0,
130
+ col_1b = 1,
131
+ col_4b = 2,
132
+ col_8b = 3,
133
+ };
134
+
135
+ // Identity is separate (fixed size, not capacity-dependent)
136
+ const IDENTITY_SIZE_CLASS: u8 = 4;
137
+
138
+ // =============================================================================
139
+ // Entry Type Constants (per specs/lmao/01h and systemSchema.ts)
140
+ // =============================================================================
141
+
142
+ const ENTRY_TYPE_SPAN_START: u8 = 1;
143
+ const ENTRY_TYPE_SPAN_OK: u8 = 2;
144
+ const ENTRY_TYPE_SPAN_ERR: u8 = 3;
145
+ const ENTRY_TYPE_SPAN_EXCEPTION: u8 = 4;
146
+
147
+ // No global capacity state - capacity is passed to each alloc/free call.
148
+ // This allows different OpContexts to have different capacities sharing the same WASM memory.
149
+
150
+ // =============================================================================
151
+ // Memory Access Helpers
152
+ // =============================================================================
153
+
154
+ /// Get typed pointer to WASM memory at offset.
155
+ /// Uses allowzero because WASM memory starts at address 0.
156
+ inline fn ptrAt(comptime T: type, offset: u32) *allowzero T {
157
+ return @ptrFromInt(offset);
158
+ }
159
+
160
+ /// Get byte slice pointer at offset
161
+ inline fn bytesAt(offset: u32) [*]allowzero u8 {
162
+ return @ptrFromInt(offset);
163
+ }
164
+
165
+ /// Get the global header at offset 0
166
+ inline fn header() *allowzero Header {
167
+ return ptrAt(Header, 0);
168
+ }
169
+
170
+ // =============================================================================
171
+ // Size Class Helpers
172
+ // =============================================================================
173
+
174
+ /// Get freelist index for a size class and capacity tier
175
+ inline fn freelistIndex(sc: SizeClass, tier: usize) usize {
176
+ return @intFromEnum(sc) * NUM_TIERS + tier;
177
+ }
178
+
179
+ /// Get freelist head for a size class at specific tier
180
+ inline fn freelistHeadAtTier(sc: SizeClass, tier: usize) u32 {
181
+ return header().freelists[freelistIndex(sc, tier)];
182
+ }
183
+
184
+ /// Set freelist head for a size class at specific tier
185
+ inline fn setFreelistHeadAtTier(sc: SizeClass, tier: usize, value: u32) void {
186
+ header().freelists[freelistIndex(sc, tier)] = value;
187
+ }
188
+
189
+ /// Get block size for a size class at a given capacity
190
+ inline fn blockSizeForCapacity(sc: SizeClass, capacity: u32) u32 {
191
+ const null_bitmap_size = (capacity + 7) >> 3;
192
+ return switch (sc) {
193
+ .span_system => capacity * 9,
194
+ .col_1b => null_bitmap_size + capacity,
195
+ .col_4b => null_bitmap_size + capacity * 4,
196
+ .col_8b => null_bitmap_size + capacity * 8,
197
+ };
198
+ }
199
+
200
+ // =============================================================================
201
+ // Allocator Core
202
+ // =============================================================================
203
+
204
+ /// Allocate a block from the given size class at specific tier.
205
+ fn allocAtTier(sc: SizeClass, tier: usize) u32 {
206
+ const h = header();
207
+ const head_offset = freelistHeadAtTier(sc, tier);
208
+
209
+ if (head_offset != 0) {
210
+ // Pop from freelist
211
+ const free_block = ptrAt(FreeBlock, head_offset);
212
+ const next = free_block.next_ptr;
213
+ setFreelistHeadAtTier(sc, tier, next);
214
+
215
+ // Cascade stats forward: copy from popped block to new head, then increment
216
+ // This ensures the new head has the aggregate stats from the entire chain
217
+ if (next != 0) {
218
+ const next_block = ptrAt(FreeBlock, next);
219
+ next_block.freelist_len = free_block.freelist_len - 1;
220
+ next_block.reuse_count = free_block.reuse_count + 1;
221
+ next_block.split_count = free_block.split_count;
222
+ next_block.merge_count = free_block.merge_count;
223
+ }
224
+
225
+ h.alloc_count += 1;
226
+ return head_offset;
227
+ }
228
+
229
+ // Freelist empty - try buddy split from larger tier
230
+ if (tier + 1 < NUM_TIERS) {
231
+ const parent_offset = allocAtTier(sc, tier + 1);
232
+ if (parent_offset != 0) {
233
+ // Split parent into two blocks of current tier size
234
+ const child_size = blockSizeForCapacity(sc, tierToCapacity(tier));
235
+ const second_child = parent_offset + child_size;
236
+
237
+ // Push second child to freelist (no merge attempt - it's a fresh split)
238
+ pushToFreelist(second_child, sc, tier, false);
239
+
240
+ // Update split count in the freelist head
241
+ const new_head = freelistHeadAtTier(sc, tier);
242
+ if (new_head != 0) {
243
+ ptrAt(FreeBlock, new_head).split_count += 1;
244
+ }
245
+
246
+ // Return first child
247
+ return parent_offset;
248
+ }
249
+ }
250
+
251
+ // No buddy available - bump allocate
252
+ const size = blockSizeForCapacity(sc, tierToCapacity(tier));
253
+ const current_bump = h.bump_ptr;
254
+
255
+ // Align to 8 bytes
256
+ const aligned = (current_bump + 7) & ~@as(u32, 7);
257
+ const new_bump = aligned + size;
258
+
259
+ // Grow memory if needed
260
+ const current_size = @wasmMemorySize(0) * 65536; // pages * 64KB
261
+ if (new_bump > current_size) {
262
+ const needed = new_bump - current_size;
263
+ const pages_needed = (needed + 65535) / 65536; // ceil division
264
+ const result = @wasmMemoryGrow(0, pages_needed);
265
+ if (result == -1) {
266
+ return 0; // Out of memory
267
+ }
268
+ }
269
+
270
+ h.bump_ptr = new_bump;
271
+ h.alloc_count += 1;
272
+
273
+ return aligned;
274
+ }
275
+
276
+ /// Free a block back to its size class freelist at specific tier.
277
+ /// Attempts to merge with adjacent neighbor blocks (address-based buddy merge).
278
+ fn freeAtTier(offset: u32, sc: SizeClass, tier: usize) void {
279
+ // Try to merge with adjacent blocks if not at max tier
280
+ if (tier + 1 < NUM_TIERS) {
281
+ const block_size = blockSizeForCapacity(sc, tierToCapacity(tier));
282
+
283
+ // Check right neighbor (block at offset + block_size)
284
+ const right_neighbor = offset + block_size;
285
+ if (findAndRemoveByOffset(sc, tier, right_neighbor)) {
286
+ // Merge: this block + right neighbor → parent at offset
287
+ freeAtTierWithMerge(offset, sc, tier + 1);
288
+ return;
289
+ }
290
+
291
+ // Check left neighbor (block at offset - block_size)
292
+ if (offset >= block_size) {
293
+ const left_neighbor = offset - block_size;
294
+ if (findAndRemoveByOffset(sc, tier, left_neighbor)) {
295
+ // Merge: left neighbor + this block → parent at left_neighbor
296
+ freeAtTierWithMerge(left_neighbor, sc, tier + 1);
297
+ return;
298
+ }
299
+ }
300
+ }
301
+
302
+ // No merge possible - just push to freelist
303
+ pushToFreelist(offset, sc, tier, false);
304
+ }
305
+
306
+ /// Free a block after a merge (increments merge count).
307
+ fn freeAtTierWithMerge(offset: u32, sc: SizeClass, tier: usize) void {
308
+ // Try to cascade merge at higher tier
309
+ if (tier + 1 < NUM_TIERS) {
310
+ const block_size = blockSizeForCapacity(sc, tierToCapacity(tier));
311
+
312
+ // Check right neighbor
313
+ const right_neighbor = offset + block_size;
314
+ if (findAndRemoveByOffset(sc, tier, right_neighbor)) {
315
+ freeAtTierWithMerge(offset, sc, tier + 1);
316
+ return;
317
+ }
318
+
319
+ // Check left neighbor
320
+ if (offset >= block_size) {
321
+ const left_neighbor = offset - block_size;
322
+ if (findAndRemoveByOffset(sc, tier, left_neighbor)) {
323
+ freeAtTierWithMerge(left_neighbor, sc, tier + 1);
324
+ return;
325
+ }
326
+ }
327
+ }
328
+
329
+ // No further merge - push with merge count increment
330
+ pushToFreelist(offset, sc, tier, true);
331
+ }
332
+
333
+ /// Push a block onto the freelist with cascading stats.
334
+ fn pushToFreelist(offset: u32, sc: SizeClass, tier: usize, is_merge: bool) void {
335
+ const h = header();
336
+ const old_head = freelistHeadAtTier(sc, tier);
337
+ const free_block = ptrAt(FreeBlock, offset);
338
+
339
+ // Push onto freelist
340
+ free_block.next_ptr = old_head;
341
+
342
+ // Cascading stats: aggregate from old head (if any) + delta
343
+ if (old_head != 0) {
344
+ const old_block = ptrAt(FreeBlock, old_head);
345
+ free_block.freelist_len = old_block.freelist_len + 1;
346
+ free_block.reuse_count = old_block.reuse_count;
347
+ free_block.split_count = old_block.split_count;
348
+ free_block.merge_count = old_block.merge_count + @as(u32, if (is_merge) 1 else 0);
349
+ } else {
350
+ free_block.freelist_len = 1;
351
+ free_block.reuse_count = 0;
352
+ free_block.split_count = 0;
353
+ free_block.merge_count = if (is_merge) 1 else 0;
354
+ }
355
+
356
+ setFreelistHeadAtTier(sc, tier, offset);
357
+ h.free_count += 1;
358
+ }
359
+
360
+ /// Find and remove a block at a specific offset from the freelist.
361
+ /// Returns true if found and removed, false otherwise.
362
+ /// O(n) scan - freelists are expected to be short in practice.
363
+ fn findAndRemoveByOffset(sc: SizeClass, tier: usize, target_offset: u32) bool {
364
+ const head_offset = freelistHeadAtTier(sc, tier);
365
+ if (head_offset == 0) return false;
366
+
367
+ // Check if HEAD is the target
368
+ if (head_offset == target_offset) {
369
+ const head_block = ptrAt(FreeBlock, head_offset);
370
+ setFreelistHeadAtTier(sc, tier, head_block.next_ptr);
371
+
372
+ // Cascade stats to new head
373
+ if (head_block.next_ptr != 0) {
374
+ const new_head = ptrAt(FreeBlock, head_block.next_ptr);
375
+ new_head.freelist_len = head_block.freelist_len - 1;
376
+ new_head.reuse_count = head_block.reuse_count;
377
+ new_head.split_count = head_block.split_count;
378
+ new_head.merge_count = head_block.merge_count;
379
+ }
380
+ return true;
381
+ }
382
+
383
+ // Scan freelist for target
384
+ var prev_offset = head_offset;
385
+ var current_offset = ptrAt(FreeBlock, head_offset).next_ptr;
386
+
387
+ while (current_offset != 0) {
388
+ if (current_offset == target_offset) {
389
+ // Found target - remove from list
390
+ const prev_block = ptrAt(FreeBlock, prev_offset);
391
+ const current_block = ptrAt(FreeBlock, current_offset);
392
+ prev_block.next_ptr = current_block.next_ptr;
393
+
394
+ // Update freelist length in head
395
+ const head_block = ptrAt(FreeBlock, freelistHeadAtTier(sc, tier));
396
+ head_block.freelist_len -= 1;
397
+
398
+ return true;
399
+ }
400
+ prev_offset = current_offset;
401
+ current_offset = ptrAt(FreeBlock, current_offset).next_ptr;
402
+ }
403
+
404
+ return false;
405
+ }
406
+
407
+ // =============================================================================
408
+ // Debug exports (temporary for troubleshooting buddy merge)
409
+ // =============================================================================
410
+
411
+ /// Debug: get freelist head offset for a size class at given capacity
412
+ export fn debug_get_freelist_head(size_class: u8, capacity: u32) u32 {
413
+ const sc: SizeClass = @enumFromInt(size_class);
414
+ const tier = capacityToTier(capacity);
415
+ return freelistHeadAtTier(sc, tier);
416
+ }
417
+
418
+ /// Debug: read next_ptr from a FreeBlock at given offset
419
+ export fn debug_read_next_ptr(offset: u32) u32 {
420
+ if (offset == 0) return 0;
421
+ return ptrAt(FreeBlock, offset).next_ptr;
422
+ }
423
+
424
+ // =============================================================================
425
+ // JS Imports (for timestamp calculation)
426
+ // =============================================================================
427
+
428
+ extern "env" fn performanceNow() f64;
429
+ extern "env" fn dateNow() f64;
430
+
431
+ // =============================================================================
432
+ // Timestamp Calculation
433
+ // =============================================================================
434
+
435
+ inline fn getTimestampNanos(trace_root_ptr: u32) i64 {
436
+ const root = ptrAt(TraceRoot, trace_root_ptr);
437
+ const current_ms = performanceNow();
438
+ const elapsed_ms = current_ms - root.monotonic_ms;
439
+ const elapsed_nanos: i64 = @intFromFloat(elapsed_ms * 1_000_000.0);
440
+ return root.wall_clock_nanos + elapsed_nanos;
441
+ }
442
+
443
+ // =============================================================================
444
+ // Exported Functions - Initialization
445
+ // =============================================================================
446
+
447
+ /// Initialize the allocator header. Call once before first allocation.
448
+ /// Idempotent - subsequent calls are no-ops if already initialized.
449
+ export fn init() void {
450
+ const h = header();
451
+ const is_first_init = h.bump_ptr == 0;
452
+
453
+ // Only initialize header on first call
454
+ if (is_first_init) {
455
+ h.bump_ptr = @sizeOf(Header);
456
+ h.alloc_count = 0;
457
+ h.free_count = 0;
458
+ h.span_id_counter = 0;
459
+
460
+ // Clear all freelists (28 capacity-tiered + 1 identity)
461
+ for (&h.freelists) |*fl| {
462
+ fl.* = 0;
463
+ }
464
+ h.freelist_identity = 0;
465
+ }
466
+ // Don't reset thread_id - it persists across init calls
467
+ }
468
+
469
+ /// Reset all freelists (for testing/benchmarking).
470
+ /// WARNING: This leaks all allocated blocks. Use free() for proper cleanup.
471
+ export fn reset() void {
472
+ const h = header();
473
+ h.bump_ptr = @sizeOf(Header);
474
+ h.alloc_count = 0;
475
+ h.free_count = 0;
476
+ h.span_id_counter = 0;
477
+
478
+ // Clear all freelists
479
+ for (&h.freelists) |*fl| {
480
+ fl.* = 0;
481
+ }
482
+ h.freelist_identity = 0;
483
+ // Don't reset thread_id - it persists across reset calls
484
+ }
485
+
486
+ // =============================================================================
487
+ // Exported Functions - Debug/Stats
488
+ // =============================================================================
489
+
490
+ export fn get_bump_ptr() u32 {
491
+ return header().bump_ptr;
492
+ }
493
+
494
+ export fn get_alloc_count() u32 {
495
+ return header().alloc_count;
496
+ }
497
+
498
+ export fn get_free_count() u32 {
499
+ return header().free_count;
500
+ }
501
+
502
+ /// Get span system block size for given capacity.
503
+ export fn get_span_system_size(capacity: u32) u32 {
504
+ return blockSizeForCapacity(.span_system, capacity);
505
+ }
506
+
507
+ /// Get 1-byte column block size for given capacity.
508
+ export fn get_col_1b_size(capacity: u32) u32 {
509
+ return blockSizeForCapacity(.col_1b, capacity);
510
+ }
511
+
512
+ /// Get 4-byte column block size for given capacity.
513
+ export fn get_col_4b_size(capacity: u32) u32 {
514
+ return blockSizeForCapacity(.col_4b, capacity);
515
+ }
516
+
517
+ /// Get 8-byte column block size for given capacity.
518
+ export fn get_col_8b_size(capacity: u32) u32 {
519
+ return blockSizeForCapacity(.col_8b, capacity);
520
+ }
521
+
522
+ // =============================================================================
523
+ // Exported Functions - Thread ID
524
+ // =============================================================================
525
+
526
+ /// Set the thread ID (called once from JS on module init).
527
+ export fn set_thread_id(high: u32, low: u32) void {
528
+ const h = header();
529
+ h.thread_id = (@as(u64, high) << 32) | @as(u64, low);
530
+ h.thread_id_set = 1;
531
+ }
532
+
533
+ export fn get_thread_id_high() u32 {
534
+ return @truncate(header().thread_id >> 32);
535
+ }
536
+
537
+ export fn get_thread_id_low() u32 {
538
+ return @truncate(header().thread_id);
539
+ }
540
+
541
+ export fn is_thread_id_set() u8 {
542
+ return header().thread_id_set;
543
+ }
544
+
545
+ export fn get_span_id_counter() u32 {
546
+ return header().span_id_counter;
547
+ }
548
+
549
+ // =============================================================================
550
+ // Exported Functions - Freelist Statistics
551
+ // =============================================================================
552
+
553
+ /// Get freelist length for a size class at given capacity (O(1) - read from HEAD)
554
+ export fn get_freelist_len(size_class: u8, capacity: u32) u32 {
555
+ const sc: SizeClass = @enumFromInt(size_class);
556
+ const tier = capacityToTier(capacity);
557
+ const head_offset = freelistHeadAtTier(sc, tier);
558
+ if (head_offset == 0) return 0;
559
+ return ptrAt(FreeBlock, head_offset).freelist_len;
560
+ }
561
+
562
+ /// Get total reuse count for a size class at given capacity (O(1) - read from HEAD)
563
+ export fn get_freelist_reuse_count(size_class: u8, capacity: u32) u32 {
564
+ const sc: SizeClass = @enumFromInt(size_class);
565
+ const tier = capacityToTier(capacity);
566
+ const head_offset = freelistHeadAtTier(sc, tier);
567
+ if (head_offset == 0) return 0;
568
+ return ptrAt(FreeBlock, head_offset).reuse_count;
569
+ }
570
+
571
+ /// Get split count for a size class at given capacity (O(1) - read from HEAD)
572
+ export fn get_freelist_split_count(size_class: u8, capacity: u32) u32 {
573
+ const sc: SizeClass = @enumFromInt(size_class);
574
+ const tier = capacityToTier(capacity);
575
+ const head_offset = freelistHeadAtTier(sc, tier);
576
+ if (head_offset == 0) return 0;
577
+ return ptrAt(FreeBlock, head_offset).split_count;
578
+ }
579
+
580
+ /// Get merge count for a size class at given capacity (O(1) - read from HEAD)
581
+ export fn get_freelist_merge_count(size_class: u8, capacity: u32) u32 {
582
+ const sc: SizeClass = @enumFromInt(size_class);
583
+ const tier = capacityToTier(capacity);
584
+ const head_offset = freelistHeadAtTier(sc, tier);
585
+ if (head_offset == 0) return 0;
586
+ return ptrAt(FreeBlock, head_offset).merge_count;
587
+ }
588
+
589
+ // =============================================================================
590
+ // Exported Functions - Identity Block Operations
591
+ // =============================================================================
592
+
593
+ /// Allocate an identity block (fixed 128 bytes, not capacity-tiered)
594
+ fn allocIdentity() u32 {
595
+ const h = header();
596
+ const head_offset = h.freelist_identity;
597
+
598
+ if (head_offset != 0) {
599
+ // Pop from freelist
600
+ const free_block = ptrAt(FreeBlock, head_offset);
601
+ h.freelist_identity = free_block.next_ptr;
602
+
603
+ if (free_block.next_ptr != 0) {
604
+ ptrAt(FreeBlock, free_block.next_ptr).reuse_count += 1;
605
+ }
606
+
607
+ h.alloc_count += 1;
608
+ return head_offset;
609
+ }
610
+
611
+ // Bump allocate
612
+ const current_bump = h.bump_ptr;
613
+ const aligned = (current_bump + 7) & ~@as(u32, 7);
614
+ const new_bump = aligned + @sizeOf(Identity);
615
+
616
+ h.bump_ptr = new_bump;
617
+ h.alloc_count += 1;
618
+
619
+ return aligned;
620
+ }
621
+
622
+ /// Free an identity block
623
+ fn freeIdentity(offset: u32) void {
624
+ const h = header();
625
+ const old_head = h.freelist_identity;
626
+ const free_block = ptrAt(FreeBlock, offset);
627
+
628
+ free_block.next_ptr = old_head;
629
+
630
+ if (old_head != 0) {
631
+ const old_block = ptrAt(FreeBlock, old_head);
632
+ free_block.freelist_len = old_block.freelist_len + 1;
633
+ free_block.reuse_count = old_block.reuse_count;
634
+ free_block.split_count = old_block.split_count;
635
+ free_block.merge_count = old_block.merge_count;
636
+ } else {
637
+ free_block.freelist_len = 1;
638
+ free_block.reuse_count = 0;
639
+ free_block.split_count = 0;
640
+ free_block.merge_count = 0;
641
+ }
642
+
643
+ h.freelist_identity = offset;
644
+ h.free_count += 1;
645
+ }
646
+
647
+ /// Allocate identity block and provide offset where JS should write trace_id bytes.
648
+ /// Returns packed u64: (identity_offset << 32) | trace_id_field_offset
649
+ /// JS can write bytes directly to memory[trace_id_field_offset..trace_id_field_offset+len]
650
+ export fn alloc_identity_root_for_js_write(trace_id_len: u32) u64 {
651
+ const max_len = @sizeOf(@TypeOf(@as(Identity, undefined).trace_id));
652
+ if (trace_id_len > max_len) {
653
+ return 0; // trace_id too long
654
+ }
655
+
656
+ const offset = allocIdentity();
657
+ const identity = ptrAt(Identity, offset);
658
+
659
+ // Initialize identity (same as alloc_identity_root)
660
+ const h = header();
661
+ h.span_id_counter += 1;
662
+ identity.span_id = h.span_id_counter;
663
+ identity.write_index = 0;
664
+ identity.trace_id_len = @truncate(trace_id_len);
665
+
666
+ // Calculate absolute byte offset to trace_id field
667
+ // Cast to u32 explicitly to ensure proper type handling
668
+ const field_offset_in_struct: u32 = @offsetOf(Identity, "trace_id");
669
+ const trace_id_field_offset: u32 = offset + field_offset_in_struct;
670
+
671
+ // Pack both offsets into u64: upper 32 bits = identity offset, lower 32 bits = trace_id field offset
672
+ return (@as(u64, offset) << 32) | @as(u64, trace_id_field_offset);
673
+ }
674
+
675
+ /// Allocate and initialize a CHILD identity block.
676
+ export fn alloc_identity_child() u32 {
677
+ const offset = allocIdentity();
678
+ const identity = ptrAt(Identity, offset);
679
+
680
+ const h = header();
681
+ h.span_id_counter += 1;
682
+ identity.span_id = h.span_id_counter;
683
+ identity.write_index = 0;
684
+ identity.trace_id_len = 0; // Child uses parent's trace_id
685
+
686
+ return offset;
687
+ }
688
+
689
+ export fn free_identity(offset: u32) void {
690
+ freeIdentity(offset);
691
+ }
692
+
693
+ export fn read_identity_span_id(identity_ptr: u32) u32 {
694
+ return ptrAt(Identity, identity_ptr).span_id;
695
+ }
696
+
697
+ export fn read_identity_trace_id_len(identity_ptr: u32) u32 {
698
+ return ptrAt(Identity, identity_ptr).trace_id_len;
699
+ }
700
+
701
+ export fn get_identity_trace_id_ptr(identity_ptr: u32) u32 {
702
+ // trace_id starts at offset 9 within Identity struct
703
+ return identity_ptr + @offsetOf(Identity, "trace_id");
704
+ }
705
+
706
+ export fn read_write_index(identity_ptr: u32) u32 {
707
+ return ptrAt(Identity, identity_ptr).write_index;
708
+ }
709
+
710
+ // =============================================================================
711
+ // Exported Functions - Block Allocation (capacity-aware)
712
+ // =============================================================================
713
+ // Each OpContext may have different capacity, so capacity is passed to each call.
714
+ // Capacity must be a power of 2 between 8 and 512.
715
+
716
+ /// Allocate a span system block (timestamp + entry_type for capacity rows).
717
+ export fn alloc_span_system(capacity: u32) u32 {
718
+ return allocWithCapacity(.span_system, capacity);
719
+ }
720
+
721
+ /// Free a span system block.
722
+ export fn free_span_system(offset: u32, capacity: u32) void {
723
+ freeWithCapacity(offset, .span_system, capacity);
724
+ }
725
+
726
+ /// Allocate a 1-byte column block (for enum/boolean).
727
+ export fn alloc_col_1b(capacity: u32) u32 {
728
+ return allocWithCapacity(.col_1b, capacity);
729
+ }
730
+
731
+ /// Free a 1-byte column block.
732
+ export fn free_col_1b(offset: u32, capacity: u32) void {
733
+ freeWithCapacity(offset, .col_1b, capacity);
734
+ }
735
+
736
+ /// Allocate a 4-byte column block (for u32/i32/f32).
737
+ export fn alloc_col_4b(capacity: u32) u32 {
738
+ return allocWithCapacity(.col_4b, capacity);
739
+ }
740
+
741
+ /// Free a 4-byte column block.
742
+ export fn free_col_4b(offset: u32, capacity: u32) void {
743
+ freeWithCapacity(offset, .col_4b, capacity);
744
+ }
745
+
746
+ /// Allocate an 8-byte column block (for f64/i64).
747
+ export fn alloc_col_8b(capacity: u32) u32 {
748
+ return allocWithCapacity(.col_8b, capacity);
749
+ }
750
+
751
+ /// Free an 8-byte column block.
752
+ export fn free_col_8b(offset: u32, capacity: u32) void {
753
+ freeWithCapacity(offset, .col_8b, capacity);
754
+ }
755
+
756
+ /// Allocate with explicit capacity (converts to tier internally).
757
+ fn allocWithCapacity(sc: SizeClass, capacity: u32) u32 {
758
+ const tier = capacityToTier(capacity);
759
+ return allocAtTier(sc, tier);
760
+ }
761
+
762
+ /// Free with explicit capacity (converts to tier internally).
763
+ fn freeWithCapacity(offset: u32, sc: SizeClass, capacity: u32) void {
764
+ const tier = capacityToTier(capacity);
765
+ freeAtTier(offset, sc, tier);
766
+ }
767
+
768
+ // =============================================================================
769
+ // Exported Functions - TraceRoot Operations
770
+ // =============================================================================
771
+
772
+ /// Initialize a TraceRoot at the given offset.
773
+ /// Sets wall clock and monotonic start times for timestamp calculation.
774
+ export fn init_trace_root(trace_root_ptr: u32) void {
775
+ const root = ptrAt(TraceRoot, trace_root_ptr);
776
+ const ms: i64 = @intFromFloat(dateNow());
777
+ root.wall_clock_nanos = ms * 1_000_000;
778
+ root.monotonic_ms = performanceNow();
779
+ }
780
+
781
+ // =============================================================================
782
+ // Exported Functions - Span Lifecycle
783
+ // =============================================================================
784
+
785
+ /// Write span-start to a Span System block.
786
+ /// Sets row 0 (span-start) and row 1 (span-exception placeholder).
787
+ /// Sets write_index = 2 in identity block.
788
+ export fn span_start(system_ptr: u32, identity_ptr: u32, trace_root_ptr: u32, capacity: u32) void {
789
+ const base = bytesAt(system_ptr);
790
+
791
+ // Span system layout: [timestamp: i64 × capacity][entry_type: u8 × capacity]
792
+ const ts_ptr: [*]allowzero i64 = @ptrCast(@alignCast(base));
793
+ const et_ptr: [*]allowzero u8 = base + capacity * 8;
794
+
795
+ // Row 0: span-start
796
+ ts_ptr[0] = getTimestampNanos(trace_root_ptr);
797
+ et_ptr[0] = ENTRY_TYPE_SPAN_START;
798
+
799
+ // Row 1: pre-initialize as span-exception
800
+ ts_ptr[1] = 0;
801
+ et_ptr[1] = ENTRY_TYPE_SPAN_EXCEPTION;
802
+
803
+ // Set write_index = 2
804
+ ptrAt(Identity, identity_ptr).write_index = 2;
805
+ }
806
+
807
+ /// Write span-ok to row 1 (successful completion).
808
+ export fn span_end_ok(system_ptr: u32, trace_root_ptr: u32, capacity: u32) void {
809
+ const base = bytesAt(system_ptr);
810
+ const ts_ptr: [*]allowzero i64 = @ptrCast(@alignCast(base));
811
+ const et_ptr: [*]allowzero u8 = base + capacity * 8;
812
+
813
+ et_ptr[1] = ENTRY_TYPE_SPAN_OK;
814
+ ts_ptr[1] = getTimestampNanos(trace_root_ptr);
815
+ }
816
+
817
+ /// Write span-err to row 1 (error result, not exception).
818
+ export fn span_end_err(system_ptr: u32, trace_root_ptr: u32, capacity: u32) void {
819
+ const base = bytesAt(system_ptr);
820
+ const ts_ptr: [*]allowzero i64 = @ptrCast(@alignCast(base));
821
+ const et_ptr: [*]allowzero u8 = base + capacity * 8;
822
+
823
+ et_ptr[1] = ENTRY_TYPE_SPAN_ERR;
824
+ ts_ptr[1] = getTimestampNanos(trace_root_ptr);
825
+ }
826
+
827
+ /// Write a log entry (info/debug/warn/error).
828
+ /// Bumps write_index, writes timestamp+entry_type, returns the idx written to.
829
+ /// SpanLogger uses returned idx for string column writes.
830
+ export fn write_log_entry(system_ptr: u32, identity_ptr: u32, trace_root_ptr: u32, entry_type: u8, capacity: u32) u32 {
831
+ const identity = ptrAt(Identity, identity_ptr);
832
+ const idx = identity.write_index;
833
+
834
+ const base = bytesAt(system_ptr);
835
+ const ts_ptr: [*]allowzero i64 = @ptrCast(@alignCast(base));
836
+ const et_ptr: [*]allowzero u8 = base + capacity * 8;
837
+
838
+ ts_ptr[idx] = getTimestampNanos(trace_root_ptr);
839
+ et_ptr[idx] = entry_type;
840
+
841
+ identity.write_index = idx + 1;
842
+ return idx;
843
+ }
844
+
845
+ // =============================================================================
846
+ // Exported Functions - Column Write Operations
847
+ // =============================================================================
848
+
849
+ /// Write an f64 value to a column.
850
+ /// Returns: column offset (same as input if already allocated, or newly allocated)
851
+ export fn write_col_f64(col_offset: u32, row_idx: u32, value: f64, capacity: u32) u32 {
852
+ var offset = col_offset;
853
+ if (offset == 0) {
854
+ offset = allocWithCapacity(.col_8b, capacity);
855
+ }
856
+
857
+ const base = bytesAt(offset);
858
+ const null_bitmap_size = (capacity + 7) >> 3;
859
+
860
+ // Write value (after null bitmap)
861
+ const val_ptr: *allowzero align(1) f64 = @ptrCast(base + null_bitmap_size + row_idx * 8);
862
+ val_ptr.* = value;
863
+
864
+ // Set null bit (mark as valid)
865
+ base[row_idx >> 3] |= @as(u8, 1) << @intCast(row_idx & 7);
866
+
867
+ return offset;
868
+ }
869
+
870
+ /// Write a u32 value to a column.
871
+ /// Returns: column offset (same as input if already allocated, or newly allocated)
872
+ export fn write_col_u32(col_offset: u32, row_idx: u32, value: u32, capacity: u32) u32 {
873
+ var offset = col_offset;
874
+ if (offset == 0) {
875
+ offset = allocWithCapacity(.col_4b, capacity);
876
+ }
877
+
878
+ const base = bytesAt(offset);
879
+ const null_bitmap_size = (capacity + 7) >> 3;
880
+ const val_ptr: *allowzero align(1) u32 = @ptrCast(base + null_bitmap_size + row_idx * 4);
881
+ val_ptr.* = value;
882
+ base[row_idx >> 3] |= @as(u8, 1) << @intCast(row_idx & 7);
883
+
884
+ return offset;
885
+ }
886
+
887
+ /// Write a u8 value to a column (for enum/boolean).
888
+ /// Returns: column offset (same as input if already allocated, or newly allocated)
889
+ export fn write_col_u8(col_offset: u32, row_idx: u32, value: u8, capacity: u32) u32 {
890
+ var offset = col_offset;
891
+ if (offset == 0) {
892
+ offset = allocWithCapacity(.col_1b, capacity);
893
+ }
894
+
895
+ const base = bytesAt(offset);
896
+ const null_bitmap_size = (capacity + 7) >> 3;
897
+ base[null_bitmap_size + row_idx] = value;
898
+ base[row_idx >> 3] |= @as(u8, 1) << @intCast(row_idx & 7);
899
+
900
+ return offset;
901
+ }
902
+
903
+ // =============================================================================
904
+ // Exported Functions - Debug/Read Operations
905
+ // =============================================================================
906
+
907
+ /// Get current performance.now() value (for debugging).
908
+ export fn get_performance_now() f64 {
909
+ return performanceNow();
910
+ }
911
+
912
+ /// Compute a timestamp relative to trace root (for debugging).
913
+ export fn debug_compute_timestamp(trace_root_ptr: u32) i64 {
914
+ return getTimestampNanos(trace_root_ptr);
915
+ }
916
+
917
+ /// Read timestamp at given row from a Span System block.
918
+ export fn read_timestamp(system_ptr: u32, row_idx: u32) i64 {
919
+ const base = bytesAt(system_ptr);
920
+ const ts_ptr: [*]allowzero const i64 = @ptrCast(@alignCast(base));
921
+ return ts_ptr[row_idx];
922
+ }
923
+
924
+ /// Read entry_type at given row from a Span System block.
925
+ export fn read_entry_type(system_ptr: u32, row_idx: u32, capacity: u32) u8 {
926
+ const base = bytesAt(system_ptr);
927
+ const et_ptr: [*]allowzero const u8 = base + capacity * 8;
928
+ return et_ptr[row_idx];
929
+ }
930
+
931
+ /// Read f64 value from a column.
932
+ export fn read_col_f64(col_offset: u32, row_idx: u32, capacity: u32) f64 {
933
+ const base = bytesAt(col_offset);
934
+ const null_bitmap_size = (capacity + 7) >> 3;
935
+ const val_ptr: *allowzero align(1) const f64 = @ptrCast(base + null_bitmap_size + row_idx * 8);
936
+ return val_ptr.*;
937
+ }
938
+
939
+ /// Check if null bit is set for a row (1 = valid, 0 = null).
940
+ export fn read_col_is_valid(col_offset: u32, row_idx: u32) u8 {
941
+ const base = bytesAt(col_offset);
942
+ const byte = base[row_idx >> 3];
943
+ const bit: u8 = @as(u8, 1) << @intCast(row_idx & 7);
944
+ return if ((byte & bit) != 0) 1 else 0;
945
+ }