@smoothbricks/lmao 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/dist/allocator.wasm +0 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/lib/JsBufferStrategy.d.ts +4 -3
  6. package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
  7. package/dist/lib/JsBufferStrategy.js +18 -11
  8. package/dist/lib/arrow/lease.d.ts +10 -0
  9. package/dist/lib/arrow/lease.d.ts.map +1 -0
  10. package/dist/lib/arrow/lease.js +33 -0
  11. package/dist/lib/arrow/utils.d.ts +3 -4
  12. package/dist/lib/arrow/utils.d.ts.map +1 -1
  13. package/dist/lib/arrow/utils.js +12 -13
  14. package/dist/lib/arrow/vocabularyDictionary.d.ts +21 -0
  15. package/dist/lib/arrow/vocabularyDictionary.d.ts.map +1 -0
  16. package/dist/lib/arrow/vocabularyDictionary.js +95 -0
  17. package/dist/lib/bufferStrategy.d.ts +3 -2
  18. package/dist/lib/bufferStrategy.d.ts.map +1 -1
  19. package/dist/lib/cloudflare/traceRows.d.ts.map +1 -1
  20. package/dist/lib/cloudflare/traceRows.js +3 -2
  21. package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
  22. package/dist/lib/codegen/evaluatorGenerator.js +12 -11
  23. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +44 -82
  24. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
  25. package/dist/lib/codegen/fixedPositionWriterGenerator.js +223 -162
  26. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts +63 -0
  27. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts.map +1 -0
  28. package/dist/lib/codegen/spanLoggerClosureMaterializer.js +447 -0
  29. package/dist/lib/codegen/spanLoggerGenerator.d.ts +36 -19
  30. package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
  31. package/dist/lib/codegen/spanLoggerGenerator.js +164 -158
  32. package/dist/lib/convertToArrow.d.ts +7 -2
  33. package/dist/lib/convertToArrow.d.ts.map +1 -1
  34. package/dist/lib/convertToArrow.js +499 -285
  35. package/dist/lib/defineOpContext.js +1 -1
  36. package/dist/lib/enumMetadata.d.ts +19 -0
  37. package/dist/lib/enumMetadata.d.ts.map +1 -0
  38. package/dist/lib/enumMetadata.js +86 -0
  39. package/dist/lib/flushScheduler.d.ts.map +1 -1
  40. package/dist/lib/flushScheduler.js +13 -4
  41. package/dist/lib/library.d.ts +16 -98
  42. package/dist/lib/library.d.ts.map +1 -1
  43. package/dist/lib/library.js +32 -525
  44. package/dist/lib/logBinding.d.ts +21 -27
  45. package/dist/lib/logBinding.d.ts.map +1 -1
  46. package/dist/lib/op.d.ts +30 -30
  47. package/dist/lib/op.d.ts.map +1 -1
  48. package/dist/lib/op.js +15 -22
  49. package/dist/lib/opContext/createOpGroup.d.ts +1 -1
  50. package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
  51. package/dist/lib/opContext/createOpGroup.js +22 -29
  52. package/dist/lib/opContext/defineOp.d.ts +4 -4
  53. package/dist/lib/opContext/defineOp.d.ts.map +1 -1
  54. package/dist/lib/opContext/defineOp.js +53 -10
  55. package/dist/lib/opContext/opGroupTypes.d.ts +2 -2
  56. package/dist/lib/opContext/opTypes.d.ts +1 -1
  57. package/dist/lib/opContext/opTypes.d.ts.map +1 -1
  58. package/dist/lib/opContext/spanContextTypes.d.ts +29 -14
  59. package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -1
  60. package/dist/lib/opContext/types.d.ts +4 -4
  61. package/dist/lib/opContext/types.d.ts.map +1 -1
  62. package/dist/lib/physicalLayoutPlan.d.ts +89 -0
  63. package/dist/lib/physicalLayoutPlan.d.ts.map +1 -0
  64. package/dist/lib/physicalLayoutPlan.js +442 -0
  65. package/dist/lib/resolveMessage.d.ts +9 -0
  66. package/dist/lib/resolveMessage.d.ts.map +1 -0
  67. package/dist/lib/resolveMessage.js +63 -0
  68. package/dist/lib/result.d.ts +5 -7
  69. package/dist/lib/result.d.ts.map +1 -1
  70. package/dist/lib/result.js +19 -26
  71. package/dist/lib/runtimeHint.d.ts +35 -0
  72. package/dist/lib/runtimeHint.d.ts.map +1 -0
  73. package/dist/lib/runtimeHint.js +79 -0
  74. package/dist/lib/schema/types.d.ts +1 -1
  75. package/dist/lib/schema/types.d.ts.map +1 -1
  76. package/dist/lib/span-buffer/aot/v1.d.ts +2 -0
  77. package/dist/lib/span-buffer/aot/v1.d.ts.map +1 -0
  78. package/dist/lib/span-buffer/aot/v1.js +24 -0
  79. package/dist/lib/spanBuffer.d.ts +33 -4
  80. package/dist/lib/spanBuffer.d.ts.map +1 -1
  81. package/dist/lib/spanBuffer.js +583 -91
  82. package/dist/lib/spanBufferStats.d.ts +1 -1
  83. package/dist/lib/spanBufferStats.d.ts.map +1 -1
  84. package/dist/lib/spanContext.d.ts +27 -51
  85. package/dist/lib/spanContext.d.ts.map +1 -1
  86. package/dist/lib/spanContext.js +822 -344
  87. package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
  88. package/dist/lib/sqlite/sqlite-common.js +20 -21
  89. package/dist/lib/testing/bun-harness.d.ts +8 -3
  90. package/dist/lib/testing/bun-harness.d.ts.map +1 -1
  91. package/dist/lib/testing/bun-harness.js +30 -18
  92. package/dist/lib/testing/extractFacts.d.ts +1 -1
  93. package/dist/lib/testing/extractFacts.d.ts.map +1 -1
  94. package/dist/lib/testing/extractFacts.js +55 -63
  95. package/dist/lib/testing/facts.d.ts +1 -1
  96. package/dist/lib/testing/facts.d.ts.map +1 -1
  97. package/dist/lib/testing/queryable-span.d.ts +1 -1
  98. package/dist/lib/testing/queryable-span.d.ts.map +1 -1
  99. package/dist/lib/testing/queryable-span.js +26 -28
  100. package/dist/lib/testing/span-query.d.ts.map +1 -1
  101. package/dist/lib/testing/span-query.js +19 -22
  102. package/dist/lib/testing/stdio-replay.d.ts.map +1 -1
  103. package/dist/lib/testing/stdio-replay.js +19 -8
  104. package/dist/lib/threadId.d.ts.map +1 -1
  105. package/dist/lib/threadId.js +6 -3
  106. package/dist/lib/traceRoot.d.ts +30 -8
  107. package/dist/lib/traceRoot.d.ts.map +1 -1
  108. package/dist/lib/traceRoot.es.d.ts +17 -15
  109. package/dist/lib/traceRoot.es.d.ts.map +1 -1
  110. package/dist/lib/traceRoot.es.js +68 -34
  111. package/dist/lib/traceRoot.js +11 -0
  112. package/dist/lib/traceRoot.node.d.ts +17 -19
  113. package/dist/lib/traceRoot.node.d.ts.map +1 -1
  114. package/dist/lib/traceRoot.node.js +66 -38
  115. package/dist/lib/traceTopology.d.ts +42 -0
  116. package/dist/lib/traceTopology.d.ts.map +1 -0
  117. package/dist/lib/traceTopology.js +260 -0
  118. package/dist/lib/tracer.d.ts +9 -5
  119. package/dist/lib/tracer.d.ts.map +1 -1
  120. package/dist/lib/tracer.js +65 -71
  121. package/dist/lib/tracers/ArrayQueueTracer.d.ts +1 -1
  122. package/dist/lib/tracers/ArrayQueueTracer.js +1 -1
  123. package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
  124. package/dist/lib/tracers/StdioTracer.js +15 -13
  125. package/dist/lib/tracers/TestTracer.d.ts +4 -6
  126. package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
  127. package/dist/lib/tracers/TestTracer.js +6 -8
  128. package/dist/lib/types.d.ts +49 -32
  129. package/dist/lib/types.d.ts.map +1 -1
  130. package/dist/lib/vocabularyRegistry.d.ts +25 -0
  131. package/dist/lib/vocabularyRegistry.d.ts.map +1 -0
  132. package/dist/lib/vocabularyRegistry.js +372 -0
  133. package/dist/lib/wasm/WasmBufferStrategy.d.ts +6 -10
  134. package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
  135. package/dist/lib/wasm/WasmBufferStrategy.js +44 -37
  136. package/dist/lib/wasm/wasmAllocator.d.ts +27 -22
  137. package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
  138. package/dist/lib/wasm/wasmAllocator.js +66 -44
  139. package/dist/lib/wasm/wasmPhysicalLayout.d.ts +67 -0
  140. package/dist/lib/wasm/wasmPhysicalLayout.d.ts.map +1 -0
  141. package/dist/lib/wasm/wasmPhysicalLayout.js +179 -0
  142. package/dist/lib/wasm/wasmSpanBuffer.d.ts +79 -31
  143. package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
  144. package/dist/lib/wasm/wasmSpanBuffer.js +442 -272
  145. package/dist/lib/wasm/wasmTraceRoot.d.ts +24 -22
  146. package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
  147. package/dist/lib/wasm/wasmTraceRoot.js +110 -71
  148. package/dist/vocabulary/register/v1.d.ts +2 -0
  149. package/dist/vocabulary/register/v1.d.ts.map +1 -0
  150. package/dist/vocabulary/register/v1.js +1 -0
  151. package/dist/wasm.d.ts +5 -0
  152. package/dist/wasm.d.ts.map +1 -0
  153. package/dist/wasm.js +4 -0
  154. package/package.json +54 -6
  155. package/src/index.ts +1 -0
  156. package/src/lib/JsBufferStrategy.ts +27 -9
  157. package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +335 -37
  158. package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +97 -26
  159. package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +75 -15
  160. package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +30 -6
  161. package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +18 -21
  162. package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +5 -2
  163. package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +25 -7
  164. package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +3 -2
  165. package/src/lib/__tests__/buffer-overflow.test.ts +24 -18
  166. package/src/lib/__tests__/capability-span-context.test.ts +505 -0
  167. package/src/lib/__tests__/capacity-tuning.test.ts +5 -3
  168. package/src/lib/__tests__/eager-columns.test.ts +345 -0
  169. package/src/lib/__tests__/enum-metadata-aot.test.ts +153 -0
  170. package/src/lib/__tests__/enum-metadata.test.ts +177 -0
  171. package/src/lib/__tests__/fixtures/empty-vocabulary-runtime.fixture.ts +15 -0
  172. package/src/lib/__tests__/flushScheduler.test.ts +5 -1
  173. package/src/lib/__tests__/identity-view.property.test.ts +179 -0
  174. package/src/lib/__tests__/library.test.ts +19 -235
  175. package/src/lib/__tests__/message-buffer-families.test.ts +878 -0
  176. package/src/lib/__tests__/nested-library-tasks.test.ts +14 -15
  177. package/src/lib/__tests__/op-metadata.test.ts +1 -1
  178. package/src/lib/__tests__/op-type-safety.test.ts +5 -16
  179. package/src/lib/__tests__/physical-layout-plan.test.ts +333 -0
  180. package/src/lib/__tests__/remap-descriptor-integration.test.ts +381 -0
  181. package/src/lib/__tests__/root-context-construction.test.ts +414 -0
  182. package/src/lib/__tests__/span-auto-runtime.test.ts +386 -0
  183. package/src/lib/__tests__/span-buffer-segment-stats.test.ts +221 -0
  184. package/src/lib/__tests__/span-lifecycle.test.ts +53 -25
  185. package/src/lib/__tests__/spanbuffer-materializer-parity.test.ts +266 -0
  186. package/src/lib/__tests__/sync-async-trace.test.ts +24 -23
  187. package/src/lib/__tests__/tag-writer-aot.test.ts +214 -0
  188. package/src/lib/__tests__/test-helpers.ts +67 -12
  189. package/src/lib/__tests__/threadId.test.ts +62 -0
  190. package/src/lib/__tests__/timestamp.test.ts +221 -93
  191. package/src/lib/__tests__/traceTopology.property.test.ts +383 -0
  192. package/src/lib/__tests__/type-narrowing.test.ts +63 -0
  193. package/src/lib/__tests__/vocabulary-dense-decoding.test.ts +405 -0
  194. package/src/lib/__tests__/vocabularyRegistry.test.ts +313 -0
  195. package/src/lib/arrow/lease.ts +43 -0
  196. package/src/lib/arrow/utils.ts +10 -14
  197. package/src/lib/arrow/vocabularyDictionary.ts +123 -0
  198. package/src/lib/bufferStrategy.ts +9 -1
  199. package/src/lib/cloudflare/traceRows.ts +3 -2
  200. package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +21 -141
  201. package/src/lib/codegen/__tests__/fixedPositionWriter-parity.test.ts +273 -0
  202. package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +61 -34
  203. package/src/lib/codegen/__tests__/nullBitmap.test.ts +33 -37
  204. package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +34 -18
  205. package/src/lib/codegen/__tests__/spanLoggerMaterializerParity.test.ts +503 -0
  206. package/src/lib/codegen/evaluatorGenerator.ts +18 -13
  207. package/src/lib/codegen/fixedPositionWriterGenerator.ts +329 -245
  208. package/src/lib/codegen/spanLoggerClosureMaterializer.ts +598 -0
  209. package/src/lib/codegen/spanLoggerGenerator.ts +241 -177
  210. package/src/lib/convertToArrow.ts +598 -311
  211. package/src/lib/defineOpContext.ts +1 -1
  212. package/src/lib/enumMetadata.ts +121 -0
  213. package/src/lib/flushScheduler.ts +11 -5
  214. package/src/lib/library.ts +37 -595
  215. package/src/lib/logBinding.ts +21 -27
  216. package/src/lib/op.ts +75 -18
  217. package/src/lib/opContext/__tests__/retry.test.ts +27 -21
  218. package/src/lib/opContext/createOpGroup.ts +33 -31
  219. package/src/lib/opContext/defineOp.ts +88 -11
  220. package/src/lib/opContext/opGroupTypes.ts +2 -2
  221. package/src/lib/opContext/opTypes.ts +1 -1
  222. package/src/lib/opContext/spanContextTypes.ts +98 -17
  223. package/src/lib/opContext/types.ts +7 -3
  224. package/src/lib/physicalLayoutPlan.ts +598 -0
  225. package/src/lib/resolveMessage.ts +67 -0
  226. package/src/lib/result.ts +20 -33
  227. package/src/lib/runtimeHint.ts +98 -0
  228. package/src/lib/schema/__tests__/featureFlags.test.ts +2 -1
  229. package/src/lib/schema/builder.ts +1 -1
  230. package/src/lib/schema/types.ts +1 -1
  231. package/src/lib/span-buffer/aot/v1.ts +26 -0
  232. package/src/lib/spanBuffer.ts +658 -92
  233. package/src/lib/spanBufferStats.ts +1 -1
  234. package/src/lib/spanContext.ts +1350 -861
  235. package/src/lib/sqlite/sqlite-common.ts +20 -31
  236. package/src/lib/testing/__tests__/topology-traversal.test.ts +174 -0
  237. package/src/lib/testing/__tests__/vitest-harness.test.ts +2 -1
  238. package/src/lib/testing/bun-harness.ts +94 -43
  239. package/src/lib/testing/extractFacts.ts +64 -78
  240. package/src/lib/testing/facts.ts +1 -1
  241. package/src/lib/testing/queryable-span.ts +23 -30
  242. package/src/lib/testing/span-query.ts +16 -20
  243. package/src/lib/testing/stdio-replay.ts +25 -8
  244. package/src/lib/testing/vitest-harness.ts +1 -1
  245. package/src/lib/threadId.ts +6 -3
  246. package/src/lib/traceRoot.es.ts +77 -42
  247. package/src/lib/traceRoot.node.ts +75 -46
  248. package/src/lib/traceRoot.ts +41 -14
  249. package/src/lib/traceTopology.ts +279 -0
  250. package/src/lib/tracer.ts +109 -98
  251. package/src/lib/tracers/ArrayQueueTracer.ts +1 -1
  252. package/src/lib/tracers/StdioTracer.ts +15 -13
  253. package/src/lib/tracers/TestTracer.ts +6 -8
  254. package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +15 -10
  255. package/src/lib/tracers/__tests__/TestTracer.test.ts +23 -13
  256. package/src/lib/types.ts +64 -33
  257. package/src/lib/vocabularyRegistry.ts +439 -0
  258. package/src/lib/wasm/WasmBufferStrategy.ts +56 -48
  259. package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +215 -11
  260. package/src/lib/wasm/__tests__/allocatorFreeBlockClamp.test.ts +86 -0
  261. package/src/lib/wasm/__tests__/wasm-identity-view.test.ts +311 -0
  262. package/src/lib/wasm/__tests__/wasm-integration.test.ts +417 -44
  263. package/src/lib/wasm/__tests__/wasm-message-buffer-families.test.ts +588 -0
  264. package/src/lib/wasm/__tests__/wasmAllocator.test.ts +100 -668
  265. package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +419 -63
  266. package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +24 -29
  267. package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +2 -2
  268. package/src/lib/wasm/wasmAllocator.ts +131 -96
  269. package/src/lib/wasm/wasmPhysicalLayout.ts +309 -0
  270. package/src/lib/wasm/wasmSpanBuffer.ts +597 -341
  271. package/src/lib/wasm/wasmTraceRoot.ts +140 -78
  272. package/src/vocabulary/register/v1.ts +1 -0
  273. package/src/wasm.ts +19 -0
  274. package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +0 -319
  275. package/src/lib/__tests__/remapped-buffer-view.test.ts +0 -635
  276. package/src/lib/wasm/allocator.zig +0 -948
@@ -0,0 +1,15 @@
1
+ import { getVocabularyDictionaryPrefix } from '../../arrow/vocabularyDictionary.js';
2
+ import { getVocabularyGeneration } from '../../vocabularyRegistry.js';
3
+
4
+ const generation = getVocabularyGeneration();
5
+ const prefix = getVocabularyDictionaryPrefix(generation);
6
+
7
+ console.log(
8
+ JSON.stringify({
9
+ generation: generation.generation,
10
+ ids: Array.from(generation.ids),
11
+ prefixLength: prefix.length,
12
+ prefixValues: Array.from(prefix.column),
13
+ emptyDenseIndex: prefix.valueToDenseIndex.get(''),
14
+ }),
15
+ );
@@ -23,7 +23,11 @@ function createTestBuffer(): AnySpanBuffer {
23
23
  buffer._writeIndex = 5;
24
24
  for (let i = 0; i < buffer._writeIndex; i++) {
25
25
  buffer.timestamp[i] = BigInt(Date.now()) * 1_000_000n;
26
- buffer.entry_type[i] = 1;
26
+ {
27
+ const entryTypes = buffer.entry_type;
28
+ if (entryTypes === undefined) throw new Error('Expected split entry-type lane');
29
+ entryTypes[i] = 1;
30
+ }
27
31
  }
28
32
  return buffer;
29
33
  }
@@ -0,0 +1,179 @@
1
+ import { describe, expect, it, spyOn } from 'bun:test';
2
+ import fc from 'fast-check';
3
+ import { JsBufferStrategy } from '../JsBufferStrategy.js';
4
+ import { createTraceId } from '../traceId.js';
5
+ import type { AnySpanBuffer } from '../types.js';
6
+ import { createTestOpMetadata, createTestSchema, createTestTraceRoot } from './test-helpers.js';
7
+
8
+ const schema = createTestSchema({});
9
+ const metadata = createTestOpMetadata({ name: 'identity-view', line: 14 });
10
+ const encoder = new TextEncoder();
11
+
12
+ function exactBytes(bytes: Uint8Array): number[] {
13
+ return Array.from(bytes);
14
+ }
15
+
16
+ function expectJsIdentity(buffer: AnySpanBuffer, parent: AnySpanBuffer | undefined, traceBytes: Uint8Array): void {
17
+ const identity = buffer._identity;
18
+ const view = new DataView(identity.buffer, identity.byteOffset, identity.byteLength);
19
+
20
+ expect(view.getBigUint64(0, true)).toBe(buffer.thread_id);
21
+ expect(view.getUint32(8, true)).toBe(buffer.span_id);
22
+ if (parent === undefined) {
23
+ expect(identity.byteLength).toBe(13 + traceBytes.byteLength);
24
+ expect(identity[12]).toBe(traceBytes.byteLength);
25
+ expect(exactBytes(identity.subarray(13))).toEqual(exactBytes(traceBytes));
26
+ expect(buffer.parent_thread_id).toBe(0n);
27
+ expect(buffer.parent_span_id).toBe(0);
28
+ expect(buffer._hasParent).toBe(false);
29
+ } else {
30
+ expect(identity.byteLength).toBe(12);
31
+ expect(buffer.parent_thread_id).toBe(parent.thread_id);
32
+ expect(buffer.parent_span_id).toBe(parent.span_id);
33
+ expect(buffer._hasParent).toBe(true);
34
+ }
35
+ }
36
+
37
+ function printableTraceIdArbitrary() {
38
+ return fc
39
+ .array(fc.integer({ min: 0x20, max: 0x7e }), { minLength: 1, maxLength: 128 })
40
+ .map((codes) => String.fromCharCode(...codes));
41
+ }
42
+
43
+ describe('JavaScript span identity views', () => {
44
+ it('uses stable trace bytes and performs no DataView allocation or UTF-8 decode during identity access', () => {
45
+ const strategy = new JsBufferStrategy<typeof schema>();
46
+ const incoming = createTraceId('0af7651916cd43dd8448eb211c80319c');
47
+ const traceRoot = createTestTraceRoot(incoming);
48
+ const root = strategy.createSpanBuffer(schema, traceRoot, metadata, 8);
49
+ const child = strategy.createChildSpanBuffer(root, metadata, metadata, 8);
50
+ const overflow = strategy.createOverflowBuffer(child);
51
+ const traceBytes = traceRoot._traceIdBytes;
52
+
53
+ expect(traceRoot.trace_id).toBe(incoming);
54
+ expect(traceRoot._traceIdBytes).toBe(traceBytes);
55
+ expect(exactBytes(traceBytes)).toEqual(exactBytes(encoder.encode(incoming)));
56
+ expect(root._identity).not.toBe(child._identity);
57
+ expect(overflow._identity).toBe(child._identity);
58
+ expect(root._traceRoot._traceIdBytes).toBe(traceBytes);
59
+ expect(child._traceRoot._traceIdBytes).toBe(traceBytes);
60
+ expect(overflow._traceRoot._traceIdBytes).toBe(traceBytes);
61
+
62
+ const originalDataView = globalThis.DataView;
63
+ const dataViewDescriptor = Object.getOwnPropertyDescriptor(globalThis, 'DataView');
64
+ if (dataViewDescriptor === undefined) throw new Error('global DataView descriptor is unavailable');
65
+ let dataViewAllocations = 0;
66
+ const CountingDataView = new Proxy(originalDataView, {
67
+ construct(target, argumentsList, newTarget) {
68
+ dataViewAllocations++;
69
+ return Reflect.construct(target, argumentsList, newTarget);
70
+ },
71
+ });
72
+ const decode = spyOn(TextDecoder.prototype, 'decode');
73
+ decode.mockClear();
74
+ Object.defineProperty(globalThis, 'DataView', { ...dataViewDescriptor, value: CountingDataView });
75
+ const copiedThreadIds = new Uint8Array(32);
76
+
77
+ try {
78
+ for (let iteration = 0; iteration < 20; iteration++) {
79
+ void root.span_id;
80
+ void root.thread_id;
81
+ void root.trace_id;
82
+ void child.span_id;
83
+ void child.thread_id;
84
+ void child.trace_id;
85
+ void child.parent_span_id;
86
+ void child.parent_thread_id;
87
+ void overflow.span_id;
88
+ void overflow.thread_id;
89
+ void overflow.trace_id;
90
+ void overflow.parent_span_id;
91
+ void overflow.parent_thread_id;
92
+ }
93
+ root.copyThreadIdTo(copiedThreadIds, 3);
94
+ child.copyParentThreadIdTo(copiedThreadIds, 19);
95
+
96
+ expect(dataViewAllocations).toBe(0);
97
+ expect(decode).toHaveBeenCalledTimes(0);
98
+ } finally {
99
+ Object.defineProperty(globalThis, 'DataView', dataViewDescriptor);
100
+ decode.mockRestore();
101
+ }
102
+
103
+ const copied = new DataView(copiedThreadIds.buffer);
104
+ expect(copied.getBigUint64(3, true)).toBe(root.thread_id);
105
+ expect(copied.getBigUint64(19, true)).toBe(root.thread_id);
106
+ });
107
+
108
+ it('preserves exact root, child, and overflow identity bytes for randomized span trees and release generations', () => {
109
+ fc.assert(
110
+ fc.property(
111
+ printableTraceIdArbitrary(),
112
+ fc.integer({ min: 0, max: 3 }),
113
+ fc.array(
114
+ fc.record({
115
+ parentSelector: fc.nat(),
116
+ overflowCount: fc.integer({ min: 0, max: 3 }),
117
+ }),
118
+ { minLength: 1, maxLength: 36 },
119
+ ),
120
+ (traceIdValue, rootOverflowCount, nodes) => {
121
+ const strategy = new JsBufferStrategy<typeof schema>();
122
+ const incoming = createTraceId(traceIdValue);
123
+ const traceRoot = createTestTraceRoot(incoming);
124
+ const root = strategy.createSpanBuffer(schema, traceRoot, metadata, 8);
125
+ const logicalSpans = [root];
126
+ const traceBytes = traceRoot._traceIdBytes;
127
+ const encodedTraceId = encoder.encode(incoming);
128
+
129
+ expect(traceRoot.trace_id).toBe(incoming);
130
+ expect(traceRoot._traceIdBytes).toBe(traceBytes);
131
+ expect(exactBytes(traceBytes)).toEqual(exactBytes(encodedTraceId));
132
+ expectJsIdentity(root, undefined, encodedTraceId);
133
+
134
+ let rootOverflowOwner = root;
135
+ for (let index = 0; index < rootOverflowCount; index++) {
136
+ const overflow = strategy.createOverflowBuffer(rootOverflowOwner);
137
+ expect(overflow._identity).toBe(root._identity);
138
+ expect(overflow._traceRoot._traceIdBytes).toBe(traceBytes);
139
+ expect(overflow.trace_id).toBe(incoming);
140
+ expect(overflow.span_id).toBe(root.span_id);
141
+ rootOverflowOwner = overflow;
142
+ }
143
+
144
+ for (const node of nodes) {
145
+ const parent = logicalSpans[node.parentSelector % logicalSpans.length];
146
+ if (parent === undefined) throw new Error('randomized parent selection failed');
147
+ const child = strategy.createChildSpanBuffer(parent, metadata, metadata, 8);
148
+ logicalSpans.push(child);
149
+
150
+ expect(child._identity).not.toBe(parent._identity);
151
+ expect(child._traceRoot._traceIdBytes).toBe(traceBytes);
152
+ expect(child.trace_id).toBe(incoming);
153
+ expectJsIdentity(child, parent, encodedTraceId);
154
+
155
+ let overflowOwner = child;
156
+ for (let index = 0; index < node.overflowCount; index++) {
157
+ const overflow = strategy.createOverflowBuffer(overflowOwner);
158
+ expect(overflow._identity).toBe(child._identity);
159
+ expect(overflow._traceRoot._traceIdBytes).toBe(traceBytes);
160
+ expect(overflow.trace_id).toBe(incoming);
161
+ expect(overflow.span_id).toBe(child.span_id);
162
+ expect(overflow.parent_span_id).toBe(parent.span_id);
163
+ expect(overflow.parent_thread_id).toBe(parent.thread_id);
164
+ overflowOwner = overflow;
165
+ }
166
+ }
167
+
168
+ const topology = traceRoot._topology;
169
+ const generation = topology.generation;
170
+ strategy.releaseBuffer(root);
171
+ expect(topology.generation).toBe(generation + 1);
172
+ expect(traceRoot._traceIdBytes).toBe(traceBytes);
173
+ expect(exactBytes(traceBytes)).toEqual(exactBytes(encodedTraceId));
174
+ },
175
+ ),
176
+ { numRuns: 60 },
177
+ );
178
+ });
179
+ });
@@ -6,7 +6,7 @@
6
6
  * - Prefix application for library composition
7
7
  * - Dependency wiring with .use()
8
8
  * - Clean API with prefixed column storage
9
- * - RemappedBufferView for Arrow conversion
9
+ * - Immutable remap descriptors for Arrow conversion
10
10
  * - Collision detection and type safety
11
11
  * - Library composition scenarios
12
12
  * - End-to-end integration verification
@@ -14,17 +14,10 @@
14
14
 
15
15
  import { describe, expect, it } from 'bun:test';
16
16
  import { defineOpContext } from '../defineOpContext.js';
17
- import {
18
- createPrefixMapping,
19
- createRemappedSpanLoggerClass,
20
- generateRemappedBufferViewClass,
21
- generateRemappedSpanLoggerClass,
22
- type PrefixMapping,
23
- prefixSchema,
24
- } from '../library.js';
17
+ import { createPrefixMapping, createRemapDescriptor, prefixSchema } from '../library.js';
25
18
  import { S } from '../schema/builder.js';
26
19
  import { defineLogSchema } from '../schema/defineLogSchema.js';
27
- import { createBuffer, getMappedOpGroupInternals, getOpGroupInternals } from './test-helpers.js';
20
+ import { getMappedOpGroupInternals, getOpGroupInternals } from './test-helpers.js';
28
21
 
29
22
  describe('Library Integration Pattern', () => {
30
23
  describe('Schema Prefixing', () => {
@@ -132,216 +125,30 @@ describe('Library Integration Pattern', () => {
132
125
  });
133
126
  });
134
127
 
135
- describe('RemappedBufferView Generation', () => {
136
- it('should generate valid RemappedBufferView class', () => {
137
- const mapping: Record<string, string> = {
138
- http_status: 'status',
139
- http_method: 'method',
140
- };
141
-
142
- const ViewClass = generateRemappedBufferViewClass(mapping);
143
-
144
- // Should create a callable constructor
145
- expect(typeof ViewClass).toBe('function');
146
-
147
- // Should cache same mapping
148
- const ViewClass2 = generateRemappedBufferViewClass(mapping);
149
- expect(ViewClass).toBe(ViewClass2); // Same cached instance
150
- });
151
-
152
- it('should handle empty prefix mapping', () => {
153
- const mapping: Record<string, string> = {};
154
- const ViewClass = generateRemappedBufferViewClass(mapping);
155
-
156
- expect(typeof ViewClass).toBe('function');
157
- });
158
-
159
- it('should handle single field mapping', () => {
160
- const mapping: Record<string, string> = {
161
- http_status: 'status',
162
- };
163
- const ViewClass = generateRemappedBufferViewClass(mapping);
164
-
165
- expect(typeof ViewClass).toBe('function');
166
- });
167
-
168
- it('should correctly map column access from prefixed to unprefixed', () => {
169
- const mapping: Record<string, string> = {
170
- http_status: 'status',
171
- http_method: 'method',
172
- };
173
-
174
- const ViewClass = generateRemappedBufferViewClass(mapping);
175
-
176
- const mockBuffer = createBuffer(
177
- defineLogSchema({
178
- status: S.number(),
179
- method: S.category(),
180
- }),
181
- );
182
- mockBuffer.status(0, 200);
183
- mockBuffer._writeIndex = 1;
184
-
185
- const mockValues = mockBuffer.getColumnIfAllocated('status');
186
- const mockNulls = mockBuffer.getNullsIfAllocated('status');
187
-
188
- const view = new ViewClass(mockBuffer);
189
-
190
- // Should map prefixed to unprefixed
191
- expect(view.getColumnIfAllocated('http_status')).toBe(mockValues);
192
- expect(view.getNullsIfAllocated('http_status')).toBe(mockNulls);
193
-
194
- // Should pass through unknown names
195
- expect(view.getColumnIfAllocated('unknown')).toBeUndefined();
196
- expect(view.getNullsIfAllocated('unknown')).toBeUndefined();
197
- });
198
- });
199
-
200
- describe('RemappedSpanLogger Generation', () => {
201
- it('should generate valid JavaScript code', () => {
128
+ describe('Remap descriptor metadata', () => {
129
+ it('preserves composed output order and schema identity in immutable cold-path metadata', () => {
202
130
  const schema = defineLogSchema({
203
131
  status: S.number(),
204
132
  method: S.enum(['GET', 'POST']),
205
133
  });
206
- const mapping: PrefixMapping = {
207
- status: 'http_status',
208
- method: 'http_method',
209
- };
210
-
211
- const code = generateRemappedSpanLoggerClass(schema, mapping);
212
-
213
- // Should be valid JavaScript
214
- expect(() => new Function(`return ${code}`)()).not.toThrow();
215
- });
216
-
217
- it('should generate class with clean method names', () => {
218
- const schema = defineLogSchema({
219
- status: S.number(),
220
- duration: S.number(),
221
- });
222
- const mapping: PrefixMapping = {
223
- status: 'http_status',
224
- duration: 'http_duration',
225
- };
226
-
227
- const code = generateRemappedSpanLoggerClass(schema, mapping);
228
-
229
- // Should contain clean method names
230
- expect(code).toContain('status(value)');
231
- expect(code).toContain('duration(value)');
232
- // Should reference prefixed columns
233
- expect(code).toContain('http_status');
234
- expect(code).toContain('http_duration');
235
- });
236
134
 
237
- it('should include enum mapping functions', () => {
238
- const schema = defineLogSchema({
239
- method: S.enum(['GET', 'POST', 'PUT']),
135
+ const descriptor = createRemapDescriptor(schema, {
136
+ v1_api_method: 'method',
137
+ v1_api_status: 'status',
240
138
  });
241
- const mapping: PrefixMapping = {
242
- method: 'http_method',
243
- };
244
-
245
- const code = generateRemappedSpanLoggerClass(schema, mapping);
246
139
 
247
- // Should contain enum mapping function
248
- expect(code).toContain('getEnumIndex_method');
249
- expect(code).toContain('case "GET"');
250
- expect(code).toContain('case "POST"');
251
- expect(code).toContain('case "PUT"');
252
- });
253
-
254
- it('should include prefix mapping for with() method', () => {
255
- const schema = defineLogSchema({
256
- status: S.number(),
140
+ expect(descriptor.sourceNames).toEqual({
141
+ v1_api_method: 'method',
142
+ v1_api_status: 'status',
257
143
  });
258
- const mapping: PrefixMapping = {
259
- status: 'http_status',
260
- };
261
-
262
- const code = generateRemappedSpanLoggerClass(schema, mapping);
263
-
264
- // Should include PREFIX_MAPPING constant
265
- expect(code).toContain('PREFIX_MAPPING');
266
- expect(code).toContain('"status":"http_status"');
267
- });
268
-
269
- it('should create a class constructor', () => {
270
- const schema = defineLogSchema({
271
- status: S.number(),
272
- });
273
- const mapping: PrefixMapping = {
274
- status: 'http_status',
275
- };
276
-
277
- const SpanLoggerClass = createRemappedSpanLoggerClass(schema, mapping);
278
-
279
- expect(typeof SpanLoggerClass).toBe('function');
280
- });
281
-
282
- it('should handle all field types in code generation', () => {
283
- const schema = defineLogSchema({
284
- enumField: S.enum(['A', 'B']),
285
- categoryField: S.category(),
286
- textField: S.text(),
287
- numberField: S.number(),
288
- booleanField: S.boolean(),
289
- });
290
-
291
- const mapping: PrefixMapping = {
292
- enumField: 'test_enumField',
293
- categoryField: 'test_categoryField',
294
- textField: 'test_textField',
295
- numberField: 'test_numberField',
296
- booleanField: 'test_booleanField',
297
- };
298
-
299
- const code = generateRemappedSpanLoggerClass(schema, mapping);
300
-
301
- // Should handle all field types appropriately
302
- expect(code).toContain('getEnumIndex_enumField'); // Enum mapping
303
- expect(code).toContain('categoryField(value)'); // Category storage
304
- expect(code).toContain('textField(value)'); // Text storage
305
- expect(code).toContain('numberField(value)'); // Number storage
306
- expect(code).toContain('booleanField(value)'); // Boolean storage
307
- });
308
-
309
- it('should cache generated classes for the same schema and mapping', () => {
310
- const schema = defineLogSchema({
311
- status: S.number(),
312
- });
313
- const mapping: PrefixMapping = {
314
- status: 'http_status',
315
- };
316
-
317
- const Class1 = createRemappedSpanLoggerClass(schema, mapping);
318
- const Class2 = createRemappedSpanLoggerClass(schema, mapping);
319
-
320
- // Same schema + mapping should return cached class
321
- expect(Class1).toBe(Class2);
322
- });
323
-
324
- it('should create different classes for different schemas', () => {
325
- const schema1 = defineLogSchema({ status: S.number() });
326
- const schema2 = defineLogSchema({ code: S.number() });
327
- const mapping1: PrefixMapping = { status: 'http_status' };
328
- const mapping2: PrefixMapping = { code: 'http_code' };
329
-
330
- const Class1 = createRemappedSpanLoggerClass(schema1, mapping1);
331
- const Class2 = createRemappedSpanLoggerClass(schema2, mapping2);
332
-
333
- expect(Class1).not.toBe(Class2);
334
- });
335
-
336
- it('should create different classes for same schema with different mappings', () => {
337
- const schema = defineLogSchema({ status: S.number() });
338
- const mapping1: PrefixMapping = { status: 'http_status' };
339
- const mapping2: PrefixMapping = { status: 'api_status' };
340
-
341
- const Class1 = createRemappedSpanLoggerClass(schema, mapping1);
342
- const Class2 = createRemappedSpanLoggerClass(schema, mapping2);
343
-
344
- expect(Class1).not.toBe(Class2);
144
+ expect(descriptor.columns).toEqual([
145
+ ['v1_api_method', 'method', schema.fields.method, 'method_values', 'method_nulls'],
146
+ ['v1_api_status', 'status', schema.fields.status, 'status_values', 'status_nulls'],
147
+ ]);
148
+ expect(Object.isFrozen(descriptor)).toBe(true);
149
+ expect(Object.isFrozen(descriptor.sourceNames)).toBe(true);
150
+ expect(Object.isFrozen(descriptor.columns)).toBe(true);
151
+ expect(descriptor.columns.every(Object.isFrozen)).toBe(true);
345
152
  });
346
153
  });
347
154
  });
@@ -908,27 +715,4 @@ describe('Edge Cases and Error Handling', () => {
908
715
  expect(prefixed).toHaveProperty('many_field99');
909
716
  });
910
717
  });
911
-
912
- describe('Buffer Remapping Edge Cases', () => {
913
- it('should handle mapping consistency', () => {
914
- // Test that mapping and code generation are consistent
915
- const schema = defineLogSchema({
916
- status: S.number(),
917
- method: S.enum(['GET', 'POST']),
918
- });
919
-
920
- const mapping = createPrefixMapping(schema, 'http');
921
- const code = generateRemappedSpanLoggerClass(schema, mapping);
922
-
923
- // Verify that the mapping referenced in code matches the generated mapping
924
- expect(code).toContain('"status":"http_status"');
925
- expect(code).toContain('"method":"http_method"');
926
-
927
- // Verify that all prefixed columns are properly referenced
928
- expect(code).toContain('http_status_values');
929
- expect(code).toContain('http_status_nulls');
930
- expect(code).toContain('http_method_values');
931
- expect(code).toContain('http_method_nulls');
932
- });
933
- });
934
718
  });