@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.
Files changed (285) hide show
  1. package/README.md +206 -206
  2. package/dist/allocator.wasm +0 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -0
  6. package/dist/lib/JsBufferStrategy.d.ts +4 -3
  7. package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
  8. package/dist/lib/JsBufferStrategy.js +18 -11
  9. package/dist/lib/arrow/lease.d.ts +10 -0
  10. package/dist/lib/arrow/lease.d.ts.map +1 -0
  11. package/dist/lib/arrow/lease.js +33 -0
  12. package/dist/lib/arrow/utils.d.ts +3 -4
  13. package/dist/lib/arrow/utils.d.ts.map +1 -1
  14. package/dist/lib/arrow/utils.js +12 -13
  15. package/dist/lib/arrow/vocabularyDictionary.d.ts +21 -0
  16. package/dist/lib/arrow/vocabularyDictionary.d.ts.map +1 -0
  17. package/dist/lib/arrow/vocabularyDictionary.js +95 -0
  18. package/dist/lib/bufferStrategy.d.ts +3 -2
  19. package/dist/lib/bufferStrategy.d.ts.map +1 -1
  20. package/dist/lib/cloudflare/traceRows.d.ts.map +1 -1
  21. package/dist/lib/cloudflare/traceRows.js +3 -2
  22. package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
  23. package/dist/lib/codegen/evaluatorGenerator.js +12 -11
  24. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +44 -82
  25. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
  26. package/dist/lib/codegen/fixedPositionWriterGenerator.js +223 -162
  27. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts +63 -0
  28. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts.map +1 -0
  29. package/dist/lib/codegen/spanLoggerClosureMaterializer.js +447 -0
  30. package/dist/lib/codegen/spanLoggerGenerator.d.ts +36 -19
  31. package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
  32. package/dist/lib/codegen/spanLoggerGenerator.js +164 -158
  33. package/dist/lib/convertToArrow.d.ts +7 -2
  34. package/dist/lib/convertToArrow.d.ts.map +1 -1
  35. package/dist/lib/convertToArrow.js +499 -285
  36. package/dist/lib/defineOpContext.js +1 -1
  37. package/dist/lib/enumMetadata.d.ts +19 -0
  38. package/dist/lib/enumMetadata.d.ts.map +1 -0
  39. package/dist/lib/enumMetadata.js +86 -0
  40. package/dist/lib/flushScheduler.d.ts.map +1 -1
  41. package/dist/lib/flushScheduler.js +13 -4
  42. package/dist/lib/library.d.ts +16 -98
  43. package/dist/lib/library.d.ts.map +1 -1
  44. package/dist/lib/library.js +32 -525
  45. package/dist/lib/logBinding.d.ts +21 -27
  46. package/dist/lib/logBinding.d.ts.map +1 -1
  47. package/dist/lib/op.d.ts +30 -30
  48. package/dist/lib/op.d.ts.map +1 -1
  49. package/dist/lib/op.js +15 -22
  50. package/dist/lib/opContext/createOpGroup.d.ts +1 -1
  51. package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
  52. package/dist/lib/opContext/createOpGroup.js +22 -29
  53. package/dist/lib/opContext/defineOp.d.ts +4 -4
  54. package/dist/lib/opContext/defineOp.d.ts.map +1 -1
  55. package/dist/lib/opContext/defineOp.js +53 -10
  56. package/dist/lib/opContext/opGroupTypes.d.ts +2 -2
  57. package/dist/lib/opContext/opTypes.d.ts +1 -1
  58. package/dist/lib/opContext/opTypes.d.ts.map +1 -1
  59. package/dist/lib/opContext/spanContextTypes.d.ts +33 -18
  60. package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -1
  61. package/dist/lib/opContext/types.d.ts +4 -4
  62. package/dist/lib/opContext/types.d.ts.map +1 -1
  63. package/dist/lib/physicalLayoutPlan.d.ts +89 -0
  64. package/dist/lib/physicalLayoutPlan.d.ts.map +1 -0
  65. package/dist/lib/physicalLayoutPlan.js +442 -0
  66. package/dist/lib/resolveMessage.d.ts +9 -0
  67. package/dist/lib/resolveMessage.d.ts.map +1 -0
  68. package/dist/lib/resolveMessage.js +63 -0
  69. package/dist/lib/result.d.ts +5 -7
  70. package/dist/lib/result.d.ts.map +1 -1
  71. package/dist/lib/result.js +19 -26
  72. package/dist/lib/runtimeHint.d.ts +35 -0
  73. package/dist/lib/runtimeHint.d.ts.map +1 -0
  74. package/dist/lib/runtimeHint.js +79 -0
  75. package/dist/lib/schema/typeGuards.d.ts +7 -47
  76. package/dist/lib/schema/typeGuards.d.ts.map +1 -1
  77. package/dist/lib/schema/typeGuards.js +7 -123
  78. package/dist/lib/schema/types.d.ts +1 -1
  79. package/dist/lib/schema/types.d.ts.map +1 -1
  80. package/dist/lib/span-buffer/aot/v1.d.ts +2 -0
  81. package/dist/lib/span-buffer/aot/v1.d.ts.map +1 -0
  82. package/dist/lib/span-buffer/aot/v1.js +24 -0
  83. package/dist/lib/spanBuffer.d.ts +33 -4
  84. package/dist/lib/spanBuffer.d.ts.map +1 -1
  85. package/dist/lib/spanBuffer.js +583 -91
  86. package/dist/lib/spanBufferStats.d.ts +1 -1
  87. package/dist/lib/spanBufferStats.d.ts.map +1 -1
  88. package/dist/lib/spanContext.d.ts +27 -51
  89. package/dist/lib/spanContext.d.ts.map +1 -1
  90. package/dist/lib/spanContext.js +822 -344
  91. package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
  92. package/dist/lib/sqlite/sqlite-common.js +20 -21
  93. package/dist/lib/testing/bun-harness.d.ts +8 -3
  94. package/dist/lib/testing/bun-harness.d.ts.map +1 -1
  95. package/dist/lib/testing/bun-harness.js +30 -18
  96. package/dist/lib/testing/extractFacts.d.ts +1 -1
  97. package/dist/lib/testing/extractFacts.d.ts.map +1 -1
  98. package/dist/lib/testing/extractFacts.js +55 -63
  99. package/dist/lib/testing/facts.d.ts +1 -1
  100. package/dist/lib/testing/facts.d.ts.map +1 -1
  101. package/dist/lib/testing/queryable-span.d.ts +1 -1
  102. package/dist/lib/testing/queryable-span.d.ts.map +1 -1
  103. package/dist/lib/testing/queryable-span.js +26 -28
  104. package/dist/lib/testing/span-query.d.ts.map +1 -1
  105. package/dist/lib/testing/span-query.js +19 -22
  106. package/dist/lib/testing/stdio-replay.d.ts.map +1 -1
  107. package/dist/lib/testing/stdio-replay.js +19 -8
  108. package/dist/lib/threadId.d.ts.map +1 -1
  109. package/dist/lib/threadId.js +6 -3
  110. package/dist/lib/traceContext.d.ts.map +1 -1
  111. package/dist/lib/traceContext.js +1 -4
  112. package/dist/lib/traceRoot.d.ts +30 -8
  113. package/dist/lib/traceRoot.d.ts.map +1 -1
  114. package/dist/lib/traceRoot.es.d.ts +17 -15
  115. package/dist/lib/traceRoot.es.d.ts.map +1 -1
  116. package/dist/lib/traceRoot.es.js +68 -34
  117. package/dist/lib/traceRoot.js +11 -0
  118. package/dist/lib/traceRoot.node.d.ts +17 -19
  119. package/dist/lib/traceRoot.node.d.ts.map +1 -1
  120. package/dist/lib/traceRoot.node.js +66 -38
  121. package/dist/lib/traceTopology.d.ts +42 -0
  122. package/dist/lib/traceTopology.d.ts.map +1 -0
  123. package/dist/lib/traceTopology.js +260 -0
  124. package/dist/lib/tracer.d.ts +9 -5
  125. package/dist/lib/tracer.d.ts.map +1 -1
  126. package/dist/lib/tracer.js +65 -71
  127. package/dist/lib/tracers/ArrayQueueTracer.d.ts +1 -1
  128. package/dist/lib/tracers/ArrayQueueTracer.js +1 -1
  129. package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
  130. package/dist/lib/tracers/StdioTracer.js +15 -13
  131. package/dist/lib/tracers/TestTracer.d.ts +4 -6
  132. package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
  133. package/dist/lib/tracers/TestTracer.js +6 -8
  134. package/dist/lib/types.d.ts +49 -32
  135. package/dist/lib/types.d.ts.map +1 -1
  136. package/dist/lib/vocabularyRegistry.d.ts +25 -0
  137. package/dist/lib/vocabularyRegistry.d.ts.map +1 -0
  138. package/dist/lib/vocabularyRegistry.js +372 -0
  139. package/dist/lib/wasm/WasmBufferStrategy.d.ts +6 -10
  140. package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
  141. package/dist/lib/wasm/WasmBufferStrategy.js +44 -37
  142. package/dist/lib/wasm/wasmAllocator.d.ts +27 -22
  143. package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
  144. package/dist/lib/wasm/wasmAllocator.js +66 -44
  145. package/dist/lib/wasm/wasmPhysicalLayout.d.ts +67 -0
  146. package/dist/lib/wasm/wasmPhysicalLayout.d.ts.map +1 -0
  147. package/dist/lib/wasm/wasmPhysicalLayout.js +179 -0
  148. package/dist/lib/wasm/wasmSpanBuffer.d.ts +79 -31
  149. package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
  150. package/dist/lib/wasm/wasmSpanBuffer.js +442 -272
  151. package/dist/lib/wasm/wasmTraceRoot.d.ts +24 -22
  152. package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
  153. package/dist/lib/wasm/wasmTraceRoot.js +110 -71
  154. package/dist/vocabulary/register/v1.d.ts +2 -0
  155. package/dist/vocabulary/register/v1.d.ts.map +1 -0
  156. package/dist/vocabulary/register/v1.js +1 -0
  157. package/dist/wasm.d.ts +5 -0
  158. package/dist/wasm.d.ts.map +1 -0
  159. package/dist/wasm.js +4 -0
  160. package/package.json +54 -6
  161. package/src/index.ts +1 -0
  162. package/src/lib/JsBufferStrategy.ts +27 -9
  163. package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +335 -37
  164. package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +97 -26
  165. package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +75 -15
  166. package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +30 -6
  167. package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +18 -21
  168. package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +5 -2
  169. package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +25 -7
  170. package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +3 -2
  171. package/src/lib/__tests__/buffer-overflow.test.ts +24 -18
  172. package/src/lib/__tests__/capability-span-context.test.ts +505 -0
  173. package/src/lib/__tests__/capacity-tuning.test.ts +5 -3
  174. package/src/lib/__tests__/eager-columns.test.ts +345 -0
  175. package/src/lib/__tests__/enum-metadata-aot.test.ts +153 -0
  176. package/src/lib/__tests__/enum-metadata.test.ts +177 -0
  177. package/src/lib/__tests__/fixtures/empty-vocabulary-runtime.fixture.ts +15 -0
  178. package/src/lib/__tests__/flushScheduler.test.ts +5 -1
  179. package/src/lib/__tests__/identity-view.property.test.ts +179 -0
  180. package/src/lib/__tests__/library.test.ts +19 -235
  181. package/src/lib/__tests__/message-buffer-families.test.ts +878 -0
  182. package/src/lib/__tests__/nested-library-tasks.test.ts +14 -15
  183. package/src/lib/__tests__/op-metadata.test.ts +1 -1
  184. package/src/lib/__tests__/op-type-safety.test.ts +5 -16
  185. package/src/lib/__tests__/physical-layout-plan.test.ts +333 -0
  186. package/src/lib/__tests__/remap-descriptor-integration.test.ts +381 -0
  187. package/src/lib/__tests__/root-context-construction.test.ts +414 -0
  188. package/src/lib/__tests__/span-auto-runtime.test.ts +386 -0
  189. package/src/lib/__tests__/span-buffer-segment-stats.test.ts +221 -0
  190. package/src/lib/__tests__/span-lifecycle.test.ts +53 -25
  191. package/src/lib/__tests__/spanbuffer-materializer-parity.test.ts +266 -0
  192. package/src/lib/__tests__/sync-async-trace.test.ts +24 -23
  193. package/src/lib/__tests__/tag-writer-aot.test.ts +214 -0
  194. package/src/lib/__tests__/test-helpers.ts +67 -12
  195. package/src/lib/__tests__/threadId.test.ts +62 -0
  196. package/src/lib/__tests__/timestamp.test.ts +221 -93
  197. package/src/lib/__tests__/traceTopology.property.test.ts +383 -0
  198. package/src/lib/__tests__/type-narrowing.test.ts +63 -0
  199. package/src/lib/__tests__/vocabulary-dense-decoding.test.ts +405 -0
  200. package/src/lib/__tests__/vocabularyRegistry.test.ts +313 -0
  201. package/src/lib/arrow/lease.ts +43 -0
  202. package/src/lib/arrow/utils.ts +10 -14
  203. package/src/lib/arrow/vocabularyDictionary.ts +123 -0
  204. package/src/lib/bufferStrategy.ts +9 -1
  205. package/src/lib/cloudflare/traceRows.ts +3 -2
  206. package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +21 -141
  207. package/src/lib/codegen/__tests__/fixedPositionWriter-parity.test.ts +273 -0
  208. package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +61 -34
  209. package/src/lib/codegen/__tests__/nullBitmap.test.ts +33 -37
  210. package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +34 -18
  211. package/src/lib/codegen/__tests__/spanLoggerMaterializerParity.test.ts +503 -0
  212. package/src/lib/codegen/evaluatorGenerator.ts +18 -13
  213. package/src/lib/codegen/fixedPositionWriterGenerator.ts +329 -245
  214. package/src/lib/codegen/spanLoggerClosureMaterializer.ts +598 -0
  215. package/src/lib/codegen/spanLoggerGenerator.ts +241 -177
  216. package/src/lib/convertToArrow.ts +598 -311
  217. package/src/lib/defineOpContext.ts +1 -1
  218. package/src/lib/enumMetadata.ts +121 -0
  219. package/src/lib/flushScheduler.ts +11 -5
  220. package/src/lib/library.ts +37 -595
  221. package/src/lib/logBinding.ts +21 -27
  222. package/src/lib/op.ts +75 -18
  223. package/src/lib/opContext/__tests__/retry.test.ts +27 -21
  224. package/src/lib/opContext/createOpGroup.ts +33 -31
  225. package/src/lib/opContext/defineOp.ts +88 -11
  226. package/src/lib/opContext/opGroupTypes.ts +2 -2
  227. package/src/lib/opContext/opTypes.ts +1 -1
  228. package/src/lib/opContext/spanContextTypes.ts +122 -24
  229. package/src/lib/opContext/types.ts +7 -3
  230. package/src/lib/physicalLayoutPlan.ts +598 -0
  231. package/src/lib/resolveMessage.ts +67 -0
  232. package/src/lib/result.ts +20 -33
  233. package/src/lib/runtimeHint.ts +98 -0
  234. package/src/lib/schema/__tests__/featureFlags.test.ts +2 -1
  235. package/src/lib/schema/builder.ts +1 -1
  236. package/src/lib/schema/typeGuards.ts +7 -151
  237. package/src/lib/schema/types.ts +1 -1
  238. package/src/lib/span-buffer/aot/v1.ts +26 -0
  239. package/src/lib/spanBuffer.ts +658 -92
  240. package/src/lib/spanBufferStats.ts +1 -1
  241. package/src/lib/spanContext.ts +1350 -861
  242. package/src/lib/sqlite/sqlite-common.ts +20 -31
  243. package/src/lib/testing/__tests__/topology-traversal.test.ts +174 -0
  244. package/src/lib/testing/__tests__/vitest-harness.test.ts +2 -1
  245. package/src/lib/testing/bun-harness.ts +94 -43
  246. package/src/lib/testing/extractFacts.ts +64 -78
  247. package/src/lib/testing/facts.ts +1 -1
  248. package/src/lib/testing/queryable-span.ts +23 -30
  249. package/src/lib/testing/span-query.ts +16 -20
  250. package/src/lib/testing/stdio-replay.ts +25 -8
  251. package/src/lib/testing/vitest-harness.ts +1 -1
  252. package/src/lib/threadId.ts +6 -3
  253. package/src/lib/traceContext.ts +1 -6
  254. package/src/lib/traceRoot.es.ts +77 -42
  255. package/src/lib/traceRoot.node.ts +75 -46
  256. package/src/lib/traceRoot.ts +41 -14
  257. package/src/lib/traceTopology.ts +279 -0
  258. package/src/lib/tracer.ts +109 -98
  259. package/src/lib/tracers/ArrayQueueTracer.ts +1 -1
  260. package/src/lib/tracers/StdioTracer.ts +15 -13
  261. package/src/lib/tracers/TestTracer.ts +6 -8
  262. package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +15 -10
  263. package/src/lib/tracers/__tests__/CompositeTracer.test.ts +150 -0
  264. package/src/lib/tracers/__tests__/TestTracer.test.ts +23 -13
  265. package/src/lib/types.ts +64 -33
  266. package/src/lib/vocabularyRegistry.ts +439 -0
  267. package/src/lib/wasm/WasmBufferStrategy.ts +56 -48
  268. package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +215 -11
  269. package/src/lib/wasm/__tests__/allocatorFreeBlockClamp.test.ts +86 -0
  270. package/src/lib/wasm/__tests__/wasm-identity-view.test.ts +311 -0
  271. package/src/lib/wasm/__tests__/wasm-integration.test.ts +417 -44
  272. package/src/lib/wasm/__tests__/wasm-message-buffer-families.test.ts +588 -0
  273. package/src/lib/wasm/__tests__/wasmAllocator.test.ts +100 -668
  274. package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +419 -63
  275. package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +24 -29
  276. package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +2 -2
  277. package/src/lib/wasm/wasmAllocator.ts +131 -96
  278. package/src/lib/wasm/wasmPhysicalLayout.ts +309 -0
  279. package/src/lib/wasm/wasmSpanBuffer.ts +597 -341
  280. package/src/lib/wasm/wasmTraceRoot.ts +140 -78
  281. package/src/vocabulary/register/v1.ts +1 -0
  282. package/src/wasm.ts +19 -0
  283. package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +0 -319
  284. package/src/lib/__tests__/remapped-buffer-view.test.ts +0 -635
  285. 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
- yield* walkTree(rootBuffer);
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.entry_type[row];
293
+ const entryType = resolveEntryType(buffer, row);
305
294
  const timestampNs = Number(buffer.timestamp[row]);
306
- const message = buffer.message_values[row] ?? null;
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
- expect(getTracer()).toBe(tracer.getTracer());
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
- > = ReturnType<typeof makeBunTestSuiteTracer<B, TExt>>['useTestTracer'];
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
- type ActiveBunTestTracer = BunTestTracerInstance<OpContextBinding>;
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
- ): BunTestSuiteTracer<OpContextBinding> {
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
- // WHY no re-validation: the global useTestSpan() already validates against
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
- ): BunTestTracerInstance<OpContextBinding> {
426
+ ) {
386
427
  return createTestTracerInstance(binding, options);
387
428
  }
388
- function createTestTracerInstance<B extends OpContextBinding, TExt extends SchemaFields = Record<never, never>>(
389
- binding: B,
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<OpContextBinding> {
392
- let activeBinding: OpContextBinding | null = null;
393
- let tracer: Tracer<OpContextBinding> | null = null;
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: SpanContext<OpContext> | null = null;
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<SpanContext<OpContext>>();
447
+ const als = new AsyncLocalStorage<HarnessSpanContext<RuntimeHarnessBinding<TFields, FF, Deps, UserCtx, TExt>>>();
401
448
 
402
- function assertRootCtx(): SpanContext<OpContext> {
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<OpContextBinding> {
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 harnessSchema =
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: SpanContext<OpContext>) => {
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(): SpanContext<OpContext> {
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<OpContextBinding> {
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: Tracer<OpContextBinding> | null = null;
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: SpanContext<OpContext> | null = null;
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
- _tracer = createRootTracer({
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
- const tracer = _tracer;
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
- }) as Promise<unknown>;
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: SpanContext<OpContext>) => {
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<TCtx extends SpanContext<OpContextOf<OpContextBinding>>>(): TCtx;
779
- export function useTestSpan(): SpanContext<OpContextOf<OpContextBinding>> {
821
+ export function useTestSpan<B extends OpContextBinding>(): SpanContext<OpContextOf<B>>;
822
+ export function useTestSpan(): unknown {
780
823
  if (_activeSuiteTracer) {
781
- return _activeSuiteTracer.useTestSpan();
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
- return _activeSuiteTracer.getTracer();
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 {