@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,7 +1,9 @@
|
|
|
1
1
|
import type { SchemaType } from '@smoothbricks/arrow-builder';
|
|
2
2
|
import { hasOwn, hasOwnString, isRecord } from '@smoothbricks/validation';
|
|
3
|
+
import { resolveEntryType, resolveMessage } from '../resolveMessage.js';
|
|
3
4
|
import type { LogSchema } from '../schema/LogSchema.js';
|
|
4
5
|
import { getSchemaType } from '../schema/typeGuards.js';
|
|
6
|
+
import { iterateSpanTree, NO_NODE } from '../traceTopology.js';
|
|
5
7
|
import type { AnySpanBuffer } from '../types.js';
|
|
6
8
|
|
|
7
9
|
export const SPANS_TABLE_INIT_SQL = `
|
|
@@ -227,36 +229,23 @@ export function parseSqliteTableInfoRows(
|
|
|
227
229
|
return rows.map((row, rowIndex) => parseSqliteTableInfoRow(row, boundary, rowIndex));
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
function* walkOverflowSegments(
|
|
231
|
-
buffer: AnySpanBuffer,
|
|
232
|
-
traceId: string,
|
|
233
|
-
spanId: number,
|
|
234
|
-
parentSpanId: number,
|
|
235
|
-
rowOffset: number,
|
|
236
|
-
): Generator<SpanSegment> {
|
|
237
|
-
yield {
|
|
238
|
-
buffer,
|
|
239
|
-
traceId,
|
|
240
|
-
spanId,
|
|
241
|
-
parentSpanId,
|
|
242
|
-
rowOffset,
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
if (buffer._overflow) {
|
|
246
|
-
yield* walkOverflowSegments(buffer._overflow, traceId, spanId, parentSpanId, rowOffset + buffer._writeIndex);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function* walkTree(buffer: AnySpanBuffer): Generator<SpanSegment> {
|
|
251
|
-
yield* walkOverflowSegments(buffer, buffer.trace_id, buffer.span_id, buffer.parent_span_id, 0);
|
|
252
|
-
|
|
253
|
-
for (const child of buffer._children) {
|
|
254
|
-
yield* walkTree(child);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
232
|
export function* walkSpanSegments(rootBuffer: AnySpanBuffer): Generator<SpanSegment> {
|
|
259
|
-
|
|
233
|
+
let logicalNode = NO_NODE;
|
|
234
|
+
let rowOffset = 0;
|
|
235
|
+
for (const buffer of iterateSpanTree(rootBuffer)) {
|
|
236
|
+
if (buffer._nodeIndex !== logicalNode) {
|
|
237
|
+
logicalNode = buffer._nodeIndex;
|
|
238
|
+
rowOffset = 0;
|
|
239
|
+
}
|
|
240
|
+
yield {
|
|
241
|
+
buffer,
|
|
242
|
+
traceId: buffer.trace_id,
|
|
243
|
+
spanId: buffer.span_id,
|
|
244
|
+
parentSpanId: buffer.parent_span_id,
|
|
245
|
+
rowOffset,
|
|
246
|
+
};
|
|
247
|
+
rowOffset += buffer._writeIndex;
|
|
248
|
+
}
|
|
260
249
|
}
|
|
261
250
|
|
|
262
251
|
export function getMissingSchemaColumns(
|
|
@@ -301,9 +290,9 @@ export function readSpanFieldValue(buffer: AnySpanBuffer, fieldName: string, row
|
|
|
301
290
|
|
|
302
291
|
export function buildInsertParams(segment: SpanSegment, row: number, activeUserFields: readonly string[]): unknown[] {
|
|
303
292
|
const { buffer, traceId, spanId, parentSpanId, rowOffset } = segment;
|
|
304
|
-
const entryType = buffer
|
|
293
|
+
const entryType = resolveEntryType(buffer, row);
|
|
305
294
|
const timestampNs = Number(buffer.timestamp[row]);
|
|
306
|
-
const message = buffer
|
|
295
|
+
const message = resolveMessage(buffer, row);
|
|
307
296
|
|
|
308
297
|
const userValues = activeUserFields.map((fieldName) => {
|
|
309
298
|
const directValue = readUserValue(buffer, fieldName, row);
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { describe, expect, it, spyOn } from 'bun:test';
|
|
2
|
+
import { defineOpContext } from '../../defineOpContext.js';
|
|
3
|
+
import { JsBufferStrategy } from '../../JsBufferStrategy.js';
|
|
4
|
+
import { resolveMessage } from '../../resolveMessage.js';
|
|
5
|
+
import { defineLogSchema } from '../../schema/defineLogSchema.js';
|
|
6
|
+
import { ENTRY_TYPE_SPAN_OK, ENTRY_TYPE_SPAN_START } from '../../schema/systemSchema.js';
|
|
7
|
+
import { createTraceRoot } from '../../traceRoot.node.js';
|
|
8
|
+
import { ArrayQueueTracer } from '../../tracers/ArrayQueueTracer.js';
|
|
9
|
+
import { StdioTracer } from '../../tracers/StdioTracer.js';
|
|
10
|
+
import { extractFacts } from '../extractFacts.js';
|
|
11
|
+
import { querySpan } from '../queryable-span.js';
|
|
12
|
+
import { extractFactsFor, findAllSpans, findSpan, spanNames } from '../span-query.js';
|
|
13
|
+
import { replayTraceToStdio } from '../stdio-replay.js';
|
|
14
|
+
|
|
15
|
+
const schema = defineLogSchema({});
|
|
16
|
+
const binding = defineOpContext({ logSchema: schema });
|
|
17
|
+
|
|
18
|
+
function createRuntimeRoot(name = 'root') {
|
|
19
|
+
const tracer = new ArrayQueueTracer(binding, {
|
|
20
|
+
bufferStrategy: new JsBufferStrategy(),
|
|
21
|
+
createTraceRoot,
|
|
22
|
+
});
|
|
23
|
+
tracer.trace(name, (ctx) => ctx.ok(null));
|
|
24
|
+
const root = tracer.queue[0];
|
|
25
|
+
if (!root) throw new Error(`Expected traced root '${name}'`);
|
|
26
|
+
return { root, tracer };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function addCompletedChild(
|
|
30
|
+
runtime: ReturnType<typeof createRuntimeRoot>,
|
|
31
|
+
parent: ReturnType<typeof createRuntimeRoot>['root'],
|
|
32
|
+
name: string,
|
|
33
|
+
) {
|
|
34
|
+
const child = runtime.tracer.bufferStrategy.createChildSpanBuffer(parent, parent._opMetadata, parent._opMetadata, 8);
|
|
35
|
+
child.message(0, name);
|
|
36
|
+
{
|
|
37
|
+
const entryTypes = child.entry_type;
|
|
38
|
+
if (entryTypes === undefined) throw new Error('Expected split entry-type lane');
|
|
39
|
+
entryTypes[0] = ENTRY_TYPE_SPAN_START;
|
|
40
|
+
}
|
|
41
|
+
{
|
|
42
|
+
const entryTypes = child.entry_type;
|
|
43
|
+
if (entryTypes === undefined) throw new Error('Expected split entry-type lane');
|
|
44
|
+
entryTypes[1] = ENTRY_TYPE_SPAN_OK;
|
|
45
|
+
}
|
|
46
|
+
child._writeIndex = 2;
|
|
47
|
+
return child;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const factOptions = {
|
|
51
|
+
includeScope: false,
|
|
52
|
+
includeTags: false,
|
|
53
|
+
includeLogs: false,
|
|
54
|
+
includeFF: false,
|
|
55
|
+
includeMetrics: false,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
describe('iterative test-support span traversal', () => {
|
|
59
|
+
it('preserves depth-first insertion order across facts, queries, and stdio replay', () => {
|
|
60
|
+
const runtime = createRuntimeRoot();
|
|
61
|
+
const first = addCompletedChild(runtime, runtime.root, 'first');
|
|
62
|
+
addCompletedChild(runtime, first, 'target');
|
|
63
|
+
addCompletedChild(runtime, first, 'nested-last');
|
|
64
|
+
addCompletedChild(runtime, runtime.root, 'target');
|
|
65
|
+
|
|
66
|
+
const expectedNames = ['first', 'target', 'nested-last', 'target'];
|
|
67
|
+
expect(spanNames(runtime.root)).toEqual(expectedNames);
|
|
68
|
+
expect(querySpan(runtime.root).names()).toEqual(expectedNames);
|
|
69
|
+
expect(findAllSpans(runtime.root, 'target').map((span) => resolveMessage(span, 0))).toEqual(['target', 'target']);
|
|
70
|
+
expect(
|
|
71
|
+
querySpan(runtime.root)
|
|
72
|
+
.findAll('target')
|
|
73
|
+
.map((span) => span.name),
|
|
74
|
+
).toEqual(['target', 'target']);
|
|
75
|
+
expect(findSpan(runtime.root, 'nested-last')).toBe(querySpan(runtime.root).find('nested-last')?.buffer);
|
|
76
|
+
expect(extractFactsFor(runtime.root, 'first', factOptions)).toEqual(querySpan(first).facts(factOptions));
|
|
77
|
+
|
|
78
|
+
expect(Array.from(extractFacts(runtime.root, factOptions))).toEqual([
|
|
79
|
+
'span:root: started',
|
|
80
|
+
'span:first: started',
|
|
81
|
+
'span:target: started',
|
|
82
|
+
'span:target: ok',
|
|
83
|
+
'span:nested-last: started',
|
|
84
|
+
'span:nested-last: ok',
|
|
85
|
+
'span:first: ok',
|
|
86
|
+
'span:target: started',
|
|
87
|
+
'span:target: ok',
|
|
88
|
+
'span:root: ok',
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
const replayEvents: string[] = [];
|
|
92
|
+
const traceStart = spyOn(StdioTracer.prototype, 'onTraceStart').mockImplementation((buffer) => {
|
|
93
|
+
replayEvents.push(`trace-start:${resolveMessage(buffer, 0)}`);
|
|
94
|
+
});
|
|
95
|
+
const spanStart = spyOn(StdioTracer.prototype, 'onSpanStart').mockImplementation((buffer) => {
|
|
96
|
+
replayEvents.push(`span-start:${resolveMessage(buffer, 0)}`);
|
|
97
|
+
});
|
|
98
|
+
const spanEnd = spyOn(StdioTracer.prototype, 'onSpanEnd').mockImplementation((buffer) => {
|
|
99
|
+
replayEvents.push(`span-end:${resolveMessage(buffer, 0)}`);
|
|
100
|
+
});
|
|
101
|
+
const traceEnd = spyOn(StdioTracer.prototype, 'onTraceEnd').mockImplementation((buffer) => {
|
|
102
|
+
replayEvents.push(`trace-end:${resolveMessage(buffer, 0)}`);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
replayTraceToStdio(binding, runtime.root);
|
|
107
|
+
} finally {
|
|
108
|
+
traceStart.mockRestore();
|
|
109
|
+
spanStart.mockRestore();
|
|
110
|
+
spanEnd.mockRestore();
|
|
111
|
+
traceEnd.mockRestore();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
expect(replayEvents).toEqual([
|
|
115
|
+
'trace-start:root',
|
|
116
|
+
'span-start:first',
|
|
117
|
+
'span-start:target',
|
|
118
|
+
'span-end:target',
|
|
119
|
+
'span-start:nested-last',
|
|
120
|
+
'span-end:nested-last',
|
|
121
|
+
'span-end:first',
|
|
122
|
+
'span-start:target',
|
|
123
|
+
'span-end:target',
|
|
124
|
+
'trace-end:root',
|
|
125
|
+
]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('handles a tree deeper than the JavaScript call stack in every public test-support traversal', () => {
|
|
129
|
+
const runtime = createRuntimeRoot();
|
|
130
|
+
const edgeCount = 20_000;
|
|
131
|
+
let parent = runtime.root;
|
|
132
|
+
|
|
133
|
+
for (let depth = 0; depth < edgeCount; depth++) {
|
|
134
|
+
parent = addCompletedChild(runtime, parent, depth === edgeCount - 1 ? 'deepest' : 'level');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const names = spanNames(runtime.root);
|
|
138
|
+
expect(names).toHaveLength(edgeCount);
|
|
139
|
+
expect(names[0]).toBe('level');
|
|
140
|
+
expect(names[edgeCount - 1]).toBe('deepest');
|
|
141
|
+
expect(findSpan(runtime.root, 'deepest')).toBe(parent);
|
|
142
|
+
expect(querySpan(runtime.root).find('deepest')?.buffer).toBe(parent);
|
|
143
|
+
|
|
144
|
+
const facts = Array.from(extractFacts(runtime.root, factOptions));
|
|
145
|
+
expect(facts).toHaveLength((edgeCount + 1) * 2);
|
|
146
|
+
expect(facts[0]).toBe('span:root: started');
|
|
147
|
+
expect(facts[edgeCount]).toBe('span:deepest: started');
|
|
148
|
+
expect(facts[edgeCount + 1]).toBe('span:deepest: ok');
|
|
149
|
+
expect(facts[facts.length - 1]).toBe('span:root: ok');
|
|
150
|
+
|
|
151
|
+
let replayedStarts = 0;
|
|
152
|
+
let replayedEnds = 0;
|
|
153
|
+
const spanStart = spyOn(StdioTracer.prototype, 'onSpanStart').mockImplementation(() => {
|
|
154
|
+
replayedStarts++;
|
|
155
|
+
});
|
|
156
|
+
const spanEnd = spyOn(StdioTracer.prototype, 'onSpanEnd').mockImplementation(() => {
|
|
157
|
+
replayedEnds++;
|
|
158
|
+
});
|
|
159
|
+
const traceStart = spyOn(StdioTracer.prototype, 'onTraceStart').mockImplementation(() => {});
|
|
160
|
+
const traceEnd = spyOn(StdioTracer.prototype, 'onTraceEnd').mockImplementation(() => {});
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
replayTraceToStdio(binding, runtime.root);
|
|
164
|
+
} finally {
|
|
165
|
+
spanStart.mockRestore();
|
|
166
|
+
spanEnd.mockRestore();
|
|
167
|
+
traceStart.mockRestore();
|
|
168
|
+
traceEnd.mockRestore();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
expect(replayedStarts).toBe(edgeCount);
|
|
172
|
+
expect(replayedEnds).toBe(edgeCount);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
@@ -21,7 +21,8 @@ describe('vitest harness tracer defaults', () => {
|
|
|
21
21
|
const tracer = makeVitestTestTracer({ binding: vitestBinding });
|
|
22
22
|
installVitestTestTracing(tracer);
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
// Global accessor erases the concrete binding generic; assert identity directly.
|
|
25
|
+
expect(Object.is(getTracer(), tracer.getTracer())).toBe(true);
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
it('routes initTraceTestRun through the active suite tracer path', () => {
|
|
@@ -179,6 +179,38 @@ function extendBindingLogSchema<
|
|
|
179
179
|
return extendedBinding;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
type RuntimeHarnessBinding<
|
|
183
|
+
TFields extends SchemaFields,
|
|
184
|
+
FF extends FeatureFlagSchema,
|
|
185
|
+
Deps extends DepsConfig,
|
|
186
|
+
UserCtx extends Record<string, unknown>,
|
|
187
|
+
TExt extends SchemaFields,
|
|
188
|
+
> = OpContextBinding<LogSchema<TFields & (BunTestHarnessBuiltins | HarnessSchema<TExt>)>, FF, Deps, UserCtx>;
|
|
189
|
+
|
|
190
|
+
function createRuntimeHarnessBinding<
|
|
191
|
+
TFields extends SchemaFields,
|
|
192
|
+
FF extends FeatureFlagSchema,
|
|
193
|
+
Deps extends DepsConfig,
|
|
194
|
+
UserCtx extends Record<string, unknown>,
|
|
195
|
+
TExt extends SchemaFields,
|
|
196
|
+
>(
|
|
197
|
+
binding: OpContextBinding<LogSchema<TFields>, FF, Deps, UserCtx>,
|
|
198
|
+
options: BunTestSetupOptions<TExt> | undefined,
|
|
199
|
+
): RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt> {
|
|
200
|
+
const harnessSchema: BunTestHarnessBuiltins | HarnessSchema<TExt> =
|
|
201
|
+
options?.extraTestColumns === undefined
|
|
202
|
+
? buildHarnessSchemaExtensions(binding, undefined)
|
|
203
|
+
: buildHarnessSchemaExtensions(binding, options.extraTestColumns);
|
|
204
|
+
return extendBindingLogSchema<
|
|
205
|
+
OpContextBinding<LogSchema<TFields>, FF, Deps, UserCtx>,
|
|
206
|
+
TFields,
|
|
207
|
+
FF,
|
|
208
|
+
Deps,
|
|
209
|
+
UserCtx,
|
|
210
|
+
BunTestHarnessBuiltins | HarnessSchema<TExt>
|
|
211
|
+
>(binding, harnessSchema);
|
|
212
|
+
}
|
|
213
|
+
|
|
182
214
|
function isTruthyEnvFlag(value: unknown): boolean {
|
|
183
215
|
return value === true || value === '1' || value === 'true';
|
|
184
216
|
}
|
|
@@ -207,6 +239,15 @@ function isTracerForBinding<B extends OpContextBinding>(value: unknown, binding:
|
|
|
207
239
|
);
|
|
208
240
|
}
|
|
209
241
|
|
|
242
|
+
function isTracerInstance(value: unknown): value is Tracer<OpContextBinding> {
|
|
243
|
+
return (
|
|
244
|
+
typeof value === 'object' &&
|
|
245
|
+
value !== null &&
|
|
246
|
+
typeof Reflect.get(value, 'trace') === 'function' &&
|
|
247
|
+
typeof Reflect.get(value, 'flush') === 'function'
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
210
251
|
function isVerboseTraceEnabled(explicitVerbose: boolean | undefined): boolean {
|
|
211
252
|
if (explicitVerbose !== undefined) {
|
|
212
253
|
return explicitVerbose;
|
|
@@ -293,14 +334,19 @@ export interface BunTestSuiteTracer<B extends OpContextBinding> {
|
|
|
293
334
|
export type BunTestSuiteUseTestTracer<
|
|
294
335
|
B extends OpContextBinding,
|
|
295
336
|
TExt extends SchemaFields = Record<never, never>,
|
|
296
|
-
> =
|
|
337
|
+
> = BunTestTracerInstance<ExtendBindingLogSchema<B, HarnessSchema<TExt>>>;
|
|
297
338
|
|
|
298
339
|
export type TestTracer<
|
|
299
340
|
B extends OpContextBinding,
|
|
300
341
|
TExt extends SchemaFields = Record<never, never>,
|
|
301
342
|
> = BunTestSuiteUseTestTracer<B, TExt>;
|
|
302
343
|
|
|
303
|
-
|
|
344
|
+
export interface ActiveBunTestTracer {
|
|
345
|
+
setup(): void;
|
|
346
|
+
useTestSpan(): unknown;
|
|
347
|
+
getTracer(): unknown;
|
|
348
|
+
createBunTestMock<TModule extends BunTestModuleShape>(bunTestModule: TModule): TModule;
|
|
349
|
+
}
|
|
304
350
|
|
|
305
351
|
let _activeSuiteTracer: ActiveBunTestTracer | null = null;
|
|
306
352
|
|
|
@@ -326,7 +372,7 @@ export function makeBunTestSuiteTracer<B extends OpContextBinding, TExt extends
|
|
|
326
372
|
export function makeBunTestSuiteTracer<B extends OpContextBinding, TExt extends SchemaFields = Record<never, never>>(
|
|
327
373
|
binding: B,
|
|
328
374
|
options?: BunTestSetupOptions<TExt>,
|
|
329
|
-
)
|
|
375
|
+
) {
|
|
330
376
|
const useTestTracer = createTestTracerInstance(binding, options);
|
|
331
377
|
return {
|
|
332
378
|
useTestTracer,
|
|
@@ -357,12 +403,7 @@ export function defineTestTracer<B extends OpContextBinding>(
|
|
|
357
403
|
return {
|
|
358
404
|
opContext: binding,
|
|
359
405
|
extraTestColumns: options?.extraTestColumns,
|
|
360
|
-
|
|
361
|
-
// the active suite tracer's (extended) binding. Re-checking against the
|
|
362
|
-
// original binding fails when extraTestColumns extend the schema, because
|
|
363
|
-
// the span's _schema is the extended LogSchema, not the original.
|
|
364
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- WHY: useTestSpan() returns SpanContext typed to the suite binding; narrowing to OpContextOf<B> is safe because initTraceTestRun validates the binding matches
|
|
365
|
-
useTestSpan: () => useTestSpan() as SpanContext<OpContextOf<B>>,
|
|
406
|
+
useTestSpan: () => useTestSpan<B>(),
|
|
366
407
|
};
|
|
367
408
|
}
|
|
368
409
|
|
|
@@ -382,31 +423,37 @@ export function makeTestTracer<B extends OpContextBinding, TExt extends SchemaFi
|
|
|
382
423
|
export function makeTestTracer<B extends OpContextBinding, TExt extends SchemaFields = Record<never, never>>(
|
|
383
424
|
binding: B,
|
|
384
425
|
options?: BunTestSetupOptions<TExt>,
|
|
385
|
-
)
|
|
426
|
+
) {
|
|
386
427
|
return createTestTracerInstance(binding, options);
|
|
387
428
|
}
|
|
388
|
-
function createTestTracerInstance<
|
|
389
|
-
|
|
429
|
+
function createTestTracerInstance<
|
|
430
|
+
TFields extends SchemaFields,
|
|
431
|
+
FF extends FeatureFlagSchema,
|
|
432
|
+
Deps extends DepsConfig,
|
|
433
|
+
UserCtx extends Record<string, unknown>,
|
|
434
|
+
TExt extends SchemaFields = Record<never, never>,
|
|
435
|
+
>(
|
|
436
|
+
binding: OpContextBinding<LogSchema<TFields>, FF, Deps, UserCtx>,
|
|
390
437
|
options?: BunTestSetupOptions<TExt>,
|
|
391
|
-
): BunTestTracerInstance<
|
|
392
|
-
let activeBinding:
|
|
393
|
-
let tracer: Tracer<
|
|
438
|
+
): BunTestTracerInstance<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>> {
|
|
439
|
+
let activeBinding: RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt> | null = null;
|
|
440
|
+
let tracer: Tracer<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>> | null = null;
|
|
394
441
|
let verboseTrace = false;
|
|
395
|
-
let rootCtx:
|
|
442
|
+
let rootCtx: HarnessSpanContext<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>> | null = null;
|
|
396
443
|
let resolveTestRun: (() => void) | null = null;
|
|
397
444
|
let rootTracePromise: Promise<unknown> | null = null;
|
|
398
445
|
let isSetup = false;
|
|
399
446
|
|
|
400
|
-
const als = new AsyncLocalStorage<
|
|
447
|
+
const als = new AsyncLocalStorage<HarnessSpanContext<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>>>();
|
|
401
448
|
|
|
402
|
-
function assertRootCtx():
|
|
449
|
+
function assertRootCtx(): HarnessSpanContext<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>> {
|
|
403
450
|
if (!rootCtx || !activeBinding || !isSpanContextForBinding(rootCtx, activeBinding)) {
|
|
404
451
|
throw new Error('Call setup() before wiring bun:test wrappers');
|
|
405
452
|
}
|
|
406
453
|
return rootCtx;
|
|
407
454
|
}
|
|
408
455
|
|
|
409
|
-
function assertTracer(): Tracer<
|
|
456
|
+
function assertTracer(): Tracer<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>> {
|
|
410
457
|
if (!tracer || !activeBinding || !isTracerForBinding(tracer, activeBinding)) {
|
|
411
458
|
throw new Error('Call setup() in preload before tests');
|
|
412
459
|
}
|
|
@@ -510,11 +557,7 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
|
|
|
510
557
|
}
|
|
511
558
|
isSetup = true;
|
|
512
559
|
|
|
513
|
-
const
|
|
514
|
-
options?.extraTestColumns === undefined
|
|
515
|
-
? buildHarnessSchemaExtensions(binding, undefined)
|
|
516
|
-
: buildHarnessSchemaExtensions(binding, options.extraTestColumns);
|
|
517
|
-
const extendedBinding = extendBindingLogSchema(binding, harnessSchema);
|
|
560
|
+
const extendedBinding = createRuntimeHarnessBinding(binding, options);
|
|
518
561
|
activeBinding = extendedBinding;
|
|
519
562
|
|
|
520
563
|
verboseTrace = isVerboseTraceEnabled(options?.verbose);
|
|
@@ -526,7 +569,7 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
|
|
|
526
569
|
});
|
|
527
570
|
|
|
528
571
|
tracer = activeTracer;
|
|
529
|
-
rootTracePromise = activeTracer.trace('test-run', (ctx
|
|
572
|
+
rootTracePromise = activeTracer.trace('test-run', (ctx) => {
|
|
530
573
|
rootCtx = ctx;
|
|
531
574
|
return new Promise<void>((resolve) => {
|
|
532
575
|
resolveTestRun = resolve;
|
|
@@ -570,7 +613,7 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
|
|
|
570
613
|
});
|
|
571
614
|
},
|
|
572
615
|
|
|
573
|
-
useTestSpan():
|
|
616
|
+
useTestSpan(): HarnessSpanContext<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>> {
|
|
574
617
|
const ctx = als.getStore();
|
|
575
618
|
if (!ctx || !activeBinding || !isSpanContextForBinding(ctx, activeBinding)) {
|
|
576
619
|
throw new Error('useTestSpan() called outside of a traced it()');
|
|
@@ -578,7 +621,7 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
|
|
|
578
621
|
return ctx;
|
|
579
622
|
},
|
|
580
623
|
|
|
581
|
-
getTracer(): Tracer<
|
|
624
|
+
getTracer(): Tracer<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>> {
|
|
582
625
|
return assertTracer();
|
|
583
626
|
},
|
|
584
627
|
|
|
@@ -601,11 +644,11 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
|
|
|
601
644
|
}
|
|
602
645
|
|
|
603
646
|
// Global singleton — one root tracer for the entire bun test run
|
|
604
|
-
let _tracer:
|
|
647
|
+
let _tracer: unknown = null;
|
|
605
648
|
let _verboseTrace = false;
|
|
606
649
|
|
|
607
650
|
// Root span context, its resolver, and the trace promise — one root per test run
|
|
608
|
-
let _rootCtx:
|
|
651
|
+
let _rootCtx: unknown = null;
|
|
609
652
|
let _resolveTestRun: (() => void) | null = null;
|
|
610
653
|
let _rootTracePromise: Promise<unknown> | null = null;
|
|
611
654
|
|
|
@@ -630,20 +673,20 @@ export function initTraceTestRun<B extends OpContextBinding>(opContext: B, optio
|
|
|
630
673
|
|
|
631
674
|
_verboseTrace = isVerboseTraceEnabled(options?.verbose);
|
|
632
675
|
|
|
633
|
-
|
|
676
|
+
const tracer = createRootTracer({
|
|
634
677
|
binding: extendedBinding,
|
|
635
678
|
sqlite: options?.sqlite,
|
|
636
679
|
verbose: _verboseTrace,
|
|
637
680
|
});
|
|
681
|
+
_tracer = tracer;
|
|
638
682
|
|
|
639
683
|
// Create the single root trace — a long-lived promise keeps it alive
|
|
640
|
-
|
|
641
|
-
_rootTracePromise = tracer.trace('test-run', (ctx: SpanContext<OpContext>) => {
|
|
684
|
+
_rootTracePromise = tracer.trace('test-run', (ctx) => {
|
|
642
685
|
_rootCtx = ctx;
|
|
643
686
|
return new Promise<void>((resolve) => {
|
|
644
687
|
_resolveTestRun = resolve;
|
|
645
688
|
});
|
|
646
|
-
})
|
|
689
|
+
});
|
|
647
690
|
|
|
648
691
|
// Register global teardown — resolve root, wait for span-end, then flush tracer outputs
|
|
649
692
|
_afterAll(async () => {
|
|
@@ -663,12 +706,12 @@ export function initTraceTestRun<B extends OpContextBinding>(opContext: B, optio
|
|
|
663
706
|
_rootTracePromise = null;
|
|
664
707
|
}
|
|
665
708
|
|
|
666
|
-
if (_tracer) {
|
|
709
|
+
if (isTracerInstance(_tracer)) {
|
|
667
710
|
try {
|
|
668
711
|
cleanupDebug('global.tracer.flush:start', { tracer: _tracer.constructor.name });
|
|
669
712
|
await _tracer.flush();
|
|
670
713
|
cleanupDebug('global.tracer.flush:end', { tracer: _tracer.constructor.name });
|
|
671
|
-
if (options?.sqlite && _rootCtx) {
|
|
714
|
+
if (options?.sqlite && isSpanContext(_rootCtx)) {
|
|
672
715
|
const traceId = _rootCtx.buffer.trace_id;
|
|
673
716
|
const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
|
|
674
717
|
console.log(`\n[trace] trace_id: ${traceId} → ${dbPath}`);
|
|
@@ -695,7 +738,7 @@ export function initTraceTestRun<B extends OpContextBinding>(opContext: B, optio
|
|
|
695
738
|
* @param bunTestModule - The original bun:test namespace (`import * as bunTest from 'bun:test'`)
|
|
696
739
|
*/
|
|
697
740
|
export function createBunTestMock<TModule extends BunTestModuleShape>(bunTestModule: TModule): TModule {
|
|
698
|
-
if (!_rootCtx) {
|
|
741
|
+
if (!isSpanContext(_rootCtx)) {
|
|
699
742
|
if (_activeSuiteTracer) {
|
|
700
743
|
return _activeSuiteTracer.createBunTestMock(bunTestModule);
|
|
701
744
|
}
|
|
@@ -734,7 +777,7 @@ export function createBunTestMock<TModule extends BunTestModuleShape>(bunTestMod
|
|
|
734
777
|
// Capture describe path at registration time (synchronous)
|
|
735
778
|
const describePath = describeStack.length > 0 ? describeStack.join(' > ') : null;
|
|
736
779
|
return origIt(name, () =>
|
|
737
|
-
rootCtx.span(name, async (ctx
|
|
780
|
+
rootCtx.span(name, async (ctx) => {
|
|
738
781
|
writeDescribeTag(ctx.tag, describePath);
|
|
739
782
|
try {
|
|
740
783
|
await als.run(ctx, fn);
|
|
@@ -775,10 +818,14 @@ export function createBunTestMock<TModule extends BunTestModuleShape>(bunTestMod
|
|
|
775
818
|
* `useTestSpan()` preserves the suite-local schema extension instead of falling
|
|
776
819
|
* back to the erased global singleton shape.
|
|
777
820
|
*/
|
|
778
|
-
export function useTestSpan<
|
|
779
|
-
export function useTestSpan():
|
|
821
|
+
export function useTestSpan<B extends OpContextBinding>(): SpanContext<OpContextOf<B>>;
|
|
822
|
+
export function useTestSpan(): unknown {
|
|
780
823
|
if (_activeSuiteTracer) {
|
|
781
|
-
|
|
824
|
+
const ctx = _activeSuiteTracer.useTestSpan();
|
|
825
|
+
if (!isSpanContext<OpContextOf<OpContextBinding>>(ctx)) {
|
|
826
|
+
throw new TypeError('Active test tracer returned an invalid span context');
|
|
827
|
+
}
|
|
828
|
+
return ctx;
|
|
782
829
|
}
|
|
783
830
|
|
|
784
831
|
const ctx = _als.getStore();
|
|
@@ -795,10 +842,14 @@ export function useTestSpan(): SpanContext<OpContextOf<OpContextBinding>> {
|
|
|
795
842
|
*/
|
|
796
843
|
export function getTracer(): Tracer<OpContextBinding> {
|
|
797
844
|
if (_activeSuiteTracer) {
|
|
798
|
-
|
|
845
|
+
const tracer = _activeSuiteTracer.getTracer();
|
|
846
|
+
if (!isTracerInstance(tracer)) {
|
|
847
|
+
throw new TypeError('Active test tracer returned an invalid tracer');
|
|
848
|
+
}
|
|
849
|
+
return tracer;
|
|
799
850
|
}
|
|
800
851
|
|
|
801
|
-
if (!_tracer) throw new Error('Call initTraceTestRun() in preload before tests');
|
|
852
|
+
if (!isTracerInstance(_tracer)) throw new Error('Call initTraceTestRun() in preload before tests');
|
|
802
853
|
return _tracer;
|
|
803
854
|
}
|
|
804
855
|
|
|
@@ -887,7 +938,7 @@ assignOptionalBoundTestFunction(describe, 'if', _describe, _describe);
|
|
|
887
938
|
export function it(name: string, fn: () => void | Promise<void>): void {
|
|
888
939
|
const describePath = _standaloneDescribeStack.length > 0 ? _standaloneDescribeStack.join(' > ') : null;
|
|
889
940
|
_it(name, () => {
|
|
890
|
-
if (!_rootCtx) throw new Error('Call initTraceTestRun() in preload before tests');
|
|
941
|
+
if (!isSpanContext(_rootCtx)) throw new Error('Call initTraceTestRun() in preload before tests');
|
|
891
942
|
return _rootCtx.span(name, async (ctx: SpanContext<OpContext>) => {
|
|
892
943
|
writeDescribeTag(ctx.tag, describePath);
|
|
893
944
|
try {
|