@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
@@ -0,0 +1,214 @@
1
+ import { describe, expect, it } from 'bun:test';
2
+ import './test-helpers.js';
3
+ import { createTagWriter, getTagWriterClass } from '../codegen/fixedPositionWriterGenerator.js';
4
+ import { resolveEnumLookupDescriptor } from '../enumMetadata.js';
5
+ import { S } from '../schema/builder.js';
6
+ import { defineLogSchema } from '../schema/defineLogSchema.js';
7
+ import { createSpanBuffer } from '../spanBuffer.js';
8
+ import type { AnySpanBuffer } from '../types.js';
9
+ import { createTestOpMetadata, createTestSchema, createTestSpanContext, createTestTraceRoot } from './test-helpers.js';
10
+
11
+ function countFunctionConstructorCalls(run: () => void): number {
12
+ const originalDescriptor = Object.getOwnPropertyDescriptor(globalThis, 'Function');
13
+ if (!originalDescriptor) throw new Error('Expected global Function descriptor');
14
+
15
+ const originalFunction = globalThis.Function;
16
+ let calls = 0;
17
+ const functionProbe = new Proxy(originalFunction, {
18
+ apply(target, thisArgument, argumentList) {
19
+ calls++;
20
+ return Reflect.apply(target, thisArgument, argumentList);
21
+ },
22
+ construct(target, argumentList, newTarget) {
23
+ calls++;
24
+ return Reflect.construct(target, argumentList, newTarget);
25
+ },
26
+ });
27
+
28
+ Object.defineProperty(globalThis, 'Function', {
29
+ configurable: originalDescriptor.configurable,
30
+ enumerable: originalDescriptor.enumerable,
31
+ value: functionProbe,
32
+ writable: originalDescriptor.writable,
33
+ });
34
+ try {
35
+ run();
36
+ } finally {
37
+ Object.defineProperty(globalThis, 'Function', originalDescriptor);
38
+ }
39
+ return calls;
40
+ }
41
+
42
+ function arrayColumn(buffer: AnySpanBuffer, name: string): unknown[] {
43
+ const column = buffer.getColumnIfAllocated(name);
44
+ if (!Array.isArray(column)) {
45
+ throw new Error(`${name} column was not allocated as an array`);
46
+ }
47
+ return column;
48
+ }
49
+
50
+ function float64Column(buffer: AnySpanBuffer, name: string): Float64Array {
51
+ const column = buffer.getColumnIfAllocated(name);
52
+ if (!(column instanceof Float64Array)) {
53
+ throw new Error(`${name} column was not allocated as a Float64Array`);
54
+ }
55
+ return column;
56
+ }
57
+
58
+ function uint8Column(buffer: AnySpanBuffer, name: string): Uint8Array {
59
+ const column = buffer.getColumnIfAllocated(name);
60
+ if (!(column instanceof Uint8Array)) {
61
+ throw new Error(`${name} column was not allocated as a Uint8Array`);
62
+ }
63
+ return column;
64
+ }
65
+
66
+ function bigUint64Column(buffer: AnySpanBuffer, name: string): BigUint64Array {
67
+ const column = buffer.getColumnIfAllocated(name);
68
+ if (!(column instanceof BigUint64Array)) {
69
+ throw new Error(`${name} column was not allocated as a BigUint64Array`);
70
+ }
71
+ return column;
72
+ }
73
+
74
+ function invokeWriterMethod(writer: object, methodName: string, value: unknown): unknown {
75
+ const method = Reflect.get(writer, methodName);
76
+ if (typeof method !== 'function') {
77
+ throw new Error(`TagWriter is missing ${methodName}()`);
78
+ }
79
+ return Reflect.apply(method, writer, [value]);
80
+ }
81
+
82
+ function setupWriter() {
83
+ const schema = createTestSchema({
84
+ categoryValue: S.category(),
85
+ textValue: S.text(),
86
+ numberValue: S.number(),
87
+ booleanValue: S.boolean(),
88
+ enumValue: S.enum(['FIRST', 'SECOND']),
89
+ });
90
+ const buffer = createSpanBuffer(schema, createTestTraceRoot('tag-writer-aot'), createTestOpMetadata(), 8);
91
+ const context = createTestSpanContext(schema, buffer);
92
+ return { buffer, schema, writer: createTagWriter(schema, context) };
93
+ }
94
+
95
+ describe('AOT-safe TagWriter class creation', () => {
96
+ it('creates and caches a constructor for a fresh schema without calling global Function', () => {
97
+ const schema = defineLogSchema({ status: S.enum(['QUEUED', 'DONE']) });
98
+ const enumLookup = resolveEnumLookupDescriptor(schema);
99
+
100
+ const functionConstructorCalls = countFunctionConstructorCalls(() => {
101
+ getTagWriterClass(schema, ['status'], enumLookup);
102
+ });
103
+
104
+ expect(functionConstructorCalls).toBe(0);
105
+ });
106
+
107
+ it('caches by schema identity and ordered eager-column key', () => {
108
+ const schema = defineLogSchema({ alpha: S.number(), beta: S.number() });
109
+ const sameEagerKey = getTagWriterClass(schema, ['alpha']);
110
+
111
+ expect(getTagWriterClass(schema, ['alpha'])).toBe(sameEagerKey);
112
+ expect(getTagWriterClass(schema, ['beta'])).not.toBe(sameEagerKey);
113
+ expect(getTagWriterClass(schema, ['alpha', 'beta'])).not.toBe(getTagWriterClass(schema, ['beta', 'alpha']));
114
+
115
+ const structurallyEqualSchema = defineLogSchema({ alpha: S.number(), beta: S.number() });
116
+ expect(getTagWriterClass(structurallyEqualSchema, ['alpha'])).not.toBe(sameEagerKey);
117
+ });
118
+ });
119
+
120
+ describe('TagWriter row-0 semantics', () => {
121
+ it('uses exact schema setter names, writes every scalar lane at row 0, and preserves fluent identity', () => {
122
+ const { buffer, writer } = setupWriter();
123
+
124
+ expect(writer.categoryValue('category-0')).toBe(writer);
125
+ expect(writer.textValue('text-0')).toBe(writer);
126
+ expect(writer.numberValue(42.5)).toBe(writer);
127
+ expect(writer.booleanValue(true)).toBe(writer);
128
+ expect(writer.enumValue('SECOND')).toBe(writer);
129
+ expect(writer.uint64_value(18_446_744_073_709_551_615n)).toBe(writer);
130
+
131
+ expect(arrayColumn(buffer, 'categoryValue')[0]).toBe('category-0');
132
+ expect(arrayColumn(buffer, 'textValue')[0]).toBe('text-0');
133
+ expect(float64Column(buffer, 'numberValue')[0]).toBe(42.5);
134
+ expect((uint8Column(buffer, 'booleanValue')[0] & 0b0000_0001) !== 0).toBe(true);
135
+ expect(uint8Column(buffer, 'enumValue')[0]).toBe(1);
136
+ expect(bigUint64Column(buffer, 'uint64_value')[0]).toBe(18_446_744_073_709_551_615n);
137
+ });
138
+
139
+ it('encodes an invalid enum value as ordinal zero', () => {
140
+ const { buffer, writer } = setupWriter();
141
+
142
+ expect(invokeWriterMethod(writer, 'enumValue', 'INVALID')).toBe(writer);
143
+ expect(uint8Column(buffer, 'enumValue')[0]).toBe(0);
144
+ });
145
+
146
+ it('with skips nullish values, evaluates attributes in schema order, and returns the same writer', () => {
147
+ const schema = createTestSchema({
148
+ first: S.number(),
149
+ nullValue: S.text(),
150
+ second: S.category(),
151
+ undefinedValue: S.number(),
152
+ third: S.boolean(),
153
+ });
154
+ const buffer = createSpanBuffer(schema, createTestTraceRoot('tag-writer-with-order'), createTestOpMetadata(), 8);
155
+ const context = createTestSpanContext(schema, buffer);
156
+ const writer = createTagWriter(schema, context);
157
+ const firstAccesses: string[] = [];
158
+ const accessed = new Set<string>();
159
+ const recordFirstAccess = (name: string): void => {
160
+ if (!accessed.has(name)) {
161
+ accessed.add(name);
162
+ firstAccesses.push(name);
163
+ }
164
+ };
165
+ const attributes = Object.defineProperties(
166
+ {},
167
+ {
168
+ third: {
169
+ enumerable: true,
170
+ get() {
171
+ recordFirstAccess('third');
172
+ return true;
173
+ },
174
+ },
175
+ undefinedValue: {
176
+ enumerable: true,
177
+ get() {
178
+ recordFirstAccess('undefinedValue');
179
+ return undefined;
180
+ },
181
+ },
182
+ second: {
183
+ enumerable: true,
184
+ get() {
185
+ recordFirstAccess('second');
186
+ return 'second-0';
187
+ },
188
+ },
189
+ nullValue: {
190
+ enumerable: true,
191
+ get() {
192
+ recordFirstAccess('nullValue');
193
+ return null;
194
+ },
195
+ },
196
+ first: {
197
+ enumerable: true,
198
+ get() {
199
+ recordFirstAccess('first');
200
+ return 1;
201
+ },
202
+ },
203
+ },
204
+ );
205
+
206
+ expect(invokeWriterMethod(writer, 'with', attributes)).toBe(writer);
207
+ expect(firstAccesses).toEqual(['first', 'nullValue', 'second', 'undefinedValue', 'third']);
208
+ expect(float64Column(buffer, 'first')[0]).toBe(1);
209
+ expect(arrayColumn(buffer, 'second')[0]).toBe('second-0');
210
+ expect((uint8Column(buffer, 'third')[0] & 0b0000_0001) !== 0).toBe(true);
211
+ expect(buffer.getColumnIfAllocated('nullValue')).toBeUndefined();
212
+ expect(buffer.getColumnIfAllocated('undefinedValue')).toBeUndefined();
213
+ });
214
+ });
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { DEFAULT_BUFFER_CAPACITY } from '@smoothbricks/arrow-builder';
9
- import { createSpanLogger, type SpanLoggerImpl } from '../codegen/spanLoggerGenerator.js';
9
+ import type { SpanLoggerImpl } from '../codegen/spanLoggerGenerator.js';
10
10
  import { defineOpContext } from '../defineOpContext.js';
11
11
  import { JsBufferStrategy } from '../JsBufferStrategy.js';
12
12
  import { createOpMetadata, DEFAULT_METADATA } from '../opContext/defineOp.js';
@@ -20,10 +20,19 @@ import type {
20
20
  } from '../opContext/opGroupTypes.js';
21
21
  import type { OpMetadata } from '../opContext/opTypes.js';
22
22
  import type { OpContext } from '../opContext/types.js';
23
+ import { type CallsitePlan, getPhysicalLayoutPlan, sealCallsitePlan } from '../physicalLayoutPlan.js';
24
+ import {
25
+ RUNTIME_HINT_ANALYZED_VALID,
26
+ RUNTIME_HINT_FULL_CAPABILITIES,
27
+ RUNTIME_HINT_MESSAGE_LAYOUT_DYNAMIC_ONLY,
28
+ RUNTIME_HINT_MESSAGE_LAYOUT_MIXED,
29
+ RUNTIME_HINT_MESSAGE_LAYOUT_STATIC_ONLY,
30
+ } from '../runtimeHint.js';
23
31
  import { LogSchema } from '../schema/LogSchema.js';
24
32
  import { mergeWithSystemSchema, type SystemSchemaFieldTypes } from '../schema/systemSchema.js';
25
33
  import type { SchemaFields } from '../schema/types.js';
26
- import { createSpanBuffer } from '../spanBuffer.js';
34
+ import { createSpanBuffer, getSpanBufferClass } from '../spanBuffer.js';
35
+ import { createSpanContextClass } from '../spanContext.js';
27
36
  import { createTraceId, type TraceId } from '../traceId.js';
28
37
  import type { ITraceRoot, TracerLifecycleHooks } from '../traceRoot.js';
29
38
  import { createTraceRoot } from '../traceRoot.node.js';
@@ -107,7 +116,11 @@ export function createTestTracerOptions<T extends LogSchema>(): TracerOptions<T>
107
116
  * Shared TestTracer instance for tests that create buffers directly.
108
117
  * Typed as TracerLifecycleHooks because that's what TraceRoot expects.
109
118
  */
110
- export const TEST_TRACER: TracerLifecycleHooks = new TestTracer(minimalOpContext, createTestTracerOptions());
119
+ type MinimalLogSchema = (typeof minimalOpContext)['logBinding']['logSchema'];
120
+ export const TEST_TRACER: TracerLifecycleHooks<MinimalLogSchema> = new TestTracer(
121
+ minimalOpContext,
122
+ createTestTracerOptions(),
123
+ );
111
124
 
112
125
  type TestSpanBufferBundle<T extends SchemaFields> = {
113
126
  logBinding: LogBinding;
@@ -180,10 +193,7 @@ export function createTestLogBinding<T extends SchemaFields>(schema: T | LogSche
180
193
  // Wrap in LogSchema if plain SchemaFields provided
181
194
  const logSchema = schema instanceof LogSchema ? schema : createTestSchema(schema);
182
195
 
183
- return {
184
- logSchema,
185
- remappedViewClass: undefined,
186
- };
196
+ return { logSchema };
187
197
  }
188
198
 
189
199
  /**
@@ -237,6 +247,48 @@ export function createTestSpanBuffer<T extends SchemaFields>(
237
247
  return { logBinding, spanBuffer };
238
248
  }
239
249
 
250
+ let testWriterContextPlanId = 0;
251
+
252
+ type TestWriterOpContext<T extends SchemaFields> = OpContext<
253
+ LogSchema<T>,
254
+ Record<string, never>,
255
+ Record<string, never>,
256
+ Record<string, never>
257
+ >;
258
+
259
+ /** Create a real capability-complete SpanContext around an existing test buffer. */
260
+ export function createTestSpanContext<
261
+ T extends SchemaFields,
262
+ Ctx extends OpContext<LogSchema<T>> = TestWriterOpContext<T>,
263
+ >(schema: LogSchema<T>, buffer: SpanBuffer<LogSchema<T>>, callsitePlan?: CallsitePlan<LogSchema<T>, Ctx>) {
264
+ const messageLayoutHint =
265
+ buffer._messageLayoutFamily === 'static-only'
266
+ ? RUNTIME_HINT_MESSAGE_LAYOUT_STATIC_ONLY
267
+ : buffer._messageLayoutFamily === 'dynamic-only'
268
+ ? RUNTIME_HINT_MESSAGE_LAYOUT_DYNAMIC_ONLY
269
+ : RUNTIME_HINT_MESSAGE_LAYOUT_MIXED;
270
+ const runtimeHint =
271
+ RUNTIME_HINT_ANALYZED_VALID | RUNTIME_HINT_FULL_CAPABILITIES | messageLayoutHint | buffer._capacity;
272
+ const resolvedPlan =
273
+ callsitePlan ??
274
+ sealCallsitePlan(
275
+ getPhysicalLayoutPlan(
276
+ getSpanBufferClass(schema),
277
+ runtimeHint,
278
+ createSpanContextClass<Ctx>(
279
+ schema,
280
+ { logSchema: schema, remapDescriptor: undefined },
281
+ RUNTIME_HINT_FULL_CAPABILITIES,
282
+ ),
283
+ undefined,
284
+ 'strategy-selected',
285
+ `test-writer-context:${testWriterContextPlanId++}`,
286
+ ),
287
+ DEFAULT_METADATA,
288
+ );
289
+ resolvedPlan.appenders.writeSpanStart(buffer, 'test-writer-context');
290
+ return new resolvedPlan.SpanContextClass(buffer, schema, resolvedPlan);
291
+ }
240
292
  /**
241
293
  * Create a properly typed SpanLogger for testing.
242
294
  *
@@ -246,12 +298,15 @@ export function createTestSpanBuffer<T extends SchemaFields>(
246
298
  * @param schema - LogSchema to use
247
299
  * @returns Object with buffer and logger, both properly typed
248
300
  */
249
- export function createTestLogger<T extends LogSchema>(schema: T): TestLoggerBundle<T> {
250
- const logBinding = createTestLogBinding(schema);
301
+ export function createTestLogger<T extends SchemaFields>(
302
+ schema: LogSchema<T>,
303
+ ): TestLoggerBundle<LogSchema<SystemSchemaFieldTypes & T>> {
304
+ const runtimeSchema = createTestSchema(schema.fields);
305
+ const logBinding = createTestLogBinding(runtimeSchema);
251
306
  const traceRoot = createTestTraceRoot();
252
- const buffer = createSpanBuffer(schema, traceRoot, DEFAULT_METADATA);
253
- const logger = createSpanLogger(schema, buffer);
254
- return { buffer, logger, logBinding };
307
+ const buffer = createSpanBuffer(runtimeSchema, traceRoot, DEFAULT_METADATA);
308
+ const context = createTestSpanContext(runtimeSchema, buffer);
309
+ return { buffer, logger: context._spanLogger, logBinding };
255
310
  }
256
311
 
257
312
  // =============================================================================
@@ -0,0 +1,62 @@
1
+ import { afterEach, describe, expect, it, spyOn } from 'bun:test';
2
+
3
+ import { _resetThreadId, copyThreadIdTo, getThreadId } from '../threadId.js';
4
+
5
+ const THREAD_ID_BYTES = Uint8Array.of(0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef);
6
+ const THREAD_ID_BIGINT = 0xefcdab8967452301n;
7
+
8
+ afterEach(() => {
9
+ _resetThreadId();
10
+ });
11
+
12
+ describe('thread ID initialization', () => {
13
+ it('initializes once and copies the singleton bytes without aliasing', () => {
14
+ const getRandomValues = spyOn(crypto, 'getRandomValues').mockImplementation((array: Uint8Array<ArrayBuffer>) => {
15
+ array.set(THREAD_ID_BYTES);
16
+ return array;
17
+ });
18
+ _resetThreadId();
19
+
20
+ try {
21
+ const firstCopy = new Uint8Array(12).fill(0xaa);
22
+
23
+ copyThreadIdTo(firstCopy, 2);
24
+ firstCopy[2] = 0;
25
+
26
+ const secondCopy = new Uint8Array(THREAD_ID_BYTES.length);
27
+ copyThreadIdTo(secondCopy, 0);
28
+
29
+ expect(getRandomValues).toHaveBeenCalledTimes(1);
30
+ expect(Array.from(firstCopy)).toEqual([0xaa, 0xaa, 0, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xaa, 0xaa]);
31
+ expect(secondCopy).toEqual(THREAD_ID_BYTES);
32
+ expect(getThreadId()).toBe(THREAD_ID_BIGINT);
33
+ } finally {
34
+ getRandomValues.mockRestore();
35
+ }
36
+ });
37
+
38
+ it('retries entropy initialization after a provider failure instead of caching zeroes', () => {
39
+ let attempts = 0;
40
+ const getRandomValues = spyOn(crypto, 'getRandomValues').mockImplementation((array: Uint8Array<ArrayBuffer>) => {
41
+ attempts++;
42
+ if (attempts === 1) throw new Error('entropy temporarily unavailable');
43
+ array.set(THREAD_ID_BYTES);
44
+ return array;
45
+ });
46
+ _resetThreadId();
47
+
48
+ try {
49
+ expect(() => getThreadId()).toThrow('entropy temporarily unavailable');
50
+
51
+ const copied = new Uint8Array(THREAD_ID_BYTES.length);
52
+ copyThreadIdTo(copied, 0);
53
+
54
+ expect(getRandomValues).toHaveBeenCalledTimes(2);
55
+ expect(copied).toEqual(THREAD_ID_BYTES);
56
+ expect(getThreadId()).toBe(THREAD_ID_BIGINT);
57
+ expect(getThreadId()).not.toBe(0n);
58
+ } finally {
59
+ getRandomValues.mockRestore();
60
+ }
61
+ });
62
+ });