@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,699 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from 'bun:test';
|
|
2
|
+
import { createWasmAllocator, SizeClass, type WasmAllocator } from '../wasmAllocator.js';
|
|
3
|
+
|
|
4
|
+
describe('WasmAllocator', () => {
|
|
5
|
+
let allocator: WasmAllocator;
|
|
6
|
+
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
allocator = await createWasmAllocator({ capacity: 64 });
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
describe('instantiation', () => {
|
|
12
|
+
it('creates allocator with default options', async () => {
|
|
13
|
+
const alloc = await createWasmAllocator();
|
|
14
|
+
expect(alloc).toBeDefined();
|
|
15
|
+
expect(alloc.memory).toBeInstanceOf(WebAssembly.Memory);
|
|
16
|
+
expect(alloc.u8).toBeInstanceOf(Uint8Array);
|
|
17
|
+
expect(alloc.u32).toBeInstanceOf(Uint32Array);
|
|
18
|
+
expect(alloc.i64).toBeInstanceOf(BigInt64Array);
|
|
19
|
+
expect(alloc.f64).toBeInstanceOf(Float64Array);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('creates allocator with custom capacity', async () => {
|
|
23
|
+
const alloc = await createWasmAllocator({ capacity: 128 });
|
|
24
|
+
expect(alloc.capacity).toBe(128);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('init', () => {
|
|
29
|
+
it('initializes freelists to empty', async () => {
|
|
30
|
+
// Create fresh allocator
|
|
31
|
+
const alloc = await createWasmAllocator({ capacity: 64 });
|
|
32
|
+
|
|
33
|
+
// All freelists should be empty after init
|
|
34
|
+
for (const tier of [8, 16, 32, 64, 128, 256, 512]) {
|
|
35
|
+
for (const sc of [SizeClass.SpanSystem, SizeClass.Col1B, SizeClass.Col4B, SizeClass.Col8B]) {
|
|
36
|
+
const len = alloc.getFreelistLen(sc, tier);
|
|
37
|
+
expect(len).toBe(0);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('stores default capacity', () => {
|
|
43
|
+
expect(allocator.capacity).toBe(64);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('can create allocator with different default capacity', async () => {
|
|
47
|
+
const alloc128 = await createWasmAllocator({ capacity: 128 });
|
|
48
|
+
expect(alloc128.capacity).toBe(128);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('allocSpanSystem', () => {
|
|
53
|
+
it('returns valid offset greater than header size (192 bytes)', () => {
|
|
54
|
+
const offset = allocator.allocSpanSystem();
|
|
55
|
+
expect(offset).toBeGreaterThanOrEqual(192);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('returns different offsets for multiple allocations', () => {
|
|
59
|
+
const offset1 = allocator.allocSpanSystem();
|
|
60
|
+
const offset2 = allocator.allocSpanSystem();
|
|
61
|
+
expect(offset1).not.toBe(offset2);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('returns 8-byte aligned offsets', () => {
|
|
65
|
+
const offset = allocator.allocSpanSystem();
|
|
66
|
+
expect(offset % 8).toBe(0);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('increments alloc count', () => {
|
|
70
|
+
const before = allocator.getAllocCount();
|
|
71
|
+
allocator.allocSpanSystem();
|
|
72
|
+
expect(allocator.getAllocCount()).toBe(before + 1);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('freelist reuse', () => {
|
|
77
|
+
it('reuses freed SpanSystem offset', () => {
|
|
78
|
+
const offset1 = allocator.allocSpanSystem();
|
|
79
|
+
allocator.freeSpanSystem(offset1);
|
|
80
|
+
const offset2 = allocator.allocSpanSystem();
|
|
81
|
+
expect(offset2).toBe(offset1);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('reuses freed 1B column offset', () => {
|
|
85
|
+
const offset1 = allocator.alloc1B();
|
|
86
|
+
allocator.free1B(offset1);
|
|
87
|
+
const offset2 = allocator.alloc1B();
|
|
88
|
+
expect(offset2).toBe(offset1);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('reuses freed 4B column offset', () => {
|
|
92
|
+
const offset1 = allocator.alloc4B();
|
|
93
|
+
allocator.free4B(offset1);
|
|
94
|
+
const offset2 = allocator.alloc4B();
|
|
95
|
+
expect(offset2).toBe(offset1);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('reuses freed 8B column offset', () => {
|
|
99
|
+
const offset1 = allocator.alloc8B();
|
|
100
|
+
allocator.free8B(offset1);
|
|
101
|
+
const offset2 = allocator.alloc8B();
|
|
102
|
+
expect(offset2).toBe(offset1);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('reuses freed identity block offset', () => {
|
|
106
|
+
const offset1 = allocator.allocIdentityChild();
|
|
107
|
+
allocator.freeIdentity(offset1);
|
|
108
|
+
const offset2 = allocator.allocIdentityChild();
|
|
109
|
+
expect(offset2).toBe(offset1);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('increments free count', () => {
|
|
113
|
+
const offset = allocator.allocSpanSystem();
|
|
114
|
+
const before = allocator.getFreeCount();
|
|
115
|
+
allocator.freeSpanSystem(offset);
|
|
116
|
+
expect(allocator.getFreeCount()).toBe(before + 1);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe('reset', () => {
|
|
121
|
+
it('clears freelists and resets bump ptr to header', () => {
|
|
122
|
+
// Allocate some blocks
|
|
123
|
+
allocator.allocSpanSystem();
|
|
124
|
+
allocator.alloc1B();
|
|
125
|
+
allocator.alloc4B();
|
|
126
|
+
allocator.alloc8B();
|
|
127
|
+
|
|
128
|
+
const bumpBefore = allocator.getBumpPtr();
|
|
129
|
+
expect(bumpBefore).toBeGreaterThan(192);
|
|
130
|
+
|
|
131
|
+
// Reset
|
|
132
|
+
allocator.reset();
|
|
133
|
+
|
|
134
|
+
// Bump ptr should be back at header (192 bytes)
|
|
135
|
+
expect(allocator.getBumpPtr()).toBe(192);
|
|
136
|
+
expect(allocator.getAllocCount()).toBe(0);
|
|
137
|
+
expect(allocator.getFreeCount()).toBe(0);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe('span lifecycle', () => {
|
|
142
|
+
it('spanStart writes entry_type=1 at row 0', () => {
|
|
143
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
144
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
145
|
+
const traceRootPtr = allocator.alloc8B();
|
|
146
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
147
|
+
|
|
148
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
149
|
+
|
|
150
|
+
expect(allocator.readEntryType(systemPtr, 0)).toBe(1); // SPAN_START
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('spanStart sets entry_type=4 (SPAN_EXCEPTION) at row 1 as placeholder', () => {
|
|
154
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
155
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
156
|
+
const traceRootPtr = allocator.alloc8B();
|
|
157
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
158
|
+
|
|
159
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
160
|
+
|
|
161
|
+
expect(allocator.readEntryType(systemPtr, 1)).toBe(4); // SPAN_EXCEPTION placeholder
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('spanStart sets writeIndex to 2', () => {
|
|
165
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
166
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
167
|
+
const traceRootPtr = allocator.alloc8B();
|
|
168
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
169
|
+
|
|
170
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
171
|
+
|
|
172
|
+
expect(allocator.readWriteIndex(identityPtr)).toBe(2);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('spanEndOk writes entry_type=2 at row 1', () => {
|
|
176
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
177
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
178
|
+
const traceRootPtr = allocator.alloc8B();
|
|
179
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
180
|
+
|
|
181
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
182
|
+
allocator.spanEndOk(systemPtr, traceRootPtr);
|
|
183
|
+
|
|
184
|
+
expect(allocator.readEntryType(systemPtr, 1)).toBe(2); // SPAN_OK
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('spanEndErr writes entry_type=3 at row 1', () => {
|
|
188
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
189
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
190
|
+
const traceRootPtr = allocator.alloc8B();
|
|
191
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
192
|
+
|
|
193
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
194
|
+
allocator.spanEndErr(systemPtr, traceRootPtr);
|
|
195
|
+
|
|
196
|
+
expect(allocator.readEntryType(systemPtr, 1)).toBe(3); // SPAN_ERR
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('spanStart writes timestamp at row 0', () => {
|
|
200
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
201
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
202
|
+
const traceRootPtr = allocator.alloc8B();
|
|
203
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
204
|
+
|
|
205
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
206
|
+
|
|
207
|
+
const timestamp = allocator.readTimestamp(systemPtr, 0);
|
|
208
|
+
expect(timestamp).toBeGreaterThan(0n);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('spanEndOk writes timestamp at row 1', () => {
|
|
212
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
213
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
214
|
+
const traceRootPtr = allocator.alloc8B();
|
|
215
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
216
|
+
|
|
217
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
218
|
+
allocator.spanEndOk(systemPtr, traceRootPtr);
|
|
219
|
+
|
|
220
|
+
const timestamp = allocator.readTimestamp(systemPtr, 1);
|
|
221
|
+
expect(timestamp).toBeGreaterThan(0n);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
describe('writeLogEntry', () => {
|
|
226
|
+
it('writes log entry and returns row index', () => {
|
|
227
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
228
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
229
|
+
const traceRootPtr = allocator.alloc8B();
|
|
230
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
231
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
232
|
+
|
|
233
|
+
// _writeIndex starts at 2 after spanStart
|
|
234
|
+
const rowIdx = allocator.writeLogEntry(systemPtr, identityPtr, traceRootPtr, 6); // INFO = 6
|
|
235
|
+
|
|
236
|
+
expect(rowIdx).toBe(2);
|
|
237
|
+
expect(allocator.readEntryType(systemPtr, 2)).toBe(6);
|
|
238
|
+
expect(allocator.readWriteIndex(identityPtr)).toBe(3);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('increments writeIndex for each log entry', () => {
|
|
242
|
+
const systemPtr = allocator.allocSpanSystem();
|
|
243
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
244
|
+
const traceRootPtr = allocator.alloc8B();
|
|
245
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
246
|
+
allocator.spanStart(systemPtr, identityPtr, traceRootPtr);
|
|
247
|
+
|
|
248
|
+
const idx1 = allocator.writeLogEntry(systemPtr, identityPtr, traceRootPtr, 6);
|
|
249
|
+
const idx2 = allocator.writeLogEntry(systemPtr, identityPtr, traceRootPtr, 7);
|
|
250
|
+
const idx3 = allocator.writeLogEntry(systemPtr, identityPtr, traceRootPtr, 8);
|
|
251
|
+
|
|
252
|
+
expect(idx1).toBe(2);
|
|
253
|
+
expect(idx2).toBe(3);
|
|
254
|
+
expect(idx3).toBe(4);
|
|
255
|
+
expect(allocator.readWriteIndex(identityPtr)).toBe(5);
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
describe('column writes', () => {
|
|
260
|
+
it('writeColF64 allocates and writes value', () => {
|
|
261
|
+
let colOffset = 0;
|
|
262
|
+
colOffset = allocator.writeColF64(colOffset, 0, 3.14);
|
|
263
|
+
|
|
264
|
+
expect(colOffset).toBeGreaterThan(0);
|
|
265
|
+
expect(allocator.readColF64(colOffset, 0)).toBeCloseTo(3.14);
|
|
266
|
+
expect(allocator.readColIsValid(colOffset, 0)).toBe(1);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('writeColF64 writes to existing column', () => {
|
|
270
|
+
let colOffset = allocator.writeColF64(0, 0, 1.0);
|
|
271
|
+
colOffset = allocator.writeColF64(colOffset, 1, 2.0);
|
|
272
|
+
allocator.writeColF64(colOffset, 2, 3.0);
|
|
273
|
+
|
|
274
|
+
expect(allocator.readColF64(colOffset, 0)).toBeCloseTo(1.0);
|
|
275
|
+
expect(allocator.readColF64(colOffset, 1)).toBeCloseTo(2.0);
|
|
276
|
+
expect(allocator.readColF64(colOffset, 2)).toBeCloseTo(3.0);
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
it('writeColU32 allocates and writes value', () => {
|
|
280
|
+
let colOffset = 0;
|
|
281
|
+
colOffset = allocator.writeColU32(colOffset, 0, 42);
|
|
282
|
+
|
|
283
|
+
expect(colOffset).toBeGreaterThan(0);
|
|
284
|
+
// Read via u32 view
|
|
285
|
+
const nullBitmapSize = Math.ceil(64 / 8); // capacity / 8
|
|
286
|
+
const valueOffset = (colOffset + nullBitmapSize) / 4; // convert to u32 index
|
|
287
|
+
expect(allocator.u32[valueOffset]).toBe(42);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it('writeColU8 allocates and writes value', () => {
|
|
291
|
+
let colOffset = 0;
|
|
292
|
+
colOffset = allocator.writeColU8(colOffset, 0, 255);
|
|
293
|
+
|
|
294
|
+
expect(colOffset).toBeGreaterThan(0);
|
|
295
|
+
// Read via u8 view
|
|
296
|
+
const nullBitmapSize = Math.ceil(64 / 8); // capacity / 8
|
|
297
|
+
expect(allocator.u8[colOffset + nullBitmapSize]).toBe(255);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('writeColF64 sets null bit (validity)', () => {
|
|
301
|
+
const colOffset = allocator.writeColF64(0, 5, 99.9);
|
|
302
|
+
|
|
303
|
+
// Check that row 5 is marked valid
|
|
304
|
+
expect(allocator.readColIsValid(colOffset, 5)).toBe(1);
|
|
305
|
+
// Check that row 0 is not valid (we didn't write to it)
|
|
306
|
+
expect(allocator.readColIsValid(colOffset, 0)).toBe(0);
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
describe('TraceRoot', () => {
|
|
311
|
+
it('initTraceRoot sets wall clock and monotonic time', () => {
|
|
312
|
+
const traceRootPtr = allocator.alloc8B(); // 8B column is large enough for 16 bytes
|
|
313
|
+
const before = Date.now();
|
|
314
|
+
|
|
315
|
+
allocator.initTraceRoot(traceRootPtr);
|
|
316
|
+
|
|
317
|
+
// Read wall clock (first 8 bytes as i64 nanoseconds)
|
|
318
|
+
const wallClockNanos = allocator.i64[traceRootPtr / 8];
|
|
319
|
+
const wallClockMs = Number(wallClockNanos / 1_000_000n);
|
|
320
|
+
|
|
321
|
+
expect(wallClockMs).toBeGreaterThanOrEqual(before);
|
|
322
|
+
expect(wallClockMs).toBeLessThan(before + 1000); // Within 1 second
|
|
323
|
+
|
|
324
|
+
// Read monotonic time (next 8 bytes as f64 milliseconds)
|
|
325
|
+
const monotonicMs = allocator.f64[(traceRootPtr + 8) / 8];
|
|
326
|
+
expect(monotonicMs).toBeGreaterThan(0);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
describe('identity block', () => {
|
|
331
|
+
it('allocIdentityChild returns valid offset', () => {
|
|
332
|
+
const identityPtr = allocator.allocIdentityChild();
|
|
333
|
+
expect(identityPtr).toBeGreaterThanOrEqual(192);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('allocIdentityChild returns unique span_id for each allocation', () => {
|
|
337
|
+
const id1 = allocator.allocIdentityChild();
|
|
338
|
+
const id2 = allocator.allocIdentityChild();
|
|
339
|
+
|
|
340
|
+
const spanId1 = allocator.readIdentitySpanId(id1);
|
|
341
|
+
const spanId2 = allocator.readIdentitySpanId(id2);
|
|
342
|
+
|
|
343
|
+
expect(spanId1).toBeGreaterThan(0);
|
|
344
|
+
expect(spanId2).toBeGreaterThan(spanId1);
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('allocIdentityRootForJsWrite stores trace_id', () => {
|
|
348
|
+
const traceId = 'test-trace-id-123';
|
|
349
|
+
const traceIdBytes = new TextEncoder().encode(traceId);
|
|
350
|
+
|
|
351
|
+
const packed = allocator.allocIdentityRootForJsWrite(traceIdBytes.length);
|
|
352
|
+
const identityPtr = Number(packed >> 32n);
|
|
353
|
+
const traceIdOffset = Number(packed & 0xffffffffn);
|
|
354
|
+
|
|
355
|
+
allocator.u8.set(traceIdBytes, traceIdOffset);
|
|
356
|
+
|
|
357
|
+
expect(allocator.readIdentityTraceIdLen(identityPtr)).toBe(traceIdBytes.length);
|
|
358
|
+
|
|
359
|
+
const storedTraceIdPtr = allocator.getIdentityTraceIdPtr(identityPtr);
|
|
360
|
+
const storedBytes = allocator.u8.slice(storedTraceIdPtr, storedTraceIdPtr + traceIdBytes.length);
|
|
361
|
+
const storedTraceId = new TextDecoder().decode(storedBytes);
|
|
362
|
+
expect(storedTraceId).toBe(traceId);
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
describe('block sizes', () => {
|
|
367
|
+
it('reports correct span system size for capacity 64', () => {
|
|
368
|
+
// capacity × 9 bytes (timestamp + entry_type, writeIndex moved to identity)
|
|
369
|
+
// 64 × 9 = 576, aligned to 8 = 576
|
|
370
|
+
expect(allocator.getSpanSystemSize()).toBe(576);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it('reports correct 1B column size for capacity 64', () => {
|
|
374
|
+
// ceil(capacity/8) + capacity × 1
|
|
375
|
+
// ceil(64/8) + 64 = 8 + 64 = 72
|
|
376
|
+
expect(allocator.getCol1BSize()).toBe(72);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it('reports correct 4B column size for capacity 64', () => {
|
|
380
|
+
// ceil(capacity/8) + capacity × 4
|
|
381
|
+
// 8 + 256 = 264
|
|
382
|
+
expect(allocator.getCol4BSize()).toBe(264);
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it('reports correct 8B column size for capacity 64', () => {
|
|
386
|
+
// ceil(capacity/8) + capacity × 8
|
|
387
|
+
// 8 + 512 = 520
|
|
388
|
+
expect(allocator.getCol8BSize()).toBe(520);
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
describe('freelist statistics', () => {
|
|
393
|
+
it('getFreelistLen returns 0 for empty freelist', () => {
|
|
394
|
+
// Fresh allocator, no frees yet
|
|
395
|
+
expect(allocator.getFreelistLen(SizeClass.SpanSystem)).toBe(0);
|
|
396
|
+
expect(allocator.getFreelistLen(SizeClass.Col1B)).toBe(0);
|
|
397
|
+
expect(allocator.getFreelistLen(SizeClass.Col4B)).toBe(0);
|
|
398
|
+
expect(allocator.getFreelistLen(SizeClass.Col8B)).toBe(0);
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it('getFreelistLen increments on free at max tier', async () => {
|
|
402
|
+
// Use max tier (512) to avoid buddy split/merge behavior
|
|
403
|
+
const alloc = await createWasmAllocator({ capacity: 512 });
|
|
404
|
+
|
|
405
|
+
// Allocate 2 blocks at max tier (bump allocates directly, no split)
|
|
406
|
+
const offset1 = alloc.allocSpanSystem(512);
|
|
407
|
+
const offset2 = alloc.allocSpanSystem(512);
|
|
408
|
+
|
|
409
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(0);
|
|
410
|
+
|
|
411
|
+
alloc.freeSpanSystem(offset1, 512);
|
|
412
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(1);
|
|
413
|
+
|
|
414
|
+
alloc.freeSpanSystem(offset2, 512);
|
|
415
|
+
// No merge at max tier, both should be in freelist
|
|
416
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(2);
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it('getFreelistReuseCount increments on alloc from freelist', async () => {
|
|
420
|
+
// Use max tier (512) to avoid buddy split/merge behavior
|
|
421
|
+
const alloc = await createWasmAllocator({ capacity: 512 });
|
|
422
|
+
|
|
423
|
+
// Allocate 2 blocks at max tier
|
|
424
|
+
const offset1 = alloc.allocSpanSystem(512);
|
|
425
|
+
const offset2 = alloc.allocSpanSystem(512);
|
|
426
|
+
|
|
427
|
+
// Free both (no merge at max tier)
|
|
428
|
+
alloc.freeSpanSystem(offset1, 512);
|
|
429
|
+
alloc.freeSpanSystem(offset2, 512);
|
|
430
|
+
|
|
431
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(2);
|
|
432
|
+
expect(alloc.getFreelistReuseCount(SizeClass.SpanSystem, 512)).toBe(0);
|
|
433
|
+
|
|
434
|
+
// Alloc from freelist - should increment reuse count
|
|
435
|
+
alloc.allocSpanSystem(512);
|
|
436
|
+
expect(alloc.getFreelistReuseCount(SizeClass.SpanSystem, 512)).toBe(1);
|
|
437
|
+
|
|
438
|
+
alloc.allocSpanSystem(512);
|
|
439
|
+
// Freelist empty now, so reuse count stays at previous HEAD value
|
|
440
|
+
expect(alloc.getFreelistReuseCount(SizeClass.SpanSystem, 512)).toBe(0); // empty freelist returns 0
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
it('cascading stats accumulate correctly', async () => {
|
|
444
|
+
// Use fresh allocator to avoid interference from other tests
|
|
445
|
+
const freshAlloc = await createWasmAllocator({ capacity: 64 });
|
|
446
|
+
|
|
447
|
+
// Allocate 6 blocks - keep every other one to prevent merge on free
|
|
448
|
+
const offsets: number[] = [];
|
|
449
|
+
const keepers: number[] = [];
|
|
450
|
+
for (let i = 0; i < 12; i++) {
|
|
451
|
+
const offset = freshAlloc.alloc8B();
|
|
452
|
+
if (i % 2 === 0) {
|
|
453
|
+
offsets.push(offset);
|
|
454
|
+
} else {
|
|
455
|
+
keepers.push(offset);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Free the 6 non-adjacent blocks (they can't merge because keepers are between them)
|
|
460
|
+
for (const offset of offsets) {
|
|
461
|
+
freshAlloc.free8B(offset);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
expect(freshAlloc.getFreelistLen(SizeClass.Col8B)).toBe(6);
|
|
465
|
+
|
|
466
|
+
// Allocate 4 back
|
|
467
|
+
freshAlloc.alloc8B();
|
|
468
|
+
freshAlloc.alloc8B();
|
|
469
|
+
freshAlloc.alloc8B();
|
|
470
|
+
freshAlloc.alloc8B();
|
|
471
|
+
|
|
472
|
+
expect(freshAlloc.getFreelistLen(SizeClass.Col8B)).toBe(2); // 6 - 4 = 2 remaining
|
|
473
|
+
expect(freshAlloc.getFreelistReuseCount(SizeClass.Col8B)).toBe(4); // 4 reuses
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
describe('buddy allocation', () => {
|
|
478
|
+
it('splits larger tier block when current tier freelist is empty', async () => {
|
|
479
|
+
// Create allocator
|
|
480
|
+
const alloc = await createWasmAllocator({ capacity: 32 });
|
|
481
|
+
|
|
482
|
+
// Allocate at capacity 64 (tier 3) and free it
|
|
483
|
+
const largeOffset = alloc.allocSpanSystem(64);
|
|
484
|
+
alloc.freeSpanSystem(largeOffset, 64);
|
|
485
|
+
|
|
486
|
+
// Freelist for tier 2 is empty, but tier 3 has a block
|
|
487
|
+
// Buddy split should occur when allocating at capacity 32
|
|
488
|
+
const offset1 = alloc.allocSpanSystem(32);
|
|
489
|
+
expect(offset1).toBe(largeOffset); // First half of split block
|
|
490
|
+
|
|
491
|
+
// Second half should now be in freelist at tier 2 (capacity 32)
|
|
492
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 32)).toBe(1);
|
|
493
|
+
|
|
494
|
+
// Split count should be 1
|
|
495
|
+
expect(alloc.getFreelistSplitCount(SizeClass.SpanSystem, 32)).toBe(1);
|
|
496
|
+
|
|
497
|
+
// Allocate again - should get second half from freelist
|
|
498
|
+
const offset2 = alloc.allocSpanSystem(32);
|
|
499
|
+
expect(offset2).toBe(largeOffset + alloc.getSpanSystemSize(32));
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
describe('buddy merge', () => {
|
|
503
|
+
it('basic freelist push/pop at max tier works correctly', async () => {
|
|
504
|
+
// Use max tier (512) to avoid split behavior
|
|
505
|
+
const alloc = await createWasmAllocator({ capacity: 512 });
|
|
506
|
+
|
|
507
|
+
// Allocate at max capacity (tier 6) - bump allocates directly
|
|
508
|
+
const offset = alloc.allocSpanSystem(512);
|
|
509
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(0); // Just allocated, freelist empty
|
|
510
|
+
|
|
511
|
+
alloc.freeSpanSystem(offset, 512);
|
|
512
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(1); // Freed, freelist has 1
|
|
513
|
+
|
|
514
|
+
// Allocate again - should get same offset from freelist
|
|
515
|
+
const offset2 = alloc.allocSpanSystem(512);
|
|
516
|
+
expect(offset2).toBe(offset);
|
|
517
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(0); // Popped, freelist empty
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
it('free at tier 6 (max) pushes correctly', async () => {
|
|
521
|
+
const alloc = await createWasmAllocator({ capacity: 512 });
|
|
522
|
+
|
|
523
|
+
// Allocate at max capacity (tier 6)
|
|
524
|
+
const offset = alloc.allocSpanSystem(512);
|
|
525
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(0);
|
|
526
|
+
|
|
527
|
+
// Free at capacity 512 (tier 6) - should NOT try to merge (no higher tier)
|
|
528
|
+
alloc.freeSpanSystem(offset, 512);
|
|
529
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(1);
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
it('adjacent blocks cascade merge to max tier', async () => {
|
|
533
|
+
const alloc = await createWasmAllocator({ capacity: 32 });
|
|
534
|
+
|
|
535
|
+
// Allocate two tier-3 blocks
|
|
536
|
+
const block1 = alloc.allocSpanSystem(64);
|
|
537
|
+
const block2 = alloc.allocSpanSystem(64);
|
|
538
|
+
|
|
539
|
+
// Verify they're adjacent
|
|
540
|
+
expect(block2).toBe(block1 + alloc.getSpanSystemSize(64));
|
|
541
|
+
|
|
542
|
+
// Free both - should cascade merge all the way to max tier
|
|
543
|
+
alloc.freeSpanSystem(block1, 64);
|
|
544
|
+
alloc.freeSpanSystem(block2, 64);
|
|
545
|
+
|
|
546
|
+
// After cascade, only max tier should have the block
|
|
547
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 64)).toBe(0);
|
|
548
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(1);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
it('merges adjacent blocks when both are freed (cascading)', async () => {
|
|
552
|
+
// Create allocator
|
|
553
|
+
const alloc = await createWasmAllocator({ capacity: 32 });
|
|
554
|
+
|
|
555
|
+
// Allocate two capacity-32 blocks (which splits all the way from max tier)
|
|
556
|
+
const child1 = alloc.allocSpanSystem(32);
|
|
557
|
+
const child2 = alloc.allocSpanSystem(32);
|
|
558
|
+
|
|
559
|
+
// Verify they're adjacent
|
|
560
|
+
expect(child2).toBe(child1 + alloc.getSpanSystemSize(32));
|
|
561
|
+
|
|
562
|
+
// Free both - they should merge and cascade up to max tier
|
|
563
|
+
alloc.freeSpanSystem(child2, 32);
|
|
564
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 32)).toBe(1); // child2 in tier-2
|
|
565
|
+
|
|
566
|
+
alloc.freeSpanSystem(child1, 32);
|
|
567
|
+
|
|
568
|
+
// After merge cascade, tier-2 should be empty
|
|
569
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 32)).toBe(0);
|
|
570
|
+
|
|
571
|
+
// The merge cascades all the way to max tier (512) because there are
|
|
572
|
+
// sibling blocks at each tier from the original split
|
|
573
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(1);
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
it('merges regardless of free order', async () => {
|
|
577
|
+
// Create allocator
|
|
578
|
+
const alloc = await createWasmAllocator({ capacity: 32 });
|
|
579
|
+
|
|
580
|
+
// Allocate two capacity-32 blocks
|
|
581
|
+
const child1 = alloc.allocSpanSystem(32);
|
|
582
|
+
const child2 = alloc.allocSpanSystem(32);
|
|
583
|
+
|
|
584
|
+
// Free in opposite order (child1 first instead of child2)
|
|
585
|
+
alloc.freeSpanSystem(child1, 32);
|
|
586
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 32)).toBe(1);
|
|
587
|
+
|
|
588
|
+
alloc.freeSpanSystem(child2, 32);
|
|
589
|
+
|
|
590
|
+
// After merge cascade, tier-2 should be empty
|
|
591
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 32)).toBe(0);
|
|
592
|
+
|
|
593
|
+
// Cascades to max tier
|
|
594
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(1);
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
it('cascading merge: all the way to max tier', async () => {
|
|
598
|
+
// Create allocator
|
|
599
|
+
const alloc = await createWasmAllocator({ capacity: 16 });
|
|
600
|
+
|
|
601
|
+
// Allocate 4 blocks at capacity 16 (splits from max tier)
|
|
602
|
+
const blockSize16 = alloc.getSpanSystemSize(16);
|
|
603
|
+
|
|
604
|
+
const blocks = [
|
|
605
|
+
alloc.allocSpanSystem(16),
|
|
606
|
+
alloc.allocSpanSystem(16),
|
|
607
|
+
alloc.allocSpanSystem(16),
|
|
608
|
+
alloc.allocSpanSystem(16),
|
|
609
|
+
];
|
|
610
|
+
|
|
611
|
+
// Verify offsets are sequential
|
|
612
|
+
expect(blocks[1]).toBe(blocks[0] + blockSize16);
|
|
613
|
+
expect(blocks[2]).toBe(blocks[0] + blockSize16 * 2);
|
|
614
|
+
expect(blocks[3]).toBe(blocks[0] + blockSize16 * 3);
|
|
615
|
+
|
|
616
|
+
// Free all 4 blocks - should cascade merge all the way to max tier
|
|
617
|
+
for (const offset of blocks) {
|
|
618
|
+
alloc.freeSpanSystem(offset, 16);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// After full cascade, should end up at max tier (512)
|
|
622
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(1);
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
it('partial merge when not all siblings freed', async () => {
|
|
626
|
+
const alloc = await createWasmAllocator({ capacity: 16 });
|
|
627
|
+
|
|
628
|
+
// Allocate 4 blocks at capacity 16
|
|
629
|
+
const blocks = [
|
|
630
|
+
alloc.allocSpanSystem(16),
|
|
631
|
+
alloc.allocSpanSystem(16),
|
|
632
|
+
alloc.allocSpanSystem(16),
|
|
633
|
+
alloc.allocSpanSystem(16),
|
|
634
|
+
];
|
|
635
|
+
|
|
636
|
+
// Free only first two - should merge to tier-2 (capacity 32) but stop there
|
|
637
|
+
// because blocks[2] and [3] are still allocated
|
|
638
|
+
alloc.freeSpanSystem(blocks[0], 16);
|
|
639
|
+
alloc.freeSpanSystem(blocks[1], 16);
|
|
640
|
+
|
|
641
|
+
// Tier-1 (16) should be empty (merged)
|
|
642
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 16)).toBe(0);
|
|
643
|
+
|
|
644
|
+
// Since blocks[2] and [3] are still allocated, merge should stop
|
|
645
|
+
// somewhere in the middle, not reach max tier
|
|
646
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(0);
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
it('merge count accumulates correctly', async () => {
|
|
650
|
+
const alloc = await createWasmAllocator({ capacity: 32 });
|
|
651
|
+
|
|
652
|
+
// Allocate and free at max tier to get a clean baseline
|
|
653
|
+
const block1 = alloc.allocSpanSystem(512);
|
|
654
|
+
const block2 = alloc.allocSpanSystem(512);
|
|
655
|
+
alloc.freeSpanSystem(block1, 512);
|
|
656
|
+
alloc.freeSpanSystem(block2, 512);
|
|
657
|
+
|
|
658
|
+
// Now tier-6 has 2 blocks (no merge possible at max tier)
|
|
659
|
+
expect(alloc.getFreelistLen(SizeClass.SpanSystem, 512)).toBe(2);
|
|
660
|
+
|
|
661
|
+
// Merge count at max tier should still be 0 (no merges at max tier)
|
|
662
|
+
expect(alloc.getFreelistMergeCount(SizeClass.SpanSystem, 512)).toBe(0);
|
|
663
|
+
});
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
describe('memory growth', () => {
|
|
668
|
+
it('grows memory when bump allocation exceeds current size', async () => {
|
|
669
|
+
// Start with minimal memory (17 pages = ~1MB)
|
|
670
|
+
const alloc = await createWasmAllocator({ initialPages: 17, capacity: 512 });
|
|
671
|
+
|
|
672
|
+
const initialBump = alloc.getBumpPtr();
|
|
673
|
+
const blockSize = alloc.getSpanSystemSize(); // 512 * 9 = 4608 bytes per block
|
|
674
|
+
|
|
675
|
+
// Allocate enough blocks to exceed initial memory
|
|
676
|
+
// 17 pages = 17 * 64KB = 1,114,112 bytes
|
|
677
|
+
// Each block is ~4608 bytes, so ~242 blocks to fill initial memory
|
|
678
|
+
const blocksToAllocate = 300; // More than fits in initial memory
|
|
679
|
+
|
|
680
|
+
const offsets: number[] = [];
|
|
681
|
+
for (let i = 0; i < blocksToAllocate; i++) {
|
|
682
|
+
const offset = alloc.allocSpanSystem();
|
|
683
|
+
expect(offset).toBeGreaterThan(0); // Should not fail
|
|
684
|
+
offsets.push(offset);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Bump pointer should have grown well beyond initial memory
|
|
688
|
+
const finalBump = alloc.getBumpPtr();
|
|
689
|
+
const totalAllocated = finalBump - initialBump;
|
|
690
|
+
|
|
691
|
+
// We should have allocated roughly blocksToAllocate * blockSize bytes
|
|
692
|
+
expect(totalAllocated).toBeGreaterThan(blocksToAllocate * blockSize * 0.9);
|
|
693
|
+
|
|
694
|
+
// Memory should have grown (check that last offset is valid by writing to it)
|
|
695
|
+
const lastOffset = offsets[offsets.length - 1];
|
|
696
|
+
expect(lastOffset).toBeGreaterThan(17 * 65536); // Beyond initial 17 pages
|
|
697
|
+
});
|
|
698
|
+
});
|
|
699
|
+
});
|