@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,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIEVE-based cache for UTF-8 string encoding
|
|
3
|
+
*
|
|
4
|
+
* Per string storage design specs:
|
|
5
|
+
* - Category/text columns store raw JS strings in hot path (zero cost)
|
|
6
|
+
* - UTF-8 encoding happens in cold path (Arrow conversion)
|
|
7
|
+
* - Frequent strings benefit from caching to avoid re-encoding
|
|
8
|
+
*
|
|
9
|
+
* Uses SIEVE algorithm (NSDI'24) which is simpler AND better than LRU
|
|
10
|
+
* for web workloads. SIEVE achieves ~9% lower miss ratio than LRU-K,
|
|
11
|
+
* ARC, and 2Q while being much simpler to implement.
|
|
12
|
+
*
|
|
13
|
+
* @see https://junchengyang.com/publication/nsdi24-SIEVE.pdf
|
|
14
|
+
*/
|
|
15
|
+
import { SieveCache } from '@neophi/sieve-cache';
|
|
16
|
+
/**
|
|
17
|
+
* Default cache size for UTF-8 encoding
|
|
18
|
+
*
|
|
19
|
+
* 4096 entries is a reasonable default that:
|
|
20
|
+
* - Handles typical category cardinality (user IDs, session IDs, etc.)
|
|
21
|
+
* - Bounds memory usage (~4KB keys + encoded values)
|
|
22
|
+
* - Provides good hit rate for repetitive strings
|
|
23
|
+
*/
|
|
24
|
+
const DEFAULT_UTF8_CACHE_SIZE = 4096;
|
|
25
|
+
/**
|
|
26
|
+
* UTF-8 encoding cache using SIEVE eviction algorithm
|
|
27
|
+
*
|
|
28
|
+
* This cache is used during Arrow conversion to avoid re-encoding
|
|
29
|
+
* strings that appear multiple times across buffers or conversions.
|
|
30
|
+
*
|
|
31
|
+
* Thread-safety: JavaScript is single-threaded, so no locks needed.
|
|
32
|
+
* The cache is safe to use in async contexts since JS awaits don't
|
|
33
|
+
* allow concurrent access to the same cache instance.
|
|
34
|
+
*/
|
|
35
|
+
export class Utf8Cache {
|
|
36
|
+
cache;
|
|
37
|
+
encoder = new TextEncoder();
|
|
38
|
+
// Stats for debugging/monitoring
|
|
39
|
+
hits = 0;
|
|
40
|
+
misses = 0;
|
|
41
|
+
constructor(maxSize = DEFAULT_UTF8_CACHE_SIZE) {
|
|
42
|
+
this.cache = new SieveCache(maxSize);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get UTF-8 encoded bytes for a string, using cache if available
|
|
46
|
+
*
|
|
47
|
+
* @param str - String to encode
|
|
48
|
+
* @returns UTF-8 encoded bytes
|
|
49
|
+
*/
|
|
50
|
+
encode(str) {
|
|
51
|
+
const cached = this.cache.get(str);
|
|
52
|
+
if (cached !== undefined) {
|
|
53
|
+
this.hits++;
|
|
54
|
+
return cached;
|
|
55
|
+
}
|
|
56
|
+
this.misses++;
|
|
57
|
+
const encoded = this.encoder.encode(str);
|
|
58
|
+
this.cache.set(str, encoded);
|
|
59
|
+
return encoded;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Calculate UTF-8 byte length of a string
|
|
63
|
+
*
|
|
64
|
+
* Uses cache if available to avoid re-encoding.
|
|
65
|
+
*
|
|
66
|
+
* @param str - String to measure
|
|
67
|
+
* @returns UTF-8 byte length
|
|
68
|
+
*/
|
|
69
|
+
byteLength(str) {
|
|
70
|
+
// Check cache first - if encoded, we know the length
|
|
71
|
+
const cached = this.cache.get(str);
|
|
72
|
+
if (cached !== undefined) {
|
|
73
|
+
this.hits++;
|
|
74
|
+
return cached.length;
|
|
75
|
+
}
|
|
76
|
+
// Not cached - encode and cache it, then return length
|
|
77
|
+
this.misses++;
|
|
78
|
+
const encoded = this.encoder.encode(str);
|
|
79
|
+
this.cache.set(str, encoded);
|
|
80
|
+
return encoded.length;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Encode string directly into buffer at offset
|
|
84
|
+
*
|
|
85
|
+
* @param str - String to encode
|
|
86
|
+
* @param buffer - Target buffer
|
|
87
|
+
* @param offset - Offset in buffer to write at
|
|
88
|
+
* @returns Number of bytes written
|
|
89
|
+
*/
|
|
90
|
+
encodeInto(str, buffer, offset) {
|
|
91
|
+
// Use encode() which leverages the cache
|
|
92
|
+
const encoded = this.encode(str);
|
|
93
|
+
buffer.set(encoded, offset);
|
|
94
|
+
return encoded.length;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Encode multiple strings, returning concatenated bytes and offsets
|
|
98
|
+
*
|
|
99
|
+
* This is optimized for Arrow dictionary construction where we need
|
|
100
|
+
* both the concatenated bytes and the offset array.
|
|
101
|
+
*
|
|
102
|
+
* @param strings - Array of strings to encode
|
|
103
|
+
* @returns Concatenated UTF-8 bytes and Arrow-format offsets
|
|
104
|
+
*/
|
|
105
|
+
encodeMany(strings) {
|
|
106
|
+
// First pass: encode all strings and calculate total size
|
|
107
|
+
const encoded = new Array(strings.length);
|
|
108
|
+
let totalSize = 0;
|
|
109
|
+
for (let i = 0; i < strings.length; i++) {
|
|
110
|
+
encoded[i] = this.encode(strings[i]);
|
|
111
|
+
totalSize += encoded[i].length;
|
|
112
|
+
}
|
|
113
|
+
// Build offsets array (Arrow format: length = strings.length + 1)
|
|
114
|
+
const offsets = new Int32Array(strings.length + 1);
|
|
115
|
+
offsets[0] = 0;
|
|
116
|
+
for (let i = 0; i < encoded.length; i++) {
|
|
117
|
+
offsets[i + 1] = offsets[i] + encoded[i].length;
|
|
118
|
+
}
|
|
119
|
+
// Concatenate all encoded bytes
|
|
120
|
+
const data = new Uint8Array(totalSize);
|
|
121
|
+
let offset = 0;
|
|
122
|
+
for (const bytes of encoded) {
|
|
123
|
+
data.set(bytes, offset);
|
|
124
|
+
offset += bytes.length;
|
|
125
|
+
}
|
|
126
|
+
return { data, offsets };
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get cache statistics
|
|
130
|
+
*/
|
|
131
|
+
get stats() {
|
|
132
|
+
const total = this.hits + this.misses;
|
|
133
|
+
return {
|
|
134
|
+
hits: this.hits,
|
|
135
|
+
misses: this.misses,
|
|
136
|
+
hitRate: total > 0 ? this.hits / total : 0,
|
|
137
|
+
size: this.cache.size,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Reset statistics (useful for per-conversion tracking)
|
|
142
|
+
*/
|
|
143
|
+
resetStats() {
|
|
144
|
+
this.hits = 0;
|
|
145
|
+
this.misses = 0;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Clear the cache entirely
|
|
149
|
+
*/
|
|
150
|
+
clear() {
|
|
151
|
+
this.cache.clear();
|
|
152
|
+
this.hits = 0;
|
|
153
|
+
this.misses = 0;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Global UTF-8 cache instance
|
|
158
|
+
*
|
|
159
|
+
* Using a global cache provides cross-conversion caching benefits:
|
|
160
|
+
* - Strings that appear in multiple spans/buffers are cached
|
|
161
|
+
* - Warm cache improves performance over time
|
|
162
|
+
*
|
|
163
|
+
* The SIEVE eviction ensures bounded memory even with unbounded inputs.
|
|
164
|
+
*/
|
|
165
|
+
export const globalUtf8Cache = new Utf8Cache();
|
|
166
|
+
/**
|
|
167
|
+
* Create a new UTF-8 cache with custom size
|
|
168
|
+
*
|
|
169
|
+
* Use this when you want a dedicated cache instance (e.g., for testing
|
|
170
|
+
* or for isolation between different conversion contexts).
|
|
171
|
+
*
|
|
172
|
+
* @param maxSize - Maximum number of entries to cache
|
|
173
|
+
* @returns New Utf8Cache instance
|
|
174
|
+
*/
|
|
175
|
+
export function createUtf8Cache(maxSize) {
|
|
176
|
+
return new Utf8Cache(maxSize);
|
|
177
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WasmBufferStrategy - Buffer strategy using WASM memory with freelist allocation.
|
|
3
|
+
*
|
|
4
|
+
* Uses WebAssembly memory for numeric columns with O(1) freelist allocation/deallocation.
|
|
5
|
+
* String columns remain in JavaScript.
|
|
6
|
+
*
|
|
7
|
+
* Memory characteristics:
|
|
8
|
+
* - Numeric data lives in contiguous WASM memory (better cache locality)
|
|
9
|
+
* - Freelist enables O(1) memory reuse across traces
|
|
10
|
+
* - Explicit release required (not GC-managed)
|
|
11
|
+
* - Arrow conversion reads from WASM memory views
|
|
12
|
+
*
|
|
13
|
+
* @module WasmBufferStrategy
|
|
14
|
+
*/
|
|
15
|
+
import type { Table } from '@uwdata/flechette';
|
|
16
|
+
import type { BufferStrategy } from '../bufferStrategy.js';
|
|
17
|
+
import type { OpMetadata } from '../opContext/opTypes.js';
|
|
18
|
+
import type { LogSchema } from '../schema/LogSchema.js';
|
|
19
|
+
import type { ITraceRoot } from '../traceRoot.js';
|
|
20
|
+
import type { AnySpanBuffer, SpanBuffer } from '../types.js';
|
|
21
|
+
import { type WasmAllocator, type WasmAllocatorOptions } from './wasmAllocator.js';
|
|
22
|
+
/**
|
|
23
|
+
* Options for WasmBufferStrategy.
|
|
24
|
+
*/
|
|
25
|
+
export interface WasmBufferStrategyOptions extends WasmAllocatorOptions {
|
|
26
|
+
/** Pre-created allocator. If not provided, one will be created. */
|
|
27
|
+
allocator?: WasmAllocator;
|
|
28
|
+
}
|
|
29
|
+
type WasmAllocatorStats = {
|
|
30
|
+
allocCount: number;
|
|
31
|
+
freeCount: number;
|
|
32
|
+
bumpPtr: number;
|
|
33
|
+
capacity: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* WasmBufferStrategy - Buffer strategy using WASM memory with freelist allocation.
|
|
37
|
+
*
|
|
38
|
+
* This strategy is optimized for high-throughput scenarios:
|
|
39
|
+
* - Numeric columns allocated from WASM freelists (O(1) alloc/free)
|
|
40
|
+
* - Better cache locality from contiguous WASM memory
|
|
41
|
+
* - Explicit memory management via releaseBuffer()
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const strategy = await WasmBufferStrategy.create<MySchema>();
|
|
46
|
+
* const tracer = new StdioTracer(binding, { bufferStrategy: strategy });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class WasmBufferStrategy<T extends LogSchema = LogSchema> implements BufferStrategy<T> {
|
|
50
|
+
/**
|
|
51
|
+
* The WASM allocator instance.
|
|
52
|
+
* Shared across all buffers created by this strategy.
|
|
53
|
+
*/
|
|
54
|
+
readonly allocator: WasmAllocator;
|
|
55
|
+
/**
|
|
56
|
+
* Private constructor - use static create() method.
|
|
57
|
+
*/
|
|
58
|
+
private constructor();
|
|
59
|
+
/**
|
|
60
|
+
* Create a WasmBufferStrategy instance.
|
|
61
|
+
*
|
|
62
|
+
* Async because WASM module loading may be asynchronous.
|
|
63
|
+
*
|
|
64
|
+
* @param options - Configuration options
|
|
65
|
+
* @returns Promise<WasmBufferStrategy>
|
|
66
|
+
*/
|
|
67
|
+
static create<T extends LogSchema = LogSchema>(options?: WasmBufferStrategyOptions): Promise<WasmBufferStrategy<T>>;
|
|
68
|
+
createSpanBuffer(schema: T, traceRoot: ITraceRoot, opMetadata: OpMetadata, capacity?: number): SpanBuffer<T>;
|
|
69
|
+
createChildSpanBuffer(parentBuffer: SpanBuffer<T>, callsiteMetadata: OpMetadata, opMetadata: OpMetadata, capacity?: number, schema?: T): SpanBuffer<T>;
|
|
70
|
+
createOverflowBuffer(buffer: SpanBuffer<T>): SpanBuffer<T>;
|
|
71
|
+
toArrowTable(buffer: AnySpanBuffer): Table;
|
|
72
|
+
releaseBuffer(buffer: AnySpanBuffer): void;
|
|
73
|
+
/**
|
|
74
|
+
* Recursively free all WASM memory for a span tree.
|
|
75
|
+
*/
|
|
76
|
+
private freeSpanTree;
|
|
77
|
+
/**
|
|
78
|
+
* Reset the allocator (for testing/benchmarking).
|
|
79
|
+
* WARNING: This invalidates ALL buffers created by this strategy.
|
|
80
|
+
*/
|
|
81
|
+
reset(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Get allocator statistics for debugging/monitoring.
|
|
84
|
+
*/
|
|
85
|
+
getStats(): WasmAllocatorStats;
|
|
86
|
+
}
|
|
87
|
+
export {};
|
|
88
|
+
//# sourceMappingURL=WasmBufferStrategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WasmBufferStrategy.d.ts","sourceRoot":"","sources":["../../../src/lib/wasm/WasmBufferStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAgBxG;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;IACrE,mEAAmE;IACnE,SAAS,CAAC,EAAE,aAAa,CAAC;CAC3B;AAED,KAAK,kBAAkB,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,qBAAa,kBAAkB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CAAE,YAAW,cAAc,CAAC,CAAC,CAAC;IAC3F;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAElC;;OAEG;IACH,OAAO;IAIP;;;;;;;OAOG;WACU,MAAM,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACjD,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAKjC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;IAwB5G,qBAAqB,CACnB,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,EAC3B,gBAAgB,EAAE,UAAU,EAC5B,UAAU,EAAE,UAAU,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,CAAC,GACT,UAAU,CAAC,CAAC,CAAC;IA0BhB,oBAAoB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAc1D,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,KAAK;IAK1C,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAK1C;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,QAAQ,IAAI,kBAAkB;CAQ/B"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { convertSpanTreeToArrowTable } from '../convertToArrow.js';
|
|
2
|
+
import { EMPTY_SCOPE } from '../spanBuffer.js';
|
|
3
|
+
import { createWasmAllocator } from './wasmAllocator.js';
|
|
4
|
+
import { createWasmChildSpanBuffer, createWasmOverflowBuffer, createWasmSpanBuffer, isWasmSpanBufferInstance, } from './wasmSpanBuffer.js';
|
|
5
|
+
function requireWasmSpanBuffer(buffer) {
|
|
6
|
+
if (!isWasmSpanBufferInstance(buffer)) {
|
|
7
|
+
throw new Error('Expected WASM-backed span buffer');
|
|
8
|
+
}
|
|
9
|
+
return buffer;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* WasmBufferStrategy - Buffer strategy using WASM memory with freelist allocation.
|
|
13
|
+
*
|
|
14
|
+
* This strategy is optimized for high-throughput scenarios:
|
|
15
|
+
* - Numeric columns allocated from WASM freelists (O(1) alloc/free)
|
|
16
|
+
* - Better cache locality from contiguous WASM memory
|
|
17
|
+
* - Explicit memory management via releaseBuffer()
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const strategy = await WasmBufferStrategy.create<MySchema>();
|
|
22
|
+
* const tracer = new StdioTracer(binding, { bufferStrategy: strategy });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export class WasmBufferStrategy {
|
|
26
|
+
/**
|
|
27
|
+
* The WASM allocator instance.
|
|
28
|
+
* Shared across all buffers created by this strategy.
|
|
29
|
+
*/
|
|
30
|
+
allocator;
|
|
31
|
+
/**
|
|
32
|
+
* Private constructor - use static create() method.
|
|
33
|
+
*/
|
|
34
|
+
constructor(allocator) {
|
|
35
|
+
this.allocator = allocator;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a WasmBufferStrategy instance.
|
|
39
|
+
*
|
|
40
|
+
* Async because WASM module loading may be asynchronous.
|
|
41
|
+
*
|
|
42
|
+
* @param options - Configuration options
|
|
43
|
+
* @returns Promise<WasmBufferStrategy>
|
|
44
|
+
*/
|
|
45
|
+
static async create(options) {
|
|
46
|
+
const allocator = options?.allocator ?? (await createWasmAllocator(options));
|
|
47
|
+
return new WasmBufferStrategy(allocator);
|
|
48
|
+
}
|
|
49
|
+
createSpanBuffer(schema, traceRoot, opMetadata, capacity) {
|
|
50
|
+
const effectiveCapacity = capacity ?? this.allocator.capacity;
|
|
51
|
+
// Create WASM buffer
|
|
52
|
+
const wasmBuffer = createWasmSpanBuffer(schema, {
|
|
53
|
+
allocator: this.allocator,
|
|
54
|
+
capacity: effectiveCapacity,
|
|
55
|
+
trace_id: traceRoot.trace_id,
|
|
56
|
+
// thread_id and span_id come from WASM (global header and allocator respectively)
|
|
57
|
+
thread_id: 0n, // Will be read from WASM header
|
|
58
|
+
span_id: 0, // Will be assigned by WASM allocator
|
|
59
|
+
}, traceRoot, // _traceRoot
|
|
60
|
+
EMPTY_SCOPE, // _scopeValues
|
|
61
|
+
opMetadata, // _opMetadata
|
|
62
|
+
opMetadata);
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- generated WASM buffers implement the SpanBuffer contract for the same schema.
|
|
64
|
+
return wasmBuffer;
|
|
65
|
+
}
|
|
66
|
+
createChildSpanBuffer(parentBuffer, callsiteMetadata, opMetadata, capacity, schema) {
|
|
67
|
+
const wasmParent = requireWasmSpanBuffer(parentBuffer);
|
|
68
|
+
const effectiveCapacity = capacity ?? wasmParent._capacity;
|
|
69
|
+
// Use provided schema (for cross-library calls) or parent's schema
|
|
70
|
+
const childSchema = schema ?? parentBuffer._logSchema;
|
|
71
|
+
const child = createWasmChildSpanBuffer(wasmParent, {
|
|
72
|
+
allocator: this.allocator,
|
|
73
|
+
capacity: effectiveCapacity,
|
|
74
|
+
thread_id: 0n, // Will be read from WASM header
|
|
75
|
+
span_id: 0, // Will be assigned by WASM allocator
|
|
76
|
+
schema: childSchema, // Pass schema for correct buffer class
|
|
77
|
+
}, parentBuffer._traceRoot, // _traceRoot (inherit from parent)
|
|
78
|
+
parentBuffer._scopeValues, // _scopeValues (inherit from parent)
|
|
79
|
+
opMetadata, // _opMetadata
|
|
80
|
+
callsiteMetadata);
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- child buffers preserve the requested schema contract.
|
|
82
|
+
return child;
|
|
83
|
+
}
|
|
84
|
+
createOverflowBuffer(buffer) {
|
|
85
|
+
const wasmBuffer = requireWasmSpanBuffer(buffer);
|
|
86
|
+
const overflow = createWasmOverflowBuffer(wasmBuffer, buffer._traceRoot, // _traceRoot (same as original)
|
|
87
|
+
buffer._scopeValues, // _scopeValues (same as original)
|
|
88
|
+
buffer._opMetadata, // _opMetadata (same as original)
|
|
89
|
+
buffer._callsiteMetadata ?? buffer._opMetadata);
|
|
90
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- overflow buffers are schema-compatible continuations of the same span.
|
|
91
|
+
return overflow;
|
|
92
|
+
}
|
|
93
|
+
toArrowTable(buffer) {
|
|
94
|
+
// Uses existing tree conversion with shared dictionaries
|
|
95
|
+
return convertSpanTreeToArrowTable(buffer);
|
|
96
|
+
}
|
|
97
|
+
releaseBuffer(buffer) {
|
|
98
|
+
// Walk the span tree and free all WASM memory
|
|
99
|
+
this.freeSpanTree(requireWasmSpanBuffer(buffer));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Recursively free all WASM memory for a span tree.
|
|
103
|
+
*/
|
|
104
|
+
freeSpanTree(buffer) {
|
|
105
|
+
// Free children first (depth-first)
|
|
106
|
+
if (buffer._children) {
|
|
107
|
+
for (const child of buffer._children) {
|
|
108
|
+
this.freeSpanTree(child);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Free overflow chain
|
|
112
|
+
if (buffer._overflow) {
|
|
113
|
+
this.freeSpanTree(buffer._overflow);
|
|
114
|
+
}
|
|
115
|
+
// Free this buffer's WASM memory
|
|
116
|
+
if (typeof buffer.free === 'function') {
|
|
117
|
+
buffer.free();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Reset the allocator (for testing/benchmarking).
|
|
122
|
+
* WARNING: This invalidates ALL buffers created by this strategy.
|
|
123
|
+
*/
|
|
124
|
+
reset() {
|
|
125
|
+
this.allocator.reset();
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get allocator statistics for debugging/monitoring.
|
|
129
|
+
*/
|
|
130
|
+
getStats() {
|
|
131
|
+
return {
|
|
132
|
+
allocCount: this.allocator.getAllocCount(),
|
|
133
|
+
freeCount: this.allocator.getFreeCount(),
|
|
134
|
+
bumpPtr: this.allocator.getBumpPtr(),
|
|
135
|
+
capacity: this.allocator.capacity,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript wrapper for the WASM allocator.
|
|
3
|
+
*
|
|
4
|
+
* Implements spec 01q: WASM Memory Architecture for SpanBuffer Storage
|
|
5
|
+
*
|
|
6
|
+
* The allocator provides O(1) alloc/free via freelists with memory reuse.
|
|
7
|
+
* Each OpContext may have a different capacity - capacity is passed to each call.
|
|
8
|
+
*
|
|
9
|
+
* Buddy Allocation:
|
|
10
|
+
* - Blocks are organized by tier (capacity 8, 16, 32, 64, 128, 256, 512)
|
|
11
|
+
* - When freelist is empty, splits from larger tier
|
|
12
|
+
* - When freeing, merges with adjacent blocks if both are free (address-based buddy merge)
|
|
13
|
+
*/
|
|
14
|
+
export interface WasmAllocator {
|
|
15
|
+
/** The underlying WASM memory */
|
|
16
|
+
readonly memory: WebAssembly.Memory;
|
|
17
|
+
/** WASM exports for direct function calls (hot path optimization) */
|
|
18
|
+
readonly exports: {
|
|
19
|
+
write_col_f64: (colOffset: number, rowIdx: number, value: number, capacity: number) => number;
|
|
20
|
+
write_col_u32: (colOffset: number, rowIdx: number, value: number, capacity: number) => number;
|
|
21
|
+
write_col_u8: (colOffset: number, rowIdx: number, value: number, capacity: number) => number;
|
|
22
|
+
write_log_entry: (systemPtr: number, identityPtr: number, traceRootPtr: number, entryType: number, capacity: number) => number;
|
|
23
|
+
};
|
|
24
|
+
/** Cached views (recreated after grow, but pre-sized to avoid grow for benchmarks) */
|
|
25
|
+
readonly u8: Uint8Array;
|
|
26
|
+
readonly u32: Uint32Array;
|
|
27
|
+
readonly i64: BigInt64Array;
|
|
28
|
+
readonly f64: Float64Array;
|
|
29
|
+
/** Default capacity for convenience methods */
|
|
30
|
+
readonly capacity: number;
|
|
31
|
+
/** Initialize allocator header (call once) */
|
|
32
|
+
init(): void;
|
|
33
|
+
/** Reset all freelists (for testing/benchmarking) */
|
|
34
|
+
reset(): void;
|
|
35
|
+
allocSpanSystem(capacity?: number): number;
|
|
36
|
+
alloc1B(capacity?: number): number;
|
|
37
|
+
alloc4B(capacity?: number): number;
|
|
38
|
+
alloc8B(capacity?: number): number;
|
|
39
|
+
freeSpanSystem(offset: number, capacity?: number): void;
|
|
40
|
+
free1B(offset: number, capacity?: number): void;
|
|
41
|
+
free4B(offset: number, capacity?: number): void;
|
|
42
|
+
free8B(offset: number, capacity?: number): void;
|
|
43
|
+
spanStart(systemPtr: number, identityPtr: number, traceRootPtr: number, capacity?: number): void;
|
|
44
|
+
spanEndOk(systemPtr: number, traceRootPtr: number, capacity?: number): void;
|
|
45
|
+
spanEndErr(systemPtr: number, traceRootPtr: number, capacity?: number): void;
|
|
46
|
+
/** Write log entry, bump writeIndex, return idx written to */
|
|
47
|
+
writeLogEntry(systemPtr: number, identityPtr: number, traceRootPtr: number, entryType: number, capacity?: number): number;
|
|
48
|
+
writeColF64(colOffset: number, rowIdx: number, value: number, capacity?: number): number;
|
|
49
|
+
writeColU32(colOffset: number, rowIdx: number, value: number, capacity?: number): number;
|
|
50
|
+
writeColU8(colOffset: number, rowIdx: number, value: number, capacity?: number): number;
|
|
51
|
+
initTraceRoot(traceRootPtr: number): void;
|
|
52
|
+
getBumpPtr(): number;
|
|
53
|
+
getAllocCount(): number;
|
|
54
|
+
getFreeCount(): number;
|
|
55
|
+
getSpanSystemSize(capacity?: number): number;
|
|
56
|
+
getCol1BSize(capacity?: number): number;
|
|
57
|
+
getCol4BSize(capacity?: number): number;
|
|
58
|
+
getCol8BSize(capacity?: number): number;
|
|
59
|
+
readTimestamp(systemPtr: number, rowIdx: number): bigint;
|
|
60
|
+
readEntryType(systemPtr: number, rowIdx: number, capacity?: number): number;
|
|
61
|
+
readWriteIndex(identityPtr: number): number;
|
|
62
|
+
readColF64(colOffset: number, rowIdx: number, capacity?: number): number;
|
|
63
|
+
readColIsValid(colOffset: number, rowIdx: number): number;
|
|
64
|
+
setThreadId(high: number, low: number): void;
|
|
65
|
+
getThreadIdHigh(): number;
|
|
66
|
+
getThreadIdLow(): number;
|
|
67
|
+
isThreadIdSet(): number;
|
|
68
|
+
getSpanIdCounter(): number;
|
|
69
|
+
allocIdentityRootForJsWrite(traceIdLen: number): bigint;
|
|
70
|
+
allocIdentityChild(): number;
|
|
71
|
+
freeIdentity(offset: number): void;
|
|
72
|
+
readIdentitySpanId(identityPtr: number): number;
|
|
73
|
+
readIdentityTraceIdLen(identityPtr: number): number;
|
|
74
|
+
getIdentityTraceIdPtr(identityPtr: number): number;
|
|
75
|
+
getFreelistLen(sizeClass: SizeClass, capacity?: number): number;
|
|
76
|
+
getFreelistReuseCount(sizeClass: SizeClass, capacity?: number): number;
|
|
77
|
+
getFreelistSplitCount(sizeClass: SizeClass, capacity?: number): number;
|
|
78
|
+
getFreelistMergeCount(sizeClass: SizeClass, capacity?: number): number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Size class enum matching Zig's SizeClass
|
|
82
|
+
*/
|
|
83
|
+
export declare enum SizeClass {
|
|
84
|
+
SpanSystem = 0,
|
|
85
|
+
Col1B = 1,
|
|
86
|
+
Col4B = 2,
|
|
87
|
+
Col8B = 3,
|
|
88
|
+
Identity = 4
|
|
89
|
+
}
|
|
90
|
+
export interface WasmAllocatorOptions {
|
|
91
|
+
/** Initial memory pages (64KB each). Default: 17 (~1MB) */
|
|
92
|
+
initialPages?: number;
|
|
93
|
+
/** Maximum memory pages. Default: 16384 (1GB) */
|
|
94
|
+
maxPages?: number;
|
|
95
|
+
/** Default capacity (rows per span buffer). Default: 64 */
|
|
96
|
+
capacity?: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create a WASM allocator instance.
|
|
100
|
+
*
|
|
101
|
+
* The allocator uses freelist for O(1) alloc/free with memory reuse.
|
|
102
|
+
* Buddy allocation enables efficient memory management across different capacities.
|
|
103
|
+
*/
|
|
104
|
+
export declare function createWasmAllocator(options?: WasmAllocatorOptions): Promise<WasmAllocator>;
|
|
105
|
+
/**
|
|
106
|
+
* Synchronous version for when WASM is pre-loaded.
|
|
107
|
+
*/
|
|
108
|
+
export declare function createWasmAllocatorSync(wasmModule: WebAssembly.Module, options?: WasmAllocatorOptions): WasmAllocator;
|
|
109
|
+
//# sourceMappingURL=wasmAllocator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasmAllocator.d.ts","sourceRoot":"","sources":["../../../src/lib/wasm/wasmAllocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;IAEpC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE;QAChB,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;QAC9F,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;QAC9F,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;QAC7F,eAAe,EAAE,CACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,KACb,MAAM,CAAC;KACb,CAAC;IAEF,sFAAsF;IACtF,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAE3B,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,8CAA8C;IAC9C,IAAI,IAAI,IAAI,CAAC;IAEb,qDAAqD;IACrD,KAAK,IAAI,IAAI,CAAC;IAGd,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAGnC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGhD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7E,8DAA8D;IAC9D,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAAC;IAGV,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzF,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzF,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAGxF,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAG1C,UAAU,IAAI,MAAM,CAAC;IACrB,aAAa,IAAI,MAAM,CAAC;IACxB,YAAY,IAAI,MAAM,CAAC;IACvB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7C,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxC,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxC,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAGxC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACzD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5E,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzE,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAG1D,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,eAAe,IAAI,MAAM,CAAC;IAC1B,cAAc,IAAI,MAAM,CAAC;IACzB,aAAa,IAAI,MAAM,CAAC;IACxB,gBAAgB,IAAI,MAAM,CAAC;IAG3B,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;IACxD,kBAAkB,IAAI,MAAM,CAAC;IAC7B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAChD,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IACpD,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAGnD,cAAc,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAChE,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvE,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvE,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxE;AAED;;GAEG;AACH,oBAAY,SAAS;IACnB,UAAU,IAAI;IACd,KAAK,IAAI;IACT,KAAK,IAAI;IACT,KAAK,IAAI;IACT,QAAQ,IAAI;CACb;AAED,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA0RD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CAmBhG;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,aAAa,CAgBrH"}
|