@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,612 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from 'bun:test';
|
|
2
|
+
import { DEFAULT_BUFFER_CAPACITY } from '@smoothbricks/arrow-builder';
|
|
3
|
+
import fc from 'fast-check';
|
|
4
|
+
import { createSpanLogger } from '../codegen/spanLoggerGenerator.js';
|
|
5
|
+
import { DEFAULT_METADATA } from '../opContext/defineOp.js';
|
|
6
|
+
import { S } from '../schema/builder.js';
|
|
7
|
+
import { LogSchema } from '../schema/LogSchema.js';
|
|
8
|
+
import { mergeWithSystemSchema } from '../schema/systemSchema.js';
|
|
9
|
+
import { createSpanBuffer, getSpanBufferClass, type SpanBufferConstructor } from '../spanBuffer.js';
|
|
10
|
+
|
|
11
|
+
import type { AnySpanBuffer } from '../types.js';
|
|
12
|
+
import { createBuffer, createTestTraceRoot } from './test-helpers.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Property-based tests for buffer overflow handling.
|
|
16
|
+
*
|
|
17
|
+
* Core properties verified:
|
|
18
|
+
* 1. Entry Preservation: All N entries exist across the buffer chain
|
|
19
|
+
* 2. Buffer Count Formula: Exact number of buffers matches mathematical expectation
|
|
20
|
+
* 3. Chain Integrity: Linked list is properly formed
|
|
21
|
+
* 4. Data Correctness: Each entry has expected attribute values
|
|
22
|
+
* 5. Overflow Counter: logBinding.sb_overflows === bufferCount - 1
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// Schema for testing - includes various column types and system fields
|
|
26
|
+
const testSchema = new LogSchema(
|
|
27
|
+
mergeWithSystemSchema({
|
|
28
|
+
requestId: S.category(),
|
|
29
|
+
userId: S.category(),
|
|
30
|
+
operation: S.enum(['SELECT', 'INSERT', 'UPDATE', 'DELETE']),
|
|
31
|
+
duration: S.number(),
|
|
32
|
+
success: S.boolean(),
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* SpanLogger reserves rows 0-1 for span-start and span-end.
|
|
38
|
+
* User entries start at row 2. So with capacity C, we can write (C-2) entries
|
|
39
|
+
* before overflow in the first buffer.
|
|
40
|
+
*/
|
|
41
|
+
const RESERVED_ROWS = 2;
|
|
42
|
+
const DB_OPERATIONS = ['SELECT', 'INSERT', 'UPDATE', 'DELETE'] as const;
|
|
43
|
+
|
|
44
|
+
type BufferChainAnalysis = {
|
|
45
|
+
bufferCount: number;
|
|
46
|
+
totalEntries: number;
|
|
47
|
+
writeIndices: number[];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Helper: Get SpanBufferClass and reset stats for testing
|
|
52
|
+
*/
|
|
53
|
+
function getTestSpanBufferClass(capacity?: number): SpanBufferConstructor {
|
|
54
|
+
const SpanBufferClass = getSpanBufferClass(testSchema);
|
|
55
|
+
// Reset stats for clean test state
|
|
56
|
+
SpanBufferClass.stats.capacity = capacity ?? DEFAULT_BUFFER_CAPACITY;
|
|
57
|
+
SpanBufferClass.stats.totalWrites = 0;
|
|
58
|
+
SpanBufferClass.stats.spansCreated = 0;
|
|
59
|
+
return SpanBufferClass;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Helper: Count overflows by walking buffer chain
|
|
64
|
+
*/
|
|
65
|
+
function countOverflows(buffer: AnySpanBuffer): number {
|
|
66
|
+
let count = 0;
|
|
67
|
+
let curr: AnySpanBuffer | undefined = buffer;
|
|
68
|
+
while (curr?._overflow) {
|
|
69
|
+
count++;
|
|
70
|
+
curr = curr._overflow;
|
|
71
|
+
}
|
|
72
|
+
return count;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Helper: Count buffers in chain and collect total entries
|
|
77
|
+
*/
|
|
78
|
+
function analyzeBufferChain(rootBuffer: AnySpanBuffer): BufferChainAnalysis {
|
|
79
|
+
const writeIndices: number[] = [];
|
|
80
|
+
let bufferCount = 0;
|
|
81
|
+
let totalEntries = 0;
|
|
82
|
+
let current: AnySpanBuffer | undefined = rootBuffer;
|
|
83
|
+
|
|
84
|
+
while (current) {
|
|
85
|
+
bufferCount++;
|
|
86
|
+
writeIndices.push(current._writeIndex);
|
|
87
|
+
totalEntries += current._writeIndex;
|
|
88
|
+
current = current._overflow as AnySpanBuffer | undefined;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { bufferCount, totalEntries, writeIndices };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
type LazyColumnProbe = {
|
|
95
|
+
_requestId_values?: unknown;
|
|
96
|
+
_userId_values?: unknown;
|
|
97
|
+
_operation_values?: unknown;
|
|
98
|
+
_duration_values?: unknown;
|
|
99
|
+
_success_values?: unknown;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
function requireOverflowBuffer(buffer: AnySpanBuffer, label: string): AnySpanBuffer {
|
|
103
|
+
if (!buffer._overflow) {
|
|
104
|
+
throw new Error(`Expected overflow buffer for ${label}`);
|
|
105
|
+
}
|
|
106
|
+
return buffer._overflow;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Helper: Collect all entries from buffer chain
|
|
111
|
+
*/
|
|
112
|
+
function collectEntries(
|
|
113
|
+
rootBuffer: AnySpanBuffer,
|
|
114
|
+
startRow = 0,
|
|
115
|
+
): Array<{
|
|
116
|
+
bufferIndex: number;
|
|
117
|
+
rowIndex: number;
|
|
118
|
+
requestId: string | undefined;
|
|
119
|
+
userId: string | undefined;
|
|
120
|
+
operation: number | undefined;
|
|
121
|
+
duration: number | undefined;
|
|
122
|
+
}> {
|
|
123
|
+
const entries: Array<{
|
|
124
|
+
bufferIndex: number;
|
|
125
|
+
rowIndex: number;
|
|
126
|
+
requestId: string | undefined;
|
|
127
|
+
userId: string | undefined;
|
|
128
|
+
operation: number | undefined;
|
|
129
|
+
duration: number | undefined;
|
|
130
|
+
}> = [];
|
|
131
|
+
|
|
132
|
+
let bufferIndex = 0;
|
|
133
|
+
let current: AnySpanBuffer | undefined = rootBuffer;
|
|
134
|
+
|
|
135
|
+
while (current) {
|
|
136
|
+
// First buffer starts at startRow, subsequent buffers start at 0
|
|
137
|
+
const start = bufferIndex === 0 ? startRow : 0;
|
|
138
|
+
const end = current._writeIndex;
|
|
139
|
+
|
|
140
|
+
const requestIdValues = current.getColumnIfAllocated('requestId');
|
|
141
|
+
const userIdValues = current.getColumnIfAllocated('userId');
|
|
142
|
+
const operationValues = current.getColumnIfAllocated('operation');
|
|
143
|
+
const durationValues = current.getColumnIfAllocated('duration');
|
|
144
|
+
|
|
145
|
+
for (let row = start; row < end; row++) {
|
|
146
|
+
const requestIdValue = Array.isArray(requestIdValues) ? requestIdValues[row] : undefined;
|
|
147
|
+
const userIdValue = Array.isArray(userIdValues) ? userIdValues[row] : undefined;
|
|
148
|
+
entries.push({
|
|
149
|
+
bufferIndex,
|
|
150
|
+
rowIndex: row,
|
|
151
|
+
requestId: typeof requestIdValue === 'string' ? requestIdValue : undefined,
|
|
152
|
+
userId: typeof userIdValue === 'string' ? userIdValue : undefined,
|
|
153
|
+
operation: operationValues instanceof Uint8Array ? operationValues[row] : undefined,
|
|
154
|
+
duration: durationValues instanceof Float64Array ? durationValues[row] : undefined,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
bufferIndex++;
|
|
159
|
+
current = current._overflow as AnySpanBuffer | undefined;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return entries;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Calculate expected buffer count for N entries.
|
|
167
|
+
*
|
|
168
|
+
* With capacity C and R reserved rows in first buffer:
|
|
169
|
+
* - First buffer holds (C - R) entries
|
|
170
|
+
* - Each subsequent buffer holds C entries
|
|
171
|
+
*
|
|
172
|
+
* Formula: 1 + ceil(max(0, N - (C - R)) / C)
|
|
173
|
+
*/
|
|
174
|
+
function expectedBufferCount(numEntries: number, capacity: number, reservedRows: number): number {
|
|
175
|
+
const firstBufferCapacity = capacity - reservedRows;
|
|
176
|
+
if (numEntries <= firstBufferCapacity) {
|
|
177
|
+
return 1;
|
|
178
|
+
}
|
|
179
|
+
const remaining = numEntries - firstBufferCapacity;
|
|
180
|
+
return 1 + Math.ceil(remaining / capacity);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
describe('Buffer Overflow Property Tests', () => {
|
|
184
|
+
let SpanBufferClass: SpanBufferConstructor;
|
|
185
|
+
|
|
186
|
+
beforeEach(() => {
|
|
187
|
+
SpanBufferClass = getTestSpanBufferClass();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe('Property: Entry Preservation', () => {
|
|
191
|
+
it('all entries are preserved across buffer chain for any entry count', () => {
|
|
192
|
+
fc.assert(
|
|
193
|
+
fc.property(
|
|
194
|
+
// Generate entry count from 1 to 200 (enough to trigger many overflows)
|
|
195
|
+
fc.integer({ min: 1, max: 200 }),
|
|
196
|
+
(numEntries) => {
|
|
197
|
+
// Reset counters for each test run
|
|
198
|
+
SpanBufferClass.stats.spansCreated = 0;
|
|
199
|
+
|
|
200
|
+
const buffer = createBuffer(testSchema);
|
|
201
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
202
|
+
|
|
203
|
+
// Write entries
|
|
204
|
+
for (let i = 0; i < numEntries; i++) {
|
|
205
|
+
logger
|
|
206
|
+
.info(`msg-${i}`)
|
|
207
|
+
.requestId(`req-${i}`)
|
|
208
|
+
.userId(`user-${i}`)
|
|
209
|
+
.operation(DB_OPERATIONS[i % 4])
|
|
210
|
+
.duration(i * 10);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Collect entries starting from row RESERVED_ROWS (rows 0-1 are span lifecycle)
|
|
214
|
+
const entries = collectEntries(buffer, RESERVED_ROWS);
|
|
215
|
+
|
|
216
|
+
// Property: exactly numEntries entries exist
|
|
217
|
+
expect(entries.length).toBe(numEntries);
|
|
218
|
+
},
|
|
219
|
+
),
|
|
220
|
+
{ numRuns: 100 },
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
describe('Property: Buffer Count Formula', () => {
|
|
226
|
+
it('buffer count matches mathematical formula for any entry count', () => {
|
|
227
|
+
fc.assert(
|
|
228
|
+
// Limit to 90 entries to stay below capacity tuning threshold (100 writes)
|
|
229
|
+
// This ensures capacity stays constant throughout the test run
|
|
230
|
+
fc.property(fc.integer({ min: 1, max: 90 }), (numEntries) => {
|
|
231
|
+
// Reset all stats including capacity before each run
|
|
232
|
+
const capacity = DEFAULT_BUFFER_CAPACITY; // 8
|
|
233
|
+
SpanBufferClass.stats.capacity = capacity;
|
|
234
|
+
SpanBufferClass.stats.totalWrites = 0;
|
|
235
|
+
SpanBufferClass.stats.spansCreated = 0;
|
|
236
|
+
|
|
237
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
|
|
238
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
239
|
+
|
|
240
|
+
// Write entries
|
|
241
|
+
for (let i = 0; i < numEntries; i++) {
|
|
242
|
+
logger.info(`msg-${i}`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const { bufferCount } = analyzeBufferChain(buffer);
|
|
246
|
+
// SpanLogger reserves 2 rows (span-start, span-end)
|
|
247
|
+
const expected = expectedBufferCount(numEntries, capacity, RESERVED_ROWS);
|
|
248
|
+
|
|
249
|
+
expect(bufferCount).toBe(expected);
|
|
250
|
+
}),
|
|
251
|
+
{ numRuns: 100 },
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
describe('Property: Chain Integrity', () => {
|
|
257
|
+
it('buffer chain is properly linked', () => {
|
|
258
|
+
fc.assert(
|
|
259
|
+
fc.property(fc.integer({ min: 1, max: 100 }), (numEntries) => {
|
|
260
|
+
SpanBufferClass.stats.spansCreated = 0;
|
|
261
|
+
|
|
262
|
+
const buffer = createBuffer(testSchema);
|
|
263
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
264
|
+
|
|
265
|
+
for (let i = 0; i < numEntries; i++) {
|
|
266
|
+
logger.info(`msg-${i}`);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Walk the chain and verify each link
|
|
270
|
+
const buffers: AnySpanBuffer[] = [];
|
|
271
|
+
let current: AnySpanBuffer | undefined = buffer;
|
|
272
|
+
while (current) {
|
|
273
|
+
buffers.push(current);
|
|
274
|
+
current = current._overflow as AnySpanBuffer | undefined;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Property: each buffer (except last) has next pointing to following buffer
|
|
278
|
+
for (let i = 0; i < buffers.length - 1; i++) {
|
|
279
|
+
expect(buffers[i]._overflow).toBe(buffers[i + 1]);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Property: last buffer has no next
|
|
283
|
+
expect(buffers[buffers.length - 1]._overflow).toBeUndefined();
|
|
284
|
+
|
|
285
|
+
// Property: all buffers share same spanId and traceId
|
|
286
|
+
const spanId = buffer.span_id;
|
|
287
|
+
const traceId = buffer.trace_id;
|
|
288
|
+
for (const buf of buffers) {
|
|
289
|
+
expect(buf.span_id).toBe(spanId);
|
|
290
|
+
expect(buf.trace_id).toBe(traceId);
|
|
291
|
+
}
|
|
292
|
+
}),
|
|
293
|
+
{ numRuns: 50 },
|
|
294
|
+
);
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
describe('Property: Data Correctness', () => {
|
|
299
|
+
it('each entry has correct attribute values', () => {
|
|
300
|
+
fc.assert(
|
|
301
|
+
fc.property(fc.integer({ min: 1, max: 100 }), (numEntries) => {
|
|
302
|
+
SpanBufferClass.stats.spansCreated = 0;
|
|
303
|
+
|
|
304
|
+
const buffer = createBuffer(testSchema);
|
|
305
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
306
|
+
|
|
307
|
+
const operations = ['SELECT', 'INSERT', 'UPDATE', 'DELETE'] as const;
|
|
308
|
+
|
|
309
|
+
// Write entries with predictable values
|
|
310
|
+
for (let i = 0; i < numEntries; i++) {
|
|
311
|
+
logger
|
|
312
|
+
.info(`msg-${i}`)
|
|
313
|
+
.requestId(`req-${i}`)
|
|
314
|
+
.userId(`user-${i}`)
|
|
315
|
+
.operation(operations[i % 4])
|
|
316
|
+
.duration(i * 10.5);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Collect starting from RESERVED_ROWS
|
|
320
|
+
const entries = collectEntries(buffer, RESERVED_ROWS);
|
|
321
|
+
|
|
322
|
+
// Property: each entry has expected values
|
|
323
|
+
for (let i = 0; i < numEntries; i++) {
|
|
324
|
+
const entry = entries[i];
|
|
325
|
+
expect(entry.requestId).toBe(`req-${i}`);
|
|
326
|
+
expect(entry.userId).toBe(`user-${i}`);
|
|
327
|
+
// Enum stored as index
|
|
328
|
+
expect(entry.operation).toBe(i % 4);
|
|
329
|
+
expect(entry.duration).toBe(i * 10.5);
|
|
330
|
+
}
|
|
331
|
+
}),
|
|
332
|
+
{ numRuns: 50 },
|
|
333
|
+
);
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
describe('Property: Overflow Counter Consistency', () => {
|
|
338
|
+
it('sb_overflows equals bufferCount - 1', () => {
|
|
339
|
+
fc.assert(
|
|
340
|
+
fc.property(fc.integer({ min: 1, max: 150 }), (numEntries) => {
|
|
341
|
+
// Reset counters
|
|
342
|
+
SpanBufferClass.stats.spansCreated = 0;
|
|
343
|
+
|
|
344
|
+
const buffer = createBuffer(testSchema);
|
|
345
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
346
|
+
|
|
347
|
+
for (let i = 0; i < numEntries; i++) {
|
|
348
|
+
logger.info(`msg-${i}`);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const { bufferCount } = analyzeBufferChain(buffer);
|
|
352
|
+
|
|
353
|
+
// Property: overflow events = bufferCount - 1 (one per chain link)
|
|
354
|
+
expect(countOverflows(buffer)).toBe(bufferCount - 1);
|
|
355
|
+
}),
|
|
356
|
+
{ numRuns: 100 },
|
|
357
|
+
);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
describe('Property: WriteIndex Bounds', () => {
|
|
362
|
+
it('each buffer writeIndex is within capacity', () => {
|
|
363
|
+
fc.assert(
|
|
364
|
+
fc.property(fc.integer({ min: 1, max: 200 }), (numEntries) => {
|
|
365
|
+
SpanBufferClass.stats.spansCreated = 0;
|
|
366
|
+
|
|
367
|
+
const buffer = createBuffer(testSchema);
|
|
368
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
369
|
+
|
|
370
|
+
for (let i = 0; i < numEntries; i++) {
|
|
371
|
+
logger.info(`msg-${i}`);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Walk chain and check each buffer
|
|
375
|
+
let current: AnySpanBuffer | undefined = buffer;
|
|
376
|
+
while (current) {
|
|
377
|
+
// Property: writeIndex <= capacity
|
|
378
|
+
expect(current._writeIndex).toBeLessThanOrEqual(current._capacity);
|
|
379
|
+
// Property: writeIndex >= 0
|
|
380
|
+
expect(current._writeIndex).toBeGreaterThanOrEqual(0);
|
|
381
|
+
current = current._overflow as AnySpanBuffer | undefined;
|
|
382
|
+
}
|
|
383
|
+
}),
|
|
384
|
+
{ numRuns: 100 },
|
|
385
|
+
);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
describe('Edge Cases', () => {
|
|
390
|
+
it('exact usable capacity: no overflow when entries fit in first buffer', () => {
|
|
391
|
+
const capacity = DEFAULT_BUFFER_CAPACITY; // 8
|
|
392
|
+
const usableCapacity = capacity - RESERVED_ROWS; // 6 entries fit
|
|
393
|
+
|
|
394
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
|
|
395
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
396
|
+
|
|
397
|
+
// Write exactly usable capacity entries (6 with capacity=8, reserved=2)
|
|
398
|
+
for (let i = 0; i < usableCapacity; i++) {
|
|
399
|
+
logger.info(`msg-${i}`);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Should be exactly 1 buffer (no overflow)
|
|
403
|
+
expect(buffer._overflow).toBeUndefined();
|
|
404
|
+
expect(countOverflows(buffer)).toBe(0);
|
|
405
|
+
// writeIndex = RESERVED_ROWS + usableCapacity = 2 + 6 = 8 = capacity
|
|
406
|
+
expect(buffer._writeIndex).toBe(capacity);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
it('usable capacity + 1: triggers exactly one overflow', () => {
|
|
410
|
+
const capacity = DEFAULT_BUFFER_CAPACITY; // 8
|
|
411
|
+
const usableCapacity = capacity - RESERVED_ROWS; // 6
|
|
412
|
+
|
|
413
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
|
|
414
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
415
|
+
|
|
416
|
+
// Write usable capacity + 1 entries (7 entries)
|
|
417
|
+
for (let i = 0; i < usableCapacity + 1; i++) {
|
|
418
|
+
logger.info(`msg-${i}`);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Should be exactly 2 buffers
|
|
422
|
+
expect(buffer._overflow).toBeDefined();
|
|
423
|
+
expect(buffer._overflow?._overflow).toBeUndefined();
|
|
424
|
+
expect(countOverflows(buffer)).toBe(1);
|
|
425
|
+
|
|
426
|
+
// First buffer full, second has 1 entry
|
|
427
|
+
expect(buffer._writeIndex).toBe(capacity);
|
|
428
|
+
expect(buffer._overflow?._writeIndex).toBe(1);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it('zero entries: single buffer with just reserved space', () => {
|
|
432
|
+
const buffer = createBuffer(testSchema);
|
|
433
|
+
// Create logger but don't write anything
|
|
434
|
+
createSpanLogger(testSchema, buffer);
|
|
435
|
+
|
|
436
|
+
expect(buffer._overflow).toBeUndefined();
|
|
437
|
+
// Logger constructor sets writeIndex to 2 (after reserved rows)
|
|
438
|
+
expect(buffer._writeIndex).toBe(RESERVED_ROWS);
|
|
439
|
+
expect(countOverflows(buffer)).toBe(0);
|
|
440
|
+
});
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
describe('Varying Capacity', () => {
|
|
444
|
+
it('property holds for different buffer capacities', () => {
|
|
445
|
+
fc.assert(
|
|
446
|
+
fc.property(
|
|
447
|
+
fc.integer({ min: 1, max: 100 }), // entries
|
|
448
|
+
fc.integer({ min: 8, max: 64 }).map((n) => (n + 7) & ~7), // capacity aligned to 8
|
|
449
|
+
(numEntries, capacity) => {
|
|
450
|
+
// Reset all stats to prevent capacity tuning from modifying them mid-test
|
|
451
|
+
SpanBufferClass.stats.capacity = capacity; // Set for chained buffers
|
|
452
|
+
SpanBufferClass.stats.totalWrites = 0;
|
|
453
|
+
SpanBufferClass.stats.spansCreated = 0;
|
|
454
|
+
|
|
455
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
|
|
456
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
457
|
+
|
|
458
|
+
for (let i = 0; i < numEntries; i++) {
|
|
459
|
+
logger.info(`msg-${i}`).requestId(`req-${i}`);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const { bufferCount } = analyzeBufferChain(buffer);
|
|
463
|
+
|
|
464
|
+
// Property: buffer count matches formula (with reserved rows)
|
|
465
|
+
const expected = expectedBufferCount(numEntries, capacity, RESERVED_ROWS);
|
|
466
|
+
expect(bufferCount).toBe(expected);
|
|
467
|
+
|
|
468
|
+
// Property: overflow count matches
|
|
469
|
+
expect(countOverflows(buffer)).toBe(bufferCount - 1);
|
|
470
|
+
},
|
|
471
|
+
),
|
|
472
|
+
{ numRuns: 100 },
|
|
473
|
+
);
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
describe('Scoped Attributes in Overflow Buffers', () => {
|
|
478
|
+
it('should prefill scoped attributes in overflow buffer from row 0 (not row 2)', () => {
|
|
479
|
+
const capacity = 8;
|
|
480
|
+
const usableCapacity = capacity - RESERVED_ROWS; // 6
|
|
481
|
+
|
|
482
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
|
|
483
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
484
|
+
|
|
485
|
+
// Set scope values that should be prefilled
|
|
486
|
+
buffer._scopeValues = Object.freeze({
|
|
487
|
+
requestId: 'req-123',
|
|
488
|
+
userId: 'user-456',
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
// Write enough entries to trigger overflow (usableCapacity + 1)
|
|
492
|
+
for (let i = 0; i < usableCapacity + 1; i++) {
|
|
493
|
+
logger.info(`msg-${i}`);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Verify overflow happened
|
|
497
|
+
expect(buffer._overflow).toBeDefined();
|
|
498
|
+
const overflowBuffer = requireOverflowBuffer(buffer, 'prefill-row0');
|
|
499
|
+
const overflowProbe = overflowBuffer as AnySpanBuffer & LazyColumnProbe;
|
|
500
|
+
|
|
501
|
+
// CRITICAL: Overflow buffer starts at _writeIndex=0, not 2
|
|
502
|
+
// The bug was that _prefillScopedAttributesOn used startIdx=2, skipping rows 0-1
|
|
503
|
+
expect(overflowBuffer._writeIndex).toBe(1); // One entry written
|
|
504
|
+
|
|
505
|
+
// CRITICAL: Columns in scope but never written to directly are NOT allocated
|
|
506
|
+
// Prefill checks _requestId_values (private) to avoid triggering lazy allocation
|
|
507
|
+
// These columns stay unallocated until Arrow conversion time
|
|
508
|
+
expect(overflowProbe._requestId_values).toBeUndefined();
|
|
509
|
+
expect(overflowProbe._userId_values).toBeUndefined();
|
|
510
|
+
|
|
511
|
+
// Row 0 has the actual entry (message IS allocated because .info() writes to it)
|
|
512
|
+
expect(overflowBuffer.message_values[0]).toBe('msg-6');
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
it('should prefill scoped attributes across multiple overflow buffers', () => {
|
|
516
|
+
const capacity = 8;
|
|
517
|
+
const usableCapacity = capacity - RESERVED_ROWS; // 6
|
|
518
|
+
|
|
519
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
|
|
520
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
521
|
+
|
|
522
|
+
buffer._scopeValues = Object.freeze({
|
|
523
|
+
requestId: 'req-xyz',
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
// Write enough to create 2 overflow buffers
|
|
527
|
+
// First buffer: 6 entries (usableCapacity), overflow 1: 8 entries (full capacity), overflow 2: 1 entry
|
|
528
|
+
const entriesToWrite = usableCapacity + capacity + 1; // 6 + 8 + 1 = 15
|
|
529
|
+
for (let i = 0; i < entriesToWrite; i++) {
|
|
530
|
+
logger.info(`msg-${i}`);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
expect(buffer._overflow).toBeDefined();
|
|
534
|
+
expect(buffer._overflow?._overflow).toBeDefined();
|
|
535
|
+
|
|
536
|
+
const overflow1 = requireOverflowBuffer(buffer, 'multiple-overflow-1');
|
|
537
|
+
const overflow2 = requireOverflowBuffer(overflow1, 'multiple-overflow-2');
|
|
538
|
+
const overflow1Probe = overflow1 as AnySpanBuffer & LazyColumnProbe;
|
|
539
|
+
const overflow2Probe = overflow2 as AnySpanBuffer & LazyColumnProbe;
|
|
540
|
+
|
|
541
|
+
// Columns in scope but never written directly stay unallocated (lazy)
|
|
542
|
+
expect(overflow1Probe._requestId_values).toBeUndefined();
|
|
543
|
+
expect(overflow2Probe._requestId_values).toBeUndefined();
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
it('only prefills columns present in _scopeValues, not all schema columns', () => {
|
|
547
|
+
const capacity = 8;
|
|
548
|
+
const usableCapacity = capacity - RESERVED_ROWS; // 6
|
|
549
|
+
|
|
550
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
|
|
551
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
552
|
+
|
|
553
|
+
// Set scope for ONLY userId and requestId, NOT operation or duration or success
|
|
554
|
+
buffer._scopeValues = Object.freeze({
|
|
555
|
+
userId: 'user-789',
|
|
556
|
+
requestId: 'req-abc',
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
// Trigger overflow
|
|
560
|
+
for (let i = 0; i < usableCapacity + 1; i++) {
|
|
561
|
+
logger.info(`msg-${i}`);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const overflowBuffer = requireOverflowBuffer(buffer, 'scope-columns');
|
|
565
|
+
const overflowProbe = overflowBuffer as AnySpanBuffer & LazyColumnProbe;
|
|
566
|
+
|
|
567
|
+
// Columns in _scopeValues but NEVER written to directly stay unallocated (lazy)
|
|
568
|
+
expect(overflowProbe._userId_values).toBeUndefined();
|
|
569
|
+
expect(overflowProbe._requestId_values).toBeUndefined();
|
|
570
|
+
|
|
571
|
+
// Columns NOT in _scopeValues also stay unallocated (lazy)
|
|
572
|
+
expect(overflowProbe._operation_values).toBeUndefined();
|
|
573
|
+
expect(overflowProbe._duration_values).toBeUndefined();
|
|
574
|
+
expect(overflowProbe._success_values).toBeUndefined();
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
it('does not allocate columns that are only in scope (lazy allocation)', () => {
|
|
578
|
+
const capacity = 8;
|
|
579
|
+
const usableCapacity = capacity - RESERVED_ROWS;
|
|
580
|
+
|
|
581
|
+
const buffer = createSpanBuffer(testSchema, createTestTraceRoot('test-trace'), DEFAULT_METADATA, capacity);
|
|
582
|
+
const logger = createSpanLogger(testSchema, buffer);
|
|
583
|
+
|
|
584
|
+
// Set scope for userId but NEVER call .userId() directly
|
|
585
|
+
buffer._scopeValues = Object.freeze({
|
|
586
|
+
userId: 'scope-only-user',
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
// Write entries without touching userId column
|
|
590
|
+
for (let i = 0; i < usableCapacity + 1; i++) {
|
|
591
|
+
logger.info(`msg-${i}`);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Verify overflow happened
|
|
595
|
+
expect(buffer._overflow).toBeDefined();
|
|
596
|
+
const overflowBuffer = requireOverflowBuffer(buffer, 'lazy-scope-only');
|
|
597
|
+
const rootProbe = buffer as AnySpanBuffer & LazyColumnProbe;
|
|
598
|
+
const overflowProbe = overflowBuffer as AnySpanBuffer & LazyColumnProbe;
|
|
599
|
+
|
|
600
|
+
// CRITICAL: prefill checks the PRIVATE property _userId_values
|
|
601
|
+
// This prevents triggering the lazy getter and allocating memory
|
|
602
|
+
// Since userId was only in scope (never written directly), it stays unallocated
|
|
603
|
+
|
|
604
|
+
// Verify column was NOT allocated (lazy allocation preserved)
|
|
605
|
+
expect(rootProbe._userId_values).toBeUndefined();
|
|
606
|
+
expect(overflowProbe._userId_values).toBeUndefined();
|
|
607
|
+
|
|
608
|
+
// Accessing via the public getter would trigger allocation
|
|
609
|
+
// (but we verify it's undefined before triggering the getter)
|
|
610
|
+
});
|
|
611
|
+
});
|
|
612
|
+
});
|