@smoothbricks/lmao 0.1.2 → 0.1.4
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/dist/allocator.wasm +0 -0
- package/dist/es.d.ts.map +1 -1
- package/dist/es.js +1 -0
- package/dist/lib/archive/chunkCompaction.d.ts.map +1 -1
- package/dist/lib/archive/chunkCompaction.js +2 -0
- package/dist/lib/archive/chunkEnvelope.d.ts.map +1 -1
- package/dist/lib/archive/chunkRouting.d.ts.map +1 -1
- package/dist/lib/archive/chunkRouting.js +3 -0
- package/dist/lib/archive/chunkStats.d.ts.map +1 -1
- package/dist/lib/archive/chunkStats.js +1 -0
- package/dist/lib/arrow/capacityStats.d.ts.map +1 -1
- package/dist/lib/arrow/capacityStats.js +1 -0
- package/dist/lib/bufferStrategy.d.ts.map +1 -1
- package/dist/lib/capacityTuning.d.ts.map +1 -1
- package/dist/lib/capacityTuning.js +1 -0
- package/dist/lib/cleanupDiagnostics.d.ts +4 -0
- package/dist/lib/cleanupDiagnostics.d.ts.map +1 -0
- package/dist/lib/cleanupDiagnostics.js +42 -0
- package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/evaluatorGenerator.js +1 -0
- package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/fixedPositionWriterGenerator.js +1 -0
- package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
- package/dist/lib/codegen/spanLoggerGenerator.js +3 -0
- package/dist/lib/convertToArrow.d.ts.map +1 -1
- package/dist/lib/convertToArrow.js +6 -0
- package/dist/lib/defineOpContext.d.ts +5 -0
- package/dist/lib/defineOpContext.d.ts.map +1 -1
- package/dist/lib/defineOpContext.js +11 -1
- package/dist/lib/errors/Blocked.d.ts.map +1 -1
- package/dist/lib/errors/Transient.d.ts.map +1 -1
- package/dist/lib/errors/retry-policy.d.ts.map +1 -1
- package/dist/lib/flushScheduler.d.ts.map +1 -1
- package/dist/lib/flushScheduler.js +12 -0
- package/dist/lib/library.d.ts +5 -0
- package/dist/lib/library.d.ts.map +1 -1
- package/dist/lib/library.js +6 -0
- package/dist/lib/op.d.ts.map +1 -1
- package/dist/lib/op.js +2 -0
- package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
- package/dist/lib/opContext/createOpGroup.js +5 -0
- package/dist/lib/opContext/defineOp.d.ts.map +1 -1
- package/dist/lib/opContext/defineOp.js +5 -0
- package/dist/lib/result.d.ts.map +1 -1
- package/dist/lib/result.js +3 -0
- package/dist/lib/schema/builder.d.ts.map +1 -1
- package/dist/lib/schema/builder.js +1 -0
- package/dist/lib/schema/defineFeatureFlags.d.ts.map +1 -1
- package/dist/lib/schema/defineLogSchema.d.ts.map +1 -1
- package/dist/lib/schema/defineLogSchema.js +1 -0
- package/dist/lib/schema/evaluator.d.ts.map +1 -1
- package/dist/lib/schema/systemSchema.d.ts.map +1 -1
- package/dist/lib/schema/systemSchema.js +1 -0
- package/dist/lib/spanBuffer.d.ts.map +1 -1
- package/dist/lib/spanBuffer.js +8 -0
- package/dist/lib/spanBufferHelpers.d.ts.map +1 -1
- package/dist/lib/spanBufferHelpers.js +1 -0
- package/dist/lib/spanBufferStats.d.ts.map +1 -1
- package/dist/lib/spanContext.d.ts +8 -0
- package/dist/lib/spanContext.d.ts.map +1 -1
- package/dist/lib/spanContext.js +35 -0
- package/dist/lib/sqlite/index.d.ts +1 -0
- package/dist/lib/sqlite/index.d.ts.map +1 -1
- package/dist/lib/sqlite/sqlite-async-writer.d.ts.map +1 -1
- package/dist/lib/sqlite/sqlite-async-writer.js +16 -0
- package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
- package/dist/lib/sqlite/sqlite-common.js +5 -1
- package/dist/lib/sqlite/sqlite-writer.d.ts.map +1 -1
- package/dist/lib/sqlite/sqlite-writer.js +22 -0
- package/dist/lib/testing/bun-harness.d.ts.map +1 -1
- package/dist/lib/testing/bun-harness.js +21 -0
- package/dist/lib/threadId.d.ts.map +1 -1
- package/dist/lib/threadId.js +2 -0
- package/dist/lib/traceId.d.ts.map +1 -1
- package/dist/lib/traceId.js +1 -0
- package/dist/lib/traceRoot.d.ts.map +1 -1
- package/dist/lib/traceRoot.es.d.ts.map +1 -1
- package/dist/lib/traceRoot.es.js +3 -0
- package/dist/lib/traceRoot.js +2 -0
- package/dist/lib/traceRoot.node.d.ts.map +1 -1
- package/dist/lib/traceRoot.node.js +1 -0
- package/dist/lib/tracer.d.ts.map +1 -1
- package/dist/lib/tracer.js +2 -0
- package/dist/lib/tracers/ArrayQueueTracer.d.ts.map +1 -1
- package/dist/lib/tracers/CompositeTracer.d.ts.map +1 -1
- package/dist/lib/tracers/CompositeTracer.js +6 -0
- package/dist/lib/tracers/NoOpTracer.d.ts.map +1 -1
- package/dist/lib/tracers/NoOpTracer.js +1 -0
- package/dist/lib/tracers/SQLiteTracer.d.ts.map +1 -1
- package/dist/lib/tracers/SQLiteTracer.js +11 -0
- package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
- package/dist/lib/tracers/StdioTracer.js +1 -0
- package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
- package/dist/lib/tracers/TestTracer.js +1 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utf8Cache.d.ts.map +1 -1
- package/dist/lib/utf8Cache.js +1 -0
- package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
- package/dist/lib/wasm/WasmBufferStrategy.js +2 -0
- package/dist/lib/wasm/wasmAllocator.d.ts +2 -0
- package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
- package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
- package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +1 -0
- package/package.json +9 -6
- package/src/es.ts +2 -0
- package/src/lib/archive/chunkCompaction.ts +2 -0
- package/src/lib/archive/chunkEnvelope.ts +2 -0
- package/src/lib/archive/chunkRouting.ts +4 -0
- package/src/lib/archive/chunkStats.ts +2 -0
- package/src/lib/arrow/capacityStats.ts +2 -0
- package/src/lib/bufferStrategy.ts +2 -0
- package/src/lib/capacityTuning.ts +2 -0
- package/src/lib/cleanupDiagnostics.ts +52 -0
- package/src/lib/codegen/evaluatorGenerator.ts +2 -0
- package/src/lib/codegen/fixedPositionWriterGenerator.ts +2 -0
- package/src/lib/codegen/spanLoggerGenerator.ts +4 -0
- package/src/lib/convertToArrow.ts +6 -0
- package/src/lib/defineOpContext.ts +17 -1
- package/src/lib/errors/Blocked.ts +2 -0
- package/src/lib/errors/Transient.ts +2 -0
- package/src/lib/errors/retry-policy.ts +2 -0
- package/src/lib/flushScheduler.ts +12 -0
- package/src/lib/library.ts +7 -0
- package/src/lib/op.ts +8 -0
- package/src/lib/opContext/createOpGroup.ts +6 -0
- package/src/lib/opContext/defineOp.ts +6 -0
- package/src/lib/result.ts +4 -0
- package/src/lib/schema/builder.ts +2 -0
- package/src/lib/schema/defineFeatureFlags.ts +2 -0
- package/src/lib/schema/defineLogSchema.ts +2 -0
- package/src/lib/schema/evaluator.ts +2 -0
- package/src/lib/schema/systemSchema.ts +2 -0
- package/src/lib/spanBuffer.ts +10 -0
- package/src/lib/spanBufferHelpers.ts +2 -0
- package/src/lib/spanBufferStats.ts +2 -0
- package/src/lib/spanContext.ts +48 -1
- package/src/lib/sqlite/__tests__/sqlite-common.test.ts +40 -1
- package/src/lib/sqlite/index.ts +1 -0
- package/src/lib/sqlite/sqlite-async-writer.ts +8 -0
- package/src/lib/sqlite/sqlite-common.ts +5 -1
- package/src/lib/sqlite/sqlite-writer.ts +6 -0
- package/src/lib/testing/bun-harness.ts +21 -0
- package/src/lib/threadId.ts +2 -0
- package/src/lib/traceId.ts +4 -0
- package/src/lib/traceRoot.es.ts +4 -0
- package/src/lib/traceRoot.node.ts +2 -0
- package/src/lib/traceRoot.ts +4 -0
- package/src/lib/tracer.ts +4 -0
- package/src/lib/tracers/ArrayQueueTracer.ts +2 -0
- package/src/lib/tracers/CompositeTracer.ts +7 -0
- package/src/lib/tracers/NoOpTracer.ts +2 -0
- package/src/lib/tracers/SQLiteTracer.ts +11 -0
- package/src/lib/tracers/StdioTracer.ts +2 -0
- package/src/lib/tracers/TestTracer.ts +2 -0
- package/src/lib/types.ts +2 -0
- package/src/lib/utf8Cache.ts +2 -0
- package/src/lib/wasm/WasmBufferStrategy.ts +4 -0
- package/src/lib/wasm/allocator.zig +4 -1
- package/src/lib/wasm/wasmAllocator.ts +5 -0
- package/src/lib/wasm/wasmSpanBuffer.ts +4 -0
- package/src/lib/wasm/wasmTraceRoot.ts +4 -0
- package/src/node.ts +2 -0
package/src/lib/spanBuffer.ts
CHANGED
|
@@ -122,6 +122,7 @@ export const SpanBufferTestUtils = {
|
|
|
122
122
|
*
|
|
123
123
|
* traceRoot is ALWAYS provided - factories extract it from parent when needed.
|
|
124
124
|
*/
|
|
125
|
+
//#region smoo/lmao!n/spanbuffer-layout.class-signature
|
|
125
126
|
export interface SpanBufferConstructor<T extends LogSchema = LogSchema> {
|
|
126
127
|
new (
|
|
127
128
|
capacity: number,
|
|
@@ -137,6 +138,7 @@ export interface SpanBufferConstructor<T extends LogSchema = LogSchema> {
|
|
|
137
138
|
readonly schema: T;
|
|
138
139
|
readonly stats: SpanBufferStats;
|
|
139
140
|
}
|
|
141
|
+
//#endregion smoo/lmao!n/spanbuffer-layout.class-signature
|
|
140
142
|
|
|
141
143
|
type GeneratedSpanBufferClass<T extends LogSchema> = new (
|
|
142
144
|
capacity: number,
|
|
@@ -214,6 +216,7 @@ const spanBufferClassCache = new WeakMap<LogSchema, SpanBufferConstructor>();
|
|
|
214
216
|
* @param schema - LogSchema defining the buffer structure
|
|
215
217
|
* @returns SpanBufferConstructor with static schema and stats properties
|
|
216
218
|
*/
|
|
219
|
+
//#region smoo/lmao!n/spanbuffer-layout.constructor
|
|
217
220
|
export function getSpanBufferClass<T extends LogSchema>(schema: T): SpanBufferConstructor<T> {
|
|
218
221
|
const cached = spanBufferClassCache.get(schema);
|
|
219
222
|
if (isSpanBufferConstructorForSchema(cached, schema)) {
|
|
@@ -439,6 +442,7 @@ export function getSpanBufferClass<T extends LogSchema>(schema: T): SpanBufferCo
|
|
|
439
442
|
|
|
440
443
|
return SpanBufferClass;
|
|
441
444
|
}
|
|
445
|
+
//#endregion smoo/lmao!n/spanbuffer-layout.constructor
|
|
442
446
|
|
|
443
447
|
// ============================================================================
|
|
444
448
|
// SpanBuffer factory functions
|
|
@@ -458,6 +462,7 @@ export function getSpanBufferClass<T extends LogSchema>(schema: T): SpanBufferCo
|
|
|
458
462
|
*/
|
|
459
463
|
const MIN_CAPACITY = 8;
|
|
460
464
|
|
|
465
|
+
//#region smoo/lmao!n/spanbuffer-layout.create-root
|
|
461
466
|
export function createSpanBuffer<T extends LogSchema>(
|
|
462
467
|
schema: T,
|
|
463
468
|
traceRoot: ITraceRoot,
|
|
@@ -485,6 +490,7 @@ export function createSpanBuffer<T extends LogSchema>(
|
|
|
485
490
|
traceRoot, // pre-built TraceRoot with trace_id, anchors, tracer
|
|
486
491
|
);
|
|
487
492
|
}
|
|
493
|
+
//#endregion smoo/lmao!n/spanbuffer-layout.create-root
|
|
488
494
|
|
|
489
495
|
/**
|
|
490
496
|
* Creates a continuation buffer when the current buffer overflows.
|
|
@@ -496,6 +502,7 @@ export function createSpanBuffer<T extends LogSchema>(
|
|
|
496
502
|
*
|
|
497
503
|
* @returns New SpanBuffer linked via `buffer._overflow`, with same schema type
|
|
498
504
|
*/
|
|
505
|
+
//#region smoo/lmao!n/spanbuffer-layout.create-overflow
|
|
499
506
|
export function createOverflowBuffer<T extends LogSchema>(buffer: SpanBuffer<T>): SpanBuffer<T> {
|
|
500
507
|
const SpanBufferClass = getSpanBufferConstructorForBuffer(buffer);
|
|
501
508
|
const stats = SpanBufferClass.stats;
|
|
@@ -520,6 +527,7 @@ export function createOverflowBuffer<T extends LogSchema>(buffer: SpanBuffer<T>)
|
|
|
520
527
|
|
|
521
528
|
return nextBuffer;
|
|
522
529
|
}
|
|
530
|
+
//#endregion smoo/lmao!n/spanbuffer-layout.create-overflow
|
|
523
531
|
|
|
524
532
|
/**
|
|
525
533
|
* Creates a child span buffer with parent linkage.
|
|
@@ -537,6 +545,7 @@ export function createOverflowBuffer<T extends LogSchema>(buffer: SpanBuffer<T>)
|
|
|
537
545
|
*
|
|
538
546
|
* @returns New SpanBuffer linked to parent
|
|
539
547
|
*/
|
|
548
|
+
//#region smoo/lmao!n/spanbuffer-layout.create-child
|
|
540
549
|
export function createChildSpanBuffer<T extends LogSchema>(
|
|
541
550
|
parentBuffer: AnySpanBuffer,
|
|
542
551
|
SpanBufferClass: SpanBufferConstructor<T>,
|
|
@@ -563,6 +572,7 @@ export function createChildSpanBuffer<T extends LogSchema>(
|
|
|
563
572
|
|
|
564
573
|
return childBuffer;
|
|
565
574
|
}
|
|
575
|
+
//#endregion smoo/lmao!n/spanbuffer-layout.create-child
|
|
566
576
|
|
|
567
577
|
// ============================================================================
|
|
568
578
|
// Constants for Arrow conversion
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { copyThreadIdTo } from './threadId.js';
|
|
12
12
|
|
|
13
|
+
//#region smoo/lmao!n/spanbuffer-layout.helpers
|
|
13
14
|
/**
|
|
14
15
|
* Shared TextEncoder instance for traceId encoding.
|
|
15
16
|
* TextEncoder is stateless and thread-safe, so one instance suffices.
|
|
@@ -71,3 +72,4 @@ export const spanBufferHelpers = {
|
|
|
71
72
|
} as const;
|
|
72
73
|
|
|
73
74
|
export type SpanBufferHelpers = typeof spanBufferHelpers;
|
|
75
|
+
//#endregion smoo/lmao!n/spanbuffer-layout.helpers
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
* Created once per `defineOpContext`, stored as static property on generated
|
|
29
29
|
* SpanBuffer class. All buffers from same context share these stats.
|
|
30
30
|
*/
|
|
31
|
+
//#region smoo/lmao!n/spanbuffer-layout.stats
|
|
31
32
|
export interface SpanBufferStats {
|
|
32
33
|
/** Current buffer capacity for new buffers (grows/shrinks based on utilization) */
|
|
33
34
|
capacity: number;
|
|
@@ -38,3 +39,4 @@ export interface SpanBufferStats {
|
|
|
38
39
|
/** Number of non-chained spans created (root + child spans, NOT overflow buffers) */
|
|
39
40
|
spansCreated: number;
|
|
40
41
|
}
|
|
42
|
+
//#endregion smoo/lmao!n/spanbuffer-layout.stats
|
package/src/lib/spanContext.ts
CHANGED
|
@@ -69,9 +69,14 @@ export const SPAN_CONTEXT_MARKER = Symbol.for('lmao.SpanContext');
|
|
|
69
69
|
// Type Exports
|
|
70
70
|
// =============================================================================
|
|
71
71
|
|
|
72
|
+
//#region smoo/lmao!n/codegen-spanlogger.ff
|
|
72
73
|
/**
|
|
73
74
|
* Internal SpanLogger type with FF methods and internal methods exposed.
|
|
74
75
|
* Used by FeatureFlagEvaluator and internal span management code.
|
|
76
|
+
*
|
|
77
|
+
* The 01g "SpanLoggerInternal Type Pattern": the public SpanLogger<T> hides
|
|
78
|
+
* ffAccess/ffUsage; the evaluator casts to this internal type to reach them.
|
|
79
|
+
* The methods themselves are generated in codegen/spanLoggerGenerator.ts.
|
|
75
80
|
*/
|
|
76
81
|
export type SpanLoggerInternal<T extends LogSchema> = SpanLoggerImpl<T> & {
|
|
77
82
|
/**
|
|
@@ -85,6 +90,7 @@ export type SpanLoggerInternal<T extends LogSchema> = SpanLoggerImpl<T> & {
|
|
|
85
90
|
*/
|
|
86
91
|
ffUsage(flagName: string, context?: Record<string, unknown>): FluentLogEntry<T>;
|
|
87
92
|
};
|
|
93
|
+
//#endregion smoo/lmao!n/codegen-spanlogger.ff
|
|
88
94
|
|
|
89
95
|
type SpanDispatchFn<Ctx extends OpContext, Args extends unknown[] = unknown[], S = unknown, E = unknown> = (
|
|
90
96
|
ctx: SpanContext<Ctx>,
|
|
@@ -202,6 +208,7 @@ function resolveSpanTarget<Ctx extends OpContext>(
|
|
|
202
208
|
// Helper Functions
|
|
203
209
|
// =============================================================================
|
|
204
210
|
|
|
211
|
+
//#region smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.start
|
|
205
212
|
/**
|
|
206
213
|
* Write span-start entry to buffer at row 0 (fixed layout)
|
|
207
214
|
* Pre-initialize row 1 as span-exception (will be overwritten by ok/err)
|
|
@@ -219,6 +226,7 @@ export function writeSpanStart<T extends LogSchema>(buffer: SpanBuffer<T>, spanN
|
|
|
219
226
|
// Delegate to TraceRoot - platform-specific implementation handles timestamps
|
|
220
227
|
buffer._traceRoot.writeSpanStart(buffer, spanName);
|
|
221
228
|
}
|
|
229
|
+
//#endregion smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.start
|
|
222
230
|
|
|
223
231
|
/**
|
|
224
232
|
* Create a SpanLogger for the given buffer.
|
|
@@ -234,6 +242,7 @@ export function createSpanLogger<T extends LogSchema>(schema: T, buffer: SpanBuf
|
|
|
234
242
|
return createSpanLoggerFromGenerator(schema, buffer);
|
|
235
243
|
}
|
|
236
244
|
|
|
245
|
+
//#region smoo/lmao!n/op-retry.delay
|
|
237
246
|
/**
|
|
238
247
|
* Calculate delay for retry based on policy and attempt number.
|
|
239
248
|
*
|
|
@@ -268,7 +277,9 @@ function calculateDelay(policy: RetryPolicy, attempt: number): number {
|
|
|
268
277
|
|
|
269
278
|
return delay;
|
|
270
279
|
}
|
|
280
|
+
//#endregion smoo/lmao!n/op-retry.delay
|
|
271
281
|
|
|
282
|
+
//#region smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.retry
|
|
272
283
|
/**
|
|
273
284
|
* Write span-retry entry to buffer.
|
|
274
285
|
*
|
|
@@ -308,7 +319,9 @@ function writeRetryEntry<T extends LogSchema>(
|
|
|
308
319
|
buffer.retry_attempt(index, attempt);
|
|
309
320
|
buffer.retry_delay_ms(index, delayMs);
|
|
310
321
|
}
|
|
322
|
+
//#endregion smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.retry
|
|
311
323
|
|
|
324
|
+
//#region smoo/lmao!n/op-retry.loop
|
|
312
325
|
/**
|
|
313
326
|
* Sleep for the specified duration.
|
|
314
327
|
*
|
|
@@ -383,7 +396,9 @@ async function executeWithRetry<T extends LogSchema, S, E>(
|
|
|
383
396
|
return result;
|
|
384
397
|
}
|
|
385
398
|
}
|
|
399
|
+
//#endregion smoo/lmao!n/op-retry.loop
|
|
386
400
|
|
|
401
|
+
//#region smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.end
|
|
387
402
|
/**
|
|
388
403
|
* Write span-end entry to buffer at row 1.
|
|
389
404
|
*
|
|
@@ -408,14 +423,20 @@ export function writeSpanEnd<T extends LogSchema, S, E>(buffer: SpanBuffer<T>, r
|
|
|
408
423
|
}
|
|
409
424
|
}
|
|
410
425
|
}
|
|
426
|
+
//#endregion smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.end
|
|
411
427
|
|
|
412
428
|
// =============================================================================
|
|
413
429
|
// SpanContext Class Types
|
|
414
430
|
// =============================================================================
|
|
415
431
|
|
|
432
|
+
//#region smoo/lmao!n/spancontext-type
|
|
416
433
|
/**
|
|
417
434
|
* Constructor type for SpanContext classes created by createSpanContextClass.
|
|
418
435
|
* Takes buffer, schema, spanLogger, tag directly (no temp object allocation).
|
|
436
|
+
*
|
|
437
|
+
* 01j "SpanContext Type Definition": the runtime SpanContext shape, parameterised by a single
|
|
438
|
+
* bundled OpContext (logSchema/flags/deps/...) rather than separate Schema/Deps/FF/Extra params,
|
|
439
|
+
* and SpanFn realized as the monomorphic span0-span8 overloads + variadic span() dispatcher.
|
|
419
440
|
*/
|
|
420
441
|
export type SpanContextClass<Ctx extends OpContext> = new (
|
|
421
442
|
buffer: SpanBuffer<Ctx['logSchema']>,
|
|
@@ -596,6 +617,7 @@ export type SpanContextInstance<Ctx extends OpContext> = SpanContext<Ctx> & {
|
|
|
596
617
|
a8: A8,
|
|
597
618
|
): Promise<Result<S, E, Ctx['logSchema']>>;
|
|
598
619
|
};
|
|
620
|
+
//#endregion smoo/lmao!n/spancontext-type
|
|
599
621
|
|
|
600
622
|
// =============================================================================
|
|
601
623
|
// SpanContext Class Factory
|
|
@@ -654,6 +676,10 @@ export function createSpanContextClass<Ctx extends OpContext>(
|
|
|
654
676
|
spanLogger: SpanLoggerImpl<Ctx['logSchema']>,
|
|
655
677
|
tag: TagWriter<Ctx['logSchema']>,
|
|
656
678
|
) {
|
|
679
|
+
//#region smoo/lmao!n/codegen-destructured-context
|
|
680
|
+
// Destructured-context assembly (01g): every property an op destructures —
|
|
681
|
+
// tag, log, scope (setScope), ok, err, span — is wired here as a closed-over
|
|
682
|
+
// field/closure so `op(({ tag, log, span, ok, err }) => ...)` needs no ctx drilling.
|
|
657
683
|
this._buffer = buffer;
|
|
658
684
|
this._schema = schema;
|
|
659
685
|
this._spanLogger = spanLogger;
|
|
@@ -669,7 +695,14 @@ export function createSpanContextClass<Ctx extends OpContext>(
|
|
|
669
695
|
this.ok = <V>(value: V): Ok<V, Ctx['logSchema']> => new Ok<V, Ctx['logSchema']>(value, schema, buffer);
|
|
670
696
|
|
|
671
697
|
this.err = <E>(error: E): Err<E, Ctx['logSchema']> => new Err<E, Ctx['logSchema']>(error, schema, buffer);
|
|
672
|
-
|
|
698
|
+
//#endregion smoo/lmao!n/codegen-destructured-context
|
|
699
|
+
|
|
700
|
+
//#region smoo/lmao!n/context-flow-span-promise
|
|
701
|
+
// 01c "Why span() Is Promise-Based" + "Child Span Creation via span()" + "spanSync()".
|
|
702
|
+
// span() is the variadic, line-number-aware Promise-based dispatcher: it detects the
|
|
703
|
+
// (line?, name, overrides?, op|fn, ...args) pattern via arguments.length (no rest-spread
|
|
704
|
+
// allocation) and routes to the monomorphic span0-span8. spanSync() is the sync-only
|
|
705
|
+
// sibling (returns Result, no Promise, no async retry loop) for guaranteed-sync callbacks.
|
|
673
706
|
// span uses regular function to access `arguments` (no ...rest spread allocation)
|
|
674
707
|
// Closes over `self` for calling prototype methods
|
|
675
708
|
// Named function for better stack traces
|
|
@@ -866,6 +899,7 @@ export function createSpanContextClass<Ctx extends OpContext>(
|
|
|
866
899
|
fn,
|
|
867
900
|
);
|
|
868
901
|
};
|
|
902
|
+
//#endregion smoo/lmao!n/context-flow-span-promise
|
|
869
903
|
}
|
|
870
904
|
|
|
871
905
|
// =========================================================================
|
|
@@ -902,9 +936,13 @@ export function createSpanContextClass<Ctx extends OpContext>(
|
|
|
902
936
|
return this._buffer;
|
|
903
937
|
}
|
|
904
938
|
|
|
939
|
+
//#region smoo/lmao!n/scope-attributes.read
|
|
940
|
+
// 01i read-only scope view: the immutable _scopeValues snapshot (setScope is wired in the
|
|
941
|
+
// destructured-context region; the immutable merge is _setScope in spanLoggerGenerator).
|
|
905
942
|
get scope(): Readonly<Partial<InferSchema<Ctx['logSchema']>>> {
|
|
906
943
|
return this._buffer._scopeValues;
|
|
907
944
|
}
|
|
945
|
+
//#endregion smoo/lmao!n/scope-attributes.read
|
|
908
946
|
|
|
909
947
|
// =========================================================================
|
|
910
948
|
// Internal methods (on prototype)
|
|
@@ -944,6 +982,12 @@ export function createSpanContextClass<Ctx extends OpContext>(
|
|
|
944
982
|
* @param remappedViewClass - Optional view class for prefixed ops (wraps buffer for Arrow conversion)
|
|
945
983
|
* @param opMetadata - Metadata for the executing op (Op's metadata or parent's for plain functions)
|
|
946
984
|
*/
|
|
985
|
+
//#region smoo/lmao!n/context-flow-child-span
|
|
986
|
+
// 01c "Child Span Creation via span()" / "How span() Works" and 01e "Op's Responsibility:
|
|
987
|
+
// Buffer Creation and Registration": _spanPre is where the child SpanBuffer is created
|
|
988
|
+
// (via the buffer strategy, using the Op's SpanBufferClass for cross-library schema),
|
|
989
|
+
// wrapped in a RemappedBufferView when the dep is prefixed/mapped, registered in the
|
|
990
|
+
// parent's _children, and span-start (row 0) is written with the caller's line number.
|
|
947
991
|
_spanPre(
|
|
948
992
|
childCtx: SpanContextInstance<Ctx>,
|
|
949
993
|
line: number,
|
|
@@ -1203,7 +1247,9 @@ export function createSpanContextClass<Ctx extends OpContext>(
|
|
|
1203
1247
|
|
|
1204
1248
|
return ctx;
|
|
1205
1249
|
}
|
|
1250
|
+
//#endregion smoo/lmao!n/context-flow-child-span
|
|
1206
1251
|
|
|
1252
|
+
//#region smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.exception
|
|
1207
1253
|
/**
|
|
1208
1254
|
* Handle span exception - writes exception details to row 1.
|
|
1209
1255
|
* Called in catch blocks of span methods.
|
|
@@ -1218,6 +1264,7 @@ export function createSpanContextClass<Ctx extends OpContext>(
|
|
|
1218
1264
|
childBuffer.exception_stack(1, errorStack);
|
|
1219
1265
|
}
|
|
1220
1266
|
}
|
|
1267
|
+
//#endregion smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.exception
|
|
1221
1268
|
|
|
1222
1269
|
// =========================================================================
|
|
1223
1270
|
// Monomorphic span methods (for transformer output)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Database } from 'bun:sqlite';
|
|
1
2
|
import { describe, expect, it } from 'bun:test';
|
|
2
3
|
import { createTestTracerOptions } from '../../__tests__/test-helpers.js';
|
|
3
4
|
import { defineOpContext } from '../../defineOpContext.js';
|
|
@@ -5,7 +6,13 @@ import { S } from '../../schema/builder.js';
|
|
|
5
6
|
import { defineLogSchema } from '../../schema/defineLogSchema.js';
|
|
6
7
|
import { TestTracer } from '../../tracers/TestTracer.js';
|
|
7
8
|
import type { AnySpanBuffer } from '../../types.js';
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
buildInsertParams,
|
|
11
|
+
buildInsertSql,
|
|
12
|
+
parseSqliteTableInfoRows,
|
|
13
|
+
SPANS_TABLE_INIT_SQL,
|
|
14
|
+
type SpanSegment,
|
|
15
|
+
} from '../sqlite-common.js';
|
|
9
16
|
|
|
10
17
|
const opContext = defineOpContext({
|
|
11
18
|
logSchema: defineLogSchema({
|
|
@@ -87,3 +94,35 @@ describe('parseSqliteTableInfoRows', () => {
|
|
|
87
94
|
).toThrow('PRAGMA table_info(spans) returned an invalid SQLite row 0: type expected string, got number');
|
|
88
95
|
});
|
|
89
96
|
});
|
|
97
|
+
|
|
98
|
+
describe('buildInsertSql', () => {
|
|
99
|
+
it('quotes user column identifiers so reserved words do not break the INSERT', () => {
|
|
100
|
+
// `check` and `order` are SQLite reserved words; a LogSchema field may use
|
|
101
|
+
// either (e.g. a `check` column). Unquoted, these produce
|
|
102
|
+
// `near "check": syntax error` at flush time.
|
|
103
|
+
const sql = buildInsertSql(['check', 'order', 'node']);
|
|
104
|
+
expect(sql).toContain('"check"');
|
|
105
|
+
expect(sql).toContain('"order"');
|
|
106
|
+
expect(sql).toContain('"node"');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('omits the user-column clause entirely when there are no active fields', () => {
|
|
110
|
+
const sql = buildInsertSql([]);
|
|
111
|
+
expect(sql).toContain(
|
|
112
|
+
'INSERT INTO spans (trace_id, span_id, parent_span_id, row_index, entry_type, timestamp_ns, message)',
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('prepares against a real SQLite spans table with a reserved-word column', () => {
|
|
117
|
+
const db = new Database(':memory:');
|
|
118
|
+
db.exec(SPANS_TABLE_INIT_SQL);
|
|
119
|
+
db.exec('ALTER TABLE spans ADD COLUMN "check" TEXT');
|
|
120
|
+
// The bug: db.prepare(buildInsertSql(['check'])) threw `near "check": syntax error`.
|
|
121
|
+
const stmt = db.prepare(buildInsertSql(['check']));
|
|
122
|
+
stmt.run('trace-1', 1, 0, 0, 0, 0, 'msg', 'pass');
|
|
123
|
+
// .values() yields raw cell arrays (no object shape to assert / no cast).
|
|
124
|
+
const rows = db.query('SELECT "check" FROM spans').values();
|
|
125
|
+
expect(rows).toEqual([['pass']]);
|
|
126
|
+
db.close();
|
|
127
|
+
});
|
|
128
|
+
});
|
package/src/lib/sqlite/index.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @module sqlite-async-writer
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { cleanupDebug } from '../cleanupDiagnostics.js';
|
|
10
11
|
import type { LogSchema } from '../schema/LogSchema.js';
|
|
11
12
|
import type { AnySpanBuffer } from '../types.js';
|
|
12
13
|
import {
|
|
@@ -82,6 +83,10 @@ export class SQLiteAsyncTraceWriter {
|
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
async flush(rootBuffer: AnySpanBuffer): Promise<void> {
|
|
86
|
+
cleanupDebug('sqliteAsyncWriter.flush:start', {
|
|
87
|
+
initialized: this.initialized,
|
|
88
|
+
statementCacheSize: this.insertStmtCache.size,
|
|
89
|
+
});
|
|
85
90
|
await this.init();
|
|
86
91
|
for (const segment of walkSpanSegments(rootBuffer)) {
|
|
87
92
|
await this.ensureColumns(segment.buffer._logSchema);
|
|
@@ -93,9 +98,12 @@ export class SQLiteAsyncTraceWriter {
|
|
|
93
98
|
await insertStmt.run(...buildInsertParams(segment, row, activeUserFields));
|
|
94
99
|
}
|
|
95
100
|
}
|
|
101
|
+
cleanupDebug('sqliteAsyncWriter.flush:end', { statementCacheSize: this.insertStmtCache.size });
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
async close(): Promise<void> {
|
|
105
|
+
cleanupDebug('sqliteAsyncWriter.close:start', { statementCacheSize: this.insertStmtCache.size });
|
|
99
106
|
await this.db.close();
|
|
107
|
+
cleanupDebug('sqliteAsyncWriter.close:end');
|
|
100
108
|
}
|
|
101
109
|
}
|
|
@@ -284,7 +284,11 @@ export function getInsertStatementCacheKey(activeUserFields: readonly string[]):
|
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
export function buildInsertSql(activeUserFields: readonly string[]): string {
|
|
287
|
-
|
|
287
|
+
// WHY quote: user column names come from arbitrary LogSchema fields and may
|
|
288
|
+
// collide with SQLite reserved words (e.g. a `check` or `order` trace column).
|
|
289
|
+
// buildAddColumnSql already quotes via quoteSqlIdentifier; the INSERT column
|
|
290
|
+
// list must too, or `near "check": syntax error` at flush time.
|
|
291
|
+
const userColsSql = activeUserFields.length > 0 ? `, ${activeUserFields.map(quoteSqlIdentifier).join(', ')}` : '';
|
|
288
292
|
const userPlaceholders = activeUserFields.length > 0 ? `, ${activeUserFields.map(() => '?').join(', ')}` : '';
|
|
289
293
|
return `INSERT INTO spans (trace_id, span_id, parent_span_id, row_index, entry_type, timestamp_ns, message${userColsSql})
|
|
290
294
|
VALUES (?, ?, ?, ?, ?, ?, ?${userPlaceholders})`;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* @module sqlite-writer
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { cleanupDebug } from '../cleanupDiagnostics.js';
|
|
18
19
|
import type { LogSchema } from '../schema/LogSchema.js';
|
|
19
20
|
import type { AnySpanBuffer } from '../types.js';
|
|
20
21
|
import {
|
|
@@ -112,17 +113,22 @@ export class SQLiteTraceWriter {
|
|
|
112
113
|
|
|
113
114
|
/** Write a root SpanBuffer tree to the database */
|
|
114
115
|
flush(rootBuffer: AnySpanBuffer): void {
|
|
116
|
+
cleanupDebug('sqliteWriter.flush:start', { statementCacheSize: this.insertStmtCache.size });
|
|
115
117
|
this.db.exec('BEGIN IMMEDIATE');
|
|
116
118
|
try {
|
|
117
119
|
this.flushAllSegments(rootBuffer);
|
|
118
120
|
this.db.exec('COMMIT');
|
|
121
|
+
cleanupDebug('sqliteWriter.flush:end', { statementCacheSize: this.insertStmtCache.size });
|
|
119
122
|
} catch (error) {
|
|
120
123
|
this.db.exec('ROLLBACK');
|
|
124
|
+
cleanupDebug('sqliteWriter.flush:error', { statementCacheSize: this.insertStmtCache.size });
|
|
121
125
|
throw error;
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
|
|
125
129
|
close(): void {
|
|
130
|
+
cleanupDebug('sqliteWriter.close:start', { statementCacheSize: this.insertStmtCache.size });
|
|
126
131
|
this.db.close();
|
|
132
|
+
cleanupDebug('sqliteWriter.close:end');
|
|
127
133
|
}
|
|
128
134
|
}
|
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
mock,
|
|
55
55
|
} from 'bun:test';
|
|
56
56
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
57
|
+
import { cleanupDebug, cleanupDebugActiveHandles } from '../cleanupDiagnostics.js';
|
|
57
58
|
import { defineOpContext } from '../defineOpContext.js';
|
|
58
59
|
import { JsBufferStrategy } from '../JsBufferStrategy.js';
|
|
59
60
|
import type { SpanContext } from '../opContext/spanContextTypes.js';
|
|
@@ -270,7 +271,9 @@ function createRootTracer<B extends OpContextBinding>({
|
|
|
270
271
|
async function closeTracer<B extends OpContextBinding>(tracer: Tracer<B>): Promise<void> {
|
|
271
272
|
const close = Reflect.get(tracer, 'close');
|
|
272
273
|
if (typeof close === 'function') {
|
|
274
|
+
cleanupDebug('tracer.close:start', { tracer: tracer.constructor.name });
|
|
273
275
|
await close.call(tracer);
|
|
276
|
+
cleanupDebug('tracer.close:end', { tracer: tracer.constructor.name });
|
|
274
277
|
}
|
|
275
278
|
}
|
|
276
279
|
|
|
@@ -531,19 +534,26 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
|
|
|
531
534
|
});
|
|
532
535
|
|
|
533
536
|
_afterAll(async () => {
|
|
537
|
+
cleanupDebug('instance.afterAll:start');
|
|
538
|
+
cleanupDebugActiveHandles('instance.afterAll:handles:start');
|
|
534
539
|
if (resolveTestRun) {
|
|
540
|
+
cleanupDebug('instance.rootTrace:resolve');
|
|
535
541
|
resolveTestRun();
|
|
536
542
|
resolveTestRun = null;
|
|
537
543
|
}
|
|
538
544
|
|
|
539
545
|
if (rootTracePromise) {
|
|
546
|
+
cleanupDebug('instance.rootTrace:await:start');
|
|
540
547
|
await rootTracePromise;
|
|
548
|
+
cleanupDebug('instance.rootTrace:await:end');
|
|
541
549
|
rootTracePromise = null;
|
|
542
550
|
}
|
|
543
551
|
|
|
544
552
|
if (tracer) {
|
|
545
553
|
try {
|
|
554
|
+
cleanupDebug('instance.tracer.flush:start', { tracer: tracer.constructor.name });
|
|
546
555
|
await tracer.flush();
|
|
556
|
+
cleanupDebug('instance.tracer.flush:end', { tracer: tracer.constructor.name });
|
|
547
557
|
if (options?.sqlite && rootCtx) {
|
|
548
558
|
const traceId = rootCtx.buffer.trace_id;
|
|
549
559
|
const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
|
|
@@ -553,6 +563,8 @@ function createTestTracerInstance<B extends OpContextBinding, TExt extends Schem
|
|
|
553
563
|
console.error('[lmao/testing] SQLite flush error:', e);
|
|
554
564
|
} finally {
|
|
555
565
|
await closeTracer(tracer);
|
|
566
|
+
cleanupDebugActiveHandles('instance.afterAll:handles:end');
|
|
567
|
+
cleanupDebug('instance.afterAll:end');
|
|
556
568
|
}
|
|
557
569
|
}
|
|
558
570
|
});
|
|
@@ -635,20 +647,27 @@ export function initTraceTestRun<B extends OpContextBinding>(opContext: B, optio
|
|
|
635
647
|
|
|
636
648
|
// Register global teardown — resolve root, wait for span-end, then flush tracer outputs
|
|
637
649
|
_afterAll(async () => {
|
|
650
|
+
cleanupDebug('global.afterAll:start');
|
|
651
|
+
cleanupDebugActiveHandles('global.afterAll:handles:start');
|
|
638
652
|
// Resolve the root promise — triggers span-end write via _executeWithContext .then()
|
|
639
653
|
if (_resolveTestRun) {
|
|
654
|
+
cleanupDebug('global.rootTrace:resolve');
|
|
640
655
|
_resolveTestRun();
|
|
641
656
|
_resolveTestRun = null;
|
|
642
657
|
}
|
|
643
658
|
// Await the trace promise so span-end is written to the buffer before flushing
|
|
644
659
|
if (_rootTracePromise) {
|
|
660
|
+
cleanupDebug('global.rootTrace:await:start');
|
|
645
661
|
await _rootTracePromise;
|
|
662
|
+
cleanupDebug('global.rootTrace:await:end');
|
|
646
663
|
_rootTracePromise = null;
|
|
647
664
|
}
|
|
648
665
|
|
|
649
666
|
if (_tracer) {
|
|
650
667
|
try {
|
|
668
|
+
cleanupDebug('global.tracer.flush:start', { tracer: _tracer.constructor.name });
|
|
651
669
|
await _tracer.flush();
|
|
670
|
+
cleanupDebug('global.tracer.flush:end', { tracer: _tracer.constructor.name });
|
|
652
671
|
if (options?.sqlite && _rootCtx) {
|
|
653
672
|
const traceId = _rootCtx.buffer.trace_id;
|
|
654
673
|
const dbPath = options.sqlite.dbPath ?? '.trace-results.db';
|
|
@@ -658,6 +677,8 @@ export function initTraceTestRun<B extends OpContextBinding>(opContext: B, optio
|
|
|
658
677
|
console.error('[lmao/testing] SQLite flush error:', e);
|
|
659
678
|
} finally {
|
|
660
679
|
await closeTracer(_tracer);
|
|
680
|
+
cleanupDebugActiveHandles('global.afterAll:handles:end');
|
|
681
|
+
cleanupDebug('global.afterAll:end');
|
|
661
682
|
}
|
|
662
683
|
}
|
|
663
684
|
});
|
package/src/lib/threadId.ts
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* @module threadId
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
+
//#region smoo/lmao!n/spanbuffer-layout.thread-id
|
|
25
26
|
/** Thread ID size in bytes */
|
|
26
27
|
export const THREAD_ID_BYTES = 8;
|
|
27
28
|
|
|
@@ -120,6 +121,7 @@ export function writeThreadIdToUint64Array(dest: BigUint64Array, index: number):
|
|
|
120
121
|
const byteView = new Uint8Array(dest.buffer, dest.byteOffset + index * 8, 8);
|
|
121
122
|
byteView.set(threadIdBytes);
|
|
122
123
|
}
|
|
124
|
+
//#endregion smoo/lmao!n/spanbuffer-layout.thread-id
|
|
123
125
|
|
|
124
126
|
/**
|
|
125
127
|
* Reset thread ID for testing purposes only.
|
package/src/lib/traceId.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* @module traceId
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
+
//#region smoo/lmao!n/span-identity.trace-id
|
|
15
16
|
/** Maximum length for a trace ID */
|
|
16
17
|
export const MAX_TRACE_ID_LENGTH = 128;
|
|
17
18
|
|
|
@@ -85,10 +86,12 @@ export function generateTraceId(): TraceId {
|
|
|
85
86
|
|
|
86
87
|
return brandTraceId(hex);
|
|
87
88
|
}
|
|
89
|
+
//#endregion smoo/lmao!n/span-identity.trace-id
|
|
88
90
|
|
|
89
91
|
// ============================================================================
|
|
90
92
|
// SpanIdentity - Span identification for external systems
|
|
91
93
|
// ============================================================================
|
|
94
|
+
//#region smoo/lmao!n/span-identity.external-correlation
|
|
92
95
|
|
|
93
96
|
/**
|
|
94
97
|
* SpanIdentity - Identifies a specific span for external correlation.
|
|
@@ -140,3 +143,4 @@ export function extractSpanIdentity(buffer: { trace_id: TraceId; span_id: number
|
|
|
140
143
|
thread_id: buffer.thread_id,
|
|
141
144
|
};
|
|
142
145
|
}
|
|
146
|
+
//#endregion smoo/lmao!n/span-identity.external-correlation
|
package/src/lib/traceRoot.es.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region corpos/billing!n/audit-pricing-metering.lmao-es-trace-root
|
|
1
2
|
/**
|
|
2
3
|
* TraceRoot - Browser/ES implementation.
|
|
3
4
|
*
|
|
@@ -94,6 +95,7 @@ export class TraceRoot implements ITraceRoot {
|
|
|
94
95
|
return createTraceId(textDecoder.decode(new Uint8Array(this._system, TRACE_ROOT_TRACE_ID_OFFSET, len)));
|
|
95
96
|
}
|
|
96
97
|
|
|
98
|
+
//#region smoo/lmao!n/trace-root-timestamps #es
|
|
97
99
|
/**
|
|
98
100
|
* Get current timestamp in nanoseconds since Unix epoch.
|
|
99
101
|
* Uses performance.now() - microsecond precision (last 3 digits = 000).
|
|
@@ -104,6 +106,7 @@ export class TraceRoot implements ITraceRoot {
|
|
|
104
106
|
const elapsedNanos = BigInt(Math.floor(elapsedMs * 1000)) * 1000n;
|
|
105
107
|
return Nanoseconds.unsafe(this._epochView[0] + elapsedNanos);
|
|
106
108
|
}
|
|
109
|
+
//#endregion smoo/lmao!n/trace-root-timestamps
|
|
107
110
|
|
|
108
111
|
/**
|
|
109
112
|
* Write span-start entry to buffer at row 0.
|
|
@@ -155,3 +158,4 @@ export function createTraceRoot(trace_id: string, tracer: TracerLifecycleHooks):
|
|
|
155
158
|
const anchorPerfNow = performance.now();
|
|
156
159
|
return new TraceRoot(createTraceId(trace_id), anchorEpochNanos, anchorPerfNow, tracer);
|
|
157
160
|
}
|
|
161
|
+
//#endregion corpos/billing!n/audit-pricing-metering.lmao-es-trace-root
|
|
@@ -28,6 +28,7 @@ const textEncoder = new TextEncoder();
|
|
|
28
28
|
/** Shared TextDecoder for trace_id decoding (stateless, reusable) */
|
|
29
29
|
const textDecoder = new TextDecoder();
|
|
30
30
|
|
|
31
|
+
//#region smoo/lmao!n/trace-root-timestamps #node
|
|
31
32
|
/**
|
|
32
33
|
* TraceRoot - Node.js implementation.
|
|
33
34
|
*
|
|
@@ -168,3 +169,4 @@ export function createTraceRoot(trace_id: string, tracer: TracerLifecycleHooks):
|
|
|
168
169
|
const anchorPerfNow = Number(anchorHrtimeBigInt);
|
|
169
170
|
return new TraceRoot(createTraceId(trace_id), anchorEpochNanos, anchorPerfNow, anchorHrtimeBigInt, tracer);
|
|
170
171
|
}
|
|
172
|
+
//#endregion smoo/lmao!n/trace-root-timestamps
|
package/src/lib/traceRoot.ts
CHANGED
|
@@ -24,6 +24,7 @@ export { createTraceId, extractSpanIdentity, generateTraceId, isValidTraceId, MA
|
|
|
24
24
|
* Tracer lifecycle hooks interface.
|
|
25
25
|
* Extracted to avoid circular dependency - Tracer implements this.
|
|
26
26
|
*/
|
|
27
|
+
//#region smoo/lmao!n/buffer-tuning-observability
|
|
27
28
|
export interface TracerLifecycleHooks {
|
|
28
29
|
onTraceStart(buffer: unknown): void;
|
|
29
30
|
onTraceEnd(buffer: unknown): void;
|
|
@@ -47,6 +48,7 @@ export interface TracerLifecycleHooks {
|
|
|
47
48
|
createOverflowBuffer(buffer: AnySpanBuffer): AnySpanBuffer;
|
|
48
49
|
};
|
|
49
50
|
}
|
|
51
|
+
//#endregion smoo/lmao!n/buffer-tuning-observability
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
54
|
* TraceRoot._system memory layout (little-endian):
|
|
@@ -61,6 +63,7 @@ export interface TracerLifecycleHooks {
|
|
|
61
63
|
*
|
|
62
64
|
* This layout enables NAPI/WASM to read anchors directly without BigInt extraction.
|
|
63
65
|
*/
|
|
66
|
+
//#region smoo/lmao!n/trace-root-timestamps #contract
|
|
64
67
|
export const TRACE_ROOT_ANCHOR_EPOCH_OFFSET = 0;
|
|
65
68
|
export const TRACE_ROOT_ANCHOR_PERF_OFFSET = 8;
|
|
66
69
|
export const TRACE_ROOT_TRACE_ID_LEN_OFFSET = 16;
|
|
@@ -152,3 +155,4 @@ export interface ITraceRoot {
|
|
|
152
155
|
*/
|
|
153
156
|
writeLogEntry(buffer: AnySpanBuffer, entryType: number): number;
|
|
154
157
|
}
|
|
158
|
+
//#endregion smoo/lmao!n/trace-root-timestamps
|
package/src/lib/tracer.ts
CHANGED
|
@@ -239,6 +239,7 @@ export type TraceFn<Ctx extends OpContext> = {
|
|
|
239
239
|
// Tracer Class
|
|
240
240
|
// =============================================================================
|
|
241
241
|
|
|
242
|
+
//#region smoo/lmao!n/tracer-architecture #contract
|
|
242
243
|
/**
|
|
243
244
|
* Tracer - Abstract base class for trace collection
|
|
244
245
|
*
|
|
@@ -357,6 +358,7 @@ export abstract class Tracer<B extends OpContextBinding = OpContextBinding> {
|
|
|
357
358
|
// trace() - Polymorphic dispatcher (like span())
|
|
358
359
|
// ===========================================================================
|
|
359
360
|
|
|
361
|
+
//#region smoo/lmao!n/tracer-architecture.trace-overloads
|
|
360
362
|
/**
|
|
361
363
|
* Polymorphic trace dispatcher.
|
|
362
364
|
*
|
|
@@ -547,6 +549,7 @@ export abstract class Tracer<B extends OpContextBinding = OpContextBinding> {
|
|
|
547
549
|
}
|
|
548
550
|
return this._trace_unknown_fn(line, name, overrides, fnOrOp);
|
|
549
551
|
}
|
|
552
|
+
//#endregion smoo/lmao!n/tracer-architecture.trace-overloads
|
|
550
553
|
|
|
551
554
|
// ===========================================================================
|
|
552
555
|
// Monomorphic trace methods (for transformer optimization)
|
|
@@ -894,3 +897,4 @@ export abstract class Tracer<B extends OpContextBinding = OpContextBinding> {
|
|
|
894
897
|
}
|
|
895
898
|
}
|
|
896
899
|
}
|
|
900
|
+
//#endregion smoo/lmao!n/tracer-architecture
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region corpos/billing!n/audit-pricing-metering.lmao-array-queue-tracer
|
|
1
2
|
import type { OpContextBinding } from '../opContext/types.js';
|
|
2
3
|
import { Tracer } from '../tracer.js';
|
|
3
4
|
import type { SpanBuffer } from '../types.js';
|
|
@@ -74,3 +75,4 @@ export class ArrayQueueTracer<B extends OpContextBinding = OpContextBinding> ext
|
|
|
74
75
|
return buffers;
|
|
75
76
|
}
|
|
76
77
|
}
|
|
78
|
+
//#endregion corpos/billing!n/audit-pricing-metering.lmao-array-queue-tracer
|