@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,896 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracer - Abstract base class for trace collection
|
|
3
|
+
*
|
|
4
|
+
* Per specs/lmao/01c_context_flow_and_op_wrappers.md:
|
|
5
|
+
* - Tracer owns trace() function for creating root spans
|
|
6
|
+
* - Collects SpanBuffers in pendingBuffers array
|
|
7
|
+
* - Subclasses implement flush() to define persistence strategy
|
|
8
|
+
*
|
|
9
|
+
* ## Design Philosophy
|
|
10
|
+
*
|
|
11
|
+
* Tracer separates two concerns:
|
|
12
|
+
* 1. **BufferStrategy**: HOW buffers are allocated (JS TypedArrays vs WASM memory)
|
|
13
|
+
* 2. **Sink behavior** (lifecycle hooks): WHAT happens with completed buffers
|
|
14
|
+
*
|
|
15
|
+
* Tracer is ABSTRACT - subclasses implement lifecycle hooks:
|
|
16
|
+
* - `onTraceEnd()` - called when root trace completes
|
|
17
|
+
* - `onSpanEnd()` - called when child span completes
|
|
18
|
+
* - `flush()` - optional, for batching strategies
|
|
19
|
+
*
|
|
20
|
+
* BufferStrategy is INJECTED via constructor:
|
|
21
|
+
* - `JsBufferStrategy` - GC-managed TypedArrays, zero-copy Arrow
|
|
22
|
+
* - `WasmBufferStrategy` - WASM memory with freelist, Arrow built in WASM
|
|
23
|
+
*
|
|
24
|
+
* The sink controls WHEN to convert/release:
|
|
25
|
+
* - StdioTracer: prints then releases immediately
|
|
26
|
+
* - TestTracer: holds buffers until clear()
|
|
27
|
+
* - SqsTracer: accumulates, converts on flush(), then releases
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // Concrete implementation - Cloudflare Queue
|
|
32
|
+
* class QueueTracer extends Tracer {
|
|
33
|
+
* constructor(binding, strategy, options, private queue: Queue) {
|
|
34
|
+
* super(binding, strategy, options);
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* async flush() {
|
|
38
|
+
* const buffers = [...this.pending];
|
|
39
|
+
* this.pending.length = 0;
|
|
40
|
+
* for (const buffer of buffers) {
|
|
41
|
+
* const table = await this.bufferStrategy.toArrowTable(buffer);
|
|
42
|
+
* await this.queue.send(table);
|
|
43
|
+
* this.bufferStrategy.releaseBuffer(buffer);
|
|
44
|
+
* }
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
*
|
|
48
|
+
* // Usage
|
|
49
|
+
* const ctx = defineOpContext({ logSchema, ctx: { env: null as Env } });
|
|
50
|
+
* const strategy = new JsBufferStrategy();
|
|
51
|
+
* const { trace, flush } = new QueueTracer(ctx, strategy, options, env.TRACES);
|
|
52
|
+
* await trace('fetch', { env: myEnv }, async (ctx) => {
|
|
53
|
+
* ctx.tag.userId('user-123');
|
|
54
|
+
* return ctx.ok('done');
|
|
55
|
+
* });
|
|
56
|
+
* executionContext.waitUntil(flush());
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @module tracer
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
import type { BufferStrategy } from './bufferStrategy.js';
|
|
63
|
+
import type { TagWriter } from './codegen/fixedPositionWriterGenerator.js';
|
|
64
|
+
import { createTagWriter } from './codegen/fixedPositionWriterGenerator.js';
|
|
65
|
+
import { createSpanLogger as createSpanLoggerFromGenerator } from './codegen/spanLoggerGenerator.js';
|
|
66
|
+
import type { LogBinding } from './logBinding.js';
|
|
67
|
+
import { Op } from './op.js';
|
|
68
|
+
import { createOpMetadata } from './opContext/defineOp.js';
|
|
69
|
+
import type { OpContext, OpContextBinding, OpContextOf, SpanContext } from './opContext/types.js';
|
|
70
|
+
import { Err, Ok, type Result } from './result.js';
|
|
71
|
+
import { createFeatureFlagEvaluator, type FlagEvaluator, InMemoryFlagEvaluator } from './schema/evaluator.js';
|
|
72
|
+
import { ENTRY_TYPE_SPAN_EXCEPTION, ENTRY_TYPE_SPAN_OK } from './schema/systemSchema.js';
|
|
73
|
+
|
|
74
|
+
import { EMPTY_SCOPE } from './spanBuffer.js';
|
|
75
|
+
import {
|
|
76
|
+
createSpanContextClass,
|
|
77
|
+
type SpanContextClass,
|
|
78
|
+
type SpanContextInstance,
|
|
79
|
+
writeSpanEnd,
|
|
80
|
+
writeSpanStart,
|
|
81
|
+
} from './spanContext.js';
|
|
82
|
+
import { generateTraceId, isValidTraceId, type TraceId } from './traceId.js';
|
|
83
|
+
import type { TraceRootFactory } from './traceRoot.js';
|
|
84
|
+
import type { SpanBuffer } from './types.js';
|
|
85
|
+
|
|
86
|
+
// =============================================================================
|
|
87
|
+
// Types
|
|
88
|
+
// =============================================================================
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Base tracer options (can be extended by subclasses)
|
|
92
|
+
*
|
|
93
|
+
* Flag evaluator typing is intentionally loose - the evaluator just needs to
|
|
94
|
+
* implement the FlagEvaluator interface. Type safety for flag access comes from
|
|
95
|
+
* the OpContext's flags schema, not from the evaluator's type parameter.
|
|
96
|
+
*/
|
|
97
|
+
export interface TracerOptions<
|
|
98
|
+
T extends import('./schema/LogSchema.js').LogSchema = import('./schema/LogSchema.js').LogSchema,
|
|
99
|
+
> {
|
|
100
|
+
/**
|
|
101
|
+
* Buffer strategy for memory management and Arrow conversion.
|
|
102
|
+
*
|
|
103
|
+
* Controls HOW buffers are allocated:
|
|
104
|
+
* - JsBufferStrategy: GC-managed TypedArrays, zero-copy Arrow
|
|
105
|
+
* - WasmBufferStrategy: WASM memory with freelist, Arrow built in WASM
|
|
106
|
+
*/
|
|
107
|
+
bufferStrategy: BufferStrategy<T>;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Factory for creating platform-specific TraceRoot instances.
|
|
111
|
+
* Import from '@smoothbricks/lmao/node' or '@smoothbricks/lmao/es'.
|
|
112
|
+
*/
|
|
113
|
+
createTraceRoot: TraceRootFactory;
|
|
114
|
+
|
|
115
|
+
/** Feature flag evaluator - provides flag values at runtime */
|
|
116
|
+
flagEvaluator?: FlagEvaluator<OpContext>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function isTraceOverridesArg(value: unknown): value is Record<string, unknown> {
|
|
120
|
+
return value !== null && typeof value === 'object' && !(value instanceof Op);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function isTraceFn<Ctx extends OpContext>(value: unknown): value is (ctx: SpanContext<Ctx>) => unknown {
|
|
124
|
+
return typeof value === 'function';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function isPromiseResult<R>(value: R | Promise<R>): value is Promise<R> {
|
|
128
|
+
return (
|
|
129
|
+
value !== null &&
|
|
130
|
+
(typeof value === 'object' || typeof value === 'function') &&
|
|
131
|
+
typeof Reflect.get(value, 'then') === 'function'
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Trace overrides - userCtx values plus optional trace_id.
|
|
137
|
+
*
|
|
138
|
+
* Like span() overrides, but with optional trace_id for distributed tracing.
|
|
139
|
+
* The trace_id must be a branded TraceId (use createTraceId() to validate).
|
|
140
|
+
*
|
|
141
|
+
* When UserCtx is empty (Record<string, never>), only trace_id is available.
|
|
142
|
+
* Otherwise, allows partial userCtx values plus trace_id.
|
|
143
|
+
*
|
|
144
|
+
* We use a conditional type to avoid issues with Partial<Record<string, never>>
|
|
145
|
+
* which creates an index signature where all values must be undefined.
|
|
146
|
+
*
|
|
147
|
+
* @typeParam UserCtx - User context type from OpContext
|
|
148
|
+
*/
|
|
149
|
+
export type TraceOverrides<UserCtx> = [UserCtx] extends [Record<string, never>]
|
|
150
|
+
? { trace_id?: TraceId }
|
|
151
|
+
: Partial<UserCtx> & { trace_id?: TraceId };
|
|
152
|
+
|
|
153
|
+
// =============================================================================
|
|
154
|
+
// TraceFn Type - Overloaded trace function signatures
|
|
155
|
+
// =============================================================================
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* TraceFn - overloaded trace creation function.
|
|
159
|
+
*
|
|
160
|
+
* Per specs/lmao/01c_context_flow_and_op_wrappers.md:
|
|
161
|
+
* Creates root spans with type-safe Op invocation or inline closures.
|
|
162
|
+
* Mirrors SpanFn but for root traces.
|
|
163
|
+
*
|
|
164
|
+
* Pattern:
|
|
165
|
+
* - With/without line numbers (transformer injection)
|
|
166
|
+
* - Always requires name (unlike span which can use op.metadata.name)
|
|
167
|
+
* - With/without overrides (userCtx + optional trace_id)
|
|
168
|
+
* - With/without Op arguments (0-8 args supported)
|
|
169
|
+
*
|
|
170
|
+
* @template Ctx - Full OpContext type from the tracer's binding
|
|
171
|
+
*/
|
|
172
|
+
export type TraceFn<Ctx extends OpContext> = {
|
|
173
|
+
// ===========================================================================
|
|
174
|
+
// Op invocations WITH line number (transformer-injected)
|
|
175
|
+
// ===========================================================================
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Trace Op with line + name + args.
|
|
179
|
+
*/
|
|
180
|
+
<S, E, Args extends unknown[]>(
|
|
181
|
+
line: number,
|
|
182
|
+
name: string,
|
|
183
|
+
op: Op<Ctx, Args, S, E>,
|
|
184
|
+
...args: Args
|
|
185
|
+
): Promise<Result<S, E>>;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Trace Op with line + name + overrides + args.
|
|
189
|
+
*/
|
|
190
|
+
<S, E, Args extends unknown[]>(
|
|
191
|
+
line: number,
|
|
192
|
+
name: string,
|
|
193
|
+
overrides: TraceOverrides<Ctx['userCtx']>,
|
|
194
|
+
op: Op<Ctx, Args, S, E>,
|
|
195
|
+
...args: Args
|
|
196
|
+
): Promise<Result<S, E>>;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Trace inline function with line + name.
|
|
200
|
+
*/
|
|
201
|
+
<R>(line: number, name: string, fn: (ctx: SpanContext<Ctx>) => R): R;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Trace inline function with line + name + overrides.
|
|
205
|
+
*/
|
|
206
|
+
<R>(line: number, name: string, overrides: TraceOverrides<Ctx['userCtx']>, fn: (ctx: SpanContext<Ctx>) => R): R;
|
|
207
|
+
|
|
208
|
+
// ===========================================================================
|
|
209
|
+
// Op invocations WITHOUT line number (fallback/manual)
|
|
210
|
+
// ===========================================================================
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Trace Op with name + args.
|
|
214
|
+
*/
|
|
215
|
+
<S, E, Args extends unknown[]>(name: string, op: Op<Ctx, Args, S, E>, ...args: Args): Promise<Result<S, E>>;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Trace Op with name + overrides + args.
|
|
219
|
+
*/
|
|
220
|
+
<S, E, Args extends unknown[]>(
|
|
221
|
+
name: string,
|
|
222
|
+
overrides: TraceOverrides<Ctx['userCtx']>,
|
|
223
|
+
op: Op<Ctx, Args, S, E>,
|
|
224
|
+
...args: Args
|
|
225
|
+
): Promise<Result<S, E>>;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Trace inline function with name.
|
|
229
|
+
*/
|
|
230
|
+
<R>(name: string, fn: (ctx: SpanContext<Ctx>) => R): R;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Trace inline function with name + overrides.
|
|
234
|
+
*/
|
|
235
|
+
<R>(name: string, overrides: TraceOverrides<Ctx['userCtx']>, fn: (ctx: SpanContext<Ctx>) => R): R;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// =============================================================================
|
|
239
|
+
// Tracer Class
|
|
240
|
+
// =============================================================================
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Tracer - Abstract base class for trace collection
|
|
244
|
+
*
|
|
245
|
+
* Provides trace execution with lifecycle hooks for buffer management.
|
|
246
|
+
* Subclasses implement onTraceStart, onTraceEnd, onSpanStart, onSpanEnd to define
|
|
247
|
+
* how spans are collected and processed.
|
|
248
|
+
*
|
|
249
|
+
* BufferStrategy is injected to control memory management and Arrow conversion.
|
|
250
|
+
*
|
|
251
|
+
* @typeParam B - OpContextBinding type (inferred from constructor argument)
|
|
252
|
+
*/
|
|
253
|
+
export abstract class Tracer<B extends OpContextBinding = OpContextBinding> {
|
|
254
|
+
private readonly logBinding: LogBinding<B['logBinding']['logSchema']>;
|
|
255
|
+
private readonly SpanContextClass: SpanContextClass<OpContextOf<B>>;
|
|
256
|
+
private readonly flagEvaluator: FlagEvaluator<OpContextOf<B>>;
|
|
257
|
+
private readonly ctxDefaults: Record<string, unknown>;
|
|
258
|
+
private readonly deps: Record<string, unknown>;
|
|
259
|
+
private readonly createTraceRoot: TraceRootFactory;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Buffer strategy for memory management and Arrow conversion.
|
|
263
|
+
* Public because SpanContext needs access for child span creation.
|
|
264
|
+
* Also accessible to subclasses for toArrowTable/releaseBuffer calls.
|
|
265
|
+
*/
|
|
266
|
+
readonly bufferStrategy: BufferStrategy<B['logBinding']['logSchema']>;
|
|
267
|
+
|
|
268
|
+
constructor(binding: B, options: TracerOptions<B['logBinding']['logSchema']>) {
|
|
269
|
+
this.logBinding = binding.logBinding;
|
|
270
|
+
this.bufferStrategy = options.bufferStrategy;
|
|
271
|
+
this.ctxDefaults = binding.ctxDefaults ?? EMPTY_SCOPE;
|
|
272
|
+
this.deps = binding.deps ?? EMPTY_SCOPE;
|
|
273
|
+
this.flagEvaluator = this._createFlagEvaluator(binding.flags, options.flagEvaluator);
|
|
274
|
+
this.createTraceRoot = options.createTraceRoot;
|
|
275
|
+
|
|
276
|
+
// Create SpanContext class for all contexts created by this tracer
|
|
277
|
+
// The class closes over schema/logBinding and provides typed methods
|
|
278
|
+
this.SpanContextClass = createSpanContextClass<OpContextOf<B>>(binding.logBinding.logSchema, binding.logBinding);
|
|
279
|
+
|
|
280
|
+
// Bind methods for destructuring (per AGENTS.md - "Always destructure")
|
|
281
|
+
this.trace = this.trace.bind(this);
|
|
282
|
+
this.trace_op = this.trace_op.bind(this);
|
|
283
|
+
this.trace_fn = this.trace_fn.bind(this);
|
|
284
|
+
this.flush = this.flush.bind(this);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private _createFlagEvaluator(
|
|
288
|
+
flags: B['flags'],
|
|
289
|
+
evaluator: FlagEvaluator<OpContext> | undefined,
|
|
290
|
+
): FlagEvaluator<OpContextOf<B>> {
|
|
291
|
+
const delegate = evaluator ?? new InMemoryFlagEvaluator<OpContextOf<B>>(flags);
|
|
292
|
+
const boundEvaluator: FlagEvaluator<OpContextOf<B>> = {
|
|
293
|
+
getSync: (ctx, flag) => delegate.getSync(ctx, flag),
|
|
294
|
+
getAsync: (ctx, flag) => delegate.getAsync(ctx, flag),
|
|
295
|
+
forContext: (ctx) => createFeatureFlagEvaluator<OpContextOf<B>>(flags, ctx, boundEvaluator),
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
return boundEvaluator;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// ===========================================================================
|
|
302
|
+
// Lifecycle Hooks (abstract - subclasses MUST implement)
|
|
303
|
+
// ===========================================================================
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Called when a root trace starts (before fn execution).
|
|
307
|
+
* Only called for root spans created via trace(), not child spans.
|
|
308
|
+
* Subclasses implement to handle trace lifecycle events (e.g., collect for batching).
|
|
309
|
+
*/
|
|
310
|
+
abstract onTraceStart(rootBuffer: SpanBuffer<B['logBinding']['logSchema']>): void;
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Called when a root trace ends (after fn completes, in finally).
|
|
314
|
+
* Always called, even if fn threw an exception.
|
|
315
|
+
* Only called for root spans created via trace(), not child spans.
|
|
316
|
+
* Subclasses implement to handle trace completion (e.g., queue for sending).
|
|
317
|
+
*/
|
|
318
|
+
abstract onTraceEnd(rootBuffer: SpanBuffer<B['logBinding']['logSchema']>): void;
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Called when a child span starts (before fn execution).
|
|
322
|
+
* Only called for child spans created via ctx.span(), not root traces.
|
|
323
|
+
* Subclasses implement if child span lifecycle needs special handling.
|
|
324
|
+
*/
|
|
325
|
+
abstract onSpanStart(childBuffer: SpanBuffer<B['logBinding']['logSchema']>): void;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Called when a child span ends (after fn completes, in finally).
|
|
329
|
+
* Always called, even if fn threw an exception.
|
|
330
|
+
* Only called for child spans created via ctx.span(), not root traces.
|
|
331
|
+
* Subclasses implement if child span lifecycle needs special handling.
|
|
332
|
+
*/
|
|
333
|
+
abstract onSpanEnd(childBuffer: SpanBuffer<B['logBinding']['logSchema']>): void;
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Called before stats are reset during capacity tuning.
|
|
337
|
+
* Allows tracer to capture stats for observability before they're lost.
|
|
338
|
+
*
|
|
339
|
+
* The buffer provides all necessary context:
|
|
340
|
+
* - buffer._stats → SpanBufferStats about to be reset
|
|
341
|
+
* - buffer._opMetadata → which Op/module these stats belong to
|
|
342
|
+
* - buffer.constructor → SpanBufferClass (schema info)
|
|
343
|
+
*
|
|
344
|
+
* @param buffer - The buffer that triggered overflow
|
|
345
|
+
*/
|
|
346
|
+
abstract onStatsWillResetFor(buffer: SpanBuffer<B['logBinding']['logSchema']>): void;
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Flush any pending data. Default is no-op.
|
|
350
|
+
* Subclasses override if they batch data (e.g., collecting in onTraceEnd then flushing here).
|
|
351
|
+
*/
|
|
352
|
+
async flush(): Promise<void> {
|
|
353
|
+
// Default no-op - subclasses override if needed
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// ===========================================================================
|
|
357
|
+
// trace() - Polymorphic dispatcher (like span())
|
|
358
|
+
// ===========================================================================
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Polymorphic trace dispatcher.
|
|
362
|
+
*
|
|
363
|
+
* Parses overloaded arguments and dispatches to monomorphic methods.
|
|
364
|
+
* Uses argument type detection for clean pattern matching.
|
|
365
|
+
*
|
|
366
|
+
* Patterns supported:
|
|
367
|
+
* - (name, fn)
|
|
368
|
+
* - (name, overrides, fn)
|
|
369
|
+
* - (name, op, ...args)
|
|
370
|
+
* - (name, overrides, op, ...args)
|
|
371
|
+
* - Plus line number prefix variants for transformer
|
|
372
|
+
*
|
|
373
|
+
* @see TraceFn for type-level documentation of all overloads
|
|
374
|
+
*/
|
|
375
|
+
trace<S, E, Args extends unknown[]>(
|
|
376
|
+
line: number,
|
|
377
|
+
name: string,
|
|
378
|
+
op: Op<OpContextOf<B>, Args, S, E>,
|
|
379
|
+
...args: Args
|
|
380
|
+
): Promise<Result<S, E>>;
|
|
381
|
+
trace<S, E, Args extends unknown[]>(
|
|
382
|
+
line: number,
|
|
383
|
+
name: string,
|
|
384
|
+
overrides: TraceOverrides<OpContextOf<B>['userCtx']>,
|
|
385
|
+
op: Op<OpContextOf<B>, Args, S, E>,
|
|
386
|
+
...args: Args
|
|
387
|
+
): Promise<Result<S, E>>;
|
|
388
|
+
trace<R>(line: number, name: string, fn: (ctx: SpanContext<OpContextOf<B>>) => R): R;
|
|
389
|
+
trace<R>(
|
|
390
|
+
line: number,
|
|
391
|
+
name: string,
|
|
392
|
+
overrides: TraceOverrides<OpContextOf<B>['userCtx']>,
|
|
393
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => R,
|
|
394
|
+
): R;
|
|
395
|
+
trace<S, E, Args extends unknown[]>(
|
|
396
|
+
name: string,
|
|
397
|
+
op: Op<OpContextOf<B>, Args, S, E>,
|
|
398
|
+
...args: Args
|
|
399
|
+
): Promise<Result<S, E>>;
|
|
400
|
+
trace<S, E, Args extends unknown[]>(
|
|
401
|
+
name: string,
|
|
402
|
+
overrides: TraceOverrides<OpContextOf<B>['userCtx']>,
|
|
403
|
+
op: Op<OpContextOf<B>, Args, S, E>,
|
|
404
|
+
...args: Args
|
|
405
|
+
): Promise<Result<S, E>>;
|
|
406
|
+
trace<R>(name: string, fn: (ctx: SpanContext<OpContextOf<B>>) => R): R;
|
|
407
|
+
trace<R>(
|
|
408
|
+
name: string,
|
|
409
|
+
overrides: TraceOverrides<OpContextOf<B>['userCtx']>,
|
|
410
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => R,
|
|
411
|
+
): R;
|
|
412
|
+
trace(...args: [number | string, ...unknown[]]): unknown {
|
|
413
|
+
const len = args.length;
|
|
414
|
+
if (len === 0) throw new Error('trace() requires at least 1 argument');
|
|
415
|
+
|
|
416
|
+
// Detect if first arg is a line number (transformer-injected)
|
|
417
|
+
const firstArg = args[0];
|
|
418
|
+
const hasLine = typeof firstArg === 'number';
|
|
419
|
+
const line = hasLine ? firstArg : 0;
|
|
420
|
+
|
|
421
|
+
// Name is always required and comes after optional line
|
|
422
|
+
const nameIdx = hasLine ? 1 : 0;
|
|
423
|
+
const name = args[nameIdx];
|
|
424
|
+
if (typeof name !== 'string') {
|
|
425
|
+
throw new Error('trace() requires a trace name string');
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Check if next arg is overrides (object but not Op or function)
|
|
429
|
+
const nextIdx = nameIdx + 1;
|
|
430
|
+
const nextArg = args[nextIdx];
|
|
431
|
+
const hasOverrides = isTraceOverridesArg(nextArg) && !isTraceFn<OpContextOf<B>>(nextArg);
|
|
432
|
+
|
|
433
|
+
const overrides = hasOverrides ? nextArg : EMPTY_SCOPE;
|
|
434
|
+
const fnIdx = nextIdx + (hasOverrides ? 1 : 0);
|
|
435
|
+
const fnOrOp = args[fnIdx];
|
|
436
|
+
const argCount = len - fnIdx - 1;
|
|
437
|
+
|
|
438
|
+
// Dispatch to monomorphic methods
|
|
439
|
+
if (fnOrOp instanceof Op) {
|
|
440
|
+
switch (argCount) {
|
|
441
|
+
case 0:
|
|
442
|
+
return this._trace_unknown_op(line, name, overrides, fnOrOp.metadata, fnOrOp.fn);
|
|
443
|
+
case 1:
|
|
444
|
+
return this._trace_unknown_op(line, name, overrides, fnOrOp.metadata, fnOrOp.fn, args[fnIdx + 1]);
|
|
445
|
+
case 2:
|
|
446
|
+
return this._trace_unknown_op(
|
|
447
|
+
line,
|
|
448
|
+
name,
|
|
449
|
+
overrides,
|
|
450
|
+
fnOrOp.metadata,
|
|
451
|
+
fnOrOp.fn,
|
|
452
|
+
args[fnIdx + 1],
|
|
453
|
+
args[fnIdx + 2],
|
|
454
|
+
);
|
|
455
|
+
case 3:
|
|
456
|
+
return this._trace_unknown_op(
|
|
457
|
+
line,
|
|
458
|
+
name,
|
|
459
|
+
overrides,
|
|
460
|
+
fnOrOp.metadata,
|
|
461
|
+
fnOrOp.fn,
|
|
462
|
+
args[fnIdx + 1],
|
|
463
|
+
args[fnIdx + 2],
|
|
464
|
+
args[fnIdx + 3],
|
|
465
|
+
);
|
|
466
|
+
case 4:
|
|
467
|
+
return this._trace_unknown_op(
|
|
468
|
+
line,
|
|
469
|
+
name,
|
|
470
|
+
overrides,
|
|
471
|
+
fnOrOp.metadata,
|
|
472
|
+
fnOrOp.fn,
|
|
473
|
+
args[fnIdx + 1],
|
|
474
|
+
args[fnIdx + 2],
|
|
475
|
+
args[fnIdx + 3],
|
|
476
|
+
args[fnIdx + 4],
|
|
477
|
+
);
|
|
478
|
+
case 5:
|
|
479
|
+
return this._trace_unknown_op(
|
|
480
|
+
line,
|
|
481
|
+
name,
|
|
482
|
+
overrides,
|
|
483
|
+
fnOrOp.metadata,
|
|
484
|
+
fnOrOp.fn,
|
|
485
|
+
args[fnIdx + 1],
|
|
486
|
+
args[fnIdx + 2],
|
|
487
|
+
args[fnIdx + 3],
|
|
488
|
+
args[fnIdx + 4],
|
|
489
|
+
args[fnIdx + 5],
|
|
490
|
+
);
|
|
491
|
+
case 6:
|
|
492
|
+
return this._trace_unknown_op(
|
|
493
|
+
line,
|
|
494
|
+
name,
|
|
495
|
+
overrides,
|
|
496
|
+
fnOrOp.metadata,
|
|
497
|
+
fnOrOp.fn,
|
|
498
|
+
args[fnIdx + 1],
|
|
499
|
+
args[fnIdx + 2],
|
|
500
|
+
args[fnIdx + 3],
|
|
501
|
+
args[fnIdx + 4],
|
|
502
|
+
args[fnIdx + 5],
|
|
503
|
+
args[fnIdx + 6],
|
|
504
|
+
);
|
|
505
|
+
case 7:
|
|
506
|
+
return this._trace_unknown_op(
|
|
507
|
+
line,
|
|
508
|
+
name,
|
|
509
|
+
overrides,
|
|
510
|
+
fnOrOp.metadata,
|
|
511
|
+
fnOrOp.fn,
|
|
512
|
+
args[fnIdx + 1],
|
|
513
|
+
args[fnIdx + 2],
|
|
514
|
+
args[fnIdx + 3],
|
|
515
|
+
args[fnIdx + 4],
|
|
516
|
+
args[fnIdx + 5],
|
|
517
|
+
args[fnIdx + 6],
|
|
518
|
+
args[fnIdx + 7],
|
|
519
|
+
);
|
|
520
|
+
case 8:
|
|
521
|
+
return this._trace_unknown_op(
|
|
522
|
+
line,
|
|
523
|
+
name,
|
|
524
|
+
overrides,
|
|
525
|
+
fnOrOp.metadata,
|
|
526
|
+
fnOrOp.fn,
|
|
527
|
+
args[fnIdx + 1],
|
|
528
|
+
args[fnIdx + 2],
|
|
529
|
+
args[fnIdx + 3],
|
|
530
|
+
args[fnIdx + 4],
|
|
531
|
+
args[fnIdx + 5],
|
|
532
|
+
args[fnIdx + 6],
|
|
533
|
+
args[fnIdx + 7],
|
|
534
|
+
args[fnIdx + 8],
|
|
535
|
+
);
|
|
536
|
+
default:
|
|
537
|
+
throw new Error(`trace() supports up to 8 op arguments, got ${argCount}`);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Function path - no args allowed
|
|
542
|
+
if (argCount > 0) {
|
|
543
|
+
throw new Error('trace() with inline function does not accept additional arguments');
|
|
544
|
+
}
|
|
545
|
+
if (!isTraceFn<OpContextOf<B>>(fnOrOp)) {
|
|
546
|
+
throw new Error('trace() requires an Op or function callback');
|
|
547
|
+
}
|
|
548
|
+
return this._trace_unknown_fn(line, name, overrides, fnOrOp);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// ===========================================================================
|
|
552
|
+
// Monomorphic trace methods (for transformer optimization)
|
|
553
|
+
// ===========================================================================
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Execute an Op as a root trace (internal monomorphic method).
|
|
557
|
+
* Supports 0-8 arguments. The transformer rewrites trace() calls to this.
|
|
558
|
+
*/
|
|
559
|
+
private _trace_op<S, E, Args extends unknown[]>(
|
|
560
|
+
line: number,
|
|
561
|
+
name: string,
|
|
562
|
+
overrides: Record<string, unknown>,
|
|
563
|
+
op: Op<OpContextOf<B>, Args, S, E>,
|
|
564
|
+
...opArgs: Args
|
|
565
|
+
): Result<S, E> | Promise<Result<S, E>> {
|
|
566
|
+
const ctx = this._createRootContext(line, name, overrides, op.metadata);
|
|
567
|
+
return this._executeResultWithContext(ctx, (c) => op.fn(c, ...opArgs));
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
private _trace_unknown_op(
|
|
571
|
+
line: number,
|
|
572
|
+
name: string,
|
|
573
|
+
overrides: Record<string, unknown>,
|
|
574
|
+
metadata: ReturnType<typeof createOpMetadata>,
|
|
575
|
+
fn: (
|
|
576
|
+
ctx: SpanContext<OpContextOf<B>>,
|
|
577
|
+
...opArgs: unknown[]
|
|
578
|
+
) => Result<unknown, unknown> | Promise<Result<unknown, unknown>>,
|
|
579
|
+
...opArgs: unknown[]
|
|
580
|
+
): Result<unknown, unknown> | Promise<Result<unknown, unknown>> {
|
|
581
|
+
const ctx = this._createRootContext(line, name, overrides, metadata);
|
|
582
|
+
return this._executeResultWithContext(ctx, (childCtx) => fn(childCtx, ...opArgs));
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Execute a function as a root trace (internal monomorphic method).
|
|
587
|
+
* The transformer rewrites trace() calls to this.
|
|
588
|
+
*/
|
|
589
|
+
private _trace_fn<R>(
|
|
590
|
+
line: number,
|
|
591
|
+
name: string,
|
|
592
|
+
overrides: Record<string, unknown>,
|
|
593
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => Promise<R>,
|
|
594
|
+
): Promise<R>;
|
|
595
|
+
private _trace_fn<R>(
|
|
596
|
+
line: number,
|
|
597
|
+
name: string,
|
|
598
|
+
overrides: Record<string, unknown>,
|
|
599
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => R,
|
|
600
|
+
): R;
|
|
601
|
+
private _trace_fn(
|
|
602
|
+
line: number,
|
|
603
|
+
name: string,
|
|
604
|
+
overrides: Record<string, unknown>,
|
|
605
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => unknown,
|
|
606
|
+
): unknown {
|
|
607
|
+
const ctx = this._createRootContext(
|
|
608
|
+
line,
|
|
609
|
+
name,
|
|
610
|
+
overrides,
|
|
611
|
+
createOpMetadata('root', 'tracer', 'runtime', 'unknown', 0),
|
|
612
|
+
);
|
|
613
|
+
return this._executeUnknownWithContext(ctx, fn);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
private _trace_unknown_fn(
|
|
617
|
+
line: number,
|
|
618
|
+
name: string,
|
|
619
|
+
overrides: Record<string, unknown>,
|
|
620
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => unknown,
|
|
621
|
+
): unknown {
|
|
622
|
+
return this._trace_fn(line, name, overrides, fn);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// ===========================================================================
|
|
626
|
+
// Public monomorphic methods (for transformer direct calls)
|
|
627
|
+
// ===========================================================================
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Execute an Op as a root trace (monomorphic - for transformer optimization).
|
|
631
|
+
* Public API for transformer to call directly, bypassing polymorphic dispatch.
|
|
632
|
+
*/
|
|
633
|
+
trace_op<S, E, Args extends unknown[]>(
|
|
634
|
+
line: number,
|
|
635
|
+
name: string,
|
|
636
|
+
overrides: TraceOverrides<OpContextOf<B>['userCtx']>,
|
|
637
|
+
op: Op<OpContextOf<B>, Args, S, E>,
|
|
638
|
+
...opArgs: Args
|
|
639
|
+
): Result<S, E> | Promise<Result<S, E>> {
|
|
640
|
+
return this._trace_op(line, name, overrides, op, ...opArgs);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Execute a function as a root trace (monomorphic - for transformer optimization).
|
|
645
|
+
* Public API for transformer to call directly, bypassing polymorphic dispatch.
|
|
646
|
+
*/
|
|
647
|
+
trace_fn<R>(
|
|
648
|
+
line: number,
|
|
649
|
+
name: string,
|
|
650
|
+
overrides: TraceOverrides<OpContextOf<B>['userCtx']>,
|
|
651
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => Promise<R>,
|
|
652
|
+
): Promise<R>;
|
|
653
|
+
trace_fn<R>(
|
|
654
|
+
line: number,
|
|
655
|
+
name: string,
|
|
656
|
+
overrides: TraceOverrides<OpContextOf<B>['userCtx']>,
|
|
657
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => R,
|
|
658
|
+
): R;
|
|
659
|
+
trace_fn(
|
|
660
|
+
line: number,
|
|
661
|
+
name: string,
|
|
662
|
+
overrides: TraceOverrides<OpContextOf<B>['userCtx']>,
|
|
663
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => unknown,
|
|
664
|
+
): unknown {
|
|
665
|
+
return this._trace_fn(line, name, overrides, fn);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// ===========================================================================
|
|
669
|
+
// Internal helpers
|
|
670
|
+
// ===========================================================================
|
|
671
|
+
|
|
672
|
+
private _createRootContext(
|
|
673
|
+
_line: number,
|
|
674
|
+
name: string,
|
|
675
|
+
overrides: Record<string, unknown>,
|
|
676
|
+
metadata: ReturnType<typeof createOpMetadata>,
|
|
677
|
+
): SpanContextInstance<OpContextOf<B>> {
|
|
678
|
+
// Extract trace_id from overrides if present
|
|
679
|
+
const traceId: TraceId = isValidTraceId(overrides.trace_id) ? overrides.trace_id : generateTraceId();
|
|
680
|
+
const schema = this.logBinding.logSchema;
|
|
681
|
+
|
|
682
|
+
// Validate null-sentinel required fields and merge user context.
|
|
683
|
+
// _resolveUserContext ignores trace_id (transport-only field).
|
|
684
|
+
const overrideRecord: Record<string, unknown> = { ...overrides };
|
|
685
|
+
const resolvedUserCtx = this._resolveUserContext(overrideRecord);
|
|
686
|
+
|
|
687
|
+
// Create TraceRoot via platform-specific factory
|
|
688
|
+
const traceRoot = this.createTraceRoot(traceId, this);
|
|
689
|
+
|
|
690
|
+
// Create root SpanBuffer with pre-built TraceRoot via strategy
|
|
691
|
+
const buffer = this.bufferStrategy.createSpanBuffer(
|
|
692
|
+
schema,
|
|
693
|
+
traceRoot, // pre-built TraceRoot with trace_id, anchors, tracer
|
|
694
|
+
metadata, // opMetadata (for both callsite and op at root level)
|
|
695
|
+
);
|
|
696
|
+
|
|
697
|
+
// Write span-start entry (row 0)
|
|
698
|
+
writeSpanStart(buffer, name);
|
|
699
|
+
|
|
700
|
+
// Create tag writer and span logger (needed for constructor)
|
|
701
|
+
const tagWriter: TagWriter<B['logBinding']['logSchema']> = createTagWriter(schema, buffer);
|
|
702
|
+
const spanLogger = createSpanLoggerFromGenerator(schema, buffer);
|
|
703
|
+
|
|
704
|
+
// Instantiate SpanContext class with direct arguments (no temp object allocation)
|
|
705
|
+
const ctx = new this.SpanContextClass(buffer, schema, spanLogger, tagWriter);
|
|
706
|
+
|
|
707
|
+
// Set up deps from config (may be EMPTY_SCOPE if none provided)
|
|
708
|
+
ctx.deps = this.deps;
|
|
709
|
+
|
|
710
|
+
ctx.ff = this.flagEvaluator.forContext(ctx);
|
|
711
|
+
|
|
712
|
+
// Copy resolved user context onto SpanContext.
|
|
713
|
+
for (const key in resolvedUserCtx) {
|
|
714
|
+
(ctx as Record<string, unknown>)[key] = resolvedUserCtx[key];
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
return ctx;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Validate null-sentinel required fields and merge with provided overrides.
|
|
722
|
+
*
|
|
723
|
+
* Per the ctx config pattern:
|
|
724
|
+
* - Properties with null values in ctxDefaults must be provided in overrides
|
|
725
|
+
* - Properties with default values can optionally be overridden
|
|
726
|
+
* - undefined is allowed for optional fields
|
|
727
|
+
*/
|
|
728
|
+
private _resolveUserContext(overrides: Record<string, unknown>): Record<string, unknown> {
|
|
729
|
+
const ctxDefaults = this.ctxDefaults;
|
|
730
|
+
|
|
731
|
+
// Check that all null-sentinel keys are provided in overrides
|
|
732
|
+
for (const key of Object.keys(ctxDefaults)) {
|
|
733
|
+
const defaultValue = ctxDefaults[key];
|
|
734
|
+
if (defaultValue === null) {
|
|
735
|
+
const providedValue = overrides[key];
|
|
736
|
+
if (providedValue === null || providedValue === undefined) {
|
|
737
|
+
throw new Error(
|
|
738
|
+
`Required context parameter '${key}' must be provided. ` +
|
|
739
|
+
'Properties with null values in ctx config are required.',
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// Merge defaults with provided overrides (provided values win)
|
|
746
|
+
const resolvedUserCtx: Record<string, unknown> = { ...ctxDefaults };
|
|
747
|
+
for (const key of Object.keys(overrides)) {
|
|
748
|
+
if (key === 'trace_id') {
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
const value = overrides[key];
|
|
752
|
+
if (value !== undefined) {
|
|
753
|
+
resolvedUserCtx[key] = value;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
return resolvedUserCtx;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Execute function with context and handle span-ok/span-err/span-exception writes
|
|
762
|
+
* Promise-agnostic: returns sync for sync fn, Promise for async fn
|
|
763
|
+
*
|
|
764
|
+
* Writes span-end entry (entry_type, timestamp, error_code) and applies deferred tags
|
|
765
|
+
* when the function returns an Ok/Err result.
|
|
766
|
+
*/
|
|
767
|
+
private _executeResultWithContext<S, E>(
|
|
768
|
+
ctx: SpanContextInstance<OpContextOf<B>>,
|
|
769
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => Result<S, E> | Promise<Result<S, E>>,
|
|
770
|
+
): Result<S, E> | Promise<Result<S, E>> {
|
|
771
|
+
const buffer = ctx._buffer;
|
|
772
|
+
|
|
773
|
+
this.onTraceStart(buffer as SpanBuffer<B['logBinding']['logSchema']>);
|
|
774
|
+
|
|
775
|
+
let isAsync = false;
|
|
776
|
+
try {
|
|
777
|
+
const result = fn(ctx);
|
|
778
|
+
|
|
779
|
+
if (isPromiseResult(result)) {
|
|
780
|
+
isAsync = true;
|
|
781
|
+
return result
|
|
782
|
+
.then(
|
|
783
|
+
(resolved) => {
|
|
784
|
+
writeSpanEnd(buffer, resolved);
|
|
785
|
+
return resolved;
|
|
786
|
+
},
|
|
787
|
+
(error: unknown) => {
|
|
788
|
+
buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_EXCEPTION);
|
|
789
|
+
|
|
790
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
791
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
792
|
+
|
|
793
|
+
buffer.message(1, errorMessage);
|
|
794
|
+
if (errorStack) {
|
|
795
|
+
buffer.exception_stack(1, errorStack);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
throw error;
|
|
799
|
+
},
|
|
800
|
+
)
|
|
801
|
+
.finally(() => this.onTraceEnd(buffer as SpanBuffer<B['logBinding']['logSchema']>));
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
writeSpanEnd(buffer, result);
|
|
805
|
+
return result;
|
|
806
|
+
} catch (error) {
|
|
807
|
+
buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_EXCEPTION);
|
|
808
|
+
|
|
809
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
810
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
811
|
+
|
|
812
|
+
buffer.message(1, errorMessage);
|
|
813
|
+
if (errorStack) {
|
|
814
|
+
buffer.exception_stack(1, errorStack);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
throw error;
|
|
818
|
+
} finally {
|
|
819
|
+
if (!isAsync) {
|
|
820
|
+
this.onTraceEnd(buffer as SpanBuffer<B['logBinding']['logSchema']>);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
private _executeUnknownWithContext(
|
|
826
|
+
ctx: SpanContextInstance<OpContextOf<B>>,
|
|
827
|
+
fn: (ctx: SpanContext<OpContextOf<B>>) => unknown,
|
|
828
|
+
): unknown {
|
|
829
|
+
const buffer = ctx._buffer;
|
|
830
|
+
|
|
831
|
+
// Call trace start hook
|
|
832
|
+
this.onTraceStart(buffer as SpanBuffer<B['logBinding']['logSchema']>);
|
|
833
|
+
|
|
834
|
+
let isAsync = false;
|
|
835
|
+
try {
|
|
836
|
+
const result = fn(ctx);
|
|
837
|
+
|
|
838
|
+
if (isPromiseResult(result)) {
|
|
839
|
+
isAsync = true;
|
|
840
|
+
return result
|
|
841
|
+
.then(
|
|
842
|
+
(resolved) => {
|
|
843
|
+
if (resolved instanceof Ok || resolved instanceof Err) {
|
|
844
|
+
writeSpanEnd(buffer, resolved);
|
|
845
|
+
} else {
|
|
846
|
+
buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_OK);
|
|
847
|
+
}
|
|
848
|
+
return resolved;
|
|
849
|
+
},
|
|
850
|
+
(error: unknown) => {
|
|
851
|
+
buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_EXCEPTION);
|
|
852
|
+
|
|
853
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
854
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
855
|
+
|
|
856
|
+
buffer.message(1, errorMessage);
|
|
857
|
+
if (errorStack) {
|
|
858
|
+
buffer.exception_stack(1, errorStack);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
throw error;
|
|
862
|
+
},
|
|
863
|
+
)
|
|
864
|
+
.finally(() => this.onTraceEnd(buffer as SpanBuffer<B['logBinding']['logSchema']>));
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
// Sync path - write span-end
|
|
868
|
+
if (result instanceof Ok || result instanceof Err) {
|
|
869
|
+
writeSpanEnd(buffer, result);
|
|
870
|
+
} else {
|
|
871
|
+
buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_OK);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
return result;
|
|
875
|
+
} catch (error) {
|
|
876
|
+
// Sync exception path
|
|
877
|
+
buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_EXCEPTION);
|
|
878
|
+
|
|
879
|
+
// Write exception details
|
|
880
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
881
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
882
|
+
|
|
883
|
+
buffer.message(1, errorMessage);
|
|
884
|
+
if (errorStack) {
|
|
885
|
+
buffer.exception_stack(1, errorStack);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
throw error;
|
|
889
|
+
} finally {
|
|
890
|
+
// Only call for sync path - async uses .finally() on promise
|
|
891
|
+
if (!isAsync) {
|
|
892
|
+
this.onTraceEnd(buffer as SpanBuffer<B['logBinding']['logSchema']>);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}
|