@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
|
@@ -1,28 +1,57 @@
|
|
|
1
1
|
import { describe, expect, it } from 'bun:test';
|
|
2
2
|
|
|
3
3
|
import { Nanoseconds } from '@smoothbricks/arrow-builder';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
4
|
+
import fc from 'fast-check';
|
|
5
|
+
import { JsBufferStrategy } from '../JsBufferStrategy.js';
|
|
6
|
+
import { resolveEntryType } from '../resolveMessage.js';
|
|
7
|
+
import { ENTRY_TYPE_INFO, ENTRY_TYPE_SPAN_OK, ENTRY_TYPE_SPAN_START } from '../schema/systemSchema.js';
|
|
8
|
+
import { createTraceId } from '../traceId.js';
|
|
9
|
+
import { createTraceRoot as createEsTraceRoot, TraceRoot as EsTraceRoot } from '../traceRoot.es.js';
|
|
10
|
+
import type { TracerLifecycleHooks } from '../traceRoot.js';
|
|
11
|
+
import { createTraceRoot as createNodeTraceRoot, TraceRoot as NodeTraceRoot } from '../traceRoot.node.js';
|
|
12
|
+
import type { SpanBuffer } from '../types.js';
|
|
13
|
+
import { createTestSpanBuffer } from './test-helpers.js';
|
|
14
|
+
|
|
15
|
+
const mockBuffer = createTestSpanBuffer({}).spanBuffer;
|
|
16
|
+
type MockLogSchema = (typeof mockBuffer)['_logSchema'];
|
|
17
|
+
|
|
18
|
+
function createMockSpanBuffer(): SpanBuffer<MockLogSchema> {
|
|
19
|
+
return createTestSpanBuffer({}).spanBuffer;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function createMockTracer(): TracerLifecycleHooks<MockLogSchema> {
|
|
23
|
+
return {
|
|
24
|
+
onTraceStart: () => {},
|
|
25
|
+
onTraceEnd: () => {},
|
|
26
|
+
onSpanStart: () => {},
|
|
27
|
+
onSpanEnd: () => {},
|
|
28
|
+
onStatsWillResetFor: () => {},
|
|
29
|
+
getFlagEvaluatorForContext: () => undefined,
|
|
30
|
+
bufferStrategy: new JsBufferStrategy<MockLogSchema>(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function withPerformanceNow<T>(now: () => number, run: () => T): T {
|
|
35
|
+
const original = performance.now;
|
|
36
|
+
Object.defineProperty(performance, 'now', { configurable: true, value: now });
|
|
37
|
+
try {
|
|
38
|
+
return run();
|
|
39
|
+
} finally {
|
|
40
|
+
Object.defineProperty(performance, 'now', { configurable: true, value: original });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
7
43
|
|
|
8
|
-
function
|
|
9
|
-
|
|
44
|
+
function appendLifecycle(root: NodeTraceRoot | EsTraceRoot, buffer: SpanBuffer<MockLogSchema>): void {
|
|
45
|
+
root._writeSpanStart(root, buffer, 'timestamp-contract');
|
|
46
|
+
root._appendLogEntry(root, buffer, ENTRY_TYPE_INFO);
|
|
47
|
+
root._appendLogEntry(root, buffer, ENTRY_TYPE_INFO);
|
|
48
|
+
root._writeSpanEnd(root, buffer, ENTRY_TYPE_SPAN_OK);
|
|
10
49
|
}
|
|
11
50
|
|
|
12
51
|
describe('Node.js TraceRoot Timestamps (process.hrtime.bigint)', () => {
|
|
13
52
|
it('should return a bigint from getTimestampNanos()', async () => {
|
|
14
53
|
const { createTraceRoot } = await import('../traceRoot.node.js');
|
|
15
|
-
const mockTracer =
|
|
16
|
-
onTraceStart: () => {},
|
|
17
|
-
onTraceEnd: () => {},
|
|
18
|
-
onSpanStart: () => {},
|
|
19
|
-
onSpanEnd: () => {},
|
|
20
|
-
onStatsWillResetFor: () => {},
|
|
21
|
-
bufferStrategy: {
|
|
22
|
-
createChildSpanBuffer: createMockSpanBuffer,
|
|
23
|
-
createOverflowBuffer: createMockSpanBuffer,
|
|
24
|
-
},
|
|
25
|
-
};
|
|
54
|
+
const mockTracer = createMockTracer();
|
|
26
55
|
const traceRoot = createTraceRoot('test-trace', mockTracer);
|
|
27
56
|
|
|
28
57
|
const ts = traceRoot.getTimestampNanos();
|
|
@@ -31,17 +60,7 @@ describe('Node.js TraceRoot Timestamps (process.hrtime.bigint)', () => {
|
|
|
31
60
|
|
|
32
61
|
it('should return increasing timestamps', async () => {
|
|
33
62
|
const { createTraceRoot } = await import('../traceRoot.node.js');
|
|
34
|
-
const mockTracer =
|
|
35
|
-
onTraceStart: () => {},
|
|
36
|
-
onTraceEnd: () => {},
|
|
37
|
-
onSpanStart: () => {},
|
|
38
|
-
onSpanEnd: () => {},
|
|
39
|
-
onStatsWillResetFor: () => {},
|
|
40
|
-
bufferStrategy: {
|
|
41
|
-
createChildSpanBuffer: createMockSpanBuffer,
|
|
42
|
-
createOverflowBuffer: createMockSpanBuffer,
|
|
43
|
-
},
|
|
44
|
-
};
|
|
63
|
+
const mockTracer = createMockTracer();
|
|
45
64
|
const traceRoot = createTraceRoot('test-trace', mockTracer);
|
|
46
65
|
|
|
47
66
|
const ts1 = traceRoot.getTimestampNanos();
|
|
@@ -57,17 +76,7 @@ describe('Node.js TraceRoot Timestamps (process.hrtime.bigint)', () => {
|
|
|
57
76
|
|
|
58
77
|
it('should be within 1ms of Date.now()', async () => {
|
|
59
78
|
const { createTraceRoot } = await import('../traceRoot.node.js');
|
|
60
|
-
const mockTracer =
|
|
61
|
-
onTraceStart: () => {},
|
|
62
|
-
onTraceEnd: () => {},
|
|
63
|
-
onSpanStart: () => {},
|
|
64
|
-
onSpanEnd: () => {},
|
|
65
|
-
onStatsWillResetFor: () => {},
|
|
66
|
-
bufferStrategy: {
|
|
67
|
-
createChildSpanBuffer: createMockSpanBuffer,
|
|
68
|
-
createOverflowBuffer: createMockSpanBuffer,
|
|
69
|
-
},
|
|
70
|
-
};
|
|
79
|
+
const mockTracer = createMockTracer();
|
|
71
80
|
|
|
72
81
|
// Sample multiple times and check they're all close
|
|
73
82
|
for (let i = 0; i < 10; i++) {
|
|
@@ -83,17 +92,7 @@ describe('Node.js TraceRoot Timestamps (process.hrtime.bigint)', () => {
|
|
|
83
92
|
|
|
84
93
|
it('should have sub-millisecond precision (true nanoseconds)', async () => {
|
|
85
94
|
const { createTraceRoot } = await import('../traceRoot.node.js');
|
|
86
|
-
const mockTracer =
|
|
87
|
-
onTraceStart: () => {},
|
|
88
|
-
onTraceEnd: () => {},
|
|
89
|
-
onSpanStart: () => {},
|
|
90
|
-
onSpanEnd: () => {},
|
|
91
|
-
onStatsWillResetFor: () => {},
|
|
92
|
-
bufferStrategy: {
|
|
93
|
-
createChildSpanBuffer: createMockSpanBuffer,
|
|
94
|
-
createOverflowBuffer: createMockSpanBuffer,
|
|
95
|
-
},
|
|
96
|
-
};
|
|
95
|
+
const mockTracer = createMockTracer();
|
|
97
96
|
const traceRoot = createTraceRoot('test-trace', mockTracer);
|
|
98
97
|
const timestamps: bigint[] = [];
|
|
99
98
|
|
|
@@ -124,17 +123,7 @@ describe('Node.js TraceRoot Timestamps (process.hrtime.bigint)', () => {
|
|
|
124
123
|
|
|
125
124
|
try {
|
|
126
125
|
const { createTraceRoot } = await import('../traceRoot.node.js');
|
|
127
|
-
const mockTracer =
|
|
128
|
-
onTraceStart: () => {},
|
|
129
|
-
onTraceEnd: () => {},
|
|
130
|
-
onSpanStart: () => {},
|
|
131
|
-
onSpanEnd: () => {},
|
|
132
|
-
onStatsWillResetFor: () => {},
|
|
133
|
-
bufferStrategy: {
|
|
134
|
-
createChildSpanBuffer: createMockSpanBuffer,
|
|
135
|
-
createOverflowBuffer: createMockSpanBuffer,
|
|
136
|
-
},
|
|
137
|
-
};
|
|
126
|
+
const mockTracer = createMockTracer();
|
|
138
127
|
|
|
139
128
|
const traceRoot = createTraceRoot('test-trace', mockTracer);
|
|
140
129
|
const ts0 = traceRoot.getTimestampNanos();
|
|
@@ -150,17 +139,7 @@ describe('Node.js TraceRoot Timestamps (process.hrtime.bigint)', () => {
|
|
|
150
139
|
describe('Browser TraceRoot Timestamps (performance.now)', () => {
|
|
151
140
|
it('should return a bigint from getTimestampNanos()', async () => {
|
|
152
141
|
const { createTraceRoot } = await import('../traceRoot.es.js');
|
|
153
|
-
const mockTracer =
|
|
154
|
-
onTraceStart: () => {},
|
|
155
|
-
onTraceEnd: () => {},
|
|
156
|
-
onSpanStart: () => {},
|
|
157
|
-
onSpanEnd: () => {},
|
|
158
|
-
onStatsWillResetFor: () => {},
|
|
159
|
-
bufferStrategy: {
|
|
160
|
-
createChildSpanBuffer: createMockSpanBuffer,
|
|
161
|
-
createOverflowBuffer: createMockSpanBuffer,
|
|
162
|
-
},
|
|
163
|
-
};
|
|
142
|
+
const mockTracer = createMockTracer();
|
|
164
143
|
const traceRoot = createTraceRoot('test-trace', mockTracer);
|
|
165
144
|
|
|
166
145
|
const ts = traceRoot.getTimestampNanos();
|
|
@@ -169,17 +148,7 @@ describe('Browser TraceRoot Timestamps (performance.now)', () => {
|
|
|
169
148
|
|
|
170
149
|
it('should return increasing timestamps', async () => {
|
|
171
150
|
const { createTraceRoot } = await import('../traceRoot.es.js');
|
|
172
|
-
const mockTracer =
|
|
173
|
-
onTraceStart: () => {},
|
|
174
|
-
onTraceEnd: () => {},
|
|
175
|
-
onSpanStart: () => {},
|
|
176
|
-
onSpanEnd: () => {},
|
|
177
|
-
onStatsWillResetFor: () => {},
|
|
178
|
-
bufferStrategy: {
|
|
179
|
-
createChildSpanBuffer: createMockSpanBuffer,
|
|
180
|
-
createOverflowBuffer: createMockSpanBuffer,
|
|
181
|
-
},
|
|
182
|
-
};
|
|
151
|
+
const mockTracer = createMockTracer();
|
|
183
152
|
const traceRoot = createTraceRoot('test-trace', mockTracer);
|
|
184
153
|
|
|
185
154
|
const ts1 = traceRoot.getTimestampNanos();
|
|
@@ -195,17 +164,7 @@ describe('Browser TraceRoot Timestamps (performance.now)', () => {
|
|
|
195
164
|
|
|
196
165
|
it('should be within 1ms of Date.now()', async () => {
|
|
197
166
|
const { createTraceRoot } = await import('../traceRoot.es.js');
|
|
198
|
-
const mockTracer =
|
|
199
|
-
onTraceStart: () => {},
|
|
200
|
-
onTraceEnd: () => {},
|
|
201
|
-
onSpanStart: () => {},
|
|
202
|
-
onSpanEnd: () => {},
|
|
203
|
-
onStatsWillResetFor: () => {},
|
|
204
|
-
bufferStrategy: {
|
|
205
|
-
createChildSpanBuffer: createMockSpanBuffer,
|
|
206
|
-
createOverflowBuffer: createMockSpanBuffer,
|
|
207
|
-
},
|
|
208
|
-
};
|
|
167
|
+
const mockTracer = createMockTracer();
|
|
209
168
|
|
|
210
169
|
// Sample multiple times and check they're all close
|
|
211
170
|
for (let i = 0; i < 10; i++) {
|
|
@@ -221,6 +180,175 @@ describe('Browser TraceRoot Timestamps (performance.now)', () => {
|
|
|
221
180
|
});
|
|
222
181
|
});
|
|
223
182
|
|
|
183
|
+
describe('Platform timestamp append contract', () => {
|
|
184
|
+
it('anchors public Node and ES factories to the Unix epoch without exact wall-clock equality', () => {
|
|
185
|
+
const before = BigInt(Date.now()) * 1_000_000n;
|
|
186
|
+
const node = createNodeTraceRoot('node-epoch', createMockTracer());
|
|
187
|
+
const es = createEsTraceRoot('es-epoch', createMockTracer());
|
|
188
|
+
const after = BigInt(Date.now()) * 1_000_000n;
|
|
189
|
+
const tolerance = 50_000_000n;
|
|
190
|
+
|
|
191
|
+
for (const root of [node, es]) {
|
|
192
|
+
const buffer = createMockSpanBuffer();
|
|
193
|
+
root._writeSpanStart(root, buffer, 'epoch');
|
|
194
|
+
expect(buffer.timestamp[0]).toBeGreaterThanOrEqual(before - tolerance);
|
|
195
|
+
expect(buffer.timestamp[0]).toBeLessThanOrEqual(after + tolerance);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('keeps lifecycle appends strictly monotonic when the wrapped clock stalls or rolls back', () => {
|
|
200
|
+
const epoch = 1_700_000_000_000_000_000n;
|
|
201
|
+
const anchor = 10_000_000n;
|
|
202
|
+
const ticks = [anchor, anchor, anchor - 50n, anchor + 1n, anchor - 1_000n];
|
|
203
|
+
const buffer = createMockSpanBuffer();
|
|
204
|
+
let index = 0;
|
|
205
|
+
const original = process.hrtime.bigint;
|
|
206
|
+
process.hrtime.bigint = () => ticks[index++] ?? ticks[ticks.length - 1];
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
const root = new NodeTraceRoot(createTraceId('rollback'), epoch, Number(anchor), anchor, createMockTracer());
|
|
210
|
+
appendLifecycle(root, buffer);
|
|
211
|
+
const chronological = [buffer.timestamp[0], buffer.timestamp[2], buffer.timestamp[3], buffer.timestamp[1]];
|
|
212
|
+
for (let i = 1; i < chronological.length; i++) {
|
|
213
|
+
expect(chronological[i]).toBeGreaterThan(chronological[i - 1]);
|
|
214
|
+
}
|
|
215
|
+
} finally {
|
|
216
|
+
process.hrtime.bigint = original;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('advances ES lifecycle appends by one microsecond when performance.now stalls or rolls back', () => {
|
|
221
|
+
const epoch = 1_700_000_000_000_000_000n;
|
|
222
|
+
const buffer = createMockSpanBuffer();
|
|
223
|
+
const ticks = [10, 10, 9, 10.0001];
|
|
224
|
+
let index = 0;
|
|
225
|
+
const root = new EsTraceRoot(createTraceId('es-rollback'), epoch, 10, createMockTracer());
|
|
226
|
+
|
|
227
|
+
withPerformanceNow(
|
|
228
|
+
() => ticks[index++] ?? ticks[ticks.length - 1],
|
|
229
|
+
() => appendLifecycle(root, buffer),
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const chronological = [buffer.timestamp[0], buffer.timestamp[2], buffer.timestamp[3], buffer.timestamp[1]];
|
|
233
|
+
expect(chronological[0]).toBe(epoch);
|
|
234
|
+
for (let i = 1; i < chronological.length; i++) {
|
|
235
|
+
expect(chronological[i] - chronological[i - 1]).toBe(1_000n);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('preserves exact nanosecond deltas after a long Node monotonic-clock gap', () => {
|
|
240
|
+
const epoch = 1_700_000_000_000_000_000n;
|
|
241
|
+
const anchor = 9_007_199_254_740_993n;
|
|
242
|
+
const gap = 365n * 24n * 60n * 60n * 1_000_000_000n;
|
|
243
|
+
const ticks = [anchor + gap, anchor + gap + 1n, anchor + gap + 2n, anchor + gap + 3n];
|
|
244
|
+
const buffer = createMockSpanBuffer();
|
|
245
|
+
let index = 0;
|
|
246
|
+
const original = process.hrtime.bigint;
|
|
247
|
+
process.hrtime.bigint = () => ticks[index++] ?? ticks[ticks.length - 1];
|
|
248
|
+
|
|
249
|
+
try {
|
|
250
|
+
const root = new NodeTraceRoot(createTraceId('long-gap'), epoch, Number(anchor), anchor, createMockTracer());
|
|
251
|
+
appendLifecycle(root, buffer);
|
|
252
|
+
expect(buffer.timestamp[0]).toBe(epoch + gap);
|
|
253
|
+
expect(buffer.timestamp[2] - buffer.timestamp[0]).toBe(1n);
|
|
254
|
+
expect(buffer.timestamp[3] - buffer.timestamp[2]).toBe(1n);
|
|
255
|
+
expect(buffer.timestamp[1] - buffer.timestamp[3]).toBe(1n);
|
|
256
|
+
} finally {
|
|
257
|
+
process.hrtime.bigint = original;
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
it('re-anchors each new trace while an existing trace ignores wall-clock rollback', () => {
|
|
262
|
+
const originalDateNow = Date.now;
|
|
263
|
+
const originalHrtime = process.hrtime.bigint;
|
|
264
|
+
const wallTimes = [1_700_000_000_000, 1_699_999_000_000];
|
|
265
|
+
const ticks = [100n, 110n, 200n, 220n, 120n];
|
|
266
|
+
const firstStart = createMockSpanBuffer();
|
|
267
|
+
const secondStart = createMockSpanBuffer();
|
|
268
|
+
let wallIndex = 0;
|
|
269
|
+
let tickIndex = 0;
|
|
270
|
+
Date.now = () => wallTimes[wallIndex++] ?? wallTimes[wallTimes.length - 1];
|
|
271
|
+
process.hrtime.bigint = () => ticks[tickIndex++] ?? ticks[ticks.length - 1];
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
const first = createNodeTraceRoot('first-anchor', createMockTracer());
|
|
275
|
+
first._writeSpanStart(first, firstStart, 'first');
|
|
276
|
+
const second = createNodeTraceRoot('second-anchor', createMockTracer());
|
|
277
|
+
second._writeSpanStart(second, secondStart, 'second');
|
|
278
|
+
const firstLater = first._timestampNow(first);
|
|
279
|
+
|
|
280
|
+
expect(firstStart.timestamp[0]).toBe(BigInt(wallTimes[0]) * 1_000_000n + 10n);
|
|
281
|
+
expect(secondStart.timestamp[0]).toBe(BigInt(wallTimes[1]) * 1_000_000n + 20n);
|
|
282
|
+
expect(firstLater).toBeGreaterThan(firstStart.timestamp[0]);
|
|
283
|
+
} finally {
|
|
284
|
+
Date.now = originalDateNow;
|
|
285
|
+
process.hrtime.bigint = originalHrtime;
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('keeps Node and ES lifecycle output equivalent at shared microsecond ticks', () => {
|
|
290
|
+
const epoch = 1_700_000_000_000_000_000n;
|
|
291
|
+
const nodeAnchor = 5_000_000n;
|
|
292
|
+
const elapsedMicros = [0, 1, 2, 3];
|
|
293
|
+
const nodeBuffer = createMockSpanBuffer();
|
|
294
|
+
const esBuffer = createMockSpanBuffer();
|
|
295
|
+
let nodeIndex = 0;
|
|
296
|
+
const original = process.hrtime.bigint;
|
|
297
|
+
process.hrtime.bigint = () => nodeAnchor + BigInt(elapsedMicros[nodeIndex++] ?? 3) * 1_000n;
|
|
298
|
+
|
|
299
|
+
try {
|
|
300
|
+
const node = new NodeTraceRoot(
|
|
301
|
+
createTraceId('node-parity'),
|
|
302
|
+
epoch,
|
|
303
|
+
Number(nodeAnchor),
|
|
304
|
+
nodeAnchor,
|
|
305
|
+
createMockTracer(),
|
|
306
|
+
);
|
|
307
|
+
let esIndex = 0;
|
|
308
|
+
const es = new EsTraceRoot(createTraceId('es-parity'), epoch, 10, createMockTracer());
|
|
309
|
+
appendLifecycle(node, nodeBuffer);
|
|
310
|
+
withPerformanceNow(
|
|
311
|
+
() => 10 + (elapsedMicros[esIndex++] ?? 3) / 1_000,
|
|
312
|
+
() => appendLifecycle(es, esBuffer),
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
expect(Array.from({ length: 4 }, (_, row) => resolveEntryType(esBuffer, row))).toEqual(
|
|
316
|
+
Array.from({ length: 4 }, (_, row) => resolveEntryType(nodeBuffer, row)),
|
|
317
|
+
);
|
|
318
|
+
expect(Array.from(esBuffer.timestamp.slice(0, 4))).toEqual(Array.from(nodeBuffer.timestamp.slice(0, 4)));
|
|
319
|
+
expect(resolveEntryType(nodeBuffer, 0)).toBe(ENTRY_TYPE_SPAN_START);
|
|
320
|
+
expect(resolveEntryType(nodeBuffer, 1)).toBe(ENTRY_TYPE_SPAN_OK);
|
|
321
|
+
} finally {
|
|
322
|
+
process.hrtime.bigint = original;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('keeps generated rapid-write sequences strictly monotonic through the real append primitive', () => {
|
|
327
|
+
fc.assert(
|
|
328
|
+
fc.property(fc.array(fc.integer({ min: -5, max: 5 }), { minLength: 4, maxLength: 40 }), (steps) => {
|
|
329
|
+
const epoch = 1_700_000_000_000_000_000n;
|
|
330
|
+
const anchor = 1_000_000n;
|
|
331
|
+
let tick = anchor;
|
|
332
|
+
let index = 0;
|
|
333
|
+
const ticks = steps.map((step) => (tick += BigInt(step)));
|
|
334
|
+
const buffer = createMockSpanBuffer();
|
|
335
|
+
const original = process.hrtime.bigint;
|
|
336
|
+
process.hrtime.bigint = () => ticks[index++] ?? ticks[ticks.length - 1];
|
|
337
|
+
try {
|
|
338
|
+
const root = new NodeTraceRoot(createTraceId('property'), epoch, Number(anchor), anchor, createMockTracer());
|
|
339
|
+
root._writeSpanStart(root, buffer, 'property');
|
|
340
|
+
for (let i = 1; i < steps.length; i++) root._appendLogEntry(root, buffer, ENTRY_TYPE_INFO);
|
|
341
|
+
const written = Array.from(buffer.timestamp.slice(0, buffer._writeIndex)).filter((value) => value !== 0n);
|
|
342
|
+
for (let i = 1; i < written.length; i++) expect(written[i]).toBeGreaterThan(written[i - 1]);
|
|
343
|
+
} finally {
|
|
344
|
+
process.hrtime.bigint = original;
|
|
345
|
+
}
|
|
346
|
+
}),
|
|
347
|
+
{ numRuns: 80 },
|
|
348
|
+
);
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
|
|
224
352
|
describe('Nanoseconds utilities', () => {
|
|
225
353
|
it('fromMillis converts correctly', () => {
|
|
226
354
|
const ns = Nanoseconds.fromMillis(1000);
|