@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.
- package/README.md +206 -206
- 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 +33 -18
- 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/typeGuards.d.ts +7 -47
- package/dist/lib/schema/typeGuards.d.ts.map +1 -1
- package/dist/lib/schema/typeGuards.js +7 -123
- 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/traceContext.d.ts.map +1 -1
- package/dist/lib/traceContext.js +1 -4
- 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 +122 -24
- 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/typeGuards.ts +7 -151
- 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/traceContext.ts +1 -6
- 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__/CompositeTracer.test.ts +150 -0
- 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,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 {
|
|
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
|
-
|
|
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
|
|
250
|
-
|
|
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(
|
|
253
|
-
const
|
|
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
|
+
});
|