@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,544 @@
|
|
|
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 { shouldTuneCapacity } from '../capacityTuning.js';
|
|
5
|
+
import { createSpanLogger } from '../codegen/spanLoggerGenerator.js';
|
|
6
|
+
import { DEFAULT_METADATA } from '../opContext/defineOp.js';
|
|
7
|
+
import { S } from '../schema/builder.js';
|
|
8
|
+
import { LogSchema } from '../schema/LogSchema.js';
|
|
9
|
+
import { mergeWithSystemSchema } from '../schema/systemSchema.js';
|
|
10
|
+
import { createSpanBuffer, getSpanBufferClass } from '../spanBuffer.js';
|
|
11
|
+
import type { SpanBufferStats } from '../spanBufferStats.js';
|
|
12
|
+
|
|
13
|
+
import { createTestTraceRoot, createTestTracerOptions } from './test-helpers.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create mock SpanBufferStats for testing capacity tuning.
|
|
17
|
+
*
|
|
18
|
+
* Per agent-todo/opgroup-refactor.md lines 58-70, 525-547:
|
|
19
|
+
* Stats are on SpanBufferClass.stats (static property), NOT on LogBinding.
|
|
20
|
+
*/
|
|
21
|
+
function createMockStats(overrides: Partial<SpanBufferStats> = {}): SpanBufferStats {
|
|
22
|
+
return {
|
|
23
|
+
capacity: overrides.capacity ?? DEFAULT_BUFFER_CAPACITY,
|
|
24
|
+
totalWrites: overrides.totalWrites ?? 0,
|
|
25
|
+
spansCreated: overrides.spansCreated ?? 0,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Compute utilization for testing
|
|
31
|
+
* Utilization = totalWrites / (spansCreated * usableRowsPerSpan)
|
|
32
|
+
*/
|
|
33
|
+
function computeUtilization(stats: SpanBufferStats): number {
|
|
34
|
+
const usableRowsPerSpan = stats.capacity - 2;
|
|
35
|
+
return stats.spansCreated > 0 ? stats.totalWrites / (stats.spansCreated * usableRowsPerSpan) : 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
describe('Capacity Tuning Algorithm', () => {
|
|
39
|
+
let stats: SpanBufferStats;
|
|
40
|
+
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
stats = createMockStats();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('shouldTuneCapacity - Success Cases', () => {
|
|
46
|
+
it('should increase capacity when utilization > 150%', () => {
|
|
47
|
+
// 10 spans, capacity 8, usable rows = 6
|
|
48
|
+
// At 150% utilization: 10 * 6 * 1.5 = 90 writes
|
|
49
|
+
// At 160% utilization: 10 * 6 * 1.6 = 96 writes
|
|
50
|
+
stats.spansCreated = 10;
|
|
51
|
+
stats.capacity = 8;
|
|
52
|
+
stats.totalWrites = 96; // 160% utilization
|
|
53
|
+
|
|
54
|
+
const initialCapacity = stats.capacity;
|
|
55
|
+
shouldTuneCapacity(stats);
|
|
56
|
+
|
|
57
|
+
expect(stats.capacity).toBe(initialCapacity * 2); // Doubled
|
|
58
|
+
expect(stats.totalWrites).toBe(0); // Reset
|
|
59
|
+
expect(stats.spansCreated).toBe(0); // Reset
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should decrease capacity when utilization < 50%', () => {
|
|
63
|
+
// 10 spans, capacity 32, usable rows = 30
|
|
64
|
+
// At 50% utilization: 10 * 30 * 0.5 = 150 writes
|
|
65
|
+
// At 40% utilization: 10 * 30 * 0.4 = 120 writes
|
|
66
|
+
stats.spansCreated = 10;
|
|
67
|
+
stats.capacity = 32;
|
|
68
|
+
stats.totalWrites = 120; // 40% utilization
|
|
69
|
+
|
|
70
|
+
shouldTuneCapacity(stats);
|
|
71
|
+
|
|
72
|
+
expect(stats.capacity).toBe(16); // Halved
|
|
73
|
+
expect(stats.totalWrites).toBe(0); // Reset
|
|
74
|
+
expect(stats.spansCreated).toBe(0); // Reset
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should double capacity from default to 2x', () => {
|
|
78
|
+
stats.spansCreated = 10;
|
|
79
|
+
stats.capacity = DEFAULT_BUFFER_CAPACITY; // 8
|
|
80
|
+
const usableRows = stats.capacity - 2; // 6
|
|
81
|
+
stats.totalWrites = Math.floor(usableRows * 10 * 1.6); // 160% utilization
|
|
82
|
+
|
|
83
|
+
shouldTuneCapacity(stats);
|
|
84
|
+
|
|
85
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should double capacity from 128 to 256', () => {
|
|
89
|
+
stats.spansCreated = 10;
|
|
90
|
+
stats.capacity = 128;
|
|
91
|
+
const usableRows = stats.capacity - 2; // 126
|
|
92
|
+
stats.totalWrites = Math.floor(usableRows * 10 * 1.6); // 160% utilization
|
|
93
|
+
|
|
94
|
+
shouldTuneCapacity(stats);
|
|
95
|
+
|
|
96
|
+
expect(stats.capacity).toBe(256);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should halve capacity from 4x to 2x default', () => {
|
|
100
|
+
stats.spansCreated = 10;
|
|
101
|
+
stats.capacity = DEFAULT_BUFFER_CAPACITY * 4; // 32
|
|
102
|
+
const usableRows = stats.capacity - 2; // 30
|
|
103
|
+
stats.totalWrites = Math.floor(usableRows * 10 * 0.4); // 40% utilization
|
|
104
|
+
|
|
105
|
+
shouldTuneCapacity(stats);
|
|
106
|
+
|
|
107
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('shouldTuneCapacity - Edge Cases', () => {
|
|
112
|
+
it('should not tune with insufficient spans (< 10)', () => {
|
|
113
|
+
stats.spansCreated = 9;
|
|
114
|
+
stats.capacity = 8;
|
|
115
|
+
stats.totalWrites = 1000; // Very high utilization, but not enough spans
|
|
116
|
+
|
|
117
|
+
const initialCapacity = stats.capacity;
|
|
118
|
+
shouldTuneCapacity(stats);
|
|
119
|
+
|
|
120
|
+
expect(stats.capacity).toBe(initialCapacity); // Unchanged
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should not tune when utilization is in stable zone (50-150%)', () => {
|
|
124
|
+
stats.spansCreated = 10;
|
|
125
|
+
stats.capacity = 8;
|
|
126
|
+
const usableRows = stats.capacity - 2; // 6
|
|
127
|
+
stats.totalWrites = usableRows * 10; // Exactly 100% utilization
|
|
128
|
+
|
|
129
|
+
const initialCapacity = stats.capacity;
|
|
130
|
+
shouldTuneCapacity(stats);
|
|
131
|
+
|
|
132
|
+
expect(stats.capacity).toBe(initialCapacity);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should cap capacity at 1024', () => {
|
|
136
|
+
stats.spansCreated = 10;
|
|
137
|
+
stats.capacity = 1024;
|
|
138
|
+
const usableRows = stats.capacity - 2;
|
|
139
|
+
stats.totalWrites = Math.floor(usableRows * 10 * 2); // 200% utilization
|
|
140
|
+
|
|
141
|
+
shouldTuneCapacity(stats);
|
|
142
|
+
|
|
143
|
+
expect(stats.capacity).toBe(1024); // Cannot increase beyond 1024
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should cap capacity at minimum (8) when decreasing', () => {
|
|
147
|
+
stats.spansCreated = 10;
|
|
148
|
+
stats.capacity = 8;
|
|
149
|
+
stats.totalWrites = 10; // Very low utilization
|
|
150
|
+
|
|
151
|
+
shouldTuneCapacity(stats);
|
|
152
|
+
|
|
153
|
+
expect(stats.capacity).toBe(8); // Cannot decrease below 8
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should handle exactly 150% utilization (boundary - no increase)', () => {
|
|
157
|
+
stats.spansCreated = 10;
|
|
158
|
+
stats.capacity = 8;
|
|
159
|
+
const usableRows = stats.capacity - 2; // 6
|
|
160
|
+
stats.totalWrites = usableRows * 10 * 1.5; // Exactly 150%
|
|
161
|
+
|
|
162
|
+
const initialCapacity = stats.capacity;
|
|
163
|
+
shouldTuneCapacity(stats);
|
|
164
|
+
|
|
165
|
+
expect(stats.capacity).toBe(initialCapacity); // > 150%, not >= 150%
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should handle exactly 50% utilization (boundary - no decrease)', () => {
|
|
169
|
+
stats.spansCreated = 10;
|
|
170
|
+
stats.capacity = 32;
|
|
171
|
+
const usableRows = stats.capacity - 2;
|
|
172
|
+
stats.totalWrites = usableRows * 10 * 0.5; // Exactly 50%
|
|
173
|
+
|
|
174
|
+
const initialCapacity = stats.capacity;
|
|
175
|
+
shouldTuneCapacity(stats);
|
|
176
|
+
|
|
177
|
+
expect(stats.capacity).toBe(initialCapacity); // < 50%, not <= 50%
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should tune at 151% utilization', () => {
|
|
181
|
+
stats.spansCreated = 100;
|
|
182
|
+
stats.capacity = 8;
|
|
183
|
+
const usableRows = stats.capacity - 2; // 6
|
|
184
|
+
stats.totalWrites = Math.floor(usableRows * 100 * 1.51); // 151% utilization
|
|
185
|
+
|
|
186
|
+
shouldTuneCapacity(stats);
|
|
187
|
+
|
|
188
|
+
expect(stats.capacity).toBe(16); // Doubled
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('should tune at 49% utilization', () => {
|
|
192
|
+
stats.spansCreated = 100;
|
|
193
|
+
stats.capacity = 32;
|
|
194
|
+
const usableRows = stats.capacity - 2;
|
|
195
|
+
stats.totalWrites = Math.floor(usableRows * 100 * 0.49); // 49% utilization
|
|
196
|
+
|
|
197
|
+
shouldTuneCapacity(stats);
|
|
198
|
+
|
|
199
|
+
expect(stats.capacity).toBe(16); // Halved
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should handle zero writes', () => {
|
|
203
|
+
stats.spansCreated = 10;
|
|
204
|
+
stats.totalWrites = 0;
|
|
205
|
+
stats.capacity = 32;
|
|
206
|
+
|
|
207
|
+
shouldTuneCapacity(stats);
|
|
208
|
+
|
|
209
|
+
expect(stats.capacity).toBe(16); // Should decrease (0% utilization < 50%)
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('should handle zero spans (no tuning possible)', () => {
|
|
213
|
+
stats.spansCreated = 0;
|
|
214
|
+
stats.totalWrites = 1000;
|
|
215
|
+
stats.capacity = 8;
|
|
216
|
+
|
|
217
|
+
const initialCapacity = stats.capacity;
|
|
218
|
+
shouldTuneCapacity(stats);
|
|
219
|
+
|
|
220
|
+
expect(stats.capacity).toBe(initialCapacity); // Unchanged - not enough spans
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe('shouldTuneCapacity - Capacity Bounds', () => {
|
|
225
|
+
it('should not increase beyond 1024 even with extreme utilization', () => {
|
|
226
|
+
stats.spansCreated = 10;
|
|
227
|
+
stats.capacity = 1024;
|
|
228
|
+
stats.totalWrites = 1000000; // Extreme utilization
|
|
229
|
+
|
|
230
|
+
shouldTuneCapacity(stats);
|
|
231
|
+
|
|
232
|
+
expect(stats.capacity).toBe(1024);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should cap at 1024 when doubling from 512', () => {
|
|
236
|
+
stats.spansCreated = 10;
|
|
237
|
+
stats.capacity = 512;
|
|
238
|
+
const usableRows = stats.capacity - 2;
|
|
239
|
+
stats.totalWrites = Math.floor(usableRows * 10 * 2); // 200% utilization
|
|
240
|
+
|
|
241
|
+
shouldTuneCapacity(stats);
|
|
242
|
+
|
|
243
|
+
expect(stats.capacity).toBe(1024); // Capped at 1024
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should not decrease below minimum', () => {
|
|
247
|
+
stats.spansCreated = 10;
|
|
248
|
+
stats.capacity = 8;
|
|
249
|
+
stats.totalWrites = 1; // Very low utilization
|
|
250
|
+
|
|
251
|
+
shouldTuneCapacity(stats);
|
|
252
|
+
|
|
253
|
+
expect(stats.capacity).toBe(8);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it('should cap at minimum when halving from 16', () => {
|
|
257
|
+
stats.spansCreated = 10;
|
|
258
|
+
stats.capacity = 16;
|
|
259
|
+
const usableRows = stats.capacity - 2;
|
|
260
|
+
stats.totalWrites = Math.floor(usableRows * 10 * 0.3); // 30% utilization
|
|
261
|
+
|
|
262
|
+
shouldTuneCapacity(stats);
|
|
263
|
+
|
|
264
|
+
expect(stats.capacity).toBe(8);
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
describe('Stats Reset After Tuning', () => {
|
|
269
|
+
it('should reset stats after increasing capacity', () => {
|
|
270
|
+
stats.spansCreated = 10;
|
|
271
|
+
stats.capacity = 8;
|
|
272
|
+
stats.totalWrites = 100; // High utilization
|
|
273
|
+
|
|
274
|
+
shouldTuneCapacity(stats);
|
|
275
|
+
|
|
276
|
+
expect(stats.totalWrites).toBe(0);
|
|
277
|
+
expect(stats.spansCreated).toBe(0);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('should reset stats after decreasing capacity', () => {
|
|
281
|
+
stats.spansCreated = 10;
|
|
282
|
+
stats.capacity = 32;
|
|
283
|
+
stats.totalWrites = 50; // Low utilization
|
|
284
|
+
|
|
285
|
+
shouldTuneCapacity(stats);
|
|
286
|
+
|
|
287
|
+
expect(stats.totalWrites).toBe(0);
|
|
288
|
+
expect(stats.spansCreated).toBe(0);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('should not reset stats when no tuning occurs', () => {
|
|
292
|
+
stats.spansCreated = 5; // Not enough spans
|
|
293
|
+
stats.totalWrites = 1000;
|
|
294
|
+
|
|
295
|
+
shouldTuneCapacity(stats);
|
|
296
|
+
|
|
297
|
+
expect(stats.totalWrites).toBe(1000); // Unchanged
|
|
298
|
+
expect(stats.spansCreated).toBe(5); // Unchanged
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
describe('Multiple Tuning Cycles', () => {
|
|
303
|
+
it('should handle multiple increases correctly', () => {
|
|
304
|
+
// Start at default (capacity=8, usableRows=6)
|
|
305
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY);
|
|
306
|
+
|
|
307
|
+
// First increase: need >150% utilization
|
|
308
|
+
// usableRows=6, spansCreated=10 → need totalWrites > 10*6*1.5 = 90
|
|
309
|
+
stats.spansCreated = 10;
|
|
310
|
+
stats.totalWrites = 100; // 100/(10*6) = 1.67 > 1.5 → grows to 16
|
|
311
|
+
shouldTuneCapacity(stats);
|
|
312
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2); // 16
|
|
313
|
+
|
|
314
|
+
// Second increase: capacity=16, usableRows=14
|
|
315
|
+
// need totalWrites > 10*14*1.5 = 210
|
|
316
|
+
stats.spansCreated = 10;
|
|
317
|
+
stats.totalWrites = 220; // 220/(10*14) = 1.57 > 1.5 → grows to 32
|
|
318
|
+
shouldTuneCapacity(stats);
|
|
319
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 4); // 32
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it('should handle multiple decreases correctly', () => {
|
|
323
|
+
stats.capacity = DEFAULT_BUFFER_CAPACITY * 8; // Start high (64)
|
|
324
|
+
|
|
325
|
+
// First decrease
|
|
326
|
+
stats.spansCreated = 10;
|
|
327
|
+
stats.totalWrites = 50; // Low utilization
|
|
328
|
+
shouldTuneCapacity(stats);
|
|
329
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 4); // 32
|
|
330
|
+
|
|
331
|
+
// Second decrease
|
|
332
|
+
stats.spansCreated = 10;
|
|
333
|
+
stats.totalWrites = 50;
|
|
334
|
+
shouldTuneCapacity(stats);
|
|
335
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2); // 16
|
|
336
|
+
|
|
337
|
+
// Third decrease
|
|
338
|
+
stats.spansCreated = 10;
|
|
339
|
+
stats.totalWrites = 20;
|
|
340
|
+
shouldTuneCapacity(stats);
|
|
341
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY); // 8
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
it('should handle increase then stabilize', () => {
|
|
345
|
+
// Start at default
|
|
346
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY); // 8
|
|
347
|
+
|
|
348
|
+
// Increase due to high utilization
|
|
349
|
+
stats.spansCreated = 10;
|
|
350
|
+
stats.totalWrites = 100;
|
|
351
|
+
shouldTuneCapacity(stats);
|
|
352
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2); // 16
|
|
353
|
+
|
|
354
|
+
// Now with new capacity, same workload should be stable
|
|
355
|
+
// 10 spans * (16-2) usable * 100% = 140 writes ideal
|
|
356
|
+
stats.spansCreated = 10;
|
|
357
|
+
stats.totalWrites = 140; // 100% utilization - stable zone
|
|
358
|
+
shouldTuneCapacity(stats);
|
|
359
|
+
expect(stats.capacity).toBe(DEFAULT_BUFFER_CAPACITY * 2); // Still 16
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
describe('Property-Based Testing for Utilization Formula', () => {
|
|
364
|
+
it('should verify all mathematical invariants for arbitrary inputs', () => {
|
|
365
|
+
fc.assert(
|
|
366
|
+
fc.property(
|
|
367
|
+
fc.record({
|
|
368
|
+
totalWrites: fc.integer({ min: 0, max: 10000 }),
|
|
369
|
+
spansCreated: fc.integer({ min: 0, max: 1000 }),
|
|
370
|
+
initialCapacity: fc.constantFrom(8, 16, 32, 64, 128, 256, 512, 1024),
|
|
371
|
+
}),
|
|
372
|
+
({ totalWrites, spansCreated, initialCapacity }) => {
|
|
373
|
+
// Set up stats state
|
|
374
|
+
stats.totalWrites = totalWrites;
|
|
375
|
+
stats.spansCreated = spansCreated;
|
|
376
|
+
stats.capacity = initialCapacity;
|
|
377
|
+
|
|
378
|
+
const beforeCapacity = stats.capacity;
|
|
379
|
+
const utilization = computeUtilization(stats);
|
|
380
|
+
shouldTuneCapacity(stats);
|
|
381
|
+
const afterCapacity = stats.capacity;
|
|
382
|
+
|
|
383
|
+
// Core invariants that must always hold
|
|
384
|
+
expect(afterCapacity).toBeGreaterThanOrEqual(8);
|
|
385
|
+
expect(afterCapacity).toBeLessThanOrEqual(1024);
|
|
386
|
+
expect(afterCapacity & (afterCapacity - 1)).toBe(0); // Power of 2
|
|
387
|
+
|
|
388
|
+
// Verify exact behavior matches specification
|
|
389
|
+
const hasEnoughSpans = spansCreated >= 10;
|
|
390
|
+
|
|
391
|
+
if (hasEnoughSpans) {
|
|
392
|
+
if (utilization > 1.5 && beforeCapacity < 1024) {
|
|
393
|
+
expect(afterCapacity).toBe(Math.min(beforeCapacity * 2, 1024));
|
|
394
|
+
} else if (utilization < 0.5 && beforeCapacity > 8) {
|
|
395
|
+
expect(afterCapacity).toBe(Math.max(8, beforeCapacity / 2));
|
|
396
|
+
} else {
|
|
397
|
+
expect(afterCapacity).toBe(beforeCapacity);
|
|
398
|
+
}
|
|
399
|
+
} else {
|
|
400
|
+
expect(afterCapacity).toBe(beforeCapacity);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Stats reset invariant: if capacity changed, stats are reset
|
|
404
|
+
if (afterCapacity !== beforeCapacity) {
|
|
405
|
+
expect(stats.totalWrites).toBe(0);
|
|
406
|
+
expect(stats.spansCreated).toBe(0);
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
),
|
|
410
|
+
{ numRuns: 1000 },
|
|
411
|
+
);
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it('should verify anti-flip-flop property: after tuning, opposite action is not triggered', () => {
|
|
415
|
+
fc.assert(
|
|
416
|
+
fc.property(
|
|
417
|
+
fc.record({
|
|
418
|
+
spansCreated: fc.integer({ min: 10, max: 100 }),
|
|
419
|
+
initialCapacity: fc.constantFrom(8, 16, 32, 64, 128, 256, 512),
|
|
420
|
+
utilizationPercent: fc.integer({ min: 1, max: 300 }),
|
|
421
|
+
}),
|
|
422
|
+
({ spansCreated, initialCapacity, utilizationPercent }) => {
|
|
423
|
+
stats.spansCreated = spansCreated;
|
|
424
|
+
stats.capacity = initialCapacity;
|
|
425
|
+
|
|
426
|
+
const usableRows = initialCapacity - 2;
|
|
427
|
+
const totalWrites = Math.floor((usableRows * spansCreated * utilizationPercent) / 100);
|
|
428
|
+
stats.totalWrites = totalWrites;
|
|
429
|
+
|
|
430
|
+
const beforeCapacity = stats.capacity;
|
|
431
|
+
shouldTuneCapacity(stats);
|
|
432
|
+
const afterCapacity = stats.capacity;
|
|
433
|
+
|
|
434
|
+
if (afterCapacity !== beforeCapacity) {
|
|
435
|
+
// Simulate the SAME workload (same totalWrites) with the new capacity
|
|
436
|
+
// This tests: if we tune and then see the same workload again,
|
|
437
|
+
// we should NOT immediately trigger the opposite tuning action
|
|
438
|
+
// Note: stats are reset after tuning, so use saved totalWrites
|
|
439
|
+
const newUsableRows = afterCapacity - 2;
|
|
440
|
+
const newUtilization = totalWrites / (spansCreated * newUsableRows);
|
|
441
|
+
|
|
442
|
+
if (afterCapacity > beforeCapacity) {
|
|
443
|
+
// We grew because utilization was >150%
|
|
444
|
+
// After growing, the new utilization should NOT trigger shrinking (<50%)
|
|
445
|
+
// This is the anti-flip-flop property
|
|
446
|
+
expect(newUtilization).toBeGreaterThanOrEqual(0.5);
|
|
447
|
+
} else {
|
|
448
|
+
// We shrunk because utilization was <50%
|
|
449
|
+
// After shrinking, the new utilization should NOT trigger growing (>150%)
|
|
450
|
+
expect(newUtilization).toBeLessThanOrEqual(1.5);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
),
|
|
455
|
+
{ numRuns: 500 },
|
|
456
|
+
);
|
|
457
|
+
});
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
describe('Integration with SpanLogger overflow', () => {
|
|
461
|
+
const userIntegrationSchema = new LogSchema({
|
|
462
|
+
testField: S.category(),
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
const integrationSchema = new LogSchema(
|
|
466
|
+
mergeWithSystemSchema({
|
|
467
|
+
testField: S.category(),
|
|
468
|
+
}),
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
it('should tune capacity based on utilization after many spans', () => {
|
|
472
|
+
const SpanBufferClass = getSpanBufferClass(integrationSchema);
|
|
473
|
+
const stats = SpanBufferClass.stats;
|
|
474
|
+
|
|
475
|
+
// Reset stats
|
|
476
|
+
const initialCapacity = 8;
|
|
477
|
+
stats.capacity = initialCapacity;
|
|
478
|
+
stats.totalWrites = 0;
|
|
479
|
+
stats.spansCreated = 0;
|
|
480
|
+
|
|
481
|
+
// Simulate 10+ spans with high utilization (>150%)
|
|
482
|
+
// Capacity 8, usable rows = 6
|
|
483
|
+
// 150% utilization = 9 writes per span
|
|
484
|
+
// 160% utilization = 9.6 writes per span
|
|
485
|
+
for (let span = 0; span < 12; span++) {
|
|
486
|
+
const buffer = createSpanBuffer(
|
|
487
|
+
integrationSchema,
|
|
488
|
+
createTestTraceRoot('test-trace'),
|
|
489
|
+
DEFAULT_METADATA,
|
|
490
|
+
undefined,
|
|
491
|
+
);
|
|
492
|
+
const logger = createSpanLogger(integrationSchema, buffer);
|
|
493
|
+
|
|
494
|
+
// Write 10 entries per span (160% utilization of 6 usable rows)
|
|
495
|
+
for (let i = 0; i < 10; i++) {
|
|
496
|
+
logger.info(`message ${i}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// After 12 spans with 10 writes each = 120 writes
|
|
501
|
+
// Utilization = 120 / (12 * 6) = 166% > 150%
|
|
502
|
+
// Should have triggered capacity increase
|
|
503
|
+
expect(stats.capacity).toBeGreaterThan(initialCapacity);
|
|
504
|
+
expect(stats.capacity & (stats.capacity - 1)).toBe(0); // Power of 2
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('should call onStatsWillResetFor before stats reset during tuning', async () => {
|
|
508
|
+
const { defineOpContext } = await import('../defineOpContext.js');
|
|
509
|
+
const { TestTracer } = await import('../tracers/TestTracer.js');
|
|
510
|
+
|
|
511
|
+
const ctx = defineOpContext({
|
|
512
|
+
logSchema: userIntegrationSchema,
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
const tracer = new TestTracer(ctx, { ...createTestTracerOptions() });
|
|
516
|
+
const { trace } = tracer;
|
|
517
|
+
|
|
518
|
+
const SpanBufferClass = getSpanBufferClass(integrationSchema);
|
|
519
|
+
const stats = SpanBufferClass.stats;
|
|
520
|
+
stats.capacity = 8;
|
|
521
|
+
stats.totalWrites = 0;
|
|
522
|
+
stats.spansCreated = 0;
|
|
523
|
+
|
|
524
|
+
// Execute multiple traces to accumulate enough spans for tuning
|
|
525
|
+
for (let t = 0; t < 15; t++) {
|
|
526
|
+
trace(`test-trace-${t}`, (ctx) => {
|
|
527
|
+
// Write many entries to trigger high utilization
|
|
528
|
+
for (let i = 0; i < 15; i++) {
|
|
529
|
+
ctx.log.info(`entry ${i}`);
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// If capacity was tuned, we should have stats snapshots
|
|
535
|
+
// (captured in onStatsWillResetFor before reset)
|
|
536
|
+
if (tracer.statsSnapshots.length > 0) {
|
|
537
|
+
const firstSnapshot = tracer.statsSnapshots[0];
|
|
538
|
+
expect(firstSnapshot.totalWrites).toBeGreaterThan(0);
|
|
539
|
+
expect(firstSnapshot.capacity).toBeGreaterThanOrEqual(8);
|
|
540
|
+
expect(firstSnapshot.buffer).toBeDefined();
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
});
|
|
544
|
+
});
|