@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,89 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import { createTestTracerOptions } from '../../__tests__/test-helpers.js';
|
|
3
|
+
import { defineOpContext } from '../../defineOpContext.js';
|
|
4
|
+
import { S } from '../../schema/builder.js';
|
|
5
|
+
import { defineLogSchema } from '../../schema/defineLogSchema.js';
|
|
6
|
+
import { TestTracer } from '../../tracers/TestTracer.js';
|
|
7
|
+
import type { AnySpanBuffer } from '../../types.js';
|
|
8
|
+
import { buildInsertParams, parseSqliteTableInfoRows, type SpanSegment } from '../sqlite-common.js';
|
|
9
|
+
|
|
10
|
+
const opContext = defineOpContext({
|
|
11
|
+
logSchema: defineLogSchema({
|
|
12
|
+
scoped_text: S.category(),
|
|
13
|
+
scoped_num: S.number(),
|
|
14
|
+
mixed: S.category(),
|
|
15
|
+
}),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
async function createSegment(): Promise<{ buffer: AnySpanBuffer; segment: SpanSegment }> {
|
|
19
|
+
const tracer = new TestTracer(opContext, createTestTracerOptions());
|
|
20
|
+
|
|
21
|
+
await tracer.trace('sqlite-scope-fallback', async (ctx) => {
|
|
22
|
+
ctx.setScope({
|
|
23
|
+
scoped_text: 'scope-text',
|
|
24
|
+
scoped_num: 7,
|
|
25
|
+
mixed: 'scope-mixed',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Direct row-0 write should override scope for row 0 only.
|
|
29
|
+
ctx.tag.mixed('direct-mixed');
|
|
30
|
+
return ctx.ok(null);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const buffer = tracer.rootBuffers[0] as AnySpanBuffer;
|
|
34
|
+
const segment: SpanSegment = {
|
|
35
|
+
buffer,
|
|
36
|
+
traceId: buffer.trace_id,
|
|
37
|
+
spanId: buffer.span_id,
|
|
38
|
+
parentSpanId: buffer.parent_span_id,
|
|
39
|
+
rowOffset: 0,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return { buffer, segment };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe('sqlite-common scope fallback', () => {
|
|
46
|
+
it('fills user columns from scope when row value is missing', async () => {
|
|
47
|
+
const { segment } = await createSegment();
|
|
48
|
+
|
|
49
|
+
const activeUserFields = ['scoped_text', 'scoped_num', 'mixed'];
|
|
50
|
+
|
|
51
|
+
const row0 = buildInsertParams(segment, 0, activeUserFields);
|
|
52
|
+
const row1 = buildInsertParams(segment, 1, activeUserFields);
|
|
53
|
+
|
|
54
|
+
expect(row0.slice(7)).toEqual(['scope-text', 7, 'direct-mixed']);
|
|
55
|
+
expect(row1.slice(7)).toEqual(['scope-text', 7, 'scope-mixed']);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('parseSqliteTableInfoRows', () => {
|
|
60
|
+
it('accepts bigint PRAGMA integers from SQLite adapters', () => {
|
|
61
|
+
expect(
|
|
62
|
+
parseSqliteTableInfoRows([
|
|
63
|
+
{
|
|
64
|
+
cid: 0n,
|
|
65
|
+
name: 'trace_id',
|
|
66
|
+
type: 'TEXT',
|
|
67
|
+
notnull: 1n,
|
|
68
|
+
dflt_value: null,
|
|
69
|
+
pk: 1n,
|
|
70
|
+
},
|
|
71
|
+
]),
|
|
72
|
+
).toEqual([
|
|
73
|
+
{
|
|
74
|
+
cid: 0,
|
|
75
|
+
name: 'trace_id',
|
|
76
|
+
type: 'TEXT',
|
|
77
|
+
notnull: 1,
|
|
78
|
+
dflt_value: null,
|
|
79
|
+
pk: 1,
|
|
80
|
+
},
|
|
81
|
+
]);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('throws a descriptive error for invalid row shapes', () => {
|
|
85
|
+
expect(() =>
|
|
86
|
+
parseSqliteTableInfoRows([{ cid: 0, name: 'trace_id', type: 1, notnull: 1, dflt_value: null, pk: 1 }]),
|
|
87
|
+
).toThrow('PRAGMA table_info(spans) returned an invalid SQLite row 0: type expected string, got number');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite persistence for LMAO span buffers.
|
|
3
|
+
*
|
|
4
|
+
* General-purpose writer API for persisting span buffer trees to SQLite.
|
|
5
|
+
* Platform-agnostic — accepts any SyncSQLiteDatabase (bun:sqlite or better-sqlite3).
|
|
6
|
+
*
|
|
7
|
+
* @module sqlite
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { SQLiteAsyncTraceWriter } from './sqlite-async-writer.js';
|
|
11
|
+
export {
|
|
12
|
+
buildAddColumnSql,
|
|
13
|
+
extractSqliteColumnsFromTableInfo,
|
|
14
|
+
getMissingSqliteColumns,
|
|
15
|
+
quoteSqlIdentifier,
|
|
16
|
+
SPANS_TABLE_INFO_SQL,
|
|
17
|
+
SPANS_TABLE_INIT_SQL,
|
|
18
|
+
} from './sqlite-common.js';
|
|
19
|
+
export { createD1SQLiteDatabase, type D1LikeDatabase, type D1LikePreparedStatement } from './sqlite-d1.js';
|
|
20
|
+
export type {
|
|
21
|
+
AsyncSQLiteDatabase,
|
|
22
|
+
AsyncSQLiteStatement,
|
|
23
|
+
SyncSQLiteDatabase,
|
|
24
|
+
SyncSQLiteStatement,
|
|
25
|
+
} from './sqlite-db.js';
|
|
26
|
+
export { SQLiteTraceWriter, type SQLiteWriterConfig } from './sqlite-writer.js';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLiteAsyncTraceWriter - Async SQLite persistence for span buffer trees.
|
|
3
|
+
*
|
|
4
|
+
* Works with async SQLite drivers (for example Cloudflare D1 adapters) while
|
|
5
|
+
* preserving the same `spans` table shape as the sync SQLiteTraceWriter.
|
|
6
|
+
*
|
|
7
|
+
* @module sqlite-async-writer
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { LogSchema } from '../schema/LogSchema.js';
|
|
11
|
+
import type { AnySpanBuffer } from '../types.js';
|
|
12
|
+
import {
|
|
13
|
+
buildAddColumnSql,
|
|
14
|
+
buildInsertParams,
|
|
15
|
+
buildInsertSql,
|
|
16
|
+
extractSqliteColumnsFromTableInfo,
|
|
17
|
+
getActiveUserFields,
|
|
18
|
+
getInsertStatementCacheKey,
|
|
19
|
+
getMissingSchemaColumns,
|
|
20
|
+
isSqliteDuplicateColumnError,
|
|
21
|
+
parseSqliteTableInfoRows,
|
|
22
|
+
SPANS_TABLE_INFO_SQL,
|
|
23
|
+
SPANS_TABLE_INIT_SQL,
|
|
24
|
+
walkSpanSegments,
|
|
25
|
+
} from './sqlite-common.js';
|
|
26
|
+
import type { AsyncSQLiteDatabase, AsyncSQLiteStatement } from './sqlite-db.js';
|
|
27
|
+
|
|
28
|
+
export class SQLiteAsyncTraceWriter {
|
|
29
|
+
private knownColumns = new Set<string>();
|
|
30
|
+
private insertStmtCache = new Map<string, AsyncSQLiteStatement>();
|
|
31
|
+
private initialized = false;
|
|
32
|
+
|
|
33
|
+
constructor(private db: AsyncSQLiteDatabase) {}
|
|
34
|
+
|
|
35
|
+
private async init(): Promise<void> {
|
|
36
|
+
if (this.initialized) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await this.db.exec(SPANS_TABLE_INIT_SQL);
|
|
41
|
+
|
|
42
|
+
await this.refreshKnownColumns();
|
|
43
|
+
|
|
44
|
+
this.initialized = true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private async refreshKnownColumns(): Promise<void> {
|
|
48
|
+
this.knownColumns.clear();
|
|
49
|
+
// WHY: async drivers are still a real schema boundary; validate PRAGMA rows before caching column names that drive
|
|
50
|
+
// later DDL and inserts.
|
|
51
|
+
const rows = parseSqliteTableInfoRows(await this.db.prepare(SPANS_TABLE_INFO_SQL).all());
|
|
52
|
+
for (const column of extractSqliteColumnsFromTableInfo(rows)) {
|
|
53
|
+
this.knownColumns.add(column.name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private async ensureColumns(schema: LogSchema): Promise<void> {
|
|
58
|
+
for (const column of getMissingSchemaColumns(schema, this.knownColumns)) {
|
|
59
|
+
try {
|
|
60
|
+
await this.db.exec(buildAddColumnSql(column));
|
|
61
|
+
} catch (error) {
|
|
62
|
+
if (!isSqliteDuplicateColumnError(error, column.name)) {
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
await this.refreshKnownColumns();
|
|
68
|
+
this.knownColumns.add(column.name);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private getInsertStatement(activeUserFields: readonly string[]): AsyncSQLiteStatement {
|
|
73
|
+
const key = getInsertStatementCacheKey(activeUserFields);
|
|
74
|
+
const cached = this.insertStmtCache.get(key);
|
|
75
|
+
if (cached) {
|
|
76
|
+
return cached;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const stmt = this.db.prepare(buildInsertSql(activeUserFields));
|
|
80
|
+
this.insertStmtCache.set(key, stmt);
|
|
81
|
+
return stmt;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async flush(rootBuffer: AnySpanBuffer): Promise<void> {
|
|
85
|
+
await this.init();
|
|
86
|
+
for (const segment of walkSpanSegments(rootBuffer)) {
|
|
87
|
+
await this.ensureColumns(segment.buffer._logSchema);
|
|
88
|
+
|
|
89
|
+
const activeUserFields = getActiveUserFields(segment.buffer._logSchema, this.knownColumns);
|
|
90
|
+
const insertStmt = this.getInsertStatement(activeUserFields);
|
|
91
|
+
|
|
92
|
+
for (let row = 0; row < segment.buffer._writeIndex; row++) {
|
|
93
|
+
await insertStmt.run(...buildInsertParams(segment, row, activeUserFields));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async close(): Promise<void> {
|
|
99
|
+
await this.db.close();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import type { SchemaType } from '@smoothbricks/arrow-builder';
|
|
2
|
+
import { hasOwn, hasOwnString, isRecord } from '@smoothbricks/validation';
|
|
3
|
+
import type { LogSchema } from '../schema/LogSchema.js';
|
|
4
|
+
import { getSchemaType } from '../schema/typeGuards.js';
|
|
5
|
+
import type { AnySpanBuffer } from '../types.js';
|
|
6
|
+
|
|
7
|
+
export const SPANS_TABLE_INIT_SQL = `
|
|
8
|
+
CREATE TABLE IF NOT EXISTS spans (
|
|
9
|
+
trace_id TEXT NOT NULL,
|
|
10
|
+
span_id INTEGER NOT NULL,
|
|
11
|
+
parent_span_id INTEGER NOT NULL,
|
|
12
|
+
row_index INTEGER NOT NULL,
|
|
13
|
+
entry_type INTEGER NOT NULL,
|
|
14
|
+
timestamp_ns INTEGER NOT NULL,
|
|
15
|
+
message TEXT,
|
|
16
|
+
PRIMARY KEY (trace_id, span_id, row_index)
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE INDEX IF NOT EXISTS idx_spans_trace ON spans(trace_id);
|
|
20
|
+
CREATE INDEX IF NOT EXISTS idx_spans_parent ON spans(trace_id, parent_span_id);
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
export const SPANS_TABLE_INFO_SQL = 'PRAGMA table_info(spans)';
|
|
24
|
+
|
|
25
|
+
type SQLiteTableInfoIntegerField = keyof Pick<SQLiteTableInfoRow, 'cid' | 'notnull' | 'pk'>;
|
|
26
|
+
|
|
27
|
+
export interface SQLiteColumnDefinition {
|
|
28
|
+
name: string;
|
|
29
|
+
sqliteType: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SQLiteTableInfoRow {
|
|
33
|
+
cid: number;
|
|
34
|
+
name: string;
|
|
35
|
+
type: string;
|
|
36
|
+
notnull: number;
|
|
37
|
+
dflt_value: string | null;
|
|
38
|
+
pk: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface SpanSegment {
|
|
42
|
+
buffer: AnySpanBuffer;
|
|
43
|
+
traceId: string;
|
|
44
|
+
spanId: number;
|
|
45
|
+
parentSpanId: number;
|
|
46
|
+
rowOffset: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Check if bit at index is set in Arrow null bitmap (1 = valid/present, 0 = null) */
|
|
50
|
+
function isBitSet(bitmap: Uint8Array, idx: number): boolean {
|
|
51
|
+
return (bitmap[idx >>> 3] & (1 << (idx & 7))) !== 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Read a user column value at the given row.
|
|
56
|
+
*
|
|
57
|
+
* Typed arrays are pre-allocated with zeros, so null bitmaps distinguish
|
|
58
|
+
* "set to zero" from "never written". JS arrays use `undefined` for unwritten slots.
|
|
59
|
+
*/
|
|
60
|
+
function readUserValue(buffer: AnySpanBuffer, fieldName: string, row: number): unknown {
|
|
61
|
+
const values = Reflect.get(buffer, `${fieldName}_values`);
|
|
62
|
+
if (!values) return undefined;
|
|
63
|
+
|
|
64
|
+
if (ArrayBuffer.isView(values)) {
|
|
65
|
+
const nulls = Reflect.get(buffer, `${fieldName}_nulls`);
|
|
66
|
+
if (!(nulls instanceof Uint8Array) || !('length' in values)) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return isBitSet(nulls, row) ? Reflect.get(values, row) : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return Array.isArray(values) ? values[row] : undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function readScopeValue(buffer: AnySpanBuffer, fieldName: string): unknown {
|
|
77
|
+
return isRecord(buffer._scopeValues) ? buffer._scopeValues[fieldName] : undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function describeSqliteBoundaryType(value: unknown): string {
|
|
81
|
+
return typeof value;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function invalidSqliteBoundaryRow(boundary: string, rowIndex: number, message: string): Error {
|
|
85
|
+
return new Error(`${boundary} returned an invalid SQLite row ${rowIndex}: ${message}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function normalizeSqliteTableInfoInteger(
|
|
89
|
+
value: unknown,
|
|
90
|
+
boundary: string,
|
|
91
|
+
rowIndex: number,
|
|
92
|
+
fieldName: SQLiteTableInfoIntegerField,
|
|
93
|
+
): number {
|
|
94
|
+
if (typeof value === 'number') {
|
|
95
|
+
return value;
|
|
96
|
+
}
|
|
97
|
+
if (typeof value === 'bigint') {
|
|
98
|
+
return Number(value);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
throw invalidSqliteBoundaryRow(
|
|
102
|
+
boundary,
|
|
103
|
+
rowIndex,
|
|
104
|
+
`${fieldName} expected number, got ${describeSqliteBoundaryType(value)}`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function parseSqliteTableInfoRow(row: unknown, boundary: string, rowIndex: number): SQLiteTableInfoRow {
|
|
109
|
+
if (!isRecord(row)) {
|
|
110
|
+
throw invalidSqliteBoundaryRow(boundary, rowIndex, `expected record, got ${describeSqliteBoundaryType(row)}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const rowRecord = row;
|
|
114
|
+
|
|
115
|
+
if (!hasOwn(rowRecord, 'cid')) {
|
|
116
|
+
throw invalidSqliteBoundaryRow(boundary, rowIndex, 'missing cid');
|
|
117
|
+
}
|
|
118
|
+
if (!hasOwnString(rowRecord, 'name')) {
|
|
119
|
+
throw invalidSqliteBoundaryRow(
|
|
120
|
+
boundary,
|
|
121
|
+
rowIndex,
|
|
122
|
+
`name expected string, got ${describeSqliteBoundaryType(rowRecord.name)}`,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (!hasOwnString(rowRecord, 'type')) {
|
|
126
|
+
throw invalidSqliteBoundaryRow(
|
|
127
|
+
boundary,
|
|
128
|
+
rowIndex,
|
|
129
|
+
`type expected string, got ${describeSqliteBoundaryType(rowRecord.type)}`,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (!hasOwn(rowRecord, 'notnull')) {
|
|
133
|
+
throw invalidSqliteBoundaryRow(boundary, rowIndex, 'missing notnull');
|
|
134
|
+
}
|
|
135
|
+
if (!hasOwn(rowRecord, 'dflt_value')) {
|
|
136
|
+
throw invalidSqliteBoundaryRow(boundary, rowIndex, 'missing dflt_value');
|
|
137
|
+
}
|
|
138
|
+
if (typeof rowRecord.dflt_value !== 'string' && rowRecord.dflt_value !== null) {
|
|
139
|
+
throw invalidSqliteBoundaryRow(
|
|
140
|
+
boundary,
|
|
141
|
+
rowIndex,
|
|
142
|
+
`dflt_value expected string|null, got ${describeSqliteBoundaryType(rowRecord.dflt_value)}`,
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (!hasOwn(rowRecord, 'pk')) {
|
|
146
|
+
throw invalidSqliteBoundaryRow(boundary, rowIndex, 'missing pk');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
// WHY: some SQLite adapters promote PRAGMA integer metadata to bigint, but the shared table-info contract uses
|
|
151
|
+
// numeric counters plus string column descriptors.
|
|
152
|
+
cid: normalizeSqliteTableInfoInteger(rowRecord.cid, boundary, rowIndex, 'cid'),
|
|
153
|
+
name: rowRecord.name,
|
|
154
|
+
type: rowRecord.type,
|
|
155
|
+
notnull: normalizeSqliteTableInfoInteger(rowRecord.notnull, boundary, rowIndex, 'notnull'),
|
|
156
|
+
dflt_value: rowRecord.dflt_value,
|
|
157
|
+
pk: normalizeSqliteTableInfoInteger(rowRecord.pk, boundary, rowIndex, 'pk'),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Map arrow-builder SchemaType to SQLite column type */
|
|
162
|
+
function schemaTypeToSqlite(schemaType: SchemaType): string {
|
|
163
|
+
switch (schemaType) {
|
|
164
|
+
case 'category':
|
|
165
|
+
case 'text':
|
|
166
|
+
case 'enum':
|
|
167
|
+
return 'TEXT';
|
|
168
|
+
case 'number':
|
|
169
|
+
return 'REAL';
|
|
170
|
+
case 'bigUint64':
|
|
171
|
+
case 'boolean':
|
|
172
|
+
return 'INTEGER';
|
|
173
|
+
case 'binary':
|
|
174
|
+
return 'BLOB';
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
throw new Error(`Unsupported schema type: ${String(schemaType)}`);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function normalizeSqliteColumnType(type: string): string {
|
|
181
|
+
return type.trim() === '' ? 'TEXT' : type;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function quoteSqlIdentifier(name: string): string {
|
|
185
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
|
|
186
|
+
throw new Error(`Unsafe SQLite identifier: ${name}`);
|
|
187
|
+
}
|
|
188
|
+
return `"${name}"`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function buildAddColumnSql(column: SQLiteColumnDefinition): string {
|
|
192
|
+
return `ALTER TABLE spans ADD COLUMN ${quoteSqlIdentifier(column.name)} ${normalizeSqliteColumnType(column.sqliteType)}`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function isSqliteDuplicateColumnError(error: unknown, columnName: string): boolean {
|
|
196
|
+
if (!(error instanceof Error)) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return error.message.toLowerCase().includes(`duplicate column name: ${columnName.toLowerCase()}`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function getMissingSqliteColumns(
|
|
204
|
+
columns: readonly SQLiteColumnDefinition[],
|
|
205
|
+
knownColumns: ReadonlySet<string>,
|
|
206
|
+
): SQLiteColumnDefinition[] {
|
|
207
|
+
const missing: SQLiteColumnDefinition[] = [];
|
|
208
|
+
for (const column of columns) {
|
|
209
|
+
if (!knownColumns.has(column.name)) {
|
|
210
|
+
missing.push(column);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return missing;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function extractSqliteColumnsFromTableInfo(columns: readonly SQLiteTableInfoRow[]): SQLiteColumnDefinition[] {
|
|
217
|
+
return columns.map((column) => ({
|
|
218
|
+
name: column.name,
|
|
219
|
+
sqliteType: normalizeSqliteColumnType(column.type),
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function parseSqliteTableInfoRows(
|
|
224
|
+
rows: readonly unknown[],
|
|
225
|
+
boundary = 'PRAGMA table_info(spans)',
|
|
226
|
+
): SQLiteTableInfoRow[] {
|
|
227
|
+
return rows.map((row, rowIndex) => parseSqliteTableInfoRow(row, boundary, rowIndex));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function* walkOverflowSegments(
|
|
231
|
+
buffer: AnySpanBuffer,
|
|
232
|
+
traceId: string,
|
|
233
|
+
spanId: number,
|
|
234
|
+
parentSpanId: number,
|
|
235
|
+
rowOffset: number,
|
|
236
|
+
): Generator<SpanSegment> {
|
|
237
|
+
yield {
|
|
238
|
+
buffer,
|
|
239
|
+
traceId,
|
|
240
|
+
spanId,
|
|
241
|
+
parentSpanId,
|
|
242
|
+
rowOffset,
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
if (buffer._overflow) {
|
|
246
|
+
yield* walkOverflowSegments(buffer._overflow, traceId, spanId, parentSpanId, rowOffset + buffer._writeIndex);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function* walkTree(buffer: AnySpanBuffer): Generator<SpanSegment> {
|
|
251
|
+
yield* walkOverflowSegments(buffer, buffer.trace_id, buffer.span_id, buffer.parent_span_id, 0);
|
|
252
|
+
|
|
253
|
+
for (const child of buffer._children) {
|
|
254
|
+
yield* walkTree(child);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function* walkSpanSegments(rootBuffer: AnySpanBuffer): Generator<SpanSegment> {
|
|
259
|
+
yield* walkTree(rootBuffer);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function getMissingSchemaColumns(
|
|
263
|
+
schema: LogSchema,
|
|
264
|
+
knownColumns: ReadonlySet<string>,
|
|
265
|
+
): SQLiteColumnDefinition[] {
|
|
266
|
+
const schemaColumns: SQLiteColumnDefinition[] = [];
|
|
267
|
+
|
|
268
|
+
for (const [name, field] of Object.entries(schema.fields)) {
|
|
269
|
+
const schemaType = getSchemaType(field);
|
|
270
|
+
if (!schemaType) continue;
|
|
271
|
+
|
|
272
|
+
schemaColumns.push({ name, sqliteType: schemaTypeToSqlite(schemaType) });
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return getMissingSqliteColumns(schemaColumns, knownColumns);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function getActiveUserFields(schema: LogSchema, knownColumns: ReadonlySet<string>): string[] {
|
|
279
|
+
return schema._columnNames.filter((fieldName) => knownColumns.has(fieldName));
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function getInsertStatementCacheKey(activeUserFields: readonly string[]): string {
|
|
283
|
+
return activeUserFields.join(',');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export function buildInsertSql(activeUserFields: readonly string[]): string {
|
|
287
|
+
const userColsSql = activeUserFields.length > 0 ? `, ${activeUserFields.join(', ')}` : '';
|
|
288
|
+
const userPlaceholders = activeUserFields.length > 0 ? `, ${activeUserFields.map(() => '?').join(', ')}` : '';
|
|
289
|
+
return `INSERT INTO spans (trace_id, span_id, parent_span_id, row_index, entry_type, timestamp_ns, message${userColsSql})
|
|
290
|
+
VALUES (?, ?, ?, ?, ?, ?, ?${userPlaceholders})`;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function buildInsertParams(segment: SpanSegment, row: number, activeUserFields: readonly string[]): unknown[] {
|
|
294
|
+
const { buffer, traceId, spanId, parentSpanId, rowOffset } = segment;
|
|
295
|
+
const entryType = buffer.entry_type[row];
|
|
296
|
+
const timestampNs = Number(buffer.timestamp[row]);
|
|
297
|
+
const message = buffer.message_values[row] ?? null;
|
|
298
|
+
|
|
299
|
+
const userValues = activeUserFields.map((fieldName) => {
|
|
300
|
+
const directValue = readUserValue(buffer, fieldName, row);
|
|
301
|
+
const val = directValue ?? readScopeValue(buffer, fieldName);
|
|
302
|
+
if (val === undefined || val === null) {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
return typeof val === 'bigint' ? Number(val) : val;
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
return [traceId, spanId, parentSpanId, rowOffset + row, entryType, timestampNs, message, ...userValues];
|
|
309
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D1 adapter for LMAO async SQLite interfaces.
|
|
3
|
+
*
|
|
4
|
+
* This keeps D1-specific behavior in one place while exposing the generic
|
|
5
|
+
* AsyncSQLiteDatabase contract used by SQLiteAsyncTracer/SQLiteAsyncTraceWriter.
|
|
6
|
+
*
|
|
7
|
+
* @module sqlite-d1
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { AsyncSQLiteDatabase, AsyncSQLiteStatement } from './sqlite-db.js';
|
|
11
|
+
|
|
12
|
+
type D1BindValue = null | number | string | ArrayBuffer | ArrayBufferView;
|
|
13
|
+
|
|
14
|
+
export interface D1LikePreparedStatement {
|
|
15
|
+
bind(...values: D1BindValue[]): D1LikePreparedStatement;
|
|
16
|
+
run(): Promise<unknown>;
|
|
17
|
+
all<T = unknown>(): Promise<{ results?: T[] }>;
|
|
18
|
+
first<T = unknown>(): Promise<T | null>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface D1LikeDatabase {
|
|
22
|
+
prepare(query: string): D1LikePreparedStatement;
|
|
23
|
+
exec(query: string): Promise<unknown>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function toD1BindValue(value: unknown): D1BindValue {
|
|
27
|
+
if (value == null) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (typeof value === 'boolean') {
|
|
32
|
+
return value ? 1 : 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (typeof value === 'bigint') {
|
|
36
|
+
return Number(value);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (typeof value === 'number' || typeof value === 'string') {
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (value instanceof ArrayBuffer) {
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (ArrayBuffer.isView(value)) {
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
throw new Error(`Unsupported D1 bind param type: ${typeof value}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
class D1StatementAdapter implements AsyncSQLiteStatement {
|
|
55
|
+
constructor(
|
|
56
|
+
private readonly db: D1LikeDatabase,
|
|
57
|
+
private readonly query: string,
|
|
58
|
+
) {}
|
|
59
|
+
|
|
60
|
+
private bind(params: unknown[]): D1LikePreparedStatement {
|
|
61
|
+
const statement = this.db.prepare(this.query);
|
|
62
|
+
return statement.bind(...params.map(toD1BindValue));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async run(...params: unknown[]): Promise<void> {
|
|
66
|
+
await this.bind(params).run();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async all(...params: unknown[]): Promise<unknown[]> {
|
|
70
|
+
const result = await this.bind(params).all();
|
|
71
|
+
return result.results ?? [];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async get(...params: unknown[]): Promise<unknown> {
|
|
75
|
+
return (await this.bind(params).first()) ?? undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
class D1DatabaseAdapter implements AsyncSQLiteDatabase {
|
|
80
|
+
constructor(private readonly db: D1LikeDatabase) {}
|
|
81
|
+
|
|
82
|
+
async exec(sql: string): Promise<void> {
|
|
83
|
+
const statements = sql
|
|
84
|
+
.split(';')
|
|
85
|
+
.map((statement) => statement.trim())
|
|
86
|
+
.filter((statement) => statement.length > 0);
|
|
87
|
+
|
|
88
|
+
for (const statement of statements) {
|
|
89
|
+
await this.db.prepare(statement).run();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
prepare(sql: string): AsyncSQLiteStatement {
|
|
94
|
+
return new D1StatementAdapter(this.db, sql);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async close(): Promise<void> {
|
|
98
|
+
// D1 bindings are managed by the worker runtime.
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function createD1SQLiteDatabase(db: D1LikeDatabase): AsyncSQLiteDatabase {
|
|
103
|
+
return new D1DatabaseAdapter(db);
|
|
104
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal SQLite interfaces used by trace persistence.
|
|
3
|
+
*
|
|
4
|
+
* Sync APIs match bun:sqlite / better-sqlite3 style drivers.
|
|
5
|
+
* Async APIs match worker-style drivers (for example D1 adapters).
|
|
6
|
+
*
|
|
7
|
+
* @module sqlite-db
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface SyncSQLiteDatabase {
|
|
11
|
+
exec(sql: string): void;
|
|
12
|
+
prepare(sql: string): SyncSQLiteStatement;
|
|
13
|
+
close(): void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface SyncSQLiteStatement {
|
|
17
|
+
run(...params: unknown[]): void;
|
|
18
|
+
all(...params: unknown[]): unknown[];
|
|
19
|
+
get(...params: unknown[]): unknown;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface AsyncSQLiteDatabase {
|
|
23
|
+
exec(sql: string): Promise<void>;
|
|
24
|
+
prepare(sql: string): AsyncSQLiteStatement;
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface AsyncSQLiteStatement {
|
|
29
|
+
run(...params: unknown[]): Promise<void>;
|
|
30
|
+
all(...params: unknown[]): Promise<unknown[]>;
|
|
31
|
+
get(...params: unknown[]): Promise<unknown>;
|
|
32
|
+
}
|