@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
@@ -9,8 +9,10 @@
9
9
  * @module wasmTraceRoot
10
10
  */
11
11
  import { Nanoseconds } from '@smoothbricks/arrow-builder';
12
+ import type { LogSchema } from '../schema/LogSchema.js';
12
13
  import { type TraceId } from '../traceId.js';
13
- import type { ITraceRoot, TracerLifecycleHooks } from '../traceRoot.js';
14
+ import { type ITraceRoot, type SpanEndPrimitive, type SpanStartPrimitive, type TimestampAppendPrimitive, type TimestampNowPrimitive, type TraceRootFactory, type TracerLifecycleHooks } from '../traceRoot.js';
15
+ import { TraceTopology } from '../traceTopology.js';
14
16
  import type { AnySpanBuffer } from '../types.js';
15
17
  import type { WasmAllocator } from './wasmAllocator.js';
16
18
  /**
@@ -20,45 +22,45 @@ import type { WasmAllocator } from './wasmAllocator.js';
20
22
  export interface WasmSpanBufferLike {
21
23
  /** Byte offset into WASM memory for system columns (timestamp + entry_type) */
22
24
  readonly _systemPtr: number;
25
+ /** Concrete per-op capacity; may differ from the allocator default. */
26
+ readonly _capacity: number;
23
27
  /** Byte offset into WASM memory for identity block (writeIndex, span_id, trace_id) */
24
28
  readonly _identityPtr: number;
25
29
  /** Message column - string array for span names and log messages */
26
30
  readonly _message: string[];
27
31
  /** Current write position (getter/setter reads from WASM identity block) */
28
32
  _writeIndex: number;
33
+ readonly _identityOwner: boolean;
34
+ readonly timestamp: BigInt64Array;
35
+ readonly entry_type: Uint8Array;
29
36
  }
30
37
  /**
31
38
  * Type guard to check if a buffer is WASM-backed.
32
39
  */
33
40
  export declare function isWasmSpanBuffer(buffer: unknown): buffer is WasmSpanBufferLike;
34
- /**
35
- * WASM-backed TraceRoot implementation.
36
- *
37
- * Implements ITraceRoot so it's compatible with SpanContext and the base Tracer.
38
- * Writes timestamps and entry types to WASM memory for WASM-backed buffers.
39
- *
40
- * Memory Layout at _traceRootPtr (16 bytes):
41
- * - Offset 0-7: anchorEpochNanos (i64) - wall clock time in nanoseconds
42
- * - Offset 8-15: anchorPerfNow (f64) - performance.now() anchor value
43
- *
44
- * The WASM allocator's initTraceRoot() captures these values at trace start,
45
- * and span lifecycle methods use them to calculate timestamps.
46
- */
47
- export declare class WasmTraceRoot implements ITraceRoot {
41
+ export declare class WasmTraceRoot<T extends LogSchema = LogSchema> implements ITraceRoot<T> {
48
42
  /** Byte offset in WASM memory where TraceRoot data lives */
49
43
  readonly _traceRootPtr: number;
44
+ private _state;
50
45
  /** The WASM allocator instance */
51
46
  readonly allocator: WasmAllocator;
52
47
  /** Trace ID string */
53
48
  readonly trace_id: TraceId;
49
+ readonly _traceIdBytes: Uint8Array;
54
50
  /** Tracer reference for lifecycle hooks */
55
- readonly tracer: TracerLifecycleHooks;
51
+ readonly tracer: TracerLifecycleHooks<T>;
52
+ readonly _topology: TraceTopology;
53
+ readonly _timestampNow: TimestampNowPrimitive;
54
+ readonly _appendLogEntry: TimestampAppendPrimitive;
55
+ readonly _writeSpanStart: SpanStartPrimitive;
56
+ readonly _writeSpanEnd: SpanEndPrimitive;
56
57
  /**
57
58
  * Raw backing buffer - not used for WASM, but required by ITraceRoot.
58
59
  * We create a minimal ArrayBuffer just to satisfy the interface.
59
60
  */
60
61
  readonly _system: ArrayBuffer;
61
- constructor(allocator: WasmAllocator, trace_id: TraceId, tracer: TracerLifecycleHooks);
62
+ constructor(allocator: WasmAllocator, trace_id: TraceId, tracer: TracerLifecycleHooks<T>);
63
+ _assertLive(): void;
62
64
  /**
63
65
  * Epoch time in nanoseconds when trace was created.
64
66
  * Read from WASM memory at _traceRootPtr offset 0.
@@ -141,9 +143,9 @@ export declare class WasmTraceRoot implements ITraceRoot {
141
143
  * @param identityPtr - Byte offset of buffer's identity block in WASM memory
142
144
  */
143
145
  readWriteIndex(identityPtr: number): number;
144
- /**
145
- * Free the TraceRoot's memory block when trace completes.
146
- */
146
+ /** Mark the handle stale when its allocator is reset wholesale. */
147
+ invalidate(): void;
148
+ /** Free the TraceRoot allocation exactly once. */
147
149
  free(): void;
148
150
  }
149
151
  /**
@@ -154,7 +156,7 @@ export declare class WasmTraceRoot implements ITraceRoot {
154
156
  * @param trace_id - Trace ID for this trace
155
157
  * @param tracer - Tracer lifecycle hooks
156
158
  */
157
- export declare function createWasmTraceRoot(allocator: WasmAllocator, trace_id: string, tracer: TracerLifecycleHooks): WasmTraceRoot;
159
+ export declare function createWasmTraceRoot<T extends LogSchema = LogSchema>(allocator: WasmAllocator, trace_id: string, tracer: TracerLifecycleHooks<T>): WasmTraceRoot<T>;
158
160
  /**
159
161
  * Factory function to create WasmTraceRoot factory.
160
162
  *
@@ -163,5 +165,5 @@ export declare function createWasmTraceRoot(allocator: WasmAllocator, trace_id:
163
165
  * @param allocator - WASM allocator instance
164
166
  * @returns Factory function compatible with TraceRootFactory type
165
167
  */
166
- export declare function createWasmTraceRootFactory(allocator: WasmAllocator): (trace_id: string, tracer: TracerLifecycleHooks) => WasmTraceRoot;
168
+ export declare function createWasmTraceRootFactory<T extends LogSchema = LogSchema>(allocator: WasmAllocator): TraceRootFactory<T>;
167
169
  //# sourceMappingURL=wasmTraceRoot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wasmTraceRoot.d.ts","sourceRoot":"","sources":["../../../src/lib/wasm/wasmTraceRoot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AASxD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sFAAsF;IACtF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC5B,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,kBAAkB,CAE9E;AAMD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,YAAW,UAAU;IAC9C,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,kCAAkC;IAClC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAElC,sBAAsB;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAEtC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAE9B,YAAY,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAepF;IAED;;;OAGG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAG7B;IAED;;;OAGG;IACH,IAAI,aAAa,IAAI,MAAM,CAG1B;IAED;;;;;;;;OAQG;IACH,iBAAiB,IAAI,WAAW,CAI/B;IAOD;;;;;;;;;OASG;IACH,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAmB5D;IAED;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAwB3D;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAW9D;IAOD;;;;;;;OAOG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAE9D;IAED;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAEzC;IAED;;;OAGG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE1C;IAED;;;;;;;;OAQG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAElF;IAED;;;OAGG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1C;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,CAEX;CACF;AAMD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,oBAAoB,GAC3B,aAAa,CAEf;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,aAAa,cAC/C,MAAM,UAAU,oBAAoB,KAAG,aAAa,CAGvE"}
1
+ {"version":3,"file":"wasmTraceRoot.d.ts","sourceRoot":"","sources":["../../../src/lib/wasm/wasmTraceRoot.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,9 @@
11
11
  import { Nanoseconds } from '@smoothbricks/arrow-builder';
12
12
  import { ENTRY_TYPE_SPAN_EXCEPTION, ENTRY_TYPE_SPAN_START } from '../schema/systemSchema.js';
13
13
  import { createTraceId } from '../traceId.js';
14
+ import { consumeSpanStartedAtAllocation, } from '../traceRoot.js';
15
+ import { TraceTopology } from '../traceTopology.js';
16
+ const traceIdEncoder = new TextEncoder();
14
17
  /**
15
18
  * Type guard to check if a buffer is WASM-backed.
16
19
  */
@@ -33,15 +36,89 @@ export function isWasmSpanBuffer(buffer) {
33
36
  * The WASM allocator's initTraceRoot() captures these values at trace start,
34
37
  * and span lifecycle methods use them to calculate timestamps.
35
38
  */
39
+ const timestampNow = (traceRoot) => {
40
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WASM primitive table is only installed on WasmTraceRoot instances.
41
+ const root = traceRoot;
42
+ root._assertLive();
43
+ const elapsedNanos = BigInt(Math.round((performance.now() - root.anchorPerfNow) * 1000000));
44
+ return Nanoseconds.unsafe(root.anchorEpochNanos + elapsedNanos);
45
+ };
46
+ const appendLogEntry = (traceRoot, buffer, entryType) => {
47
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WASM primitive table is only installed on WasmTraceRoot instances.
48
+ const root = traceRoot;
49
+ root._assertLive();
50
+ if (isWasmSpanBuffer(buffer) && buffer._messagePhysicalLayout !== 'packed' && buffer._identityOwner) {
51
+ return root.allocator.writeLogEntry(buffer._systemPtr, buffer._identityPtr, root._traceRootPtr, entryType, buffer._capacity);
52
+ }
53
+ const idx = buffer._writeIndex;
54
+ const entryTypes = buffer.entry_type;
55
+ if (entryTypes === undefined)
56
+ throw new TypeError('Split WASM appender requires entry_type storage');
57
+ buffer.timestamp[idx] = timestampNow(root);
58
+ entryTypes[idx] = entryType;
59
+ buffer._writeIndex = idx + 1;
60
+ return idx;
61
+ };
62
+ const writeSpanStartPrimitive = (traceRoot, buffer, spanName) => {
63
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WASM primitive table is only installed on WasmTraceRoot instances.
64
+ const root = traceRoot;
65
+ root._assertLive();
66
+ if (isWasmSpanBuffer(buffer) && buffer._messagePhysicalLayout !== 'packed') {
67
+ if (!consumeSpanStartedAtAllocation(buffer)) {
68
+ root.allocator.spanStart(buffer._systemPtr, buffer._identityPtr, root._traceRootPtr, buffer._capacity);
69
+ }
70
+ buffer._message[0] = spanName;
71
+ return;
72
+ }
73
+ const entryTypes = buffer.entry_type;
74
+ if (entryTypes === undefined)
75
+ throw new TypeError('Split WASM span-start appender requires entry_type storage');
76
+ buffer.timestamp[0] = timestampNow(root);
77
+ entryTypes[0] = ENTRY_TYPE_SPAN_START;
78
+ buffer.message(0, spanName);
79
+ entryTypes[1] = ENTRY_TYPE_SPAN_EXCEPTION;
80
+ buffer.timestamp[1] = 0n;
81
+ buffer._writeIndex = 2;
82
+ };
83
+ const writeSpanEndPrimitive = (traceRoot, buffer, entryType) => {
84
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WASM primitive table is only installed on WasmTraceRoot instances.
85
+ const root = traceRoot;
86
+ root._assertLive();
87
+ if (isWasmSpanBuffer(buffer) && buffer._messagePhysicalLayout !== 'packed') {
88
+ if (entryType === 2)
89
+ root.allocator.spanEndOk(buffer._systemPtr, root._traceRootPtr, buffer._capacity);
90
+ else
91
+ root.allocator.spanEndErr(buffer._systemPtr, root._traceRootPtr, buffer._capacity);
92
+ if (entryType !== 2 && entryType !== 3) {
93
+ const splitEntryTypes = buffer.entry_type;
94
+ if (splitEntryTypes === undefined)
95
+ throw new TypeError('Split WASM buffer is missing entry_type storage');
96
+ splitEntryTypes[1] = entryType;
97
+ }
98
+ return;
99
+ }
100
+ const entryTypes = buffer.entry_type;
101
+ if (entryTypes === undefined)
102
+ throw new TypeError('Split WASM span-end appender requires entry_type storage');
103
+ buffer.timestamp[1] = timestampNow(root);
104
+ entryTypes[1] = entryType;
105
+ };
36
106
  export class WasmTraceRoot {
37
107
  /** Byte offset in WASM memory where TraceRoot data lives */
38
108
  _traceRootPtr;
109
+ _state = 'live';
39
110
  /** The WASM allocator instance */
40
111
  allocator;
41
112
  /** Trace ID string */
42
113
  trace_id;
114
+ _traceIdBytes;
43
115
  /** Tracer reference for lifecycle hooks */
44
116
  tracer;
117
+ _topology;
118
+ _timestampNow = timestampNow;
119
+ _appendLogEntry = appendLogEntry;
120
+ _writeSpanStart = writeSpanStartPrimitive;
121
+ _writeSpanEnd = writeSpanEndPrimitive;
45
122
  /**
46
123
  * Raw backing buffer - not used for WASM, but required by ITraceRoot.
47
124
  * We create a minimal ArrayBuffer just to satisfy the interface.
@@ -50,21 +127,28 @@ export class WasmTraceRoot {
50
127
  constructor(allocator, trace_id, tracer) {
51
128
  this.allocator = allocator;
52
129
  this.trace_id = trace_id;
130
+ this._traceIdBytes = traceIdEncoder.encode(trace_id);
53
131
  this.tracer = tracer;
54
- // Create minimal _system buffer (not actually used, but required by interface)
132
+ this._topology = new TraceTopology();
55
133
  this._system = new ArrayBuffer(16);
56
- // Allocate an 8B column block for TraceRoot data (16 bytes needed, 8B block is large enough)
57
- // The 8B column block size is: ceil(capacity/8) + capacity*8 = 8 + 512 = 520 bytes for capacity 64
58
- // We only need 16 bytes, so this works fine
59
- this._traceRootPtr = allocator.alloc8B();
60
- // Initialize wall clock and monotonic start times in WASM memory
134
+ // Native TraceRoot is exactly two aligned 8-byte fields.
135
+ const traceRootPtr = allocator.allocExact(16, 8);
136
+ if (traceRootPtr === 0) {
137
+ throw new Error('WASM trace-root allocation failed');
138
+ }
139
+ this._traceRootPtr = traceRootPtr;
61
140
  allocator.initTraceRoot(this._traceRootPtr);
62
141
  }
142
+ _assertLive() {
143
+ if (this._state !== 'live')
144
+ throw new Error('WASM trace root has been released');
145
+ }
63
146
  /**
64
147
  * Epoch time in nanoseconds when trace was created.
65
148
  * Read from WASM memory at _traceRootPtr offset 0.
66
149
  */
67
150
  get anchorEpochNanos() {
151
+ this._assertLive();
68
152
  // i64 view is indexed by 8-byte chunks
69
153
  return this.allocator.i64[this._traceRootPtr / 8];
70
154
  }
@@ -73,6 +157,7 @@ export class WasmTraceRoot {
73
157
  * Read from WASM memory at _traceRootPtr offset 8.
74
158
  */
75
159
  get anchorPerfNow() {
160
+ this._assertLive();
76
161
  // f64 view is indexed by 8-byte chunks
77
162
  return this.allocator.f64[(this._traceRootPtr + 8) / 8];
78
163
  }
@@ -86,9 +171,7 @@ export class WasmTraceRoot {
86
171
  * We convert to nanoseconds for consistency with the trace format.
87
172
  */
88
173
  getTimestampNanos() {
89
- const elapsedMs = performance.now() - this.anchorPerfNow;
90
- const elapsedNanos = BigInt(Math.round(elapsedMs * 1000000));
91
- return Nanoseconds.unsafe(this.anchorEpochNanos + elapsedNanos);
174
+ return this._timestampNow(this);
92
175
  }
93
176
  // ===========================================================================
94
177
  // ITraceRoot implementation (takes buffer parameter)
@@ -105,25 +188,7 @@ export class WasmTraceRoot {
105
188
  * @param spanName - Name for this span
106
189
  */
107
190
  writeSpanStart(buffer, spanName) {
108
- if (isWasmSpanBuffer(buffer)) {
109
- // WASM path: delegate to WASM allocator
110
- // spanStart writes row 0 (span-start) and row 1 (span-exception placeholder)
111
- // Also sets writeIndex to 2 in the identity block
112
- this.allocator.spanStart(buffer._systemPtr, buffer._identityPtr, this._traceRootPtr);
113
- // Write span name to message column (JS string array)
114
- buffer._message[0] = spanName;
115
- // Note: _writeIndex is set by WASM spanStart to 2, but the getter reads from WASM
116
- // so we don't need to set it here explicitly (the setter would write to WASM anyway)
117
- }
118
- else {
119
- // JS path: write directly to TypedArrays (fallback for mixed usage)
120
- buffer.timestamp[0] = this.getTimestampNanos();
121
- buffer.entry_type[0] = ENTRY_TYPE_SPAN_START;
122
- buffer.message(0, spanName);
123
- buffer.entry_type[1] = ENTRY_TYPE_SPAN_EXCEPTION;
124
- buffer.timestamp[1] = 0n;
125
- buffer._writeIndex = 2;
126
- }
191
+ this._writeSpanStart(this, buffer, spanName);
127
192
  }
128
193
  /**
129
194
  * Write span-end entry to buffer at row 1.
@@ -133,32 +198,7 @@ export class WasmTraceRoot {
133
198
  * @param entryType - Entry type (SPAN_OK, SPAN_ERR, or SPAN_EXCEPTION)
134
199
  */
135
200
  writeSpanEnd(buffer, entryType) {
136
- if (isWasmSpanBuffer(buffer)) {
137
- // WASM path: use appropriate end function based on entry type
138
- // Note: WASM spanEndOk/spanEndErr write to row 1
139
- if (entryType === 2) {
140
- // SPAN_OK
141
- this.allocator.spanEndOk(buffer._systemPtr, this._traceRootPtr);
142
- }
143
- else if (entryType === 3) {
144
- // SPAN_ERR
145
- this.allocator.spanEndErr(buffer._systemPtr, this._traceRootPtr);
146
- }
147
- else {
148
- // SPAN_EXCEPTION or other - write via generic log entry
149
- // For now, use spanEndErr as fallback (entry_type will be overwritten)
150
- this.allocator.spanEndErr(buffer._systemPtr, this._traceRootPtr);
151
- // Overwrite entry_type if needed (for EXCEPTION)
152
- if (entryType !== 3) {
153
- buffer.entry_type[1] = entryType;
154
- }
155
- }
156
- }
157
- else {
158
- // JS path
159
- buffer.timestamp[1] = this.getTimestampNanos();
160
- buffer.entry_type[1] = entryType;
161
- }
201
+ this._writeSpanEnd(this, buffer, entryType);
162
202
  }
163
203
  /**
164
204
  * Write log entry: bump writeIndex, write timestamp + entry_type, return idx.
@@ -169,16 +209,7 @@ export class WasmTraceRoot {
169
209
  * @returns The row index where entry was written
170
210
  */
171
211
  writeLogEntry(buffer, entryType) {
172
- if (isWasmSpanBuffer(buffer)) {
173
- // WASM path: bump writeIndex, write timestamp + entry_type, return idx
174
- return this.allocator.writeLogEntry(buffer._systemPtr, buffer._identityPtr, this._traceRootPtr, entryType);
175
- }
176
- // JS path: bump writeIndex, write directly, return idx
177
- const idx = buffer._writeIndex;
178
- buffer.timestamp[idx] = this.getTimestampNanos();
179
- buffer.entry_type[idx] = entryType;
180
- buffer._writeIndex = idx + 1;
181
- return idx;
212
+ return this._appendLogEntry(this, buffer, entryType);
182
213
  }
183
214
  // ===========================================================================
184
215
  // Low-level WASM pointer-based methods (for direct WASM access and tests)
@@ -193,6 +224,7 @@ export class WasmTraceRoot {
193
224
  * @param identityPtr - Byte offset of buffer's identity block in WASM memory
194
225
  */
195
226
  writeSpanStartPtr(systemPtr, identityPtr) {
227
+ this._assertLive();
196
228
  this.allocator.spanStart(systemPtr, identityPtr, this._traceRootPtr);
197
229
  }
198
230
  /**
@@ -200,6 +232,7 @@ export class WasmTraceRoot {
200
232
  * @param systemPtr - Byte offset of buffer's system block in WASM memory
201
233
  */
202
234
  writeSpanEndOkPtr(systemPtr) {
235
+ this._assertLive();
203
236
  this.allocator.spanEndOk(systemPtr, this._traceRootPtr);
204
237
  }
205
238
  /**
@@ -207,6 +240,7 @@ export class WasmTraceRoot {
207
240
  * @param systemPtr - Byte offset of buffer's system block in WASM memory
208
241
  */
209
242
  writeSpanEndErrPtr(systemPtr) {
243
+ this._assertLive();
210
244
  this.allocator.spanEndErr(systemPtr, this._traceRootPtr);
211
245
  }
212
246
  /**
@@ -219,6 +253,7 @@ export class WasmTraceRoot {
219
253
  * @returns Row index where entry was written
220
254
  */
221
255
  writeLogEntryPtr(systemPtr, identityPtr, entryType) {
256
+ this._assertLive();
222
257
  return this.allocator.writeLogEntry(systemPtr, identityPtr, this._traceRootPtr, entryType);
223
258
  }
224
259
  /**
@@ -226,13 +261,19 @@ export class WasmTraceRoot {
226
261
  * @param identityPtr - Byte offset of buffer's identity block in WASM memory
227
262
  */
228
263
  readWriteIndex(identityPtr) {
264
+ this._assertLive();
229
265
  return this.allocator.readWriteIndex(identityPtr);
230
266
  }
231
- /**
232
- * Free the TraceRoot's memory block when trace completes.
233
- */
267
+ /** Mark the handle stale when its allocator is reset wholesale. */
268
+ invalidate() {
269
+ this._state = 'freed';
270
+ }
271
+ /** Free the TraceRoot allocation exactly once. */
234
272
  free() {
235
- this.allocator.free8B(this._traceRootPtr);
273
+ if (this._state === 'freed')
274
+ return;
275
+ this.allocator.freeExact(this._traceRootPtr, 16, 8);
276
+ this._state = 'freed';
236
277
  }
237
278
  }
238
279
  // =============================================================================
@@ -258,8 +299,6 @@ export function createWasmTraceRoot(allocator, trace_id, tracer) {
258
299
  * @returns Factory function compatible with TraceRootFactory type
259
300
  */
260
301
  export function createWasmTraceRootFactory(allocator) {
261
- return (trace_id, tracer) => {
262
- return new WasmTraceRoot(allocator, createTraceId(trace_id), tracer);
263
- };
302
+ return (trace_id, tracer) => new WasmTraceRoot(allocator, createTraceId(trace_id), tracer);
264
303
  }
265
304
  //#endregion smoo/lmao!n/wasm-mem.trace-root
@@ -0,0 +1,2 @@
1
+ import '../../lib/vocabularyRegistry.js';
2
+ //# sourceMappingURL=v1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"v1.d.ts","sourceRoot":"","sources":["../../../src/vocabulary/register/v1.ts"],"names":[],"mappings":"AAAA,OAAO,iCAAiC,CAAC"}
@@ -0,0 +1 @@
1
+ import '../../lib/vocabularyRegistry.js';
package/dist/wasm.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { WasmBufferStrategy, type WasmBufferStrategyOptions } from './lib/wasm/WasmBufferStrategy.js';
2
+ export { createWasmAllocator, createWasmAllocatorSync, WASM_NO_LAYOUT_OFFSET, WASM_SPAN_IDENTITY_CHILD, WASM_SPAN_IDENTITY_ROOT, type WasmAllocator, type WasmAllocatorOptions, } from './lib/wasm/wasmAllocator.js';
3
+ export { isWasmSpanBufferInstance, type WasmSpanBufferInstance, } from './lib/wasm/wasmSpanBuffer.js';
4
+ export { createWasmTraceRoot, createWasmTraceRootFactory, WasmTraceRoot, } from './lib/wasm/wasmTraceRoot.js';
5
+ //# sourceMappingURL=wasm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wasm.d.ts","sourceRoot":"","sources":["../src/wasm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AACtG,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,KAAK,aAAa,EAClB,KAAK,oBAAoB,GAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,wBAAwB,EACxB,KAAK,sBAAsB,GAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,aAAa,GACd,MAAM,6BAA6B,CAAC"}
package/dist/wasm.js ADDED
@@ -0,0 +1,4 @@
1
+ export { WasmBufferStrategy } from './lib/wasm/WasmBufferStrategy.js';
2
+ export { createWasmAllocator, createWasmAllocatorSync, WASM_NO_LAYOUT_OFFSET, WASM_SPAN_IDENTITY_CHILD, WASM_SPAN_IDENTITY_ROOT, } from './lib/wasm/wasmAllocator.js';
3
+ export { isWasmSpanBufferInstance, } from './lib/wasm/wasmSpanBuffer.js';
4
+ export { createWasmTraceRoot, createWasmTraceRootFactory, WasmTraceRoot, } from './lib/wasm/wasmTraceRoot.js';
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@smoothbricks/lmao",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
- "sideEffects": false,
5
+ "sideEffects": [
6
+ "./dist/vocabulary/register/v1.js",
7
+ "./src/vocabulary/register/v1.ts",
8
+ "./dist/lib/span-buffer/aot/v1.js",
9
+ "./src/lib/span-buffer/aot/v1.ts"
10
+ ],
6
11
  "main": "./dist/index.js",
7
12
  "module": "./dist/index.js",
8
13
  "types": "./dist/index.d.ts",
@@ -14,6 +19,18 @@
14
19
  "import": "./dist/index.js",
15
20
  "default": "./dist/index.js"
16
21
  },
22
+ "./span-buffer/aot/v1": {
23
+ "types": "./dist/lib/span-buffer/aot/v1.d.ts",
24
+ "development": "./src/lib/span-buffer/aot/v1.ts",
25
+ "import": "./dist/lib/span-buffer/aot/v1.js",
26
+ "default": "./dist/lib/span-buffer/aot/v1.js"
27
+ },
28
+ "./vocabulary/register/v1": {
29
+ "types": "./dist/vocabulary/register/v1.d.ts",
30
+ "development": "./src/vocabulary/register/v1.ts",
31
+ "import": "./dist/vocabulary/register/v1.js",
32
+ "default": "./dist/vocabulary/register/v1.js"
33
+ },
17
34
  "./node": {
18
35
  "types": "./dist/node.d.ts",
19
36
  "development": "./src/node.ts",
@@ -26,6 +43,12 @@
26
43
  "import": "./dist/es.js",
27
44
  "default": "./dist/es.js"
28
45
  },
46
+ "./wasm": {
47
+ "types": "./dist/wasm.d.ts",
48
+ "development": "./src/wasm.ts",
49
+ "import": "./dist/wasm.js",
50
+ "default": "./dist/wasm.js"
51
+ },
29
52
  "./cloudflare": {
30
53
  "types": "./dist/cloudflare.d.ts",
31
54
  "development": "./src/cloudflare.ts",
@@ -124,16 +147,16 @@
124
147
  "dependencies": {
125
148
  "@msgpack/msgpack": "^3.1.3",
126
149
  "@neophi/sieve-cache": "^1.5.0",
127
- "@smoothbricks/arrow-builder": "0.1.4",
128
- "@smoothbricks/validation": "0.1.3",
150
+ "@smoothbricks/arrow-builder": "0.1.5",
151
+ "@smoothbricks/validation": "0.1.4",
129
152
  "@uwdata/flechette": "^2.3.0",
130
153
  "tslib": "^2.8.1",
131
- "typia": "13.1.1"
154
+ "typia": "13.1.19"
132
155
  },
133
156
  "scripts": {
134
157
  "bench": "bun run benchmarks/*.bench.ts",
135
158
  "bench:wasm": "bun run benchmarks/js-vs-wasm.bench.ts",
136
- "build:wasm": "zig build -Doptimize=ReleaseSmall",
159
+ "build:wasm": "nx run lmao:rust-wasm",
137
160
  "test": "nx run lmao:test --outputStyle=stream"
138
161
  },
139
162
  "nx": {
@@ -155,6 +178,31 @@
155
178
  "timeoutMs": 120000,
156
179
  "killAfterMs": 1e4
157
180
  }
181
+ },
182
+ "rust-wasm": {
183
+ "executor": "nx:run-commands",
184
+ "cache": true,
185
+ "dependsOn": [
186
+ "^build",
187
+ {
188
+ "projects": [
189
+ "lmao-rs"
190
+ ],
191
+ "target": "cargo-wasm"
192
+ }
193
+ ],
194
+ "inputs": [
195
+ {
196
+ "dependentTasksOutputFiles": "**/*.wasm"
197
+ }
198
+ ],
199
+ "outputs": [
200
+ "{projectRoot}/dist/allocator.wasm"
201
+ ],
202
+ "options": {
203
+ "command": "mkdir -p dist && cp ../lmao-rs/dist/lmao_wasm.wasm dist/allocator.wasm",
204
+ "cwd": "{projectRoot}"
205
+ }
158
206
  }
159
207
  },
160
208
  "tags": [
package/src/index.ts CHANGED
@@ -114,6 +114,7 @@ export { createSpanLogger, createSpanLoggerClass } from './lib/codegen/spanLogge
114
114
 
115
115
  export * from './lib/convertToArrow.js';
116
116
  export * from './lib/spanBuffer.js';
117
+ export * from './lib/traceTopology.js';
117
118
  export * from './lib/types.js';
118
119
 
119
120
  // =============================================================================
@@ -21,6 +21,7 @@ import {
21
21
  createOverflowBuffer as createOverflowBufferImpl,
22
22
  createSpanBuffer as createSpanBufferImpl,
23
23
  getSpanBufferClass,
24
+ resolveSpanBufferCapacity,
24
25
  type SpanBufferConstructor,
25
26
  } from './spanBuffer.js';
26
27
  import type { ITraceRoot } from './traceRoot.js';
@@ -69,8 +70,14 @@ export class JsBufferStrategy<T extends LogSchema = LogSchema> implements Buffer
69
70
  return cached;
70
71
  }
71
72
 
72
- createSpanBuffer(schema: T, traceRoot: ITraceRoot, opMetadata: OpMetadata, capacity?: number): SpanBuffer<T> {
73
- return createSpanBufferImpl(schema, traceRoot, opMetadata, capacity);
73
+ createSpanBuffer(
74
+ schema: T,
75
+ traceRoot: ITraceRoot,
76
+ opMetadata: OpMetadata,
77
+ capacity?: number,
78
+ plannedClass?: SpanBufferConstructor<T>,
79
+ ): SpanBuffer<T> {
80
+ return createSpanBufferImpl(schema, traceRoot, opMetadata, capacity, plannedClass);
74
81
  }
75
82
 
76
83
  createChildSpanBuffer(
@@ -79,11 +86,23 @@ export class JsBufferStrategy<T extends LogSchema = LogSchema> implements Buffer
79
86
  opMetadata: OpMetadata,
80
87
  capacity?: number,
81
88
  schema?: T,
89
+ plannedClass?: SpanBufferConstructor<T>,
82
90
  ): SpanBuffer<T> {
83
- // Use provided schema (for cross-library calls) or parent's schema
84
- const childSchema = schema ?? parentBuffer._logSchema;
85
- const SpanBufferClass = this.getSpanBufferClassForSchema(childSchema);
86
- return createChildSpanBufferImpl(parentBuffer, SpanBufferClass, callsiteMetadata, opMetadata, capacity);
91
+ const targetSchema = schema ?? parentBuffer._logSchema;
92
+ const metadataSpanBufferClass = opMetadata._physicalLayoutPlan?.SpanBufferClass;
93
+ if (
94
+ metadataSpanBufferClass !== undefined &&
95
+ !isSpanBufferConstructorForSchema(metadataSpanBufferClass, targetSchema)
96
+ ) {
97
+ throw new TypeError('Planned SpanBuffer class does not match schema');
98
+ }
99
+ const plannedSpanBufferClass = plannedClass ?? metadataSpanBufferClass;
100
+ const SpanBufferClass = plannedSpanBufferClass ?? this.getSpanBufferClassForSchema(targetSchema);
101
+ const actualCapacity =
102
+ plannedSpanBufferClass === undefined
103
+ ? resolveSpanBufferCapacity(capacity, SpanBufferClass.stats.capacity)
104
+ : capacity;
105
+ return createChildSpanBufferImpl(parentBuffer, SpanBufferClass, callsiteMetadata, opMetadata, actualCapacity);
87
106
  }
88
107
 
89
108
  createOverflowBuffer(buffer: SpanBuffer<T>): SpanBuffer<T> {
@@ -95,8 +114,7 @@ export class JsBufferStrategy<T extends LogSchema = LogSchema> implements Buffer
95
114
  return convertSpanTreeToArrowTable(buffer);
96
115
  }
97
116
 
98
- releaseBuffer(_buffer: AnySpanBuffer): void {
99
- // No-op for JS strategy - GC handles memory
100
- // The buffer will be collected when no references remain
117
+ releaseBuffer(buffer: AnySpanBuffer): void {
118
+ buffer._traceRoot._topology.release();
101
119
  }
102
120
  }