@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,171 @@
|
|
|
1
|
+
import { LogSchema } from './LogSchema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validate a single field value against its schema metadata.
|
|
4
|
+
* Uses __schema_type for type dispatch — no Sury dependency.
|
|
5
|
+
*
|
|
6
|
+
* Handles all schema compositions: optional, refine, union, key.
|
|
7
|
+
* Throws on unknown __schema_type to prevent silent acceptance of invalid data.
|
|
8
|
+
*/
|
|
9
|
+
function validateField(key, value, schema) {
|
|
10
|
+
const s = schema;
|
|
11
|
+
// Handle optional schemas (created via S.optional())
|
|
12
|
+
if (s.__optional) {
|
|
13
|
+
if (value === undefined || value === null)
|
|
14
|
+
return undefined;
|
|
15
|
+
// Value is present — recursively validate against the inner schema
|
|
16
|
+
if (s.__inner) {
|
|
17
|
+
return validateField(key, value, s.__inner);
|
|
18
|
+
}
|
|
19
|
+
// Optional with no inner schema — accept the value as-is
|
|
20
|
+
// (shouldn't happen with well-formed schemas, but defensive)
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
if (value === undefined || value === null) {
|
|
24
|
+
throw new Error(`Field "${key}": expected a value, got ${value === null ? 'null' : 'undefined'}`);
|
|
25
|
+
}
|
|
26
|
+
// Handle refine() schemas — invoke the stored refiner function
|
|
27
|
+
if (s.__refiner) {
|
|
28
|
+
try {
|
|
29
|
+
return s.__refiner(value, {
|
|
30
|
+
fail(msg) {
|
|
31
|
+
throw new Error(`Field "${key}": refinement failed — ${msg}`);
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
if (err instanceof Error && err.message.startsWith(`Field "${key}":`))
|
|
37
|
+
throw err;
|
|
38
|
+
throw new Error(`Field "${key}": refinement failed — ${err instanceof Error ? err.message : String(err)}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Handle union() schemas — try each member, accept if any matches
|
|
42
|
+
if (s.__union) {
|
|
43
|
+
const errors = [];
|
|
44
|
+
for (const member of s.__union) {
|
|
45
|
+
try {
|
|
46
|
+
return validateField(key, value, member);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
errors.push(err instanceof Error ? err.message : String(err));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
throw new Error(`Field "${key}": value does not match any union member. Tried ${s.__union.length}: ${errors.join('; ')}`);
|
|
53
|
+
}
|
|
54
|
+
switch (s.__schema_type) {
|
|
55
|
+
case 'number':
|
|
56
|
+
if (typeof value !== 'number')
|
|
57
|
+
throw new Error(`Field "${key}": expected number, got ${typeof value}`);
|
|
58
|
+
return value;
|
|
59
|
+
case 'boolean':
|
|
60
|
+
if (typeof value !== 'boolean')
|
|
61
|
+
throw new Error(`Field "${key}": expected boolean, got ${typeof value}`);
|
|
62
|
+
return value;
|
|
63
|
+
case 'text':
|
|
64
|
+
case 'category':
|
|
65
|
+
if (typeof value !== 'string')
|
|
66
|
+
throw new Error(`Field "${key}": expected string, got ${typeof value}`);
|
|
67
|
+
return value;
|
|
68
|
+
case 'enum':
|
|
69
|
+
if (typeof value !== 'string')
|
|
70
|
+
throw new Error(`Field "${key}": expected string, got ${typeof value}`);
|
|
71
|
+
if (s.__enum_values && !s.__enum_values.includes(value)) {
|
|
72
|
+
throw new Error(`Field "${key}": expected one of [${s.__enum_values.join(', ')}], got "${value}"`);
|
|
73
|
+
}
|
|
74
|
+
return value;
|
|
75
|
+
case 'bigUint64':
|
|
76
|
+
if (typeof value !== 'bigint')
|
|
77
|
+
throw new Error(`Field "${key}": expected bigint, got ${typeof value}`);
|
|
78
|
+
return value;
|
|
79
|
+
case 'binary':
|
|
80
|
+
// Binary accepts any value (raw bytes or encoder-wrapped)
|
|
81
|
+
return value;
|
|
82
|
+
case 'key':
|
|
83
|
+
// Key schema — validate the runtime value using the stored validator
|
|
84
|
+
if (typeof value !== 'string')
|
|
85
|
+
throw new Error(`Field "${key}": expected string key value, got ${typeof value}`);
|
|
86
|
+
if (s.__key_validator) {
|
|
87
|
+
return s.__key_validator(value);
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
default:
|
|
91
|
+
throw new Error(`Field "${key}": unknown schema type "${s.__schema_type ?? '<none>'}". ` +
|
|
92
|
+
'All schema types must be explicitly handled in validateField.');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Validate an object against a set of schema columns.
|
|
97
|
+
*/
|
|
98
|
+
function validateObject(data, columns) {
|
|
99
|
+
if (!isUnknownRecord(data)) {
|
|
100
|
+
throw new Error(`Expected object, got ${data === null ? 'null' : typeof data}`);
|
|
101
|
+
}
|
|
102
|
+
const result = {};
|
|
103
|
+
for (const [key, schema] of columns) {
|
|
104
|
+
result[key] = validateField(key, data[key], schema);
|
|
105
|
+
}
|
|
106
|
+
assertValidatedObject(result, columns);
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
function isUnknownRecord(value) {
|
|
110
|
+
return typeof value === 'object' && value !== null;
|
|
111
|
+
}
|
|
112
|
+
function assertValidatedObject(value, columns) {
|
|
113
|
+
for (const [key] of columns) {
|
|
114
|
+
if (!(key in value)) {
|
|
115
|
+
throw new Error(`Missing validated field "${key}"`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function defineLogSchema(schema, options) {
|
|
120
|
+
// Wrap user input into LogSchema first
|
|
121
|
+
const logSchema = schema instanceof LogSchema ? schema : new LogSchema(schema);
|
|
122
|
+
// Assert attribute names don't use reserved names
|
|
123
|
+
if (!options?._skipReservedNameValidation) {
|
|
124
|
+
LogSchema.assertUserFieldNames(logSchema._columnNames);
|
|
125
|
+
}
|
|
126
|
+
// Add validation methods directly to logSchema (preserves LogSchema instance)
|
|
127
|
+
// Use Object.assign to mutate logSchema in place, preserving prototype chain
|
|
128
|
+
const result = Object.assign(logSchema, {
|
|
129
|
+
/**
|
|
130
|
+
* Validate data and throw on error
|
|
131
|
+
*
|
|
132
|
+
* @throws Error if validation fails
|
|
133
|
+
*/
|
|
134
|
+
validate: (data) => {
|
|
135
|
+
return validateObject(data, logSchema._columns);
|
|
136
|
+
},
|
|
137
|
+
/**
|
|
138
|
+
* Validate data and return null on error
|
|
139
|
+
*
|
|
140
|
+
* @returns Validated data or null if invalid
|
|
141
|
+
*/
|
|
142
|
+
parse: (data) => {
|
|
143
|
+
try {
|
|
144
|
+
return validateObject(data, logSchema._columns);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
/**
|
|
151
|
+
* Safe parse with detailed error information
|
|
152
|
+
*
|
|
153
|
+
* @returns Result object with success flag
|
|
154
|
+
*/
|
|
155
|
+
safeParse: (data) => {
|
|
156
|
+
try {
|
|
157
|
+
return { success: true, value: validateObject(data, logSchema._columns) };
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
161
|
+
return { success: false, error };
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
// Verify result is still a LogSchema instance (Object.assign returns the mutated target)
|
|
166
|
+
if (!(result instanceof LogSchema)) {
|
|
167
|
+
throw new Error('defineLogSchema: Object.assign broke LogSchema instance');
|
|
168
|
+
}
|
|
169
|
+
// Return logSchema (still a LogSchema instance with added methods)
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import type { FluentLogEntry } from '../codegen/spanLoggerGenerator.js';
|
|
2
|
+
import type { OpContext } from '../opContext/types.js';
|
|
3
|
+
import type { SpanContext } from '../spanContext.js';
|
|
4
|
+
import type { FeatureFlagSchema } from './defineFeatureFlags.js';
|
|
5
|
+
import type { LogSchema } from './LogSchema.js';
|
|
6
|
+
/**
|
|
7
|
+
* Serializable flag value types
|
|
8
|
+
*/
|
|
9
|
+
export type FlagValue = string | number | boolean | null;
|
|
10
|
+
/**
|
|
11
|
+
* SpanContext without 'ff' field - prevents infinite recursion in evaluators
|
|
12
|
+
*/
|
|
13
|
+
export type SpanContextWithoutFf<Ctx extends OpContext> = Omit<SpanContext<Ctx>, 'ff'>;
|
|
14
|
+
/**
|
|
15
|
+
* Feature flag evaluator interface (backend implementation)
|
|
16
|
+
*
|
|
17
|
+
* This is implemented by the backend (database, LaunchDarkly, etc.)
|
|
18
|
+
* and provides the actual flag values.
|
|
19
|
+
*
|
|
20
|
+
* ## Stateless Design - ctx is a parameter
|
|
21
|
+
*
|
|
22
|
+
* The evaluator receives `Omit<SpanContext, 'ff'>` as a PARAMETER (not stored state).
|
|
23
|
+
* This allows the evaluator to:
|
|
24
|
+
* - Be stateless (CAN be a singleton, but doesn't have to be)
|
|
25
|
+
* - Access full context (ctx.log, ctx.span, ctx.scope, ctx.deps, user properties)
|
|
26
|
+
* - Prevent infinite recursion (can't access ctx.ff which would call evaluator again)
|
|
27
|
+
*
|
|
28
|
+
* ## forContext() - Flexible Wrapper Creation
|
|
29
|
+
*
|
|
30
|
+
* The evaluator decides how to create the per-span wrapper:
|
|
31
|
+
* - Return a new wrapper with `this` as the evaluator (most common - reuse evaluator)
|
|
32
|
+
* - Return `this` if the evaluator itself implements the wrapper interface
|
|
33
|
+
* - Return a completely different evaluator/wrapper (e.g., per-span caching)
|
|
34
|
+
*
|
|
35
|
+
* The wrapper (FeatureFlagEvaluator) holds a ctx reference to enable fluent getters.
|
|
36
|
+
*
|
|
37
|
+
* @template Ctx - OpContext bundle (contains flags via Ctx['flags'])
|
|
38
|
+
*/
|
|
39
|
+
export interface FlagEvaluator<Ctx extends OpContext = OpContext> {
|
|
40
|
+
/**
|
|
41
|
+
* Get a flag value synchronously (for cached/static flags)
|
|
42
|
+
*
|
|
43
|
+
* The evaluator receives ctx as a parameter (stateless design).
|
|
44
|
+
* Can use ctx.log/ctx.span for tracing, ctx.scope for targeting.
|
|
45
|
+
*
|
|
46
|
+
* @param ctx - SpanContext without 'ff' (can log, create spans, access scope)
|
|
47
|
+
* @param flag - Flag name to evaluate
|
|
48
|
+
*/
|
|
49
|
+
getSync<K extends string>(ctx: SpanContextWithoutFf<Ctx>, flag: K): FlagValue;
|
|
50
|
+
/**
|
|
51
|
+
* Get a flag value asynchronously (for dynamic flags)
|
|
52
|
+
*
|
|
53
|
+
* The evaluator receives ctx as a parameter (stateless design).
|
|
54
|
+
* Can use ctx.log/ctx.span for tracing external calls.
|
|
55
|
+
*
|
|
56
|
+
* @param ctx - SpanContext without 'ff' (can log, create spans, access scope)
|
|
57
|
+
* @param flag - Flag name to evaluate
|
|
58
|
+
*/
|
|
59
|
+
getAsync<K extends string>(ctx: SpanContextWithoutFf<Ctx>, flag: K): Promise<FlagValue>;
|
|
60
|
+
/**
|
|
61
|
+
* Factory method: Create per-span wrapper from span context.
|
|
62
|
+
*
|
|
63
|
+
* Returns a FeatureFlagEvaluator (per-span wrapper) with typed getters for each flag.
|
|
64
|
+
*
|
|
65
|
+
* ## Implementation Choices
|
|
66
|
+
*
|
|
67
|
+
* Common pattern: Return a new wrapper that holds `this` as the evaluator
|
|
68
|
+
* ```typescript
|
|
69
|
+
* forContext(ctx) {
|
|
70
|
+
* return new FeatureFlagEvaluator(schema, ctx, this); // Reuse evaluator, new wrapper
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* Alternative: Return `this` if evaluator implements the wrapper interface
|
|
75
|
+
* ```typescript
|
|
76
|
+
* forContext(ctx) {
|
|
77
|
+
* return this; // Evaluator itself is the wrapper (uncommon)
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* Alternative: Return different evaluator (e.g., per-span caching layer)
|
|
82
|
+
* ```typescript
|
|
83
|
+
* forContext(ctx) {
|
|
84
|
+
* return new CachedEvaluator(ctx, this); // Different wrapper with caching
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* The wrapper MUST store ctx because JS getters (`get darkMode()`) cannot receive parameters.
|
|
89
|
+
*
|
|
90
|
+
* Receives `Omit<SpanContext, 'ff'>` to prevent infinite recursion.
|
|
91
|
+
*/
|
|
92
|
+
forContext(ctx: SpanContextWithoutFf<Ctx>): FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Column writers interface (to be implemented in buffer phase)
|
|
96
|
+
*
|
|
97
|
+
* Used for logging flag access and usage to span buffers.
|
|
98
|
+
*/
|
|
99
|
+
export interface FlagColumnWriters {
|
|
100
|
+
writeEntryType(type: 'ff-access' | 'ff-usage'): void;
|
|
101
|
+
writeFfName(name: string): void;
|
|
102
|
+
writeFfValue(value: FlagValue): void;
|
|
103
|
+
writeAction(action?: string): void;
|
|
104
|
+
writeOutcome(outcome?: string): void;
|
|
105
|
+
writeContextAttributes(context: Record<string, unknown>): void;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Track context for feature flag usage analytics
|
|
109
|
+
*/
|
|
110
|
+
export interface FlagTrackContext {
|
|
111
|
+
action?: string;
|
|
112
|
+
outcome?: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Boolean flag context - returned when boolean flag is true
|
|
116
|
+
*/
|
|
117
|
+
export interface BooleanFlagContext<TLog extends LogSchema = LogSchema> {
|
|
118
|
+
readonly value: true;
|
|
119
|
+
track(context?: FlagTrackContext): FluentLogEntry<TLog>;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Variant flag context - returned when variant flag is enabled
|
|
123
|
+
*/
|
|
124
|
+
export interface VariantFlagContext<V extends string, TLog extends LogSchema = LogSchema> {
|
|
125
|
+
readonly value: V;
|
|
126
|
+
track(context?: FlagTrackContext): FluentLogEntry<TLog>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Config flag context - returned when config flag is enabled
|
|
130
|
+
* Spreads the config object and adds track() method
|
|
131
|
+
*/
|
|
132
|
+
export type ConfigFlagContext<T extends Record<string, unknown>, TLog extends LogSchema = LogSchema> = T & {
|
|
133
|
+
track(context?: FlagTrackContext): FluentLogEntry<TLog>;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Infer the flag context type for a single flag definition
|
|
137
|
+
*/
|
|
138
|
+
type InferFlagContextType<Ctx extends OpContext, T> = T extends boolean ? BooleanFlagContext<Ctx['logSchema']> : T extends string ? VariantFlagContext<T, Ctx['logSchema']> : T extends Record<string, unknown> ? ConfigFlagContext<T, Ctx['logSchema']> : {
|
|
139
|
+
value: T;
|
|
140
|
+
track(context?: FlagTrackContext): FluentLogEntry<Ctx['logSchema']>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Infer feature flag types from OpContext - returns FlagContext | undefined for each flag
|
|
144
|
+
*
|
|
145
|
+
* - Returns undefined when flag is false/disabled
|
|
146
|
+
* - Returns FlagContext wrapper when flag is truthy/enabled
|
|
147
|
+
*/
|
|
148
|
+
export type InferFeatureFlagsWithContext<Ctx extends OpContext> = Ctx['flags'] extends FeatureFlagSchema ? {
|
|
149
|
+
readonly [K in keyof Ctx['flags']]: InferFlagContextType<Ctx, import('@smoothbricks/arrow-builder').Output<Ctx['flags'][K]['schema']>> | undefined;
|
|
150
|
+
} : Record<string, never>;
|
|
151
|
+
/**
|
|
152
|
+
* Feature flag evaluator with undefined/truthy semantics (PER-SPAN WRAPPER)
|
|
153
|
+
*
|
|
154
|
+
* ## Architecture: Stateless Evaluator + Per-Span Wrapper
|
|
155
|
+
*
|
|
156
|
+
* ```
|
|
157
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
158
|
+
* │ FlagEvaluator (backend - CAN be singleton) │
|
|
159
|
+
* │ - getSync(ctx, flag) → FlagValue │
|
|
160
|
+
* │ - getAsync(ctx, flag) → Promise<FlagValue> │
|
|
161
|
+
* │ - forContext(ctx) → new FeatureFlagEvaluator(ctx, this) │
|
|
162
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
163
|
+
* ▲
|
|
164
|
+
* │ reference (can be reused or new)
|
|
165
|
+
* │
|
|
166
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
167
|
+
* │ FeatureFlagEvaluator (PER-SPAN - holds ctx reference) │
|
|
168
|
+
* │ #spanContext = ctx │
|
|
169
|
+
* │ #evaluator = backend evaluator │
|
|
170
|
+
* │ │
|
|
171
|
+
* │ get darkMode() { │
|
|
172
|
+
* │ return this.#getFlag('darkMode'); │
|
|
173
|
+
* │ // calls this.#evaluator.getSync(this.#spanContext, 'x') │
|
|
174
|
+
* │ } │
|
|
175
|
+
* │ │
|
|
176
|
+
* │ forContext(childCtx) { │
|
|
177
|
+
* │ // Reuse same evaluator, new wrapper with childCtx │
|
|
178
|
+
* │ return new FeatureFlagEvaluator(childCtx, this.#evaluator)│
|
|
179
|
+
* │ } │
|
|
180
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* ## Why Per-Span Wrapper?
|
|
184
|
+
*
|
|
185
|
+
* JS getters (`get darkMode()`) cannot receive parameters. To provide the fluent
|
|
186
|
+
* API `ctx.ff.darkMode`, we need to store the ctx reference in the wrapper instance.
|
|
187
|
+
*
|
|
188
|
+
* The backend evaluator (FlagEvaluator) receives ctx as a parameter, so it CAN be
|
|
189
|
+
* stateless/singleton. The wrapper is created per-span to bind ctx to getters.
|
|
190
|
+
*
|
|
191
|
+
* ## Behavior
|
|
192
|
+
*
|
|
193
|
+
* - Returns undefined when flag is false/disabled
|
|
194
|
+
* - Returns FlagContext wrapper when flag is truthy/enabled
|
|
195
|
+
* - First access logs ff-access entry
|
|
196
|
+
* - Subsequent access in same span returns cached value (no duplicate log)
|
|
197
|
+
* - track() always logs ff-usage entry
|
|
198
|
+
*
|
|
199
|
+
* ## V8 Optimization Benefits
|
|
200
|
+
*
|
|
201
|
+
* - Stable hidden class (all instances have same shape)
|
|
202
|
+
* - Monomorphic property access (getters are real properties)
|
|
203
|
+
* - No Proxy trap overhead
|
|
204
|
+
* - Inline caching works properly
|
|
205
|
+
*
|
|
206
|
+
* ## Generated Class Pattern
|
|
207
|
+
*
|
|
208
|
+
* The class constructor returns a generated class instance rather than this instance.
|
|
209
|
+
* This is a valid JavaScript pattern for creating optimized instances with schema-specific properties.
|
|
210
|
+
*
|
|
211
|
+
* @template Ctx - OpContext bundle (contains flags via Ctx['flags'])
|
|
212
|
+
*/
|
|
213
|
+
export declare abstract class FeatureFlagEvaluator<Ctx extends OpContext = OpContext> {
|
|
214
|
+
/**
|
|
215
|
+
* Get async flag value
|
|
216
|
+
* Returns undefined when false, FlagContext when truthy
|
|
217
|
+
*/
|
|
218
|
+
abstract get<K extends keyof InferFeatureFlagsWithContext<Ctx> & string>(flag: K): Promise<InferFeatureFlagsWithContext<Ctx>[K]>;
|
|
219
|
+
abstract get(flag: string): Promise<unknown>;
|
|
220
|
+
/**
|
|
221
|
+
* Create a new wrapper for a child span context.
|
|
222
|
+
*
|
|
223
|
+
* The implementation can reuse the same evaluator (singleton pattern),
|
|
224
|
+
* create a new evaluator, or return `this` if the evaluator itself
|
|
225
|
+
* implements the wrapper interface.
|
|
226
|
+
*/
|
|
227
|
+
abstract forContext(ctx: SpanContext<Ctx>): FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Create a FeatureFlagEvaluator instance using the generated class
|
|
231
|
+
*/
|
|
232
|
+
export declare function createFeatureFlagEvaluator<Ctx extends OpContext>(schema: Ctx['flags'], spanContext: SpanContextWithoutFf<Ctx>, evaluator: FlagEvaluator<Ctx>): FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
|
|
233
|
+
/**
|
|
234
|
+
* Simple in-memory flag evaluator for testing
|
|
235
|
+
*
|
|
236
|
+
* Demonstrates the simplest evaluator pattern:
|
|
237
|
+
* - getSync/getAsync receive ctx first, enabling evaluators to use ctx.log, ctx.scope
|
|
238
|
+
* - forContext bootstraps the generated FeatureFlagEvaluator class (creates per-span wrapper)
|
|
239
|
+
* - Generated class has typed getters (ff.darkMode) and calls this.getSync(ctx, flag)
|
|
240
|
+
*/
|
|
241
|
+
export declare class InMemoryFlagEvaluator<Ctx extends OpContext = OpContext> implements FlagEvaluator<Ctx> {
|
|
242
|
+
private flags;
|
|
243
|
+
private ffSchema;
|
|
244
|
+
constructor(ffSchema: Ctx['flags'], initialFlags?: Record<string, FlagValue>);
|
|
245
|
+
/**
|
|
246
|
+
* Get flag value synchronously.
|
|
247
|
+
* Simple evaluator ignores ctx - just returns stored value.
|
|
248
|
+
* Advanced evaluators can use ctx.log, ctx.span, ctx.scope, etc.
|
|
249
|
+
*/
|
|
250
|
+
getSync<K extends string>(_ctx: SpanContextWithoutFf<Ctx>, flag: K): FlagValue;
|
|
251
|
+
/**
|
|
252
|
+
* Get flag value asynchronously.
|
|
253
|
+
* Simple evaluator ignores ctx - just returns stored value.
|
|
254
|
+
* Advanced evaluators can use ctx.log, ctx.span for tracing external calls.
|
|
255
|
+
*/
|
|
256
|
+
getAsync<K extends string>(_ctx: SpanContextWithoutFf<Ctx>, flag: K): Promise<FlagValue>;
|
|
257
|
+
setFlag(flag: string, value: FlagValue): void;
|
|
258
|
+
/**
|
|
259
|
+
* Create span-bound FeatureFlagEvaluator with typed getters.
|
|
260
|
+
*
|
|
261
|
+
* Returns a per-span wrapper that holds ctx reference and reuses this evaluator.
|
|
262
|
+
* The generated class has typed getters (ff.darkMode) and calls this.getSync(ctx, flag).
|
|
263
|
+
*/
|
|
264
|
+
forContext(ctx: SpanContextWithoutFf<Ctx>): FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
|
|
265
|
+
}
|
|
266
|
+
export {};
|
|
267
|
+
//# sourceMappingURL=evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../../src/lib/schema/evaluator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { createEvaluatorClass } from '../codegen/evaluatorGenerator.js';
|
|
2
|
+
import { ENTRY_TYPE_FF_ACCESS } from './systemSchema.js';
|
|
3
|
+
function validateFlagValue(value, schema, defaultValue) {
|
|
4
|
+
const meta = schema;
|
|
5
|
+
// Handle refine() schemas — invoke the stored refiner, fall back to default on failure
|
|
6
|
+
if (meta.__refiner) {
|
|
7
|
+
try {
|
|
8
|
+
return meta.__refiner(value, {
|
|
9
|
+
fail(msg) {
|
|
10
|
+
throw new Error(msg);
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return defaultValue;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
switch (meta.__schema_type) {
|
|
19
|
+
case 'number':
|
|
20
|
+
return typeof value === 'number' ? value : defaultValue;
|
|
21
|
+
case 'boolean':
|
|
22
|
+
return typeof value === 'boolean' ? value : defaultValue;
|
|
23
|
+
case 'text':
|
|
24
|
+
case 'category':
|
|
25
|
+
return typeof value === 'string' ? value : defaultValue;
|
|
26
|
+
case 'enum':
|
|
27
|
+
if (typeof value !== 'string')
|
|
28
|
+
return defaultValue;
|
|
29
|
+
if (meta.__enum_values && !meta.__enum_values.includes(value))
|
|
30
|
+
return defaultValue;
|
|
31
|
+
return value;
|
|
32
|
+
case 'bigUint64':
|
|
33
|
+
return typeof value === 'bigint' ? value : defaultValue;
|
|
34
|
+
case 'key':
|
|
35
|
+
// Key schema in feature flags — validate it's a string
|
|
36
|
+
return typeof value === 'string' ? value : defaultValue;
|
|
37
|
+
default:
|
|
38
|
+
// Unknown schema type — reject by returning the default value.
|
|
39
|
+
// This prevents silently accepting invalid data for unhandled schema types.
|
|
40
|
+
return defaultValue;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Feature Flag Evaluator Class
|
|
45
|
+
// ============================================================================
|
|
46
|
+
/**
|
|
47
|
+
* Get or create a generated evaluator class for a schema.
|
|
48
|
+
*
|
|
49
|
+
* The worker-safe constructor cache lives in `evaluatorGenerator.ts`.
|
|
50
|
+
*/
|
|
51
|
+
function getOrCreateEvaluatorClass(schema) {
|
|
52
|
+
return createEvaluatorClass(schema, validateFlagValue, ENTRY_TYPE_FF_ACCESS);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Feature flag evaluator with undefined/truthy semantics (PER-SPAN WRAPPER)
|
|
56
|
+
*
|
|
57
|
+
* ## Architecture: Stateless Evaluator + Per-Span Wrapper
|
|
58
|
+
*
|
|
59
|
+
* ```
|
|
60
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
61
|
+
* │ FlagEvaluator (backend - CAN be singleton) │
|
|
62
|
+
* │ - getSync(ctx, flag) → FlagValue │
|
|
63
|
+
* │ - getAsync(ctx, flag) → Promise<FlagValue> │
|
|
64
|
+
* │ - forContext(ctx) → new FeatureFlagEvaluator(ctx, this) │
|
|
65
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
66
|
+
* ▲
|
|
67
|
+
* │ reference (can be reused or new)
|
|
68
|
+
* │
|
|
69
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
70
|
+
* │ FeatureFlagEvaluator (PER-SPAN - holds ctx reference) │
|
|
71
|
+
* │ #spanContext = ctx │
|
|
72
|
+
* │ #evaluator = backend evaluator │
|
|
73
|
+
* │ │
|
|
74
|
+
* │ get darkMode() { │
|
|
75
|
+
* │ return this.#getFlag('darkMode'); │
|
|
76
|
+
* │ // calls this.#evaluator.getSync(this.#spanContext, 'x') │
|
|
77
|
+
* │ } │
|
|
78
|
+
* │ │
|
|
79
|
+
* │ forContext(childCtx) { │
|
|
80
|
+
* │ // Reuse same evaluator, new wrapper with childCtx │
|
|
81
|
+
* │ return new FeatureFlagEvaluator(childCtx, this.#evaluator)│
|
|
82
|
+
* │ } │
|
|
83
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* ## Why Per-Span Wrapper?
|
|
87
|
+
*
|
|
88
|
+
* JS getters (`get darkMode()`) cannot receive parameters. To provide the fluent
|
|
89
|
+
* API `ctx.ff.darkMode`, we need to store the ctx reference in the wrapper instance.
|
|
90
|
+
*
|
|
91
|
+
* The backend evaluator (FlagEvaluator) receives ctx as a parameter, so it CAN be
|
|
92
|
+
* stateless/singleton. The wrapper is created per-span to bind ctx to getters.
|
|
93
|
+
*
|
|
94
|
+
* ## Behavior
|
|
95
|
+
*
|
|
96
|
+
* - Returns undefined when flag is false/disabled
|
|
97
|
+
* - Returns FlagContext wrapper when flag is truthy/enabled
|
|
98
|
+
* - First access logs ff-access entry
|
|
99
|
+
* - Subsequent access in same span returns cached value (no duplicate log)
|
|
100
|
+
* - track() always logs ff-usage entry
|
|
101
|
+
*
|
|
102
|
+
* ## V8 Optimization Benefits
|
|
103
|
+
*
|
|
104
|
+
* - Stable hidden class (all instances have same shape)
|
|
105
|
+
* - Monomorphic property access (getters are real properties)
|
|
106
|
+
* - No Proxy trap overhead
|
|
107
|
+
* - Inline caching works properly
|
|
108
|
+
*
|
|
109
|
+
* ## Generated Class Pattern
|
|
110
|
+
*
|
|
111
|
+
* The class constructor returns a generated class instance rather than this instance.
|
|
112
|
+
* This is a valid JavaScript pattern for creating optimized instances with schema-specific properties.
|
|
113
|
+
*
|
|
114
|
+
* @template Ctx - OpContext bundle (contains flags via Ctx['flags'])
|
|
115
|
+
*/
|
|
116
|
+
export class FeatureFlagEvaluator {
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Create a FeatureFlagEvaluator instance using the generated class
|
|
120
|
+
*/
|
|
121
|
+
export function createFeatureFlagEvaluator(schema, spanContext, evaluator) {
|
|
122
|
+
const GeneratedClass = getOrCreateEvaluatorClass(schema);
|
|
123
|
+
const instance = new GeneratedClass(spanContext, evaluator);
|
|
124
|
+
return instance;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Simple in-memory flag evaluator for testing
|
|
128
|
+
*
|
|
129
|
+
* Demonstrates the simplest evaluator pattern:
|
|
130
|
+
* - getSync/getAsync receive ctx first, enabling evaluators to use ctx.log, ctx.scope
|
|
131
|
+
* - forContext bootstraps the generated FeatureFlagEvaluator class (creates per-span wrapper)
|
|
132
|
+
* - Generated class has typed getters (ff.darkMode) and calls this.getSync(ctx, flag)
|
|
133
|
+
*/
|
|
134
|
+
export class InMemoryFlagEvaluator {
|
|
135
|
+
flags = {};
|
|
136
|
+
ffSchema;
|
|
137
|
+
constructor(ffSchema, initialFlags = {}) {
|
|
138
|
+
this.ffSchema = ffSchema;
|
|
139
|
+
this.flags = initialFlags;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get flag value synchronously.
|
|
143
|
+
* Simple evaluator ignores ctx - just returns stored value.
|
|
144
|
+
* Advanced evaluators can use ctx.log, ctx.span, ctx.scope, etc.
|
|
145
|
+
*/
|
|
146
|
+
getSync(_ctx, flag) {
|
|
147
|
+
return this.flags[flag] ?? null;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get flag value asynchronously.
|
|
151
|
+
* Simple evaluator ignores ctx - just returns stored value.
|
|
152
|
+
* Advanced evaluators can use ctx.log, ctx.span for tracing external calls.
|
|
153
|
+
*/
|
|
154
|
+
async getAsync(_ctx, flag) {
|
|
155
|
+
return this.flags[flag] ?? null;
|
|
156
|
+
}
|
|
157
|
+
setFlag(flag, value) {
|
|
158
|
+
this.flags[flag] = value;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Create span-bound FeatureFlagEvaluator with typed getters.
|
|
162
|
+
*
|
|
163
|
+
* Returns a per-span wrapper that holds ctx reference and reuses this evaluator.
|
|
164
|
+
* The generated class has typed getters (ff.darkMode) and calls this.getSync(ctx, flag).
|
|
165
|
+
*/
|
|
166
|
+
forContext(ctx) {
|
|
167
|
+
return createFeatureFlagEvaluator(this.ffSchema, ctx, this);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema extension utilities for composing tag attribute schemas
|
|
3
|
+
*
|
|
4
|
+
* This enables building complex schemas from smaller, reusable pieces:
|
|
5
|
+
* - Base attributes (requestId, userId, etc.)
|
|
6
|
+
* - HTTP-specific attributes (httpStatus, httpMethod, etc.)
|
|
7
|
+
* - Database-specific attributes (dbQuery, dbDuration, etc.)
|
|
8
|
+
* - Custom domain attributes
|
|
9
|
+
*/
|
|
10
|
+
import { LogSchema } from './LogSchema.js';
|
|
11
|
+
import type { SchemaFields } from './types.js';
|
|
12
|
+
export declare function extendSchema<T extends SchemaFields, U extends SchemaFields>(base: LogSchema<T>, extension: U): LogSchema<T & U>;
|
|
13
|
+
export declare function extendSchema<T extends SchemaFields, U extends SchemaFields>(base: T, extension: U): T & U;
|
|
14
|
+
//# sourceMappingURL=extend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../../../src/lib/schema/extend.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,YAAY,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,YAAY,EACzE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAClB,SAAS,EAAE,CAAC,GACX,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACpB,wBAAgB,YAAY,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,YAAY,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC"}
|