@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,544 @@
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 { shouldTuneCapacity } from '../capacityTuning.js';
5
+ import { createSpanLogger } from '../codegen/spanLoggerGenerator.js';
6
+ import { DEFAULT_METADATA } from '../opContext/defineOp.js';
7
+ import { S } from '../schema/builder.js';
8
+ import { LogSchema } from '../schema/LogSchema.js';
9
+ import { mergeWithSystemSchema } from '../schema/systemSchema.js';
10
+ import { createSpanBuffer, getSpanBufferClass } from '../spanBuffer.js';
11
+ import type { SpanBufferStats } from '../spanBufferStats.js';
12
+
13
+ import { createTestTraceRoot, createTestTracerOptions } from './test-helpers.js';
14
+
15
+ /**
16
+ * Create mock SpanBufferStats for testing capacity tuning.
17
+ *
18
+ * Per agent-todo/opgroup-refactor.md lines 58-70, 525-547:
19
+ * Stats are on SpanBufferClass.stats (static property), NOT on LogBinding.
20
+ */
21
+ function createMockStats(overrides: Partial<SpanBufferStats> = {}): SpanBufferStats {
22
+ return {
23
+ capacity: overrides.capacity ?? DEFAULT_BUFFER_CAPACITY,
24
+ totalWrites: overrides.totalWrites ?? 0,
25
+ spansCreated: overrides.spansCreated ?? 0,
26
+ };
27
+ }
28
+
29
+ /**
30
+ * Compute utilization for testing
31
+ * Utilization = totalWrites / (spansCreated * usableRowsPerSpan)
32
+ */
33
+ function computeUtilization(stats: SpanBufferStats): number {
34
+ const usableRowsPerSpan = stats.capacity - 2;
35
+ return stats.spansCreated > 0 ? stats.totalWrites / (stats.spansCreated * usableRowsPerSpan) : 0;
36
+ }
37
+
38
+ describe('Capacity Tuning Algorithm', () => {
39
+ let stats: SpanBufferStats;
40
+
41
+ beforeEach(() => {
42
+ stats = createMockStats();
43
+ });
44
+
45
+ describe('shouldTuneCapacity - Success Cases', () => {
46
+ it('should increase capacity when utilization > 150%', () => {
47
+ // 10 spans, capacity 8, usable rows = 6
48
+ // At 150% utilization: 10 * 6 * 1.5 = 90 writes
49
+ // At 160% utilization: 10 * 6 * 1.6 = 96 writes
50
+ stats.spansCreated = 10;
51
+ stats.capacity = 8;
52
+ stats.totalWrites = 96; // 160% utilization
53
+
54
+ const initialCapacity = stats.capacity;
55
+ shouldTuneCapacity(stats);
56
+
57
+ expect(stats.capacity).toBe(initialCapacity * 2); // Doubled
58
+ expect(stats.totalWrites).toBe(0); // Reset
59
+ expect(stats.spansCreated).toBe(0); // Reset
60
+ });
61
+
62
+ it('should decrease capacity when utilization < 50%', () => {
63
+ // 10 spans, capacity 32, usable rows = 30
64
+ // At 50% utilization: 10 * 30 * 0.5 = 150 writes
65
+ // At 40% utilization: 10 * 30 * 0.4 = 120 writes
66
+ stats.spansCreated = 10;
67
+ stats.capacity = 32;
68
+ stats.totalWrites = 120; // 40% utilization
69
+
70
+ shouldTuneCapacity(stats);
71
+
72
+ expect(stats.capacity).toBe(16); // Halved
73
+ expect(stats.totalWrites).toBe(0); // Reset
74
+ expect(stats.spansCreated).toBe(0); // Reset
75
+ });
76
+
77
+ it('should double capacity from default to 2x', () => {
78
+ stats.spansCreated = 10;
79
+ stats.capacity = DEFAULT_BUFFER_CAPACITY; // 8
80
+ const usableRows = stats.capacity - 2; // 6
81
+ stats.totalWrites = Math.floor(usableRows * 10 * 1.6); // 160% utilization
82
+
83
+ shouldTuneCapacity(stats);
84
+
85
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2);
86
+ });
87
+
88
+ it('should double capacity from 128 to 256', () => {
89
+ stats.spansCreated = 10;
90
+ stats.capacity = 128;
91
+ const usableRows = stats.capacity - 2; // 126
92
+ stats.totalWrites = Math.floor(usableRows * 10 * 1.6); // 160% utilization
93
+
94
+ shouldTuneCapacity(stats);
95
+
96
+ expect(stats.capacity).toBe(256);
97
+ });
98
+
99
+ it('should halve capacity from 4x to 2x default', () => {
100
+ stats.spansCreated = 10;
101
+ stats.capacity = DEFAULT_BUFFER_CAPACITY * 4; // 32
102
+ const usableRows = stats.capacity - 2; // 30
103
+ stats.totalWrites = Math.floor(usableRows * 10 * 0.4); // 40% utilization
104
+
105
+ shouldTuneCapacity(stats);
106
+
107
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2);
108
+ });
109
+ });
110
+
111
+ describe('shouldTuneCapacity - Edge Cases', () => {
112
+ it('should not tune with insufficient spans (< 10)', () => {
113
+ stats.spansCreated = 9;
114
+ stats.capacity = 8;
115
+ stats.totalWrites = 1000; // Very high utilization, but not enough spans
116
+
117
+ const initialCapacity = stats.capacity;
118
+ shouldTuneCapacity(stats);
119
+
120
+ expect(stats.capacity).toBe(initialCapacity); // Unchanged
121
+ });
122
+
123
+ it('should not tune when utilization is in stable zone (50-150%)', () => {
124
+ stats.spansCreated = 10;
125
+ stats.capacity = 8;
126
+ const usableRows = stats.capacity - 2; // 6
127
+ stats.totalWrites = usableRows * 10; // Exactly 100% utilization
128
+
129
+ const initialCapacity = stats.capacity;
130
+ shouldTuneCapacity(stats);
131
+
132
+ expect(stats.capacity).toBe(initialCapacity);
133
+ });
134
+
135
+ it('should cap capacity at 1024', () => {
136
+ stats.spansCreated = 10;
137
+ stats.capacity = 1024;
138
+ const usableRows = stats.capacity - 2;
139
+ stats.totalWrites = Math.floor(usableRows * 10 * 2); // 200% utilization
140
+
141
+ shouldTuneCapacity(stats);
142
+
143
+ expect(stats.capacity).toBe(1024); // Cannot increase beyond 1024
144
+ });
145
+
146
+ it('should cap capacity at minimum (8) when decreasing', () => {
147
+ stats.spansCreated = 10;
148
+ stats.capacity = 8;
149
+ stats.totalWrites = 10; // Very low utilization
150
+
151
+ shouldTuneCapacity(stats);
152
+
153
+ expect(stats.capacity).toBe(8); // Cannot decrease below 8
154
+ });
155
+
156
+ it('should handle exactly 150% utilization (boundary - no increase)', () => {
157
+ stats.spansCreated = 10;
158
+ stats.capacity = 8;
159
+ const usableRows = stats.capacity - 2; // 6
160
+ stats.totalWrites = usableRows * 10 * 1.5; // Exactly 150%
161
+
162
+ const initialCapacity = stats.capacity;
163
+ shouldTuneCapacity(stats);
164
+
165
+ expect(stats.capacity).toBe(initialCapacity); // > 150%, not >= 150%
166
+ });
167
+
168
+ it('should handle exactly 50% utilization (boundary - no decrease)', () => {
169
+ stats.spansCreated = 10;
170
+ stats.capacity = 32;
171
+ const usableRows = stats.capacity - 2;
172
+ stats.totalWrites = usableRows * 10 * 0.5; // Exactly 50%
173
+
174
+ const initialCapacity = stats.capacity;
175
+ shouldTuneCapacity(stats);
176
+
177
+ expect(stats.capacity).toBe(initialCapacity); // < 50%, not <= 50%
178
+ });
179
+
180
+ it('should tune at 151% utilization', () => {
181
+ stats.spansCreated = 100;
182
+ stats.capacity = 8;
183
+ const usableRows = stats.capacity - 2; // 6
184
+ stats.totalWrites = Math.floor(usableRows * 100 * 1.51); // 151% utilization
185
+
186
+ shouldTuneCapacity(stats);
187
+
188
+ expect(stats.capacity).toBe(16); // Doubled
189
+ });
190
+
191
+ it('should tune at 49% utilization', () => {
192
+ stats.spansCreated = 100;
193
+ stats.capacity = 32;
194
+ const usableRows = stats.capacity - 2;
195
+ stats.totalWrites = Math.floor(usableRows * 100 * 0.49); // 49% utilization
196
+
197
+ shouldTuneCapacity(stats);
198
+
199
+ expect(stats.capacity).toBe(16); // Halved
200
+ });
201
+
202
+ it('should handle zero writes', () => {
203
+ stats.spansCreated = 10;
204
+ stats.totalWrites = 0;
205
+ stats.capacity = 32;
206
+
207
+ shouldTuneCapacity(stats);
208
+
209
+ expect(stats.capacity).toBe(16); // Should decrease (0% utilization < 50%)
210
+ });
211
+
212
+ it('should handle zero spans (no tuning possible)', () => {
213
+ stats.spansCreated = 0;
214
+ stats.totalWrites = 1000;
215
+ stats.capacity = 8;
216
+
217
+ const initialCapacity = stats.capacity;
218
+ shouldTuneCapacity(stats);
219
+
220
+ expect(stats.capacity).toBe(initialCapacity); // Unchanged - not enough spans
221
+ });
222
+ });
223
+
224
+ describe('shouldTuneCapacity - Capacity Bounds', () => {
225
+ it('should not increase beyond 1024 even with extreme utilization', () => {
226
+ stats.spansCreated = 10;
227
+ stats.capacity = 1024;
228
+ stats.totalWrites = 1000000; // Extreme utilization
229
+
230
+ shouldTuneCapacity(stats);
231
+
232
+ expect(stats.capacity).toBe(1024);
233
+ });
234
+
235
+ it('should cap at 1024 when doubling from 512', () => {
236
+ stats.spansCreated = 10;
237
+ stats.capacity = 512;
238
+ const usableRows = stats.capacity - 2;
239
+ stats.totalWrites = Math.floor(usableRows * 10 * 2); // 200% utilization
240
+
241
+ shouldTuneCapacity(stats);
242
+
243
+ expect(stats.capacity).toBe(1024); // Capped at 1024
244
+ });
245
+
246
+ it('should not decrease below minimum', () => {
247
+ stats.spansCreated = 10;
248
+ stats.capacity = 8;
249
+ stats.totalWrites = 1; // Very low utilization
250
+
251
+ shouldTuneCapacity(stats);
252
+
253
+ expect(stats.capacity).toBe(8);
254
+ });
255
+
256
+ it('should cap at minimum when halving from 16', () => {
257
+ stats.spansCreated = 10;
258
+ stats.capacity = 16;
259
+ const usableRows = stats.capacity - 2;
260
+ stats.totalWrites = Math.floor(usableRows * 10 * 0.3); // 30% utilization
261
+
262
+ shouldTuneCapacity(stats);
263
+
264
+ expect(stats.capacity).toBe(8);
265
+ });
266
+ });
267
+
268
+ describe('Stats Reset After Tuning', () => {
269
+ it('should reset stats after increasing capacity', () => {
270
+ stats.spansCreated = 10;
271
+ stats.capacity = 8;
272
+ stats.totalWrites = 100; // High utilization
273
+
274
+ shouldTuneCapacity(stats);
275
+
276
+ expect(stats.totalWrites).toBe(0);
277
+ expect(stats.spansCreated).toBe(0);
278
+ });
279
+
280
+ it('should reset stats after decreasing capacity', () => {
281
+ stats.spansCreated = 10;
282
+ stats.capacity = 32;
283
+ stats.totalWrites = 50; // Low utilization
284
+
285
+ shouldTuneCapacity(stats);
286
+
287
+ expect(stats.totalWrites).toBe(0);
288
+ expect(stats.spansCreated).toBe(0);
289
+ });
290
+
291
+ it('should not reset stats when no tuning occurs', () => {
292
+ stats.spansCreated = 5; // Not enough spans
293
+ stats.totalWrites = 1000;
294
+
295
+ shouldTuneCapacity(stats);
296
+
297
+ expect(stats.totalWrites).toBe(1000); // Unchanged
298
+ expect(stats.spansCreated).toBe(5); // Unchanged
299
+ });
300
+ });
301
+
302
+ describe('Multiple Tuning Cycles', () => {
303
+ it('should handle multiple increases correctly', () => {
304
+ // Start at default (capacity=8, usableRows=6)
305
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY);
306
+
307
+ // First increase: need >150% utilization
308
+ // usableRows=6, spansCreated=10 → need totalWrites > 10*6*1.5 = 90
309
+ stats.spansCreated = 10;
310
+ stats.totalWrites = 100; // 100/(10*6) = 1.67 > 1.5 → grows to 16
311
+ shouldTuneCapacity(stats);
312
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2); // 16
313
+
314
+ // Second increase: capacity=16, usableRows=14
315
+ // need totalWrites > 10*14*1.5 = 210
316
+ stats.spansCreated = 10;
317
+ stats.totalWrites = 220; // 220/(10*14) = 1.57 > 1.5 → grows to 32
318
+ shouldTuneCapacity(stats);
319
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 4); // 32
320
+ });
321
+
322
+ it('should handle multiple decreases correctly', () => {
323
+ stats.capacity = DEFAULT_BUFFER_CAPACITY * 8; // Start high (64)
324
+
325
+ // First decrease
326
+ stats.spansCreated = 10;
327
+ stats.totalWrites = 50; // Low utilization
328
+ shouldTuneCapacity(stats);
329
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 4); // 32
330
+
331
+ // Second decrease
332
+ stats.spansCreated = 10;
333
+ stats.totalWrites = 50;
334
+ shouldTuneCapacity(stats);
335
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2); // 16
336
+
337
+ // Third decrease
338
+ stats.spansCreated = 10;
339
+ stats.totalWrites = 20;
340
+ shouldTuneCapacity(stats);
341
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY); // 8
342
+ });
343
+
344
+ it('should handle increase then stabilize', () => {
345
+ // Start at default
346
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY); // 8
347
+
348
+ // Increase due to high utilization
349
+ stats.spansCreated = 10;
350
+ stats.totalWrites = 100;
351
+ shouldTuneCapacity(stats);
352
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2); // 16
353
+
354
+ // Now with new capacity, same workload should be stable
355
+ // 10 spans * (16-2) usable * 100% = 140 writes ideal
356
+ stats.spansCreated = 10;
357
+ stats.totalWrites = 140; // 100% utilization - stable zone
358
+ shouldTuneCapacity(stats);
359
+ expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2); // Still 16
360
+ });
361
+ });
362
+
363
+ describe('Property-Based Testing for Utilization Formula', () => {
364
+ it('should verify all mathematical invariants for arbitrary inputs', () => {
365
+ fc.assert(
366
+ fc.property(
367
+ fc.record({
368
+ totalWrites: fc.integer({ min: 0, max: 10000 }),
369
+ spansCreated: fc.integer({ min: 0, max: 1000 }),
370
+ initialCapacity: fc.constantFrom(8, 16, 32, 64, 128, 256, 512, 1024),
371
+ }),
372
+ ({ totalWrites, spansCreated, initialCapacity }) => {
373
+ // Set up stats state
374
+ stats.totalWrites = totalWrites;
375
+ stats.spansCreated = spansCreated;
376
+ stats.capacity = initialCapacity;
377
+
378
+ const beforeCapacity = stats.capacity;
379
+ const utilization = computeUtilization(stats);
380
+ shouldTuneCapacity(stats);
381
+ const afterCapacity = stats.capacity;
382
+
383
+ // Core invariants that must always hold
384
+ expect(afterCapacity).toBeGreaterThanOrEqual(8);
385
+ expect(afterCapacity).toBeLessThanOrEqual(1024);
386
+ expect(afterCapacity & (afterCapacity - 1)).toBe(0); // Power of 2
387
+
388
+ // Verify exact behavior matches specification
389
+ const hasEnoughSpans = spansCreated >= 10;
390
+
391
+ if (hasEnoughSpans) {
392
+ if (utilization > 1.5 && beforeCapacity < 1024) {
393
+ expect(afterCapacity).toBe(Math.min(beforeCapacity * 2, 1024));
394
+ } else if (utilization < 0.5 && beforeCapacity > 8) {
395
+ expect(afterCapacity).toBe(Math.max(8, beforeCapacity / 2));
396
+ } else {
397
+ expect(afterCapacity).toBe(beforeCapacity);
398
+ }
399
+ } else {
400
+ expect(afterCapacity).toBe(beforeCapacity);
401
+ }
402
+
403
+ // Stats reset invariant: if capacity changed, stats are reset
404
+ if (afterCapacity !== beforeCapacity) {
405
+ expect(stats.totalWrites).toBe(0);
406
+ expect(stats.spansCreated).toBe(0);
407
+ }
408
+ },
409
+ ),
410
+ { numRuns: 1000 },
411
+ );
412
+ });
413
+
414
+ it('should verify anti-flip-flop property: after tuning, opposite action is not triggered', () => {
415
+ fc.assert(
416
+ fc.property(
417
+ fc.record({
418
+ spansCreated: fc.integer({ min: 10, max: 100 }),
419
+ initialCapacity: fc.constantFrom(8, 16, 32, 64, 128, 256, 512),
420
+ utilizationPercent: fc.integer({ min: 1, max: 300 }),
421
+ }),
422
+ ({ spansCreated, initialCapacity, utilizationPercent }) => {
423
+ stats.spansCreated = spansCreated;
424
+ stats.capacity = initialCapacity;
425
+
426
+ const usableRows = initialCapacity - 2;
427
+ const totalWrites = Math.floor((usableRows * spansCreated * utilizationPercent) / 100);
428
+ stats.totalWrites = totalWrites;
429
+
430
+ const beforeCapacity = stats.capacity;
431
+ shouldTuneCapacity(stats);
432
+ const afterCapacity = stats.capacity;
433
+
434
+ if (afterCapacity !== beforeCapacity) {
435
+ // Simulate the SAME workload (same totalWrites) with the new capacity
436
+ // This tests: if we tune and then see the same workload again,
437
+ // we should NOT immediately trigger the opposite tuning action
438
+ // Note: stats are reset after tuning, so use saved totalWrites
439
+ const newUsableRows = afterCapacity - 2;
440
+ const newUtilization = totalWrites / (spansCreated * newUsableRows);
441
+
442
+ if (afterCapacity > beforeCapacity) {
443
+ // We grew because utilization was >150%
444
+ // After growing, the new utilization should NOT trigger shrinking (<50%)
445
+ // This is the anti-flip-flop property
446
+ expect(newUtilization).toBeGreaterThanOrEqual(0.5);
447
+ } else {
448
+ // We shrunk because utilization was <50%
449
+ // After shrinking, the new utilization should NOT trigger growing (>150%)
450
+ expect(newUtilization).toBeLessThanOrEqual(1.5);
451
+ }
452
+ }
453
+ },
454
+ ),
455
+ { numRuns: 500 },
456
+ );
457
+ });
458
+ });
459
+
460
+ describe('Integration with SpanLogger overflow', () => {
461
+ const userIntegrationSchema = new LogSchema({
462
+ testField: S.category(),
463
+ });
464
+
465
+ const integrationSchema = new LogSchema(
466
+ mergeWithSystemSchema({
467
+ testField: S.category(),
468
+ }),
469
+ );
470
+
471
+ it('should tune capacity based on utilization after many spans', () => {
472
+ const SpanBufferClass = getSpanBufferClass(integrationSchema);
473
+ const stats = SpanBufferClass.stats;
474
+
475
+ // Reset stats
476
+ const initialCapacity = 8;
477
+ stats.capacity = initialCapacity;
478
+ stats.totalWrites = 0;
479
+ stats.spansCreated = 0;
480
+
481
+ // Simulate 10+ spans with high utilization (>150%)
482
+ // Capacity 8, usable rows = 6
483
+ // 150% utilization = 9 writes per span
484
+ // 160% utilization = 9.6 writes per span
485
+ for (let span = 0; span < 12; span++) {
486
+ const buffer = createSpanBuffer(
487
+ integrationSchema,
488
+ createTestTraceRoot('test-trace'),
489
+ DEFAULT_METADATA,
490
+ undefined,
491
+ );
492
+ const logger = createSpanLogger(integrationSchema, buffer);
493
+
494
+ // Write 10 entries per span (160% utilization of 6 usable rows)
495
+ for (let i = 0; i < 10; i++) {
496
+ logger.info(`message ${i}`);
497
+ }
498
+ }
499
+
500
+ // After 12 spans with 10 writes each = 120 writes
501
+ // Utilization = 120 / (12 * 6) = 166% > 150%
502
+ // Should have triggered capacity increase
503
+ expect(stats.capacity).toBeGreaterThan(initialCapacity);
504
+ expect(stats.capacity & (stats.capacity - 1)).toBe(0); // Power of 2
505
+ });
506
+
507
+ it('should call onStatsWillResetFor before stats reset during tuning', async () => {
508
+ const { defineOpContext } = await import('../defineOpContext.js');
509
+ const { TestTracer } = await import('../tracers/TestTracer.js');
510
+
511
+ const ctx = defineOpContext({
512
+ logSchema: userIntegrationSchema,
513
+ });
514
+
515
+ const tracer = new TestTracer(ctx, { ...createTestTracerOptions() });
516
+ const { trace } = tracer;
517
+
518
+ const SpanBufferClass = getSpanBufferClass(integrationSchema);
519
+ const stats = SpanBufferClass.stats;
520
+ stats.capacity = 8;
521
+ stats.totalWrites = 0;
522
+ stats.spansCreated = 0;
523
+
524
+ // Execute multiple traces to accumulate enough spans for tuning
525
+ for (let t = 0; t < 15; t++) {
526
+ trace(`test-trace-${t}`, (ctx) => {
527
+ // Write many entries to trigger high utilization
528
+ for (let i = 0; i < 15; i++) {
529
+ ctx.log.info(`entry ${i}`);
530
+ }
531
+ });
532
+ }
533
+
534
+ // If capacity was tuned, we should have stats snapshots
535
+ // (captured in onStatsWillResetFor before reset)
536
+ if (tracer.statsSnapshots.length > 0) {
537
+ const firstSnapshot = tracer.statsSnapshots[0];
538
+ expect(firstSnapshot.totalWrites).toBeGreaterThan(0);
539
+ expect(firstSnapshot.capacity).toBeGreaterThanOrEqual(8);
540
+ expect(firstSnapshot.buffer).toBeDefined();
541
+ }
542
+ });
543
+ });
544
+ });