@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.
- package/dist/allocator.wasm +0 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/JsBufferStrategy.d.ts +4 -3
- package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
- package/dist/lib/JsBufferStrategy.js +18 -11
- package/dist/lib/arrow/lease.d.ts +10 -0
- package/dist/lib/arrow/lease.d.ts.map +1 -0
- package/dist/lib/arrow/lease.js +33 -0
- package/dist/lib/arrow/utils.d.ts +3 -4
- package/dist/lib/arrow/utils.d.ts.map +1 -1
- package/dist/lib/arrow/utils.js +12 -13
- package/dist/lib/arrow/vocabularyDictionary.d.ts +21 -0
- package/dist/lib/arrow/vocabularyDictionary.d.ts.map +1 -0
- package/dist/lib/arrow/vocabularyDictionary.js +95 -0
- package/dist/lib/bufferStrategy.d.ts +3 -2
- package/dist/lib/bufferStrategy.d.ts.map +1 -1
- package/dist/lib/cloudflare/traceRows.d.ts.map +1 -1
- package/dist/lib/cloudflare/traceRows.js +3 -2
- package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/evaluatorGenerator.js +12 -11
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +44 -82
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/fixedPositionWriterGenerator.js +223 -162
- package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts +63 -0
- package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts.map +1 -0
- package/dist/lib/codegen/spanLoggerClosureMaterializer.js +447 -0
- package/dist/lib/codegen/spanLoggerGenerator.d.ts +36 -19
- package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/spanLoggerGenerator.js +164 -158
- package/dist/lib/convertToArrow.d.ts +7 -2
- package/dist/lib/convertToArrow.d.ts.map +1 -1
- package/dist/lib/convertToArrow.js +499 -285
- package/dist/lib/defineOpContext.js +1 -1
- package/dist/lib/enumMetadata.d.ts +19 -0
- package/dist/lib/enumMetadata.d.ts.map +1 -0
- package/dist/lib/enumMetadata.js +86 -0
- package/dist/lib/flushScheduler.d.ts.map +1 -1
- package/dist/lib/flushScheduler.js +13 -4
- package/dist/lib/library.d.ts +16 -98
- package/dist/lib/library.d.ts.map +1 -1
- package/dist/lib/library.js +32 -525
- package/dist/lib/logBinding.d.ts +21 -27
- package/dist/lib/logBinding.d.ts.map +1 -1
- package/dist/lib/op.d.ts +30 -30
- package/dist/lib/op.d.ts.map +1 -1
- package/dist/lib/op.js +15 -22
- package/dist/lib/opContext/createOpGroup.d.ts +1 -1
- package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
- package/dist/lib/opContext/createOpGroup.js +22 -29
- package/dist/lib/opContext/defineOp.d.ts +4 -4
- package/dist/lib/opContext/defineOp.d.ts.map +1 -1
- package/dist/lib/opContext/defineOp.js +53 -10
- package/dist/lib/opContext/opGroupTypes.d.ts +2 -2
- package/dist/lib/opContext/opTypes.d.ts +1 -1
- package/dist/lib/opContext/opTypes.d.ts.map +1 -1
- package/dist/lib/opContext/spanContextTypes.d.ts +29 -14
- package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -1
- package/dist/lib/opContext/types.d.ts +4 -4
- package/dist/lib/opContext/types.d.ts.map +1 -1
- package/dist/lib/physicalLayoutPlan.d.ts +89 -0
- package/dist/lib/physicalLayoutPlan.d.ts.map +1 -0
- package/dist/lib/physicalLayoutPlan.js +442 -0
- package/dist/lib/resolveMessage.d.ts +9 -0
- package/dist/lib/resolveMessage.d.ts.map +1 -0
- package/dist/lib/resolveMessage.js +63 -0
- package/dist/lib/result.d.ts +5 -7
- package/dist/lib/result.d.ts.map +1 -1
- package/dist/lib/result.js +19 -26
- package/dist/lib/runtimeHint.d.ts +35 -0
- package/dist/lib/runtimeHint.d.ts.map +1 -0
- package/dist/lib/runtimeHint.js +79 -0
- package/dist/lib/schema/types.d.ts +1 -1
- package/dist/lib/schema/types.d.ts.map +1 -1
- package/dist/lib/span-buffer/aot/v1.d.ts +2 -0
- package/dist/lib/span-buffer/aot/v1.d.ts.map +1 -0
- package/dist/lib/span-buffer/aot/v1.js +24 -0
- package/dist/lib/spanBuffer.d.ts +33 -4
- package/dist/lib/spanBuffer.d.ts.map +1 -1
- package/dist/lib/spanBuffer.js +583 -91
- package/dist/lib/spanBufferStats.d.ts +1 -1
- package/dist/lib/spanBufferStats.d.ts.map +1 -1
- package/dist/lib/spanContext.d.ts +27 -51
- package/dist/lib/spanContext.d.ts.map +1 -1
- package/dist/lib/spanContext.js +822 -344
- package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
- package/dist/lib/sqlite/sqlite-common.js +20 -21
- package/dist/lib/testing/bun-harness.d.ts +8 -3
- package/dist/lib/testing/bun-harness.d.ts.map +1 -1
- package/dist/lib/testing/bun-harness.js +30 -18
- package/dist/lib/testing/extractFacts.d.ts +1 -1
- package/dist/lib/testing/extractFacts.d.ts.map +1 -1
- package/dist/lib/testing/extractFacts.js +55 -63
- package/dist/lib/testing/facts.d.ts +1 -1
- package/dist/lib/testing/facts.d.ts.map +1 -1
- package/dist/lib/testing/queryable-span.d.ts +1 -1
- package/dist/lib/testing/queryable-span.d.ts.map +1 -1
- package/dist/lib/testing/queryable-span.js +26 -28
- package/dist/lib/testing/span-query.d.ts.map +1 -1
- package/dist/lib/testing/span-query.js +19 -22
- package/dist/lib/testing/stdio-replay.d.ts.map +1 -1
- package/dist/lib/testing/stdio-replay.js +19 -8
- package/dist/lib/threadId.d.ts.map +1 -1
- package/dist/lib/threadId.js +6 -3
- package/dist/lib/traceRoot.d.ts +30 -8
- package/dist/lib/traceRoot.d.ts.map +1 -1
- package/dist/lib/traceRoot.es.d.ts +17 -15
- package/dist/lib/traceRoot.es.d.ts.map +1 -1
- package/dist/lib/traceRoot.es.js +68 -34
- package/dist/lib/traceRoot.js +11 -0
- package/dist/lib/traceRoot.node.d.ts +17 -19
- package/dist/lib/traceRoot.node.d.ts.map +1 -1
- package/dist/lib/traceRoot.node.js +66 -38
- package/dist/lib/traceTopology.d.ts +42 -0
- package/dist/lib/traceTopology.d.ts.map +1 -0
- package/dist/lib/traceTopology.js +260 -0
- package/dist/lib/tracer.d.ts +9 -5
- package/dist/lib/tracer.d.ts.map +1 -1
- package/dist/lib/tracer.js +65 -71
- package/dist/lib/tracers/ArrayQueueTracer.d.ts +1 -1
- package/dist/lib/tracers/ArrayQueueTracer.js +1 -1
- package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
- package/dist/lib/tracers/StdioTracer.js +15 -13
- package/dist/lib/tracers/TestTracer.d.ts +4 -6
- package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
- package/dist/lib/tracers/TestTracer.js +6 -8
- package/dist/lib/types.d.ts +49 -32
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/vocabularyRegistry.d.ts +25 -0
- package/dist/lib/vocabularyRegistry.d.ts.map +1 -0
- package/dist/lib/vocabularyRegistry.js +372 -0
- package/dist/lib/wasm/WasmBufferStrategy.d.ts +6 -10
- package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
- package/dist/lib/wasm/WasmBufferStrategy.js +44 -37
- package/dist/lib/wasm/wasmAllocator.d.ts +27 -22
- package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
- package/dist/lib/wasm/wasmAllocator.js +66 -44
- package/dist/lib/wasm/wasmPhysicalLayout.d.ts +67 -0
- package/dist/lib/wasm/wasmPhysicalLayout.d.ts.map +1 -0
- package/dist/lib/wasm/wasmPhysicalLayout.js +179 -0
- package/dist/lib/wasm/wasmSpanBuffer.d.ts +79 -31
- package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
- package/dist/lib/wasm/wasmSpanBuffer.js +442 -272
- package/dist/lib/wasm/wasmTraceRoot.d.ts +24 -22
- package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
- package/dist/lib/wasm/wasmTraceRoot.js +110 -71
- package/dist/vocabulary/register/v1.d.ts +2 -0
- package/dist/vocabulary/register/v1.d.ts.map +1 -0
- package/dist/vocabulary/register/v1.js +1 -0
- package/dist/wasm.d.ts +5 -0
- package/dist/wasm.d.ts.map +1 -0
- package/dist/wasm.js +4 -0
- package/package.json +54 -6
- package/src/index.ts +1 -0
- package/src/lib/JsBufferStrategy.ts +27 -9
- package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +335 -37
- package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +97 -26
- package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +75 -15
- package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +30 -6
- package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +18 -21
- package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +5 -2
- package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +25 -7
- package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +3 -2
- package/src/lib/__tests__/buffer-overflow.test.ts +24 -18
- package/src/lib/__tests__/capability-span-context.test.ts +505 -0
- package/src/lib/__tests__/capacity-tuning.test.ts +5 -3
- package/src/lib/__tests__/eager-columns.test.ts +345 -0
- package/src/lib/__tests__/enum-metadata-aot.test.ts +153 -0
- package/src/lib/__tests__/enum-metadata.test.ts +177 -0
- package/src/lib/__tests__/fixtures/empty-vocabulary-runtime.fixture.ts +15 -0
- package/src/lib/__tests__/flushScheduler.test.ts +5 -1
- package/src/lib/__tests__/identity-view.property.test.ts +179 -0
- package/src/lib/__tests__/library.test.ts +19 -235
- package/src/lib/__tests__/message-buffer-families.test.ts +878 -0
- package/src/lib/__tests__/nested-library-tasks.test.ts +14 -15
- package/src/lib/__tests__/op-metadata.test.ts +1 -1
- package/src/lib/__tests__/op-type-safety.test.ts +5 -16
- package/src/lib/__tests__/physical-layout-plan.test.ts +333 -0
- package/src/lib/__tests__/remap-descriptor-integration.test.ts +381 -0
- package/src/lib/__tests__/root-context-construction.test.ts +414 -0
- package/src/lib/__tests__/span-auto-runtime.test.ts +386 -0
- package/src/lib/__tests__/span-buffer-segment-stats.test.ts +221 -0
- package/src/lib/__tests__/span-lifecycle.test.ts +53 -25
- package/src/lib/__tests__/spanbuffer-materializer-parity.test.ts +266 -0
- package/src/lib/__tests__/sync-async-trace.test.ts +24 -23
- package/src/lib/__tests__/tag-writer-aot.test.ts +214 -0
- package/src/lib/__tests__/test-helpers.ts +67 -12
- package/src/lib/__tests__/threadId.test.ts +62 -0
- package/src/lib/__tests__/timestamp.test.ts +221 -93
- package/src/lib/__tests__/traceTopology.property.test.ts +383 -0
- package/src/lib/__tests__/type-narrowing.test.ts +63 -0
- package/src/lib/__tests__/vocabulary-dense-decoding.test.ts +405 -0
- package/src/lib/__tests__/vocabularyRegistry.test.ts +313 -0
- package/src/lib/arrow/lease.ts +43 -0
- package/src/lib/arrow/utils.ts +10 -14
- package/src/lib/arrow/vocabularyDictionary.ts +123 -0
- package/src/lib/bufferStrategy.ts +9 -1
- package/src/lib/cloudflare/traceRows.ts +3 -2
- package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +21 -141
- package/src/lib/codegen/__tests__/fixedPositionWriter-parity.test.ts +273 -0
- package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +61 -34
- package/src/lib/codegen/__tests__/nullBitmap.test.ts +33 -37
- package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +34 -18
- package/src/lib/codegen/__tests__/spanLoggerMaterializerParity.test.ts +503 -0
- package/src/lib/codegen/evaluatorGenerator.ts +18 -13
- package/src/lib/codegen/fixedPositionWriterGenerator.ts +329 -245
- package/src/lib/codegen/spanLoggerClosureMaterializer.ts +598 -0
- package/src/lib/codegen/spanLoggerGenerator.ts +241 -177
- package/src/lib/convertToArrow.ts +598 -311
- package/src/lib/defineOpContext.ts +1 -1
- package/src/lib/enumMetadata.ts +121 -0
- package/src/lib/flushScheduler.ts +11 -5
- package/src/lib/library.ts +37 -595
- package/src/lib/logBinding.ts +21 -27
- package/src/lib/op.ts +75 -18
- package/src/lib/opContext/__tests__/retry.test.ts +27 -21
- package/src/lib/opContext/createOpGroup.ts +33 -31
- package/src/lib/opContext/defineOp.ts +88 -11
- package/src/lib/opContext/opGroupTypes.ts +2 -2
- package/src/lib/opContext/opTypes.ts +1 -1
- package/src/lib/opContext/spanContextTypes.ts +98 -17
- package/src/lib/opContext/types.ts +7 -3
- package/src/lib/physicalLayoutPlan.ts +598 -0
- package/src/lib/resolveMessage.ts +67 -0
- package/src/lib/result.ts +20 -33
- package/src/lib/runtimeHint.ts +98 -0
- package/src/lib/schema/__tests__/featureFlags.test.ts +2 -1
- package/src/lib/schema/builder.ts +1 -1
- package/src/lib/schema/types.ts +1 -1
- package/src/lib/span-buffer/aot/v1.ts +26 -0
- package/src/lib/spanBuffer.ts +658 -92
- package/src/lib/spanBufferStats.ts +1 -1
- package/src/lib/spanContext.ts +1350 -861
- package/src/lib/sqlite/sqlite-common.ts +20 -31
- package/src/lib/testing/__tests__/topology-traversal.test.ts +174 -0
- package/src/lib/testing/__tests__/vitest-harness.test.ts +2 -1
- package/src/lib/testing/bun-harness.ts +94 -43
- package/src/lib/testing/extractFacts.ts +64 -78
- package/src/lib/testing/facts.ts +1 -1
- package/src/lib/testing/queryable-span.ts +23 -30
- package/src/lib/testing/span-query.ts +16 -20
- package/src/lib/testing/stdio-replay.ts +25 -8
- package/src/lib/testing/vitest-harness.ts +1 -1
- package/src/lib/threadId.ts +6 -3
- package/src/lib/traceRoot.es.ts +77 -42
- package/src/lib/traceRoot.node.ts +75 -46
- package/src/lib/traceRoot.ts +41 -14
- package/src/lib/traceTopology.ts +279 -0
- package/src/lib/tracer.ts +109 -98
- package/src/lib/tracers/ArrayQueueTracer.ts +1 -1
- package/src/lib/tracers/StdioTracer.ts +15 -13
- package/src/lib/tracers/TestTracer.ts +6 -8
- package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +15 -10
- package/src/lib/tracers/__tests__/TestTracer.test.ts +23 -13
- package/src/lib/types.ts +64 -33
- package/src/lib/vocabularyRegistry.ts +439 -0
- package/src/lib/wasm/WasmBufferStrategy.ts +56 -48
- package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +215 -11
- package/src/lib/wasm/__tests__/allocatorFreeBlockClamp.test.ts +86 -0
- package/src/lib/wasm/__tests__/wasm-identity-view.test.ts +311 -0
- package/src/lib/wasm/__tests__/wasm-integration.test.ts +417 -44
- package/src/lib/wasm/__tests__/wasm-message-buffer-families.test.ts +588 -0
- package/src/lib/wasm/__tests__/wasmAllocator.test.ts +100 -668
- package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +419 -63
- package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +24 -29
- package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +2 -2
- package/src/lib/wasm/wasmAllocator.ts +131 -96
- package/src/lib/wasm/wasmPhysicalLayout.ts +309 -0
- package/src/lib/wasm/wasmSpanBuffer.ts +597 -341
- package/src/lib/wasm/wasmTraceRoot.ts +140 -78
- package/src/vocabulary/register/v1.ts +1 -0
- package/src/wasm.ts +19 -0
- package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +0 -319
- package/src/lib/__tests__/remapped-buffer-view.test.ts +0 -635
- 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
|
-
|
|
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
|
-
* -
|
|
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 {
|
|
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('
|
|
136
|
-
it('
|
|
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
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
expect(
|
|
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
|
});
|