@smoothbricks/lmao 0.2.2 → 0.3.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 (285) hide show
  1. package/README.md +206 -206
  2. package/dist/allocator.wasm +0 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -0
  6. package/dist/lib/JsBufferStrategy.d.ts +4 -3
  7. package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
  8. package/dist/lib/JsBufferStrategy.js +18 -11
  9. package/dist/lib/arrow/lease.d.ts +10 -0
  10. package/dist/lib/arrow/lease.d.ts.map +1 -0
  11. package/dist/lib/arrow/lease.js +33 -0
  12. package/dist/lib/arrow/utils.d.ts +3 -4
  13. package/dist/lib/arrow/utils.d.ts.map +1 -1
  14. package/dist/lib/arrow/utils.js +12 -13
  15. package/dist/lib/arrow/vocabularyDictionary.d.ts +21 -0
  16. package/dist/lib/arrow/vocabularyDictionary.d.ts.map +1 -0
  17. package/dist/lib/arrow/vocabularyDictionary.js +95 -0
  18. package/dist/lib/bufferStrategy.d.ts +3 -2
  19. package/dist/lib/bufferStrategy.d.ts.map +1 -1
  20. package/dist/lib/cloudflare/traceRows.d.ts.map +1 -1
  21. package/dist/lib/cloudflare/traceRows.js +3 -2
  22. package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
  23. package/dist/lib/codegen/evaluatorGenerator.js +12 -11
  24. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +44 -82
  25. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
  26. package/dist/lib/codegen/fixedPositionWriterGenerator.js +223 -162
  27. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts +63 -0
  28. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts.map +1 -0
  29. package/dist/lib/codegen/spanLoggerClosureMaterializer.js +447 -0
  30. package/dist/lib/codegen/spanLoggerGenerator.d.ts +36 -19
  31. package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
  32. package/dist/lib/codegen/spanLoggerGenerator.js +164 -158
  33. package/dist/lib/convertToArrow.d.ts +7 -2
  34. package/dist/lib/convertToArrow.d.ts.map +1 -1
  35. package/dist/lib/convertToArrow.js +499 -285
  36. package/dist/lib/defineOpContext.js +1 -1
  37. package/dist/lib/enumMetadata.d.ts +19 -0
  38. package/dist/lib/enumMetadata.d.ts.map +1 -0
  39. package/dist/lib/enumMetadata.js +86 -0
  40. package/dist/lib/flushScheduler.d.ts.map +1 -1
  41. package/dist/lib/flushScheduler.js +13 -4
  42. package/dist/lib/library.d.ts +16 -98
  43. package/dist/lib/library.d.ts.map +1 -1
  44. package/dist/lib/library.js +32 -525
  45. package/dist/lib/logBinding.d.ts +21 -27
  46. package/dist/lib/logBinding.d.ts.map +1 -1
  47. package/dist/lib/op.d.ts +30 -30
  48. package/dist/lib/op.d.ts.map +1 -1
  49. package/dist/lib/op.js +15 -22
  50. package/dist/lib/opContext/createOpGroup.d.ts +1 -1
  51. package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
  52. package/dist/lib/opContext/createOpGroup.js +22 -29
  53. package/dist/lib/opContext/defineOp.d.ts +4 -4
  54. package/dist/lib/opContext/defineOp.d.ts.map +1 -1
  55. package/dist/lib/opContext/defineOp.js +53 -10
  56. package/dist/lib/opContext/opGroupTypes.d.ts +2 -2
  57. package/dist/lib/opContext/opTypes.d.ts +1 -1
  58. package/dist/lib/opContext/opTypes.d.ts.map +1 -1
  59. package/dist/lib/opContext/spanContextTypes.d.ts +33 -18
  60. package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -1
  61. package/dist/lib/opContext/types.d.ts +4 -4
  62. package/dist/lib/opContext/types.d.ts.map +1 -1
  63. package/dist/lib/physicalLayoutPlan.d.ts +89 -0
  64. package/dist/lib/physicalLayoutPlan.d.ts.map +1 -0
  65. package/dist/lib/physicalLayoutPlan.js +442 -0
  66. package/dist/lib/resolveMessage.d.ts +9 -0
  67. package/dist/lib/resolveMessage.d.ts.map +1 -0
  68. package/dist/lib/resolveMessage.js +63 -0
  69. package/dist/lib/result.d.ts +5 -7
  70. package/dist/lib/result.d.ts.map +1 -1
  71. package/dist/lib/result.js +19 -26
  72. package/dist/lib/runtimeHint.d.ts +35 -0
  73. package/dist/lib/runtimeHint.d.ts.map +1 -0
  74. package/dist/lib/runtimeHint.js +79 -0
  75. package/dist/lib/schema/typeGuards.d.ts +7 -47
  76. package/dist/lib/schema/typeGuards.d.ts.map +1 -1
  77. package/dist/lib/schema/typeGuards.js +7 -123
  78. package/dist/lib/schema/types.d.ts +1 -1
  79. package/dist/lib/schema/types.d.ts.map +1 -1
  80. package/dist/lib/span-buffer/aot/v1.d.ts +2 -0
  81. package/dist/lib/span-buffer/aot/v1.d.ts.map +1 -0
  82. package/dist/lib/span-buffer/aot/v1.js +24 -0
  83. package/dist/lib/spanBuffer.d.ts +33 -4
  84. package/dist/lib/spanBuffer.d.ts.map +1 -1
  85. package/dist/lib/spanBuffer.js +583 -91
  86. package/dist/lib/spanBufferStats.d.ts +1 -1
  87. package/dist/lib/spanBufferStats.d.ts.map +1 -1
  88. package/dist/lib/spanContext.d.ts +27 -51
  89. package/dist/lib/spanContext.d.ts.map +1 -1
  90. package/dist/lib/spanContext.js +822 -344
  91. package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
  92. package/dist/lib/sqlite/sqlite-common.js +20 -21
  93. package/dist/lib/testing/bun-harness.d.ts +8 -3
  94. package/dist/lib/testing/bun-harness.d.ts.map +1 -1
  95. package/dist/lib/testing/bun-harness.js +30 -18
  96. package/dist/lib/testing/extractFacts.d.ts +1 -1
  97. package/dist/lib/testing/extractFacts.d.ts.map +1 -1
  98. package/dist/lib/testing/extractFacts.js +55 -63
  99. package/dist/lib/testing/facts.d.ts +1 -1
  100. package/dist/lib/testing/facts.d.ts.map +1 -1
  101. package/dist/lib/testing/queryable-span.d.ts +1 -1
  102. package/dist/lib/testing/queryable-span.d.ts.map +1 -1
  103. package/dist/lib/testing/queryable-span.js +26 -28
  104. package/dist/lib/testing/span-query.d.ts.map +1 -1
  105. package/dist/lib/testing/span-query.js +19 -22
  106. package/dist/lib/testing/stdio-replay.d.ts.map +1 -1
  107. package/dist/lib/testing/stdio-replay.js +19 -8
  108. package/dist/lib/threadId.d.ts.map +1 -1
  109. package/dist/lib/threadId.js +6 -3
  110. package/dist/lib/traceContext.d.ts.map +1 -1
  111. package/dist/lib/traceContext.js +1 -4
  112. package/dist/lib/traceRoot.d.ts +30 -8
  113. package/dist/lib/traceRoot.d.ts.map +1 -1
  114. package/dist/lib/traceRoot.es.d.ts +17 -15
  115. package/dist/lib/traceRoot.es.d.ts.map +1 -1
  116. package/dist/lib/traceRoot.es.js +68 -34
  117. package/dist/lib/traceRoot.js +11 -0
  118. package/dist/lib/traceRoot.node.d.ts +17 -19
  119. package/dist/lib/traceRoot.node.d.ts.map +1 -1
  120. package/dist/lib/traceRoot.node.js +66 -38
  121. package/dist/lib/traceTopology.d.ts +42 -0
  122. package/dist/lib/traceTopology.d.ts.map +1 -0
  123. package/dist/lib/traceTopology.js +260 -0
  124. package/dist/lib/tracer.d.ts +9 -5
  125. package/dist/lib/tracer.d.ts.map +1 -1
  126. package/dist/lib/tracer.js +65 -71
  127. package/dist/lib/tracers/ArrayQueueTracer.d.ts +1 -1
  128. package/dist/lib/tracers/ArrayQueueTracer.js +1 -1
  129. package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
  130. package/dist/lib/tracers/StdioTracer.js +15 -13
  131. package/dist/lib/tracers/TestTracer.d.ts +4 -6
  132. package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
  133. package/dist/lib/tracers/TestTracer.js +6 -8
  134. package/dist/lib/types.d.ts +49 -32
  135. package/dist/lib/types.d.ts.map +1 -1
  136. package/dist/lib/vocabularyRegistry.d.ts +25 -0
  137. package/dist/lib/vocabularyRegistry.d.ts.map +1 -0
  138. package/dist/lib/vocabularyRegistry.js +372 -0
  139. package/dist/lib/wasm/WasmBufferStrategy.d.ts +6 -10
  140. package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
  141. package/dist/lib/wasm/WasmBufferStrategy.js +44 -37
  142. package/dist/lib/wasm/wasmAllocator.d.ts +27 -22
  143. package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
  144. package/dist/lib/wasm/wasmAllocator.js +66 -44
  145. package/dist/lib/wasm/wasmPhysicalLayout.d.ts +67 -0
  146. package/dist/lib/wasm/wasmPhysicalLayout.d.ts.map +1 -0
  147. package/dist/lib/wasm/wasmPhysicalLayout.js +179 -0
  148. package/dist/lib/wasm/wasmSpanBuffer.d.ts +79 -31
  149. package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
  150. package/dist/lib/wasm/wasmSpanBuffer.js +442 -272
  151. package/dist/lib/wasm/wasmTraceRoot.d.ts +24 -22
  152. package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
  153. package/dist/lib/wasm/wasmTraceRoot.js +110 -71
  154. package/dist/vocabulary/register/v1.d.ts +2 -0
  155. package/dist/vocabulary/register/v1.d.ts.map +1 -0
  156. package/dist/vocabulary/register/v1.js +1 -0
  157. package/dist/wasm.d.ts +5 -0
  158. package/dist/wasm.d.ts.map +1 -0
  159. package/dist/wasm.js +4 -0
  160. package/package.json +54 -6
  161. package/src/index.ts +1 -0
  162. package/src/lib/JsBufferStrategy.ts +27 -9
  163. package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +335 -37
  164. package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +97 -26
  165. package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +75 -15
  166. package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +30 -6
  167. package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +18 -21
  168. package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +5 -2
  169. package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +25 -7
  170. package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +3 -2
  171. package/src/lib/__tests__/buffer-overflow.test.ts +24 -18
  172. package/src/lib/__tests__/capability-span-context.test.ts +505 -0
  173. package/src/lib/__tests__/capacity-tuning.test.ts +5 -3
  174. package/src/lib/__tests__/eager-columns.test.ts +345 -0
  175. package/src/lib/__tests__/enum-metadata-aot.test.ts +153 -0
  176. package/src/lib/__tests__/enum-metadata.test.ts +177 -0
  177. package/src/lib/__tests__/fixtures/empty-vocabulary-runtime.fixture.ts +15 -0
  178. package/src/lib/__tests__/flushScheduler.test.ts +5 -1
  179. package/src/lib/__tests__/identity-view.property.test.ts +179 -0
  180. package/src/lib/__tests__/library.test.ts +19 -235
  181. package/src/lib/__tests__/message-buffer-families.test.ts +878 -0
  182. package/src/lib/__tests__/nested-library-tasks.test.ts +14 -15
  183. package/src/lib/__tests__/op-metadata.test.ts +1 -1
  184. package/src/lib/__tests__/op-type-safety.test.ts +5 -16
  185. package/src/lib/__tests__/physical-layout-plan.test.ts +333 -0
  186. package/src/lib/__tests__/remap-descriptor-integration.test.ts +381 -0
  187. package/src/lib/__tests__/root-context-construction.test.ts +414 -0
  188. package/src/lib/__tests__/span-auto-runtime.test.ts +386 -0
  189. package/src/lib/__tests__/span-buffer-segment-stats.test.ts +221 -0
  190. package/src/lib/__tests__/span-lifecycle.test.ts +53 -25
  191. package/src/lib/__tests__/spanbuffer-materializer-parity.test.ts +266 -0
  192. package/src/lib/__tests__/sync-async-trace.test.ts +24 -23
  193. package/src/lib/__tests__/tag-writer-aot.test.ts +214 -0
  194. package/src/lib/__tests__/test-helpers.ts +67 -12
  195. package/src/lib/__tests__/threadId.test.ts +62 -0
  196. package/src/lib/__tests__/timestamp.test.ts +221 -93
  197. package/src/lib/__tests__/traceTopology.property.test.ts +383 -0
  198. package/src/lib/__tests__/type-narrowing.test.ts +63 -0
  199. package/src/lib/__tests__/vocabulary-dense-decoding.test.ts +405 -0
  200. package/src/lib/__tests__/vocabularyRegistry.test.ts +313 -0
  201. package/src/lib/arrow/lease.ts +43 -0
  202. package/src/lib/arrow/utils.ts +10 -14
  203. package/src/lib/arrow/vocabularyDictionary.ts +123 -0
  204. package/src/lib/bufferStrategy.ts +9 -1
  205. package/src/lib/cloudflare/traceRows.ts +3 -2
  206. package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +21 -141
  207. package/src/lib/codegen/__tests__/fixedPositionWriter-parity.test.ts +273 -0
  208. package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +61 -34
  209. package/src/lib/codegen/__tests__/nullBitmap.test.ts +33 -37
  210. package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +34 -18
  211. package/src/lib/codegen/__tests__/spanLoggerMaterializerParity.test.ts +503 -0
  212. package/src/lib/codegen/evaluatorGenerator.ts +18 -13
  213. package/src/lib/codegen/fixedPositionWriterGenerator.ts +329 -245
  214. package/src/lib/codegen/spanLoggerClosureMaterializer.ts +598 -0
  215. package/src/lib/codegen/spanLoggerGenerator.ts +241 -177
  216. package/src/lib/convertToArrow.ts +598 -311
  217. package/src/lib/defineOpContext.ts +1 -1
  218. package/src/lib/enumMetadata.ts +121 -0
  219. package/src/lib/flushScheduler.ts +11 -5
  220. package/src/lib/library.ts +37 -595
  221. package/src/lib/logBinding.ts +21 -27
  222. package/src/lib/op.ts +75 -18
  223. package/src/lib/opContext/__tests__/retry.test.ts +27 -21
  224. package/src/lib/opContext/createOpGroup.ts +33 -31
  225. package/src/lib/opContext/defineOp.ts +88 -11
  226. package/src/lib/opContext/opGroupTypes.ts +2 -2
  227. package/src/lib/opContext/opTypes.ts +1 -1
  228. package/src/lib/opContext/spanContextTypes.ts +122 -24
  229. package/src/lib/opContext/types.ts +7 -3
  230. package/src/lib/physicalLayoutPlan.ts +598 -0
  231. package/src/lib/resolveMessage.ts +67 -0
  232. package/src/lib/result.ts +20 -33
  233. package/src/lib/runtimeHint.ts +98 -0
  234. package/src/lib/schema/__tests__/featureFlags.test.ts +2 -1
  235. package/src/lib/schema/builder.ts +1 -1
  236. package/src/lib/schema/typeGuards.ts +7 -151
  237. package/src/lib/schema/types.ts +1 -1
  238. package/src/lib/span-buffer/aot/v1.ts +26 -0
  239. package/src/lib/spanBuffer.ts +658 -92
  240. package/src/lib/spanBufferStats.ts +1 -1
  241. package/src/lib/spanContext.ts +1350 -861
  242. package/src/lib/sqlite/sqlite-common.ts +20 -31
  243. package/src/lib/testing/__tests__/topology-traversal.test.ts +174 -0
  244. package/src/lib/testing/__tests__/vitest-harness.test.ts +2 -1
  245. package/src/lib/testing/bun-harness.ts +94 -43
  246. package/src/lib/testing/extractFacts.ts +64 -78
  247. package/src/lib/testing/facts.ts +1 -1
  248. package/src/lib/testing/queryable-span.ts +23 -30
  249. package/src/lib/testing/span-query.ts +16 -20
  250. package/src/lib/testing/stdio-replay.ts +25 -8
  251. package/src/lib/testing/vitest-harness.ts +1 -1
  252. package/src/lib/threadId.ts +6 -3
  253. package/src/lib/traceContext.ts +1 -6
  254. package/src/lib/traceRoot.es.ts +77 -42
  255. package/src/lib/traceRoot.node.ts +75 -46
  256. package/src/lib/traceRoot.ts +41 -14
  257. package/src/lib/traceTopology.ts +279 -0
  258. package/src/lib/tracer.ts +109 -98
  259. package/src/lib/tracers/ArrayQueueTracer.ts +1 -1
  260. package/src/lib/tracers/StdioTracer.ts +15 -13
  261. package/src/lib/tracers/TestTracer.ts +6 -8
  262. package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +15 -10
  263. package/src/lib/tracers/__tests__/CompositeTracer.test.ts +150 -0
  264. package/src/lib/tracers/__tests__/TestTracer.test.ts +23 -13
  265. package/src/lib/types.ts +64 -33
  266. package/src/lib/vocabularyRegistry.ts +439 -0
  267. package/src/lib/wasm/WasmBufferStrategy.ts +56 -48
  268. package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +215 -11
  269. package/src/lib/wasm/__tests__/allocatorFreeBlockClamp.test.ts +86 -0
  270. package/src/lib/wasm/__tests__/wasm-identity-view.test.ts +311 -0
  271. package/src/lib/wasm/__tests__/wasm-integration.test.ts +417 -44
  272. package/src/lib/wasm/__tests__/wasm-message-buffer-families.test.ts +588 -0
  273. package/src/lib/wasm/__tests__/wasmAllocator.test.ts +100 -668
  274. package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +419 -63
  275. package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +24 -29
  276. package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +2 -2
  277. package/src/lib/wasm/wasmAllocator.ts +131 -96
  278. package/src/lib/wasm/wasmPhysicalLayout.ts +309 -0
  279. package/src/lib/wasm/wasmSpanBuffer.ts +597 -341
  280. package/src/lib/wasm/wasmTraceRoot.ts +140 -78
  281. package/src/vocabulary/register/v1.ts +1 -0
  282. package/src/wasm.ts +19 -0
  283. package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +0 -319
  284. package/src/lib/__tests__/remapped-buffer-view.test.ts +0 -635
  285. package/src/lib/wasm/allocator.zig +0 -948
@@ -11,40 +11,98 @@
11
11
  */
12
12
 
13
13
  import { Nanoseconds } from '@smoothbricks/arrow-builder';
14
+ import type { LogSchema } from './schema/LogSchema.js';
14
15
  import { ENTRY_TYPE_SPAN_EXCEPTION, ENTRY_TYPE_SPAN_START } from './schema/systemSchema.js';
15
16
  import { createTraceId, type TraceId } from './traceId.js';
16
17
  import {
17
18
  type ITraceRoot,
19
+ type SpanEndPrimitive,
20
+ type SpanStartPrimitive,
21
+ type TimestampAppendPrimitive,
22
+ type TimestampNowPrimitive,
18
23
  TRACE_ROOT_ANCHOR_EPOCH_OFFSET,
19
24
  TRACE_ROOT_ANCHOR_PERF_OFFSET,
20
25
  TRACE_ROOT_TRACE_ID_LEN_OFFSET,
21
26
  TRACE_ROOT_TRACE_ID_OFFSET,
22
27
  type TracerLifecycleHooks,
23
28
  } from './traceRoot.js';
29
+ import { TraceTopology } from './traceTopology.js';
24
30
  import type { AnySpanBuffer } from './types.js';
25
31
 
26
32
  /** Shared TextEncoder for trace_id encoding (stateless, reusable) */
27
33
  const textEncoder = new TextEncoder();
28
34
 
29
- /** Shared TextDecoder for trace_id decoding (stateless, reusable) */
30
- const textDecoder = new TextDecoder();
31
-
32
35
  /**
33
36
  * TraceRoot - Browser implementation with performance.now() timing.
34
37
  *
35
38
  * Stores anchor data in _system ArrayBuffer for consistency with Node.js layout,
36
39
  * but all timestamp calculations are done in pure JS.
37
40
  */
38
- export class TraceRoot implements ITraceRoot {
41
+ function nextTimestamp(root: TraceRoot): Nanoseconds {
42
+ const elapsedNanos = BigInt(Math.floor((performance.now() - root._anchorPerformanceNow) * 1000)) * 1000n;
43
+ let timestamp = root._anchorEpochNanos + elapsedNanos;
44
+ if (timestamp <= root._lastTimestampNanos) timestamp = root._lastTimestampNanos + 1000n;
45
+ root._lastTimestampNanos = timestamp;
46
+ return Nanoseconds.unsafe(timestamp);
47
+ }
48
+
49
+ const timestampNow: TimestampNowPrimitive = (traceRoot) => {
50
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- ES primitive table is only installed on TraceRoot.es instances.
51
+ return nextTimestamp(traceRoot as TraceRoot);
52
+ };
53
+
54
+ const appendLogEntry: TimestampAppendPrimitive = (traceRoot, buffer, entryType) => {
55
+ const entryTypes = buffer.entry_type;
56
+ if (entryTypes === undefined) throw new TypeError('Split timestamp appender requires entry_type storage');
57
+ const idx = buffer._writeIndex;
58
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- ES primitive table is only installed on TraceRoot.es instances.
59
+ buffer.timestamp[idx] = nextTimestamp(traceRoot as TraceRoot);
60
+ entryTypes[idx] = entryType;
61
+ buffer._writeIndex = idx + 1;
62
+ return idx;
63
+ };
64
+
65
+ const writeSpanStartPrimitive: SpanStartPrimitive = (traceRoot, buffer, spanName) => {
66
+ const entryTypes = buffer.entry_type;
67
+ if (entryTypes === undefined) throw new TypeError('Split span-start appender requires entry_type storage');
68
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- ES primitive table is only installed on TraceRoot.es instances.
69
+ buffer.timestamp[0] = nextTimestamp(traceRoot as TraceRoot);
70
+ entryTypes[0] = ENTRY_TYPE_SPAN_START;
71
+ if (buffer.message_values) buffer.message(0, spanName);
72
+ entryTypes[1] = ENTRY_TYPE_SPAN_EXCEPTION;
73
+ buffer.timestamp[1] = 0n;
74
+ buffer._writeIndex = 2;
75
+ };
76
+
77
+ const writeSpanEndPrimitive: SpanEndPrimitive = (traceRoot, buffer, entryType) => {
78
+ const entryTypes = buffer.entry_type;
79
+ if (entryTypes === undefined) throw new TypeError('Split span-end appender requires entry_type storage');
80
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- ES primitive table is only installed on TraceRoot.es instances.
81
+ buffer.timestamp[1] = nextTimestamp(traceRoot as TraceRoot);
82
+ entryTypes[1] = entryType;
83
+ buffer._sealStatsChain();
84
+ };
85
+
86
+ export class TraceRoot<T extends LogSchema = LogSchema> implements ITraceRoot<T> {
39
87
  /**
40
88
  * Raw backing buffer containing anchor timestamps and trace_id.
41
89
  */
42
90
  readonly _system: ArrayBuffer;
91
+ readonly _traceIdBytes: Uint8Array;
92
+ readonly trace_id: TraceId;
43
93
 
44
94
  /**
45
95
  * Tracer reference for lifecycle hooks and event callbacks.
46
96
  */
47
- readonly tracer: TracerLifecycleHooks;
97
+ readonly tracer: TracerLifecycleHooks<T>;
98
+ readonly _topology: TraceTopology;
99
+ readonly _timestampNow = timestampNow;
100
+ readonly _appendLogEntry = appendLogEntry;
101
+ readonly _writeSpanStart = writeSpanStartPrimitive;
102
+ readonly _writeSpanEnd = writeSpanEndPrimitive;
103
+ readonly _anchorEpochNanos: bigint;
104
+ readonly _anchorPerformanceNow: number;
105
+ _lastTimestampNanos = 0n;
48
106
 
49
107
  /**
50
108
  * Cached TypedArray views for fast JS access.
@@ -52,11 +110,16 @@ export class TraceRoot implements ITraceRoot {
52
110
  private readonly _epochView: BigInt64Array;
53
111
  private readonly _perfView: Float64Array;
54
112
 
55
- constructor(trace_id: TraceId, anchorEpochNanos: bigint, anchorPerfNow: number, tracer: TracerLifecycleHooks) {
113
+ constructor(trace_id: TraceId, anchorEpochNanos: bigint, anchorPerfNow: number, tracer: TracerLifecycleHooks<T>) {
56
114
  // Allocate buffer: 17 bytes header + trace_id length
57
115
  // trace_id is validated to be ASCII (1 byte per char) so length === byte length
58
116
  this._system = new ArrayBuffer(TRACE_ROOT_TRACE_ID_OFFSET + trace_id.length);
117
+ this._traceIdBytes = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, trace_id.length);
118
+ this.trace_id = trace_id;
59
119
  this.tracer = tracer;
120
+ this._topology = new TraceTopology();
121
+ this._anchorEpochNanos = anchorEpochNanos;
122
+ this._anchorPerformanceNow = anchorPerfNow;
60
123
 
61
124
  // Create cached views (one-time allocation)
62
125
  this._epochView = new BigInt64Array(this._system, TRACE_ROOT_ANCHOR_EPOCH_OFFSET, 1);
@@ -66,11 +129,9 @@ export class TraceRoot implements ITraceRoot {
66
129
  this._epochView[0] = anchorEpochNanos;
67
130
  this._perfView[0] = anchorPerfNow;
68
131
 
69
- // Encode trace_id directly into buffer (no intermediate allocation)
70
- const u8View = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_LEN_OFFSET);
71
- const traceIdDest = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, trace_id.length);
72
- const { written } = textEncoder.encodeInto(trace_id, traceIdDest);
73
- u8View[0] = written;
132
+ // Encode once into the canonical trace-owned view used by root span identities.
133
+ const { written } = textEncoder.encodeInto(trace_id, this._traceIdBytes);
134
+ new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_LEN_OFFSET, 1)[0] = written;
74
135
  }
75
136
 
76
137
  /**
@@ -87,24 +148,13 @@ export class TraceRoot implements ITraceRoot {
87
148
  return this._perfView[0];
88
149
  }
89
150
 
90
- /**
91
- * Trace ID for this trace.
92
- */
93
- get trace_id(): TraceId {
94
- const len = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_LEN_OFFSET, 1)[0];
95
- return createTraceId(textDecoder.decode(new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, len)));
96
- }
97
-
98
151
  //#region smoo/lmao!n/trace-root-timestamps #es
99
152
  /**
100
153
  * Get current timestamp in nanoseconds since Unix epoch.
101
154
  * Uses performance.now() - microsecond precision (last 3 digits = 000).
102
155
  */
103
156
  getTimestampNanos(): Nanoseconds {
104
- const elapsedMs = performance.now() - this._perfView[0];
105
- // Convert to nanoseconds (last 3 digits = 000 due to microsecond precision)
106
- const elapsedNanos = BigInt(Math.floor(elapsedMs * 1000)) * 1000n;
107
- return Nanoseconds.unsafe(this._epochView[0] + elapsedNanos);
157
+ return this._timestampNow(this);
108
158
  }
109
159
  //#endregion smoo/lmao!n/trace-root-timestamps
110
160
 
@@ -114,17 +164,7 @@ export class TraceRoot implements ITraceRoot {
114
164
  * Pure JS implementation - writes timestamp, entry_type, message, and sets _writeIndex.
115
165
  */
116
166
  writeSpanStart(buffer: AnySpanBuffer, spanName: string): void {
117
- // Row 0: span-start
118
- buffer.timestamp[0] = this.getTimestampNanos();
119
- buffer.entry_type[0] = ENTRY_TYPE_SPAN_START;
120
- buffer.message(0, spanName);
121
-
122
- // Row 1: pre-initialize as span-exception (will be overwritten on ok/err)
123
- buffer.entry_type[1] = ENTRY_TYPE_SPAN_EXCEPTION;
124
- buffer.timestamp[1] = 0n;
125
-
126
- // Events start at row 2
127
- buffer._writeIndex = 2;
167
+ this._writeSpanStart(this, buffer, spanName);
128
168
  }
129
169
 
130
170
  /**
@@ -132,8 +172,7 @@ export class TraceRoot implements ITraceRoot {
132
172
  * Writes both timestamp and entry_type.
133
173
  */
134
174
  writeSpanEnd(buffer: AnySpanBuffer, entryType: number): void {
135
- buffer.timestamp[1] = this.getTimestampNanos();
136
- buffer.entry_type[1] = entryType;
175
+ this._writeSpanEnd(this, buffer, entryType);
137
176
  }
138
177
 
139
178
  /**
@@ -141,11 +180,7 @@ export class TraceRoot implements ITraceRoot {
141
180
  * SpanLogger uses returned idx for string column writes.
142
181
  */
143
182
  writeLogEntry(buffer: AnySpanBuffer, entryType: number): number {
144
- const idx = buffer._writeIndex;
145
- buffer.timestamp[idx] = this.getTimestampNanos();
146
- buffer.entry_type[idx] = entryType;
147
- buffer._writeIndex = idx + 1;
148
- return idx;
183
+ return this._appendLogEntry(this, buffer, entryType);
149
184
  }
150
185
  }
151
186
 
@@ -153,7 +188,7 @@ export class TraceRoot implements ITraceRoot {
153
188
  * Factory function for creating browser TraceRoot instances.
154
189
  * Pass this to Tracer constructor for browser/ES environments.
155
190
  */
156
- export function createTraceRoot(trace_id: string, tracer: TracerLifecycleHooks): TraceRoot {
191
+ export function createTraceRoot<T extends LogSchema>(trace_id: string, tracer: TracerLifecycleHooks<T>): TraceRoot<T> {
157
192
  const anchorEpochNanos = BigInt(Date.now()) * 1_000_000n;
158
193
  const anchorPerfNow = performance.now();
159
194
  return new TraceRoot(createTraceId(trace_id), anchorEpochNanos, anchorPerfNow, tracer);
@@ -10,40 +10,94 @@
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
16
  import {
16
17
  type ITraceRoot,
18
+ type SpanEndPrimitive,
19
+ type SpanStartPrimitive,
20
+ type TimestampAppendPrimitive,
21
+ type TimestampNowPrimitive,
17
22
  TRACE_ROOT_ANCHOR_EPOCH_OFFSET,
18
23
  TRACE_ROOT_ANCHOR_PERF_OFFSET,
19
24
  TRACE_ROOT_TRACE_ID_LEN_OFFSET,
20
25
  TRACE_ROOT_TRACE_ID_OFFSET,
21
26
  type TracerLifecycleHooks,
22
27
  } from './traceRoot.js';
28
+ import { TraceTopology } from './traceTopology.js';
23
29
  import type { AnySpanBuffer } from './types.js';
24
30
 
25
31
  /** Shared TextEncoder for trace_id encoding (stateless, reusable) */
26
32
  const textEncoder = new TextEncoder();
27
33
 
28
- /** Shared TextDecoder for trace_id decoding (stateless, reusable) */
29
- const textDecoder = new TextDecoder();
30
-
31
34
  //#region smoo/lmao!n/trace-root-timestamps #node
32
35
  /**
33
36
  * TraceRoot - Node.js implementation.
34
37
  *
35
38
  * Stores anchor data in _system ArrayBuffer and writes timestamps directly from JS.
36
39
  */
37
- export class TraceRoot implements ITraceRoot {
40
+ function nextTimestamp(root: TraceRoot): Nanoseconds {
41
+ let timestamp = root._epochHrtimeOffset + process.hrtime.bigint();
42
+ if (timestamp <= root._lastTimestampNanos) timestamp = root._lastTimestampNanos + 1n;
43
+ root._lastTimestampNanos = timestamp;
44
+ return Nanoseconds.unsafe(timestamp);
45
+ }
46
+
47
+ const timestampNow: TimestampNowPrimitive = (traceRoot) => {
48
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Node primitive table is only installed on TraceRoot.node instances.
49
+ return nextTimestamp(traceRoot as TraceRoot);
50
+ };
51
+
52
+ const appendLogEntry: TimestampAppendPrimitive = (traceRoot, buffer, entryType) => {
53
+ const entryTypes = buffer.entry_type;
54
+ if (entryTypes === undefined) throw new TypeError('Split timestamp appender requires entry_type storage');
55
+ const idx = buffer._writeIndex;
56
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Node primitive table is only installed on TraceRoot.node instances.
57
+ buffer.timestamp[idx] = nextTimestamp(traceRoot as TraceRoot);
58
+ entryTypes[idx] = entryType;
59
+ buffer._writeIndex = idx + 1;
60
+ return idx;
61
+ };
62
+
63
+ const writeSpanStartPrimitive: SpanStartPrimitive = (traceRoot, buffer, spanName) => {
64
+ const entryTypes = buffer.entry_type;
65
+ if (entryTypes === undefined) throw new TypeError('Split span-start appender requires entry_type storage');
66
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Node primitive table is only installed on TraceRoot.node instances.
67
+ buffer.timestamp[0] = nextTimestamp(traceRoot as TraceRoot);
68
+ entryTypes[0] = ENTRY_TYPE_SPAN_START;
69
+ if (buffer.message_values) buffer.message(0, spanName);
70
+ entryTypes[1] = ENTRY_TYPE_SPAN_EXCEPTION;
71
+ buffer.timestamp[1] = 0n;
72
+ buffer._writeIndex = 2;
73
+ };
74
+
75
+ const writeSpanEndPrimitive: SpanEndPrimitive = (traceRoot, buffer, entryType) => {
76
+ const entryTypes = buffer.entry_type;
77
+ if (entryTypes === undefined) throw new TypeError('Split span-end appender requires entry_type storage');
78
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Node primitive table is only installed on TraceRoot.node instances.
79
+ buffer.timestamp[1] = nextTimestamp(traceRoot as TraceRoot);
80
+ entryTypes[1] = entryType;
81
+ buffer._sealStatsChain();
82
+ };
83
+
84
+ export class TraceRoot<T extends LogSchema = LogSchema> implements ITraceRoot<T> {
38
85
  /**
39
86
  * Raw backing buffer containing anchor timestamps and trace_id.
40
87
  */
41
88
  readonly _system: ArrayBuffer;
89
+ readonly _traceIdBytes: Uint8Array;
90
+ readonly trace_id: TraceId;
42
91
 
43
92
  /**
44
93
  * Tracer reference for lifecycle hooks and event callbacks.
45
94
  */
46
- readonly tracer: TracerLifecycleHooks;
95
+ readonly tracer: TracerLifecycleHooks<T>;
96
+ readonly _topology: TraceTopology;
97
+ readonly _timestampNow = timestampNow;
98
+ readonly _appendLogEntry = appendLogEntry;
99
+ readonly _writeSpanStart = writeSpanStartPrimitive;
100
+ readonly _writeSpanEnd = writeSpanEndPrimitive;
47
101
 
48
102
  /**
49
103
  * Cached TypedArray views for fast JS access.
@@ -51,23 +105,24 @@ export class TraceRoot implements ITraceRoot {
51
105
  private readonly _epochView: BigInt64Array;
52
106
  private readonly _perfView: Float64Array;
53
107
 
54
- /**
55
- * Cached anchor hrtime as the exact BigInt, so the JS timestamp delta stays
56
- * correct after the f64 `anchorPerfNow` loses integer precision (~104 days uptime).
57
- */
58
- private readonly _anchorHrtimeBigInt: bigint;
108
+ /** Epoch offset makes each exact timestamp one clock read plus one BigInt addition. */
109
+ readonly _epochHrtimeOffset: bigint;
110
+ _lastTimestampNanos = 0n;
59
111
 
60
112
  constructor(
61
113
  trace_id: TraceId,
62
114
  anchorEpochNanos: bigint,
63
115
  anchorPerfNow: number,
64
116
  anchorHrtimeBigInt: bigint,
65
- tracer: TracerLifecycleHooks,
117
+ tracer: TracerLifecycleHooks<T>,
66
118
  ) {
67
119
  // Allocate buffer: 17 bytes header + trace_id length
68
120
  // trace_id is validated to be ASCII (1 byte per char) so length === byte length
69
121
  this._system = new ArrayBuffer(TRACE_ROOT_TRACE_ID_OFFSET + trace_id.length);
122
+ this._traceIdBytes = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, trace_id.length);
123
+ this.trace_id = trace_id;
70
124
  this.tracer = tracer;
125
+ this._topology = new TraceTopology();
71
126
 
72
127
  // Create cached views (one-time allocation)
73
128
  this._epochView = new BigInt64Array(this._system, TRACE_ROOT_ANCHOR_EPOCH_OFFSET, 1);
@@ -77,14 +132,11 @@ export class TraceRoot implements ITraceRoot {
77
132
  this._epochView[0] = anchorEpochNanos;
78
133
  this._perfView[0] = anchorPerfNow;
79
134
 
80
- // Keep exact monotonic anchor for JS fallback (avoid Number precision loss after ~104 days uptime)
81
- this._anchorHrtimeBigInt = anchorHrtimeBigInt;
135
+ this._epochHrtimeOffset = anchorEpochNanos - anchorHrtimeBigInt;
82
136
 
83
- // Encode trace_id directly into buffer (no intermediate allocation)
84
- const u8View = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_LEN_OFFSET);
85
- const traceIdDest = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, trace_id.length);
86
- const { written } = textEncoder.encodeInto(trace_id, traceIdDest);
87
- u8View[0] = written;
137
+ // Encode once into the canonical trace-owned view used by root span identities.
138
+ const { written } = textEncoder.encodeInto(trace_id, this._traceIdBytes);
139
+ new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_LEN_OFFSET, 1)[0] = written;
88
140
  }
89
141
 
90
142
  /**
@@ -101,22 +153,12 @@ export class TraceRoot implements ITraceRoot {
101
153
  return this._perfView[0];
102
154
  }
103
155
 
104
- /**
105
- * Trace ID for this trace.
106
- */
107
- get trace_id(): TraceId {
108
- const len = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_LEN_OFFSET, 1)[0];
109
- return createTraceId(textDecoder.decode(new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, len)));
110
- }
111
-
112
156
  /**
113
157
  * Get current timestamp in nanoseconds since Unix epoch.
114
158
  * Uses process.hrtime.bigint() for true nanosecond precision.
115
159
  */
116
160
  getTimestampNanos(): Nanoseconds {
117
- const currentHrtime = process.hrtime.bigint();
118
- const elapsedNanos = currentHrtime - this._anchorHrtimeBigInt;
119
- return Nanoseconds.unsafe(this._epochView[0] + elapsedNanos);
161
+ return this._timestampNow(this);
120
162
  }
121
163
 
122
164
  /**
@@ -124,15 +166,7 @@ export class TraceRoot implements ITraceRoot {
124
166
  *
125
167
  */
126
168
  writeSpanStart(buffer: AnySpanBuffer, spanName: string): void {
127
- buffer.timestamp[0] = this.getTimestampNanos();
128
- buffer.entry_type[0] = ENTRY_TYPE_SPAN_START;
129
- buffer.message(0, spanName);
130
-
131
- // Pre-initialize row 1 as span-exception
132
- buffer.entry_type[1] = ENTRY_TYPE_SPAN_EXCEPTION;
133
- buffer.timestamp[1] = 0n;
134
-
135
- buffer._writeIndex = 2;
169
+ this._writeSpanStart(this, buffer, spanName);
136
170
  }
137
171
 
138
172
  /**
@@ -141,8 +175,7 @@ export class TraceRoot implements ITraceRoot {
141
175
  *
142
176
  */
143
177
  writeSpanEnd(buffer: AnySpanBuffer, entryType: number): void {
144
- buffer.timestamp[1] = this.getTimestampNanos();
145
- buffer.entry_type[1] = entryType;
178
+ this._writeSpanEnd(this, buffer, entryType);
146
179
  }
147
180
 
148
181
  /**
@@ -150,11 +183,7 @@ export class TraceRoot implements ITraceRoot {
150
183
  * SpanLogger uses returned idx for string column writes.
151
184
  */
152
185
  writeLogEntry(buffer: AnySpanBuffer, entryType: number): number {
153
- const idx = buffer._writeIndex;
154
- buffer.timestamp[idx] = this.getTimestampNanos();
155
- buffer.entry_type[idx] = entryType;
156
- buffer._writeIndex = idx + 1;
157
- return idx;
186
+ return this._appendLogEntry(this, buffer, entryType);
158
187
  }
159
188
  }
160
189
 
@@ -162,7 +191,7 @@ export class TraceRoot implements ITraceRoot {
162
191
  * Factory function for creating Node.js TraceRoot instances.
163
192
  * Pass this to Tracer constructor for Node.js environments.
164
193
  */
165
- export function createTraceRoot(trace_id: string, tracer: TracerLifecycleHooks): TraceRoot {
194
+ export function createTraceRoot<T extends LogSchema>(trace_id: string, tracer: TracerLifecycleHooks<T>): TraceRoot<T> {
166
195
  const anchorEpochNanos = BigInt(Date.now()) * 1_000_000n;
167
196
  const anchorHrtimeBigInt = process.hrtime.bigint();
168
197
  // Also store as f64 in the shared _system layout (WASM reads it without BigInt extraction)
@@ -14,39 +14,46 @@
14
14
  */
15
15
 
16
16
  import type { Nanoseconds } from '@smoothbricks/arrow-builder';
17
+ import type { BufferStrategy } from './bufferStrategy.js';
18
+ import type { LogSchema } from './schema/LogSchema.js';
19
+ import type { TraceTopology } from './traceTopology.js';
17
20
  import type { AnySpanBuffer } from './types.js';
18
21
 
19
22
  export type { SpanIdentity, TraceId } from './traceId.js';
20
23
  // Re-export TraceId types from traceId.ts
21
24
  export { createTraceId, extractSpanIdentity, generateTraceId, isValidTraceId, MAX_TRACE_ID_LENGTH } from './traceId.js';
22
25
 
26
+ /**
27
+ * Consume the one-shot marker set when a WASM allocation export already
28
+ * initialized the system lifecycle rows. Message storage is still populated
29
+ * by the selected physical appender after this returns.
30
+ */
31
+ export function consumeSpanStartedAtAllocation(buffer: AnySpanBuffer): boolean {
32
+ if (buffer._spanStartedAtAllocation !== true) return false;
33
+ buffer._spanStartedAtAllocation = false;
34
+ return true;
35
+ }
36
+
23
37
  /**
24
38
  * Tracer lifecycle hooks interface.
25
39
  * Extracted to avoid circular dependency - Tracer implements this.
26
40
  */
27
41
  //#region smoo/lmao!n/buffer-tuning-observability
28
- export interface TracerLifecycleHooks {
42
+ export interface TracerLifecycleHooks<T extends LogSchema = LogSchema> {
29
43
  onTraceStart(buffer: unknown): void;
30
44
  onTraceEnd(buffer: unknown): void;
31
45
  onSpanStart(buffer: unknown): void;
32
46
  onSpanEnd(buffer: unknown): void;
33
47
  onStatsWillResetFor(buffer: unknown): void;
48
+ /** Internal evaluator source used when a specialized parent omits the public ff slot. */
49
+ getFlagEvaluatorForContext(): unknown;
34
50
 
35
51
  /**
36
52
  * Buffer strategy for creating child and overflow buffers.
37
53
  * SpanContext uses this to create child spans with the correct strategy (JS or WASM).
38
54
  * Note: Caller must call writeSpanStart() after createChildSpanBuffer() to set span name.
39
55
  */
40
- readonly bufferStrategy: {
41
- createChildSpanBuffer(
42
- parentBuffer: AnySpanBuffer,
43
- callsiteMetadata: unknown,
44
- opMetadata: unknown,
45
- capacity?: number,
46
- schema?: unknown,
47
- ): AnySpanBuffer;
48
- createOverflowBuffer(buffer: AnySpanBuffer): AnySpanBuffer;
49
- };
56
+ readonly bufferStrategy: BufferStrategy<T>;
50
57
  }
51
58
  //#endregion smoo/lmao!n/buffer-tuning-observability
52
59
 
@@ -82,19 +89,33 @@ export const TRACE_ROOT_TRACE_ID_OFFSET = 17;
82
89
  *
83
90
  * The factory creates anchor timestamps internally using platform-specific APIs.
84
91
  */
85
- export type TraceRootFactory = (trace_id: string, tracer: TracerLifecycleHooks) => ITraceRoot;
92
+ export type TraceRootFactory<T extends LogSchema = LogSchema> = (
93
+ trace_id: string,
94
+ tracer: TracerLifecycleHooks<T>,
95
+ ) => ITraceRoot<T>;
86
96
 
87
- export interface ITraceRoot {
97
+ /** Platform-fixed primitives copied into the physical plan/generated writer hot path. */
98
+ export type TimestampNowPrimitive = (traceRoot: ITraceRoot) => Nanoseconds;
99
+ export type TimestampAppendPrimitive = (traceRoot: ITraceRoot, buffer: AnySpanBuffer, entryType: number) => number;
100
+ export type SpanStartPrimitive = (traceRoot: ITraceRoot, buffer: AnySpanBuffer, spanName: string) => void;
101
+ export type SpanEndPrimitive = (traceRoot: ITraceRoot, buffer: AnySpanBuffer, entryType: number) => void;
102
+
103
+ export interface ITraceRoot<T extends LogSchema = LogSchema> {
88
104
  /**
89
105
  * Raw backing buffer containing anchor timestamps and trace_id.
90
106
  * The WASM path can read this directly without BigInt extraction.
91
107
  */
92
108
  readonly _system: ArrayBuffer;
109
+ /** Canonical immutable UTF-8 trace ID bytes, shared by span identity construction. */
110
+ readonly _traceIdBytes: Uint8Array;
93
111
 
94
112
  /**
95
113
  * Tracer reference for lifecycle hooks and event callbacks.
96
114
  */
97
- readonly tracer: TracerLifecycleHooks;
115
+ readonly tracer: TracerLifecycleHooks<T>;
116
+
117
+ /** Trace-owned arena for logical span topology. */
118
+ readonly _topology: TraceTopology;
98
119
 
99
120
  /**
100
121
  * Trace ID for this trace.
@@ -114,6 +135,12 @@ export interface ITraceRoot {
114
135
  */
115
136
  readonly anchorPerfNow: number;
116
137
 
138
+ /** Monomorphic platform implementations cached by plans and generated writers. */
139
+ readonly _timestampNow: TimestampNowPrimitive;
140
+ readonly _appendLogEntry: TimestampAppendPrimitive;
141
+ readonly _writeSpanStart: SpanStartPrimitive;
142
+ readonly _writeSpanEnd: SpanEndPrimitive;
143
+
117
144
  /**
118
145
  * Get current timestamp in nanoseconds since Unix epoch.
119
146
  * Platform-specific implementation.