@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,934 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for Library Integration Pattern and Module Builder Pattern
|
|
3
|
+
*
|
|
4
|
+
* Tests specs/lmao/01e_library_integration_pattern.md and specs/lmao/01l_op_context_pattern.md
|
|
5
|
+
* - Module definition with defineModule()
|
|
6
|
+
* - Prefix application for library composition
|
|
7
|
+
* - Dependency wiring with .use()
|
|
8
|
+
* - Clean API with prefixed column storage
|
|
9
|
+
* - RemappedBufferView for Arrow conversion
|
|
10
|
+
* - Collision detection and type safety
|
|
11
|
+
* - Library composition scenarios
|
|
12
|
+
* - End-to-end integration verification
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { describe, expect, it } from 'bun:test';
|
|
16
|
+
import { defineOpContext } from '../defineOpContext.js';
|
|
17
|
+
import {
|
|
18
|
+
createPrefixMapping,
|
|
19
|
+
createRemappedSpanLoggerClass,
|
|
20
|
+
generateRemappedBufferViewClass,
|
|
21
|
+
generateRemappedSpanLoggerClass,
|
|
22
|
+
type PrefixMapping,
|
|
23
|
+
prefixSchema,
|
|
24
|
+
} from '../library.js';
|
|
25
|
+
import { S } from '../schema/builder.js';
|
|
26
|
+
import { defineLogSchema } from '../schema/defineLogSchema.js';
|
|
27
|
+
import { createBuffer, getMappedOpGroupInternals, getOpGroupInternals } from './test-helpers.js';
|
|
28
|
+
|
|
29
|
+
describe('Library Integration Pattern', () => {
|
|
30
|
+
describe('Schema Prefixing', () => {
|
|
31
|
+
it('should prefix all field names in schema', () => {
|
|
32
|
+
const schema = defineLogSchema({
|
|
33
|
+
status: S.number(),
|
|
34
|
+
method: S.enum(['GET', 'POST']),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const prefixed = prefixSchema(schema, 'http');
|
|
38
|
+
|
|
39
|
+
expect(prefixed).toHaveProperty('http_status');
|
|
40
|
+
expect(prefixed).toHaveProperty('http_method');
|
|
41
|
+
expect(prefixed).not.toHaveProperty('status');
|
|
42
|
+
expect(prefixed).not.toHaveProperty('method');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should preserve schema metadata during prefixing', () => {
|
|
46
|
+
const schema = defineLogSchema({
|
|
47
|
+
operation: S.enum(['CREATE', 'DELETE']),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const prefixed = prefixSchema(schema, 'db');
|
|
51
|
+
const dbOperation = prefixed.db_operation;
|
|
52
|
+
|
|
53
|
+
if (typeof dbOperation !== 'object' || dbOperation === null) {
|
|
54
|
+
throw new Error('Expected prefixed db_operation metadata to be an object');
|
|
55
|
+
}
|
|
56
|
+
expect(dbOperation).toHaveProperty('__schema_type', 'enum');
|
|
57
|
+
expect(dbOperation).toHaveProperty('__enum_values');
|
|
58
|
+
expect(Reflect.get(dbOperation, '__enum_values')).toEqual(['CREATE', 'DELETE']);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should create correct prefix mapping', () => {
|
|
62
|
+
const schema = defineLogSchema({
|
|
63
|
+
status: S.number(),
|
|
64
|
+
method: S.category(),
|
|
65
|
+
url: S.text(),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const mapping = createPrefixMapping(schema, 'http');
|
|
69
|
+
|
|
70
|
+
expect(mapping).toEqual({
|
|
71
|
+
status: 'http_status',
|
|
72
|
+
method: 'http_method',
|
|
73
|
+
url: 'http_url',
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should handle empty schema', () => {
|
|
78
|
+
const schema = defineLogSchema({});
|
|
79
|
+
const mapping = createPrefixMapping(schema, 'test');
|
|
80
|
+
|
|
81
|
+
expect(mapping).toEqual({});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should handle complex schema types with prefixing', () => {
|
|
85
|
+
const schema = defineLogSchema({
|
|
86
|
+
enumField: S.enum(['A', 'B', 'C']),
|
|
87
|
+
categoryField: S.category(),
|
|
88
|
+
textField: S.text(),
|
|
89
|
+
numberField: S.number(),
|
|
90
|
+
booleanField: S.boolean(),
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const prefixed = prefixSchema(schema, 'test');
|
|
94
|
+
|
|
95
|
+
// All fields should be prefixed
|
|
96
|
+
expect(prefixed).toHaveProperty('test_enumField');
|
|
97
|
+
expect(prefixed).toHaveProperty('test_categoryField');
|
|
98
|
+
expect(prefixed).toHaveProperty('test_textField');
|
|
99
|
+
expect(prefixed).toHaveProperty('test_numberField');
|
|
100
|
+
expect(prefixed).toHaveProperty('test_booleanField');
|
|
101
|
+
|
|
102
|
+
// Metadata should be preserved
|
|
103
|
+
expect(prefixed.test_enumField).toHaveProperty('__schema_type', 'enum');
|
|
104
|
+
expect(prefixed.test_categoryField).toHaveProperty('__schema_type', 'category');
|
|
105
|
+
expect(prefixed.test_textField).toHaveProperty('__schema_type', 'text');
|
|
106
|
+
expect(prefixed.test_numberField).toHaveProperty('__schema_type', 'number');
|
|
107
|
+
expect(prefixed.test_booleanField).toHaveProperty('__schema_type', 'boolean');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should handle special characters in prefix', () => {
|
|
111
|
+
const schema = defineLogSchema({
|
|
112
|
+
field: S.text(),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const prefixed = prefixSchema(schema, 'prefix-with-dashes');
|
|
116
|
+
|
|
117
|
+
expect(prefixed).toHaveProperty('prefix-with-dashes_field');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should handle schema with many fields', () => {
|
|
121
|
+
const schemaFields: Record<string, ReturnType<typeof S.number>> = {};
|
|
122
|
+
for (let i = 0; i < 100; i++) {
|
|
123
|
+
schemaFields[`field${i}`] = S.number();
|
|
124
|
+
}
|
|
125
|
+
const schema = defineLogSchema(schemaFields);
|
|
126
|
+
|
|
127
|
+
const prefixed = prefixSchema(schema, 'many');
|
|
128
|
+
|
|
129
|
+
expect(prefixed._columnNames.length).toBe(100);
|
|
130
|
+
expect(prefixed).toHaveProperty('many_field0');
|
|
131
|
+
expect(prefixed).toHaveProperty('many_field99');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe('RemappedBufferView Generation', () => {
|
|
136
|
+
it('should generate valid RemappedBufferView class', () => {
|
|
137
|
+
const mapping: Record<string, string> = {
|
|
138
|
+
http_status: 'status',
|
|
139
|
+
http_method: 'method',
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const ViewClass = generateRemappedBufferViewClass(mapping);
|
|
143
|
+
|
|
144
|
+
// Should create a callable constructor
|
|
145
|
+
expect(typeof ViewClass).toBe('function');
|
|
146
|
+
|
|
147
|
+
// Should cache same mapping
|
|
148
|
+
const ViewClass2 = generateRemappedBufferViewClass(mapping);
|
|
149
|
+
expect(ViewClass).toBe(ViewClass2); // Same cached instance
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should handle empty prefix mapping', () => {
|
|
153
|
+
const mapping: Record<string, string> = {};
|
|
154
|
+
const ViewClass = generateRemappedBufferViewClass(mapping);
|
|
155
|
+
|
|
156
|
+
expect(typeof ViewClass).toBe('function');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should handle single field mapping', () => {
|
|
160
|
+
const mapping: Record<string, string> = {
|
|
161
|
+
http_status: 'status',
|
|
162
|
+
};
|
|
163
|
+
const ViewClass = generateRemappedBufferViewClass(mapping);
|
|
164
|
+
|
|
165
|
+
expect(typeof ViewClass).toBe('function');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should correctly map column access from prefixed to unprefixed', () => {
|
|
169
|
+
const mapping: Record<string, string> = {
|
|
170
|
+
http_status: 'status',
|
|
171
|
+
http_method: 'method',
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const ViewClass = generateRemappedBufferViewClass(mapping);
|
|
175
|
+
|
|
176
|
+
const mockBuffer = createBuffer(
|
|
177
|
+
defineLogSchema({
|
|
178
|
+
status: S.number(),
|
|
179
|
+
method: S.category(),
|
|
180
|
+
}),
|
|
181
|
+
);
|
|
182
|
+
mockBuffer.status(0, 200);
|
|
183
|
+
mockBuffer._writeIndex = 1;
|
|
184
|
+
|
|
185
|
+
const mockValues = mockBuffer.getColumnIfAllocated('status');
|
|
186
|
+
const mockNulls = mockBuffer.getNullsIfAllocated('status');
|
|
187
|
+
|
|
188
|
+
const view = new ViewClass(mockBuffer);
|
|
189
|
+
|
|
190
|
+
// Should map prefixed to unprefixed
|
|
191
|
+
expect(view.getColumnIfAllocated('http_status')).toBe(mockValues);
|
|
192
|
+
expect(view.getNullsIfAllocated('http_status')).toBe(mockNulls);
|
|
193
|
+
|
|
194
|
+
// Should pass through unknown names
|
|
195
|
+
expect(view.getColumnIfAllocated('unknown')).toBeUndefined();
|
|
196
|
+
expect(view.getNullsIfAllocated('unknown')).toBeUndefined();
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
describe('RemappedSpanLogger Generation', () => {
|
|
201
|
+
it('should generate valid JavaScript code', () => {
|
|
202
|
+
const schema = defineLogSchema({
|
|
203
|
+
status: S.number(),
|
|
204
|
+
method: S.enum(['GET', 'POST']),
|
|
205
|
+
});
|
|
206
|
+
const mapping: PrefixMapping = {
|
|
207
|
+
status: 'http_status',
|
|
208
|
+
method: 'http_method',
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const code = generateRemappedSpanLoggerClass(schema, mapping);
|
|
212
|
+
|
|
213
|
+
// Should be valid JavaScript
|
|
214
|
+
expect(() => new Function(`return ${code}`)()).not.toThrow();
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should generate class with clean method names', () => {
|
|
218
|
+
const schema = defineLogSchema({
|
|
219
|
+
status: S.number(),
|
|
220
|
+
duration: S.number(),
|
|
221
|
+
});
|
|
222
|
+
const mapping: PrefixMapping = {
|
|
223
|
+
status: 'http_status',
|
|
224
|
+
duration: 'http_duration',
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const code = generateRemappedSpanLoggerClass(schema, mapping);
|
|
228
|
+
|
|
229
|
+
// Should contain clean method names
|
|
230
|
+
expect(code).toContain('status(value)');
|
|
231
|
+
expect(code).toContain('duration(value)');
|
|
232
|
+
// Should reference prefixed columns
|
|
233
|
+
expect(code).toContain('http_status');
|
|
234
|
+
expect(code).toContain('http_duration');
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('should include enum mapping functions', () => {
|
|
238
|
+
const schema = defineLogSchema({
|
|
239
|
+
method: S.enum(['GET', 'POST', 'PUT']),
|
|
240
|
+
});
|
|
241
|
+
const mapping: PrefixMapping = {
|
|
242
|
+
method: 'http_method',
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const code = generateRemappedSpanLoggerClass(schema, mapping);
|
|
246
|
+
|
|
247
|
+
// Should contain enum mapping function
|
|
248
|
+
expect(code).toContain('getEnumIndex_method');
|
|
249
|
+
expect(code).toContain('case "GET"');
|
|
250
|
+
expect(code).toContain('case "POST"');
|
|
251
|
+
expect(code).toContain('case "PUT"');
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('should include prefix mapping for with() method', () => {
|
|
255
|
+
const schema = defineLogSchema({
|
|
256
|
+
status: S.number(),
|
|
257
|
+
});
|
|
258
|
+
const mapping: PrefixMapping = {
|
|
259
|
+
status: 'http_status',
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const code = generateRemappedSpanLoggerClass(schema, mapping);
|
|
263
|
+
|
|
264
|
+
// Should include PREFIX_MAPPING constant
|
|
265
|
+
expect(code).toContain('PREFIX_MAPPING');
|
|
266
|
+
expect(code).toContain('"status":"http_status"');
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('should create a class constructor', () => {
|
|
270
|
+
const schema = defineLogSchema({
|
|
271
|
+
status: S.number(),
|
|
272
|
+
});
|
|
273
|
+
const mapping: PrefixMapping = {
|
|
274
|
+
status: 'http_status',
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const SpanLoggerClass = createRemappedSpanLoggerClass(schema, mapping);
|
|
278
|
+
|
|
279
|
+
expect(typeof SpanLoggerClass).toBe('function');
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('should handle all field types in code generation', () => {
|
|
283
|
+
const schema = defineLogSchema({
|
|
284
|
+
enumField: S.enum(['A', 'B']),
|
|
285
|
+
categoryField: S.category(),
|
|
286
|
+
textField: S.text(),
|
|
287
|
+
numberField: S.number(),
|
|
288
|
+
booleanField: S.boolean(),
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
const mapping: PrefixMapping = {
|
|
292
|
+
enumField: 'test_enumField',
|
|
293
|
+
categoryField: 'test_categoryField',
|
|
294
|
+
textField: 'test_textField',
|
|
295
|
+
numberField: 'test_numberField',
|
|
296
|
+
booleanField: 'test_booleanField',
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const code = generateRemappedSpanLoggerClass(schema, mapping);
|
|
300
|
+
|
|
301
|
+
// Should handle all field types appropriately
|
|
302
|
+
expect(code).toContain('getEnumIndex_enumField'); // Enum mapping
|
|
303
|
+
expect(code).toContain('categoryField(value)'); // Category storage
|
|
304
|
+
expect(code).toContain('textField(value)'); // Text storage
|
|
305
|
+
expect(code).toContain('numberField(value)'); // Number storage
|
|
306
|
+
expect(code).toContain('booleanField(value)'); // Boolean storage
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('should cache generated classes for the same schema and mapping', () => {
|
|
310
|
+
const schema = defineLogSchema({
|
|
311
|
+
status: S.number(),
|
|
312
|
+
});
|
|
313
|
+
const mapping: PrefixMapping = {
|
|
314
|
+
status: 'http_status',
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const Class1 = createRemappedSpanLoggerClass(schema, mapping);
|
|
318
|
+
const Class2 = createRemappedSpanLoggerClass(schema, mapping);
|
|
319
|
+
|
|
320
|
+
// Same schema + mapping should return cached class
|
|
321
|
+
expect(Class1).toBe(Class2);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should create different classes for different schemas', () => {
|
|
325
|
+
const schema1 = defineLogSchema({ status: S.number() });
|
|
326
|
+
const schema2 = defineLogSchema({ code: S.number() });
|
|
327
|
+
const mapping1: PrefixMapping = { status: 'http_status' };
|
|
328
|
+
const mapping2: PrefixMapping = { code: 'http_code' };
|
|
329
|
+
|
|
330
|
+
const Class1 = createRemappedSpanLoggerClass(schema1, mapping1);
|
|
331
|
+
const Class2 = createRemappedSpanLoggerClass(schema2, mapping2);
|
|
332
|
+
|
|
333
|
+
expect(Class1).not.toBe(Class2);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('should create different classes for same schema with different mappings', () => {
|
|
337
|
+
const schema = defineLogSchema({ status: S.number() });
|
|
338
|
+
const mapping1: PrefixMapping = { status: 'http_status' };
|
|
339
|
+
const mapping2: PrefixMapping = { status: 'api_status' };
|
|
340
|
+
|
|
341
|
+
const Class1 = createRemappedSpanLoggerClass(schema, mapping1);
|
|
342
|
+
const Class2 = createRemappedSpanLoggerClass(schema, mapping2);
|
|
343
|
+
|
|
344
|
+
expect(Class1).not.toBe(Class2);
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
describe('Module Builder Pattern Integration', () => {
|
|
350
|
+
// Helper function to create test OpGroups
|
|
351
|
+
const createHttpOpGroup = () => {
|
|
352
|
+
const { defineOps } = defineOpContext({
|
|
353
|
+
logSchema: defineLogSchema({
|
|
354
|
+
status: S.number(),
|
|
355
|
+
method: S.enum(['GET', 'POST', 'PUT', 'DELETE']),
|
|
356
|
+
url: S.text(),
|
|
357
|
+
duration: S.number(),
|
|
358
|
+
}),
|
|
359
|
+
});
|
|
360
|
+
return defineOps({});
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const createDbOpGroup = () => {
|
|
364
|
+
const { defineOps } = defineOpContext({
|
|
365
|
+
logSchema: defineLogSchema({
|
|
366
|
+
query: S.text(),
|
|
367
|
+
duration: S.number(),
|
|
368
|
+
rows: S.number(),
|
|
369
|
+
}),
|
|
370
|
+
});
|
|
371
|
+
return defineOps({});
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
const createRetryOpGroup = () => {
|
|
375
|
+
const { defineOps } = defineOpContext({
|
|
376
|
+
logSchema: defineLogSchema({
|
|
377
|
+
attempt: S.number(),
|
|
378
|
+
delay: S.number(),
|
|
379
|
+
}),
|
|
380
|
+
});
|
|
381
|
+
return defineOps({});
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
describe('OpGroup Definition and Schema Access', () => {
|
|
385
|
+
it('should define OpGroups with schemas', () => {
|
|
386
|
+
const { defineOps } = defineOpContext({
|
|
387
|
+
logSchema: defineLogSchema({
|
|
388
|
+
userId: S.category(),
|
|
389
|
+
endpoint: S.category(),
|
|
390
|
+
}),
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const appOpGroup = defineOps({});
|
|
394
|
+
|
|
395
|
+
expect(getOpGroupInternals(appOpGroup)._logSchema._columnNames).toContain('userId');
|
|
396
|
+
expect(getOpGroupInternals(appOpGroup)._logSchema._columnNames).toContain('endpoint');
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it('should provide access to OpGroup schema', () => {
|
|
400
|
+
const httpOpGroup = createHttpOpGroup();
|
|
401
|
+
|
|
402
|
+
// Test direct schema access
|
|
403
|
+
expect(getOpGroupInternals(httpOpGroup)._logSchema._columnNames).toContain('status');
|
|
404
|
+
expect(getOpGroupInternals(httpOpGroup)._logSchema._columnNames).toContain('method');
|
|
405
|
+
expect(getOpGroupInternals(httpOpGroup)._logSchema._columnNames).toContain('url');
|
|
406
|
+
expect(getOpGroupInternals(httpOpGroup)._logSchema._columnNames).toContain('duration');
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('should handle complex schema types', () => {
|
|
410
|
+
const { defineOps } = defineOpContext({
|
|
411
|
+
logSchema: defineLogSchema({
|
|
412
|
+
enumField: S.enum(['A', 'B']),
|
|
413
|
+
categoryField: S.category(),
|
|
414
|
+
textField: S.text(),
|
|
415
|
+
numberField: S.number(),
|
|
416
|
+
booleanField: S.boolean(),
|
|
417
|
+
}),
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const complexOpGroup = defineOps({});
|
|
421
|
+
|
|
422
|
+
expect(getOpGroupInternals(complexOpGroup)._logSchema._columnNames).toContain('enumField');
|
|
423
|
+
expect(getOpGroupInternals(complexOpGroup)._logSchema._columnNames).toContain('categoryField');
|
|
424
|
+
expect(getOpGroupInternals(complexOpGroup)._logSchema._columnNames).toContain('textField');
|
|
425
|
+
expect(getOpGroupInternals(complexOpGroup)._logSchema._columnNames).toContain('numberField');
|
|
426
|
+
expect(getOpGroupInternals(complexOpGroup)._logSchema._columnNames).toContain('booleanField');
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
it('should reject op names starting with underscore', () => {
|
|
430
|
+
const { defineOps } = defineOpContext({
|
|
431
|
+
logSchema: defineLogSchema({ field: S.category() }),
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
expect(() =>
|
|
435
|
+
defineOps({
|
|
436
|
+
_privateOp: async (ctx) => ctx.ok({}),
|
|
437
|
+
}),
|
|
438
|
+
).toThrow('Op name "_privateOp" cannot start with underscore');
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
it('should reject reserved op names', () => {
|
|
442
|
+
const { defineOps } = defineOpContext({
|
|
443
|
+
logSchema: defineLogSchema({ field: S.category() }),
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
expect(() =>
|
|
447
|
+
defineOps({
|
|
448
|
+
prefix: async (ctx) => ctx.ok({}),
|
|
449
|
+
}),
|
|
450
|
+
).toThrow('Op name "prefix" is reserved');
|
|
451
|
+
|
|
452
|
+
expect(() =>
|
|
453
|
+
defineOps({
|
|
454
|
+
mapColumns: async (ctx) => ctx.ok({}),
|
|
455
|
+
}),
|
|
456
|
+
).toThrow('Op name "mapColumns" is reserved');
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it('should allow valid op names', () => {
|
|
460
|
+
const { defineOps } = defineOpContext({
|
|
461
|
+
logSchema: defineLogSchema({ field: S.category() }),
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// These should NOT throw
|
|
465
|
+
const opGroup = defineOps({
|
|
466
|
+
doSomething: async (ctx) => ctx.ok({}),
|
|
467
|
+
anotherOp: async (ctx) => ctx.ok({}),
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
expect(opGroup).toBeDefined();
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
describe('Prefix Application', () => {
|
|
475
|
+
it('should apply prefix to OpGroup schema', () => {
|
|
476
|
+
const httpOpGroup = createHttpOpGroup();
|
|
477
|
+
const prefixedHttpOpGroup = httpOpGroup.prefix('http');
|
|
478
|
+
|
|
479
|
+
// Original schema should have unprefixed names
|
|
480
|
+
expect(getOpGroupInternals(httpOpGroup)._logSchema._columnNames).toContain('status');
|
|
481
|
+
expect(getOpGroupInternals(httpOpGroup)._logSchema._columnNames).toContain('method');
|
|
482
|
+
|
|
483
|
+
// Verify that prefix was applied (check mapping)
|
|
484
|
+
expect(getMappedOpGroupInternals(prefixedHttpOpGroup)._columnMapping.status).toBe('http_status');
|
|
485
|
+
expect(getMappedOpGroupInternals(prefixedHttpOpGroup)._columnMapping.method).toBe('http_method');
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
it('should support prefix chaining', () => {
|
|
489
|
+
const httpOpGroup = createHttpOpGroup();
|
|
490
|
+
const doublePrefixed = httpOpGroup.prefix('api').prefix('v1');
|
|
491
|
+
|
|
492
|
+
// Verify both prefixes are in the mapping
|
|
493
|
+
expect(getMappedOpGroupInternals(doublePrefixed)._columnMapping.status).toBe('v1_api_status');
|
|
494
|
+
expect(getMappedOpGroupInternals(doublePrefixed)._columnMapping.method).toBe('v1_api_method');
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it('should handle different field types with prefixing', () => {
|
|
498
|
+
const { defineOps } = defineOpContext({
|
|
499
|
+
logSchema: defineLogSchema({
|
|
500
|
+
enumField: S.enum(['A', 'B']),
|
|
501
|
+
categoryField: S.category(),
|
|
502
|
+
textField: S.text(),
|
|
503
|
+
numberField: S.number(),
|
|
504
|
+
booleanField: S.boolean(),
|
|
505
|
+
}),
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
const complexOpGroup = defineOps({});
|
|
509
|
+
const prefixed = complexOpGroup.prefix('complex');
|
|
510
|
+
|
|
511
|
+
// Verify all field types are mapped with prefix
|
|
512
|
+
expect(getMappedOpGroupInternals(prefixed)._columnMapping.enumField).toBe('complex_enumField');
|
|
513
|
+
expect(getMappedOpGroupInternals(prefixed)._columnMapping.categoryField).toBe('complex_categoryField');
|
|
514
|
+
expect(getMappedOpGroupInternals(prefixed)._columnMapping.textField).toBe('complex_textField');
|
|
515
|
+
expect(getMappedOpGroupInternals(prefixed)._columnMapping.numberField).toBe('complex_numberField');
|
|
516
|
+
expect(getMappedOpGroupInternals(prefixed)._columnMapping.booleanField).toBe('complex_booleanField');
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
it('should preserve schema metadata in prefixed OpGroups', () => {
|
|
520
|
+
const httpOpGroup = createHttpOpGroup();
|
|
521
|
+
|
|
522
|
+
// Schema should preserve field metadata
|
|
523
|
+
const statusField = getOpGroupInternals(httpOpGroup)._logSchema.fields.status;
|
|
524
|
+
expect(statusField).toHaveProperty('__schema_type', 'number');
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
describe('OpGroup Mapping and Composition', () => {
|
|
529
|
+
it('should map OpGroup columns', () => {
|
|
530
|
+
const httpOpGroup = createHttpOpGroup();
|
|
531
|
+
const retryOpGroup = createRetryOpGroup();
|
|
532
|
+
|
|
533
|
+
// Map HTTP OpGroup with custom prefix
|
|
534
|
+
const mappedHttp = httpOpGroup.prefix('http');
|
|
535
|
+
const mappedRetry = retryOpGroup.prefix('http_retry');
|
|
536
|
+
|
|
537
|
+
expect(mappedHttp).toBeDefined();
|
|
538
|
+
// Verify the mappings are set
|
|
539
|
+
expect(getMappedOpGroupInternals(mappedHttp)._columnMapping.status).toBe('http_status');
|
|
540
|
+
expect(getMappedOpGroupInternals(mappedRetry)._columnMapping.attempt).toBe('http_retry_attempt');
|
|
541
|
+
expect(getMappedOpGroupInternals(mappedRetry)._columnMapping.delay).toBe('http_retry_delay');
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it('should support multiple OpGroups with different prefixes', () => {
|
|
545
|
+
const httpOpGroup = createHttpOpGroup();
|
|
546
|
+
const dbOpGroup = createDbOpGroup();
|
|
547
|
+
const retryOpGroup = createRetryOpGroup();
|
|
548
|
+
|
|
549
|
+
// Create different prefixed versions
|
|
550
|
+
const mappedHttp = httpOpGroup.prefix('http');
|
|
551
|
+
const mappedDb = dbOpGroup.prefix('db');
|
|
552
|
+
const mappedRetry = retryOpGroup.prefix('shared_retry');
|
|
553
|
+
|
|
554
|
+
expect(mappedHttp).toBeDefined();
|
|
555
|
+
expect(mappedDb).toBeDefined();
|
|
556
|
+
expect(mappedRetry).toBeDefined();
|
|
557
|
+
|
|
558
|
+
// Verify each has correct mappings
|
|
559
|
+
expect(getMappedOpGroupInternals(mappedHttp)._columnMapping.status).toBe('http_status');
|
|
560
|
+
expect(getMappedOpGroupInternals(mappedDb)._columnMapping.query).toBe('db_query');
|
|
561
|
+
expect(getMappedOpGroupInternals(mappedRetry)._columnMapping.attempt).toBe('shared_retry_attempt');
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
it('should handle dependency chains', () => {
|
|
565
|
+
const retryOpGroup = createRetryOpGroup();
|
|
566
|
+
const httpOpGroup = createHttpOpGroup();
|
|
567
|
+
|
|
568
|
+
// Create prefixed versions
|
|
569
|
+
const nestedRetry = retryOpGroup.prefix('http_retry_nested');
|
|
570
|
+
const wiredHttp = httpOpGroup.prefix('http');
|
|
571
|
+
|
|
572
|
+
expect(wiredHttp).toBeDefined();
|
|
573
|
+
expect(nestedRetry).toBeDefined();
|
|
574
|
+
expect(getMappedOpGroupInternals(nestedRetry)._columnMapping.attempt).toBe('http_retry_nested_attempt');
|
|
575
|
+
expect(getMappedOpGroupInternals(nestedRetry)._columnMapping.delay).toBe('http_retry_nested_delay');
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
it('should maintain type safety in OpGroup composition', () => {
|
|
579
|
+
const httpOpGroup = createHttpOpGroup();
|
|
580
|
+
const retryOpGroup = createRetryOpGroup();
|
|
581
|
+
|
|
582
|
+
// This should compile without TypeScript errors
|
|
583
|
+
const mappedHttp = httpOpGroup.prefix('http');
|
|
584
|
+
const mappedRetry = retryOpGroup.prefix('http_retry');
|
|
585
|
+
|
|
586
|
+
expect(mappedHttp).toBeDefined();
|
|
587
|
+
expect(mappedRetry).toBeDefined();
|
|
588
|
+
|
|
589
|
+
// Verify that original schemas are accessible
|
|
590
|
+
expect(getMappedOpGroupInternals(mappedHttp)._logSchema._columnNames).toContain('status');
|
|
591
|
+
expect(getMappedOpGroupInternals(mappedRetry)._logSchema._columnNames).toContain('attempt');
|
|
592
|
+
});
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
describe('Op Context Creation', () => {
|
|
596
|
+
it('should define Op context with extra properties', () => {
|
|
597
|
+
const factory = defineOpContext({
|
|
598
|
+
logSchema: defineLogSchema({}),
|
|
599
|
+
ctx: {
|
|
600
|
+
env: null as { region: string } | null,
|
|
601
|
+
requestId: '' as string,
|
|
602
|
+
userId: undefined as string | undefined,
|
|
603
|
+
},
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
expect(factory.defineOp).toBeDefined();
|
|
607
|
+
expect(factory.defineOps).toBeDefined();
|
|
608
|
+
// logBinding is used with new Tracer({ logBinding, sink }) pattern
|
|
609
|
+
expect(factory.logBinding).toBeDefined();
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
it('should define Op context with required context properties', () => {
|
|
613
|
+
const factory = defineOpContext({
|
|
614
|
+
logSchema: defineLogSchema({}),
|
|
615
|
+
ctx: {
|
|
616
|
+
env: null as { region: string } | null,
|
|
617
|
+
requestId: '' as string,
|
|
618
|
+
},
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
// logBinding is used with new Tracer({ logBinding, sink }) pattern
|
|
622
|
+
expect(factory.logBinding).toBeDefined();
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
it('should define Op context with optional context properties', () => {
|
|
626
|
+
const factory = defineOpContext({
|
|
627
|
+
logSchema: defineLogSchema({}),
|
|
628
|
+
ctx: {
|
|
629
|
+
env: null as { region: string } | null,
|
|
630
|
+
requestId: '' as string,
|
|
631
|
+
userId: undefined as string | undefined,
|
|
632
|
+
},
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
// logBinding is used with new Tracer({ logBinding, sink }) pattern
|
|
636
|
+
expect(factory.logBinding).toBeDefined();
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
it('should define Op context with context defaults', () => {
|
|
640
|
+
const factory = defineOpContext({
|
|
641
|
+
logSchema: defineLogSchema({}),
|
|
642
|
+
ctx: {
|
|
643
|
+
env: null as { region: string } | null,
|
|
644
|
+
requestId: '' as string,
|
|
645
|
+
timeout: 5000 as number,
|
|
646
|
+
},
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
// logBinding is used with new Tracer({ logBinding, sink }) pattern
|
|
650
|
+
expect(factory.logBinding).toBeDefined();
|
|
651
|
+
});
|
|
652
|
+
});
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
describe('Library Composition Scenarios', () => {
|
|
656
|
+
// Helper factories for creating Op contexts
|
|
657
|
+
const createHttpOpGroupFactory = () => {
|
|
658
|
+
return defineOpContext({
|
|
659
|
+
logSchema: defineLogSchema({
|
|
660
|
+
status: S.number(),
|
|
661
|
+
method: S.enum(['GET', 'POST', 'PUT', 'DELETE']),
|
|
662
|
+
url: S.text(),
|
|
663
|
+
duration: S.number(),
|
|
664
|
+
}),
|
|
665
|
+
});
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
const createDbOpGroupFactory = () => {
|
|
669
|
+
return defineOpContext({
|
|
670
|
+
logSchema: defineLogSchema({
|
|
671
|
+
query: S.text(),
|
|
672
|
+
duration: S.number(),
|
|
673
|
+
rows: S.number(),
|
|
674
|
+
}),
|
|
675
|
+
});
|
|
676
|
+
};
|
|
677
|
+
|
|
678
|
+
const createRetryOpGroupFactory = () => {
|
|
679
|
+
return defineOpContext({
|
|
680
|
+
logSchema: defineLogSchema({
|
|
681
|
+
attempt: S.number(),
|
|
682
|
+
delay: S.number(),
|
|
683
|
+
}),
|
|
684
|
+
});
|
|
685
|
+
};
|
|
686
|
+
|
|
687
|
+
describe('Simple Library Usage', () => {
|
|
688
|
+
it('should handle single library usage with prefixing', () => {
|
|
689
|
+
const httpFactory = createHttpOpGroupFactory();
|
|
690
|
+
const { defineOps } = httpFactory;
|
|
691
|
+
const httpOpGroup = defineOps({});
|
|
692
|
+
const prefixedHttp = httpOpGroup.prefix('http');
|
|
693
|
+
|
|
694
|
+
// Verify that the mapping has all http fields
|
|
695
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.status).toBe('http_status');
|
|
696
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.method).toBe('http_method');
|
|
697
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.url).toBe('http_url');
|
|
698
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.duration).toBe('http_duration');
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
it('should maintain separate namespaces with multiple OpGroups', () => {
|
|
702
|
+
const httpFactory = createHttpOpGroupFactory();
|
|
703
|
+
const dbFactory = createDbOpGroupFactory();
|
|
704
|
+
|
|
705
|
+
const { defineOps: defineHttpOps } = httpFactory;
|
|
706
|
+
const { defineOps: defineDbOps } = dbFactory;
|
|
707
|
+
|
|
708
|
+
const httpOpGroup = defineHttpOps({});
|
|
709
|
+
const dbOpGroup = defineDbOps({});
|
|
710
|
+
|
|
711
|
+
const prefixedHttp = httpOpGroup.prefix('http');
|
|
712
|
+
const prefixedDb = dbOpGroup.prefix('db');
|
|
713
|
+
|
|
714
|
+
// Each library should have its own prefix
|
|
715
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.status).toBe('http_status');
|
|
716
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.method).toBe('http_method');
|
|
717
|
+
expect(getMappedOpGroupInternals(prefixedDb)._columnMapping.query).toBe('db_query');
|
|
718
|
+
expect(getMappedOpGroupInternals(prefixedDb)._columnMapping.duration).toBe('db_duration');
|
|
719
|
+
expect(getMappedOpGroupInternals(prefixedDb)._columnMapping.rows).toBe('db_rows');
|
|
720
|
+
});
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
describe('Nested Library Dependencies', () => {
|
|
724
|
+
it('should handle chained prefix mapping', () => {
|
|
725
|
+
const httpFactory = createHttpOpGroupFactory();
|
|
726
|
+
const retryFactory = createRetryOpGroupFactory();
|
|
727
|
+
|
|
728
|
+
const { defineOps: defineHttpOps } = httpFactory;
|
|
729
|
+
const { defineOps: defineRetryOps } = retryFactory;
|
|
730
|
+
|
|
731
|
+
const httpOpGroup = defineHttpOps({});
|
|
732
|
+
const retryOpGroup = defineRetryOps({});
|
|
733
|
+
|
|
734
|
+
// HTTP prefixed with 'http'
|
|
735
|
+
const prefixedHttp = httpOpGroup.prefix('http');
|
|
736
|
+
// Retry prefixed with 'http_retry'
|
|
737
|
+
const prefixedRetry = retryOpGroup.prefix('http_retry');
|
|
738
|
+
|
|
739
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.status).toBe('http_status');
|
|
740
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.method).toBe('http_method');
|
|
741
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.url).toBe('http_url');
|
|
742
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.duration).toBe('http_duration');
|
|
743
|
+
|
|
744
|
+
// Retry dependency fields should be present with prefix
|
|
745
|
+
expect(getMappedOpGroupInternals(prefixedRetry)._columnMapping.attempt).toBe('http_retry_attempt');
|
|
746
|
+
expect(getMappedOpGroupInternals(prefixedRetry)._columnMapping.delay).toBe('http_retry_delay');
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
it('should handle multiple prefix chains', () => {
|
|
750
|
+
const retryFactory = createRetryOpGroupFactory();
|
|
751
|
+
const httpFactory = createHttpOpGroupFactory();
|
|
752
|
+
|
|
753
|
+
const { defineOps: defineRetryOps } = retryFactory;
|
|
754
|
+
const { defineOps: defineHttpOps } = httpFactory;
|
|
755
|
+
|
|
756
|
+
const retryOpGroup = defineRetryOps({});
|
|
757
|
+
const httpOpGroup = defineHttpOps({});
|
|
758
|
+
|
|
759
|
+
// Create different prefixed versions
|
|
760
|
+
const retryForHttp = retryOpGroup.prefix('http_retry');
|
|
761
|
+
const retryForAuth = retryOpGroup.prefix('http_auth_retry');
|
|
762
|
+
const sharedRetry = retryOpGroup.prefix('shared_auth_retry');
|
|
763
|
+
|
|
764
|
+
// Verify each mapping is correct
|
|
765
|
+
expect(getMappedOpGroupInternals(retryForHttp)._columnMapping.attempt).toBe('http_retry_attempt');
|
|
766
|
+
expect(getMappedOpGroupInternals(retryForAuth)._columnMapping.attempt).toBe('http_auth_retry_attempt');
|
|
767
|
+
expect(getMappedOpGroupInternals(sharedRetry)._columnMapping.attempt).toBe('shared_auth_retry_attempt');
|
|
768
|
+
|
|
769
|
+
// HTTP stays prefixed with 'http'
|
|
770
|
+
const prefixedHttp = httpOpGroup.prefix('http');
|
|
771
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.status).toBe('http_status');
|
|
772
|
+
});
|
|
773
|
+
});
|
|
774
|
+
|
|
775
|
+
describe('Complex Composition', () => {
|
|
776
|
+
it('should handle multiple OpGroups with shared prefixes', () => {
|
|
777
|
+
const httpFactory = createHttpOpGroupFactory();
|
|
778
|
+
const dbFactory = createDbOpGroupFactory();
|
|
779
|
+
const retryFactory = createRetryOpGroupFactory();
|
|
780
|
+
const cacheFactory = defineOpContext({
|
|
781
|
+
logSchema: defineLogSchema({
|
|
782
|
+
hits: S.number(),
|
|
783
|
+
misses: S.number(),
|
|
784
|
+
}),
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
const { defineOps: defineHttpOps } = httpFactory;
|
|
788
|
+
const { defineOps: defineDbOps } = dbFactory;
|
|
789
|
+
const { defineOps: defineRetryOps } = retryFactory;
|
|
790
|
+
const { defineOps: defineCacheOps } = cacheFactory;
|
|
791
|
+
|
|
792
|
+
const httpOpGroup = defineHttpOps({});
|
|
793
|
+
const dbOpGroup = defineDbOps({});
|
|
794
|
+
const retryOpGroup = defineRetryOps({});
|
|
795
|
+
const cacheOpGroup = defineCacheOps({});
|
|
796
|
+
|
|
797
|
+
// Create shared retry instance for both HTTP and DB
|
|
798
|
+
const sharedRetry = retryOpGroup.prefix('shared_retry');
|
|
799
|
+
const sharedCache = cacheOpGroup.prefix('shared_cache');
|
|
800
|
+
|
|
801
|
+
// Create prefixed versions
|
|
802
|
+
const prefixedHttp = httpOpGroup.prefix('http');
|
|
803
|
+
const prefixedDb = dbOpGroup.prefix('db');
|
|
804
|
+
const dbCache = cacheOpGroup.prefix('db_cache');
|
|
805
|
+
|
|
806
|
+
expect(prefixedHttp).toBeDefined();
|
|
807
|
+
expect(prefixedDb).toBeDefined();
|
|
808
|
+
expect(sharedRetry).toBeDefined();
|
|
809
|
+
expect(sharedCache).toBeDefined();
|
|
810
|
+
|
|
811
|
+
// Verify all mappings are correct
|
|
812
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.status).toBe('http_status');
|
|
813
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.method).toBe('http_method');
|
|
814
|
+
expect(getMappedOpGroupInternals(prefixedDb)._columnMapping.query).toBe('db_query');
|
|
815
|
+
expect(getMappedOpGroupInternals(prefixedDb)._columnMapping.duration).toBe('db_duration');
|
|
816
|
+
expect(getMappedOpGroupInternals(prefixedDb)._columnMapping.rows).toBe('db_rows');
|
|
817
|
+
expect(getMappedOpGroupInternals(sharedRetry)._columnMapping.attempt).toBe('shared_retry_attempt');
|
|
818
|
+
expect(getMappedOpGroupInternals(sharedRetry)._columnMapping.delay).toBe('shared_retry_delay');
|
|
819
|
+
expect(getMappedOpGroupInternals(sharedCache)._columnMapping.hits).toBe('shared_cache_hits');
|
|
820
|
+
expect(getMappedOpGroupInternals(sharedCache)._columnMapping.misses).toBe('shared_cache_misses');
|
|
821
|
+
expect(getMappedOpGroupInternals(dbCache)._columnMapping.hits).toBe('db_cache_hits');
|
|
822
|
+
expect(getMappedOpGroupInternals(dbCache)._columnMapping.misses).toBe('db_cache_misses');
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
it('should handle different prefix patterns', () => {
|
|
826
|
+
const httpFactory = createHttpOpGroupFactory();
|
|
827
|
+
const dbFactory = createDbOpGroupFactory();
|
|
828
|
+
const retryFactory = createRetryOpGroupFactory();
|
|
829
|
+
|
|
830
|
+
const { defineOps: defineHttpOps } = httpFactory;
|
|
831
|
+
const { defineOps: defineDbOps } = dbFactory;
|
|
832
|
+
const { defineOps: defineRetryOps } = retryFactory;
|
|
833
|
+
|
|
834
|
+
const httpOpGroup = defineHttpOps({});
|
|
835
|
+
const dbOpGroup = defineDbOps({});
|
|
836
|
+
const retryOpGroup = defineRetryOps({});
|
|
837
|
+
|
|
838
|
+
// Pattern: Shared retry with different prefix configurations
|
|
839
|
+
const fastRetry = retryOpGroup.prefix('fast_retry');
|
|
840
|
+
const slowRetry = retryOpGroup.prefix('slow_retry');
|
|
841
|
+
|
|
842
|
+
const prefixedHttp = httpOpGroup.prefix('http');
|
|
843
|
+
const prefixedDb = dbOpGroup.prefix('db');
|
|
844
|
+
|
|
845
|
+
expect(prefixedHttp).toBeDefined();
|
|
846
|
+
expect(prefixedDb).toBeDefined();
|
|
847
|
+
|
|
848
|
+
// Verify that both retry prefixes are available
|
|
849
|
+
expect(getMappedOpGroupInternals(fastRetry)._columnMapping.attempt).toBe('fast_retry_attempt');
|
|
850
|
+
expect(getMappedOpGroupInternals(slowRetry)._columnMapping.attempt).toBe('slow_retry_attempt');
|
|
851
|
+
|
|
852
|
+
// HTTP and DB have their own prefixes
|
|
853
|
+
expect(getMappedOpGroupInternals(prefixedHttp)._columnMapping.status).toBe('http_status');
|
|
854
|
+
expect(getMappedOpGroupInternals(prefixedDb)._columnMapping.query).toBe('db_query');
|
|
855
|
+
});
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
describe('Edge Cases and Error Handling', () => {
|
|
860
|
+
describe('Prefix Edge Cases', () => {
|
|
861
|
+
it('should handle empty prefix string', () => {
|
|
862
|
+
const schema = defineLogSchema({
|
|
863
|
+
field: S.text(),
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
const prefixed = prefixSchema(schema, '');
|
|
867
|
+
|
|
868
|
+
expect(prefixed).toHaveProperty('_field');
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
it('should handle null and undefined values gracefully', () => {
|
|
872
|
+
// Test with undefined field (edge case)
|
|
873
|
+
const schemaWithUndefined = defineLogSchema({
|
|
874
|
+
validField: S.text(),
|
|
875
|
+
});
|
|
876
|
+
Reflect.apply(Array.prototype.push, schemaWithUndefined._columns, [['undefinedField', undefined]]);
|
|
877
|
+
|
|
878
|
+
const prefixedWithUndefined = prefixSchema(schemaWithUndefined, 'test');
|
|
879
|
+
|
|
880
|
+
expect(prefixedWithUndefined).toHaveProperty('test_validField');
|
|
881
|
+
expect(prefixedWithUndefined).toHaveProperty('test_undefinedField');
|
|
882
|
+
expect(Reflect.get(prefixedWithUndefined, 'test_undefinedField')).toBeUndefined();
|
|
883
|
+
|
|
884
|
+
// Test with null field (edge case)
|
|
885
|
+
const schemaWithNull = defineLogSchema({
|
|
886
|
+
validField: S.text(),
|
|
887
|
+
});
|
|
888
|
+
Reflect.apply(Array.prototype.push, schemaWithNull._columns, [['nullField', null]]);
|
|
889
|
+
|
|
890
|
+
const prefixedWithNull = prefixSchema(schemaWithNull, 'test');
|
|
891
|
+
|
|
892
|
+
expect(prefixedWithNull).toHaveProperty('test_validField');
|
|
893
|
+
expect(prefixedWithNull).toHaveProperty('test_nullField');
|
|
894
|
+
expect(Reflect.get(prefixedWithNull, 'test_nullField')).toBeNull();
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
it('should handle schema with many fields', () => {
|
|
898
|
+
const schemaFields: Record<string, ReturnType<typeof S.number>> = {};
|
|
899
|
+
for (let i = 0; i < 100; i++) {
|
|
900
|
+
schemaFields[`field${i}`] = S.number();
|
|
901
|
+
}
|
|
902
|
+
const schema = defineLogSchema(schemaFields);
|
|
903
|
+
|
|
904
|
+
const prefixed = prefixSchema(schema, 'many');
|
|
905
|
+
|
|
906
|
+
expect(prefixed._columnNames.length).toBe(100);
|
|
907
|
+
expect(prefixed).toHaveProperty('many_field0');
|
|
908
|
+
expect(prefixed).toHaveProperty('many_field99');
|
|
909
|
+
});
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
describe('Buffer Remapping Edge Cases', () => {
|
|
913
|
+
it('should handle mapping consistency', () => {
|
|
914
|
+
// Test that mapping and code generation are consistent
|
|
915
|
+
const schema = defineLogSchema({
|
|
916
|
+
status: S.number(),
|
|
917
|
+
method: S.enum(['GET', 'POST']),
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
const mapping = createPrefixMapping(schema, 'http');
|
|
921
|
+
const code = generateRemappedSpanLoggerClass(schema, mapping);
|
|
922
|
+
|
|
923
|
+
// Verify that the mapping referenced in code matches the generated mapping
|
|
924
|
+
expect(code).toContain('"status":"http_status"');
|
|
925
|
+
expect(code).toContain('"method":"http_method"');
|
|
926
|
+
|
|
927
|
+
// Verify that all prefixed columns are properly referenced
|
|
928
|
+
expect(code).toContain('http_status_values');
|
|
929
|
+
expect(code).toContain('http_status_nulls');
|
|
930
|
+
expect(code).toContain('http_method_values');
|
|
931
|
+
expect(code).toContain('http_method_nulls');
|
|
932
|
+
});
|
|
933
|
+
});
|
|
934
|
+
});
|