@smoothbricks/lmao 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +269 -0
- package/dist/allocator.wasm +0 -0
- package/dist/bun/preload.d.ts +11 -0
- package/dist/bun/preload.d.ts.map +1 -0
- package/dist/bun/preload.js +10 -0
- package/dist/bun/trace-preload.d.ts +8 -0
- package/dist/bun/trace-preload.d.ts.map +1 -0
- package/dist/bun/trace-preload.js +12 -0
- package/dist/es.d.ts +8 -0
- package/dist/es.d.ts.map +1 -0
- package/dist/es.js +9 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/lib/JsBufferStrategy.d.ts +49 -0
- package/dist/lib/JsBufferStrategy.d.ts.map +1 -0
- package/dist/lib/JsBufferStrategy.js +60 -0
- package/dist/lib/archive/chunkCompaction.d.ts +15 -0
- package/dist/lib/archive/chunkCompaction.d.ts.map +1 -0
- package/dist/lib/archive/chunkCompaction.js +24 -0
- package/dist/lib/archive/chunkEnvelope.d.ts +21 -0
- package/dist/lib/archive/chunkEnvelope.d.ts.map +1 -0
- package/dist/lib/archive/chunkEnvelope.js +55 -0
- package/dist/lib/archive/chunkRouting.d.ts +10 -0
- package/dist/lib/archive/chunkRouting.d.ts.map +1 -0
- package/dist/lib/archive/chunkRouting.js +47 -0
- package/dist/lib/archive/chunkStats.d.ts +12 -0
- package/dist/lib/archive/chunkStats.d.ts.map +1 -0
- package/dist/lib/archive/chunkStats.js +10 -0
- package/dist/lib/archive/index.d.ts +5 -0
- package/dist/lib/archive/index.d.ts.map +1 -0
- package/dist/lib/archive/index.js +4 -0
- package/dist/lib/arrow/capacityStats.d.ts +9 -0
- package/dist/lib/arrow/capacityStats.d.ts.map +1 -0
- package/dist/lib/arrow/capacityStats.js +231 -0
- package/dist/lib/arrow/dictionaries.d.ts +27 -0
- package/dist/lib/arrow/dictionaries.d.ts.map +1 -0
- package/dist/lib/arrow/dictionaries.js +135 -0
- package/dist/lib/arrow/flechette.d.ts +40 -0
- package/dist/lib/arrow/flechette.d.ts.map +1 -0
- package/dist/lib/arrow/flechette.js +67 -0
- package/dist/lib/arrow/utils.d.ts +38 -0
- package/dist/lib/arrow/utils.d.ts.map +1 -0
- package/dist/lib/arrow/utils.js +112 -0
- package/dist/lib/buffer/Nanoseconds.d.ts +109 -0
- package/dist/lib/buffer/Nanoseconds.d.ts.map +1 -0
- package/dist/lib/buffer/Nanoseconds.js +86 -0
- package/dist/lib/bufferStrategy.d.ts +95 -0
- package/dist/lib/bufferStrategy.d.ts.map +1 -0
- package/dist/lib/bufferStrategy.js +1 -0
- package/dist/lib/capacityTuning.d.ts +50 -0
- package/dist/lib/capacityTuning.d.ts.map +1 -0
- package/dist/lib/capacityTuning.js +65 -0
- package/dist/lib/codegen/evaluatorGenerator.d.ts +35 -0
- package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -0
- package/dist/lib/codegen/evaluatorGenerator.js +199 -0
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +139 -0
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -0
- package/dist/lib/codegen/fixedPositionWriterGenerator.js +289 -0
- package/dist/lib/codegen/spanLoggerGenerator.d.ts +115 -0
- package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -0
- package/dist/lib/codegen/spanLoggerGenerator.js +575 -0
- package/dist/lib/convertToArrow.d.ts +40 -0
- package/dist/lib/convertToArrow.d.ts.map +1 -0
- package/dist/lib/convertToArrow.js +1467 -0
- package/dist/lib/defineOpContext.d.ts +96 -0
- package/dist/lib/defineOpContext.d.ts.map +1 -0
- package/dist/lib/defineOpContext.js +227 -0
- package/dist/lib/errors/Blocked.d.ts +113 -0
- package/dist/lib/errors/Blocked.d.ts.map +1 -0
- package/dist/lib/errors/Blocked.js +68 -0
- package/dist/lib/errors/CodeError.d.ts +101 -0
- package/dist/lib/errors/CodeError.d.ts.map +1 -0
- package/dist/lib/errors/CodeError.js +42 -0
- package/dist/lib/errors/RetriesExhausted.d.ts +67 -0
- package/dist/lib/errors/RetriesExhausted.d.ts.map +1 -0
- package/dist/lib/errors/RetriesExhausted.js +31 -0
- package/dist/lib/errors/Transient.d.ts +115 -0
- package/dist/lib/errors/Transient.d.ts.map +1 -0
- package/dist/lib/errors/Transient.js +54 -0
- package/dist/lib/errors/index.d.ts +14 -0
- package/dist/lib/errors/index.d.ts.map +1 -0
- package/dist/lib/errors/index.js +16 -0
- package/dist/lib/errors/retry-policy.d.ts +60 -0
- package/dist/lib/errors/retry-policy.d.ts.map +1 -0
- package/dist/lib/errors/retry-policy.js +54 -0
- package/dist/lib/flushScheduler.d.ts +162 -0
- package/dist/lib/flushScheduler.d.ts.map +1 -0
- package/dist/lib/flushScheduler.js +388 -0
- package/dist/lib/library.d.ts +149 -0
- package/dist/lib/library.d.ts.map +1 -0
- package/dist/lib/library.js +588 -0
- package/dist/lib/logApi.d.ts +61 -0
- package/dist/lib/logApi.d.ts.map +1 -0
- package/dist/lib/logApi.js +12 -0
- package/dist/lib/logBinding.d.ts +63 -0
- package/dist/lib/logBinding.d.ts.map +1 -0
- package/dist/lib/logBinding.js +1 -0
- package/dist/lib/op.d.ts +105 -0
- package/dist/lib/op.d.ts.map +1 -0
- package/dist/lib/op.js +59 -0
- package/dist/lib/opContext/contextTypes.d.ts +88 -0
- package/dist/lib/opContext/contextTypes.d.ts.map +1 -0
- package/dist/lib/opContext/contextTypes.js +34 -0
- package/dist/lib/opContext/createOpGroup.d.ts +57 -0
- package/dist/lib/opContext/createOpGroup.d.ts.map +1 -0
- package/dist/lib/opContext/createOpGroup.js +341 -0
- package/dist/lib/opContext/defineOp.d.ts +83 -0
- package/dist/lib/opContext/defineOp.d.ts.map +1 -0
- package/dist/lib/opContext/defineOp.js +197 -0
- package/dist/lib/opContext/featureFlagTypes.d.ts +58 -0
- package/dist/lib/opContext/featureFlagTypes.d.ts.map +1 -0
- package/dist/lib/opContext/featureFlagTypes.js +1 -0
- package/dist/lib/opContext/index.d.ts +13 -0
- package/dist/lib/opContext/index.d.ts.map +1 -0
- package/dist/lib/opContext/index.js +15 -0
- package/dist/lib/opContext/opGroupTypes.d.ts +250 -0
- package/dist/lib/opContext/opGroupTypes.d.ts.map +1 -0
- package/dist/lib/opContext/opGroupTypes.js +31 -0
- package/dist/lib/opContext/opTypes.d.ts +48 -0
- package/dist/lib/opContext/opTypes.d.ts.map +1 -0
- package/dist/lib/opContext/opTypes.js +7 -0
- package/dist/lib/opContext/spanContextTypes.d.ts +347 -0
- package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -0
- package/dist/lib/opContext/spanContextTypes.js +1 -0
- package/dist/lib/opContext/types.d.ts +297 -0
- package/dist/lib/opContext/types.d.ts.map +1 -0
- package/dist/lib/opContext/types.js +16 -0
- package/dist/lib/result.d.ts +308 -0
- package/dist/lib/result.d.ts.map +1 -0
- package/dist/lib/result.js +359 -0
- package/dist/lib/schema/LogSchema.d.ts +62 -0
- package/dist/lib/schema/LogSchema.d.ts.map +1 -0
- package/dist/lib/schema/LogSchema.js +134 -0
- package/dist/lib/schema/builder.d.ts +12 -0
- package/dist/lib/schema/builder.d.ts.map +1 -0
- package/dist/lib/schema/builder.js +169 -0
- package/dist/lib/schema/defineFeatureFlags.d.ts +60 -0
- package/dist/lib/schema/defineFeatureFlags.d.ts.map +1 -0
- package/dist/lib/schema/defineFeatureFlags.js +29 -0
- package/dist/lib/schema/defineLogSchema.d.ts +87 -0
- package/dist/lib/schema/defineLogSchema.d.ts.map +1 -0
- package/dist/lib/schema/defineLogSchema.js +171 -0
- package/dist/lib/schema/evaluator.d.ts +267 -0
- package/dist/lib/schema/evaluator.d.ts.map +1 -0
- package/dist/lib/schema/evaluator.js +169 -0
- package/dist/lib/schema/extend.d.ts +14 -0
- package/dist/lib/schema/extend.d.ts.map +1 -0
- package/dist/lib/schema/extend.js +51 -0
- package/dist/lib/schema/systemSchema.d.ts +112 -0
- package/dist/lib/schema/systemSchema.d.ts.map +1 -0
- package/dist/lib/schema/systemSchema.js +260 -0
- package/dist/lib/schema/typeGuards.d.ts +52 -0
- package/dist/lib/schema/typeGuards.d.ts.map +1 -0
- package/dist/lib/schema/typeGuards.js +127 -0
- package/dist/lib/schema/types.d.ts +156 -0
- package/dist/lib/schema/types.d.ts.map +1 -0
- package/dist/lib/schema/types.js +4 -0
- package/dist/lib/spanBuffer.d.ts +133 -0
- package/dist/lib/spanBuffer.d.ts.map +1 -0
- package/dist/lib/spanBuffer.js +442 -0
- package/dist/lib/spanBufferHelpers.d.ts +53 -0
- package/dist/lib/spanBufferHelpers.d.ts.map +1 -0
- package/dist/lib/spanBufferHelpers.js +65 -0
- package/dist/lib/spanBufferStats.d.ts +38 -0
- package/dist/lib/spanBufferStats.d.ts.map +1 -0
- package/dist/lib/spanBufferStats.js +1 -0
- package/dist/lib/spanContext.d.ts +141 -0
- package/dist/lib/spanContext.d.ts.map +1 -0
- package/dist/lib/spanContext.js +763 -0
- package/dist/lib/sqlite/index.d.ts +14 -0
- package/dist/lib/sqlite/index.d.ts.map +1 -0
- package/dist/lib/sqlite/index.js +12 -0
- package/dist/lib/sqlite/sqlite-async-writer.d.ts +24 -0
- package/dist/lib/sqlite/sqlite-async-writer.d.ts.map +1 -0
- package/dist/lib/sqlite/sqlite-async-writer.js +65 -0
- package/dist/lib/sqlite/sqlite-common.d.ts +37 -0
- package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -0
- package/dist/lib/sqlite/sqlite-common.js +207 -0
- package/dist/lib/sqlite/sqlite-d1.d.ts +25 -0
- package/dist/lib/sqlite/sqlite-d1.d.ts.map +1 -0
- package/dist/lib/sqlite/sqlite-d1.js +67 -0
- package/dist/lib/sqlite/sqlite-db.d.ts +29 -0
- package/dist/lib/sqlite/sqlite-db.d.ts.map +1 -0
- package/dist/lib/sqlite/sqlite-db.js +1 -0
- package/dist/lib/sqlite/sqlite-node.d.ts +16 -0
- package/dist/lib/sqlite/sqlite-node.d.ts.map +1 -0
- package/dist/lib/sqlite/sqlite-node.js +68 -0
- package/dist/lib/sqlite/sqlite-writer.d.ts +39 -0
- package/dist/lib/sqlite/sqlite-writer.d.ts.map +1 -0
- package/dist/lib/sqlite/sqlite-writer.js +78 -0
- package/dist/lib/testing/bun-harness.d.ts +150 -0
- package/dist/lib/testing/bun-harness.d.ts.map +1 -0
- package/dist/lib/testing/bun-harness.js +729 -0
- package/dist/lib/testing/extractFacts.d.ts +73 -0
- package/dist/lib/testing/extractFacts.d.ts.map +1 -0
- package/dist/lib/testing/extractFacts.js +237 -0
- package/dist/lib/testing/facts.d.ts +235 -0
- package/dist/lib/testing/facts.d.ts.map +1 -0
- package/dist/lib/testing/facts.js +209 -0
- package/dist/lib/testing/index.d.ts +58 -0
- package/dist/lib/testing/index.d.ts.map +1 -0
- package/dist/lib/testing/index.js +74 -0
- package/dist/lib/testing/queryable-span.d.ts +39 -0
- package/dist/lib/testing/queryable-span.d.ts.map +1 -0
- package/dist/lib/testing/queryable-span.js +58 -0
- package/dist/lib/testing/span-query.d.ts +21 -0
- package/dist/lib/testing/span-query.d.ts.map +1 -0
- package/dist/lib/testing/span-query.js +47 -0
- package/dist/lib/testing/stdio-replay.d.ts +4 -0
- package/dist/lib/testing/stdio-replay.d.ts.map +1 -0
- package/dist/lib/testing/stdio-replay.js +42 -0
- package/dist/lib/testing/trace-query.d.ts +59 -0
- package/dist/lib/testing/trace-query.d.ts.map +1 -0
- package/dist/lib/testing/trace-query.js +462 -0
- package/dist/lib/testing/vitest-harness.d.ts +135 -0
- package/dist/lib/testing/vitest-harness.d.ts.map +1 -0
- package/dist/lib/testing/vitest-harness.js +486 -0
- package/dist/lib/threadId.d.ts +58 -0
- package/dist/lib/threadId.d.ts.map +1 -0
- package/dist/lib/threadId.js +123 -0
- package/dist/lib/traceContext.d.ts +116 -0
- package/dist/lib/traceContext.d.ts.map +1 -0
- package/dist/lib/traceContext.js +37 -0
- package/dist/lib/traceId.d.ts +78 -0
- package/dist/lib/traceId.d.ts.map +1 -0
- package/dist/lib/traceId.js +87 -0
- package/dist/lib/traceRoot.d.ts +133 -0
- package/dist/lib/traceRoot.d.ts.map +1 -0
- package/dist/lib/traceRoot.es.d.ts +75 -0
- package/dist/lib/traceRoot.es.d.ts.map +1 -0
- package/dist/lib/traceRoot.es.js +129 -0
- package/dist/lib/traceRoot.js +19 -0
- package/dist/lib/traceRoot.node.d.ts +77 -0
- package/dist/lib/traceRoot.node.d.ts.map +1 -0
- package/dist/lib/traceRoot.node.js +133 -0
- package/dist/lib/traceRoot.universal.d.ts +3 -0
- package/dist/lib/traceRoot.universal.d.ts.map +1 -0
- package/dist/lib/traceRoot.universal.js +17 -0
- package/dist/lib/tracer.d.ts +296 -0
- package/dist/lib/tracer.d.ts.map +1 -0
- package/dist/lib/tracer.js +346 -0
- package/dist/lib/tracers/ArrayQueueTracer.d.ts +56 -0
- package/dist/lib/tracers/ArrayQueueTracer.d.ts.map +1 -0
- package/dist/lib/tracers/ArrayQueueTracer.js +67 -0
- package/dist/lib/tracers/CompositeTracer.d.ts +24 -0
- package/dist/lib/tracers/CompositeTracer.d.ts.map +1 -0
- package/dist/lib/tracers/CompositeTracer.js +57 -0
- package/dist/lib/tracers/NoOpTracer.d.ts +58 -0
- package/dist/lib/tracers/NoOpTracer.d.ts.map +1 -0
- package/dist/lib/tracers/NoOpTracer.js +41 -0
- package/dist/lib/tracers/SQLiteTracer.d.ts +42 -0
- package/dist/lib/tracers/SQLiteTracer.d.ts.map +1 -0
- package/dist/lib/tracers/SQLiteTracer.js +84 -0
- package/dist/lib/tracers/StdioTracer.d.ts +83 -0
- package/dist/lib/tracers/StdioTracer.d.ts.map +1 -0
- package/dist/lib/tracers/StdioTracer.js +270 -0
- package/dist/lib/tracers/TestTracer.d.ts +95 -0
- package/dist/lib/tracers/TestTracer.d.ts.map +1 -0
- package/dist/lib/tracers/TestTracer.js +87 -0
- package/dist/lib/tracers/index.d.ts +12 -0
- package/dist/lib/tracers/index.d.ts.map +1 -0
- package/dist/lib/tracers/index.js +11 -0
- package/dist/lib/types.d.ts +366 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/utf8Cache.d.ts +111 -0
- package/dist/lib/utf8Cache.d.ts.map +1 -0
- package/dist/lib/utf8Cache.js +177 -0
- package/dist/lib/wasm/WasmBufferStrategy.d.ts +88 -0
- package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -0
- package/dist/lib/wasm/WasmBufferStrategy.js +138 -0
- package/dist/lib/wasm/wasmAllocator.d.ts +109 -0
- package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -0
- package/dist/lib/wasm/wasmAllocator.js +227 -0
- package/dist/lib/wasm/wasmSpanBuffer.d.ts +123 -0
- package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -0
- package/dist/lib/wasm/wasmSpanBuffer.js +772 -0
- package/dist/lib/wasm/wasmTraceRoot.d.ts +167 -0
- package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -0
- package/dist/lib/wasm/wasmTraceRoot.js +264 -0
- package/dist/node.d.ts +7 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +8 -0
- package/dist/testing.d.ts +18 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +17 -0
- package/package.json +193 -0
- package/src/bun/preload.ts +11 -0
- package/src/bun/trace-preload.ts +14 -0
- package/src/es.ts +11 -0
- package/src/index.ts +194 -0
- package/src/lib/JsBufferStrategy.ts +102 -0
- package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +485 -0
- package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +390 -0
- package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +647 -0
- package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +292 -0
- package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +354 -0
- package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +127 -0
- package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +392 -0
- package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +389 -0
- package/src/lib/__tests__/arrow-conversion-algorithms.test.ts +54 -0
- package/src/lib/__tests__/arrow-test-helpers.ts +71 -0
- package/src/lib/__tests__/binary-e2e.test.ts +203 -0
- package/src/lib/__tests__/buffer-overflow-op-api.test.ts +608 -0
- package/src/lib/__tests__/buffer-overflow.test.ts +612 -0
- package/src/lib/__tests__/capacity-tuning.test.ts +544 -0
- package/src/lib/__tests__/effective-schema.test.ts +439 -0
- package/src/lib/__tests__/flechette.test.ts +42 -0
- package/src/lib/__tests__/flushScheduler.test.ts +537 -0
- package/src/lib/__tests__/integration.test.ts +600 -0
- package/src/lib/__tests__/library.test.ts +934 -0
- package/src/lib/__tests__/nested-library-tasks.test.ts +849 -0
- package/src/lib/__tests__/op-context-binding.test.ts +135 -0
- package/src/lib/__tests__/op-metadata.test.ts +198 -0
- package/src/lib/__tests__/op-type-safety.test.ts +71 -0
- package/src/lib/__tests__/package-exports.test.ts +57 -0
- package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +319 -0
- package/src/lib/__tests__/remapped-buffer-view.test.ts +635 -0
- package/src/lib/__tests__/scope-attributes.test.ts +348 -0
- package/src/lib/__tests__/span-lifecycle.test.ts +680 -0
- package/src/lib/__tests__/sync-async-trace.test.ts +435 -0
- package/src/lib/__tests__/test-helpers.ts +318 -0
- package/src/lib/__tests__/timestamp.test.ts +259 -0
- package/src/lib/__tests__/trace-archive-primitives.test.ts +98 -0
- package/src/lib/__tests__/traceContext-type-enforcement.test.ts +271 -0
- package/src/lib/__tests__/tracer.test.ts +211 -0
- package/src/lib/__tests__/type-narrowing.test.ts +137 -0
- package/src/lib/archive/chunkCompaction.ts +44 -0
- package/src/lib/archive/chunkEnvelope.ts +79 -0
- package/src/lib/archive/chunkRouting.ts +70 -0
- package/src/lib/archive/chunkStats.ts +25 -0
- package/src/lib/archive/index.ts +4 -0
- package/src/lib/arrow/capacityStats.ts +340 -0
- package/src/lib/arrow/dictionaries.ts +159 -0
- package/src/lib/arrow/flechette.ts +114 -0
- package/src/lib/arrow/utils.ts +126 -0
- package/src/lib/buffer/Nanoseconds.ts +131 -0
- package/src/lib/bufferStrategy.ts +106 -0
- package/src/lib/capacityTuning.ts +102 -0
- package/src/lib/codegen/__tests__/__snapshots__/evaluatorGenerator.test.ts.snap +160 -0
- package/src/lib/codegen/__tests__/__snapshots__/scopeGenerator.test.ts.snap +196 -0
- package/src/lib/codegen/__tests__/__snapshots__/spanLoggerGenerator.test.ts.snap +1965 -0
- package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +516 -0
- package/src/lib/codegen/__tests__/nullBitmap.test.ts +207 -0
- package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +237 -0
- package/src/lib/codegen/evaluatorGenerator.ts +309 -0
- package/src/lib/codegen/fixedPositionWriterGenerator.ts +444 -0
- package/src/lib/codegen/spanLoggerGenerator.ts +715 -0
- package/src/lib/convertToArrow.ts +1805 -0
- package/src/lib/defineOpContext.ts +398 -0
- package/src/lib/errors/Blocked.ts +165 -0
- package/src/lib/errors/CodeError.ts +132 -0
- package/src/lib/errors/RetriesExhausted.ts +78 -0
- package/src/lib/errors/Transient.ts +168 -0
- package/src/lib/errors/__tests__/Blocked-config.test.ts +152 -0
- package/src/lib/errors/__tests__/Transient.test.ts +129 -0
- package/src/lib/errors/__tests__/retry-policy.test.ts +85 -0
- package/src/lib/errors/index.ts +24 -0
- package/src/lib/errors/retry-policy.ts +87 -0
- package/src/lib/flushScheduler.ts +509 -0
- package/src/lib/library.ts +682 -0
- package/src/lib/logApi.ts +70 -0
- package/src/lib/logBinding.ts +67 -0
- package/src/lib/op.ts +103 -0
- package/src/lib/opContext/__tests__/retry.test.ts +764 -0
- package/src/lib/opContext/contextTypes.ts +130 -0
- package/src/lib/opContext/createOpGroup.ts +456 -0
- package/src/lib/opContext/defineOp.ts +281 -0
- package/src/lib/opContext/featureFlagTypes.ts +54 -0
- package/src/lib/opContext/index.ts +16 -0
- package/src/lib/opContext/opGroupTypes.ts +342 -0
- package/src/lib/opContext/opTypes.ts +80 -0
- package/src/lib/opContext/spanContextTypes.ts +398 -0
- package/src/lib/opContext/types.ts +403 -0
- package/src/lib/result.ts +550 -0
- package/src/lib/schema/LogSchema.ts +153 -0
- package/src/lib/schema/__tests__/defineLogSchema.test.ts +342 -0
- package/src/lib/schema/__tests__/featureFlags.test.ts +443 -0
- package/src/lib/schema/builder.ts +201 -0
- package/src/lib/schema/defineFeatureFlags.ts +91 -0
- package/src/lib/schema/defineLogSchema.ts +291 -0
- package/src/lib/schema/evaluator.ts +404 -0
- package/src/lib/schema/extend.ts +69 -0
- package/src/lib/schema/systemSchema.ts +339 -0
- package/src/lib/schema/typeGuards.ts +163 -0
- package/src/lib/schema/types.ts +265 -0
- package/src/lib/spanBuffer.ts +571 -0
- package/src/lib/spanBufferHelpers.ts +73 -0
- package/src/lib/spanBufferStats.ts +40 -0
- package/src/lib/spanContext.ts +1566 -0
- package/src/lib/sqlite/__tests__/sqlite-common.test.ts +89 -0
- package/src/lib/sqlite/index.ts +26 -0
- package/src/lib/sqlite/sqlite-async-writer.ts +101 -0
- package/src/lib/sqlite/sqlite-common.ts +309 -0
- package/src/lib/sqlite/sqlite-d1.ts +104 -0
- package/src/lib/sqlite/sqlite-db.ts +32 -0
- package/src/lib/sqlite/sqlite-node.ts +83 -0
- package/src/lib/sqlite/sqlite-writer.ts +128 -0
- package/src/lib/testing/TRACE-TESTING.md +100 -0
- package/src/lib/testing/__tests__/bun-harness.test.ts +108 -0
- package/src/lib/testing/__tests__/extractFacts.test.ts +279 -0
- package/src/lib/testing/__tests__/facts.test.ts +324 -0
- package/src/lib/testing/__tests__/vitest-harness.test.ts +32 -0
- package/src/lib/testing/bun-harness.ts +990 -0
- package/src/lib/testing/extractFacts.ts +362 -0
- package/src/lib/testing/facts.ts +470 -0
- package/src/lib/testing/index.ts +141 -0
- package/src/lib/testing/queryable-span.ts +108 -0
- package/src/lib/testing/span-query.ts +65 -0
- package/src/lib/testing/stdio-replay.ts +50 -0
- package/src/lib/testing/trace-query.ts +329 -0
- package/src/lib/testing/vitest-harness.ts +691 -0
- package/src/lib/threadId.ts +135 -0
- package/src/lib/traceContext.ts +182 -0
- package/src/lib/traceId.ts +142 -0
- package/src/lib/traceRoot.es.ts +157 -0
- package/src/lib/traceRoot.node.ts +170 -0
- package/src/lib/traceRoot.ts +154 -0
- package/src/lib/traceRoot.universal.ts +22 -0
- package/src/lib/tracer.ts +896 -0
- package/src/lib/tracers/ArrayQueueTracer.ts +76 -0
- package/src/lib/tracers/CompositeTracer.ts +76 -0
- package/src/lib/tracers/NoOpTracer.ts +73 -0
- package/src/lib/tracers/SQLiteTracer.ts +115 -0
- package/src/lib/tracers/StdioTracer.ts +380 -0
- package/src/lib/tracers/TestTracer.ts +146 -0
- package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +184 -0
- package/src/lib/tracers/__tests__/NoOpTracer.test.ts +204 -0
- package/src/lib/tracers/__tests__/StdioTracer.test.ts +313 -0
- package/src/lib/tracers/__tests__/TestTracer.test.ts +200 -0
- package/src/lib/tracers/index.ts +12 -0
- package/src/lib/types.ts +498 -0
- package/src/lib/utf8Cache.ts +201 -0
- package/src/lib/wasm/WasmBufferStrategy.ts +219 -0
- package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +256 -0
- package/src/lib/wasm/__tests__/wasm-integration.test.ts +476 -0
- package/src/lib/wasm/__tests__/wasmAllocator.test.ts +699 -0
- package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +449 -0
- package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +390 -0
- package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +444 -0
- package/src/lib/wasm/allocator.zig +945 -0
- package/src/lib/wasm/wasmAllocator.ts +469 -0
- package/src/lib/wasm/wasmSpanBuffer.ts +1014 -0
- package/src/lib/wasm/wasmTraceRoot.ts +315 -0
- package/src/node.ts +10 -0
- package/src/testing.ts +18 -0
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for span lifecycle entry types and fluent result API
|
|
3
|
+
* Per specs/lmao/01h_entry_types_and_logging_primitives.md
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from 'bun:test';
|
|
7
|
+
import { Nanoseconds } from '@smoothbricks/arrow-builder';
|
|
8
|
+
import { convertSpanTreeToArrowTable } from '../convertToArrow.js';
|
|
9
|
+
import { defineOpContext } from '../defineOpContext.js';
|
|
10
|
+
import { defineCodeError } from '../result.js';
|
|
11
|
+
import { S } from '../schema/builder.js';
|
|
12
|
+
import { defineLogSchema } from '../schema/defineLogSchema.js';
|
|
13
|
+
import {
|
|
14
|
+
ENTRY_TYPE_INFO,
|
|
15
|
+
ENTRY_TYPE_SPAN_ERR,
|
|
16
|
+
ENTRY_TYPE_SPAN_EXCEPTION,
|
|
17
|
+
ENTRY_TYPE_SPAN_OK,
|
|
18
|
+
ENTRY_TYPE_SPAN_START,
|
|
19
|
+
} from '../schema/systemSchema.js';
|
|
20
|
+
import { createSpanBuffer } from '../spanBuffer.js';
|
|
21
|
+
import { TestTracer } from '../tracers/TestTracer.js';
|
|
22
|
+
import type { AnySpanBuffer, SpanBuffer } from '../types.js';
|
|
23
|
+
import { createTestOpMetadata, createTestTraceRoot, createTestTracerOptions } from './test-helpers.js';
|
|
24
|
+
|
|
25
|
+
// Error code factories for tests
|
|
26
|
+
const VALIDATION_ERROR = defineCodeError('VALIDATION_ERROR')<{ field: string; message?: string }>();
|
|
27
|
+
const TEST_ERROR = defineCodeError('TEST_ERROR')<{ message: string }>();
|
|
28
|
+
const ERROR_CODE = defineCodeError('ERROR_CODE')<{ detail: string }>();
|
|
29
|
+
|
|
30
|
+
// Test schema
|
|
31
|
+
// Note: resultMessage, exceptionMessage, errorCode, and exceptionStack are now system columns
|
|
32
|
+
// (defined in systemSchema) - they don't need to be defined here
|
|
33
|
+
const testSchema = defineLogSchema({
|
|
34
|
+
userId: S.category(),
|
|
35
|
+
operation: S.enum(['CREATE', 'READ', 'UPDATE', 'DELETE']),
|
|
36
|
+
spanName: S.category(),
|
|
37
|
+
requestId: S.category(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Create op context factory - no feature flags needed for these tests
|
|
41
|
+
const ctx = defineOpContext({
|
|
42
|
+
logSchema: testSchema,
|
|
43
|
+
ctx: {
|
|
44
|
+
requestId: undefined as string | undefined,
|
|
45
|
+
userId: undefined as string | undefined,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
function getColumnValue(
|
|
50
|
+
table: ReturnType<typeof convertSpanTreeToArrowTable>,
|
|
51
|
+
columnName: string,
|
|
52
|
+
rowIndex: number,
|
|
53
|
+
): unknown {
|
|
54
|
+
const column = table.getChild(columnName);
|
|
55
|
+
if (!column) {
|
|
56
|
+
throw new Error(`column not found: ${columnName}`);
|
|
57
|
+
}
|
|
58
|
+
return column.get(rowIndex);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getNullableStringColumnValue(
|
|
62
|
+
table: ReturnType<typeof convertSpanTreeToArrowTable>,
|
|
63
|
+
columnName: string,
|
|
64
|
+
rowIndex: number,
|
|
65
|
+
): string | null {
|
|
66
|
+
const value = getColumnValue(table, columnName, rowIndex);
|
|
67
|
+
if (value === null || typeof value === 'string') {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
throw new Error(`Expected ${columnName} row ${rowIndex} to be string|null, got ${typeof value}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function getNullableBigintColumnValue(
|
|
74
|
+
table: ReturnType<typeof convertSpanTreeToArrowTable>,
|
|
75
|
+
columnName: string,
|
|
76
|
+
rowIndex: number,
|
|
77
|
+
): bigint | number | null {
|
|
78
|
+
const value = getColumnValue(table, columnName, rowIndex);
|
|
79
|
+
if (value === null || typeof value === 'bigint' || typeof value === 'number') {
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
throw new Error(`Expected ${columnName} row ${rowIndex} to be bigint|number|null, got ${typeof value}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
describe('Span Lifecycle', () => {
|
|
86
|
+
it('should write span-start entry when task begins', async () => {
|
|
87
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
88
|
+
|
|
89
|
+
await trace('testTask', async (ctx) => {
|
|
90
|
+
return ctx.ok('success');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Buffer is internal, but we can verify behavior through side effects
|
|
94
|
+
// The span-start entry should be written before any other operations
|
|
95
|
+
expect(true).toBe(true); // Placeholder - real test would inspect buffer
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should write span-ok entry with ctx.ok()', async () => {
|
|
99
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
100
|
+
|
|
101
|
+
const result = await trace('testTask', async (ctx) => {
|
|
102
|
+
return ctx.ok({ id: 123, name: 'test' });
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
expect(result.success).toBe(true);
|
|
106
|
+
if (result.success) {
|
|
107
|
+
expect(result.value).toEqual({ id: 123, name: 'test' });
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should write span-err entry with ctx.err()', async () => {
|
|
112
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
113
|
+
|
|
114
|
+
const result = await trace('testTask', async (ctx) => {
|
|
115
|
+
return ctx.err(VALIDATION_ERROR({ field: 'email', message: 'Invalid email' }));
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
expect(result.success).toBe(false);
|
|
119
|
+
if (!result.success) {
|
|
120
|
+
expect(result.error.code).toBe('VALIDATION_ERROR');
|
|
121
|
+
expect(result.error.field).toBe('email');
|
|
122
|
+
expect(result.error.message).toBe('Invalid email');
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should write span-exception entry when task throws', async () => {
|
|
127
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
128
|
+
|
|
129
|
+
await expect(
|
|
130
|
+
trace('testTask', async (_ctx) => {
|
|
131
|
+
throw new Error('Unexpected error');
|
|
132
|
+
}),
|
|
133
|
+
).rejects.toThrow('Unexpected error');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should support spanSync for synchronous child spans', async () => {
|
|
137
|
+
const tracer = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
138
|
+
|
|
139
|
+
const result = await tracer.trace('root-task', async (rootCtx) => {
|
|
140
|
+
const childResult = rootCtx.spanSync('sync-child', (childCtx) => {
|
|
141
|
+
childCtx.tag.spanName('sync-child');
|
|
142
|
+
return childCtx.ok('child-ok');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expect(childResult).not.toBeInstanceOf(Promise);
|
|
146
|
+
expect(childResult.success).toBe(true);
|
|
147
|
+
return rootCtx.ok('root-ok');
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
expect(result.success).toBe(true);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('Fluent Result API', () => {
|
|
155
|
+
it('should support .with() for setting attributes on ok result', async () => {
|
|
156
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
157
|
+
|
|
158
|
+
const result = await trace('testTask', async (ctx) => {
|
|
159
|
+
const result = ctx.ok({ id: 123 }).with({
|
|
160
|
+
userId: 'user1',
|
|
161
|
+
operation: 'CREATE',
|
|
162
|
+
});
|
|
163
|
+
return result;
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
expect(result.success).toBe(true);
|
|
167
|
+
if (result.success) {
|
|
168
|
+
expect(result.value).toEqual({ id: 123 });
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('should support .message() for setting message on ok result', async () => {
|
|
173
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
174
|
+
|
|
175
|
+
const result = await trace('testTask', async (ctx) => {
|
|
176
|
+
return ctx.ok({ id: 123 }).message('User created successfully');
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
expect(result.success).toBe(true);
|
|
180
|
+
if (result.success) {
|
|
181
|
+
expect(result.value).toEqual({ id: 123 });
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('should support chaining .with() and .message()', async () => {
|
|
186
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
187
|
+
|
|
188
|
+
const result = await trace('testTask', async (ctx) => {
|
|
189
|
+
return ctx.ok({ id: 123 }).with({ userId: 'user1', operation: 'CREATE' }).message('User created successfully');
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
expect(result.success).toBe(true);
|
|
193
|
+
if (result.success) {
|
|
194
|
+
expect(result.value).toEqual({ id: 123 });
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should support .with() on err result', async () => {
|
|
199
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
200
|
+
|
|
201
|
+
const result = await trace('testTask', async (ctx) => {
|
|
202
|
+
return ctx.err(VALIDATION_ERROR({ field: 'email' })).with({ userId: 'user1', operation: 'CREATE' });
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
expect(result.success).toBe(false);
|
|
206
|
+
if (!result.success) {
|
|
207
|
+
expect(result.error.code).toBe('VALIDATION_ERROR');
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('should support .message() on err result', async () => {
|
|
212
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
213
|
+
|
|
214
|
+
const result = await trace('testTask', async (ctx) => {
|
|
215
|
+
return ctx.err(VALIDATION_ERROR({ field: 'email' })).message('Invalid email format');
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
expect(result.success).toBe(false);
|
|
219
|
+
if (!result.success) {
|
|
220
|
+
expect(result.error.code).toBe('VALIDATION_ERROR');
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
describe('Child Span Lifecycle', () => {
|
|
226
|
+
it('should write span-start for child spans', async () => {
|
|
227
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
228
|
+
|
|
229
|
+
const result = await trace('parentTask', async (ctx) => {
|
|
230
|
+
const childResult = await ctx.span('childSpan', async (childCtx) => {
|
|
231
|
+
return childCtx.ok('child success');
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
return childResult;
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
expect(result.success).toBe(true);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('should write span-exception for child span errors', async () => {
|
|
241
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
242
|
+
|
|
243
|
+
await expect(
|
|
244
|
+
trace('parentTask', async (ctx) => {
|
|
245
|
+
await ctx.span('childSpan', async (_childCtx) => {
|
|
246
|
+
throw new Error('Child span error');
|
|
247
|
+
});
|
|
248
|
+
return ctx.ok(undefined);
|
|
249
|
+
}),
|
|
250
|
+
).rejects.toThrow('Child span error');
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('should handle nested child spans', async () => {
|
|
254
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
255
|
+
|
|
256
|
+
const result = await trace('parentTask', async (ctx) => {
|
|
257
|
+
const result1 = await ctx.span('child1', async (child1Ctx) => {
|
|
258
|
+
const result2 = await child1Ctx.span('child2', async (child2Ctx) => {
|
|
259
|
+
return child2Ctx.ok('grandchild success');
|
|
260
|
+
});
|
|
261
|
+
return child1Ctx.ok(result2);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
return ctx.ok(result1);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
expect(result.success).toBe(true);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('should create child span when op() is called from parent span context', async () => {
|
|
271
|
+
// This test verifies the bug fix: when defineOp() ops are called from a parent
|
|
272
|
+
// SpanContext (has buffer property), it should create a child span, not a root span.
|
|
273
|
+
let parentBuffer: AnySpanBuffer | undefined;
|
|
274
|
+
let childBuffer: AnySpanBuffer | undefined;
|
|
275
|
+
|
|
276
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
277
|
+
const result = await trace('parent-task', async (ctx) => {
|
|
278
|
+
parentBuffer = ctx.buffer;
|
|
279
|
+
|
|
280
|
+
// Call child op from parent span context
|
|
281
|
+
// This should create a child span, not a root span
|
|
282
|
+
const childResult = await ctx.span('child-task', async (childCtx) => {
|
|
283
|
+
childBuffer = childCtx.buffer;
|
|
284
|
+
if (!childBuffer) {
|
|
285
|
+
throw new Error('childBuffer is undefined');
|
|
286
|
+
}
|
|
287
|
+
const child = childBuffer;
|
|
288
|
+
|
|
289
|
+
// Verify child span is linked to parent
|
|
290
|
+
expect(child._parent).toBeDefined();
|
|
291
|
+
// Use === comparison to avoid type mismatch between SpanBuffer<Schema> and untyped SpanBuffer
|
|
292
|
+
expect(child._parent === parentBuffer).toBe(true);
|
|
293
|
+
expect(parentBuffer).toBeDefined();
|
|
294
|
+
if (!parentBuffer) {
|
|
295
|
+
throw new Error('parentBuffer is undefined');
|
|
296
|
+
}
|
|
297
|
+
const parent = parentBuffer;
|
|
298
|
+
|
|
299
|
+
// Verify child span inherits parent's schema
|
|
300
|
+
expect(child._logSchema).toBe(parent._logSchema);
|
|
301
|
+
|
|
302
|
+
// Verify child span has different spanId but same traceId
|
|
303
|
+
expect(child.span_id).not.toBe(parent.span_id);
|
|
304
|
+
expect(child.trace_id).toBe(parent.trace_id);
|
|
305
|
+
|
|
306
|
+
return childCtx.ok('child-done');
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
return childResult;
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
expect(result.success).toBe(true);
|
|
313
|
+
expect(parentBuffer).toBeDefined();
|
|
314
|
+
expect(childBuffer).toBeDefined();
|
|
315
|
+
expect(childBuffer?._parent).toBe(parentBuffer);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('should create proper parent-child hierarchy in Arrow conversion when op() called from parent', async () => {
|
|
319
|
+
// This test verifies that when op() is called from a parent span, the resulting
|
|
320
|
+
// child span appears correctly in Arrow conversion with proper parent_span_id relationships.
|
|
321
|
+
let rootBuffer: AnySpanBuffer | undefined;
|
|
322
|
+
|
|
323
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
324
|
+
|
|
325
|
+
await trace('root-task', async (ctx) => {
|
|
326
|
+
rootBuffer = ctx.buffer;
|
|
327
|
+
ctx.tag.operation('CREATE');
|
|
328
|
+
|
|
329
|
+
// Create child span from root span context
|
|
330
|
+
await ctx.span('child-task', async (childCtx) => {
|
|
331
|
+
childCtx.tag.operation('READ');
|
|
332
|
+
return childCtx.ok('child-done');
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
return ctx.ok('root-done');
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
expect(rootBuffer).toBeDefined();
|
|
339
|
+
if (!rootBuffer) {
|
|
340
|
+
throw new Error('rootBuffer is undefined');
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Convert to Arrow table to verify parent-child relationships
|
|
344
|
+
const table = convertSpanTreeToArrowTable(rootBuffer);
|
|
345
|
+
|
|
346
|
+
// Should have at least 4 rows:
|
|
347
|
+
// - Row 0: root span-start
|
|
348
|
+
// - Row 1: root span-ok
|
|
349
|
+
// - Row 2: child span-start
|
|
350
|
+
// - Row 3: child span-ok
|
|
351
|
+
expect(table.numRows).toBeGreaterThanOrEqual(4);
|
|
352
|
+
|
|
353
|
+
const rows = Array.from({ length: table.numRows }, (_, rowIndex) => ({
|
|
354
|
+
entry_type: getNullableStringColumnValue(table, 'entry_type', rowIndex),
|
|
355
|
+
message: getNullableStringColumnValue(table, 'message', rowIndex),
|
|
356
|
+
span_id: getNullableBigintColumnValue(table, 'span_id', rowIndex),
|
|
357
|
+
parent_span_id: getNullableBigintColumnValue(table, 'parent_span_id', rowIndex),
|
|
358
|
+
trace_id: getNullableStringColumnValue(table, 'trace_id', rowIndex),
|
|
359
|
+
}));
|
|
360
|
+
|
|
361
|
+
// Find root span-start (entry_type = span-start, message matches)
|
|
362
|
+
const rootSpanStart = rows.find((r) => r?.entry_type === 'span-start' && r?.message === 'root-task');
|
|
363
|
+
const childSpanStart = rows.find((r) => r?.entry_type === 'span-start' && r?.message === 'child-task');
|
|
364
|
+
|
|
365
|
+
expect(rootSpanStart).toBeDefined();
|
|
366
|
+
expect(childSpanStart).toBeDefined();
|
|
367
|
+
|
|
368
|
+
// Root span has no parent (it's the trace root itself)
|
|
369
|
+
expect(rootSpanStart?.parent_span_id).toBeNull();
|
|
370
|
+
|
|
371
|
+
// Child span should reference root span's span_id
|
|
372
|
+
expect(childSpanStart?.parent_span_id).toBe(rootSpanStart?.span_id);
|
|
373
|
+
|
|
374
|
+
// Both should have same trace_id
|
|
375
|
+
expect(rootSpanStart?.trace_id).toBe(childSpanStart?.trace_id);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
it('should inherit parent schema when op() called from parent span', async () => {
|
|
379
|
+
// This test verifies that child spans created via op() inherit the parent's schema.
|
|
380
|
+
// In the Op-centric API, all ops share the same schema defined in the factory,
|
|
381
|
+
// so child spans automatically inherit the parent's schema.
|
|
382
|
+
const sharedSchema = defineLogSchema({
|
|
383
|
+
userId: S.category(),
|
|
384
|
+
requestId: S.category(),
|
|
385
|
+
operation: S.enum(['CREATE', 'READ', 'UPDATE', 'DELETE']),
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
const sharedCtx = defineOpContext({
|
|
389
|
+
logSchema: sharedSchema,
|
|
390
|
+
ctx: {
|
|
391
|
+
requestId: undefined as string | undefined,
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
let parentBuffer: AnySpanBuffer | undefined;
|
|
396
|
+
let childBuffer: AnySpanBuffer | undefined;
|
|
397
|
+
|
|
398
|
+
const { trace } = new TestTracer(sharedCtx, { ...createTestTracerOptions() });
|
|
399
|
+
|
|
400
|
+
await trace('parent-task', async (ctx) => {
|
|
401
|
+
parentBuffer = ctx.buffer;
|
|
402
|
+
ctx.tag.userId('user123').requestId('req456').operation('CREATE');
|
|
403
|
+
|
|
404
|
+
// Call child op from parent span context
|
|
405
|
+
// Child will inherit parent's schema (same factory)
|
|
406
|
+
await ctx.span('child-task', async (childCtx) => {
|
|
407
|
+
childBuffer = childCtx.buffer;
|
|
408
|
+
if (!childBuffer) {
|
|
409
|
+
throw new Error('childBuffer is undefined');
|
|
410
|
+
}
|
|
411
|
+
const child = childBuffer;
|
|
412
|
+
|
|
413
|
+
// Verify child span inherits parent's schema
|
|
414
|
+
// All ops in the factory share the same schema
|
|
415
|
+
expect(parentBuffer).toBeDefined();
|
|
416
|
+
if (!parentBuffer) {
|
|
417
|
+
throw new Error('parentBuffer is undefined');
|
|
418
|
+
}
|
|
419
|
+
const parent = parentBuffer;
|
|
420
|
+
expect(child._logSchema).toBe(parent._logSchema);
|
|
421
|
+
|
|
422
|
+
// Child should be able to access parent's schema fields
|
|
423
|
+
childCtx.tag.userId('user123').operation('READ');
|
|
424
|
+
|
|
425
|
+
return childCtx.ok('child-done');
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
return ctx.ok('parent-done');
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
expect(parentBuffer).toBeDefined();
|
|
432
|
+
expect(childBuffer).toBeDefined();
|
|
433
|
+
expect(childBuffer?._parent).toBe(parentBuffer);
|
|
434
|
+
// Child buffer's schema is the same as parent's schema (inherited)
|
|
435
|
+
// Both buffers are instances of the same SpanBuffer class, so they share the same static schema
|
|
436
|
+
expect(childBuffer?._logSchema).toBe(parentBuffer?._logSchema);
|
|
437
|
+
});
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
describe('FluentResult Type Compatibility', () => {
|
|
441
|
+
it('should allow direct access to success property', async () => {
|
|
442
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
443
|
+
|
|
444
|
+
const result = await trace('testTask', async (ctx) => {
|
|
445
|
+
const result = ctx.ok({ id: 123 });
|
|
446
|
+
|
|
447
|
+
// Should be able to access success property directly
|
|
448
|
+
if (result.success) {
|
|
449
|
+
return ctx.ok(result.value);
|
|
450
|
+
}
|
|
451
|
+
return ctx.ok(null);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
expect(result.success).toBe(true);
|
|
455
|
+
if (result.success) {
|
|
456
|
+
expect(result.value).toEqual({ id: 123 });
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it('should allow direct access to error property', async () => {
|
|
461
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
462
|
+
|
|
463
|
+
const result = await trace('testTask', async (ctx) => {
|
|
464
|
+
const result = ctx.err(TEST_ERROR({ message: 'test' }));
|
|
465
|
+
|
|
466
|
+
// Should be able to access error property directly
|
|
467
|
+
if (!result.success) {
|
|
468
|
+
return ctx.ok(result.error.code);
|
|
469
|
+
}
|
|
470
|
+
return ctx.ok(null);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
expect(result.success).toBe(true);
|
|
474
|
+
if (result.success) {
|
|
475
|
+
expect(result.value).toBe('TEST_ERROR');
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Tests for fixed row layout in span buffers
|
|
482
|
+
* Per specs/lmao/01h_entry_types_and_logging_primitives.md:
|
|
483
|
+
* - Row 0: span-start (written at span creation)
|
|
484
|
+
* - Row 1: span-end (pre-initialized as exception, overwritten by ok/err)
|
|
485
|
+
* - Row 2+: events (ctx.log.* appends here)
|
|
486
|
+
*/
|
|
487
|
+
describe('Fixed Row Layout', () => {
|
|
488
|
+
it('should have span-start at row 0 and span-ok at row 1 after ctx.ok()', async () => {
|
|
489
|
+
let capturedBuffer: SpanBuffer<(typeof ctx)['logBinding']['logSchema']> | undefined;
|
|
490
|
+
|
|
491
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
492
|
+
const result = await trace('test-task', async (ctx) => {
|
|
493
|
+
capturedBuffer = ctx.buffer;
|
|
494
|
+
return ctx.ok('done');
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
expect(result.success).toBe(true);
|
|
498
|
+
expect(capturedBuffer).toBeDefined();
|
|
499
|
+
expect(capturedBuffer?.entry_type[0]).toBe(ENTRY_TYPE_SPAN_START);
|
|
500
|
+
expect(capturedBuffer?.entry_type[1]).toBe(ENTRY_TYPE_SPAN_OK);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
it('should have span-start at row 0 and span-err at row 1 after ctx.err()', async () => {
|
|
504
|
+
let capturedBuffer: AnySpanBuffer | undefined;
|
|
505
|
+
|
|
506
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
507
|
+
const result = await trace('test', async (ctx) => {
|
|
508
|
+
capturedBuffer = ctx.buffer;
|
|
509
|
+
return ctx.err(ERROR_CODE({ detail: 'error detail' }));
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
expect(result.success).toBe(false);
|
|
513
|
+
expect(capturedBuffer).toBeDefined();
|
|
514
|
+
expect(capturedBuffer?.entry_type[0]).toBe(ENTRY_TYPE_SPAN_START);
|
|
515
|
+
expect(capturedBuffer?.entry_type[1]).toBe(ENTRY_TYPE_SPAN_ERR);
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
it('should write ok fluent result attributes directly to row 1', async () => {
|
|
519
|
+
let capturedBuffer: SpanBuffer<(typeof ctx)['logBinding']['logSchema']> | undefined;
|
|
520
|
+
|
|
521
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
522
|
+
await trace('test', async (ctx) => {
|
|
523
|
+
capturedBuffer = ctx.buffer;
|
|
524
|
+
return ctx.ok('done').with({ userId: 'user-1', operation: 'CREATE' }).message('completed').line(42);
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
expect(capturedBuffer).toBeDefined();
|
|
528
|
+
if (!capturedBuffer) {
|
|
529
|
+
throw new Error('capturedBuffer is undefined');
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
expect(capturedBuffer.message_values[1]).toBe('completed');
|
|
533
|
+
expect(capturedBuffer.userId_values[1]).toBe('user-1');
|
|
534
|
+
expect(capturedBuffer.operation_values[1]).toBe(0);
|
|
535
|
+
expect(capturedBuffer.line_values[1]).toBe(42);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
it('should write err fluent result attributes directly to row 1', async () => {
|
|
539
|
+
let capturedBuffer: SpanBuffer<(typeof ctx)['logBinding']['logSchema']> | undefined;
|
|
540
|
+
|
|
541
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
542
|
+
await trace('test', async (ctx) => {
|
|
543
|
+
capturedBuffer = ctx.buffer;
|
|
544
|
+
return ctx
|
|
545
|
+
.err(VALIDATION_ERROR({ field: 'email' }))
|
|
546
|
+
.with({ userId: 'user-2' })
|
|
547
|
+
.message('failed')
|
|
548
|
+
.line(99);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
expect(capturedBuffer).toBeDefined();
|
|
552
|
+
if (!capturedBuffer) {
|
|
553
|
+
throw new Error('capturedBuffer is undefined');
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
expect(capturedBuffer.message_values[1]).toBe('failed');
|
|
557
|
+
expect(capturedBuffer.userId_values[1]).toBe('user-2');
|
|
558
|
+
expect(capturedBuffer.error_code_values[1]).toBe('VALIDATION_ERROR');
|
|
559
|
+
expect(capturedBuffer.line_values[1]).toBe(99);
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
it('should have span-start at row 0 and span-exception at row 1 on thrown error', async () => {
|
|
563
|
+
let capturedBuffer: AnySpanBuffer | undefined;
|
|
564
|
+
|
|
565
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
566
|
+
|
|
567
|
+
await expect(
|
|
568
|
+
trace('test', async (ctx) => {
|
|
569
|
+
capturedBuffer = ctx.buffer;
|
|
570
|
+
throw new Error('Unexpected failure');
|
|
571
|
+
}),
|
|
572
|
+
).rejects.toThrow('Unexpected failure');
|
|
573
|
+
expect(capturedBuffer).toBeDefined();
|
|
574
|
+
expect(capturedBuffer?.entry_type[0]).toBe(ENTRY_TYPE_SPAN_START);
|
|
575
|
+
expect(capturedBuffer?.entry_type[1]).toBe(ENTRY_TYPE_SPAN_EXCEPTION);
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
it('should start writeIndex at 2 after span-start is written', async () => {
|
|
579
|
+
// This tests the writeSpanStart function behavior
|
|
580
|
+
// After writeSpanStart, writeIndex should be 2 (row 0 = span-start, row 1 = pre-init, events at row 2+)
|
|
581
|
+
|
|
582
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
583
|
+
await trace('test', async (ctx) => {
|
|
584
|
+
// At this point, writeSpanStart has been called
|
|
585
|
+
// Events logged here should go to row 2+
|
|
586
|
+
ctx.log.info('first event');
|
|
587
|
+
return ctx.ok('done');
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
// The task completed successfully, meaning:
|
|
591
|
+
// - Row 0 has span-start
|
|
592
|
+
// - Row 1 has span-ok (from ctx.ok)
|
|
593
|
+
// - Row 2 would have first event (info)
|
|
594
|
+
expect(true).toBe(true); // Task completed without error
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
it('should append events starting at row 2', async () => {
|
|
598
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
599
|
+
const result = await trace('test', async (ctx) => {
|
|
600
|
+
ctx.log.info('first event'); // Should be row 2
|
|
601
|
+
ctx.log.info('second event'); // Should be row 3
|
|
602
|
+
return ctx.ok('done');
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
expect(result.success).toBe(true);
|
|
606
|
+
// If events were incorrectly written to row 0 or 1, the span lifecycle would be corrupted
|
|
607
|
+
// The fact that ok() works after logging confirms proper row layout
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
it('should allow duration calculation as timestamps[1] - timestamps[0]', async () => {
|
|
611
|
+
// This tests the fixed layout enables simple duration calculation
|
|
612
|
+
const { trace } = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
613
|
+
await trace('test', async (ctx) => {
|
|
614
|
+
// Small delay to ensure non-zero duration
|
|
615
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
616
|
+
return ctx.ok('done');
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
// The fixed layout means:
|
|
620
|
+
// - timestamps[0] = span-start time
|
|
621
|
+
// - timestamps[1] = span-end time
|
|
622
|
+
// Duration = timestamps[1] - timestamps[0]
|
|
623
|
+
// This is verified by the fact that the task completed successfully
|
|
624
|
+
expect(true).toBe(true);
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
it('should export entry type constants for use in tests and consumers', () => {
|
|
628
|
+
// Per specs/lmao/01h_entry_types_and_logging_primitives.md
|
|
629
|
+
// Just verify the constants are exported and are numbers
|
|
630
|
+
expect(typeof ENTRY_TYPE_SPAN_START).toBe('number');
|
|
631
|
+
expect(typeof ENTRY_TYPE_SPAN_OK).toBe('number');
|
|
632
|
+
expect(typeof ENTRY_TYPE_SPAN_ERR).toBe('number');
|
|
633
|
+
expect(typeof ENTRY_TYPE_SPAN_EXCEPTION).toBe('number');
|
|
634
|
+
expect(typeof ENTRY_TYPE_INFO).toBe('number');
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
it('should create buffer with proper structure for fixed layout', () => {
|
|
638
|
+
// Create buffer using the new Phase 2 API
|
|
639
|
+
const opMetadata = createTestOpMetadata();
|
|
640
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), opMetadata);
|
|
641
|
+
|
|
642
|
+
// Buffer should have timestamps array for duration calculation
|
|
643
|
+
expect(buffer.timestamp).toBeInstanceOf(BigInt64Array);
|
|
644
|
+
|
|
645
|
+
// Buffer should have operations array for entry types
|
|
646
|
+
expect(buffer.entry_type).toBeInstanceOf(Uint8Array);
|
|
647
|
+
|
|
648
|
+
// Buffer should have enough capacity for at least rows 0, 1, and events
|
|
649
|
+
expect(buffer._capacity).toBeGreaterThanOrEqual(2);
|
|
650
|
+
|
|
651
|
+
// Fresh buffer starts at writeIndex 0
|
|
652
|
+
expect(buffer._writeIndex).toBe(0);
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
it('should expose _spanStartTime from timestamp row 0', () => {
|
|
656
|
+
const opMetadata = createTestOpMetadata();
|
|
657
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), opMetadata);
|
|
658
|
+
|
|
659
|
+
buffer.timestamp[0] = 111n;
|
|
660
|
+
expect(buffer._spanStartTime).toBe(Nanoseconds.unsafe(111n));
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
it('should expose _lastLoggedTime across overflow chain', () => {
|
|
664
|
+
const opMetadata = createTestOpMetadata();
|
|
665
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), opMetadata, 4);
|
|
666
|
+
|
|
667
|
+
buffer._writeIndex = 4;
|
|
668
|
+
buffer.timestamp[0] = 100n;
|
|
669
|
+
buffer.timestamp[1] = 200n;
|
|
670
|
+
buffer.timestamp[2] = 300n;
|
|
671
|
+
buffer.timestamp[3] = 400n;
|
|
672
|
+
|
|
673
|
+
const overflow = buffer.getOrCreateOverflow();
|
|
674
|
+
overflow._writeIndex = 2;
|
|
675
|
+
overflow.timestamp[0] = 500n;
|
|
676
|
+
overflow.timestamp[1] = 600n;
|
|
677
|
+
|
|
678
|
+
expect(buffer._lastLoggedTime).toBe(Nanoseconds.unsafe(600n));
|
|
679
|
+
});
|
|
680
|
+
});
|