@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,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RetryPolicy - configures retry behavior for transient failures.
|
|
3
|
+
*
|
|
4
|
+
* Carried by TransientError instances. Op class (in LMAO) reads policy
|
|
5
|
+
* from transient errors to handle retry loop.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Define error with default policy
|
|
10
|
+
* const RATE_LIMITED = Transient<{ retryAfter?: number }>('RATE_LIMITED', exponentialBackoff(5));
|
|
11
|
+
*
|
|
12
|
+
* // Usage with default policy
|
|
13
|
+
* ctx.err(RATE_LIMITED({ retryAfter: 60000 }));
|
|
14
|
+
*
|
|
15
|
+
* // Override policy for this call
|
|
16
|
+
* ctx.err(RATE_LIMITED({ retryAfter: 60000 }, fixedDelay(1, 60000)));
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export interface RetryPolicy {
|
|
20
|
+
/** Backoff strategy */
|
|
21
|
+
backoff: 'exponential' | 'linear' | 'fixed';
|
|
22
|
+
/** Maximum retry attempts (including initial attempt) */
|
|
23
|
+
maxAttempts: number;
|
|
24
|
+
/** Base delay in milliseconds */
|
|
25
|
+
baseDelayMs: number;
|
|
26
|
+
/** Maximum delay cap in milliseconds (optional, defaults to 30000) */
|
|
27
|
+
maxDelayMs?: number;
|
|
28
|
+
/** Add randomness to delay (default: true) */
|
|
29
|
+
jitter?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Create linear backoff policy.
|
|
34
|
+
* Delay increases linearly: baseDelay * attempt
|
|
35
|
+
*
|
|
36
|
+
* @example linearBackoff(3) → 100ms, 200ms, 300ms
|
|
37
|
+
* @example linearBackoff(5, 200) → 200ms, 400ms, 600ms, 800ms, 1000ms
|
|
38
|
+
*/
|
|
39
|
+
export function linearBackoff(maxAttempts: number, baseDelayMs = 100): RetryPolicy {
|
|
40
|
+
return {
|
|
41
|
+
backoff: 'linear',
|
|
42
|
+
maxAttempts,
|
|
43
|
+
baseDelayMs,
|
|
44
|
+
jitter: true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create exponential backoff policy.
|
|
50
|
+
* Delay doubles each attempt: baseDelay * 2^(attempt-1)
|
|
51
|
+
*
|
|
52
|
+
* @example exponentialBackoff(3) → 100ms, 200ms, 400ms
|
|
53
|
+
* @example exponentialBackoff(5, 50) → 50ms, 100ms, 200ms, 400ms, 800ms
|
|
54
|
+
*/
|
|
55
|
+
export function exponentialBackoff(maxAttempts: number, baseDelayMs = 100): RetryPolicy {
|
|
56
|
+
return {
|
|
57
|
+
backoff: 'exponential',
|
|
58
|
+
maxAttempts,
|
|
59
|
+
baseDelayMs,
|
|
60
|
+
jitter: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Create fixed delay policy.
|
|
66
|
+
* Same delay between each attempt.
|
|
67
|
+
*
|
|
68
|
+
* @example fixedDelay(3, 1000) → 1000ms, 1000ms, 1000ms
|
|
69
|
+
* @example fixedDelay(1, 60000) → single retry after 60s (for rate limit Retry-After)
|
|
70
|
+
*/
|
|
71
|
+
export function fixedDelay(maxAttempts: number, delayMs = 1000): RetryPolicy {
|
|
72
|
+
return {
|
|
73
|
+
backoff: 'fixed',
|
|
74
|
+
maxAttempts,
|
|
75
|
+
baseDelayMs: delayMs,
|
|
76
|
+
jitter: false, // Fixed delay typically doesn't want jitter
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Merge base policy with override.
|
|
82
|
+
* Override fields take precedence.
|
|
83
|
+
*/
|
|
84
|
+
export function mergePolicy(base: RetryPolicy, override?: Partial<RetryPolicy>): RetryPolicy {
|
|
85
|
+
if (!override) return base;
|
|
86
|
+
return { ...base, ...override };
|
|
87
|
+
}
|
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background flush scheduler with adaptive flushing
|
|
3
|
+
*
|
|
4
|
+
* Per specs/lmao/01b2_buffer_self_tuning.md:
|
|
5
|
+
* - Adaptive flush intervals based on capacity, time, memory pressure
|
|
6
|
+
* - Idle detection for opportunistic flushing
|
|
7
|
+
* - Background processing (cold path)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Column, type Table, tableFromColumns } from '@uwdata/flechette';
|
|
11
|
+
import type { CapacityStatsEntry } from './arrow/capacityStats.js';
|
|
12
|
+
import { convertSpanTreeToArrowTable } from './convertToArrow.js';
|
|
13
|
+
import type { SpanBufferConstructor } from './spanBuffer.js';
|
|
14
|
+
import type { AnySpanBuffer, OpMetadata } from './types.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Number of flushes before logging capacity stats.
|
|
18
|
+
* Capacity stats are logged periodically to avoid overhead on every flush.
|
|
19
|
+
*/
|
|
20
|
+
const CAPACITY_STATS_FLUSH_INTERVAL = 100;
|
|
21
|
+
|
|
22
|
+
function isSpanBufferConstructor(value: unknown): value is SpanBufferConstructor {
|
|
23
|
+
return typeof value === 'function' && typeof Reflect.get(value, 'stats') === 'object';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isNodeTimer(value: unknown): value is NodeJS.Timeout {
|
|
27
|
+
return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'hasRef') === 'function';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function mergeTables(first: Table, rest: Table[]): Table {
|
|
31
|
+
if (rest.length === 0) return first;
|
|
32
|
+
|
|
33
|
+
const names = first.names as string[];
|
|
34
|
+
const merged: [string, Column<unknown>][] = names.map((name, index) => {
|
|
35
|
+
const batches = [...(first.getChildAt(index)?.data ?? [])];
|
|
36
|
+
for (const table of rest) {
|
|
37
|
+
const col = table.getChild(name);
|
|
38
|
+
if (!col) continue;
|
|
39
|
+
batches.push(...col.data);
|
|
40
|
+
}
|
|
41
|
+
return [name, new Column(batches)];
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return tableFromColumns(merged);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Flush handler function type
|
|
49
|
+
* Called when buffers are ready to be flushed
|
|
50
|
+
*/
|
|
51
|
+
export type FlushHandler = (table: Table, metadata: FlushMetadata) => Promise<void> | void;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Metadata about the flush operation
|
|
55
|
+
*/
|
|
56
|
+
export interface FlushMetadata {
|
|
57
|
+
totalRows: number;
|
|
58
|
+
totalBuffers: number;
|
|
59
|
+
flushReason: 'capacity' | 'time' | 'memory' | 'idle' | 'manual';
|
|
60
|
+
timestamp: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Flush scheduler configuration
|
|
65
|
+
*/
|
|
66
|
+
export interface FlushSchedulerConfig {
|
|
67
|
+
/**
|
|
68
|
+
* Maximum time between flushes (milliseconds)
|
|
69
|
+
* Default: 10000 (10 seconds)
|
|
70
|
+
*/
|
|
71
|
+
maxFlushInterval?: number;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Minimum time between flushes (milliseconds)
|
|
75
|
+
* Default: 1000 (1 second)
|
|
76
|
+
*/
|
|
77
|
+
minFlushInterval?: number;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Capacity threshold for automatic flush (0.0 - 1.0)
|
|
81
|
+
* Flush when buffer is X% full
|
|
82
|
+
* Default: 0.8 (80%)
|
|
83
|
+
*/
|
|
84
|
+
capacityThreshold?: number;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Enable idle detection for opportunistic flushing
|
|
88
|
+
* Default: true
|
|
89
|
+
*/
|
|
90
|
+
idleDetection?: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Idle timeout (milliseconds) - flush if no activity for this duration
|
|
94
|
+
* Default: 5000 (5 seconds)
|
|
95
|
+
*/
|
|
96
|
+
idleTimeout?: number;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Enable memory pressure detection
|
|
100
|
+
* Default: true (Node.js only)
|
|
101
|
+
*/
|
|
102
|
+
memoryPressureDetection?: boolean;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Memory pressure threshold (bytes)
|
|
106
|
+
* Flush when available memory drops below this
|
|
107
|
+
* Default: 100MB
|
|
108
|
+
*/
|
|
109
|
+
memoryPressureThreshold?: number;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Background flush scheduler
|
|
114
|
+
* Manages automatic flushing of span buffers to Arrow tables
|
|
115
|
+
*/
|
|
116
|
+
export class FlushScheduler {
|
|
117
|
+
private config: Required<FlushSchedulerConfig>;
|
|
118
|
+
private handler: FlushHandler;
|
|
119
|
+
|
|
120
|
+
private buffers = new Set<AnySpanBuffer>();
|
|
121
|
+
private lastFlushTime = Date.now();
|
|
122
|
+
private lastActivityTime = Date.now();
|
|
123
|
+
private flushTimer?: NodeJS.Timeout;
|
|
124
|
+
private idleTimer?: NodeJS.Timeout;
|
|
125
|
+
private memoryTimer?: NodeJS.Timeout;
|
|
126
|
+
private isRunning = false;
|
|
127
|
+
|
|
128
|
+
/** Flush counter for periodic capacity stats logging */
|
|
129
|
+
private _flushCount = 0;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Track unique (SpanBufferConstructor, OpMetadata) pairs that have been flushed since last capacity stats log.
|
|
133
|
+
* We use SpanBufferConstructor as the key (for dedup) and store the OpMetadata for building PreEncodedEntry at conversion time.
|
|
134
|
+
* The constructor has static stats property with the capacity stats we need.
|
|
135
|
+
*/
|
|
136
|
+
private _bufferClassesSinceLastStatsLog = new Map<SpanBufferConstructor, OpMetadata>();
|
|
137
|
+
|
|
138
|
+
constructor(handler: FlushHandler, config: FlushSchedulerConfig = {}) {
|
|
139
|
+
this.handler = handler;
|
|
140
|
+
|
|
141
|
+
// Apply defaults
|
|
142
|
+
this.config = {
|
|
143
|
+
maxFlushInterval: config.maxFlushInterval ?? 10000,
|
|
144
|
+
minFlushInterval: config.minFlushInterval ?? 1000,
|
|
145
|
+
capacityThreshold: config.capacityThreshold ?? 0.8,
|
|
146
|
+
idleDetection: config.idleDetection ?? true,
|
|
147
|
+
idleTimeout: config.idleTimeout ?? 5000,
|
|
148
|
+
memoryPressureDetection: config.memoryPressureDetection ?? true,
|
|
149
|
+
memoryPressureThreshold: config.memoryPressureThreshold ?? 100 * 1024 * 1024, // 100MB
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Register a buffer for automatic flushing
|
|
155
|
+
*/
|
|
156
|
+
register(buffer: AnySpanBuffer): void {
|
|
157
|
+
this.buffers.add(buffer);
|
|
158
|
+
this.lastActivityTime = Date.now();
|
|
159
|
+
|
|
160
|
+
// Start scheduler if not running
|
|
161
|
+
if (!this.isRunning) {
|
|
162
|
+
this.start();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Start the flush scheduler
|
|
168
|
+
*/
|
|
169
|
+
start(): void {
|
|
170
|
+
if (this.isRunning) return;
|
|
171
|
+
|
|
172
|
+
this.isRunning = true;
|
|
173
|
+
this.lastFlushTime = Date.now();
|
|
174
|
+
this.lastActivityTime = Date.now();
|
|
175
|
+
|
|
176
|
+
// Set up periodic flush timer
|
|
177
|
+
this.flushTimer = setInterval(() => {
|
|
178
|
+
this.checkFlushConditions();
|
|
179
|
+
}, 1000); // Check every second
|
|
180
|
+
|
|
181
|
+
// Set up idle detection timer
|
|
182
|
+
if (this.config.idleDetection) {
|
|
183
|
+
this.idleTimer = setInterval(() => {
|
|
184
|
+
this.checkIdleFlush();
|
|
185
|
+
}, this.config.idleTimeout);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Set up memory pressure timer (Node.js only)
|
|
189
|
+
if (this.config.memoryPressureDetection && typeof process !== 'undefined') {
|
|
190
|
+
this.memoryTimer = setInterval(() => {
|
|
191
|
+
this.checkMemoryPressure();
|
|
192
|
+
}, 2000); // Check every 2 seconds
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Stop the flush scheduler
|
|
198
|
+
*/
|
|
199
|
+
stop(): void {
|
|
200
|
+
if (!this.isRunning) return;
|
|
201
|
+
|
|
202
|
+
this.isRunning = false;
|
|
203
|
+
|
|
204
|
+
if (this.flushTimer) {
|
|
205
|
+
clearInterval(this.flushTimer);
|
|
206
|
+
this.flushTimer = undefined;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (this.idleTimer) {
|
|
210
|
+
clearInterval(this.idleTimer);
|
|
211
|
+
this.idleTimer = undefined;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (this.memoryTimer) {
|
|
215
|
+
clearInterval(this.memoryTimer);
|
|
216
|
+
this.memoryTimer = undefined;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Manually trigger a flush
|
|
222
|
+
*/
|
|
223
|
+
async flush(): Promise<void> {
|
|
224
|
+
await this.doFlush('manual');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Check flush conditions and flush if needed
|
|
229
|
+
*/
|
|
230
|
+
private checkFlushConditions(): void {
|
|
231
|
+
const now = Date.now();
|
|
232
|
+
const timeSinceLastFlush = now - this.lastFlushTime;
|
|
233
|
+
|
|
234
|
+
// Check max flush interval
|
|
235
|
+
if (timeSinceLastFlush >= this.config.maxFlushInterval) {
|
|
236
|
+
this.doFlush('time').catch(console.error);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Check capacity threshold
|
|
241
|
+
if (this.shouldFlushByCapacity()) {
|
|
242
|
+
this.doFlush('capacity').catch(console.error);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Check if should flush based on capacity
|
|
249
|
+
*/
|
|
250
|
+
private shouldFlushByCapacity(): boolean {
|
|
251
|
+
for (const buffer of this.buffers) {
|
|
252
|
+
const utilizationRatio = buffer._writeIndex / buffer._capacity;
|
|
253
|
+
if (utilizationRatio >= this.config.capacityThreshold) {
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Check idle state and flush if idle
|
|
262
|
+
*/
|
|
263
|
+
private checkIdleFlush(): void {
|
|
264
|
+
const now = Date.now();
|
|
265
|
+
const timeSinceActivity = now - this.lastActivityTime;
|
|
266
|
+
|
|
267
|
+
if (timeSinceActivity >= this.config.idleTimeout) {
|
|
268
|
+
// Only flush if there's data and min interval has passed
|
|
269
|
+
const timeSinceLastFlush = now - this.lastFlushTime;
|
|
270
|
+
if (this.buffers.size > 0 && timeSinceLastFlush >= this.config.minFlushInterval) {
|
|
271
|
+
this.doFlush('idle').catch(console.error);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Check memory pressure and flush if needed
|
|
278
|
+
* Node.js only
|
|
279
|
+
*/
|
|
280
|
+
private checkMemoryPressure(): void {
|
|
281
|
+
if (typeof process === 'undefined') return;
|
|
282
|
+
|
|
283
|
+
try {
|
|
284
|
+
const memUsage = process.memoryUsage();
|
|
285
|
+
const availableMemory = memUsage.heapTotal - memUsage.heapUsed;
|
|
286
|
+
|
|
287
|
+
if (availableMemory < this.config.memoryPressureThreshold) {
|
|
288
|
+
this.doFlush('memory').catch(console.error);
|
|
289
|
+
}
|
|
290
|
+
} catch {
|
|
291
|
+
// Ignore errors in memory detection
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Perform the actual flush operation
|
|
297
|
+
*/
|
|
298
|
+
private async doFlush(reason: FlushMetadata['flushReason']): Promise<void> {
|
|
299
|
+
if (this.buffers.size === 0) return;
|
|
300
|
+
|
|
301
|
+
const now = Date.now();
|
|
302
|
+
const timeSinceLastFlush = now - this.lastFlushTime;
|
|
303
|
+
|
|
304
|
+
// Respect minimum flush interval
|
|
305
|
+
if (reason !== 'manual' && timeSinceLastFlush < this.config.minFlushInterval) {
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Collect all buffers to flush
|
|
310
|
+
const buffersToFlush = Array.from(this.buffers);
|
|
311
|
+
|
|
312
|
+
// Collect unique (SpanBufferConstructor, OpMetadata) pairs from buffers being flushed
|
|
313
|
+
// Use SpanBufferConstructor as the key to dedup - multiple buffers may share the same class
|
|
314
|
+
// We pick the first OpMetadata we see for each class (they should be consistent)
|
|
315
|
+
const bufferClassesInThisFlush = new Map<SpanBufferConstructor, OpMetadata>();
|
|
316
|
+
for (const buffer of buffersToFlush) {
|
|
317
|
+
let currentBuffer: AnySpanBuffer | undefined = buffer;
|
|
318
|
+
while (currentBuffer) {
|
|
319
|
+
const bufferClass = currentBuffer.constructor;
|
|
320
|
+
if (!isSpanBufferConstructor(bufferClass)) {
|
|
321
|
+
throw new TypeError('Expected span buffer constructor with shared stats metadata');
|
|
322
|
+
}
|
|
323
|
+
// Only add if we haven't seen this buffer class before
|
|
324
|
+
if (!bufferClassesInThisFlush.has(bufferClass)) {
|
|
325
|
+
bufferClassesInThisFlush.set(bufferClass, currentBuffer._opMetadata);
|
|
326
|
+
}
|
|
327
|
+
currentBuffer = currentBuffer._overflow;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Add to tracking map (for periodic capacity stats logging)
|
|
332
|
+
for (const [bufferClass, metadata] of bufferClassesInThisFlush) {
|
|
333
|
+
// Only set if not already present (preserve first metadata seen)
|
|
334
|
+
if (!this._bufferClassesSinceLastStatsLog.has(bufferClass)) {
|
|
335
|
+
this._bufferClassesSinceLastStatsLog.set(bufferClass, metadata);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Increment flush counter
|
|
340
|
+
this._flushCount++;
|
|
341
|
+
|
|
342
|
+
// Check if we should log capacity stats
|
|
343
|
+
const shouldLogCapacityStats = this._flushCount >= CAPACITY_STATS_FLUSH_INTERVAL;
|
|
344
|
+
// Convert Map to CapacityStatsEntry[] for the conversion function
|
|
345
|
+
const modulesToLogStatsForConversion: CapacityStatsEntry[] | undefined = shouldLogCapacityStats
|
|
346
|
+
? Array.from(this._bufferClassesSinceLastStatsLog.entries()).map(([bufferClass, metadata]) => ({
|
|
347
|
+
bufferClass,
|
|
348
|
+
metadata,
|
|
349
|
+
}))
|
|
350
|
+
: undefined;
|
|
351
|
+
|
|
352
|
+
// Count total rows and buffers
|
|
353
|
+
let totalRows = 0;
|
|
354
|
+
let totalBuffers = 0;
|
|
355
|
+
|
|
356
|
+
for (const buffer of buffersToFlush) {
|
|
357
|
+
// Count rows in buffer chain
|
|
358
|
+
let currentBuffer: AnySpanBuffer | undefined = buffer;
|
|
359
|
+
while (currentBuffer) {
|
|
360
|
+
totalRows += currentBuffer._writeIndex;
|
|
361
|
+
totalBuffers++;
|
|
362
|
+
currentBuffer = currentBuffer._overflow;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (totalRows === 0 && !shouldLogCapacityStats) return;
|
|
367
|
+
|
|
368
|
+
// Convert all buffers to Arrow tables and concatenate
|
|
369
|
+
const tables: Table[] = [];
|
|
370
|
+
|
|
371
|
+
for (const buffer of buffersToFlush) {
|
|
372
|
+
try {
|
|
373
|
+
const table = convertSpanTreeToArrowTable(buffer, undefined, modulesToLogStatsForConversion);
|
|
374
|
+
|
|
375
|
+
if (table.numRows > 0) {
|
|
376
|
+
tables.push(table);
|
|
377
|
+
}
|
|
378
|
+
} catch (error) {
|
|
379
|
+
console.error('Error converting buffer to Arrow table:', error);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Concatenate all tables
|
|
384
|
+
if (tables.length === 0) {
|
|
385
|
+
// No tables but might have capacity stats - create empty table
|
|
386
|
+
// Capacity stats will be in the first table if any buffer had data
|
|
387
|
+
// If no buffers had data, we still need to handle capacity stats
|
|
388
|
+
// For now, return early - capacity stats will be logged on next flush with data
|
|
389
|
+
if (!shouldLogCapacityStats) return;
|
|
390
|
+
// If we should log stats but have no tables, we need to create a table with just capacity stats
|
|
391
|
+
// This is handled by convertSpanTreeToArrowTable returning a table with capacity stats batch
|
|
392
|
+
// But since we have no buffers, we can't call it. So we skip logging stats this time.
|
|
393
|
+
// Stats will be logged when there's actual data to flush.
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const [firstTable, ...otherTables] = tables;
|
|
397
|
+
const combinedTable = mergeTables(firstTable, otherTables);
|
|
398
|
+
|
|
399
|
+
// Call handler
|
|
400
|
+
const metadata: FlushMetadata = {
|
|
401
|
+
totalRows,
|
|
402
|
+
totalBuffers,
|
|
403
|
+
flushReason: reason,
|
|
404
|
+
timestamp: now,
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
await this.handler(combinedTable, metadata);
|
|
409
|
+
this.lastFlushTime = now;
|
|
410
|
+
|
|
411
|
+
// Reset flush counter and module tracking if we logged capacity stats
|
|
412
|
+
if (shouldLogCapacityStats) {
|
|
413
|
+
this._flushCount = 0;
|
|
414
|
+
this._bufferClassesSinceLastStatsLog.clear();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Reset buffers after successful flush to avoid duplicate re-processing
|
|
418
|
+
for (const buffer of buffersToFlush) {
|
|
419
|
+
// Reset writeIndex to 0 for the root buffer
|
|
420
|
+
buffer._writeIndex = 0;
|
|
421
|
+
|
|
422
|
+
// Clear any linked/chained buffers
|
|
423
|
+
let nextBuffer = buffer._overflow;
|
|
424
|
+
while (nextBuffer) {
|
|
425
|
+
nextBuffer._writeIndex = 0;
|
|
426
|
+
const temp = nextBuffer._overflow;
|
|
427
|
+
nextBuffer._overflow = undefined; // Unlink chained buffer
|
|
428
|
+
nextBuffer = temp;
|
|
429
|
+
}
|
|
430
|
+
buffer._overflow = undefined; // Clear link from root buffer
|
|
431
|
+
|
|
432
|
+
// A flushed root buffer is no longer pending; callers must re-register on future writes.
|
|
433
|
+
this.buffers.delete(buffer);
|
|
434
|
+
}
|
|
435
|
+
} catch (error) {
|
|
436
|
+
console.error('Error in flush handler:', error);
|
|
437
|
+
// Do NOT reset buffers on failure to avoid data loss
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Record activity (called when buffers are written to)
|
|
443
|
+
*/
|
|
444
|
+
recordActivity(): void {
|
|
445
|
+
this.lastActivityTime = Date.now();
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Global flush scheduler instance (optional)
|
|
451
|
+
* Applications can use this or create their own
|
|
452
|
+
*/
|
|
453
|
+
let globalScheduler: FlushScheduler | null = null;
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Get or create global flush scheduler
|
|
457
|
+
*/
|
|
458
|
+
export function getGlobalFlushScheduler(handler: FlushHandler, config?: FlushSchedulerConfig): FlushScheduler {
|
|
459
|
+
if (!globalScheduler) {
|
|
460
|
+
globalScheduler = new FlushScheduler(handler, config);
|
|
461
|
+
}
|
|
462
|
+
return globalScheduler;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Reset global flush scheduler (for testing)
|
|
467
|
+
*/
|
|
468
|
+
export function resetGlobalFlushScheduler(): void {
|
|
469
|
+
if (globalScheduler) {
|
|
470
|
+
globalScheduler.stop();
|
|
471
|
+
globalScheduler = null;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Test utilities for accessing FlushScheduler internals
|
|
477
|
+
* @internal
|
|
478
|
+
*/
|
|
479
|
+
export const FlushSchedulerTestUtils = {
|
|
480
|
+
/**
|
|
481
|
+
* Get the flush timer for a scheduler instance (for testing)
|
|
482
|
+
*/
|
|
483
|
+
getFlushTimer(scheduler: FlushScheduler): NodeJS.Timeout | undefined {
|
|
484
|
+
const timer = Reflect.get(scheduler, 'flushTimer');
|
|
485
|
+
return isNodeTimer(timer) ? timer : undefined;
|
|
486
|
+
},
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Set the flush timer for a scheduler instance (for testing)
|
|
490
|
+
*/
|
|
491
|
+
setFlushTimer(scheduler: FlushScheduler, timer: NodeJS.Timeout | undefined): void {
|
|
492
|
+
Reflect.set(scheduler, 'flushTimer', timer);
|
|
493
|
+
},
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Get the last activity time for a scheduler instance (for testing)
|
|
497
|
+
*/
|
|
498
|
+
getLastActivityTime(scheduler: FlushScheduler): number | undefined {
|
|
499
|
+
const time = Reflect.get(scheduler, 'lastActivityTime');
|
|
500
|
+
return typeof time === 'number' ? time : undefined;
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Set the last activity time for a scheduler instance (for testing)
|
|
505
|
+
*/
|
|
506
|
+
setLastActivityTime(scheduler: FlushScheduler, time: number | null | undefined): void {
|
|
507
|
+
Reflect.set(scheduler, 'lastActivityTime', time);
|
|
508
|
+
},
|
|
509
|
+
};
|