@smoothbricks/lmao 0.2.2 → 0.2.3

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 (276) hide show
  1. package/dist/allocator.wasm +0 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/lib/JsBufferStrategy.d.ts +4 -3
  6. package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
  7. package/dist/lib/JsBufferStrategy.js +18 -11
  8. package/dist/lib/arrow/lease.d.ts +10 -0
  9. package/dist/lib/arrow/lease.d.ts.map +1 -0
  10. package/dist/lib/arrow/lease.js +33 -0
  11. package/dist/lib/arrow/utils.d.ts +3 -4
  12. package/dist/lib/arrow/utils.d.ts.map +1 -1
  13. package/dist/lib/arrow/utils.js +12 -13
  14. package/dist/lib/arrow/vocabularyDictionary.d.ts +21 -0
  15. package/dist/lib/arrow/vocabularyDictionary.d.ts.map +1 -0
  16. package/dist/lib/arrow/vocabularyDictionary.js +95 -0
  17. package/dist/lib/bufferStrategy.d.ts +3 -2
  18. package/dist/lib/bufferStrategy.d.ts.map +1 -1
  19. package/dist/lib/cloudflare/traceRows.d.ts.map +1 -1
  20. package/dist/lib/cloudflare/traceRows.js +3 -2
  21. package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
  22. package/dist/lib/codegen/evaluatorGenerator.js +12 -11
  23. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +44 -82
  24. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
  25. package/dist/lib/codegen/fixedPositionWriterGenerator.js +223 -162
  26. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts +63 -0
  27. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts.map +1 -0
  28. package/dist/lib/codegen/spanLoggerClosureMaterializer.js +447 -0
  29. package/dist/lib/codegen/spanLoggerGenerator.d.ts +36 -19
  30. package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
  31. package/dist/lib/codegen/spanLoggerGenerator.js +164 -158
  32. package/dist/lib/convertToArrow.d.ts +7 -2
  33. package/dist/lib/convertToArrow.d.ts.map +1 -1
  34. package/dist/lib/convertToArrow.js +499 -285
  35. package/dist/lib/defineOpContext.js +1 -1
  36. package/dist/lib/enumMetadata.d.ts +19 -0
  37. package/dist/lib/enumMetadata.d.ts.map +1 -0
  38. package/dist/lib/enumMetadata.js +86 -0
  39. package/dist/lib/flushScheduler.d.ts.map +1 -1
  40. package/dist/lib/flushScheduler.js +13 -4
  41. package/dist/lib/library.d.ts +16 -98
  42. package/dist/lib/library.d.ts.map +1 -1
  43. package/dist/lib/library.js +32 -525
  44. package/dist/lib/logBinding.d.ts +21 -27
  45. package/dist/lib/logBinding.d.ts.map +1 -1
  46. package/dist/lib/op.d.ts +30 -30
  47. package/dist/lib/op.d.ts.map +1 -1
  48. package/dist/lib/op.js +15 -22
  49. package/dist/lib/opContext/createOpGroup.d.ts +1 -1
  50. package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
  51. package/dist/lib/opContext/createOpGroup.js +22 -29
  52. package/dist/lib/opContext/defineOp.d.ts +4 -4
  53. package/dist/lib/opContext/defineOp.d.ts.map +1 -1
  54. package/dist/lib/opContext/defineOp.js +53 -10
  55. package/dist/lib/opContext/opGroupTypes.d.ts +2 -2
  56. package/dist/lib/opContext/opTypes.d.ts +1 -1
  57. package/dist/lib/opContext/opTypes.d.ts.map +1 -1
  58. package/dist/lib/opContext/spanContextTypes.d.ts +29 -14
  59. package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -1
  60. package/dist/lib/opContext/types.d.ts +4 -4
  61. package/dist/lib/opContext/types.d.ts.map +1 -1
  62. package/dist/lib/physicalLayoutPlan.d.ts +89 -0
  63. package/dist/lib/physicalLayoutPlan.d.ts.map +1 -0
  64. package/dist/lib/physicalLayoutPlan.js +442 -0
  65. package/dist/lib/resolveMessage.d.ts +9 -0
  66. package/dist/lib/resolveMessage.d.ts.map +1 -0
  67. package/dist/lib/resolveMessage.js +63 -0
  68. package/dist/lib/result.d.ts +5 -7
  69. package/dist/lib/result.d.ts.map +1 -1
  70. package/dist/lib/result.js +19 -26
  71. package/dist/lib/runtimeHint.d.ts +35 -0
  72. package/dist/lib/runtimeHint.d.ts.map +1 -0
  73. package/dist/lib/runtimeHint.js +79 -0
  74. package/dist/lib/schema/types.d.ts +1 -1
  75. package/dist/lib/schema/types.d.ts.map +1 -1
  76. package/dist/lib/span-buffer/aot/v1.d.ts +2 -0
  77. package/dist/lib/span-buffer/aot/v1.d.ts.map +1 -0
  78. package/dist/lib/span-buffer/aot/v1.js +24 -0
  79. package/dist/lib/spanBuffer.d.ts +33 -4
  80. package/dist/lib/spanBuffer.d.ts.map +1 -1
  81. package/dist/lib/spanBuffer.js +583 -91
  82. package/dist/lib/spanBufferStats.d.ts +1 -1
  83. package/dist/lib/spanBufferStats.d.ts.map +1 -1
  84. package/dist/lib/spanContext.d.ts +27 -51
  85. package/dist/lib/spanContext.d.ts.map +1 -1
  86. package/dist/lib/spanContext.js +822 -344
  87. package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
  88. package/dist/lib/sqlite/sqlite-common.js +20 -21
  89. package/dist/lib/testing/bun-harness.d.ts +8 -3
  90. package/dist/lib/testing/bun-harness.d.ts.map +1 -1
  91. package/dist/lib/testing/bun-harness.js +30 -18
  92. package/dist/lib/testing/extractFacts.d.ts +1 -1
  93. package/dist/lib/testing/extractFacts.d.ts.map +1 -1
  94. package/dist/lib/testing/extractFacts.js +55 -63
  95. package/dist/lib/testing/facts.d.ts +1 -1
  96. package/dist/lib/testing/facts.d.ts.map +1 -1
  97. package/dist/lib/testing/queryable-span.d.ts +1 -1
  98. package/dist/lib/testing/queryable-span.d.ts.map +1 -1
  99. package/dist/lib/testing/queryable-span.js +26 -28
  100. package/dist/lib/testing/span-query.d.ts.map +1 -1
  101. package/dist/lib/testing/span-query.js +19 -22
  102. package/dist/lib/testing/stdio-replay.d.ts.map +1 -1
  103. package/dist/lib/testing/stdio-replay.js +19 -8
  104. package/dist/lib/threadId.d.ts.map +1 -1
  105. package/dist/lib/threadId.js +6 -3
  106. package/dist/lib/traceRoot.d.ts +30 -8
  107. package/dist/lib/traceRoot.d.ts.map +1 -1
  108. package/dist/lib/traceRoot.es.d.ts +17 -15
  109. package/dist/lib/traceRoot.es.d.ts.map +1 -1
  110. package/dist/lib/traceRoot.es.js +68 -34
  111. package/dist/lib/traceRoot.js +11 -0
  112. package/dist/lib/traceRoot.node.d.ts +17 -19
  113. package/dist/lib/traceRoot.node.d.ts.map +1 -1
  114. package/dist/lib/traceRoot.node.js +66 -38
  115. package/dist/lib/traceTopology.d.ts +42 -0
  116. package/dist/lib/traceTopology.d.ts.map +1 -0
  117. package/dist/lib/traceTopology.js +260 -0
  118. package/dist/lib/tracer.d.ts +9 -5
  119. package/dist/lib/tracer.d.ts.map +1 -1
  120. package/dist/lib/tracer.js +65 -71
  121. package/dist/lib/tracers/ArrayQueueTracer.d.ts +1 -1
  122. package/dist/lib/tracers/ArrayQueueTracer.js +1 -1
  123. package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
  124. package/dist/lib/tracers/StdioTracer.js +15 -13
  125. package/dist/lib/tracers/TestTracer.d.ts +4 -6
  126. package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
  127. package/dist/lib/tracers/TestTracer.js +6 -8
  128. package/dist/lib/types.d.ts +49 -32
  129. package/dist/lib/types.d.ts.map +1 -1
  130. package/dist/lib/vocabularyRegistry.d.ts +25 -0
  131. package/dist/lib/vocabularyRegistry.d.ts.map +1 -0
  132. package/dist/lib/vocabularyRegistry.js +372 -0
  133. package/dist/lib/wasm/WasmBufferStrategy.d.ts +6 -10
  134. package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
  135. package/dist/lib/wasm/WasmBufferStrategy.js +44 -37
  136. package/dist/lib/wasm/wasmAllocator.d.ts +27 -22
  137. package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
  138. package/dist/lib/wasm/wasmAllocator.js +66 -44
  139. package/dist/lib/wasm/wasmPhysicalLayout.d.ts +67 -0
  140. package/dist/lib/wasm/wasmPhysicalLayout.d.ts.map +1 -0
  141. package/dist/lib/wasm/wasmPhysicalLayout.js +179 -0
  142. package/dist/lib/wasm/wasmSpanBuffer.d.ts +79 -31
  143. package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
  144. package/dist/lib/wasm/wasmSpanBuffer.js +442 -272
  145. package/dist/lib/wasm/wasmTraceRoot.d.ts +24 -22
  146. package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
  147. package/dist/lib/wasm/wasmTraceRoot.js +110 -71
  148. package/dist/vocabulary/register/v1.d.ts +2 -0
  149. package/dist/vocabulary/register/v1.d.ts.map +1 -0
  150. package/dist/vocabulary/register/v1.js +1 -0
  151. package/dist/wasm.d.ts +5 -0
  152. package/dist/wasm.d.ts.map +1 -0
  153. package/dist/wasm.js +4 -0
  154. package/package.json +54 -6
  155. package/src/index.ts +1 -0
  156. package/src/lib/JsBufferStrategy.ts +27 -9
  157. package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +335 -37
  158. package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +97 -26
  159. package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +75 -15
  160. package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +30 -6
  161. package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +18 -21
  162. package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +5 -2
  163. package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +25 -7
  164. package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +3 -2
  165. package/src/lib/__tests__/buffer-overflow.test.ts +24 -18
  166. package/src/lib/__tests__/capability-span-context.test.ts +505 -0
  167. package/src/lib/__tests__/capacity-tuning.test.ts +5 -3
  168. package/src/lib/__tests__/eager-columns.test.ts +345 -0
  169. package/src/lib/__tests__/enum-metadata-aot.test.ts +153 -0
  170. package/src/lib/__tests__/enum-metadata.test.ts +177 -0
  171. package/src/lib/__tests__/fixtures/empty-vocabulary-runtime.fixture.ts +15 -0
  172. package/src/lib/__tests__/flushScheduler.test.ts +5 -1
  173. package/src/lib/__tests__/identity-view.property.test.ts +179 -0
  174. package/src/lib/__tests__/library.test.ts +19 -235
  175. package/src/lib/__tests__/message-buffer-families.test.ts +878 -0
  176. package/src/lib/__tests__/nested-library-tasks.test.ts +14 -15
  177. package/src/lib/__tests__/op-metadata.test.ts +1 -1
  178. package/src/lib/__tests__/op-type-safety.test.ts +5 -16
  179. package/src/lib/__tests__/physical-layout-plan.test.ts +333 -0
  180. package/src/lib/__tests__/remap-descriptor-integration.test.ts +381 -0
  181. package/src/lib/__tests__/root-context-construction.test.ts +414 -0
  182. package/src/lib/__tests__/span-auto-runtime.test.ts +386 -0
  183. package/src/lib/__tests__/span-buffer-segment-stats.test.ts +221 -0
  184. package/src/lib/__tests__/span-lifecycle.test.ts +53 -25
  185. package/src/lib/__tests__/spanbuffer-materializer-parity.test.ts +266 -0
  186. package/src/lib/__tests__/sync-async-trace.test.ts +24 -23
  187. package/src/lib/__tests__/tag-writer-aot.test.ts +214 -0
  188. package/src/lib/__tests__/test-helpers.ts +67 -12
  189. package/src/lib/__tests__/threadId.test.ts +62 -0
  190. package/src/lib/__tests__/timestamp.test.ts +221 -93
  191. package/src/lib/__tests__/traceTopology.property.test.ts +383 -0
  192. package/src/lib/__tests__/type-narrowing.test.ts +63 -0
  193. package/src/lib/__tests__/vocabulary-dense-decoding.test.ts +405 -0
  194. package/src/lib/__tests__/vocabularyRegistry.test.ts +313 -0
  195. package/src/lib/arrow/lease.ts +43 -0
  196. package/src/lib/arrow/utils.ts +10 -14
  197. package/src/lib/arrow/vocabularyDictionary.ts +123 -0
  198. package/src/lib/bufferStrategy.ts +9 -1
  199. package/src/lib/cloudflare/traceRows.ts +3 -2
  200. package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +21 -141
  201. package/src/lib/codegen/__tests__/fixedPositionWriter-parity.test.ts +273 -0
  202. package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +61 -34
  203. package/src/lib/codegen/__tests__/nullBitmap.test.ts +33 -37
  204. package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +34 -18
  205. package/src/lib/codegen/__tests__/spanLoggerMaterializerParity.test.ts +503 -0
  206. package/src/lib/codegen/evaluatorGenerator.ts +18 -13
  207. package/src/lib/codegen/fixedPositionWriterGenerator.ts +329 -245
  208. package/src/lib/codegen/spanLoggerClosureMaterializer.ts +598 -0
  209. package/src/lib/codegen/spanLoggerGenerator.ts +241 -177
  210. package/src/lib/convertToArrow.ts +598 -311
  211. package/src/lib/defineOpContext.ts +1 -1
  212. package/src/lib/enumMetadata.ts +121 -0
  213. package/src/lib/flushScheduler.ts +11 -5
  214. package/src/lib/library.ts +37 -595
  215. package/src/lib/logBinding.ts +21 -27
  216. package/src/lib/op.ts +75 -18
  217. package/src/lib/opContext/__tests__/retry.test.ts +27 -21
  218. package/src/lib/opContext/createOpGroup.ts +33 -31
  219. package/src/lib/opContext/defineOp.ts +88 -11
  220. package/src/lib/opContext/opGroupTypes.ts +2 -2
  221. package/src/lib/opContext/opTypes.ts +1 -1
  222. package/src/lib/opContext/spanContextTypes.ts +98 -17
  223. package/src/lib/opContext/types.ts +7 -3
  224. package/src/lib/physicalLayoutPlan.ts +598 -0
  225. package/src/lib/resolveMessage.ts +67 -0
  226. package/src/lib/result.ts +20 -33
  227. package/src/lib/runtimeHint.ts +98 -0
  228. package/src/lib/schema/__tests__/featureFlags.test.ts +2 -1
  229. package/src/lib/schema/builder.ts +1 -1
  230. package/src/lib/schema/types.ts +1 -1
  231. package/src/lib/span-buffer/aot/v1.ts +26 -0
  232. package/src/lib/spanBuffer.ts +658 -92
  233. package/src/lib/spanBufferStats.ts +1 -1
  234. package/src/lib/spanContext.ts +1350 -861
  235. package/src/lib/sqlite/sqlite-common.ts +20 -31
  236. package/src/lib/testing/__tests__/topology-traversal.test.ts +174 -0
  237. package/src/lib/testing/__tests__/vitest-harness.test.ts +2 -1
  238. package/src/lib/testing/bun-harness.ts +94 -43
  239. package/src/lib/testing/extractFacts.ts +64 -78
  240. package/src/lib/testing/facts.ts +1 -1
  241. package/src/lib/testing/queryable-span.ts +23 -30
  242. package/src/lib/testing/span-query.ts +16 -20
  243. package/src/lib/testing/stdio-replay.ts +25 -8
  244. package/src/lib/testing/vitest-harness.ts +1 -1
  245. package/src/lib/threadId.ts +6 -3
  246. package/src/lib/traceRoot.es.ts +77 -42
  247. package/src/lib/traceRoot.node.ts +75 -46
  248. package/src/lib/traceRoot.ts +41 -14
  249. package/src/lib/traceTopology.ts +279 -0
  250. package/src/lib/tracer.ts +109 -98
  251. package/src/lib/tracers/ArrayQueueTracer.ts +1 -1
  252. package/src/lib/tracers/StdioTracer.ts +15 -13
  253. package/src/lib/tracers/TestTracer.ts +6 -8
  254. package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +15 -10
  255. package/src/lib/tracers/__tests__/TestTracer.test.ts +23 -13
  256. package/src/lib/types.ts +64 -33
  257. package/src/lib/vocabularyRegistry.ts +439 -0
  258. package/src/lib/wasm/WasmBufferStrategy.ts +56 -48
  259. package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +215 -11
  260. package/src/lib/wasm/__tests__/allocatorFreeBlockClamp.test.ts +86 -0
  261. package/src/lib/wasm/__tests__/wasm-identity-view.test.ts +311 -0
  262. package/src/lib/wasm/__tests__/wasm-integration.test.ts +417 -44
  263. package/src/lib/wasm/__tests__/wasm-message-buffer-families.test.ts +588 -0
  264. package/src/lib/wasm/__tests__/wasmAllocator.test.ts +100 -668
  265. package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +419 -63
  266. package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +24 -29
  267. package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +2 -2
  268. package/src/lib/wasm/wasmAllocator.ts +131 -96
  269. package/src/lib/wasm/wasmPhysicalLayout.ts +309 -0
  270. package/src/lib/wasm/wasmSpanBuffer.ts +597 -341
  271. package/src/lib/wasm/wasmTraceRoot.ts +140 -78
  272. package/src/vocabulary/register/v1.ts +1 -0
  273. package/src/wasm.ts +19 -0
  274. package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +0 -319
  275. package/src/lib/__tests__/remapped-buffer-view.test.ts +0 -635
  276. package/src/lib/wasm/allocator.zig +0 -948
@@ -10,12 +10,25 @@
10
10
  */
11
11
 
12
12
  import { Nanoseconds } from '@smoothbricks/arrow-builder';
13
+ import type { LogSchema } from '../schema/LogSchema.js';
13
14
  import { ENTRY_TYPE_SPAN_EXCEPTION, ENTRY_TYPE_SPAN_START } from '../schema/systemSchema.js';
14
15
  import { createTraceId, type TraceId } from '../traceId.js';
15
- import type { ITraceRoot, TracerLifecycleHooks } from '../traceRoot.js';
16
+ import {
17
+ consumeSpanStartedAtAllocation,
18
+ type ITraceRoot,
19
+ type SpanEndPrimitive,
20
+ type SpanStartPrimitive,
21
+ type TimestampAppendPrimitive,
22
+ type TimestampNowPrimitive,
23
+ type TraceRootFactory,
24
+ type TracerLifecycleHooks,
25
+ } from '../traceRoot.js';
26
+ import { TraceTopology } from '../traceTopology.js';
16
27
  import type { AnySpanBuffer } from '../types.js';
17
28
  import type { WasmAllocator } from './wasmAllocator.js';
18
29
 
30
+ const traceIdEncoder = new TextEncoder();
31
+
19
32
  // Spec link (88): realizes specs/lmao/01q_wasm_memory_architecture.md#smoo/lmao!n/wasm-mem (span lifecycle writer).
20
33
  //#region smoo/lmao!n/wasm-mem.trace-root
21
34
 
@@ -30,12 +43,17 @@ import type { WasmAllocator } from './wasmAllocator.js';
30
43
  export interface WasmSpanBufferLike {
31
44
  /** Byte offset into WASM memory for system columns (timestamp + entry_type) */
32
45
  readonly _systemPtr: number;
46
+ /** Concrete per-op capacity; may differ from the allocator default. */
47
+ readonly _capacity: number;
33
48
  /** Byte offset into WASM memory for identity block (writeIndex, span_id, trace_id) */
34
49
  readonly _identityPtr: number;
35
50
  /** Message column - string array for span names and log messages */
36
51
  readonly _message: string[];
37
52
  /** Current write position (getter/setter reads from WASM identity block) */
38
53
  _writeIndex: number;
54
+ readonly _identityOwner: boolean;
55
+ readonly timestamp: BigInt64Array;
56
+ readonly entry_type: Uint8Array;
39
57
  }
40
58
 
41
59
  /**
@@ -62,18 +80,96 @@ export function isWasmSpanBuffer(buffer: unknown): buffer is WasmSpanBufferLike
62
80
  * The WASM allocator's initTraceRoot() captures these values at trace start,
63
81
  * and span lifecycle methods use them to calculate timestamps.
64
82
  */
65
- export class WasmTraceRoot implements ITraceRoot {
83
+ const timestampNow: TimestampNowPrimitive = (traceRoot) => {
84
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WASM primitive table is only installed on WasmTraceRoot instances.
85
+ const root = traceRoot as WasmTraceRoot;
86
+ root._assertLive();
87
+ const elapsedNanos = BigInt(Math.round((performance.now() - root.anchorPerfNow) * 1_000_000));
88
+ return Nanoseconds.unsafe(root.anchorEpochNanos + elapsedNanos);
89
+ };
90
+
91
+ const appendLogEntry: TimestampAppendPrimitive = (traceRoot, buffer, entryType) => {
92
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WASM primitive table is only installed on WasmTraceRoot instances.
93
+ const root = traceRoot as WasmTraceRoot;
94
+ root._assertLive();
95
+ if (isWasmSpanBuffer(buffer) && buffer._messagePhysicalLayout !== 'packed' && buffer._identityOwner) {
96
+ return root.allocator.writeLogEntry(
97
+ buffer._systemPtr,
98
+ buffer._identityPtr,
99
+ root._traceRootPtr,
100
+ entryType,
101
+ buffer._capacity,
102
+ );
103
+ }
104
+ const idx = buffer._writeIndex;
105
+ const entryTypes = buffer.entry_type;
106
+ if (entryTypes === undefined) throw new TypeError('Split WASM appender requires entry_type storage');
107
+ buffer.timestamp[idx] = timestampNow(root);
108
+ entryTypes[idx] = entryType;
109
+ buffer._writeIndex = idx + 1;
110
+ return idx;
111
+ };
112
+
113
+ const writeSpanStartPrimitive: SpanStartPrimitive = (traceRoot, buffer, spanName) => {
114
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WASM primitive table is only installed on WasmTraceRoot instances.
115
+ const root = traceRoot as WasmTraceRoot;
116
+ root._assertLive();
117
+ if (isWasmSpanBuffer(buffer) && buffer._messagePhysicalLayout !== 'packed') {
118
+ if (!consumeSpanStartedAtAllocation(buffer)) {
119
+ root.allocator.spanStart(buffer._systemPtr, buffer._identityPtr, root._traceRootPtr, buffer._capacity);
120
+ }
121
+ buffer._message[0] = spanName;
122
+ return;
123
+ }
124
+ const entryTypes = buffer.entry_type;
125
+ if (entryTypes === undefined) throw new TypeError('Split WASM span-start appender requires entry_type storage');
126
+ buffer.timestamp[0] = timestampNow(root);
127
+ entryTypes[0] = ENTRY_TYPE_SPAN_START;
128
+ buffer.message(0, spanName);
129
+ entryTypes[1] = ENTRY_TYPE_SPAN_EXCEPTION;
130
+ buffer.timestamp[1] = 0n;
131
+ buffer._writeIndex = 2;
132
+ };
133
+
134
+ const writeSpanEndPrimitive: SpanEndPrimitive = (traceRoot, buffer, entryType) => {
135
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WASM primitive table is only installed on WasmTraceRoot instances.
136
+ const root = traceRoot as WasmTraceRoot;
137
+ root._assertLive();
138
+ if (isWasmSpanBuffer(buffer) && buffer._messagePhysicalLayout !== 'packed') {
139
+ if (entryType === 2) root.allocator.spanEndOk(buffer._systemPtr, root._traceRootPtr, buffer._capacity);
140
+ else root.allocator.spanEndErr(buffer._systemPtr, root._traceRootPtr, buffer._capacity);
141
+ if (entryType !== 2 && entryType !== 3) {
142
+ const splitEntryTypes = buffer.entry_type;
143
+ if (splitEntryTypes === undefined) throw new TypeError('Split WASM buffer is missing entry_type storage');
144
+ splitEntryTypes[1] = entryType;
145
+ }
146
+ return;
147
+ }
148
+ const entryTypes = buffer.entry_type;
149
+ if (entryTypes === undefined) throw new TypeError('Split WASM span-end appender requires entry_type storage');
150
+ buffer.timestamp[1] = timestampNow(root);
151
+ entryTypes[1] = entryType;
152
+ };
153
+
154
+ export class WasmTraceRoot<T extends LogSchema = LogSchema> implements ITraceRoot<T> {
66
155
  /** Byte offset in WASM memory where TraceRoot data lives */
67
156
  readonly _traceRootPtr: number;
157
+ private _state: 'live' | 'freed' = 'live';
68
158
 
69
159
  /** The WASM allocator instance */
70
160
  readonly allocator: WasmAllocator;
71
161
 
72
162
  /** Trace ID string */
73
163
  readonly trace_id: TraceId;
164
+ readonly _traceIdBytes: Uint8Array;
74
165
 
75
166
  /** Tracer reference for lifecycle hooks */
76
- readonly tracer: TracerLifecycleHooks;
167
+ readonly tracer: TracerLifecycleHooks<T>;
168
+ readonly _topology: TraceTopology;
169
+ readonly _timestampNow = timestampNow;
170
+ readonly _appendLogEntry = appendLogEntry;
171
+ readonly _writeSpanStart = writeSpanStartPrimitive;
172
+ readonly _writeSpanEnd = writeSpanEndPrimitive;
77
173
 
78
174
  /**
79
175
  * Raw backing buffer - not used for WASM, but required by ITraceRoot.
@@ -81,28 +177,32 @@ export class WasmTraceRoot implements ITraceRoot {
81
177
  */
82
178
  readonly _system: ArrayBuffer;
83
179
 
84
- constructor(allocator: WasmAllocator, trace_id: TraceId, tracer: TracerLifecycleHooks) {
180
+ constructor(allocator: WasmAllocator, trace_id: TraceId, tracer: TracerLifecycleHooks<T>) {
85
181
  this.allocator = allocator;
86
182
  this.trace_id = trace_id;
183
+ this._traceIdBytes = traceIdEncoder.encode(trace_id);
87
184
  this.tracer = tracer;
185
+ this._topology = new TraceTopology();
88
186
 
89
- // Create minimal _system buffer (not actually used, but required by interface)
90
187
  this._system = new ArrayBuffer(16);
91
-
92
- // Allocate an 8B column block for TraceRoot data (16 bytes needed, 8B block is large enough)
93
- // The 8B column block size is: ceil(capacity/8) + capacity*8 = 8 + 512 = 520 bytes for capacity 64
94
- // We only need 16 bytes, so this works fine
95
- this._traceRootPtr = allocator.alloc8B();
96
-
97
- // Initialize wall clock and monotonic start times in WASM memory
188
+ // Native TraceRoot is exactly two aligned 8-byte fields.
189
+ const traceRootPtr = allocator.allocExact(16, 8);
190
+ if (traceRootPtr === 0) {
191
+ throw new Error('WASM trace-root allocation failed');
192
+ }
193
+ this._traceRootPtr = traceRootPtr;
98
194
  allocator.initTraceRoot(this._traceRootPtr);
99
195
  }
196
+ _assertLive(): void {
197
+ if (this._state !== 'live') throw new Error('WASM trace root has been released');
198
+ }
100
199
 
101
200
  /**
102
201
  * Epoch time in nanoseconds when trace was created.
103
202
  * Read from WASM memory at _traceRootPtr offset 0.
104
203
  */
105
204
  get anchorEpochNanos(): bigint {
205
+ this._assertLive();
106
206
  // i64 view is indexed by 8-byte chunks
107
207
  return this.allocator.i64[this._traceRootPtr / 8];
108
208
  }
@@ -112,6 +212,7 @@ export class WasmTraceRoot implements ITraceRoot {
112
212
  * Read from WASM memory at _traceRootPtr offset 8.
113
213
  */
114
214
  get anchorPerfNow(): number {
215
+ this._assertLive();
115
216
  // f64 view is indexed by 8-byte chunks
116
217
  return this.allocator.f64[(this._traceRootPtr + 8) / 8];
117
218
  }
@@ -126,9 +227,7 @@ export class WasmTraceRoot implements ITraceRoot {
126
227
  * We convert to nanoseconds for consistency with the trace format.
127
228
  */
128
229
  getTimestampNanos(): Nanoseconds {
129
- const elapsedMs = performance.now() - this.anchorPerfNow;
130
- const elapsedNanos = BigInt(Math.round(elapsedMs * 1_000_000));
131
- return Nanoseconds.unsafe(this.anchorEpochNanos + elapsedNanos);
230
+ return this._timestampNow(this);
132
231
  }
133
232
 
134
233
  // ===========================================================================
@@ -147,24 +246,7 @@ export class WasmTraceRoot implements ITraceRoot {
147
246
  * @param spanName - Name for this span
148
247
  */
149
248
  writeSpanStart(buffer: AnySpanBuffer, spanName: string): void {
150
- if (isWasmSpanBuffer(buffer)) {
151
- // WASM path: delegate to WASM allocator
152
- // spanStart writes row 0 (span-start) and row 1 (span-exception placeholder)
153
- // Also sets writeIndex to 2 in the identity block
154
- this.allocator.spanStart(buffer._systemPtr, buffer._identityPtr, this._traceRootPtr);
155
- // Write span name to message column (JS string array)
156
- buffer._message[0] = spanName;
157
- // Note: _writeIndex is set by WASM spanStart to 2, but the getter reads from WASM
158
- // so we don't need to set it here explicitly (the setter would write to WASM anyway)
159
- } else {
160
- // JS path: write directly to TypedArrays (fallback for mixed usage)
161
- buffer.timestamp[0] = this.getTimestampNanos();
162
- buffer.entry_type[0] = ENTRY_TYPE_SPAN_START;
163
- buffer.message(0, spanName);
164
- buffer.entry_type[1] = ENTRY_TYPE_SPAN_EXCEPTION;
165
- buffer.timestamp[1] = 0n;
166
- buffer._writeIndex = 2;
167
- }
249
+ this._writeSpanStart(this, buffer, spanName);
168
250
  }
169
251
 
170
252
  /**
@@ -175,29 +257,7 @@ export class WasmTraceRoot implements ITraceRoot {
175
257
  * @param entryType - Entry type (SPAN_OK, SPAN_ERR, or SPAN_EXCEPTION)
176
258
  */
177
259
  writeSpanEnd(buffer: AnySpanBuffer, entryType: number): void {
178
- if (isWasmSpanBuffer(buffer)) {
179
- // WASM path: use appropriate end function based on entry type
180
- // Note: WASM spanEndOk/spanEndErr write to row 1
181
- if (entryType === 2) {
182
- // SPAN_OK
183
- this.allocator.spanEndOk(buffer._systemPtr, this._traceRootPtr);
184
- } else if (entryType === 3) {
185
- // SPAN_ERR
186
- this.allocator.spanEndErr(buffer._systemPtr, this._traceRootPtr);
187
- } else {
188
- // SPAN_EXCEPTION or other - write via generic log entry
189
- // For now, use spanEndErr as fallback (entry_type will be overwritten)
190
- this.allocator.spanEndErr(buffer._systemPtr, this._traceRootPtr);
191
- // Overwrite entry_type if needed (for EXCEPTION)
192
- if (entryType !== 3) {
193
- buffer.entry_type[1] = entryType;
194
- }
195
- }
196
- } else {
197
- // JS path
198
- buffer.timestamp[1] = this.getTimestampNanos();
199
- buffer.entry_type[1] = entryType;
200
- }
260
+ this._writeSpanEnd(this, buffer, entryType);
201
261
  }
202
262
 
203
263
  /**
@@ -209,16 +269,7 @@ export class WasmTraceRoot implements ITraceRoot {
209
269
  * @returns The row index where entry was written
210
270
  */
211
271
  writeLogEntry(buffer: AnySpanBuffer, entryType: number): number {
212
- if (isWasmSpanBuffer(buffer)) {
213
- // WASM path: bump writeIndex, write timestamp + entry_type, return idx
214
- return this.allocator.writeLogEntry(buffer._systemPtr, buffer._identityPtr, this._traceRootPtr, entryType);
215
- }
216
- // JS path: bump writeIndex, write directly, return idx
217
- const idx = buffer._writeIndex;
218
- buffer.timestamp[idx] = this.getTimestampNanos();
219
- buffer.entry_type[idx] = entryType;
220
- buffer._writeIndex = idx + 1;
221
- return idx;
272
+ return this._appendLogEntry(this, buffer, entryType);
222
273
  }
223
274
 
224
275
  // ===========================================================================
@@ -235,6 +286,7 @@ export class WasmTraceRoot implements ITraceRoot {
235
286
  * @param identityPtr - Byte offset of buffer's identity block in WASM memory
236
287
  */
237
288
  writeSpanStartPtr(systemPtr: number, identityPtr: number): void {
289
+ this._assertLive();
238
290
  this.allocator.spanStart(systemPtr, identityPtr, this._traceRootPtr);
239
291
  }
240
292
 
@@ -243,6 +295,7 @@ export class WasmTraceRoot implements ITraceRoot {
243
295
  * @param systemPtr - Byte offset of buffer's system block in WASM memory
244
296
  */
245
297
  writeSpanEndOkPtr(systemPtr: number): void {
298
+ this._assertLive();
246
299
  this.allocator.spanEndOk(systemPtr, this._traceRootPtr);
247
300
  }
248
301
 
@@ -251,6 +304,7 @@ export class WasmTraceRoot implements ITraceRoot {
251
304
  * @param systemPtr - Byte offset of buffer's system block in WASM memory
252
305
  */
253
306
  writeSpanEndErrPtr(systemPtr: number): void {
307
+ this._assertLive();
254
308
  this.allocator.spanEndErr(systemPtr, this._traceRootPtr);
255
309
  }
256
310
 
@@ -264,6 +318,7 @@ export class WasmTraceRoot implements ITraceRoot {
264
318
  * @returns Row index where entry was written
265
319
  */
266
320
  writeLogEntryPtr(systemPtr: number, identityPtr: number, entryType: number): number {
321
+ this._assertLive();
267
322
  return this.allocator.writeLogEntry(systemPtr, identityPtr, this._traceRootPtr, entryType);
268
323
  }
269
324
 
@@ -272,14 +327,20 @@ export class WasmTraceRoot implements ITraceRoot {
272
327
  * @param identityPtr - Byte offset of buffer's identity block in WASM memory
273
328
  */
274
329
  readWriteIndex(identityPtr: number): number {
330
+ this._assertLive();
275
331
  return this.allocator.readWriteIndex(identityPtr);
276
332
  }
277
333
 
278
- /**
279
- * Free the TraceRoot's memory block when trace completes.
280
- */
334
+ /** Mark the handle stale when its allocator is reset wholesale. */
335
+ invalidate(): void {
336
+ this._state = 'freed';
337
+ }
338
+
339
+ /** Free the TraceRoot allocation exactly once. */
281
340
  free(): void {
282
- this.allocator.free8B(this._traceRootPtr);
341
+ if (this._state === 'freed') return;
342
+ this.allocator.freeExact(this._traceRootPtr, 16, 8);
343
+ this._state = 'freed';
283
344
  }
284
345
  }
285
346
 
@@ -295,12 +356,12 @@ export class WasmTraceRoot implements ITraceRoot {
295
356
  * @param trace_id - Trace ID for this trace
296
357
  * @param tracer - Tracer lifecycle hooks
297
358
  */
298
- export function createWasmTraceRoot(
359
+ export function createWasmTraceRoot<T extends LogSchema = LogSchema>(
299
360
  allocator: WasmAllocator,
300
361
  trace_id: string,
301
- tracer: TracerLifecycleHooks,
302
- ): WasmTraceRoot {
303
- return new WasmTraceRoot(allocator, createTraceId(trace_id), tracer);
362
+ tracer: TracerLifecycleHooks<T>,
363
+ ): WasmTraceRoot<T> {
364
+ return new WasmTraceRoot<T>(allocator, createTraceId(trace_id), tracer);
304
365
  }
305
366
 
306
367
  /**
@@ -311,9 +372,10 @@ export function createWasmTraceRoot(
311
372
  * @param allocator - WASM allocator instance
312
373
  * @returns Factory function compatible with TraceRootFactory type
313
374
  */
314
- export function createWasmTraceRootFactory(allocator: WasmAllocator) {
315
- return (trace_id: string, tracer: TracerLifecycleHooks): WasmTraceRoot => {
316
- return new WasmTraceRoot(allocator, createTraceId(trace_id), tracer);
317
- };
375
+ export function createWasmTraceRootFactory<T extends LogSchema = LogSchema>(
376
+ allocator: WasmAllocator,
377
+ ): TraceRootFactory<T> {
378
+ return (trace_id: string, tracer: TracerLifecycleHooks<T>): WasmTraceRoot<T> =>
379
+ new WasmTraceRoot<T>(allocator, createTraceId(trace_id), tracer);
318
380
  }
319
381
  //#endregion smoo/lmao!n/wasm-mem.trace-root
@@ -0,0 +1 @@
1
+ import '../../lib/vocabularyRegistry.js';
package/src/wasm.ts ADDED
@@ -0,0 +1,19 @@
1
+ export { WasmBufferStrategy, type WasmBufferStrategyOptions } from './lib/wasm/WasmBufferStrategy.js';
2
+ export {
3
+ createWasmAllocator,
4
+ createWasmAllocatorSync,
5
+ WASM_NO_LAYOUT_OFFSET,
6
+ WASM_SPAN_IDENTITY_CHILD,
7
+ WASM_SPAN_IDENTITY_ROOT,
8
+ type WasmAllocator,
9
+ type WasmAllocatorOptions,
10
+ } from './lib/wasm/wasmAllocator.js';
11
+ export {
12
+ isWasmSpanBufferInstance,
13
+ type WasmSpanBufferInstance,
14
+ } from './lib/wasm/wasmSpanBuffer.js';
15
+ export {
16
+ createWasmTraceRoot,
17
+ createWasmTraceRootFactory,
18
+ WasmTraceRoot,
19
+ } from './lib/wasm/wasmTraceRoot.js';