@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,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thread ID - Process-level unique identifier for distributed span identification
|
|
3
|
+
*
|
|
4
|
+
* Each worker/process gets a unique 64-bit random ID that remains constant
|
|
5
|
+
* for the lifetime of the process. Combined with a local incrementing counter,
|
|
6
|
+
* this provides globally unique span IDs without coordination.
|
|
7
|
+
*
|
|
8
|
+
* The thread ID is stored as raw bytes (Uint8Array) to enable zero-copy
|
|
9
|
+
* writes to SpanBuffer identity sections.
|
|
10
|
+
*
|
|
11
|
+
* ## Module-level = Per-Process/Worker Singleton
|
|
12
|
+
*
|
|
13
|
+
* ES modules are instantiated once per JavaScript realm:
|
|
14
|
+
* - **Node.js main process**: One thread ID per process
|
|
15
|
+
* - **Node.js worker_threads**: Each Worker gets its own module instance → own thread ID
|
|
16
|
+
* - **Browser main thread**: One thread ID
|
|
17
|
+
* - **Web Workers**: Each Worker gets its own module instance → own thread ID
|
|
18
|
+
*
|
|
19
|
+
* This is exactly what we want: each "thread of execution" automatically gets
|
|
20
|
+
* a unique ID without any explicit thread-local storage API.
|
|
21
|
+
*
|
|
22
|
+
* @module threadId
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** Thread ID size in bytes */
|
|
26
|
+
export const THREAD_ID_BYTES = 8;
|
|
27
|
+
|
|
28
|
+
/** Process-level thread ID bytes (lazily initialized) */
|
|
29
|
+
let threadIdBytes: Uint8Array | null = null;
|
|
30
|
+
|
|
31
|
+
/** Cached BigInt representation (lazily computed) */
|
|
32
|
+
let threadIdBigInt: bigint | null = null;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Ensure thread ID is initialized.
|
|
36
|
+
* Called lazily on first access.
|
|
37
|
+
*/
|
|
38
|
+
function ensureInitialized(): void {
|
|
39
|
+
if (threadIdBytes !== null) return;
|
|
40
|
+
|
|
41
|
+
threadIdBytes = new Uint8Array(THREAD_ID_BYTES);
|
|
42
|
+
|
|
43
|
+
// Use Web Crypto API - available in browsers, Node 19+, Deno, Bun, Workers
|
|
44
|
+
if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {
|
|
45
|
+
crypto.getRandomValues(threadIdBytes);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// For Node.js < 19, try to use node:crypto
|
|
50
|
+
try {
|
|
51
|
+
const nodeCrypto = require('node:crypto');
|
|
52
|
+
if (nodeCrypto && typeof nodeCrypto.randomFillSync === 'function') {
|
|
53
|
+
nodeCrypto.randomFillSync(threadIdBytes);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
// node:crypto not available
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
throw new Error(
|
|
61
|
+
'crypto.getRandomValues is not available. ' +
|
|
62
|
+
'For React Native, install and import "react-native-get-random-values" before using this library.',
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Copy the process thread ID bytes to a destination buffer.
|
|
68
|
+
* This is the primary hot-path API for SpanBuffer construction.
|
|
69
|
+
*
|
|
70
|
+
* @param dest - Destination Uint8Array
|
|
71
|
+
* @param offset - Byte offset in destination
|
|
72
|
+
*/
|
|
73
|
+
export function copyThreadIdTo(dest: Uint8Array, offset: number): void {
|
|
74
|
+
ensureInitialized();
|
|
75
|
+
if (!threadIdBytes) {
|
|
76
|
+
throw new Error('ThreadId bytes not initialized');
|
|
77
|
+
}
|
|
78
|
+
dest.set(threadIdBytes, offset);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get the process thread ID as a BigInt.
|
|
83
|
+
* Use copyThreadIdTo() for hot-path writes; this is for Arrow conversion.
|
|
84
|
+
*
|
|
85
|
+
* @returns 64-bit thread ID as BigInt
|
|
86
|
+
*/
|
|
87
|
+
export function getThreadId(): bigint {
|
|
88
|
+
ensureInitialized();
|
|
89
|
+
if (threadIdBigInt === null) {
|
|
90
|
+
if (!threadIdBytes) {
|
|
91
|
+
throw new Error('ThreadId bytes not initialized');
|
|
92
|
+
}
|
|
93
|
+
const b = threadIdBytes;
|
|
94
|
+
// Little-endian conversion to match identity byte layout
|
|
95
|
+
threadIdBigInt =
|
|
96
|
+
BigInt(b[0]) |
|
|
97
|
+
(BigInt(b[1]) << 8n) |
|
|
98
|
+
(BigInt(b[2]) << 16n) |
|
|
99
|
+
(BigInt(b[3]) << 24n) |
|
|
100
|
+
(BigInt(b[4]) << 32n) |
|
|
101
|
+
(BigInt(b[5]) << 40n) |
|
|
102
|
+
(BigInt(b[6]) << 48n) |
|
|
103
|
+
(BigInt(b[7]) << 56n);
|
|
104
|
+
}
|
|
105
|
+
return threadIdBigInt;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Write the process thread ID to a BigUint64Array at the given index.
|
|
110
|
+
* Avoids BigInt conversion by writing bytes directly to the underlying buffer.
|
|
111
|
+
*
|
|
112
|
+
* @param dest - Destination BigUint64Array
|
|
113
|
+
* @param index - Element index (not byte offset)
|
|
114
|
+
*/
|
|
115
|
+
export function writeThreadIdToUint64Array(dest: BigUint64Array, index: number): void {
|
|
116
|
+
ensureInitialized();
|
|
117
|
+
if (!threadIdBytes) {
|
|
118
|
+
throw new Error('ThreadId bytes not initialized');
|
|
119
|
+
}
|
|
120
|
+
const byteView = new Uint8Array(dest.buffer, dest.byteOffset + index * 8, 8);
|
|
121
|
+
byteView.set(threadIdBytes);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Reset thread ID for testing purposes only.
|
|
126
|
+
*
|
|
127
|
+
* **WARNING**: Only use in tests! Resetting in production would break
|
|
128
|
+
* span ID uniqueness guarantees.
|
|
129
|
+
*
|
|
130
|
+
* @internal
|
|
131
|
+
*/
|
|
132
|
+
export function _resetThreadId(): void {
|
|
133
|
+
threadIdBytes = null;
|
|
134
|
+
threadIdBigInt = null;
|
|
135
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TraceContext Types and Prototype System
|
|
3
|
+
*
|
|
4
|
+
* Per specs/lmao/01c_context_flow_and_op_wrappers.md and specs/lmao/01l_op_context_pattern.md:
|
|
5
|
+
* - TraceContext is created via module.traceContext() at request entry
|
|
6
|
+
* - Uses prototype-based inheritance for V8 hidden class optimization
|
|
7
|
+
* - Contains system properties (traceId, timestamps, threadId) + user Extra
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { OpContext } from './opContext/types.js';
|
|
11
|
+
import type { Result } from './result.js';
|
|
12
|
+
import type { FeatureFlagSchema } from './schema/defineFeatureFlags.js';
|
|
13
|
+
import type { FlagEvaluator } from './schema/evaluator.js';
|
|
14
|
+
import type { LogSchema } from './schema/types.js';
|
|
15
|
+
import type { TraceId } from './traceId.js';
|
|
16
|
+
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// Reserved Keys
|
|
19
|
+
// =============================================================================
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Reserved keys that Extra cannot contain (compile-time enforcement)
|
|
23
|
+
*
|
|
24
|
+
* Per spec 01l lines 379-386
|
|
25
|
+
*/
|
|
26
|
+
export type ReservedTraceContextKeys = 'traceId' | 'anchorEpochMicros' | 'anchorPerfNow' | 'threadId' | 'ff' | 'span';
|
|
27
|
+
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// Op Type (imported from op.ts)
|
|
30
|
+
// =============================================================================
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Op type - traced operation
|
|
34
|
+
*
|
|
35
|
+
* Imported from op.ts to break circular dependency.
|
|
36
|
+
* The actual Op class is defined in op.ts.
|
|
37
|
+
*/
|
|
38
|
+
import type { Op } from './op.js';
|
|
39
|
+
|
|
40
|
+
export type { Op } from './op.js';
|
|
41
|
+
|
|
42
|
+
// =============================================================================
|
|
43
|
+
// RootSpanFn Type
|
|
44
|
+
// =============================================================================
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Function type for ctx.span() at the root level
|
|
48
|
+
*
|
|
49
|
+
* Per spec 01c lines 243-244 and experiment exp7-full-ctx.ts lines 253-259:
|
|
50
|
+
* Supports both with and without line number (transformer injects line number)
|
|
51
|
+
*
|
|
52
|
+
* The first argument (lineNumber) is injected by the transformer.
|
|
53
|
+
*/
|
|
54
|
+
export type RootSpanFn = {
|
|
55
|
+
// Overload 1: With line number (transformer output)
|
|
56
|
+
<Ctx extends OpContext, Args extends unknown[], S, E>(
|
|
57
|
+
line: number,
|
|
58
|
+
name: string,
|
|
59
|
+
op: Op<Ctx, Args, S, E>,
|
|
60
|
+
...args: Args
|
|
61
|
+
): Promise<Result<S, E>>;
|
|
62
|
+
// Overload 2: Without line number (user writes)
|
|
63
|
+
<Ctx extends OpContext, Args extends unknown[], S, E>(
|
|
64
|
+
name: string,
|
|
65
|
+
op: Op<Ctx, Args, S, E>,
|
|
66
|
+
...args: Args
|
|
67
|
+
): Promise<Result<S, E>>;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// =============================================================================
|
|
71
|
+
// TraceContext Interface
|
|
72
|
+
// =============================================================================
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* TraceContext system properties - root context created via module.traceContext()
|
|
76
|
+
*
|
|
77
|
+
* Per spec 01c lines 206-216 and 01l lines 369-377:
|
|
78
|
+
* - System properties are auto-generated and cannot be overridden via Extra
|
|
79
|
+
*
|
|
80
|
+
* @typeParam FF - Feature flag schema type
|
|
81
|
+
* @typeParam T - LogSchema type (for typed evaluation context)
|
|
82
|
+
* @typeParam Env - Environment type
|
|
83
|
+
*/
|
|
84
|
+
export interface TraceContextSystem<
|
|
85
|
+
FF extends FeatureFlagSchema,
|
|
86
|
+
T extends LogSchema = LogSchema,
|
|
87
|
+
Env extends Record<string, unknown> = Record<string, unknown>,
|
|
88
|
+
> {
|
|
89
|
+
// System properties (always present, auto-generated)
|
|
90
|
+
readonly anchorEpochMicros: number; // Nanoseconds.now() / 1000n at trace root (microsecond precision)
|
|
91
|
+
readonly anchorPerfNow: number; // performance.now() at trace root
|
|
92
|
+
/** Root flag evaluator - use forContext(spanCtx) to get span-bound evaluator */
|
|
93
|
+
readonly ff: FlagEvaluator<OpContext<T, FF, Record<string, never>, Env>>;
|
|
94
|
+
readonly span: RootSpanFn;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* TraceContext - system properties + user Extra
|
|
99
|
+
*
|
|
100
|
+
* Per spec 01c lines 215-216:
|
|
101
|
+
* ```typescript
|
|
102
|
+
* interface TraceContext<FF, Extra> { ... } & Extra;
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* Extra properties are spread via intersection at usage site.
|
|
106
|
+
*
|
|
107
|
+
* @typeParam FF - Feature flag schema type
|
|
108
|
+
* @typeParam Extra - User-defined properties (e.g., requestId, userId, env)
|
|
109
|
+
*/
|
|
110
|
+
export type TraceContext<FF extends FeatureFlagSchema, Extra extends Record<string, unknown>> = TraceContextSystem<FF> &
|
|
111
|
+
Extra;
|
|
112
|
+
|
|
113
|
+
// =============================================================================
|
|
114
|
+
// Prototype System for V8 Hidden Class Optimization
|
|
115
|
+
// =============================================================================
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Internal symbol to mark contexts as prototype-based
|
|
119
|
+
* Used for type guards and instanceof-like checks
|
|
120
|
+
*/
|
|
121
|
+
export const TRACE_CONTEXT_MARKER = Symbol.for('lmao.TraceContext');
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Base prototype interface for all trace contexts.
|
|
125
|
+
*
|
|
126
|
+
* Per specs/lmao/01c_context_flow_and_op_wrappers.md:
|
|
127
|
+
* - Methods are defined ONCE on a shared prototype
|
|
128
|
+
* - Object.create() is used for inheritance (no object spreads)
|
|
129
|
+
* - Properties are assigned directly for stable hidden classes
|
|
130
|
+
*
|
|
131
|
+
* This is used internally and should not be accessed directly.
|
|
132
|
+
*/
|
|
133
|
+
export interface TraceContextBase {
|
|
134
|
+
/** Marker for prototype chain detection */
|
|
135
|
+
readonly [TRACE_CONTEXT_MARKER]: true;
|
|
136
|
+
/** Trace ID for this context */
|
|
137
|
+
trace_id: TraceId | undefined;
|
|
138
|
+
/** Epoch microseconds when trace started */
|
|
139
|
+
anchorEpochMicros: number | undefined;
|
|
140
|
+
/** performance.now() when trace started */
|
|
141
|
+
anchorPerfNow: number | undefined;
|
|
142
|
+
/** Feature flag evaluator */
|
|
143
|
+
ff: unknown;
|
|
144
|
+
/** Root span function */
|
|
145
|
+
span: unknown;
|
|
146
|
+
/** Pre-computed Extra keys for V8 optimization (avoid Object.keys in hot path) */
|
|
147
|
+
_extraKeys?: string[];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The shared prototype object for TraceContext.
|
|
152
|
+
*
|
|
153
|
+
* Per V8 optimization guidelines:
|
|
154
|
+
* - Define methods ONCE on prototype, not per-instance
|
|
155
|
+
* - Use Object.create() for inheritance chains
|
|
156
|
+
* - Avoid object spreads which break hidden classes
|
|
157
|
+
*/
|
|
158
|
+
export const TraceContextProto: TraceContextBase = {
|
|
159
|
+
[TRACE_CONTEXT_MARKER]: true,
|
|
160
|
+
trace_id: undefined,
|
|
161
|
+
anchorEpochMicros: undefined,
|
|
162
|
+
anchorPerfNow: undefined,
|
|
163
|
+
ff: undefined,
|
|
164
|
+
span: undefined,
|
|
165
|
+
_extraKeys: undefined,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// =============================================================================
|
|
169
|
+
// Type Guard
|
|
170
|
+
// =============================================================================
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Type guard to check if a value is a TraceContext
|
|
174
|
+
*/
|
|
175
|
+
export function isTraceContext(value: unknown): value is TraceContext<FeatureFlagSchema, Record<string, unknown>> {
|
|
176
|
+
return (
|
|
177
|
+
typeof value === 'object' &&
|
|
178
|
+
value !== null &&
|
|
179
|
+
TRACE_CONTEXT_MARKER in value &&
|
|
180
|
+
(value as Record<symbol, unknown>)[TRACE_CONTEXT_MARKER] === true
|
|
181
|
+
);
|
|
182
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TraceId - Branded string type for trace identification
|
|
3
|
+
*
|
|
4
|
+
* A TraceId is a string that uniquely identifies a distributed trace.
|
|
5
|
+
* It's validated to be non-empty and at most 128 characters (ASCII).
|
|
6
|
+
*
|
|
7
|
+
* Common formats:
|
|
8
|
+
* - W3C Trace Context: 32 hex chars (e.g., "0af7651916cd43dd8448eb211c80319c")
|
|
9
|
+
* - OpenTelemetry: same as W3C
|
|
10
|
+
* - Custom: any string up to 128 chars
|
|
11
|
+
*
|
|
12
|
+
* @module traceId
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Maximum length for a trace ID */
|
|
16
|
+
export const MAX_TRACE_ID_LENGTH = 128;
|
|
17
|
+
|
|
18
|
+
/** Branded type for validated trace IDs */
|
|
19
|
+
export type TraceId = string & { readonly __brand: 'TraceId' };
|
|
20
|
+
|
|
21
|
+
function brandTraceId(value: string): TraceId;
|
|
22
|
+
function brandTraceId(value: string): string {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Precompiled regex for non-ASCII detection (2x faster than loop) */
|
|
27
|
+
const NON_ASCII_REGEX = /[^\x20-\x7E]/;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Validate and create a TraceId from a string.
|
|
31
|
+
* @throws Error if validation fails
|
|
32
|
+
*/
|
|
33
|
+
export function createTraceId(value: string): TraceId {
|
|
34
|
+
if (typeof value !== 'string') {
|
|
35
|
+
throw new Error('TraceId must be a string');
|
|
36
|
+
}
|
|
37
|
+
if (value.length === 0) {
|
|
38
|
+
throw new Error('TraceId cannot be empty');
|
|
39
|
+
}
|
|
40
|
+
if (value.length > MAX_TRACE_ID_LENGTH) {
|
|
41
|
+
throw new Error(`TraceId cannot exceed ${MAX_TRACE_ID_LENGTH} characters`);
|
|
42
|
+
}
|
|
43
|
+
if (NON_ASCII_REGEX.test(value)) {
|
|
44
|
+
throw new Error('TraceId must be ASCII printable characters only');
|
|
45
|
+
}
|
|
46
|
+
return brandTraceId(value);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Check if a value is a valid TraceId without throwing.
|
|
51
|
+
*/
|
|
52
|
+
export function isValidTraceId(value: unknown): value is TraceId {
|
|
53
|
+
return (
|
|
54
|
+
typeof value === 'string' && value.length > 0 && value.length <= MAX_TRACE_ID_LENGTH && !NON_ASCII_REGEX.test(value)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Generate a new random TraceId (W3C format: 32 hex chars).
|
|
60
|
+
*/
|
|
61
|
+
export function generateTraceId(): TraceId {
|
|
62
|
+
const bytes = new Uint8Array(16);
|
|
63
|
+
|
|
64
|
+
if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {
|
|
65
|
+
crypto.getRandomValues(bytes);
|
|
66
|
+
} else {
|
|
67
|
+
try {
|
|
68
|
+
const nodeCrypto = require('node:crypto');
|
|
69
|
+
if (nodeCrypto?.randomFillSync) {
|
|
70
|
+
nodeCrypto.randomFillSync(bytes);
|
|
71
|
+
}
|
|
72
|
+
} catch {
|
|
73
|
+
// Fallback to Math.random (not ideal but works)
|
|
74
|
+
for (let i = 0; i < 16; i++) {
|
|
75
|
+
bytes[i] = Math.floor(Math.random() * 256);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Convert to hex string
|
|
81
|
+
let hex = '';
|
|
82
|
+
for (let i = 0; i < 16; i++) {
|
|
83
|
+
hex += bytes[i].toString(16).padStart(2, '0');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return brandTraceId(hex);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ============================================================================
|
|
90
|
+
// SpanIdentity - Span identification for external systems
|
|
91
|
+
// ============================================================================
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* SpanIdentity - Identifies a specific span for external correlation.
|
|
95
|
+
*
|
|
96
|
+
* distributed tracing headers, error reporting). Contains the minimal fields needed
|
|
97
|
+
* to uniquely identify a span within a trace.
|
|
98
|
+
*
|
|
99
|
+
* **Usage:**
|
|
100
|
+
* ```typescript
|
|
101
|
+
* // Extract from buffer
|
|
102
|
+
* const identity: SpanIdentity = {
|
|
103
|
+
* trace_id: buffer.trace_id,
|
|
104
|
+
* span_id: buffer.span_id,
|
|
105
|
+
* thread_id: buffer.thread_id,
|
|
106
|
+
* };
|
|
107
|
+
*
|
|
108
|
+
* // Use in signals/messages
|
|
109
|
+
* signalReportDown({ service, reporter, span: identity });
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
112
|
+
* **Fields:**
|
|
113
|
+
* - `trace_id`: 128-bit UUID identifying the entire trace (branded string)
|
|
114
|
+
* - `span_id`: 32-bit counter unique within the trace
|
|
115
|
+
* - `thread_id`: 64-bit identifier for execution thread/context
|
|
116
|
+
*
|
|
117
|
+
* @see specs/lmao/01b4_span_identity.md for full identity design
|
|
118
|
+
*/
|
|
119
|
+
export interface SpanIdentity {
|
|
120
|
+
/** Trace ID - 128-bit UUID identifying the entire trace */
|
|
121
|
+
readonly trace_id: TraceId;
|
|
122
|
+
|
|
123
|
+
/** Span ID - 32-bit counter unique within this trace */
|
|
124
|
+
readonly span_id: number;
|
|
125
|
+
|
|
126
|
+
/** Thread ID - 64-bit identifier for execution thread/context */
|
|
127
|
+
readonly thread_id: bigint;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Extract SpanIdentity from a span buffer.
|
|
132
|
+
*
|
|
133
|
+
* @param buffer - Any object with trace_id, span_id, thread_id properties
|
|
134
|
+
* @returns SpanIdentity for external correlation
|
|
135
|
+
*/
|
|
136
|
+
export function extractSpanIdentity(buffer: { trace_id: TraceId; span_id: number; thread_id: bigint }): SpanIdentity {
|
|
137
|
+
return {
|
|
138
|
+
trace_id: buffer.trace_id,
|
|
139
|
+
span_id: buffer.span_id,
|
|
140
|
+
thread_id: buffer.thread_id,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TraceRoot - Browser/ES implementation.
|
|
3
|
+
*
|
|
4
|
+
* Uses performance.now() for timing with microsecond precision (~5-20μs).
|
|
5
|
+
* Last 3 digits of nanoseconds are always 000.
|
|
6
|
+
*
|
|
7
|
+
* For Node.js with NAPI-optimized writes, use traceRoot.node.ts instead.
|
|
8
|
+
*
|
|
9
|
+
* @module traceRoot.es
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Nanoseconds } from '@smoothbricks/arrow-builder';
|
|
13
|
+
import { ENTRY_TYPE_SPAN_EXCEPTION, ENTRY_TYPE_SPAN_START } from './schema/systemSchema.js';
|
|
14
|
+
import { createTraceId, type TraceId } from './traceId.js';
|
|
15
|
+
import {
|
|
16
|
+
type ITraceRoot,
|
|
17
|
+
TRACE_ROOT_ANCHOR_EPOCH_OFFSET,
|
|
18
|
+
TRACE_ROOT_ANCHOR_PERF_OFFSET,
|
|
19
|
+
TRACE_ROOT_TRACE_ID_LEN_OFFSET,
|
|
20
|
+
TRACE_ROOT_TRACE_ID_OFFSET,
|
|
21
|
+
type TracerLifecycleHooks,
|
|
22
|
+
} from './traceRoot.js';
|
|
23
|
+
import type { AnySpanBuffer } from './types.js';
|
|
24
|
+
|
|
25
|
+
/** Shared TextEncoder for trace_id encoding (stateless, reusable) */
|
|
26
|
+
const textEncoder = new TextEncoder();
|
|
27
|
+
|
|
28
|
+
/** Shared TextDecoder for trace_id decoding (stateless, reusable) */
|
|
29
|
+
const textDecoder = new TextDecoder();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* TraceRoot - Browser implementation with performance.now() timing.
|
|
33
|
+
*
|
|
34
|
+
* Stores anchor data in _system ArrayBuffer for consistency with Node.js layout,
|
|
35
|
+
* but all timestamp calculations are done in pure JS.
|
|
36
|
+
*/
|
|
37
|
+
export class TraceRoot implements ITraceRoot {
|
|
38
|
+
/**
|
|
39
|
+
* Raw backing buffer containing anchor timestamps and trace_id.
|
|
40
|
+
*/
|
|
41
|
+
readonly _system: ArrayBuffer;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Tracer reference for lifecycle hooks and event callbacks.
|
|
45
|
+
*/
|
|
46
|
+
readonly tracer: TracerLifecycleHooks;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Cached TypedArray views for fast JS access.
|
|
50
|
+
*/
|
|
51
|
+
private readonly _epochView: BigInt64Array;
|
|
52
|
+
private readonly _perfView: Float64Array;
|
|
53
|
+
|
|
54
|
+
constructor(trace_id: TraceId, anchorEpochNanos: bigint, anchorPerfNow: number, tracer: TracerLifecycleHooks) {
|
|
55
|
+
// Allocate buffer: 17 bytes header + trace_id length
|
|
56
|
+
// trace_id is validated to be ASCII (1 byte per char) so length === byte length
|
|
57
|
+
this._system = new ArrayBuffer(TRACE_ROOT_TRACE_ID_OFFSET + trace_id.length);
|
|
58
|
+
this.tracer = tracer;
|
|
59
|
+
|
|
60
|
+
// Create cached views (one-time allocation)
|
|
61
|
+
this._epochView = new BigInt64Array(this._system, TRACE_ROOT_ANCHOR_EPOCH_OFFSET, 1);
|
|
62
|
+
this._perfView = new Float64Array(this._system, TRACE_ROOT_ANCHOR_PERF_OFFSET, 1);
|
|
63
|
+
|
|
64
|
+
// Write anchor data directly
|
|
65
|
+
this._epochView[0] = anchorEpochNanos;
|
|
66
|
+
this._perfView[0] = anchorPerfNow;
|
|
67
|
+
|
|
68
|
+
// Encode trace_id directly into buffer (no intermediate allocation)
|
|
69
|
+
const u8View = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_LEN_OFFSET);
|
|
70
|
+
const traceIdDest = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, trace_id.length);
|
|
71
|
+
const { written } = textEncoder.encodeInto(trace_id, traceIdDest);
|
|
72
|
+
u8View[0] = written;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Epoch time in nanoseconds when trace was created.
|
|
77
|
+
*/
|
|
78
|
+
get anchorEpochNanos(): bigint {
|
|
79
|
+
return this._epochView[0];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* High-resolution timer anchor when trace was created (performance.now() value).
|
|
84
|
+
*/
|
|
85
|
+
get anchorPerfNow(): number {
|
|
86
|
+
return this._perfView[0];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Trace ID for this trace.
|
|
91
|
+
*/
|
|
92
|
+
get trace_id(): TraceId {
|
|
93
|
+
const len = new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_LEN_OFFSET, 1)[0];
|
|
94
|
+
return createTraceId(textDecoder.decode(new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, len)));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get current timestamp in nanoseconds since Unix epoch.
|
|
99
|
+
* Uses performance.now() - microsecond precision (last 3 digits = 000).
|
|
100
|
+
*/
|
|
101
|
+
getTimestampNanos(): Nanoseconds {
|
|
102
|
+
const elapsedMs = performance.now() - this._perfView[0];
|
|
103
|
+
// Convert to nanoseconds (last 3 digits = 000 due to microsecond precision)
|
|
104
|
+
const elapsedNanos = BigInt(Math.floor(elapsedMs * 1000)) * 1000n;
|
|
105
|
+
return Nanoseconds.unsafe(this._epochView[0] + elapsedNanos);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Write span-start entry to buffer at row 0.
|
|
110
|
+
*
|
|
111
|
+
* Pure JS implementation - writes timestamp, entry_type, message, and sets _writeIndex.
|
|
112
|
+
*/
|
|
113
|
+
writeSpanStart(buffer: AnySpanBuffer, spanName: string): void {
|
|
114
|
+
// Row 0: span-start
|
|
115
|
+
buffer.timestamp[0] = this.getTimestampNanos();
|
|
116
|
+
buffer.entry_type[0] = ENTRY_TYPE_SPAN_START;
|
|
117
|
+
buffer.message(0, spanName);
|
|
118
|
+
|
|
119
|
+
// Row 1: pre-initialize as span-exception (will be overwritten on ok/err)
|
|
120
|
+
buffer.entry_type[1] = ENTRY_TYPE_SPAN_EXCEPTION;
|
|
121
|
+
buffer.timestamp[1] = 0n;
|
|
122
|
+
|
|
123
|
+
// Events start at row 2
|
|
124
|
+
buffer._writeIndex = 2;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Write span-end entry to buffer at row 1.
|
|
129
|
+
* Writes both timestamp and entry_type.
|
|
130
|
+
*/
|
|
131
|
+
writeSpanEnd(buffer: AnySpanBuffer, entryType: number): void {
|
|
132
|
+
buffer.timestamp[1] = this.getTimestampNanos();
|
|
133
|
+
buffer.entry_type[1] = entryType;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Write log entry: bump writeIndex, write timestamp + entry_type, return idx.
|
|
138
|
+
* SpanLogger uses returned idx for string column writes.
|
|
139
|
+
*/
|
|
140
|
+
writeLogEntry(buffer: AnySpanBuffer, entryType: number): number {
|
|
141
|
+
const idx = buffer._writeIndex;
|
|
142
|
+
buffer.timestamp[idx] = this.getTimestampNanos();
|
|
143
|
+
buffer.entry_type[idx] = entryType;
|
|
144
|
+
buffer._writeIndex = idx + 1;
|
|
145
|
+
return idx;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Factory function for creating browser TraceRoot instances.
|
|
151
|
+
* Pass this to Tracer constructor for browser/ES environments.
|
|
152
|
+
*/
|
|
153
|
+
export function createTraceRoot(trace_id: string, tracer: TracerLifecycleHooks): TraceRoot {
|
|
154
|
+
const anchorEpochNanos = BigInt(Date.now()) * 1_000_000n;
|
|
155
|
+
const anchorPerfNow = performance.now();
|
|
156
|
+
return new TraceRoot(createTraceId(trace_id), anchorEpochNanos, anchorPerfNow, tracer);
|
|
157
|
+
}
|