@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,1566 @@
|
|
|
1
|
+
/* biome-ignore-all lint/complexity/noArguments: hot-path overload dispatch avoids rest-arg allocations */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SpanContext - Context provided to op functions during span execution
|
|
5
|
+
*
|
|
6
|
+
* Per specs/lmao/01c_context_flow_and_op_wrappers.md and specs/lmao/01l_op_context_pattern.md:
|
|
7
|
+
* - SpanContext combines built-in properties with user-extensible Extra
|
|
8
|
+
* - Uses prototype-based inheritance for V8 hidden class optimization
|
|
9
|
+
* - Child spans inherit scoped attributes from parents
|
|
10
|
+
*
|
|
11
|
+
* ## Class-Based Design
|
|
12
|
+
*
|
|
13
|
+
* SpanContext is implemented as a class factory pattern:
|
|
14
|
+
* - `createSpanContextClass()` returns a class that closes over schema/logBinding
|
|
15
|
+
* - Child contexts use `Object.create(parent)` for prototype inheritance
|
|
16
|
+
* - User properties (deps, ff, env) are inherited via prototype chain
|
|
17
|
+
* - Context overrides work by setting own properties that shadow inherited ones
|
|
18
|
+
*
|
|
19
|
+
* ## Method Binding for Destructuring
|
|
20
|
+
*
|
|
21
|
+
* Methods that users commonly destructure (span, ok, err, setScope) are defined
|
|
22
|
+
* as arrow function properties. This means:
|
|
23
|
+
* - They're own properties on each instance (slight memory overhead)
|
|
24
|
+
* - But destructuring works without explicit .bind() calls
|
|
25
|
+
* - const { span, ok, err } = ctx; // Just works!
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import type { TagWriter } from './codegen/fixedPositionWriterGenerator.js';
|
|
29
|
+
import { createTagWriter } from './codegen/fixedPositionWriterGenerator.js';
|
|
30
|
+
import {
|
|
31
|
+
createSpanLogger as createSpanLoggerFromGenerator,
|
|
32
|
+
type FluentLogEntry,
|
|
33
|
+
type ScopeUpdate,
|
|
34
|
+
type SpanLoggerImpl,
|
|
35
|
+
} from './codegen/spanLoggerGenerator.js';
|
|
36
|
+
import { Blocked } from './errors/Blocked.js';
|
|
37
|
+
import type { RetryPolicy } from './errors/retry-policy.js';
|
|
38
|
+
import { TransientError } from './errors/Transient.js';
|
|
39
|
+
import type { RemappedViewConstructor } from './logBinding.js';
|
|
40
|
+
import { Op } from './op.js';
|
|
41
|
+
import type { OpContext, OpMetadata, SpanContext, SpanFn, SpanLogger, SpanSyncFn } from './opContext/types.js';
|
|
42
|
+
import { Err, hasErrorCode, Ok, type Result } from './result.js';
|
|
43
|
+
import type { FeatureFlagEvaluator, InferFeatureFlagsWithContext } from './schema/evaluator.js';
|
|
44
|
+
import {
|
|
45
|
+
ENTRY_TYPE_SPAN_ERR,
|
|
46
|
+
ENTRY_TYPE_SPAN_EXCEPTION,
|
|
47
|
+
ENTRY_TYPE_SPAN_OK,
|
|
48
|
+
ENTRY_TYPE_SPAN_RETRY,
|
|
49
|
+
} from './schema/systemSchema.js';
|
|
50
|
+
import type { InferSchema, LogSchema } from './schema/types.js';
|
|
51
|
+
import type { SpanBufferConstructor } from './spanBuffer.js';
|
|
52
|
+
import type { LogBinding, SpanBuffer } from './types.js';
|
|
53
|
+
|
|
54
|
+
// Note: TraceRoot.writeSpanStart() is used instead of direct timestamp writes.
|
|
55
|
+
// The platform-specific TraceRoot (traceRoot.es.ts or traceRoot.node.ts) handles
|
|
56
|
+
// timestamp calculation and writes to buffer._system columns.
|
|
57
|
+
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// SpanContext Symbol Marker
|
|
60
|
+
// =============================================================================
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Internal symbol to mark span contexts
|
|
64
|
+
* Used for type guards and prototype chain detection
|
|
65
|
+
*/
|
|
66
|
+
export const SPAN_CONTEXT_MARKER = Symbol.for('lmao.SpanContext');
|
|
67
|
+
|
|
68
|
+
// =============================================================================
|
|
69
|
+
// Type Exports
|
|
70
|
+
// =============================================================================
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Internal SpanLogger type with FF methods and internal methods exposed.
|
|
74
|
+
* Used by FeatureFlagEvaluator and internal span management code.
|
|
75
|
+
*/
|
|
76
|
+
export type SpanLoggerInternal<T extends LogSchema> = SpanLoggerImpl<T> & {
|
|
77
|
+
/**
|
|
78
|
+
* Write feature flag access entry (internal, not on public type).
|
|
79
|
+
* Called by FeatureFlagEvaluator to log flag access.
|
|
80
|
+
*/
|
|
81
|
+
ffAccess(flagName: string, value: unknown): void;
|
|
82
|
+
/**
|
|
83
|
+
* Write feature flag usage entry (internal, not on public type).
|
|
84
|
+
* Called by FeatureFlagEvaluator to log flag usage.
|
|
85
|
+
*/
|
|
86
|
+
ffUsage(flagName: string, context?: Record<string, unknown>): FluentLogEntry<T>;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
type SpanDispatchFn<Ctx extends OpContext, Args extends unknown[] = unknown[], S = unknown, E = unknown> = (
|
|
90
|
+
ctx: SpanContext<Ctx>,
|
|
91
|
+
...args: Args
|
|
92
|
+
) => Result<S, E> | Promise<Result<S, E>>;
|
|
93
|
+
|
|
94
|
+
type SpanDispatchTarget<Ctx extends OpContext> = {
|
|
95
|
+
readonly SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>;
|
|
96
|
+
readonly remappedViewClass: RemappedViewConstructor | undefined;
|
|
97
|
+
readonly opMetadata: OpMetadata;
|
|
98
|
+
readonly fn: SpanDispatchFn<Ctx>;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
function isOpInstance<Ctx extends OpContext>(value: unknown): value is Op<Ctx, unknown[], unknown, unknown> {
|
|
102
|
+
return value instanceof Op;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// WHY: resolveSpanTarget() accepts either an Op instance or a raw span
|
|
106
|
+
// function. TypeScript needs an explicit predicate here to preserve the call
|
|
107
|
+
// signature when the non-Op branch passes `value` through as `fn`.
|
|
108
|
+
function isSpanDispatchFn<Ctx extends OpContext>(value: unknown): value is SpanDispatchFn<Ctx> {
|
|
109
|
+
return typeof value === 'function';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function isSpanBufferConstructorForSchema<T extends LogSchema>(
|
|
113
|
+
value: unknown,
|
|
114
|
+
schema: T,
|
|
115
|
+
): value is SpanBufferConstructor<T> {
|
|
116
|
+
return (
|
|
117
|
+
typeof value === 'function' &&
|
|
118
|
+
Reflect.get(value, 'schema') === schema &&
|
|
119
|
+
typeof Reflect.get(value, 'stats') === 'object'
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function getBufferConstructor<T extends LogSchema>(buffer: SpanBuffer<T>): SpanBufferConstructor<T> {
|
|
124
|
+
const ctor = buffer.constructor;
|
|
125
|
+
if (!isSpanBufferConstructorForSchema(ctor, buffer._logSchema)) {
|
|
126
|
+
throw new TypeError('Span buffer constructor does not match the buffer schema');
|
|
127
|
+
}
|
|
128
|
+
return ctor;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function isSpanBufferForSchema<T extends LogSchema>(buffer: unknown, schema: T): buffer is SpanBuffer<T> {
|
|
132
|
+
return (
|
|
133
|
+
typeof buffer === 'object' &&
|
|
134
|
+
buffer !== null &&
|
|
135
|
+
Reflect.get(buffer, '_logSchema') === schema &&
|
|
136
|
+
isSpanBufferConstructorForSchema(Reflect.get(buffer, 'constructor'), schema)
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function isSpanContextInstance<Ctx extends OpContext>(value: unknown): value is SpanContextInstance<Ctx> {
|
|
141
|
+
return (
|
|
142
|
+
isSpanContext<Ctx>(value) &&
|
|
143
|
+
Reflect.has(value, '_buffer') &&
|
|
144
|
+
Reflect.has(value, '_spanLogger') &&
|
|
145
|
+
Reflect.has(value, '_schema')
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function createInheritedContext<Ctx extends OpContext>(parent: SpanContextInstance<Ctx>): SpanContextInstance<Ctx> {
|
|
150
|
+
const child: unknown = Object.create(parent);
|
|
151
|
+
if (!isSpanContextInstance<Ctx>(child)) {
|
|
152
|
+
throw new TypeError('Failed to create child span context');
|
|
153
|
+
}
|
|
154
|
+
return child;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function createInheritedContextWithOverrides<Ctx extends OpContext>(
|
|
158
|
+
parent: SpanContextInstance<Ctx>,
|
|
159
|
+
overrides: object,
|
|
160
|
+
): SpanContextInstance<Ctx> {
|
|
161
|
+
const child: unknown = Object.assign(Object.create(parent), overrides);
|
|
162
|
+
if (!isSpanContextInstance<Ctx>(child)) {
|
|
163
|
+
throw new TypeError('Failed to create overridden child span context');
|
|
164
|
+
}
|
|
165
|
+
return child;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function readStringArgument(args: IArguments, index: number, label: string): string {
|
|
169
|
+
const value = args[index];
|
|
170
|
+
if (typeof value !== 'string') {
|
|
171
|
+
throw new TypeError(`${label} must be a string`);
|
|
172
|
+
}
|
|
173
|
+
return value;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function resolveSpanTarget<Ctx extends OpContext>(
|
|
177
|
+
value: unknown,
|
|
178
|
+
fallbackBuffer: SpanBuffer<Ctx['logSchema']>,
|
|
179
|
+
): SpanDispatchTarget<Ctx> {
|
|
180
|
+
if (isOpInstance<Ctx>(value)) {
|
|
181
|
+
return {
|
|
182
|
+
SpanBufferClass: value.SpanBufferClass,
|
|
183
|
+
remappedViewClass: value.remappedViewClass,
|
|
184
|
+
opMetadata: value.metadata,
|
|
185
|
+
fn: value.fn,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (!isSpanDispatchFn<Ctx>(value)) {
|
|
190
|
+
throw new TypeError('span() expects an Op or function');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
SpanBufferClass: getBufferConstructor(fallbackBuffer),
|
|
195
|
+
remappedViewClass: undefined,
|
|
196
|
+
opMetadata: fallbackBuffer._opMetadata,
|
|
197
|
+
fn: value,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// =============================================================================
|
|
202
|
+
// Helper Functions
|
|
203
|
+
// =============================================================================
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Write span-start entry to buffer at row 0 (fixed layout)
|
|
207
|
+
* Pre-initialize row 1 as span-exception (will be overwritten by ok/err)
|
|
208
|
+
* Set writeIndex to 2 (events start after reserved rows)
|
|
209
|
+
*
|
|
210
|
+
* Per specs/lmao/01h_entry_types_and_logging_primitives.md:
|
|
211
|
+
* - Row 0: span-start (written here)
|
|
212
|
+
* - Row 1: span-end (pre-initialized as exception, overwritten by ok/err)
|
|
213
|
+
* - Row 2+: events (ctx.log.* appends here)
|
|
214
|
+
*
|
|
215
|
+
* @param buffer - SpanBuffer to write to
|
|
216
|
+
* @param spanName - Name for this span
|
|
217
|
+
*/
|
|
218
|
+
export function writeSpanStart<T extends LogSchema>(buffer: SpanBuffer<T>, spanName: string): void {
|
|
219
|
+
// Delegate to TraceRoot - platform-specific implementation handles timestamps
|
|
220
|
+
buffer._traceRoot.writeSpanStart(buffer, spanName);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Create a SpanLogger for the given buffer.
|
|
225
|
+
*
|
|
226
|
+
* Per specs/lmao/01i_span_scope_attributes.md: Scope values are stored directly on buffer._scopeValues.
|
|
227
|
+
* The SpanLogger reads/writes scope via buffer._scopeValues - no separate Scope class needed.
|
|
228
|
+
*
|
|
229
|
+
* @param schema - Tag attribute schema with field definitions
|
|
230
|
+
* @param buffer - SpanBuffer to write entries to (per-span instance)
|
|
231
|
+
* @returns SpanLogger with typed methods matching schema
|
|
232
|
+
*/
|
|
233
|
+
export function createSpanLogger<T extends LogSchema>(schema: T, buffer: SpanBuffer<T>): SpanLoggerImpl<T> {
|
|
234
|
+
return createSpanLoggerFromGenerator(schema, buffer);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Calculate delay for retry based on policy and attempt number.
|
|
239
|
+
*
|
|
240
|
+
* @param policy - RetryPolicy from TransientError
|
|
241
|
+
* @param attempt - Current attempt number (1-indexed)
|
|
242
|
+
* @returns Delay in milliseconds before next retry
|
|
243
|
+
*/
|
|
244
|
+
function calculateDelay(policy: RetryPolicy, attempt: number): number {
|
|
245
|
+
let delay: number;
|
|
246
|
+
|
|
247
|
+
switch (policy.backoff) {
|
|
248
|
+
case 'exponential':
|
|
249
|
+
// Delay doubles each attempt: baseDelay * 2^(attempt-1)
|
|
250
|
+
delay = Math.min(policy.baseDelayMs * 2 ** (attempt - 1), policy.maxDelayMs ?? 30000);
|
|
251
|
+
break;
|
|
252
|
+
case 'linear':
|
|
253
|
+
// Delay increases linearly: baseDelay * attempt
|
|
254
|
+
delay = Math.min(policy.baseDelayMs * attempt, policy.maxDelayMs ?? 30000);
|
|
255
|
+
break;
|
|
256
|
+
case 'fixed':
|
|
257
|
+
// Same delay between each attempt
|
|
258
|
+
delay = policy.baseDelayMs;
|
|
259
|
+
break;
|
|
260
|
+
default:
|
|
261
|
+
delay = policy.baseDelayMs;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Apply jitter if enabled (default true) - random value between 0 and delay
|
|
265
|
+
if (policy.jitter !== false) {
|
|
266
|
+
delay = Math.floor(Math.random() * delay);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return delay;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Write span-retry entry to buffer.
|
|
274
|
+
*
|
|
275
|
+
* Per specs/lmao/01h_entry_types_and_logging_primitives.md:
|
|
276
|
+
* - span-retry appends to Row 2+ in parent span buffer (like log entries)
|
|
277
|
+
* - Trace-only entry (NOT written to event log)
|
|
278
|
+
* - Contains: attempt number, error code, and delay until next attempt
|
|
279
|
+
*
|
|
280
|
+
* @param buffer - SpanBuffer to write to (appends at _writeIndex)
|
|
281
|
+
* @param attempt - Attempt number (1-indexed)
|
|
282
|
+
* @param error - TransientError that triggered the retry
|
|
283
|
+
* @param delayMs - Delay before next attempt
|
|
284
|
+
*/
|
|
285
|
+
function writeRetryEntry<T extends LogSchema>(
|
|
286
|
+
buffer: SpanBuffer<T>,
|
|
287
|
+
attempt: number,
|
|
288
|
+
error: TransientError<string, unknown>,
|
|
289
|
+
delayMs: number,
|
|
290
|
+
): void {
|
|
291
|
+
// Get current write index and advance for next write
|
|
292
|
+
const index = buffer._writeIndex;
|
|
293
|
+
|
|
294
|
+
// Write entry via TraceRoot for timestamp handling
|
|
295
|
+
// TraceRoot.writeLogEntry writes timestamp and entry_type at the given index
|
|
296
|
+
buffer._traceRoot.writeLogEntry(buffer, ENTRY_TYPE_SPAN_RETRY);
|
|
297
|
+
|
|
298
|
+
// Write retry-specific message: retry:op:{opName} for prefix-based querying
|
|
299
|
+
const opName = buffer._opMetadata?.name ?? 'unknown';
|
|
300
|
+
buffer.message(index, `retry:op:${opName}`);
|
|
301
|
+
|
|
302
|
+
// Write error code if available
|
|
303
|
+
if (error.code) {
|
|
304
|
+
buffer.error_code(index, error.code);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Retry metadata fields for direct queryability in Arrow output
|
|
308
|
+
buffer.retry_attempt(index, attempt);
|
|
309
|
+
buffer.retry_delay_ms(index, delayMs);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Sleep for the specified duration.
|
|
314
|
+
*
|
|
315
|
+
* @param ms - Duration in milliseconds
|
|
316
|
+
* @returns Promise that resolves after the delay
|
|
317
|
+
*/
|
|
318
|
+
function sleep(ms: number): Promise<void> {
|
|
319
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Execute function with retry loop for TransientError handling.
|
|
324
|
+
*
|
|
325
|
+
* Per plan 19-03: Op class handles retry loop internally.
|
|
326
|
+
* - TransientError from op body triggers retry based on error.policy
|
|
327
|
+
* - Retry respects maxAttempts from TransientError.policy
|
|
328
|
+
* - span-retry entry written for each transient failure
|
|
329
|
+
* - Only final result written as span-ok or span-err
|
|
330
|
+
* - BlockedError returns immediately without retry
|
|
331
|
+
*
|
|
332
|
+
* @param buffer - SpanBuffer to write retry entries to
|
|
333
|
+
* @param fn - Function to execute (may be retried)
|
|
334
|
+
* @returns Final result (success, non-transient error, or exhausted transient error)
|
|
335
|
+
*/
|
|
336
|
+
async function executeWithRetry<T extends LogSchema, S, E>(
|
|
337
|
+
buffer: SpanBuffer<T>,
|
|
338
|
+
fn: () => Result<S, E> | Promise<Result<S, E>>,
|
|
339
|
+
): Promise<Result<S, E>> {
|
|
340
|
+
let attempt = 0;
|
|
341
|
+
|
|
342
|
+
while (true) {
|
|
343
|
+
attempt++;
|
|
344
|
+
|
|
345
|
+
// Execute the function
|
|
346
|
+
const result = await fn();
|
|
347
|
+
|
|
348
|
+
// Success - return immediately
|
|
349
|
+
if (result instanceof Ok) {
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Error result - check error type for retry behavior
|
|
354
|
+
const error = (result as Err<E>).error;
|
|
355
|
+
|
|
356
|
+
// BlockedError - return immediately, no retry
|
|
357
|
+
if (error instanceof Blocked) {
|
|
358
|
+
return result;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// TransientError - check if we should retry
|
|
362
|
+
if (error instanceof TransientError) {
|
|
363
|
+
const { policy } = error;
|
|
364
|
+
|
|
365
|
+
// Check attempt limit (maxAttempts includes initial attempt)
|
|
366
|
+
if (attempt >= policy.maxAttempts) {
|
|
367
|
+
// Exhausted - return final error
|
|
368
|
+
return result;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// Calculate delay based on policy and attempt number
|
|
372
|
+
const delay = calculateDelay(policy, attempt);
|
|
373
|
+
|
|
374
|
+
// Write span-retry entry to buffer for observability
|
|
375
|
+
writeRetryEntry(buffer, attempt, error, delay);
|
|
376
|
+
|
|
377
|
+
// Wait before retry
|
|
378
|
+
await sleep(delay);
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Non-transient error - return immediately
|
|
383
|
+
return result;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Write span-end entry to buffer at row 1.
|
|
389
|
+
*
|
|
390
|
+
* Called by span methods after fn() returns to write:
|
|
391
|
+
* - entry_type (SPAN_OK or SPAN_ERR based on result instanceof)
|
|
392
|
+
* - timestamp
|
|
393
|
+
* - error_code (for Err only)
|
|
394
|
+
* - result row attributes already written eagerly by the fixed-position ResultWriter
|
|
395
|
+
*
|
|
396
|
+
* @param buffer - SpanBuffer to write to
|
|
397
|
+
* @param result - The result returned by the span function
|
|
398
|
+
*/
|
|
399
|
+
export function writeSpanEnd<T extends LogSchema, S, E>(buffer: SpanBuffer<T>, result: Result<S, E>): void {
|
|
400
|
+
// Write entry_type and timestamp via TraceRoot (platform-specific)
|
|
401
|
+
if (result instanceof Ok) {
|
|
402
|
+
buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_OK);
|
|
403
|
+
} else if (result instanceof Err) {
|
|
404
|
+
buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_ERR);
|
|
405
|
+
// Write error_code if the error has a code property
|
|
406
|
+
if (hasErrorCode(result.error)) {
|
|
407
|
+
buffer.error_code(1, result.error.code);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// =============================================================================
|
|
413
|
+
// SpanContext Class Types
|
|
414
|
+
// =============================================================================
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Constructor type for SpanContext classes created by createSpanContextClass.
|
|
418
|
+
* Takes buffer, schema, spanLogger, tag directly (no temp object allocation).
|
|
419
|
+
*/
|
|
420
|
+
export type SpanContextClass<Ctx extends OpContext> = new (
|
|
421
|
+
buffer: SpanBuffer<Ctx['logSchema']>,
|
|
422
|
+
schema: Ctx['logSchema'],
|
|
423
|
+
spanLogger: SpanLoggerImpl<Ctx['logSchema']>,
|
|
424
|
+
tag: TagWriter<Ctx['logSchema']>,
|
|
425
|
+
) => SpanContextInstance<Ctx>;
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Instance type of SpanContext class - what ops actually receive.
|
|
429
|
+
* This is a type alias that extends the public SpanContext with internal properties.
|
|
430
|
+
*/
|
|
431
|
+
export type SpanContextInstance<Ctx extends OpContext> = SpanContext<Ctx> & {
|
|
432
|
+
// Internal properties
|
|
433
|
+
_buffer: SpanBuffer<Ctx['logSchema']>;
|
|
434
|
+
_schema: Ctx['logSchema'];
|
|
435
|
+
_spanLogger: SpanLoggerImpl<Ctx['logSchema']>;
|
|
436
|
+
_logBinding: LogBinding;
|
|
437
|
+
|
|
438
|
+
// Internal methods
|
|
439
|
+
_newCtx0(): SpanContextInstance<Ctx>;
|
|
440
|
+
_newCtx1(overrides: object): SpanContextInstance<Ctx>;
|
|
441
|
+
_spanPre(
|
|
442
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
443
|
+
line: number,
|
|
444
|
+
name: string,
|
|
445
|
+
SpanBufferClass: SpanBufferConstructor,
|
|
446
|
+
remappedViewClass: import('./logBinding.js').RemappedViewConstructor | undefined,
|
|
447
|
+
opMetadata: import('./opContext/opTypes.js').OpMetadata,
|
|
448
|
+
): SpanContextInstance<Ctx>;
|
|
449
|
+
_spanException(buffer: SpanBuffer<Ctx['logSchema']>, error: unknown): void;
|
|
450
|
+
|
|
451
|
+
// Monomorphic span methods (span0-span8)
|
|
452
|
+
// Transformer emits: ctx.span0(line, name, ctx, SpanBufferClass, remappedViewClass, opMetadata, fn, ...args)
|
|
453
|
+
spanSync0<S, E>(
|
|
454
|
+
line: number,
|
|
455
|
+
name: string,
|
|
456
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
457
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
458
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
459
|
+
opMetadata: OpMetadata,
|
|
460
|
+
fn: (ctx: SpanContext<Ctx>) => Result<S, E>,
|
|
461
|
+
): Result<S, E>;
|
|
462
|
+
span0<S, E>(
|
|
463
|
+
line: number,
|
|
464
|
+
name: string,
|
|
465
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
466
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
467
|
+
remappedViewClass: import('./logBinding.js').RemappedViewConstructor | undefined,
|
|
468
|
+
opMetadata: import('./opContext/opTypes.js').OpMetadata,
|
|
469
|
+
fn: (ctx: SpanContext<Ctx>) => Result<S, E> | Promise<Result<S, E>>,
|
|
470
|
+
): Promise<Result<S, E>>;
|
|
471
|
+
span1<S, E, A1>(
|
|
472
|
+
line: number,
|
|
473
|
+
name: string,
|
|
474
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
475
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
476
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
477
|
+
opMetadata: OpMetadata,
|
|
478
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1) => Result<S, E> | Promise<Result<S, E>>,
|
|
479
|
+
a1: A1,
|
|
480
|
+
): Promise<Result<S, E>>;
|
|
481
|
+
span2<S, E, A1, A2>(
|
|
482
|
+
line: number,
|
|
483
|
+
name: string,
|
|
484
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
485
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
486
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
487
|
+
opMetadata: OpMetadata,
|
|
488
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2) => Result<S, E> | Promise<Result<S, E>>,
|
|
489
|
+
a1: A1,
|
|
490
|
+
a2: A2,
|
|
491
|
+
): Promise<Result<S, E>>;
|
|
492
|
+
span3<S, E, A1, A2, A3>(
|
|
493
|
+
line: number,
|
|
494
|
+
name: string,
|
|
495
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
496
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
497
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
498
|
+
opMetadata: OpMetadata,
|
|
499
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3) => Result<S, E> | Promise<Result<S, E>>,
|
|
500
|
+
a1: A1,
|
|
501
|
+
a2: A2,
|
|
502
|
+
a3: A3,
|
|
503
|
+
): Promise<Result<S, E>>;
|
|
504
|
+
span4<S, E, A1, A2, A3, A4>(
|
|
505
|
+
line: number,
|
|
506
|
+
name: string,
|
|
507
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
508
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
509
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
510
|
+
opMetadata: OpMetadata,
|
|
511
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4) => Result<S, E> | Promise<Result<S, E>>,
|
|
512
|
+
a1: A1,
|
|
513
|
+
a2: A2,
|
|
514
|
+
a3: A3,
|
|
515
|
+
a4: A4,
|
|
516
|
+
): Promise<Result<S, E>>;
|
|
517
|
+
span5<S, E, A1, A2, A3, A4, A5>(
|
|
518
|
+
line: number,
|
|
519
|
+
name: string,
|
|
520
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
521
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
522
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
523
|
+
opMetadata: OpMetadata,
|
|
524
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Result<S, E> | Promise<Result<S, E>>,
|
|
525
|
+
a1: A1,
|
|
526
|
+
a2: A2,
|
|
527
|
+
a3: A3,
|
|
528
|
+
a4: A4,
|
|
529
|
+
a5: A5,
|
|
530
|
+
): Promise<Result<S, E>>;
|
|
531
|
+
span6<S, E, A1, A2, A3, A4, A5, A6>(
|
|
532
|
+
line: number,
|
|
533
|
+
name: string,
|
|
534
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
535
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
536
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
537
|
+
opMetadata: OpMetadata,
|
|
538
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => Result<S, E> | Promise<Result<S, E>>,
|
|
539
|
+
a1: A1,
|
|
540
|
+
a2: A2,
|
|
541
|
+
a3: A3,
|
|
542
|
+
a4: A4,
|
|
543
|
+
a5: A5,
|
|
544
|
+
a6: A6,
|
|
545
|
+
): Promise<Result<S, E>>;
|
|
546
|
+
span7<S, E, A1, A2, A3, A4, A5, A6, A7>(
|
|
547
|
+
line: number,
|
|
548
|
+
name: string,
|
|
549
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
550
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
551
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
552
|
+
opMetadata: OpMetadata,
|
|
553
|
+
fn: (
|
|
554
|
+
ctx: SpanContext<Ctx>,
|
|
555
|
+
a1: A1,
|
|
556
|
+
a2: A2,
|
|
557
|
+
a3: A3,
|
|
558
|
+
a4: A4,
|
|
559
|
+
a5: A5,
|
|
560
|
+
a6: A6,
|
|
561
|
+
a7: A7,
|
|
562
|
+
) => Result<S, E> | Promise<Result<S, E>>,
|
|
563
|
+
a1: A1,
|
|
564
|
+
a2: A2,
|
|
565
|
+
a3: A3,
|
|
566
|
+
a4: A4,
|
|
567
|
+
a5: A5,
|
|
568
|
+
a6: A6,
|
|
569
|
+
a7: A7,
|
|
570
|
+
): Promise<Result<S, E>>;
|
|
571
|
+
span8<S, E, A1, A2, A3, A4, A5, A6, A7, A8>(
|
|
572
|
+
line: number,
|
|
573
|
+
name: string,
|
|
574
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
575
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
576
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
577
|
+
opMetadata: OpMetadata,
|
|
578
|
+
fn: (
|
|
579
|
+
ctx: SpanContext<Ctx>,
|
|
580
|
+
a1: A1,
|
|
581
|
+
a2: A2,
|
|
582
|
+
a3: A3,
|
|
583
|
+
a4: A4,
|
|
584
|
+
a5: A5,
|
|
585
|
+
a6: A6,
|
|
586
|
+
a7: A7,
|
|
587
|
+
a8: A8,
|
|
588
|
+
) => Result<S, E, Ctx['logSchema']> | Promise<Result<S, E, Ctx['logSchema']>>,
|
|
589
|
+
a1: A1,
|
|
590
|
+
a2: A2,
|
|
591
|
+
a3: A3,
|
|
592
|
+
a4: A4,
|
|
593
|
+
a5: A5,
|
|
594
|
+
a6: A6,
|
|
595
|
+
a7: A7,
|
|
596
|
+
a8: A8,
|
|
597
|
+
): Promise<Result<S, E, Ctx['logSchema']>>;
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
// =============================================================================
|
|
601
|
+
// SpanContext Class Factory
|
|
602
|
+
// =============================================================================
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Create a SpanContext class for the given schema and logBinding.
|
|
606
|
+
*
|
|
607
|
+
* The returned class:
|
|
608
|
+
* - Closes over schema/logBinding (available to all methods)
|
|
609
|
+
* - Constructor takes buffer, spanLogger, tag directly (no temp object allocation)
|
|
610
|
+
* - Uses prototype methods for internal methods (_spanPre, _spanException, span0-span8)
|
|
611
|
+
* - Supports context inheritance via Object.create(parent) for child spans
|
|
612
|
+
* - Supports context overrides via own properties shadowing inherited ones
|
|
613
|
+
*
|
|
614
|
+
* @param schemaOnly - Tag attribute schema
|
|
615
|
+
* @param logBinding - LogBinding with schema and stats
|
|
616
|
+
* @returns Class constructor for SpanContext instances
|
|
617
|
+
*/
|
|
618
|
+
export function createSpanContextClass<Ctx extends OpContext>(
|
|
619
|
+
_schemaOnly: Ctx['logSchema'],
|
|
620
|
+
logBinding: LogBinding,
|
|
621
|
+
): SpanContextClass<Ctx> {
|
|
622
|
+
/**
|
|
623
|
+
* SpanContext implementation class.
|
|
624
|
+
*
|
|
625
|
+
* Constructor takes core values directly so arrow functions can close over them,
|
|
626
|
+
* avoiding both temp object allocation and property lookups in hot paths.
|
|
627
|
+
*/
|
|
628
|
+
class SpanContextImpl {
|
|
629
|
+
// Core properties set via constructor
|
|
630
|
+
_buffer: SpanBuffer<Ctx['logSchema']>;
|
|
631
|
+
_schema: Ctx['logSchema'];
|
|
632
|
+
_spanLogger: SpanLoggerImpl<Ctx['logSchema']>;
|
|
633
|
+
_logBinding: LogBinding<Ctx['logSchema']> = logBinding;
|
|
634
|
+
|
|
635
|
+
// User-facing properties
|
|
636
|
+
tag: TagWriter<Ctx['logSchema']>;
|
|
637
|
+
log: SpanLogger<Ctx['logSchema']>;
|
|
638
|
+
ff!: FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
|
|
639
|
+
deps!: Record<string, unknown>;
|
|
640
|
+
|
|
641
|
+
// Index signature for user context properties (env, requestId, etc.)
|
|
642
|
+
[key: string]: unknown;
|
|
643
|
+
|
|
644
|
+
// Arrow functions that close over constructor args directly
|
|
645
|
+
setScope: (attributes: ScopeUpdate<Ctx['logSchema']> | null) => void;
|
|
646
|
+
ok: <V>(value: V) => Ok<V, Ctx['logSchema']>;
|
|
647
|
+
err: <E>(error: E) => Err<E, Ctx['logSchema']>;
|
|
648
|
+
span: SpanFn<Ctx>;
|
|
649
|
+
spanSync: SpanSyncFn<Ctx>;
|
|
650
|
+
|
|
651
|
+
constructor(
|
|
652
|
+
buffer: SpanBuffer<Ctx['logSchema']>,
|
|
653
|
+
schema: Ctx['logSchema'],
|
|
654
|
+
spanLogger: SpanLoggerImpl<Ctx['logSchema']>,
|
|
655
|
+
tag: TagWriter<Ctx['logSchema']>,
|
|
656
|
+
) {
|
|
657
|
+
this._buffer = buffer;
|
|
658
|
+
this._schema = schema;
|
|
659
|
+
this._spanLogger = spanLogger;
|
|
660
|
+
this.tag = tag;
|
|
661
|
+
this.log = spanLogger;
|
|
662
|
+
|
|
663
|
+
// Regular functions close over constructor args directly - no property lookups
|
|
664
|
+
// Using regular function (not arrow) allows destructuring while closing over args
|
|
665
|
+
this.setScope = (attributes: ScopeUpdate<Ctx['logSchema']> | null): void => {
|
|
666
|
+
spanLogger._setScope(attributes ?? {});
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
this.ok = <V>(value: V): Ok<V, Ctx['logSchema']> => new Ok<V, Ctx['logSchema']>(value, schema, buffer);
|
|
670
|
+
|
|
671
|
+
this.err = <E>(error: E): Err<E, Ctx['logSchema']> => new Err<E, Ctx['logSchema']>(error, schema, buffer);
|
|
672
|
+
|
|
673
|
+
// span uses regular function to access `arguments` (no ...rest spread allocation)
|
|
674
|
+
// Closes over `self` for calling prototype methods
|
|
675
|
+
// Named function for better stack traces
|
|
676
|
+
const self = this;
|
|
677
|
+
const span: SpanFn<Ctx> = function span(
|
|
678
|
+
nameOrLine: string | number,
|
|
679
|
+
_arg1?: unknown,
|
|
680
|
+
_arg2?: unknown,
|
|
681
|
+
_arg3?: unknown,
|
|
682
|
+
_arg4?: unknown,
|
|
683
|
+
_arg5?: unknown,
|
|
684
|
+
_arg6?: unknown,
|
|
685
|
+
_arg7?: unknown,
|
|
686
|
+
_arg8?: unknown,
|
|
687
|
+
_arg9?: unknown,
|
|
688
|
+
_arg10?: unknown,
|
|
689
|
+
_arg11?: unknown,
|
|
690
|
+
): Promise<Result<unknown, unknown>> {
|
|
691
|
+
// Use arguments.length instead of ...rest to avoid array allocation
|
|
692
|
+
const len = arguments.length;
|
|
693
|
+
|
|
694
|
+
// Detect call pattern:
|
|
695
|
+
// - span(name, fn) - len=2, typeof arg0 === 'string'
|
|
696
|
+
// - span(line, name, fn) - len=3, typeof arg0 === 'number'
|
|
697
|
+
// - span(name, overrides, fn) - len=3, typeof arg0 === 'string', typeof arg1 === 'object'
|
|
698
|
+
// - span(line, name, overrides, fn) - len=4, typeof arg0 === 'number', typeof arg2 === 'object'
|
|
699
|
+
// Plus additional args for span arguments
|
|
700
|
+
|
|
701
|
+
const hasLine = typeof nameOrLine === 'number';
|
|
702
|
+
const spanLine = hasLine ? nameOrLine : 0;
|
|
703
|
+
const spanName = hasLine ? readStringArgument(arguments, 1, 'span name') : nameOrLine;
|
|
704
|
+
|
|
705
|
+
// Index where fn/op or overrides starts
|
|
706
|
+
const checkIdx = hasLine ? 2 : 1;
|
|
707
|
+
const maybeOverrides = arguments[checkIdx];
|
|
708
|
+
|
|
709
|
+
// Check if it's an overrides object (not Op, not function)
|
|
710
|
+
const hasOverrides =
|
|
711
|
+
maybeOverrides !== null &&
|
|
712
|
+
typeof maybeOverrides === 'object' &&
|
|
713
|
+
!(maybeOverrides instanceof Op) &&
|
|
714
|
+
typeof maybeOverrides !== 'function';
|
|
715
|
+
|
|
716
|
+
const fnIdx = checkIdx + (hasOverrides ? 1 : 0);
|
|
717
|
+
const target = resolveSpanTarget<Ctx>(arguments[fnIdx], self._buffer);
|
|
718
|
+
|
|
719
|
+
// Create child context - use _newCtx0 or _newCtx1 based on overrides
|
|
720
|
+
const childCtx = hasOverrides ? self._newCtx1(maybeOverrides) : self._newCtx0();
|
|
721
|
+
|
|
722
|
+
// Dispatch to monomorphic methods with all Op properties extracted
|
|
723
|
+
const argCount = len - fnIdx - 1;
|
|
724
|
+
switch (argCount) {
|
|
725
|
+
case 0:
|
|
726
|
+
return self.span0(
|
|
727
|
+
spanLine,
|
|
728
|
+
spanName,
|
|
729
|
+
childCtx,
|
|
730
|
+
target.SpanBufferClass,
|
|
731
|
+
target.remappedViewClass,
|
|
732
|
+
target.opMetadata,
|
|
733
|
+
target.fn,
|
|
734
|
+
);
|
|
735
|
+
case 1:
|
|
736
|
+
return self.span1(
|
|
737
|
+
spanLine,
|
|
738
|
+
spanName,
|
|
739
|
+
childCtx,
|
|
740
|
+
target.SpanBufferClass,
|
|
741
|
+
target.remappedViewClass,
|
|
742
|
+
target.opMetadata,
|
|
743
|
+
target.fn,
|
|
744
|
+
arguments[fnIdx + 1],
|
|
745
|
+
);
|
|
746
|
+
case 2:
|
|
747
|
+
return self.span2(
|
|
748
|
+
spanLine,
|
|
749
|
+
spanName,
|
|
750
|
+
childCtx,
|
|
751
|
+
target.SpanBufferClass,
|
|
752
|
+
target.remappedViewClass,
|
|
753
|
+
target.opMetadata,
|
|
754
|
+
target.fn,
|
|
755
|
+
arguments[fnIdx + 1],
|
|
756
|
+
arguments[fnIdx + 2],
|
|
757
|
+
);
|
|
758
|
+
case 3:
|
|
759
|
+
return self.span3(
|
|
760
|
+
spanLine,
|
|
761
|
+
spanName,
|
|
762
|
+
childCtx,
|
|
763
|
+
target.SpanBufferClass,
|
|
764
|
+
target.remappedViewClass,
|
|
765
|
+
target.opMetadata,
|
|
766
|
+
target.fn,
|
|
767
|
+
arguments[fnIdx + 1],
|
|
768
|
+
arguments[fnIdx + 2],
|
|
769
|
+
arguments[fnIdx + 3],
|
|
770
|
+
);
|
|
771
|
+
case 4:
|
|
772
|
+
return self.span4(
|
|
773
|
+
spanLine,
|
|
774
|
+
spanName,
|
|
775
|
+
childCtx,
|
|
776
|
+
target.SpanBufferClass,
|
|
777
|
+
target.remappedViewClass,
|
|
778
|
+
target.opMetadata,
|
|
779
|
+
target.fn,
|
|
780
|
+
arguments[fnIdx + 1],
|
|
781
|
+
arguments[fnIdx + 2],
|
|
782
|
+
arguments[fnIdx + 3],
|
|
783
|
+
arguments[fnIdx + 4],
|
|
784
|
+
);
|
|
785
|
+
case 5:
|
|
786
|
+
return self.span5(
|
|
787
|
+
spanLine,
|
|
788
|
+
spanName,
|
|
789
|
+
childCtx,
|
|
790
|
+
target.SpanBufferClass,
|
|
791
|
+
target.remappedViewClass,
|
|
792
|
+
target.opMetadata,
|
|
793
|
+
target.fn,
|
|
794
|
+
arguments[fnIdx + 1],
|
|
795
|
+
arguments[fnIdx + 2],
|
|
796
|
+
arguments[fnIdx + 3],
|
|
797
|
+
arguments[fnIdx + 4],
|
|
798
|
+
arguments[fnIdx + 5],
|
|
799
|
+
);
|
|
800
|
+
case 6:
|
|
801
|
+
return self.span6(
|
|
802
|
+
spanLine,
|
|
803
|
+
spanName,
|
|
804
|
+
childCtx,
|
|
805
|
+
target.SpanBufferClass,
|
|
806
|
+
target.remappedViewClass,
|
|
807
|
+
target.opMetadata,
|
|
808
|
+
target.fn,
|
|
809
|
+
arguments[fnIdx + 1],
|
|
810
|
+
arguments[fnIdx + 2],
|
|
811
|
+
arguments[fnIdx + 3],
|
|
812
|
+
arguments[fnIdx + 4],
|
|
813
|
+
arguments[fnIdx + 5],
|
|
814
|
+
arguments[fnIdx + 6],
|
|
815
|
+
);
|
|
816
|
+
case 7:
|
|
817
|
+
return self.span7(
|
|
818
|
+
spanLine,
|
|
819
|
+
spanName,
|
|
820
|
+
childCtx,
|
|
821
|
+
target.SpanBufferClass,
|
|
822
|
+
target.remappedViewClass,
|
|
823
|
+
target.opMetadata,
|
|
824
|
+
target.fn,
|
|
825
|
+
arguments[fnIdx + 1],
|
|
826
|
+
arguments[fnIdx + 2],
|
|
827
|
+
arguments[fnIdx + 3],
|
|
828
|
+
arguments[fnIdx + 4],
|
|
829
|
+
arguments[fnIdx + 5],
|
|
830
|
+
arguments[fnIdx + 6],
|
|
831
|
+
arguments[fnIdx + 7],
|
|
832
|
+
);
|
|
833
|
+
case 8:
|
|
834
|
+
return self.span8(
|
|
835
|
+
spanLine,
|
|
836
|
+
spanName,
|
|
837
|
+
childCtx,
|
|
838
|
+
target.SpanBufferClass,
|
|
839
|
+
target.remappedViewClass,
|
|
840
|
+
target.opMetadata,
|
|
841
|
+
target.fn,
|
|
842
|
+
arguments[fnIdx + 1],
|
|
843
|
+
arguments[fnIdx + 2],
|
|
844
|
+
arguments[fnIdx + 3],
|
|
845
|
+
arguments[fnIdx + 4],
|
|
846
|
+
arguments[fnIdx + 5],
|
|
847
|
+
arguments[fnIdx + 6],
|
|
848
|
+
arguments[fnIdx + 7],
|
|
849
|
+
arguments[fnIdx + 8],
|
|
850
|
+
);
|
|
851
|
+
default:
|
|
852
|
+
throw new Error(`span() supports up to 8 arguments, got ${argCount}`);
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
this.span = span;
|
|
856
|
+
|
|
857
|
+
this.spanSync = function spanSync<S, E>(name: string, fn: (ctx: SpanContext<Ctx>) => Result<S, E>): Result<S, E> {
|
|
858
|
+
const childCtx = self._newCtx0();
|
|
859
|
+
return self.spanSync0(
|
|
860
|
+
0,
|
|
861
|
+
name,
|
|
862
|
+
childCtx,
|
|
863
|
+
getBufferConstructor(self._buffer),
|
|
864
|
+
undefined,
|
|
865
|
+
self._buffer._opMetadata,
|
|
866
|
+
fn,
|
|
867
|
+
);
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// =========================================================================
|
|
872
|
+
// Getters (on prototype, inherited by children)
|
|
873
|
+
// =========================================================================
|
|
874
|
+
|
|
875
|
+
get [SPAN_CONTEXT_MARKER](): true {
|
|
876
|
+
return true;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
get module(): import('./opContext/opTypes.js').OpMetadata {
|
|
880
|
+
return this._buffer._opMetadata;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
get callee_package(): string {
|
|
884
|
+
return this._buffer._opMetadata.package_name;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
get callee_file(): string {
|
|
888
|
+
return this._buffer._opMetadata.package_file;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
get callee_line(): number {
|
|
892
|
+
// Access the line_values array directly to read line number at row 0
|
|
893
|
+
// line_values is a Float64Array per the system schema (LazyNumberSchema)
|
|
894
|
+
return this._buffer.line_values[0];
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
get callee_git_sha(): string {
|
|
898
|
+
return this._buffer._opMetadata.git_sha;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
get buffer(): SpanBuffer<Ctx['logSchema']> {
|
|
902
|
+
return this._buffer;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
get scope(): Readonly<Partial<InferSchema<Ctx['logSchema']>>> {
|
|
906
|
+
return this._buffer._scopeValues;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// =========================================================================
|
|
910
|
+
// Internal methods (on prototype)
|
|
911
|
+
// =========================================================================
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Create a new child context with prototype chain inheritance.
|
|
915
|
+
* Called by transformer for spans without overrides.
|
|
916
|
+
*
|
|
917
|
+
* Transformer emits: ctx.span0(line, name, ctx._newCtx0(), fn)
|
|
918
|
+
*/
|
|
919
|
+
_newCtx0(): SpanContextInstance<Ctx> {
|
|
920
|
+
return createInheritedContext(this);
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/**
|
|
924
|
+
* Create a new child context with prototype chain inheritance + user overrides.
|
|
925
|
+
* Called by transformer for spans with overrides.
|
|
926
|
+
*
|
|
927
|
+
* Transformer emits: ctx.span0(line, name, ctx._newCtx1({ requestId }), fn)
|
|
928
|
+
*/
|
|
929
|
+
_newCtx1(overrides: object): SpanContextInstance<Ctx> {
|
|
930
|
+
return createInheritedContextWithOverrides(this, overrides);
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Complete child span context setup - creates buffer, registers with parent.
|
|
935
|
+
* Called by span0-span8 after _newCtx0/_newCtx1 has created the prototype chain.
|
|
936
|
+
*
|
|
937
|
+
* Properties are set in HOT→COLD order per specs/lmao/01b1_buffer_performance_optimizations.md
|
|
938
|
+
* to ensure frequently-accessed properties get V8 in-object slots.
|
|
939
|
+
*
|
|
940
|
+
* @param childCtx - Child context created by _newCtx0 or _newCtx1
|
|
941
|
+
* @param line - Source line number (0 if not provided by transformer)
|
|
942
|
+
* @param name - Child span name
|
|
943
|
+
* @param SpanBufferClass - Buffer class to use (Op's class or parent's class for plain functions)
|
|
944
|
+
* @param remappedViewClass - Optional view class for prefixed ops (wraps buffer for Arrow conversion)
|
|
945
|
+
* @param opMetadata - Metadata for the executing op (Op's metadata or parent's for plain functions)
|
|
946
|
+
*/
|
|
947
|
+
_spanPre(
|
|
948
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
949
|
+
line: number,
|
|
950
|
+
name: string,
|
|
951
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
952
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
953
|
+
opMetadata: OpMetadata,
|
|
954
|
+
): SpanContextInstance<Ctx> {
|
|
955
|
+
// Get Op's schema for cross-library calls (child may have different schema than parent)
|
|
956
|
+
const childSchema = SpanBufferClass.schema;
|
|
957
|
+
|
|
958
|
+
// Use buffer strategy for child span creation (supports both JS and WASM buffers)
|
|
959
|
+
// Pass schema for cross-library calls where child has different schema than parent
|
|
960
|
+
const createdBuffer = this._buffer._traceRoot.tracer.bufferStrategy.createChildSpanBuffer(
|
|
961
|
+
this._buffer, // parentBuffer
|
|
962
|
+
this._buffer._opMetadata, // callsiteMetadata - WHO called span() (for row 0)
|
|
963
|
+
opMetadata, // opMetadata - WHICH op is executing (for rows 1+)
|
|
964
|
+
undefined, // capacity - use default
|
|
965
|
+
childSchema, // schema - Op's schema for correct tag methods
|
|
966
|
+
);
|
|
967
|
+
if (!isSpanBufferForSchema(createdBuffer, childSchema)) {
|
|
968
|
+
throw new TypeError('Child span buffer does not match the requested schema');
|
|
969
|
+
}
|
|
970
|
+
const childBuffer = createdBuffer;
|
|
971
|
+
|
|
972
|
+
// Why wrap buffer: RemappedBufferView translates prefixed column names during Arrow conversion
|
|
973
|
+
// Parent sees remapped names, child sees unprefixed names (transparent to child)
|
|
974
|
+
const bufferOrView = remappedViewClass ? new remappedViewClass(childBuffer) : childBuffer;
|
|
975
|
+
|
|
976
|
+
// Why push wrapped buffer: Parent's _children see remapped names for Arrow conversion
|
|
977
|
+
this._buffer._children.push(bufferOrView);
|
|
978
|
+
|
|
979
|
+
// Write span-start for child span (row 0) and pre-initialize span-end (row 1)
|
|
980
|
+
writeSpanStart(childBuffer, name);
|
|
981
|
+
|
|
982
|
+
// Write line number to row 0 (line() takes pos and value)
|
|
983
|
+
childBuffer.line(0, line);
|
|
984
|
+
const childLogger = createSpanLogger(childSchema, childBuffer);
|
|
985
|
+
const childTagAPI = createTagWriter(childSchema, childBuffer);
|
|
986
|
+
|
|
987
|
+
// Cast to impl for property assignment
|
|
988
|
+
const ctx = childCtx;
|
|
989
|
+
|
|
990
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
991
|
+
// PROPERTY ASSIGNMENT ORDER: HOT → COLD (V8 in-object slots optimization)
|
|
992
|
+
// First ~10-12 properties get fast in-object slots per spec
|
|
993
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
994
|
+
|
|
995
|
+
// SLOT 1-4: HOTTEST - accessed on every span operation
|
|
996
|
+
ctx._buffer = childBuffer;
|
|
997
|
+
ctx._spanLogger = childLogger;
|
|
998
|
+
ctx.tag = childTagAPI;
|
|
999
|
+
ctx.log = childLogger;
|
|
1000
|
+
|
|
1001
|
+
// SLOT 5-7: HOT - reserved keys copied from parent for O(1) access
|
|
1002
|
+
ctx.deps = this.deps;
|
|
1003
|
+
// Create child-bound FF evaluator so flag access logs to child buffer
|
|
1004
|
+
// If no evaluator (ff is EMPTY_SCOPE), just copy the reference
|
|
1005
|
+
ctx.ff = this.ff.forContext ? this.ff.forContext(ctx) : this.ff;
|
|
1006
|
+
// Note: user-defined extras (env, requestId, etc.) inherited via prototype chain
|
|
1007
|
+
|
|
1008
|
+
// SLOT 8-11: WARM - function properties (created per-context for destructuring)
|
|
1009
|
+
// Regular functions close over local variables directly - no property lookups
|
|
1010
|
+
const childSpan: SpanFn<Ctx> = function span(
|
|
1011
|
+
nameOrLine: string | number,
|
|
1012
|
+
_arg1?: unknown,
|
|
1013
|
+
_arg2?: unknown,
|
|
1014
|
+
_arg3?: unknown,
|
|
1015
|
+
_arg4?: unknown,
|
|
1016
|
+
_arg5?: unknown,
|
|
1017
|
+
_arg6?: unknown,
|
|
1018
|
+
_arg7?: unknown,
|
|
1019
|
+
_arg8?: unknown,
|
|
1020
|
+
_arg9?: unknown,
|
|
1021
|
+
_arg10?: unknown,
|
|
1022
|
+
_arg11?: unknown,
|
|
1023
|
+
): Promise<Result<unknown, unknown>> {
|
|
1024
|
+
const len = arguments.length;
|
|
1025
|
+
const hasLine = typeof nameOrLine === 'number';
|
|
1026
|
+
const spanLine = hasLine ? nameOrLine : 0;
|
|
1027
|
+
const spanName = hasLine ? readStringArgument(arguments, 1, 'span name') : nameOrLine;
|
|
1028
|
+
const checkIdx = hasLine ? 2 : 1;
|
|
1029
|
+
const maybeOverrides = arguments[checkIdx];
|
|
1030
|
+
const hasOverrides =
|
|
1031
|
+
maybeOverrides !== null &&
|
|
1032
|
+
typeof maybeOverrides === 'object' &&
|
|
1033
|
+
!(maybeOverrides instanceof Op) &&
|
|
1034
|
+
typeof maybeOverrides !== 'function';
|
|
1035
|
+
const fnIdx = checkIdx + (hasOverrides ? 1 : 0);
|
|
1036
|
+
const target = resolveSpanTarget<Ctx>(arguments[fnIdx], childBuffer);
|
|
1037
|
+
|
|
1038
|
+
// Create child context - use _newCtx0 or _newCtx1 based on overrides
|
|
1039
|
+
const newChildCtx = hasOverrides ? ctx._newCtx1(maybeOverrides) : ctx._newCtx0();
|
|
1040
|
+
const argCount = len - fnIdx - 1;
|
|
1041
|
+
switch (argCount) {
|
|
1042
|
+
case 0:
|
|
1043
|
+
return ctx.span0(
|
|
1044
|
+
spanLine,
|
|
1045
|
+
spanName,
|
|
1046
|
+
newChildCtx,
|
|
1047
|
+
target.SpanBufferClass,
|
|
1048
|
+
target.remappedViewClass,
|
|
1049
|
+
target.opMetadata,
|
|
1050
|
+
target.fn,
|
|
1051
|
+
);
|
|
1052
|
+
case 1:
|
|
1053
|
+
return ctx.span1(
|
|
1054
|
+
spanLine,
|
|
1055
|
+
spanName,
|
|
1056
|
+
newChildCtx,
|
|
1057
|
+
target.SpanBufferClass,
|
|
1058
|
+
target.remappedViewClass,
|
|
1059
|
+
target.opMetadata,
|
|
1060
|
+
target.fn,
|
|
1061
|
+
arguments[fnIdx + 1],
|
|
1062
|
+
);
|
|
1063
|
+
case 2:
|
|
1064
|
+
return ctx.span2(
|
|
1065
|
+
spanLine,
|
|
1066
|
+
spanName,
|
|
1067
|
+
newChildCtx,
|
|
1068
|
+
target.SpanBufferClass,
|
|
1069
|
+
target.remappedViewClass,
|
|
1070
|
+
target.opMetadata,
|
|
1071
|
+
target.fn,
|
|
1072
|
+
arguments[fnIdx + 1],
|
|
1073
|
+
arguments[fnIdx + 2],
|
|
1074
|
+
);
|
|
1075
|
+
case 3:
|
|
1076
|
+
return ctx.span3(
|
|
1077
|
+
spanLine,
|
|
1078
|
+
spanName,
|
|
1079
|
+
newChildCtx,
|
|
1080
|
+
target.SpanBufferClass,
|
|
1081
|
+
target.remappedViewClass,
|
|
1082
|
+
target.opMetadata,
|
|
1083
|
+
target.fn,
|
|
1084
|
+
arguments[fnIdx + 1],
|
|
1085
|
+
arguments[fnIdx + 2],
|
|
1086
|
+
arguments[fnIdx + 3],
|
|
1087
|
+
);
|
|
1088
|
+
case 4:
|
|
1089
|
+
return ctx.span4(
|
|
1090
|
+
spanLine,
|
|
1091
|
+
spanName,
|
|
1092
|
+
newChildCtx,
|
|
1093
|
+
target.SpanBufferClass,
|
|
1094
|
+
target.remappedViewClass,
|
|
1095
|
+
target.opMetadata,
|
|
1096
|
+
target.fn,
|
|
1097
|
+
arguments[fnIdx + 1],
|
|
1098
|
+
arguments[fnIdx + 2],
|
|
1099
|
+
arguments[fnIdx + 3],
|
|
1100
|
+
arguments[fnIdx + 4],
|
|
1101
|
+
);
|
|
1102
|
+
case 5:
|
|
1103
|
+
return ctx.span5(
|
|
1104
|
+
spanLine,
|
|
1105
|
+
spanName,
|
|
1106
|
+
newChildCtx,
|
|
1107
|
+
target.SpanBufferClass,
|
|
1108
|
+
target.remappedViewClass,
|
|
1109
|
+
target.opMetadata,
|
|
1110
|
+
target.fn,
|
|
1111
|
+
arguments[fnIdx + 1],
|
|
1112
|
+
arguments[fnIdx + 2],
|
|
1113
|
+
arguments[fnIdx + 3],
|
|
1114
|
+
arguments[fnIdx + 4],
|
|
1115
|
+
arguments[fnIdx + 5],
|
|
1116
|
+
);
|
|
1117
|
+
case 6:
|
|
1118
|
+
return ctx.span6(
|
|
1119
|
+
spanLine,
|
|
1120
|
+
spanName,
|
|
1121
|
+
newChildCtx,
|
|
1122
|
+
target.SpanBufferClass,
|
|
1123
|
+
target.remappedViewClass,
|
|
1124
|
+
target.opMetadata,
|
|
1125
|
+
target.fn,
|
|
1126
|
+
arguments[fnIdx + 1],
|
|
1127
|
+
arguments[fnIdx + 2],
|
|
1128
|
+
arguments[fnIdx + 3],
|
|
1129
|
+
arguments[fnIdx + 4],
|
|
1130
|
+
arguments[fnIdx + 5],
|
|
1131
|
+
arguments[fnIdx + 6],
|
|
1132
|
+
);
|
|
1133
|
+
case 7:
|
|
1134
|
+
return ctx.span7(
|
|
1135
|
+
spanLine,
|
|
1136
|
+
spanName,
|
|
1137
|
+
newChildCtx,
|
|
1138
|
+
target.SpanBufferClass,
|
|
1139
|
+
target.remappedViewClass,
|
|
1140
|
+
target.opMetadata,
|
|
1141
|
+
target.fn,
|
|
1142
|
+
arguments[fnIdx + 1],
|
|
1143
|
+
arguments[fnIdx + 2],
|
|
1144
|
+
arguments[fnIdx + 3],
|
|
1145
|
+
arguments[fnIdx + 4],
|
|
1146
|
+
arguments[fnIdx + 5],
|
|
1147
|
+
arguments[fnIdx + 6],
|
|
1148
|
+
arguments[fnIdx + 7],
|
|
1149
|
+
);
|
|
1150
|
+
case 8:
|
|
1151
|
+
return ctx.span8(
|
|
1152
|
+
spanLine,
|
|
1153
|
+
spanName,
|
|
1154
|
+
newChildCtx,
|
|
1155
|
+
target.SpanBufferClass,
|
|
1156
|
+
target.remappedViewClass,
|
|
1157
|
+
target.opMetadata,
|
|
1158
|
+
target.fn,
|
|
1159
|
+
arguments[fnIdx + 1],
|
|
1160
|
+
arguments[fnIdx + 2],
|
|
1161
|
+
arguments[fnIdx + 3],
|
|
1162
|
+
arguments[fnIdx + 4],
|
|
1163
|
+
arguments[fnIdx + 5],
|
|
1164
|
+
arguments[fnIdx + 6],
|
|
1165
|
+
arguments[fnIdx + 7],
|
|
1166
|
+
arguments[fnIdx + 8],
|
|
1167
|
+
);
|
|
1168
|
+
default:
|
|
1169
|
+
throw new Error(`span() supports up to 8 arguments, got ${argCount}`);
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
ctx.span = childSpan;
|
|
1173
|
+
|
|
1174
|
+
ctx.spanSync = function spanSync<S, E>(
|
|
1175
|
+
name: string,
|
|
1176
|
+
fn: (syncCtx: SpanContext<Ctx>) => Result<S, E>,
|
|
1177
|
+
): Result<S, E> {
|
|
1178
|
+
const newChildCtx = ctx._newCtx0();
|
|
1179
|
+
return ctx.spanSync0(
|
|
1180
|
+
0,
|
|
1181
|
+
name,
|
|
1182
|
+
newChildCtx,
|
|
1183
|
+
getBufferConstructor(childBuffer),
|
|
1184
|
+
undefined,
|
|
1185
|
+
childBuffer._opMetadata,
|
|
1186
|
+
fn,
|
|
1187
|
+
);
|
|
1188
|
+
};
|
|
1189
|
+
|
|
1190
|
+
ctx.ok = function ok<V>(value: V): Ok<V, Ctx['logSchema']> {
|
|
1191
|
+
return new Ok<V, Ctx['logSchema']>(value, childSchema, childBuffer);
|
|
1192
|
+
};
|
|
1193
|
+
ctx.err = function err<E>(error: E): Err<E, Ctx['logSchema']> {
|
|
1194
|
+
return new Err<E, Ctx['logSchema']>(error, childSchema, childBuffer);
|
|
1195
|
+
};
|
|
1196
|
+
ctx.setScope = function setScope(attributes: ScopeUpdate<Ctx['logSchema']> | null): void {
|
|
1197
|
+
childLogger._setScope(attributes ?? {});
|
|
1198
|
+
};
|
|
1199
|
+
|
|
1200
|
+
// SLOT 12+: COLD - internal/rarely accessed
|
|
1201
|
+
ctx._schema = childSchema;
|
|
1202
|
+
ctx._logBinding = logBinding;
|
|
1203
|
+
|
|
1204
|
+
return ctx;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* Handle span exception - writes exception details to row 1.
|
|
1209
|
+
* Called in catch blocks of span methods.
|
|
1210
|
+
*/
|
|
1211
|
+
_spanException(childBuffer: SpanBuffer<Ctx['logSchema']>, error: unknown): void {
|
|
1212
|
+
// Write entry_type and timestamp via TraceRoot (platform-specific)
|
|
1213
|
+
childBuffer._traceRoot.writeSpanEnd(childBuffer, ENTRY_TYPE_SPAN_EXCEPTION);
|
|
1214
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1215
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
1216
|
+
childBuffer.message(1, errorMessage);
|
|
1217
|
+
if (errorStack) {
|
|
1218
|
+
childBuffer.exception_stack(1, errorStack);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
// =========================================================================
|
|
1223
|
+
// Monomorphic span methods (for transformer output)
|
|
1224
|
+
// Transformer emits: ctx.span0(line, name, ctx, fn) or
|
|
1225
|
+
// ctx.span0(line, name, Object.assign(Object.create(ctx), overrides), fn)
|
|
1226
|
+
// childCtx inherits from parent via prototype chain, may have user overrides as own properties
|
|
1227
|
+
// =========================================================================
|
|
1228
|
+
|
|
1229
|
+
spanSync0<S, E>(
|
|
1230
|
+
line: number,
|
|
1231
|
+
name: string,
|
|
1232
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1233
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1234
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1235
|
+
opMetadata: OpMetadata,
|
|
1236
|
+
fn: (ctx: SpanContext<Ctx>) => Result<S, E>,
|
|
1237
|
+
): Result<S, E> {
|
|
1238
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1239
|
+
const buffer = ctx._buffer;
|
|
1240
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1241
|
+
try {
|
|
1242
|
+
const result = fn(ctx);
|
|
1243
|
+
writeSpanEnd(buffer, result);
|
|
1244
|
+
return result;
|
|
1245
|
+
} catch (error) {
|
|
1246
|
+
this._spanException(buffer, error);
|
|
1247
|
+
throw error;
|
|
1248
|
+
} finally {
|
|
1249
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
async span0<S, E>(
|
|
1254
|
+
line: number,
|
|
1255
|
+
name: string,
|
|
1256
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1257
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1258
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1259
|
+
opMetadata: OpMetadata,
|
|
1260
|
+
fn: (ctx: SpanContext<Ctx>) => Result<S, E> | Promise<Result<S, E>>,
|
|
1261
|
+
): Promise<Result<S, E>> {
|
|
1262
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1263
|
+
const buffer = ctx._buffer;
|
|
1264
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1265
|
+
try {
|
|
1266
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1267
|
+
const result = await executeWithRetry(buffer, () => fn(ctx));
|
|
1268
|
+
writeSpanEnd(buffer, result);
|
|
1269
|
+
return result;
|
|
1270
|
+
} catch (error) {
|
|
1271
|
+
this._spanException(buffer, error);
|
|
1272
|
+
throw error;
|
|
1273
|
+
} finally {
|
|
1274
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
async span1<S, E, A1>(
|
|
1279
|
+
line: number,
|
|
1280
|
+
name: string,
|
|
1281
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1282
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1283
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1284
|
+
opMetadata: OpMetadata,
|
|
1285
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1) => Result<S, E> | Promise<Result<S, E>>,
|
|
1286
|
+
a1: A1,
|
|
1287
|
+
): Promise<Result<S, E>> {
|
|
1288
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1289
|
+
const buffer = ctx._buffer;
|
|
1290
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1291
|
+
try {
|
|
1292
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1293
|
+
const result = await executeWithRetry(buffer, () => fn(ctx, a1));
|
|
1294
|
+
writeSpanEnd(buffer, result);
|
|
1295
|
+
return result;
|
|
1296
|
+
} catch (error) {
|
|
1297
|
+
this._spanException(buffer, error);
|
|
1298
|
+
throw error;
|
|
1299
|
+
} finally {
|
|
1300
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
async span2<S, E, A1, A2>(
|
|
1305
|
+
line: number,
|
|
1306
|
+
name: string,
|
|
1307
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1308
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1309
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1310
|
+
opMetadata: OpMetadata,
|
|
1311
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2) => Result<S, E> | Promise<Result<S, E>>,
|
|
1312
|
+
a1: A1,
|
|
1313
|
+
a2: A2,
|
|
1314
|
+
): Promise<Result<S, E>> {
|
|
1315
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1316
|
+
const buffer = ctx._buffer;
|
|
1317
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1318
|
+
try {
|
|
1319
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1320
|
+
const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2));
|
|
1321
|
+
writeSpanEnd(buffer, result);
|
|
1322
|
+
return result;
|
|
1323
|
+
} catch (error) {
|
|
1324
|
+
this._spanException(buffer, error);
|
|
1325
|
+
throw error;
|
|
1326
|
+
} finally {
|
|
1327
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
async span3<S, E, A1, A2, A3>(
|
|
1332
|
+
line: number,
|
|
1333
|
+
name: string,
|
|
1334
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1335
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1336
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1337
|
+
opMetadata: OpMetadata,
|
|
1338
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3) => Result<S, E> | Promise<Result<S, E>>,
|
|
1339
|
+
a1: A1,
|
|
1340
|
+
a2: A2,
|
|
1341
|
+
a3: A3,
|
|
1342
|
+
): Promise<Result<S, E>> {
|
|
1343
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1344
|
+
const buffer = ctx._buffer;
|
|
1345
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1346
|
+
try {
|
|
1347
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1348
|
+
const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3));
|
|
1349
|
+
writeSpanEnd(buffer, result);
|
|
1350
|
+
return result;
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
this._spanException(buffer, error);
|
|
1353
|
+
throw error;
|
|
1354
|
+
} finally {
|
|
1355
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
async span4<S, E, A1, A2, A3, A4>(
|
|
1360
|
+
line: number,
|
|
1361
|
+
name: string,
|
|
1362
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1363
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1364
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1365
|
+
opMetadata: OpMetadata,
|
|
1366
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4) => Result<S, E> | Promise<Result<S, E>>,
|
|
1367
|
+
a1: A1,
|
|
1368
|
+
a2: A2,
|
|
1369
|
+
a3: A3,
|
|
1370
|
+
a4: A4,
|
|
1371
|
+
): Promise<Result<S, E>> {
|
|
1372
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1373
|
+
const buffer = ctx._buffer;
|
|
1374
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1375
|
+
try {
|
|
1376
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1377
|
+
const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4));
|
|
1378
|
+
writeSpanEnd(buffer, result);
|
|
1379
|
+
return result;
|
|
1380
|
+
} catch (error) {
|
|
1381
|
+
this._spanException(buffer, error);
|
|
1382
|
+
throw error;
|
|
1383
|
+
} finally {
|
|
1384
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
async span5<S, E, A1, A2, A3, A4, A5>(
|
|
1389
|
+
line: number,
|
|
1390
|
+
name: string,
|
|
1391
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1392
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1393
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1394
|
+
opMetadata: OpMetadata,
|
|
1395
|
+
fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Result<S, E> | Promise<Result<S, E>>,
|
|
1396
|
+
a1: A1,
|
|
1397
|
+
a2: A2,
|
|
1398
|
+
a3: A3,
|
|
1399
|
+
a4: A4,
|
|
1400
|
+
a5: A5,
|
|
1401
|
+
): Promise<Result<S, E>> {
|
|
1402
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1403
|
+
const buffer = ctx._buffer;
|
|
1404
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1405
|
+
try {
|
|
1406
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1407
|
+
const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4, a5));
|
|
1408
|
+
writeSpanEnd(buffer, result);
|
|
1409
|
+
return result;
|
|
1410
|
+
} catch (error) {
|
|
1411
|
+
this._spanException(buffer, error);
|
|
1412
|
+
throw error;
|
|
1413
|
+
} finally {
|
|
1414
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
async span6<S, E, A1, A2, A3, A4, A5, A6>(
|
|
1419
|
+
line: number,
|
|
1420
|
+
name: string,
|
|
1421
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1422
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1423
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1424
|
+
opMetadata: OpMetadata,
|
|
1425
|
+
fn: (
|
|
1426
|
+
ctx: SpanContext<Ctx>,
|
|
1427
|
+
a1: A1,
|
|
1428
|
+
a2: A2,
|
|
1429
|
+
a3: A3,
|
|
1430
|
+
a4: A4,
|
|
1431
|
+
a5: A5,
|
|
1432
|
+
a6: A6,
|
|
1433
|
+
) => Result<S, E> | Promise<Result<S, E>>,
|
|
1434
|
+
a1: A1,
|
|
1435
|
+
a2: A2,
|
|
1436
|
+
a3: A3,
|
|
1437
|
+
a4: A4,
|
|
1438
|
+
a5: A5,
|
|
1439
|
+
a6: A6,
|
|
1440
|
+
): Promise<Result<S, E>> {
|
|
1441
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1442
|
+
const buffer = ctx._buffer;
|
|
1443
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1444
|
+
try {
|
|
1445
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1446
|
+
const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4, a5, a6));
|
|
1447
|
+
writeSpanEnd(buffer, result);
|
|
1448
|
+
return result;
|
|
1449
|
+
} catch (error) {
|
|
1450
|
+
this._spanException(buffer, error);
|
|
1451
|
+
throw error;
|
|
1452
|
+
} finally {
|
|
1453
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
async span7<S, E, A1, A2, A3, A4, A5, A6, A7>(
|
|
1458
|
+
line: number,
|
|
1459
|
+
name: string,
|
|
1460
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1461
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1462
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1463
|
+
opMetadata: OpMetadata,
|
|
1464
|
+
fn: (
|
|
1465
|
+
ctx: SpanContext<Ctx>,
|
|
1466
|
+
a1: A1,
|
|
1467
|
+
a2: A2,
|
|
1468
|
+
a3: A3,
|
|
1469
|
+
a4: A4,
|
|
1470
|
+
a5: A5,
|
|
1471
|
+
a6: A6,
|
|
1472
|
+
a7: A7,
|
|
1473
|
+
) => Result<S, E> | Promise<Result<S, E>>,
|
|
1474
|
+
a1: A1,
|
|
1475
|
+
a2: A2,
|
|
1476
|
+
a3: A3,
|
|
1477
|
+
a4: A4,
|
|
1478
|
+
a5: A5,
|
|
1479
|
+
a6: A6,
|
|
1480
|
+
a7: A7,
|
|
1481
|
+
): Promise<Result<S, E>> {
|
|
1482
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1483
|
+
const buffer = ctx._buffer;
|
|
1484
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1485
|
+
try {
|
|
1486
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1487
|
+
const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4, a5, a6, a7));
|
|
1488
|
+
writeSpanEnd(buffer, result);
|
|
1489
|
+
return result;
|
|
1490
|
+
} catch (error) {
|
|
1491
|
+
this._spanException(buffer, error);
|
|
1492
|
+
throw error;
|
|
1493
|
+
} finally {
|
|
1494
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
async span8<S, E, A1, A2, A3, A4, A5, A6, A7, A8>(
|
|
1499
|
+
line: number,
|
|
1500
|
+
name: string,
|
|
1501
|
+
childCtx: SpanContextInstance<Ctx>,
|
|
1502
|
+
SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
|
|
1503
|
+
remappedViewClass: RemappedViewConstructor | undefined,
|
|
1504
|
+
opMetadata: OpMetadata,
|
|
1505
|
+
fn: (
|
|
1506
|
+
ctx: SpanContext<Ctx>,
|
|
1507
|
+
a1: A1,
|
|
1508
|
+
a2: A2,
|
|
1509
|
+
a3: A3,
|
|
1510
|
+
a4: A4,
|
|
1511
|
+
a5: A5,
|
|
1512
|
+
a6: A6,
|
|
1513
|
+
a7: A7,
|
|
1514
|
+
a8: A8,
|
|
1515
|
+
) => Result<S, E, Ctx['logSchema']> | Promise<Result<S, E, Ctx['logSchema']>>,
|
|
1516
|
+
a1: A1,
|
|
1517
|
+
a2: A2,
|
|
1518
|
+
a3: A3,
|
|
1519
|
+
a4: A4,
|
|
1520
|
+
a5: A5,
|
|
1521
|
+
a6: A6,
|
|
1522
|
+
a7: A7,
|
|
1523
|
+
a8: A8,
|
|
1524
|
+
): Promise<Result<S, E, Ctx['logSchema']>> {
|
|
1525
|
+
const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
|
|
1526
|
+
const buffer = ctx._buffer;
|
|
1527
|
+
buffer._traceRoot.tracer.onSpanStart(buffer);
|
|
1528
|
+
try {
|
|
1529
|
+
// Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
|
|
1530
|
+
const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4, a5, a6, a7, a8));
|
|
1531
|
+
writeSpanEnd(buffer, result);
|
|
1532
|
+
return result;
|
|
1533
|
+
} catch (error) {
|
|
1534
|
+
this._spanException(buffer, error);
|
|
1535
|
+
throw error;
|
|
1536
|
+
} finally {
|
|
1537
|
+
buffer._traceRoot.tracer.onSpanEnd(buffer);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
const SpanContextCtor: SpanContextClass<Ctx> = SpanContextImpl;
|
|
1543
|
+
return SpanContextCtor;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
// =============================================================================
|
|
1547
|
+
// Type Guard
|
|
1548
|
+
// =============================================================================
|
|
1549
|
+
|
|
1550
|
+
/**
|
|
1551
|
+
* Type guard to check if a value is a SpanContext
|
|
1552
|
+
*/
|
|
1553
|
+
export function isSpanContext<Ctx extends OpContext>(value: unknown): value is SpanContext<Ctx> {
|
|
1554
|
+
return (
|
|
1555
|
+
typeof value === 'object' &&
|
|
1556
|
+
value !== null &&
|
|
1557
|
+
SPAN_CONTEXT_MARKER in value &&
|
|
1558
|
+
Reflect.get(value, SPAN_CONTEXT_MARKER) === true
|
|
1559
|
+
);
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
// =============================================================================
|
|
1563
|
+
// Re-export public types from opContext/types
|
|
1564
|
+
// =============================================================================
|
|
1565
|
+
|
|
1566
|
+
export type { FluentLogEntry, SpanContext, SpanFn, SpanLogger } from './opContext/types.js';
|