@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,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Op-Centric API for LMAO - Main Entry Point
|
|
3
|
+
*
|
|
4
|
+
* This is the factory function that creates the Op-centric API.
|
|
5
|
+
* All types are exported from './opContext/index.js'
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { defineOpContext, S, defineLogSchema } from '@smoothbricks/lmao';
|
|
10
|
+
*
|
|
11
|
+
* const { defineOp, defineOps } = defineOpContext({
|
|
12
|
+
* logSchema: defineLogSchema({ userId: S.category() }),
|
|
13
|
+
* ctx: { env: null as Env },
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* export const myHandler = defineOp('handler', async (ctx, req: Request) => {
|
|
17
|
+
* ctx.tag.userId('user-123');
|
|
18
|
+
* return ctx.ok({ status: 'ok' });
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import {
|
|
24
|
+
type AnyOpGroup,
|
|
25
|
+
type AnyOpGroupPublic,
|
|
26
|
+
createDefineOp,
|
|
27
|
+
createDefineOps,
|
|
28
|
+
createOpGroup,
|
|
29
|
+
type DepsConfig,
|
|
30
|
+
type EffectiveSchema,
|
|
31
|
+
type FeatureFlagSchema,
|
|
32
|
+
isMappedOpGroup,
|
|
33
|
+
type OpContext,
|
|
34
|
+
type OpContextConfig,
|
|
35
|
+
type OpContextFactory,
|
|
36
|
+
RESERVED_CONTEXT_PROPS,
|
|
37
|
+
type ValidateUserContext,
|
|
38
|
+
} from './opContext/index.js';
|
|
39
|
+
import { LogSchema } from './schema/LogSchema.js';
|
|
40
|
+
import { mergeWithSystemSchema, SYSTEM_SCHEMA_FIELD_NAMES } from './schema/systemSchema.js';
|
|
41
|
+
import type { SchemaFields } from './schema/types.js';
|
|
42
|
+
|
|
43
|
+
const EMPTY_FLAGS = Object.freeze({}) satisfies Record<string, never>;
|
|
44
|
+
const EMPTY_DEPS = Object.freeze({}) satisfies Record<string, never>;
|
|
45
|
+
const EMPTY_USER_CTX = Object.freeze({}) satisfies Record<string, never>;
|
|
46
|
+
|
|
47
|
+
// =============================================================================
|
|
48
|
+
// EFFECTIVE SCHEMA COMPUTATION
|
|
49
|
+
// =============================================================================
|
|
50
|
+
|
|
51
|
+
// isMappedOpGroup is imported from opContext/index.js
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Check if a field name is a system field (original or prefixed).
|
|
55
|
+
*
|
|
56
|
+
* System fields can appear as:
|
|
57
|
+
* - Original names: 'message', 'line', 'error_code', etc.
|
|
58
|
+
* - Prefixed names: 'http_message', 'db_line', 'auth_error_code', etc.
|
|
59
|
+
*
|
|
60
|
+
* @param fieldName - The field name to check
|
|
61
|
+
* @returns True if the field is a system field
|
|
62
|
+
*/
|
|
63
|
+
function isSystemField(fieldName: string): boolean {
|
|
64
|
+
// Check direct match first
|
|
65
|
+
if (SYSTEM_SCHEMA_FIELD_NAMES.has(fieldName)) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
// Check if it's a prefixed system field (e.g., 'http_message' -> 'message')
|
|
69
|
+
const underscoreIdx = fieldName.indexOf('_');
|
|
70
|
+
if (underscoreIdx !== -1) {
|
|
71
|
+
const suffix = fieldName.slice(underscoreIdx + 1);
|
|
72
|
+
if (SYSTEM_SCHEMA_FIELD_NAMES.has(suffix)) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Filter out system schema fields from a schema.
|
|
81
|
+
*
|
|
82
|
+
* System fields (message, line, error_code, etc.) are merged into every logSchema
|
|
83
|
+
* by defineOpContext, but they should NOT be contributed when a dep is wired.
|
|
84
|
+
* Each app gets its own system fields via mergeWithSystemSchema.
|
|
85
|
+
*
|
|
86
|
+
* This function handles both original and prefixed system field names.
|
|
87
|
+
*
|
|
88
|
+
* @param fields - Schema fields to filter
|
|
89
|
+
* @returns Schema fields without system fields
|
|
90
|
+
*/
|
|
91
|
+
function filterOutSystemFields(fields: SchemaFields): SchemaFields {
|
|
92
|
+
const result: SchemaFields = {};
|
|
93
|
+
for (const key of Object.keys(fields)) {
|
|
94
|
+
if (!isSystemField(key)) {
|
|
95
|
+
result[key] = fields[key];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function isInternalOpGroup(dep: AnyOpGroupPublic): dep is AnyOpGroupPublic & AnyOpGroup {
|
|
102
|
+
return '_logSchema' in dep;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get the schema fields contributed by a dep (OpGroup or MappedOpGroup).
|
|
107
|
+
*
|
|
108
|
+
* - For OpGroup: returns original schema fields (no transformation), excluding system fields
|
|
109
|
+
* - For MappedOpGroup: returns contributedSchema (after prefix/mapping)
|
|
110
|
+
*
|
|
111
|
+
* System fields (message, line, error_code, etc.) are always filtered out because
|
|
112
|
+
* each app gets its own system fields via mergeWithSystemSchema - deps should NOT
|
|
113
|
+
* contribute system fields.
|
|
114
|
+
*
|
|
115
|
+
* The returned object maps field names to their schema definitions.
|
|
116
|
+
*
|
|
117
|
+
* @param dep - An OpGroup or MappedOpGroup (with internal properties _logSchema, _contributedSchema)
|
|
118
|
+
* @returns The schema fields this dep contributes (user fields only, no system fields)
|
|
119
|
+
*/
|
|
120
|
+
function getContributedSchemaFromDep(dep: AnyOpGroupPublic): SchemaFields {
|
|
121
|
+
if (!isInternalOpGroup(dep)) {
|
|
122
|
+
throw new Error('Invalid op dependency: expected an OpGroup created by defineOps()');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (isMappedOpGroup(dep)) {
|
|
126
|
+
// MappedOpGroup has _contributedSchema with mapped field names
|
|
127
|
+
// This already excludes null-mapped columns (they were dropped in buildContributedSchema)
|
|
128
|
+
// Filter out system fields in case the original schema included them
|
|
129
|
+
return filterOutSystemFields(dep._contributedSchema);
|
|
130
|
+
}
|
|
131
|
+
// OpGroup contributes its original schema fields, excluding system fields
|
|
132
|
+
return filterOutSystemFields(dep._logSchema.fields);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Compute the effective schema by merging app schema with all dep contributions.
|
|
137
|
+
*
|
|
138
|
+
* The effective schema is the union of:
|
|
139
|
+
* 1. App's own schema fields
|
|
140
|
+
* 2. All dep contributed fields (after prefix/mapping)
|
|
141
|
+
*
|
|
142
|
+
* Throws if multiple deps contribute the same field name (conflict detection).
|
|
143
|
+
*
|
|
144
|
+
* @param appFields - The app's own schema fields
|
|
145
|
+
* @param deps - The deps config (name -> OpGroup | MappedOpGroup)
|
|
146
|
+
* @returns Combined schema fields for the effective schema
|
|
147
|
+
* @throws Error if deps contribute conflicting field names
|
|
148
|
+
*/
|
|
149
|
+
function computeEffectiveSchema<T extends SchemaFields>(appFields: T): T;
|
|
150
|
+
function computeEffectiveSchema<T extends SchemaFields, Deps extends DepsConfig>(
|
|
151
|
+
appFields: T,
|
|
152
|
+
deps: Deps,
|
|
153
|
+
): EffectiveSchema<T, Deps>;
|
|
154
|
+
function computeEffectiveSchema(appFields: SchemaFields, deps?: DepsConfig): SchemaFields {
|
|
155
|
+
if (!deps || Object.keys(deps).length === 0) {
|
|
156
|
+
return appFields;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Start with app fields
|
|
160
|
+
const effective: SchemaFields = { ...appFields };
|
|
161
|
+
|
|
162
|
+
// Track which dep contributed each field for conflict detection
|
|
163
|
+
const fieldSource: Record<string, string> = {};
|
|
164
|
+
for (const fieldName of Object.keys(appFields)) {
|
|
165
|
+
fieldSource[fieldName] = 'app';
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Add each dep's contributed fields
|
|
169
|
+
for (const [depName, dep] of Object.entries(deps)) {
|
|
170
|
+
// Cast to AnyOpGroup to access internal properties (_logSchema, _contributedSchema)
|
|
171
|
+
// These exist at runtime but are hidden from public TypeScript interfaces
|
|
172
|
+
const contributed = getContributedSchemaFromDep(dep);
|
|
173
|
+
|
|
174
|
+
for (const [fieldName, fieldDef] of Object.entries(contributed)) {
|
|
175
|
+
// Check for conflict
|
|
176
|
+
if (fieldName in effective) {
|
|
177
|
+
const existingSource = fieldSource[fieldName];
|
|
178
|
+
throw new Error(
|
|
179
|
+
`Schema conflict: field '${fieldName}' contributed by dep '${depName}' ` +
|
|
180
|
+
`conflicts with field from '${existingSource}'. ` +
|
|
181
|
+
'Use .prefix() or .mapColumns() to resolve the conflict.',
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
effective[fieldName] = fieldDef;
|
|
186
|
+
fieldSource[fieldName] = depName;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return effective;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function buildOpContextFactory<
|
|
194
|
+
EffectiveFields extends SchemaFields,
|
|
195
|
+
FF extends FeatureFlagSchema,
|
|
196
|
+
Deps extends DepsConfig,
|
|
197
|
+
UserCtx extends Record<string, unknown>,
|
|
198
|
+
>(
|
|
199
|
+
effectiveFields: EffectiveFields,
|
|
200
|
+
flags: FF,
|
|
201
|
+
deps: Deps,
|
|
202
|
+
ctxDefaults: UserCtx,
|
|
203
|
+
): OpContextFactory<LogSchema<EffectiveFields>, FF, Deps, UserCtx> {
|
|
204
|
+
// Merge effective schema with system schema (message, line, error_code, etc.)
|
|
205
|
+
// System columns are always available on SpanBuffer regardless of user schema.
|
|
206
|
+
// Type parameter stays on the effective user/dependency schema because callers should infer
|
|
207
|
+
// only the public columns, while the runtime object still carries the merged system fields.
|
|
208
|
+
const mergedSchema = new LogSchema<EffectiveFields>(mergeWithSystemSchema(effectiveFields));
|
|
209
|
+
|
|
210
|
+
// Create a LogBinding for ops to use.
|
|
211
|
+
// NOTE: Stats are NO LONGER on LogBinding - they are on SpanBufferClass.stats (static property).
|
|
212
|
+
// This avoids sync bugs from having two stat objects and reduces per-instance memory.
|
|
213
|
+
// See agent-todo/opgroup-refactor.md lines 58-70, 525-547 for rationale.
|
|
214
|
+
const logBinding = {
|
|
215
|
+
logSchema: mergedSchema,
|
|
216
|
+
remappedViewClass: undefined,
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// WHY: build the binding first so Ops created by defineOp carry it via _opContextBinding.
|
|
220
|
+
// This enables downstream consumers (defineAgentOps, OpRegistry) to extract the LMAO schema.
|
|
221
|
+
const opContextBinding = { logBinding, flags, ctxDefaults, deps };
|
|
222
|
+
|
|
223
|
+
// Create the defineOp and defineOps functions bound to this config.
|
|
224
|
+
// CRITICAL: Use mergedSchema (with system columns), not just the app schema, because
|
|
225
|
+
// runtime SpanBuffer generation needs the full row shape even though public factory.logSchema
|
|
226
|
+
// intentionally exposes only user/dependency columns.
|
|
227
|
+
const defineOp = createDefineOp<OpContext<typeof mergedSchema, FF, Deps, UserCtx>>({
|
|
228
|
+
logSchema: mergedSchema,
|
|
229
|
+
flags,
|
|
230
|
+
opContextBinding,
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
const defineOps = createDefineOps<OpContext<typeof mergedSchema, FF, Deps, UserCtx>>(
|
|
234
|
+
{ logSchema: mergedSchema, flags, opContextBinding },
|
|
235
|
+
createOpGroup,
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
// Create effective schema LogSchema instance for factory.logSchema.
|
|
239
|
+
// This contains app fields + all dep contributed fields (user fields only, no system).
|
|
240
|
+
const effectiveLogSchema = new LogSchema(effectiveFields);
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
logSchema: effectiveLogSchema,
|
|
244
|
+
flags,
|
|
245
|
+
logBinding,
|
|
246
|
+
ctxDefaults,
|
|
247
|
+
deps,
|
|
248
|
+
defineOp,
|
|
249
|
+
defineOps,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Define an Op context factory
|
|
255
|
+
*
|
|
256
|
+
* Creates a factory for defining Ops that share the same schema, deps, and context.
|
|
257
|
+
* This is the main entry point for the Op-centric API.
|
|
258
|
+
*
|
|
259
|
+
* @param config - Context configuration
|
|
260
|
+
* @returns OpContextFactory with defineOp, defineOps
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* import { defineOpContext } from '@smoothbricks/lmao';
|
|
265
|
+
*
|
|
266
|
+
* const { defineOp, defineOps } = defineOpContext({
|
|
267
|
+
* logSchema: myLogSchema,
|
|
268
|
+
* deps: {
|
|
269
|
+
* http: httpOps.prefix('http'),
|
|
270
|
+
* auth: authOps.prefix('auth'),
|
|
271
|
+
* },
|
|
272
|
+
* flags: myFeatureFlags,
|
|
273
|
+
* ctx: {
|
|
274
|
+
* env: null as CFWorkerEnv, // Must provide at createTrace()
|
|
275
|
+
* config: { retryCount: 3 }, // Has default
|
|
276
|
+
* },
|
|
277
|
+
* });
|
|
278
|
+
*
|
|
279
|
+
* // Define ops
|
|
280
|
+
* export const myHandler = defineOp('handler', async (ctx, req: Request) => {
|
|
281
|
+
* ctx.tag.method(req.method);
|
|
282
|
+
* return ctx.ok({ status: 'ok' });
|
|
283
|
+
* });
|
|
284
|
+
*
|
|
285
|
+
* // Or batch define and export as OpGroup
|
|
286
|
+
* export const myOps = defineOps({
|
|
287
|
+
* myHandler,
|
|
288
|
+
* healthCheck: async (ctx) => ctx.ok({ healthy: true }),
|
|
289
|
+
* });
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
export function defineOpContext<T extends SchemaFields>(
|
|
293
|
+
config: OpContextConfig<T, Record<string, never>, Record<string, never>, Record<string, never>>,
|
|
294
|
+
): OpContextFactory<LogSchema<T>, Record<string, never>, Record<string, never>, Record<string, never>>;
|
|
295
|
+
export function defineOpContext<T extends SchemaFields, const FF extends FeatureFlagSchema>(
|
|
296
|
+
config: OpContextConfig<T, FF, Record<string, never>, Record<string, never>> & { flags: FF },
|
|
297
|
+
): OpContextFactory<LogSchema<T>, FF, Record<string, never>, Record<string, never>>;
|
|
298
|
+
export function defineOpContext<T extends SchemaFields, UserCtx extends Record<string, unknown>>(
|
|
299
|
+
config: OpContextConfig<T, Record<string, never>, Record<string, never>, UserCtx> & {
|
|
300
|
+
ctx: ValidateUserContext<UserCtx>;
|
|
301
|
+
},
|
|
302
|
+
): OpContextFactory<LogSchema<T>, Record<string, never>, Record<string, never>, UserCtx>;
|
|
303
|
+
export function defineOpContext<
|
|
304
|
+
T extends SchemaFields,
|
|
305
|
+
const FF extends FeatureFlagSchema,
|
|
306
|
+
UserCtx extends Record<string, unknown>,
|
|
307
|
+
>(
|
|
308
|
+
config: OpContextConfig<T, FF, Record<string, never>, UserCtx> & { flags: FF; ctx: ValidateUserContext<UserCtx> },
|
|
309
|
+
): OpContextFactory<LogSchema<T>, FF, Record<string, never>, UserCtx>;
|
|
310
|
+
export function defineOpContext<T extends SchemaFields, Deps extends DepsConfig>(
|
|
311
|
+
config: OpContextConfig<T, Record<string, never>, Deps, Record<string, never>> & { deps: Deps },
|
|
312
|
+
): OpContextFactory<LogSchema<EffectiveSchema<T, Deps>>, Record<string, never>, Deps, Record<string, never>>;
|
|
313
|
+
export function defineOpContext<T extends SchemaFields, const FF extends FeatureFlagSchema, Deps extends DepsConfig>(
|
|
314
|
+
config: OpContextConfig<T, FF, Deps, Record<string, never>> & { flags: FF; deps: Deps },
|
|
315
|
+
): OpContextFactory<LogSchema<EffectiveSchema<T, Deps>>, FF, Deps, Record<string, never>>;
|
|
316
|
+
export function defineOpContext<
|
|
317
|
+
T extends SchemaFields,
|
|
318
|
+
Deps extends DepsConfig,
|
|
319
|
+
UserCtx extends Record<string, unknown>,
|
|
320
|
+
>(
|
|
321
|
+
config: OpContextConfig<T, Record<string, never>, Deps, UserCtx> & { deps: Deps; ctx: ValidateUserContext<UserCtx> },
|
|
322
|
+
): OpContextFactory<LogSchema<EffectiveSchema<T, Deps>>, Record<string, never>, Deps, UserCtx>;
|
|
323
|
+
export function defineOpContext<
|
|
324
|
+
T extends SchemaFields,
|
|
325
|
+
const FF extends FeatureFlagSchema,
|
|
326
|
+
Deps extends DepsConfig,
|
|
327
|
+
UserCtx extends Record<string, unknown>,
|
|
328
|
+
>(
|
|
329
|
+
config: OpContextConfig<T, FF, Deps, UserCtx> & { flags: FF; deps: Deps; ctx: ValidateUserContext<UserCtx> },
|
|
330
|
+
): OpContextFactory<LogSchema<EffectiveSchema<T, Deps>>, FF, Deps, UserCtx>;
|
|
331
|
+
export function defineOpContext<
|
|
332
|
+
T extends SchemaFields,
|
|
333
|
+
const FF extends FeatureFlagSchema = Record<string, never>,
|
|
334
|
+
Deps extends DepsConfig = Record<string, never>,
|
|
335
|
+
UserCtx extends Record<string, unknown> = Record<string, never>,
|
|
336
|
+
>(config: OpContextConfig<T, FF, Deps, UserCtx>) {
|
|
337
|
+
// Runtime validation: check for reserved property names in user context
|
|
338
|
+
if (config.ctx) {
|
|
339
|
+
const userKeys = Object.keys(config.ctx);
|
|
340
|
+
for (const key of userKeys) {
|
|
341
|
+
if (RESERVED_CONTEXT_PROPS.some((reservedProp) => reservedProp === key)) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
`Cannot use '${key}' in ctx - it is a reserved SpanContext property. ` +
|
|
344
|
+
`Reserved: ${RESERVED_CONTEXT_PROPS.join(', ')}`,
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
// Check for underscore prefix (reserved for internal use)
|
|
348
|
+
if (key.startsWith('_')) {
|
|
349
|
+
throw new Error(`Cannot use '${key}' in ctx - properties starting with '_' are reserved for internal use.`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Compute effective schema by combining app schema with dep contributions.
|
|
355
|
+
// This merges app fields + all dep contributed fields (after prefix/mapping).
|
|
356
|
+
if (config.deps === undefined) {
|
|
357
|
+
const effectiveFields = computeEffectiveSchema(config.logSchema.fields);
|
|
358
|
+
|
|
359
|
+
if (config.flags === undefined) {
|
|
360
|
+
if (config.ctx === undefined) {
|
|
361
|
+
return buildOpContextFactory(effectiveFields, EMPTY_FLAGS, EMPTY_DEPS, EMPTY_USER_CTX);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return buildOpContextFactory(effectiveFields, EMPTY_FLAGS, EMPTY_DEPS, config.ctx);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (config.ctx === undefined) {
|
|
368
|
+
return buildOpContextFactory(effectiveFields, config.flags, EMPTY_DEPS, EMPTY_USER_CTX);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return buildOpContextFactory(effectiveFields, config.flags, EMPTY_DEPS, config.ctx);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const effectiveFields = computeEffectiveSchema(config.logSchema.fields, config.deps);
|
|
375
|
+
|
|
376
|
+
if (config.flags === undefined) {
|
|
377
|
+
if (config.ctx === undefined) {
|
|
378
|
+
return buildOpContextFactory(effectiveFields, EMPTY_FLAGS, config.deps, EMPTY_USER_CTX);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return buildOpContextFactory(effectiveFields, EMPTY_FLAGS, config.deps, config.ctx);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (config.ctx === undefined) {
|
|
385
|
+
return buildOpContextFactory(effectiveFields, config.flags, config.deps, EMPTY_USER_CTX);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return buildOpContextFactory(effectiveFields, config.flags, config.deps, config.ctx);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Re-export everything from opContext for convenience
|
|
392
|
+
export * from './opContext/index.js';
|
|
393
|
+
|
|
394
|
+
// Re-export schema utilities
|
|
395
|
+
export { S } from './schema/builder.js';
|
|
396
|
+
export { defineFeatureFlags } from './schema/defineFeatureFlags.js';
|
|
397
|
+
export { defineLogSchema } from './schema/defineLogSchema.js';
|
|
398
|
+
export { LogSchema } from './schema/LogSchema.js';
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blocked error - indicates an Op cannot proceed due to a temporary condition.
|
|
3
|
+
*
|
|
4
|
+
* A tagged error type for use with `result.isErr(Blocked)` to discriminate
|
|
5
|
+
* blocked states from other errors. Useful for retry logic and dependency waiting.
|
|
6
|
+
*
|
|
7
|
+
* Uses BlockedConfig for retry configuration (closure-based nextRetry).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { defineOpContext, S, Err } from '@smoothbricks/lmao';
|
|
12
|
+
* import { Blocked } from '@smoothbricks/lmao/errors/Blocked';
|
|
13
|
+
*
|
|
14
|
+
* const { defineOp } = defineOpContext({
|
|
15
|
+
* logSchema: { service: S.category() },
|
|
16
|
+
* ctx: { env: null as Env },
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* const fetchData = defineOp('fetchData', async (ctx, service: string) => {
|
|
20
|
+
* const health = await checkHealth(service);
|
|
21
|
+
* if (!health.available) {
|
|
22
|
+
* // Return Err with Blocked - can chain .with() for tags
|
|
23
|
+
* return new Err(Blocked.service(service)).with({ service });
|
|
24
|
+
* }
|
|
25
|
+
* ctx.tag.service(service);
|
|
26
|
+
* return ctx.ok(await doFetch(service));
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // With closure-based retry (captures HTTP response context)
|
|
30
|
+
* const callApi = defineOp('callApi', async (ctx, url: string) => {
|
|
31
|
+
* const response = await fetch(url);
|
|
32
|
+
* if (response.status === 503) {
|
|
33
|
+
* const retryAfterSec = parseInt(response.headers.get('Retry-After') ?? '5');
|
|
34
|
+
* return new Err(Blocked.service('payment-api', {
|
|
35
|
+
* maxAttempts: 5,
|
|
36
|
+
* nextRetry: (attempt) => {
|
|
37
|
+
* if (attempt === 1) return retryAfterSec * 1000;
|
|
38
|
+
* return 5000 * Math.pow(2, attempt - 1);
|
|
39
|
+
* },
|
|
40
|
+
* }));
|
|
41
|
+
* }
|
|
42
|
+
* return ctx.ok(await response.json());
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* // Caller can discriminate blocked from other errors
|
|
46
|
+
* const result = await trace('fetch', fetchData, 'payment-api');
|
|
47
|
+
* if (result.isErr(Blocked)) {
|
|
48
|
+
* // Handle temporary unavailability - retry, queue, etc.
|
|
49
|
+
* console.log(`Blocked on ${result.error.reason.name}`);
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
import type { TaggedError } from '../result.js';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Reason why an Op is blocked.
|
|
58
|
+
*/
|
|
59
|
+
export type BlockedReason =
|
|
60
|
+
| { readonly type: 'service'; readonly name: string }
|
|
61
|
+
| { readonly type: 'ended'; readonly target: string }
|
|
62
|
+
| { readonly type: 'index'; readonly indexName: string };
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Convert a blocked reason union into its display name.
|
|
66
|
+
*/
|
|
67
|
+
export function getBlockedReasonName(reason: BlockedReason): string {
|
|
68
|
+
switch (reason.type) {
|
|
69
|
+
case 'service':
|
|
70
|
+
return reason.name;
|
|
71
|
+
case 'ended':
|
|
72
|
+
return reason.target;
|
|
73
|
+
case 'index':
|
|
74
|
+
return reason.indexName;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Engine-level retry configuration for blocked operations.
|
|
80
|
+
*
|
|
81
|
+
* The nextRetry closure is powerful because it captures the Op's execution context.
|
|
82
|
+
* Each time the Op re-executes, it produces a new Blocked error with a new closure
|
|
83
|
+
* that may reference updated information (e.g., fresh Retry-After headers).
|
|
84
|
+
*/
|
|
85
|
+
export interface BlockedConfig {
|
|
86
|
+
/** Max canary retries before RetriesExhausted (default: 5) */
|
|
87
|
+
readonly maxAttempts?: number;
|
|
88
|
+
/** Closure returning delay in ms before next retry. Captures Op context. */
|
|
89
|
+
readonly nextRetry?: (attempt: number) => number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
type BlockedInspectView = {
|
|
93
|
+
_tag: 'Blocked';
|
|
94
|
+
reason: BlockedReason;
|
|
95
|
+
blockedConfig?: BlockedConfig;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
type BlockedJsonView = {
|
|
99
|
+
_tag: 'Blocked';
|
|
100
|
+
reason: BlockedReason;
|
|
101
|
+
blockedConfig?: Omit<BlockedConfig, 'nextRetry'> & { nextRetry?: string };
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export class Blocked extends Error implements TaggedError<'Blocked'> {
|
|
105
|
+
static readonly _tag = 'Blocked' as const;
|
|
106
|
+
|
|
107
|
+
get _tag(): 'Blocked' {
|
|
108
|
+
return 'Blocked';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Retry configuration */
|
|
112
|
+
readonly blockedConfig: BlockedConfig | undefined;
|
|
113
|
+
|
|
114
|
+
constructor(
|
|
115
|
+
/** The reason this Op is blocked */
|
|
116
|
+
readonly reason: BlockedReason,
|
|
117
|
+
/** Optional retry configuration */
|
|
118
|
+
config?: BlockedConfig,
|
|
119
|
+
) {
|
|
120
|
+
super(`Blocked: ${getBlockedReasonName(reason)}`);
|
|
121
|
+
this.name = 'Blocked';
|
|
122
|
+
this.blockedConfig = config;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Create a Blocked error for a service being unavailable */
|
|
126
|
+
static service(name: string, config?: BlockedConfig): Blocked {
|
|
127
|
+
return new Blocked({ type: 'service', name }, config);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Create a Blocked error waiting for another execution to end */
|
|
131
|
+
static ended(target: string, config?: BlockedConfig): Blocked {
|
|
132
|
+
return new Blocked({ type: 'ended', target }, config);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Create a Blocked error for an index being rebuilt */
|
|
136
|
+
static index(indexName: string, config?: BlockedConfig): Blocked {
|
|
137
|
+
return new Blocked({ type: 'index', indexName }, config);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Clean output for console.log in Node.js */
|
|
141
|
+
[Symbol.for('nodejs.util.inspect.custom')](): BlockedInspectView {
|
|
142
|
+
return {
|
|
143
|
+
_tag: this._tag,
|
|
144
|
+
reason: this.reason,
|
|
145
|
+
...(this.blockedConfig ? { blockedConfig: this.blockedConfig } : {}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Clean output for JSON.stringify */
|
|
150
|
+
toJSON(): BlockedJsonView {
|
|
151
|
+
const config = this.blockedConfig;
|
|
152
|
+
return {
|
|
153
|
+
_tag: this._tag,
|
|
154
|
+
reason: this.reason,
|
|
155
|
+
...(config
|
|
156
|
+
? {
|
|
157
|
+
blockedConfig: {
|
|
158
|
+
...(config.maxAttempts != null ? { maxAttempts: config.maxAttempts } : {}),
|
|
159
|
+
...(config.nextRetry ? { nextRetry: '[closure]' } : {}),
|
|
160
|
+
},
|
|
161
|
+
}
|
|
162
|
+
: {}),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeError - typed error codes with data payloads.
|
|
3
|
+
*
|
|
4
|
+
* Use the `Code()` helper to define typed error codes, then use them with `ctx.err()`.
|
|
5
|
+
* The error code becomes the `_tag` for discrimination with `result.isErr(CODE)`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Code } from '@smoothbricks/lmao/errors/CodeError';
|
|
10
|
+
*
|
|
11
|
+
* // Define typed error codes
|
|
12
|
+
* const NOT_FOUND = Code<{ id: string }>('NOT_FOUND');
|
|
13
|
+
* const VALIDATION_ERROR = Code<{ field: string; reason: string }>('VALIDATION_ERROR');
|
|
14
|
+
* const TIMEOUT = Code('TIMEOUT'); // No data payload
|
|
15
|
+
*
|
|
16
|
+
* // Use in Ops
|
|
17
|
+
* const fetchUser = defineOp('fetchUser', async (ctx, id: string) => {
|
|
18
|
+
* const user = await db.find(id);
|
|
19
|
+
* if (!user) {
|
|
20
|
+
* return ctx.err(NOT_FOUND({ id }));
|
|
21
|
+
* }
|
|
22
|
+
* return ctx.ok(user);
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Discriminate errors
|
|
26
|
+
* const result = await trace('fetch', fetchUser, 'abc');
|
|
27
|
+
* if (result.isErr(NOT_FOUND)) {
|
|
28
|
+
* console.log(`User ${result.error.data.id} not found`);
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { TaggedError, TaggedErrorConstructor } from '../result.js';
|
|
34
|
+
|
|
35
|
+
type CodeErrorJson<C extends string, D> = { code: C; data: D };
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Error instance created by a Code constructor.
|
|
39
|
+
*
|
|
40
|
+
* @typeParam C - The error code string literal type (also serves as _tag)
|
|
41
|
+
* @typeParam D - The data payload type
|
|
42
|
+
*/
|
|
43
|
+
export class CodeError<C extends string, D = void> extends Error implements TaggedError<C> {
|
|
44
|
+
/**
|
|
45
|
+
* The error code - also serves as the tag for discrimination.
|
|
46
|
+
*/
|
|
47
|
+
readonly code: C;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The typed data payload.
|
|
51
|
+
*/
|
|
52
|
+
readonly data: D;
|
|
53
|
+
|
|
54
|
+
constructor(code: C, data: D) {
|
|
55
|
+
super(code);
|
|
56
|
+
this.name = 'CodeError';
|
|
57
|
+
this.code = code;
|
|
58
|
+
this.data = data;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Tag for discrimination with isErr(Tag).
|
|
63
|
+
* Returns the error code.
|
|
64
|
+
*/
|
|
65
|
+
get _tag(): C {
|
|
66
|
+
return this.code;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
[Symbol.for('nodejs.util.inspect.custom')](): CodeErrorJson<C, D> {
|
|
70
|
+
return { code: this.code, data: this.data };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
toJSON(): CodeErrorJson<C, D> {
|
|
74
|
+
return { code: this.code, data: this.data };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Constructor function for a specific error code.
|
|
80
|
+
* Has static `_tag` for use with `isErr(CODE)`.
|
|
81
|
+
*/
|
|
82
|
+
export interface CodeConstructor<C extends string, D = void> extends TaggedErrorConstructor<CodeError<C, D>> {
|
|
83
|
+
(data: D): CodeError<C, D>;
|
|
84
|
+
readonly _tag: C;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Constructor function for error codes with no data.
|
|
89
|
+
*/
|
|
90
|
+
export interface CodeConstructorVoid<C extends string> extends TaggedErrorConstructor<CodeError<C, void>> {
|
|
91
|
+
(): CodeError<C, void>;
|
|
92
|
+
readonly _tag: C;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
type CodeFactoryReturn<C extends string, D> = [unknown] extends [D]
|
|
96
|
+
? CodeConstructor<C, D>
|
|
97
|
+
: undefined extends D
|
|
98
|
+
? CodeConstructorVoid<C>
|
|
99
|
+
: CodeConstructor<C, D>;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Define a typed error code.
|
|
103
|
+
*
|
|
104
|
+
* @param code - The error code string (becomes _tag for discrimination)
|
|
105
|
+
* @returns A constructor function that creates CodeError instances
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* // With typed data
|
|
110
|
+
* const NOT_FOUND = Code<{ id: string }>('NOT_FOUND');
|
|
111
|
+
* ctx.err(NOT_FOUND({ id: 'abc' }));
|
|
112
|
+
*
|
|
113
|
+
* // Without data
|
|
114
|
+
* const TIMEOUT = Code('TIMEOUT');
|
|
115
|
+
* ctx.err(TIMEOUT());
|
|
116
|
+
*
|
|
117
|
+
* // Discrimination
|
|
118
|
+
* if (result.isErr(NOT_FOUND)) {
|
|
119
|
+
* console.log(result.error.data.id); // TypeScript knows the type
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export function Code<C extends string>(code: C): CodeConstructorVoid<C>;
|
|
124
|
+
export function Code<D, C extends string = string>(code: C): CodeFactoryReturn<C, D>;
|
|
125
|
+
export function Code(code: string) {
|
|
126
|
+
function createCodeError(data?: unknown) {
|
|
127
|
+
return new CodeError(code, data);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
Object.defineProperty(createCodeError, '_tag', { value: code, writable: false, enumerable: true });
|
|
131
|
+
return createCodeError;
|
|
132
|
+
}
|