@smoothbricks/lmao 0.1.4 → 0.2.1

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.
Files changed (148) hide show
  1. package/dist/cloudflare.d.ts +15 -0
  2. package/dist/cloudflare.d.ts.map +1 -0
  3. package/dist/cloudflare.js +14 -0
  4. package/dist/es.js +1 -0
  5. package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
  6. package/dist/lib/JsBufferStrategy.js +12 -0
  7. package/dist/lib/archive/chunkEnvelope.js +1 -0
  8. package/dist/lib/archive/chunkRouting.js +1 -0
  9. package/dist/lib/archive/chunkStats.js +1 -0
  10. package/dist/lib/arrow/capacityStats.js +1 -0
  11. package/dist/lib/arrow/dictionaries.d.ts.map +1 -1
  12. package/dist/lib/buffer/Nanoseconds.d.ts.map +1 -1
  13. package/dist/lib/buffer/Nanoseconds.js +34 -0
  14. package/dist/lib/bufferStrategy.js +21 -0
  15. package/dist/lib/capacityTuning.js +26 -0
  16. package/dist/lib/cleanupDiagnostics.js +2 -2
  17. package/dist/lib/cloudflare/classSplit.d.ts +73 -0
  18. package/dist/lib/cloudflare/classSplit.d.ts.map +1 -0
  19. package/dist/lib/cloudflare/classSplit.js +101 -0
  20. package/dist/lib/cloudflare/collectorClient.d.ts +69 -0
  21. package/dist/lib/cloudflare/collectorClient.d.ts.map +1 -0
  22. package/dist/lib/cloudflare/collectorClient.js +82 -0
  23. package/dist/lib/cloudflare/diagnosticDrain.d.ts +78 -0
  24. package/dist/lib/cloudflare/diagnosticDrain.d.ts.map +1 -0
  25. package/dist/lib/cloudflare/diagnosticDrain.js +120 -0
  26. package/dist/lib/cloudflare/traceRows.d.ts +19 -0
  27. package/dist/lib/cloudflare/traceRows.d.ts.map +1 -0
  28. package/dist/lib/cloudflare/traceRows.js +51 -0
  29. package/dist/lib/codegen/evaluatorGenerator.js +2 -1
  30. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +8 -0
  31. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
  32. package/dist/lib/codegen/fixedPositionWriterGenerator.js +18 -1
  33. package/dist/lib/codegen/spanLoggerGenerator.js +1 -0
  34. package/dist/lib/errors/Blocked.d.ts +1 -1
  35. package/dist/lib/errors/Blocked.d.ts.map +1 -1
  36. package/dist/lib/errors/Blocked.js +53 -0
  37. package/dist/lib/errors/CodeError.d.ts.map +1 -1
  38. package/dist/lib/errors/CodeError.js +31 -0
  39. package/dist/lib/errors/RetriesExhausted.d.ts +1 -1
  40. package/dist/lib/errors/RetriesExhausted.d.ts.map +1 -1
  41. package/dist/lib/errors/RetriesExhausted.js +38 -0
  42. package/dist/lib/errors/Transient.d.ts +1 -1
  43. package/dist/lib/errors/Transient.d.ts.map +1 -1
  44. package/dist/lib/errors/Transient.js +31 -0
  45. package/dist/lib/errors/retry-policy.js +1 -0
  46. package/dist/lib/flushScheduler.d.ts +0 -3
  47. package/dist/lib/flushScheduler.d.ts.map +1 -1
  48. package/dist/lib/library.js +1 -0
  49. package/dist/lib/logApi.js +11 -0
  50. package/dist/lib/logBinding.js +13 -0
  51. package/dist/lib/op.d.ts.map +1 -1
  52. package/dist/lib/op.js +15 -0
  53. package/dist/lib/opContext/contextTypes.d.ts +1 -1
  54. package/dist/lib/opContext/contextTypes.d.ts.map +1 -1
  55. package/dist/lib/opContext/createOpGroup.js +1 -0
  56. package/dist/lib/opContext/featureFlagTypes.js +13 -0
  57. package/dist/lib/opContext/opGroupTypes.d.ts +1 -1
  58. package/dist/lib/opContext/opGroupTypes.d.ts.map +1 -1
  59. package/dist/lib/opContext/opGroupTypes.js +16 -0
  60. package/dist/lib/opContext/opTypes.js +14 -0
  61. package/dist/lib/opContext/spanContextTypes.js +19 -0
  62. package/dist/lib/opContext/types.js +15 -0
  63. package/dist/lib/result.d.ts.map +1 -1
  64. package/dist/lib/schema/LogSchema.d.ts.map +1 -1
  65. package/dist/lib/schema/builder.js +1 -0
  66. package/dist/lib/schema/defineFeatureFlags.js +1 -0
  67. package/dist/lib/schema/defineLogSchema.js +10 -0
  68. package/dist/lib/schema/evaluator.d.ts.map +1 -1
  69. package/dist/lib/schema/evaluator.js +1 -0
  70. package/dist/lib/schema/systemSchema.d.ts +1 -1
  71. package/dist/lib/schema/systemSchema.d.ts.map +1 -1
  72. package/dist/lib/schema/systemSchema.js +8 -0
  73. package/dist/lib/schema/types.js +6 -0
  74. package/dist/lib/spanBuffer.d.ts.map +1 -1
  75. package/dist/lib/spanBufferHelpers.js +1 -0
  76. package/dist/lib/spanBufferStats.js +24 -0
  77. package/dist/lib/spanContext.js +1 -0
  78. package/dist/lib/sqlite/sqlite-async-writer.d.ts.map +1 -1
  79. package/dist/lib/sqlite/sqlite-common.d.ts +2 -0
  80. package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
  81. package/dist/lib/sqlite/sqlite-common.js +4 -0
  82. package/dist/lib/sqlite/sqlite-d1.js +8 -0
  83. package/dist/lib/sqlite/sqlite-db.js +8 -0
  84. package/dist/lib/sqlite/sqlite-writer.d.ts.map +1 -1
  85. package/dist/lib/testing/bun-harness.d.ts +4 -0
  86. package/dist/lib/testing/bun-harness.d.ts.map +1 -1
  87. package/dist/lib/testing/extractFacts.js +8 -0
  88. package/dist/lib/testing/facts.d.ts.map +1 -1
  89. package/dist/lib/testing/facts.js +19 -0
  90. package/dist/lib/testing/queryable-span.js +16 -0
  91. package/dist/lib/testing/span-query.js +8 -0
  92. package/dist/lib/testing/trace-query.d.ts.map +1 -1
  93. package/dist/lib/testing/trace-query.js +247 -219
  94. package/dist/lib/traceContext.js +8 -0
  95. package/dist/lib/traceId.js +1 -0
  96. package/dist/lib/traceRoot.d.ts +5 -5
  97. package/dist/lib/traceRoot.es.d.ts.map +1 -1
  98. package/dist/lib/traceRoot.es.js +2 -1
  99. package/dist/lib/traceRoot.js +16 -1
  100. package/dist/lib/traceRoot.node.d.ts +2 -2
  101. package/dist/lib/traceRoot.node.d.ts.map +1 -1
  102. package/dist/lib/traceRoot.node.js +4 -3
  103. package/dist/lib/tracer.d.ts.map +1 -1
  104. package/dist/lib/tracer.js +61 -0
  105. package/dist/lib/tracers/ArrayQueueTracer.d.ts.map +1 -1
  106. package/dist/lib/tracers/ArrayQueueTracer.js +1 -0
  107. package/dist/lib/tracers/CompositeTracer.d.ts.map +1 -1
  108. package/dist/lib/tracers/CompositeTracer.js +1 -0
  109. package/dist/lib/tracers/NoOpTracer.d.ts.map +1 -1
  110. package/dist/lib/tracers/NoOpTracer.js +25 -0
  111. package/dist/lib/tracers/SQLiteTracer.d.ts.map +1 -1
  112. package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
  113. package/dist/lib/tracers/StdioTracer.js +39 -6
  114. package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
  115. package/dist/lib/tracers/TestTracer.js +30 -0
  116. package/dist/lib/types.js +10 -0
  117. package/dist/lib/utf8Cache.d.ts.map +1 -1
  118. package/dist/lib/utf8Cache.js +1 -0
  119. package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
  120. package/dist/lib/wasm/WasmBufferStrategy.js +15 -0
  121. package/dist/lib/wasm/wasmAllocator.js +16 -0
  122. package/dist/lib/wasm/wasmSpanBuffer.js +12 -0
  123. package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
  124. package/dist/lib/wasm/wasmTraceRoot.js +2 -1
  125. package/dist/node.js +1 -0
  126. package/package.json +11 -4
  127. package/src/cloudflare.ts +35 -0
  128. package/src/lib/bufferStrategy.ts +2 -2
  129. package/src/lib/cleanupDiagnostics.ts +2 -2
  130. package/src/lib/cloudflare/__tests__/classSplit.test.ts +171 -0
  131. package/src/lib/cloudflare/__tests__/collectorClient.test.ts +104 -0
  132. package/src/lib/cloudflare/__tests__/diagnosticDrain.test.ts +165 -0
  133. package/src/lib/cloudflare/classSplit.ts +139 -0
  134. package/src/lib/cloudflare/collectorClient.ts +117 -0
  135. package/src/lib/cloudflare/diagnosticDrain.ts +152 -0
  136. package/src/lib/cloudflare/traceRows.ts +60 -0
  137. package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +304 -0
  138. package/src/lib/codegen/evaluatorGenerator.ts +2 -2
  139. package/src/lib/codegen/fixedPositionWriterGenerator.ts +26 -1
  140. package/src/lib/schema/defineFeatureFlags.ts +2 -2
  141. package/src/lib/schema/evaluator.ts +2 -2
  142. package/src/lib/sqlite/sqlite-common.ts +5 -0
  143. package/src/lib/testing/__tests__/facts.test.ts +6 -6
  144. package/src/lib/traceRoot.es.ts +2 -2
  145. package/src/lib/traceRoot.node.ts +3 -3
  146. package/src/lib/traceRoot.ts +5 -5
  147. package/src/lib/tracers/ArrayQueueTracer.ts +2 -2
  148. package/src/lib/codegen/__tests__/__snapshots__/spanLoggerGenerator.test.ts.snap +0 -1965
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Cloudflare trace-sink adapters (specs/lmao/01u_cloudflare_trace_segments.md).
3
+ *
4
+ * Two delivery lanes over the base Tracer lifecycle, no Cloudflare types required — every
5
+ * platform binding (Pipelines stream send, Queues producer, collector shard) is injected
6
+ * structurally:
7
+ * - billing-grade: CollectorClient (awaited within the request; ack = DO storage commit)
8
+ * - diagnostic: DiagnosticDrainTracer + transports (waitUntil, fire-and-forget)
9
+ * - both: ClassSplitTracer routes rows per delivery class via an injected classifier
10
+ */
11
+ export { type ClassSplitOptions, ClassSplitTracer, type DeliveryClass, type DeliveryClassifier, } from './lib/cloudflare/classSplit.js';
12
+ export { COLLECTOR_ACK, type CollectorAck, type CollectorClient, type CollectorSendFailure, FakeCollectorClient, } from './lib/cloudflare/collectorClient.js';
13
+ export { type DiagnosticDrainOptions, DiagnosticDrainTracer, type DiagnosticTransport, type PipelinesStreamSend, PipelinesStreamTransport, type QueuesFallbackOptions, QueuesFallbackTransport, type TraceChunkQueueMessage, } from './lib/cloudflare/diagnosticDrain.js';
14
+ export { spanBufferToTraceRows, type TraceRow, type TraceRowValue } from './lib/cloudflare/traceRows.js';
15
+ //# sourceMappingURL=cloudflare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudflare.d.ts","sourceRoot":"","sources":["../src/cloudflare.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,kBAAkB,GACxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,mBAAmB,GACpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,KAAK,sBAAsB,EAC3B,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,uBAAuB,EACvB,KAAK,sBAAsB,GAC5B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Cloudflare trace-sink adapters (specs/lmao/01u_cloudflare_trace_segments.md).
3
+ *
4
+ * Two delivery lanes over the base Tracer lifecycle, no Cloudflare types required — every
5
+ * platform binding (Pipelines stream send, Queues producer, collector shard) is injected
6
+ * structurally:
7
+ * - billing-grade: CollectorClient (awaited within the request; ack = DO storage commit)
8
+ * - diagnostic: DiagnosticDrainTracer + transports (waitUntil, fire-and-forget)
9
+ * - both: ClassSplitTracer routes rows per delivery class via an injected classifier
10
+ */
11
+ export { ClassSplitTracer, } from './lib/cloudflare/classSplit.js';
12
+ export { COLLECTOR_ACK, FakeCollectorClient, } from './lib/cloudflare/collectorClient.js';
13
+ export { DiagnosticDrainTracer, PipelinesStreamTransport, QueuesFallbackTransport, } from './lib/cloudflare/diagnosticDrain.js';
14
+ export { spanBufferToTraceRows } from './lib/cloudflare/traceRows.js';
package/dist/es.js CHANGED
@@ -8,3 +8,4 @@ export * from './index.js';
8
8
  // Export browser-specific TraceRoot factory for Tracer construction
9
9
  //#region smoo/lmao!n/trace-root-timestamps.entry-points #es
10
10
  export { createTraceRoot } from './lib/traceRoot.es.js';
11
+ //#endregion smoo/lmao!n/trace-root-timestamps.entry-points
@@ -1 +1 @@
1
- {"version":3,"file":"JsBufferStrategy.d.ts","sourceRoot":"","sources":["../../src/lib/JsBufferStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAQvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAS5D;;;;;;;;;;;;;GAaG;AACH,qBAAa,gBAAgB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CAAE,YAAW,cAAc,CAAC,CAAC,CAAC;IACzF;;;OAGG;IACH,OAAO,CAAC,oBAAoB,CAAmD;IAE/E;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAYnC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;IAI5G,qBAAqB,CACnB,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,EAC3B,gBAAgB,EAAE,UAAU,EAC5B,UAAU,EAAE,UAAU,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,CAAC,GACT,UAAU,CAAC,CAAC,CAAC;IAOhB,oBAAoB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAI1D,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,KAAK;IAK1C,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;CAI5C"}
1
+ {"version":3,"file":"JsBufferStrategy.d.ts","sourceRoot":"","sources":["../../src/lib/JsBufferStrategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAQvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAS5D;;;;;;;;;;;;;GAaG;AACH,qBAAa,gBAAgB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CAAE,YAAW,cAAc,CAAC,CAAC,CAAC;IACzF;;;OAGG;IACH,OAAO,CAAC,oBAAoB,CAAmD;IAE/E;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAYnC,gBAAgB,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAE3G;IAED,qBAAqB,CACnB,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,EAC3B,gBAAgB,EAAE,UAAU,EAC5B,UAAU,EAAE,UAAU,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,CAAC,GACT,UAAU,CAAC,CAAC,CAAC,CAKf;IAED,oBAAoB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAEzD;IAED,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,KAAK,CAGzC;IAED,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAG1C;CACF"}
@@ -1,3 +1,15 @@
1
+ /**
2
+ * JsBufferStrategy - Default buffer strategy using JavaScript TypedArrays.
3
+ *
4
+ * Uses GC-managed memory with zero-copy Arrow conversion via flechette.
5
+ *
6
+ * Memory characteristics:
7
+ * - Buffers are regular JS objects with TypedArray properties
8
+ * - GC handles deallocation (no explicit release needed)
9
+ * - Arrow conversion shares ArrayBuffer references (zero-copy)
10
+ *
11
+ * @module JsBufferStrategy
12
+ */
1
13
  import { convertSpanTreeToArrowTable } from './convertToArrow.js';
2
14
  import { createChildSpanBuffer as createChildSpanBufferImpl, createOverflowBuffer as createOverflowBufferImpl, createSpanBuffer as createSpanBufferImpl, getSpanBufferClass, } from './spanBuffer.js';
3
15
  function isSpanBufferConstructorForSchema(ctor, schema) {
@@ -53,3 +53,4 @@ function fnv1a64(input) {
53
53
  }
54
54
  return hash.toString(16).padStart(16, '0');
55
55
  }
56
+ //#endregion smoo/lmao!n/trace-archive-envelope.build
@@ -48,3 +48,4 @@ export function splitChunkByPartition(rows, partitionOf, partitionField = 'group
48
48
  };
49
49
  });
50
50
  }
51
+ //#endregion smoo/lmao!n/trace-archive-partition-split.split
@@ -9,3 +9,4 @@ export function extractChunkStats(envelope, partitions = []) {
9
9
  duration_ms: Math.max(0, envelope.ended_at_ms - envelope.started_at_ms),
10
10
  };
11
11
  }
12
+ //#endregion smoo/lmao!n/trace-archive-stats.chunk-level
@@ -230,3 +230,4 @@ export function createCapacityStatsTable(entriesToLog, periodStartNs, mergedSche
230
230
  }
231
231
  return tableFromColumns(cols);
232
232
  }
233
+ //#endregion smoo/lmao!n/buffer-tuning-stats-logging
@@ -1 +1 @@
1
- {"version":3,"file":"dictionaries.d.ts","sourceRoot":"","sources":["../../../src/lib/arrow/dictionaries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAyB,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD;;;GAGG;AACH,qBAAa,qBAAqB;aAEd,UAAU,EAAE,MAAM,EAAE;aACpB,OAAO,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW;aAC/C,cAAc,EAAE,qBAAqB,GAAG,sBAAsB,GAAG,sBAAsB;aACvF,cAAc,EAAE,OAAO;aACvB,UAAU,EAAE,UAAU,GAAG,SAAS;aAClC,SAAS,EAAE,MAAM;gBALjB,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW,EAC/C,cAAc,EAAE,qBAAqB,GAAG,sBAAsB,GAAG,sBAAsB,EACvF,cAAc,EAAE,OAAO,EACvB,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,SAAS,EAAE,MAAM;CAEpC;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,aAAa,EAAE,EACxB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACxC,qBAAqB,CAkDvB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,aAAa,EAAE,EACxB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACxC,qBAAqB,GAAG,IAAI,CAqE9B"}
1
+ {"version":3,"file":"dictionaries.d.ts","sourceRoot":"","sources":["../../../src/lib/arrow/dictionaries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAyB,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD;;;GAGG;AACH,qBAAa,qBAAqB;aAEd,UAAU,EAAE,MAAM,EAAE;aACpB,OAAO,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW;aAC/C,cAAc,EAAE,qBAAqB,GAAG,sBAAsB,GAAG,sBAAsB;aACvF,cAAc,EAAE,OAAO;aACvB,UAAU,EAAE,UAAU,GAAG,SAAS;aAClC,SAAS,EAAE,MAAM;IANnC,YACkB,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW,EAC/C,cAAc,EAAE,qBAAqB,GAAG,sBAAsB,GAAG,sBAAsB,EACvF,cAAc,EAAE,OAAO,EACvB,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,SAAS,EAAE,MAAM,EAC/B;CACL;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,aAAa,EAAE,EACxB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACxC,qBAAqB,CAkDvB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,aAAa,EAAE,EACxB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GACxC,qBAAqB,GAAG,IAAI,CAqE9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"Nanoseconds.d.ts","sourceRoot":"","sources":["../../../src/lib/buffer/Nanoseconds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;GAKG;AACH,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,MAAM,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,gBAAgB,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC;AAOlF;;GAEG;AACH,yBAAiB,WAAW,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAgB,GAAG,IAAI,WAAW,CAMjC;IAED;;;;;;;;;;OAUG;IACH,SAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAEtD;IAED;;;;;;;;OAQG;IACH,SAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAEjD;IAED;;;;;OAKG;IACH,SAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEnD;IAED;;;;;OAKG;IACH,SAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEnD;CACF"}
1
+ {"version":3,"file":"Nanoseconds.d.ts","sourceRoot":"","sources":["../../../src/lib/buffer/Nanoseconds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;GAKG;AACH,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,MAAM,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,gBAAgB,CAAC,EAAE,aAAa,CAAA;CAAE,CAAC;AAOlF;;GAEG;AACH,yBAAiB,WAAW,CAAC,CAAC;IAC5B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAgB,GAAG,IAAI,WAAW,CAMjC;IAED;;;;;;;;;;OAUG;IACH,SAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAEtD;IAED;;;;;;;;OAQG;IACH,SAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAEjD;IAED;;;;;OAKG;IACH,SAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEnD;IAED;;;;;OAKG;IACH,SAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEnD;CACF"}
@@ -1,3 +1,37 @@
1
+ /**
2
+ * Nanoseconds branded type for type-safe timestamp handling
3
+ *
4
+ * Prevents accidental unit mixing (milliseconds vs nanoseconds) and provides
5
+ * a centralized location for timestamp conversion utilities.
6
+ *
7
+ * This is a generic buffer concept used for high-precision time-series data.
8
+ *
9
+ * **Benefits:**
10
+ * - Type safety prevents mixing time units
11
+ * - Self-documenting code - units clear from type
12
+ * - Zero runtime overhead on hot path (BigInt operations are fast)
13
+ * - Conversion functions centralized and tested
14
+ * - Works with Arrow's TimestampNanosecond type
15
+ *
16
+ * **Precision:**
17
+ * - BigInt can represent arbitrarily large integers
18
+ * - Nanoseconds since epoch will never overflow
19
+ * - Node.js: Native nanosecond precision via process.hrtime.bigint()
20
+ * - Browser: Microsecond precision via performance.now() (last 3 digits are 000)
21
+ *
22
+ * @module nanoseconds
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import { Nanoseconds } from '@smoothbricks/arrow-builder';
27
+ *
28
+ * // Node.js: Native nanoseconds
29
+ * const timestamp = Nanoseconds.now();
30
+ *
31
+ * // Store in buffer (BigInt64Array)
32
+ * buffer.timestamps[idx] = timestamp; // Type-safe!
33
+ * ```
34
+ */
1
35
  function toNanoseconds(value) {
2
36
  return value;
3
37
  }
@@ -1 +1,22 @@
1
+ //#region smoo/lmao!n/buffer-strategy
2
+ /**
3
+ * BufferStrategy - Abstraction for SpanBuffer memory management and Arrow conversion.
4
+ *
5
+ * This interface separates memory management concerns from sink concerns (Tracer):
6
+ * - BufferStrategy: HOW buffers are allocated and converted (JS TypedArrays vs WASM)
7
+ * - Tracer (sink): WHAT happens with completed buffers (stdio, queue, test accumulation)
8
+ *
9
+ * Key responsibilities:
10
+ * 1. Buffer creation (root, child, overflow)
11
+ * 2. Arrow conversion (strategy knows optimal path)
12
+ * 3. Buffer release (GC for JS, freelist for WASM)
13
+ *
14
+ * The sink (Tracer subclass) controls WHEN to convert and release:
15
+ * - StdioTracer: prints then releases immediately
16
+ * - TestTracer: holds buffers until clear()
17
+ * - SqsTracer: accumulates, converts on flush(), then releases
18
+ *
19
+ * @module bufferStrategy
20
+ */
1
21
  export {};
22
+ //#endregion smoo/lmao!n/buffer-strategy
@@ -1,3 +1,28 @@
1
+ /**
2
+ * Capacity Tuning - Self-tuning buffer capacity based on utilization
3
+ *
4
+ * Per specs/lmao/01b2_buffer_self_tuning.md:
5
+ * - Track row utilization = totalWrites / (spansCreated * usableRowsPerSpan)
6
+ * - Increase capacity if utilization > 150% (regularly overflowing)
7
+ * - Decrease capacity if utilization < 50% (wasting space)
8
+ * - Maintain power-of-2 capacities between 8 and 1024
9
+ *
10
+ * ## Utilization Model
11
+ *
12
+ * - 100% = exactly filling first buffer per span (ideal)
13
+ * - 150% = filling 1.5x first buffer (some spans overflow)
14
+ * - 200% = filling 2x first buffer (every span overflows once)
15
+ * - 50% = only using half the first buffer (wasting space)
16
+ *
17
+ * The 3x gap between shrink (50%) and grow (150%) thresholds prevents flip-flopping:
18
+ * - After grow: utilization halves → lands in stable zone
19
+ * - After shrink: utilization doubles → lands in stable zone
20
+ *
21
+ * ## Architecture Note
22
+ *
23
+ * Stats are on SpanBufferClass.stats (static property), NOT on LogBinding.
24
+ * This reduces per-instance memory and avoids sync bugs from having two stat objects.
25
+ */
1
26
  //#region smoo/lmao!n/buffer-tuning-capacity
2
27
  /** Minimum spans needed before tuning decisions */
3
28
  const MIN_SPANS_FOR_TUNING = 10;
@@ -64,3 +89,4 @@ export function shouldTuneCapacity(stats) {
64
89
  resetStats(stats);
65
90
  }
66
91
  }
92
+ //#endregion smoo/lmao!n/buffer-tuning-capacity
@@ -34,8 +34,8 @@ export function cleanupDebugActiveHandles(label) {
34
34
  if (typeof handle !== 'object' || handle === null) {
35
35
  return typeof handle;
36
36
  }
37
- const constructor = Reflect.get(handle, 'constructor');
38
- const name = typeof constructor === 'function' ? Reflect.get(constructor, 'name') : undefined;
37
+ const handleConstructor = Reflect.get(handle, 'constructor');
38
+ const name = typeof handleConstructor === 'function' ? Reflect.get(handleConstructor, 'name') : undefined;
39
39
  return typeof name === 'string' && name.length > 0 ? name : 'Object';
40
40
  });
41
41
  cleanupDebug(label, { activeHandleCount: handles.length, activeHandles: names });
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Class-split flush adapter — routes each completed root buffer's rows by delivery class.
3
+ *
4
+ * Per specs/lmao/01u_cloudflare_trace_segments.md §Delivery Classes every trace row belongs to
5
+ * exactly one class:
6
+ * - billing-grade rows go to the CollectorClient, AWAITED within the request via
7
+ * `settleBillable()` before/alongside response completion — an Err fails the billable request
8
+ * (backpressure ownership: never silently queue billing-grade rows in the isolate)
9
+ * - diagnostic rows go to the drain transport lazily, on the waitUntil-scheduled `flush()`
10
+ *
11
+ * The classifier is an injected function: the spec fixes the CLASSES, not the classification
12
+ * mechanism, so the mapping from row to class stays a seam (constructor-injected like the
13
+ * transports).
14
+ *
15
+ * Canonical request flow (01s wrapper seam):
16
+ * const settled = await tracer.settleBillable(); // before returning the response
17
+ * if (settled instanceof Err) return failBillableRequest(settled.error);
18
+ * ctx.waitUntil(tracer.flush()); // diagnostics, fire-and-forget
19
+ */
20
+ import type { OpContextBinding } from '../opContext/types.js';
21
+ import { type Result } from '../result.js';
22
+ import type { TracerOptions } from '../tracer.js';
23
+ import { ArrayQueueTracer } from '../tracers/ArrayQueueTracer.js';
24
+ import type { CollectorAck, CollectorClient, CollectorSendFailure } from './collectorClient.js';
25
+ import type { DiagnosticTransport } from './diagnosticDrain.js';
26
+ import { type TraceRow } from './traceRows.js';
27
+ export type DeliveryClass = 'billing-grade' | 'diagnostic';
28
+ /** Injected classification seam — decides which lane one row rides. */
29
+ export type DeliveryClassifier = (row: TraceRow) => DeliveryClass;
30
+ export interface ClassSplitOptions<T extends import('../schema/LogSchema.js').LogSchema = import('../schema/LogSchema.js').LogSchema> extends TracerOptions<T> {
31
+ collector: CollectorClient;
32
+ diagnostics: DiagnosticTransport;
33
+ classify: DeliveryClassifier;
34
+ /** Diagnostic-lane failure hook: emit metrics; drop is within the class's loss budget. */
35
+ onDiagnosticSendError?: (error: unknown, rows: readonly TraceRow[]) => void;
36
+ /**
37
+ * Billing rows found only at flush() time (the wrapper skipped settleBillable) whose late
38
+ * awaited send failed. This is a broken-integration alarm — page on it; the rows are lost to
39
+ * this isolate and only replay/reconciliation (01u §Zero-Loss Sources) can heal the gap.
40
+ */
41
+ onLateBillableSendFailure?: (failure: CollectorSendFailure, rows: readonly TraceRow[]) => void;
42
+ }
43
+ /**
44
+ * Tracer tying the two lanes together over onTraceEnd (queue) + settleBillable/flush (drain).
45
+ *
46
+ * Diagnostic rows discovered during settleBillable are held for the same request's flush() —
47
+ * request-scoped staging only, never cross-request accumulation of billing-grade data.
48
+ */
49
+ export declare class ClassSplitTracer<B extends OpContextBinding = OpContextBinding> extends ArrayQueueTracer<B> {
50
+ private readonly collector;
51
+ private readonly diagnostics;
52
+ private readonly classify;
53
+ private readonly onDiagnosticSendError;
54
+ private readonly onLateBillableSendFailure;
55
+ private pendingDiagnosticRows;
56
+ constructor(binding: B, options: ClassSplitOptions<B['logBinding']['logSchema']>);
57
+ private partitionDrained;
58
+ /**
59
+ * Drain completed traces and durably deliver the billing-grade rows — awaited within the
60
+ * request. Ok(null) means no billing rows were produced; Err means the collector could not
61
+ * make the revenue records durable and the billable request must fail. Diagnostic rows are
62
+ * staged for this request's flush().
63
+ */
64
+ settleBillable(): Promise<Result<CollectorAck | null, CollectorSendFailure>>;
65
+ /**
66
+ * Lazy, waitUntil-schedulable drain: never rejects. Diagnostic rows (staged + newly drained)
67
+ * go to the drain transport; failures hit onDiagnosticSendError per the class's loss budget.
68
+ * Billing rows found here mean settleBillable was skipped — they are still sent awaited (never
69
+ * silently dropped or left buffered), with failures escalated via onLateBillableSendFailure.
70
+ */
71
+ flush(): Promise<void>;
72
+ }
73
+ //# sourceMappingURL=classSplit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classSplit.d.ts","sourceRoot":"","sources":["../../../src/lib/cloudflare/classSplit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEtE,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,YAAY,CAAC;AAE3D,uEAAuE;AACvE,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,QAAQ,KAAK,aAAa,CAAC;AAKlE,MAAM,WAAW,iBAAiB,CAChC,CAAC,SAAS,OAAO,wBAAwB,EAAE,SAAS,GAAG,OAAO,wBAAwB,EAAE,SAAS,CACjG,SAAQ,aAAa,CAAC,CAAC,CAAC;IACxB,SAAS,EAAE,eAAe,CAAC;IAC3B,WAAW,EAAE,mBAAmB,CAAC;IACjC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,0FAA0F;IAC1F,qBAAqB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,QAAQ,EAAE,KAAK,IAAI,CAAC;IAC5E;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,SAAS,QAAQ,EAAE,KAAK,IAAI,CAAC;CAChG;AAOD;;;;;GAKG;AACH,qBAAa,gBAAgB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IACtG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAoE;IAC1G,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAE5B;IACd,OAAO,CAAC,qBAAqB,CAAkB;IAE/C,YAAY,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,EAO/E;IAED,OAAO,CAAC,gBAAgB;IAiBxB;;;;;OAKG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,EAAE,oBAAoB,CAAC,CAAC,CAKjF;IAED;;;;;OAKG;IACY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBpC;CACF"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Class-split flush adapter — routes each completed root buffer's rows by delivery class.
3
+ *
4
+ * Per specs/lmao/01u_cloudflare_trace_segments.md §Delivery Classes every trace row belongs to
5
+ * exactly one class:
6
+ * - billing-grade rows go to the CollectorClient, AWAITED within the request via
7
+ * `settleBillable()` before/alongside response completion — an Err fails the billable request
8
+ * (backpressure ownership: never silently queue billing-grade rows in the isolate)
9
+ * - diagnostic rows go to the drain transport lazily, on the waitUntil-scheduled `flush()`
10
+ *
11
+ * The classifier is an injected function: the spec fixes the CLASSES, not the classification
12
+ * mechanism, so the mapping from row to class stays a seam (constructor-injected like the
13
+ * transports).
14
+ *
15
+ * Canonical request flow (01s wrapper seam):
16
+ * const settled = await tracer.settleBillable(); // before returning the response
17
+ * if (settled instanceof Err) return failBillableRequest(settled.error);
18
+ * ctx.waitUntil(tracer.flush()); // diagnostics, fire-and-forget
19
+ */
20
+ import { Err, Ok } from '../result.js';
21
+ import { ArrayQueueTracer } from '../tracers/ArrayQueueTracer.js';
22
+ import { spanBufferToTraceRows } from './traceRows.js';
23
+ /** Singleton for the common "nothing billable in this request" settle outcome. */
24
+ const SETTLED_NOTHING_BILLABLE = new Ok(null);
25
+ /**
26
+ * Tracer tying the two lanes together over onTraceEnd (queue) + settleBillable/flush (drain).
27
+ *
28
+ * Diagnostic rows discovered during settleBillable are held for the same request's flush() —
29
+ * request-scoped staging only, never cross-request accumulation of billing-grade data.
30
+ */
31
+ export class ClassSplitTracer extends ArrayQueueTracer {
32
+ collector;
33
+ diagnostics;
34
+ classify;
35
+ onDiagnosticSendError;
36
+ onLateBillableSendFailure;
37
+ pendingDiagnosticRows = [];
38
+ constructor(binding, options) {
39
+ super(binding, options);
40
+ this.collector = options.collector;
41
+ this.diagnostics = options.diagnostics;
42
+ this.classify = options.classify;
43
+ this.onDiagnosticSendError = options.onDiagnosticSendError;
44
+ this.onLateBillableSendFailure = options.onLateBillableSendFailure;
45
+ }
46
+ partitionDrained() {
47
+ const billing = [];
48
+ const diagnostic = [];
49
+ for (const buffer of this.drain()) {
50
+ let rows;
51
+ try {
52
+ rows = spanBufferToTraceRows(buffer);
53
+ }
54
+ finally {
55
+ this.bufferStrategy.releaseBuffer(buffer);
56
+ }
57
+ for (const row of rows) {
58
+ (this.classify(row) === 'billing-grade' ? billing : diagnostic).push(row);
59
+ }
60
+ }
61
+ return { billing, diagnostic };
62
+ }
63
+ /**
64
+ * Drain completed traces and durably deliver the billing-grade rows — awaited within the
65
+ * request. Ok(null) means no billing rows were produced; Err means the collector could not
66
+ * make the revenue records durable and the billable request must fail. Diagnostic rows are
67
+ * staged for this request's flush().
68
+ */
69
+ async settleBillable() {
70
+ const { billing, diagnostic } = this.partitionDrained();
71
+ this.pendingDiagnosticRows.push(...diagnostic);
72
+ if (billing.length === 0)
73
+ return SETTLED_NOTHING_BILLABLE;
74
+ return this.collector.send(billing);
75
+ }
76
+ /**
77
+ * Lazy, waitUntil-schedulable drain: never rejects. Diagnostic rows (staged + newly drained)
78
+ * go to the drain transport; failures hit onDiagnosticSendError per the class's loss budget.
79
+ * Billing rows found here mean settleBillable was skipped — they are still sent awaited (never
80
+ * silently dropped or left buffered), with failures escalated via onLateBillableSendFailure.
81
+ */
82
+ async flush() {
83
+ const { billing, diagnostic } = this.partitionDrained();
84
+ const diagnosticRows = this.pendingDiagnosticRows.concat(diagnostic);
85
+ this.pendingDiagnosticRows = [];
86
+ if (billing.length > 0) {
87
+ const result = await this.collector.send(billing);
88
+ if (result instanceof Err) {
89
+ this.onLateBillableSendFailure?.(result.error, billing);
90
+ }
91
+ }
92
+ if (diagnosticRows.length > 0) {
93
+ try {
94
+ await this.diagnostics.send(diagnosticRows);
95
+ }
96
+ catch (error) {
97
+ this.onDiagnosticSendError?.(error, diagnosticRows);
98
+ }
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Billing-grade collector client.
3
+ *
4
+ * Per specs/lmao/01u_cloudflare_trace_segments.md §Delivery Classes / §Zero-Loss Sources:
5
+ * `send(rows)` resolves Ok only when the collector has ACKED — and the ack means the collector
6
+ * DO's transactional-storage commit completed, which IS the durability point. From that moment
7
+ * the rows are durable and replay-owned.
8
+ *
9
+ * Send-before-response contract: the caller awaits `send` within the request; an Err fails the
10
+ * billable request (same principle as any payment-gateway outage). Implementations and callers
11
+ * must NEVER buffer billing-grade rows in the isolate across requests — an isolate eviction
12
+ * between requests silently destroys revenue records.
13
+ *
14
+ * The collector DO itself is not deployed yet; this module ships the interface plus an in-memory
15
+ * fake with ack/fail/latency injection so lane composition is testable today.
16
+ */
17
+ import { type Result } from '../result.js';
18
+ import type { TraceRow } from './traceRows.js';
19
+ /** Proof of collector durability: the DO transactional-storage commit completed. */
20
+ export interface CollectorAck {
21
+ readonly durable: true;
22
+ }
23
+ /** Singleton ack — the ack carries no data, so never allocate it per send. */
24
+ export declare const COLLECTOR_ACK: CollectorAck;
25
+ /** Operational send failure — the caller must fail the billable request on this. */
26
+ export interface CollectorSendFailure {
27
+ readonly code: 'collector-unavailable' | 'collector-rejected';
28
+ readonly message: string;
29
+ }
30
+ /**
31
+ * Transport to the billing-grade collector shard.
32
+ *
33
+ * `send` resolves Ok(CollectorAck) only after the collector's DO transactional-storage commit;
34
+ * operational failures come back as Err (never throw) so the request path can fail deliberately.
35
+ */
36
+ export interface CollectorClient {
37
+ send(rows: readonly TraceRow[]): Promise<Result<CollectorAck, CollectorSendFailure>>;
38
+ }
39
+ /**
40
+ * In-memory CollectorClient fake with ack/fail/latency injection.
41
+ *
42
+ * Modes:
43
+ * - default: every send acks immediately (after optional injected latency)
44
+ * - `failNext(failure)`: queue an Err for upcoming sends
45
+ * - `holdSends()`: sends stay pending until the test calls `ackNext()`/`rejectNext()` — this is
46
+ * how contract tests prove "resolves only when the collector acks"
47
+ */
48
+ export declare class FakeCollectorClient implements CollectorClient {
49
+ /** Row batches the fake has durably acked, in ack order. */
50
+ readonly acked: (readonly TraceRow[])[];
51
+ private readonly failures;
52
+ private readonly held;
53
+ private holding;
54
+ private latencyMs;
55
+ /** Queue an Err result for the next send (FIFO across multiple calls). */
56
+ failNext(failure: CollectorSendFailure): void;
57
+ /** Inject artificial ack latency for subsequent sends. */
58
+ setLatency(ms: number): void;
59
+ /** Switch to manual mode: sends stay pending until ackNext()/rejectNext(). */
60
+ holdSends(): void;
61
+ /** Number of sends currently awaiting a manual ack. */
62
+ get pendingCount(): number;
63
+ /** Ack the oldest held send (DO commit happened). */
64
+ ackNext(): void;
65
+ /** Fail the oldest held send with an operational failure. */
66
+ rejectNext(failure: CollectorSendFailure): void;
67
+ send(rows: readonly TraceRow[]): Promise<Result<CollectorAck, CollectorSendFailure>>;
68
+ }
69
+ //# sourceMappingURL=collectorClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collectorClient.d.ts","sourceRoot":"","sources":["../../../src/lib/cloudflare/collectorClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;CACxB;AAED,8EAA8E;AAC9E,eAAO,MAAM,aAAa,EAAE,YAAgC,CAAC;AAE7D,oFAAoF;AACpF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,GAAG,oBAAoB,CAAC;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC,CAAC;CACtF;AAOD;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,CAAC,SAAS,QAAQ,EAAE,CAAC,EAAE,CAAM;IAE7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkB;IACvC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAK;IAEtB,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAE5C;IAED,0DAA0D;IAC1D,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE3B;IAED,8EAA8E;IAC9E,SAAS,IAAI,IAAI,CAEhB;IAED,uDAAuD;IACvD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,qDAAqD;IACrD,OAAO,IAAI,IAAI,CAKd;IAED,6DAA6D;IAC7D,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAI9C;IAEK,IAAI,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC,CAazF;CACF"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Billing-grade collector client.
3
+ *
4
+ * Per specs/lmao/01u_cloudflare_trace_segments.md §Delivery Classes / §Zero-Loss Sources:
5
+ * `send(rows)` resolves Ok only when the collector has ACKED — and the ack means the collector
6
+ * DO's transactional-storage commit completed, which IS the durability point. From that moment
7
+ * the rows are durable and replay-owned.
8
+ *
9
+ * Send-before-response contract: the caller awaits `send` within the request; an Err fails the
10
+ * billable request (same principle as any payment-gateway outage). Implementations and callers
11
+ * must NEVER buffer billing-grade rows in the isolate across requests — an isolate eviction
12
+ * between requests silently destroys revenue records.
13
+ *
14
+ * The collector DO itself is not deployed yet; this module ships the interface plus an in-memory
15
+ * fake with ack/fail/latency injection so lane composition is testable today.
16
+ */
17
+ import { Err, Ok } from '../result.js';
18
+ /** Singleton ack — the ack carries no data, so never allocate it per send. */
19
+ export const COLLECTOR_ACK = { durable: true };
20
+ /**
21
+ * In-memory CollectorClient fake with ack/fail/latency injection.
22
+ *
23
+ * Modes:
24
+ * - default: every send acks immediately (after optional injected latency)
25
+ * - `failNext(failure)`: queue an Err for upcoming sends
26
+ * - `holdSends()`: sends stay pending until the test calls `ackNext()`/`rejectNext()` — this is
27
+ * how contract tests prove "resolves only when the collector acks"
28
+ */
29
+ export class FakeCollectorClient {
30
+ /** Row batches the fake has durably acked, in ack order. */
31
+ acked = [];
32
+ failures = [];
33
+ held = [];
34
+ holding = false;
35
+ latencyMs = 0;
36
+ /** Queue an Err result for the next send (FIFO across multiple calls). */
37
+ failNext(failure) {
38
+ this.failures.push(failure);
39
+ }
40
+ /** Inject artificial ack latency for subsequent sends. */
41
+ setLatency(ms) {
42
+ this.latencyMs = ms;
43
+ }
44
+ /** Switch to manual mode: sends stay pending until ackNext()/rejectNext(). */
45
+ holdSends() {
46
+ this.holding = true;
47
+ }
48
+ /** Number of sends currently awaiting a manual ack. */
49
+ get pendingCount() {
50
+ return this.held.length;
51
+ }
52
+ /** Ack the oldest held send (DO commit happened). */
53
+ ackNext() {
54
+ const pending = this.held.shift();
55
+ if (!pending)
56
+ throw new Error('FakeCollectorClient.ackNext: no held send');
57
+ this.acked.push(pending.rows);
58
+ pending.resolve(new Ok(COLLECTOR_ACK));
59
+ }
60
+ /** Fail the oldest held send with an operational failure. */
61
+ rejectNext(failure) {
62
+ const pending = this.held.shift();
63
+ if (!pending)
64
+ throw new Error('FakeCollectorClient.rejectNext: no held send');
65
+ pending.resolve(new Err(failure));
66
+ }
67
+ async send(rows) {
68
+ if (this.latencyMs > 0) {
69
+ await new Promise((resolve) => setTimeout(resolve, this.latencyMs));
70
+ }
71
+ if (this.holding) {
72
+ return new Promise((resolve) => {
73
+ this.held.push({ rows, resolve });
74
+ });
75
+ }
76
+ const failure = this.failures.shift();
77
+ if (failure)
78
+ return new Err(failure);
79
+ this.acked.push(rows);
80
+ return new Ok(COLLECTOR_ACK);
81
+ }
82
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Diagnostic-class drain adapter.
3
+ *
4
+ * Per specs/lmao/01u_cloudflare_trace_segments.md §LMAO Sink Fit: no new abstraction — the base
5
+ * Tracer lifecycle (onTraceEnd queueing + flush) already models this. The drain tracer extends
6
+ * ArrayQueueTracer; flush() drains completed root buffers, flattens them to rows, and hands them
7
+ * to a constructor-injected transport.
8
+ *
9
+ * Transports (per 01u §Collection Lanes and Fallbacks):
10
+ * - primary: a Pipelines-stream-binding-shaped send fn (`env.TRACE_STREAM.send(rows)`) — rows,
11
+ * because Pipelines owns batching and Parquet encoding for the raw tier
12
+ * - fallback: Cloudflare Queues — batched TraceChunkEnvelope messages built from the existing
13
+ * lib/archive primitives (chunk_id idempotency); NEVER per-span messages (128 KB messages,
14
+ * per-64 KB op billing make per-span ~160x more expensive)
15
+ *
16
+ * Delivery is fire-and-forget: flush() is scheduled via ctx.waitUntil and never rejects; enqueue
17
+ * failures surface through the onSendError hook (01s §Failure Handling — emit metrics, rely on
18
+ * queue policy/backoff), they never block.
19
+ */
20
+ import { type TraceChunkEnvelope } from '../archive/chunkEnvelope.js';
21
+ import type { OpContextBinding } from '../opContext/types.js';
22
+ import type { TracerOptions } from '../tracer.js';
23
+ import { ArrayQueueTracer } from '../tracers/ArrayQueueTracer.js';
24
+ import { type TraceRow } from './traceRows.js';
25
+ /** Shape of a Cloudflare Pipelines stream binding's send — promise resolves on confirmed ingest. */
26
+ export type PipelinesStreamSend = (rows: TraceRow[]) => Promise<void>;
27
+ /** Diagnostic-lane transport seam: delivers one drained batch of rows, at most best-effort. */
28
+ export interface DiagnosticTransport {
29
+ send(rows: readonly TraceRow[]): Promise<void>;
30
+ }
31
+ /** Primary diagnostic transport: rows straight into the injected Pipelines stream binding. */
32
+ export declare class PipelinesStreamTransport implements DiagnosticTransport {
33
+ private readonly sendToStream;
34
+ constructor(sendToStream: PipelinesStreamSend);
35
+ send(rows: readonly TraceRow[]): Promise<void>;
36
+ }
37
+ /** One Queues-fallback message: chunk envelope (idempotency + routing metadata) plus its rows. */
38
+ export interface TraceChunkQueueMessage {
39
+ readonly envelope: TraceChunkEnvelope;
40
+ readonly rows: readonly TraceRow[];
41
+ }
42
+ export interface QueuesFallbackOptions {
43
+ /** Logical file reference recorded in the envelopes, e.g. 'queue://worker-name'. */
44
+ fileRef: string;
45
+ /** Max rows per queue message — bounds message size under the 128 KB Queues limit. */
46
+ maxRowsPerMessage: number;
47
+ /** Injected queue producer, e.g. (msg) => env.TRACE_QUEUE.send(msg). */
48
+ sendMessage: (message: TraceChunkQueueMessage) => Promise<void>;
49
+ }
50
+ /**
51
+ * Queues-fallback transport: rows are batched into chunk-envelope messages.
52
+ *
53
+ * The chunk_ref is a deterministic content hash of the batch, so a retried send of the same
54
+ * batch produces the same chunk_id and the consumer's chunk_id dedup makes redelivery a no-op.
55
+ */
56
+ export declare class QueuesFallbackTransport implements DiagnosticTransport {
57
+ private readonly options;
58
+ constructor(options: QueuesFallbackOptions);
59
+ send(rows: readonly TraceRow[]): Promise<void>;
60
+ }
61
+ export interface DiagnosticDrainOptions<T extends import('../schema/LogSchema.js').LogSchema = import('../schema/LogSchema.js').LogSchema> extends TracerOptions<T> {
62
+ transport: DiagnosticTransport;
63
+ /** Failure hook (01s §Failure Handling): emit runtime metrics/alerts here; never rethrows. */
64
+ onSendError?: (error: unknown, rows: readonly TraceRow[]) => void;
65
+ }
66
+ /**
67
+ * Diagnostic-lane sink tracer: queue completed roots (ArrayQueueTracer), drain + send on flush().
68
+ *
69
+ * flush() is waitUntil-schedulable: it never rejects, and buffers are always released back to
70
+ * the strategy regardless of transport outcome.
71
+ */
72
+ export declare class DiagnosticDrainTracer<B extends OpContextBinding = OpContextBinding> extends ArrayQueueTracer<B> {
73
+ private readonly transport;
74
+ private readonly onSendError;
75
+ constructor(binding: B, options: DiagnosticDrainOptions<B['logBinding']['logSchema']>);
76
+ flush(): Promise<void>;
77
+ }
78
+ //# sourceMappingURL=diagnosticDrain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnosticDrain.d.ts","sourceRoot":"","sources":["../../../src/lib/cloudflare/diagnosticDrain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEtE,oGAAoG;AACpG,MAAM,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEtE,+FAA+F;AAC/F,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,8FAA8F;AAC9F,qBAAa,wBAAyB,YAAW,mBAAmB;IACtD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAAzC,YAA6B,YAAY,EAAE,mBAAmB,EAAI;IAElE,IAAI,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAG7C;CACF;AAED,kGAAkG;AAClG,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,WAAW,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjE;AAwBD;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAApC,YAA6B,OAAO,EAAE,qBAAqB,EAI1D;IAEK,IAAI,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAcnD;CACF;AAED,MAAM,WAAW,sBAAsB,CACrC,CAAC,SAAS,OAAO,wBAAwB,EAAE,SAAS,GAAG,OAAO,wBAAwB,EAAE,SAAS,CACjG,SAAQ,aAAa,CAAC,CAAC,CAAC;IACxB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,8FAA8F;IAC9F,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,QAAQ,EAAE,KAAK,IAAI,CAAC;CACnE;AAED;;;;;GAKG;AACH,qBAAa,qBAAqB,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC3G,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoE;IAEhG,YAAY,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,CAAC,EAIpF;IAEc,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAepC;CACF"}