@smoothbricks/lmao 0.1.3 → 0.2.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.
Files changed (181) hide show
  1. package/dist/allocator.wasm +0 -0
  2. package/dist/cloudflare.d.ts +15 -0
  3. package/dist/cloudflare.d.ts.map +1 -0
  4. package/dist/cloudflare.js +14 -0
  5. package/dist/es.d.ts.map +1 -1
  6. package/dist/es.js +1 -0
  7. package/dist/lib/archive/chunkCompaction.d.ts.map +1 -1
  8. package/dist/lib/archive/chunkCompaction.js +2 -0
  9. package/dist/lib/archive/chunkEnvelope.d.ts.map +1 -1
  10. package/dist/lib/archive/chunkRouting.d.ts.map +1 -1
  11. package/dist/lib/archive/chunkRouting.js +3 -0
  12. package/dist/lib/archive/chunkStats.d.ts.map +1 -1
  13. package/dist/lib/archive/chunkStats.js +1 -0
  14. package/dist/lib/arrow/capacityStats.d.ts.map +1 -1
  15. package/dist/lib/arrow/capacityStats.js +1 -0
  16. package/dist/lib/bufferStrategy.d.ts.map +1 -1
  17. package/dist/lib/capacityTuning.d.ts.map +1 -1
  18. package/dist/lib/capacityTuning.js +1 -0
  19. package/dist/lib/cloudflare/classSplit.d.ts +73 -0
  20. package/dist/lib/cloudflare/classSplit.d.ts.map +1 -0
  21. package/dist/lib/cloudflare/classSplit.js +82 -0
  22. package/dist/lib/cloudflare/collectorClient.d.ts +69 -0
  23. package/dist/lib/cloudflare/collectorClient.d.ts.map +1 -0
  24. package/dist/lib/cloudflare/collectorClient.js +82 -0
  25. package/dist/lib/cloudflare/diagnosticDrain.d.ts +78 -0
  26. package/dist/lib/cloudflare/diagnosticDrain.d.ts.map +1 -0
  27. package/dist/lib/cloudflare/diagnosticDrain.js +120 -0
  28. package/dist/lib/cloudflare/traceRows.d.ts +19 -0
  29. package/dist/lib/cloudflare/traceRows.d.ts.map +1 -0
  30. package/dist/lib/cloudflare/traceRows.js +51 -0
  31. package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
  32. package/dist/lib/codegen/evaluatorGenerator.js +1 -0
  33. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +8 -0
  34. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
  35. package/dist/lib/codegen/fixedPositionWriterGenerator.js +18 -1
  36. package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
  37. package/dist/lib/codegen/spanLoggerGenerator.js +3 -0
  38. package/dist/lib/convertToArrow.d.ts.map +1 -1
  39. package/dist/lib/convertToArrow.js +6 -0
  40. package/dist/lib/defineOpContext.d.ts +5 -0
  41. package/dist/lib/defineOpContext.d.ts.map +1 -1
  42. package/dist/lib/defineOpContext.js +11 -1
  43. package/dist/lib/errors/Blocked.d.ts.map +1 -1
  44. package/dist/lib/errors/Transient.d.ts.map +1 -1
  45. package/dist/lib/errors/retry-policy.d.ts.map +1 -1
  46. package/dist/lib/flushScheduler.d.ts.map +1 -1
  47. package/dist/lib/flushScheduler.js +2 -0
  48. package/dist/lib/library.d.ts +5 -0
  49. package/dist/lib/library.d.ts.map +1 -1
  50. package/dist/lib/library.js +6 -0
  51. package/dist/lib/op.d.ts.map +1 -1
  52. package/dist/lib/op.js +2 -0
  53. package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
  54. package/dist/lib/opContext/createOpGroup.js +5 -0
  55. package/dist/lib/opContext/defineOp.d.ts.map +1 -1
  56. package/dist/lib/opContext/defineOp.js +5 -0
  57. package/dist/lib/result.d.ts.map +1 -1
  58. package/dist/lib/result.js +3 -0
  59. package/dist/lib/schema/builder.d.ts.map +1 -1
  60. package/dist/lib/schema/builder.js +1 -0
  61. package/dist/lib/schema/defineFeatureFlags.d.ts.map +1 -1
  62. package/dist/lib/schema/defineLogSchema.d.ts.map +1 -1
  63. package/dist/lib/schema/defineLogSchema.js +1 -0
  64. package/dist/lib/schema/evaluator.d.ts.map +1 -1
  65. package/dist/lib/schema/systemSchema.d.ts.map +1 -1
  66. package/dist/lib/schema/systemSchema.js +1 -0
  67. package/dist/lib/spanBuffer.d.ts.map +1 -1
  68. package/dist/lib/spanBuffer.js +8 -0
  69. package/dist/lib/spanBufferHelpers.d.ts.map +1 -1
  70. package/dist/lib/spanBufferHelpers.js +1 -0
  71. package/dist/lib/spanBufferStats.d.ts.map +1 -1
  72. package/dist/lib/spanContext.d.ts +8 -0
  73. package/dist/lib/spanContext.d.ts.map +1 -1
  74. package/dist/lib/spanContext.js +35 -0
  75. package/dist/lib/sqlite/index.d.ts +1 -0
  76. package/dist/lib/sqlite/index.d.ts.map +1 -1
  77. package/dist/lib/sqlite/sqlite-common.d.ts +2 -0
  78. package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
  79. package/dist/lib/sqlite/sqlite-common.js +9 -1
  80. package/dist/lib/threadId.d.ts.map +1 -1
  81. package/dist/lib/threadId.js +2 -0
  82. package/dist/lib/traceId.d.ts.map +1 -1
  83. package/dist/lib/traceId.js +1 -0
  84. package/dist/lib/traceRoot.d.ts +5 -5
  85. package/dist/lib/traceRoot.d.ts.map +1 -1
  86. package/dist/lib/traceRoot.es.d.ts.map +1 -1
  87. package/dist/lib/traceRoot.es.js +3 -0
  88. package/dist/lib/traceRoot.js +3 -1
  89. package/dist/lib/traceRoot.node.d.ts +2 -2
  90. package/dist/lib/traceRoot.node.d.ts.map +1 -1
  91. package/dist/lib/traceRoot.node.js +4 -3
  92. package/dist/lib/tracer.d.ts.map +1 -1
  93. package/dist/lib/tracer.js +2 -0
  94. package/dist/lib/tracers/ArrayQueueTracer.d.ts.map +1 -1
  95. package/dist/lib/tracers/CompositeTracer.d.ts.map +1 -1
  96. package/dist/lib/tracers/CompositeTracer.js +1 -0
  97. package/dist/lib/tracers/NoOpTracer.d.ts.map +1 -1
  98. package/dist/lib/tracers/NoOpTracer.js +1 -0
  99. package/dist/lib/tracers/SQLiteTracer.d.ts.map +1 -1
  100. package/dist/lib/tracers/SQLiteTracer.js +2 -0
  101. package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
  102. package/dist/lib/tracers/StdioTracer.js +1 -0
  103. package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
  104. package/dist/lib/tracers/TestTracer.js +1 -0
  105. package/dist/lib/types.d.ts.map +1 -1
  106. package/dist/lib/utf8Cache.d.ts.map +1 -1
  107. package/dist/lib/utf8Cache.js +1 -0
  108. package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
  109. package/dist/lib/wasm/WasmBufferStrategy.js +2 -0
  110. package/dist/lib/wasm/wasmAllocator.d.ts +2 -0
  111. package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
  112. package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
  113. package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
  114. package/dist/node.d.ts.map +1 -1
  115. package/dist/node.js +1 -0
  116. package/package.json +10 -4
  117. package/src/cloudflare.ts +35 -0
  118. package/src/es.ts +2 -0
  119. package/src/lib/archive/chunkCompaction.ts +2 -0
  120. package/src/lib/archive/chunkEnvelope.ts +2 -0
  121. package/src/lib/archive/chunkRouting.ts +4 -0
  122. package/src/lib/archive/chunkStats.ts +2 -0
  123. package/src/lib/arrow/capacityStats.ts +2 -0
  124. package/src/lib/bufferStrategy.ts +2 -0
  125. package/src/lib/capacityTuning.ts +2 -0
  126. package/src/lib/cloudflare/__tests__/classSplit.test.ts +171 -0
  127. package/src/lib/cloudflare/__tests__/collectorClient.test.ts +104 -0
  128. package/src/lib/cloudflare/__tests__/diagnosticDrain.test.ts +165 -0
  129. package/src/lib/cloudflare/classSplit.ts +139 -0
  130. package/src/lib/cloudflare/collectorClient.ts +117 -0
  131. package/src/lib/cloudflare/diagnosticDrain.ts +152 -0
  132. package/src/lib/cloudflare/traceRows.ts +60 -0
  133. package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +304 -0
  134. package/src/lib/codegen/evaluatorGenerator.ts +2 -0
  135. package/src/lib/codegen/fixedPositionWriterGenerator.ts +28 -1
  136. package/src/lib/codegen/spanLoggerGenerator.ts +4 -0
  137. package/src/lib/convertToArrow.ts +6 -0
  138. package/src/lib/defineOpContext.ts +17 -1
  139. package/src/lib/errors/Blocked.ts +2 -0
  140. package/src/lib/errors/Transient.ts +2 -0
  141. package/src/lib/errors/retry-policy.ts +2 -0
  142. package/src/lib/flushScheduler.ts +2 -0
  143. package/src/lib/library.ts +7 -0
  144. package/src/lib/op.ts +8 -0
  145. package/src/lib/opContext/createOpGroup.ts +6 -0
  146. package/src/lib/opContext/defineOp.ts +6 -0
  147. package/src/lib/result.ts +4 -0
  148. package/src/lib/schema/builder.ts +2 -0
  149. package/src/lib/schema/defineFeatureFlags.ts +2 -0
  150. package/src/lib/schema/defineLogSchema.ts +2 -0
  151. package/src/lib/schema/evaluator.ts +2 -0
  152. package/src/lib/schema/systemSchema.ts +2 -0
  153. package/src/lib/spanBuffer.ts +10 -0
  154. package/src/lib/spanBufferHelpers.ts +2 -0
  155. package/src/lib/spanBufferStats.ts +2 -0
  156. package/src/lib/spanContext.ts +48 -1
  157. package/src/lib/sqlite/__tests__/sqlite-common.test.ts +40 -1
  158. package/src/lib/sqlite/index.ts +1 -0
  159. package/src/lib/sqlite/sqlite-common.ts +10 -1
  160. package/src/lib/testing/__tests__/facts.test.ts +6 -6
  161. package/src/lib/threadId.ts +2 -0
  162. package/src/lib/traceId.ts +4 -0
  163. package/src/lib/traceRoot.es.ts +4 -0
  164. package/src/lib/traceRoot.node.ts +5 -3
  165. package/src/lib/traceRoot.ts +9 -5
  166. package/src/lib/tracer.ts +4 -0
  167. package/src/lib/tracers/ArrayQueueTracer.ts +2 -0
  168. package/src/lib/tracers/CompositeTracer.ts +2 -0
  169. package/src/lib/tracers/NoOpTracer.ts +2 -0
  170. package/src/lib/tracers/SQLiteTracer.ts +2 -0
  171. package/src/lib/tracers/StdioTracer.ts +2 -0
  172. package/src/lib/tracers/TestTracer.ts +2 -0
  173. package/src/lib/types.ts +2 -0
  174. package/src/lib/utf8Cache.ts +2 -0
  175. package/src/lib/wasm/WasmBufferStrategy.ts +4 -0
  176. package/src/lib/wasm/allocator.zig +4 -1
  177. package/src/lib/wasm/wasmAllocator.ts +5 -0
  178. package/src/lib/wasm/wasmSpanBuffer.ts +4 -0
  179. package/src/lib/wasm/wasmTraceRoot.ts +4 -0
  180. package/src/node.ts +2 -0
  181. package/src/lib/codegen/__tests__/__snapshots__/spanLoggerGenerator.test.ts.snap +0 -1965
@@ -250,9 +250,15 @@ function buildOpContextFactory<
250
250
  };
251
251
  }
252
252
 
253
+ //#region smoo/lmao!n/opcontext-definition
253
254
  /**
254
255
  * Define an Op context factory
255
256
  *
257
+ * 01j "Module Definition", renamed: this is the shipped entry point (defineOpContext,
258
+ * not defineModule().ctx().make()). Returns { defineOp, defineOps }; user context is the
259
+ * `ctx` config field (runtime defaults, reserved-key-guarded — see the nested
260
+ * n/schema-env-config region), deps carry their own prefix, and per-Op attribution is OpMetadata.
261
+ *
256
262
  * Creates a factory for defining Ops that share the same schema, deps, and context.
257
263
  * This is the main entry point for the Op-centric API.
258
264
  *
@@ -334,7 +340,14 @@ export function defineOpContext<
334
340
  Deps extends DepsConfig = Record<string, never>,
335
341
  UserCtx extends Record<string, unknown> = Record<string, never>,
336
342
  >(config: OpContextConfig<T, FF, Deps, UserCtx>) {
337
- // Runtime validation: check for reserved property names in user context
343
+ //#region smoo/lmao!n/schema-env-config
344
+ // Runtime validation: check for reserved property names in user context.
345
+ // The `ctx` config object is the env/deployment-config surface from
346
+ // 01a "Environment Variable Configuration" — a plain user object (env, services,
347
+ // requestId, ...) spread into SpanContext, guarded only against reserved/internal keys.
348
+ //#region smoo/lmao!n/schema-env-config.reserved
349
+ // 01l "Reserved Names": ctx keys cannot collide with built-in SpanContext members
350
+ // (buffer/tag/log/scope/setScope/ok/err/span/ff/deps) or start with `_` (internal).
338
351
  if (config.ctx) {
339
352
  const userKeys = Object.keys(config.ctx);
340
353
  for (const key of userKeys) {
@@ -350,6 +363,8 @@ export function defineOpContext<
350
363
  }
351
364
  }
352
365
  }
366
+ //#endregion smoo/lmao!n/schema-env-config.reserved
367
+ //#endregion smoo/lmao!n/schema-env-config
353
368
 
354
369
  // Compute effective schema by combining app schema with dep contributions.
355
370
  // This merges app fields + all dep contributed fields (after prefix/mapping).
@@ -387,6 +402,7 @@ export function defineOpContext<
387
402
 
388
403
  return buildOpContextFactory(effectiveFields, config.flags, config.deps, config.ctx);
389
404
  }
405
+ //#endregion smoo/lmao!n/opcontext-definition
390
406
 
391
407
  // Re-export everything from opContext for convenience
392
408
  export * from './opContext/index.js';
@@ -53,6 +53,7 @@
53
53
 
54
54
  import type { TaggedError } from '../result.js';
55
55
 
56
+ //#region smoo/lmao!n/op-context-tagged-errors.blocked
56
57
  /**
57
58
  * Reason why an Op is blocked.
58
59
  */
@@ -163,3 +164,4 @@ export class Blocked extends Error implements TaggedError<'Blocked'> {
163
164
  };
164
165
  }
165
166
  }
167
+ //#endregion smoo/lmao!n/op-context-tagged-errors.blocked
@@ -1,3 +1,4 @@
1
+ //#region smoo/lmao!n/op-retry.transient
1
2
  /**
2
3
  * TransientError - typed transient error codes with embedded retry policy.
3
4
  *
@@ -166,3 +167,4 @@ function isRetryPolicyLike(value: unknown): value is Partial<RetryPolicy> {
166
167
 
167
168
  // Re-export policy helpers for convenience
168
169
  export { exponentialBackoff, fixedDelay, linearBackoff, mergePolicy, type RetryPolicy } from './retry-policy.js';
170
+ //#endregion smoo/lmao!n/op-retry.transient
@@ -1,3 +1,4 @@
1
+ //#region smoo/lmao!n/op-retry.policy
1
2
  /**
2
3
  * RetryPolicy - configures retry behavior for transient failures.
3
4
  *
@@ -85,3 +86,4 @@ export function mergePolicy(base: RetryPolicy, override?: Partial<RetryPolicy>):
85
86
  if (!override) return base;
86
87
  return { ...base, ...override };
87
88
  }
89
+ //#endregion smoo/lmao!n/op-retry.policy
@@ -120,6 +120,7 @@ export interface FlushSchedulerConfig {
120
120
  * Background flush scheduler
121
121
  * Manages automatic flushing of span buffers to Arrow tables
122
122
  */
123
+ //#region smoo/lmao!n/buffer-tuning-flush
123
124
  export class FlushScheduler {
124
125
  private config: Required<FlushSchedulerConfig>;
125
126
  private handler: FlushHandler;
@@ -464,6 +465,7 @@ export class FlushScheduler {
464
465
  this.lastActivityTime = Date.now();
465
466
  }
466
467
  }
468
+ //#endregion smoo/lmao!n/buffer-tuning-flush
467
469
 
468
470
  /**
469
471
  * Global flush scheduler instance (optional)
@@ -71,10 +71,16 @@ function isRemappedSpanLoggerClass<T extends LogSchema>(value: unknown): value i
71
71
  );
72
72
  }
73
73
 
74
+ //#region smoo/lmao!n/codegen-prefixed-remap
74
75
  /**
75
76
  * Prefix a tag attribute schema
76
77
  * Renames all fields with a prefix to avoid conflicts
77
78
  *
79
+ * 01j "Library Compilation (Prefixed)": a library defines clean field names
80
+ * (status, method); the consumer applies a prefix (http) at wire time. This block
81
+ * generates the prefixed schema, the clean->prefixed mapping, and the RemappedSpanLogger /
82
+ * RemappedBufferView classes whose clean methods write to prefixed columns.
83
+ *
78
84
  * Example:
79
85
  * - Input: { status: S.number(), method: S.enum(['GET', 'POST']) }
80
86
  * - Prefix: 'http'
@@ -680,3 +686,4 @@ export function createRemappedSpanLoggerClass<T extends LogSchema>(
680
686
 
681
687
  return GeneratedClass;
682
688
  }
689
+ //#endregion smoo/lmao!n/codegen-prefixed-remap
package/src/lib/op.ts CHANGED
@@ -31,6 +31,11 @@ import type { SpanBufferConstructor } from './spanBuffer.js';
31
31
  * Includes pre-encoded UTF-8 entries for Arrow dictionary building -
32
32
  * encode once at Op definition time, reuse for every span conversion.
33
33
  */
34
+ //#region smoo/lmao!n/opcontext-hierarchy
35
+ // 01j "ModuleContext", renamed: per-Op source-attribution metadata
36
+ // (package_name/package_file/git_sha) + pre-encoded UTF-8 entries for Arrow
37
+ // dictionary building. One per defineOp; SpanBuffer/SpanContext are the other
38
+ // two levels of the 01j Context Hierarchy.
34
39
  export interface OpMetadata {
35
40
  /** Op name for metrics tracking (distinct from span names which are provided at call sites) */
36
41
  readonly name: string;
@@ -50,11 +55,13 @@ export interface OpMetadata {
50
55
  /** Pre-encoded git_sha for Arrow dictionary building */
51
56
  readonly git_sha_entry: PreEncodedEntry;
52
57
  }
58
+ //#endregion smoo/lmao!n/opcontext-hierarchy
53
59
 
54
60
  // =============================================================================
55
61
  // Op Class
56
62
  // =============================================================================
57
63
 
64
+ //#region smoo/lmao!n/op-class
58
65
  /**
59
66
  * Op - Traced operation (Phase 2 architecture)
60
67
  *
@@ -101,3 +108,4 @@ export class Op<Ctx extends OpContext, Args extends unknown[], S, E> {
101
108
  readonly _opContextBinding?: OpContextBinding,
102
109
  ) {}
103
110
  }
111
+ //#endregion smoo/lmao!n/op-class
@@ -34,6 +34,11 @@ import type {
34
34
  import { validateOpName } from './opGroupTypes.js';
35
35
  import type { OpContext } from './types.js';
36
36
 
37
+ //#region smoo/lmao!n/column-mapping-api
38
+ // 01l "Dependencies with Column Mapping" + 01e "Column Mapping API": .prefix(name) and
39
+ // .mapColumns({ col: 'new' | 'shared' | null }) are realized here. Each call clones the
40
+ // OpGroup's ops with a fresh RemappedBufferView (cold-path codegen via library.ts), so the
41
+ // hot path still writes the clean unprefixed columns; the view remaps clean->target for Arrow.
37
42
  // =============================================================================
38
43
  // INTERNAL HELPERS
39
44
  // =============================================================================
@@ -454,3 +459,4 @@ export function createOpGroup<Ctx extends OpContext, Ops extends OpGroupOps<Ctx>
454
459
  assertGroupCarriesOps<Ctx, Ops>(group, ops);
455
460
  return group;
456
461
  }
462
+ //#endregion smoo/lmao!n/column-mapping-api
@@ -14,6 +14,11 @@ import type { OpGroup, OpGroupOps } from './opGroupTypes.js';
14
14
  import type { Op, OpFn, OpMetadata, OpsFromRecord } from './opTypes.js';
15
15
  import type { OpContext } from './types.js';
16
16
 
17
+ //#region smoo/lmao!n/metadata-injection
18
+ // 01l "Metadata Injection (Transformer)": package_name/package_file/git_sha/line are the
19
+ // per-Op OpMetadata the transformer injects at the defineOpContext call site. createOpMetadata
20
+ // pre-encodes the dictionary entries (interned UTF-8); DEFAULT_METADATA is the un-injected
21
+ // placeholder; extractMetadataFromStack is the no-transformer dev fallback (parses the stack).
17
22
  // =============================================================================
18
23
  // METADATA HELPERS
19
24
  // =============================================================================
@@ -130,6 +135,7 @@ export function extractMetadataFromStack(skipFrames = 2): OpMetadata {
130
135
 
131
136
  return createOpMetadata('unknown', packageName, filePath, 'runtime', lineNumber);
132
137
  }
138
+ //#endregion smoo/lmao!n/metadata-injection
133
139
 
134
140
  // =============================================================================
135
141
  // FACTORY CONFIG
package/src/lib/result.ts CHANGED
@@ -104,6 +104,7 @@ function createCodeErrorValue<Code extends string, Fields extends object>(
104
104
  // OK CLASS
105
105
  // =============================================================================
106
106
 
107
+ //#region smoo/lmao!n/lmao-entry-fluentok
107
108
  /**
108
109
  * Success result with fluent tag application.
109
110
  *
@@ -240,11 +241,13 @@ export class Ok<V, T extends LogSchema = LogSchema> {
240
241
  return { ok: true, value: this.value };
241
242
  }
242
243
  }
244
+ //#endregion smoo/lmao!n/lmao-entry-fluentok
243
245
 
244
246
  // =============================================================================
245
247
  // ERR CLASS
246
248
  // =============================================================================
247
249
 
250
+ //#region smoo/lmao!n/lmao-entry-fluenterr
248
251
  /**
249
252
  * Error result with fluent tag application.
250
253
  *
@@ -410,6 +413,7 @@ export class Err<E, T extends LogSchema = LogSchema> {
410
413
  return { ok: false, error: this.error };
411
414
  }
412
415
  }
416
+ //#endregion smoo/lmao!n/lmao-entry-fluenterr
413
417
 
414
418
  // =============================================================================
415
419
  // RESULT TYPE
@@ -66,6 +66,7 @@ function createSchemaWithFlagBuilder<Value, TSchema extends Schema<Value>>(
66
66
  return schemaWithBuilder;
67
67
  }
68
68
 
69
+ //#region smoo/lmao!n/schema-string-types
69
70
  /**
70
71
  * Schema builder that wraps arrow-builder's S with feature flag support
71
72
  *
@@ -199,3 +200,4 @@ const schemaBuilderImpl: SchemaBuilder = {
199
200
  // Export as S for convenience
200
201
  // Note: The SchemaBuilder type is exported from types.ts
201
202
  export const S = schemaBuilderImpl;
203
+ //#endregion smoo/lmao!n/schema-string-types
@@ -1,3 +1,4 @@
1
+ //#region smoo/lmao!n/flag-flag-schema
1
2
  import type { Output } from '@smoothbricks/arrow-builder';
2
3
  import type { FeatureFlagDefinition } from './types.js';
3
4
 
@@ -89,3 +90,4 @@ export interface UsageContext {
89
90
  value?: number;
90
91
  metadata?: Record<string, string | number | boolean>;
91
92
  }
93
+ //#endregion smoo/lmao!n/flag-flag-schema
@@ -229,6 +229,7 @@ function assertValidatedObject<T extends SchemaFields>(
229
229
  }
230
230
  }
231
231
 
232
+ //#region smoo/lmao!n/schema-log-schema
232
233
  export function defineLogSchema<T extends SchemaFields>(
233
234
  schema: T,
234
235
  options?: DefineLogSchemaOptions,
@@ -289,3 +290,4 @@ export function defineLogSchema<T extends SchemaFields>(
289
290
  // Return logSchema (still a LogSchema instance with added methods)
290
291
  return result;
291
292
  }
293
+ //#endregion smoo/lmao!n/schema-log-schema
@@ -1,3 +1,4 @@
1
+ //#region smoo/lmao!n/flag-evaluator
1
2
  import type { Schema, SchemaWithMetadata } from '@smoothbricks/arrow-builder';
2
3
  import { createEvaluatorClass, type GeneratedEvaluatorInstance } from '../codegen/evaluatorGenerator.js';
3
4
  import type { FluentLogEntry } from '../codegen/spanLoggerGenerator.js';
@@ -402,3 +403,4 @@ export class InMemoryFlagEvaluator<Ctx extends OpContext = OpContext> implements
402
403
  return createFeatureFlagEvaluator(this.ffSchema, ctx, this);
403
404
  }
404
405
  }
406
+ //#endregion smoo/lmao!n/flag-evaluator
@@ -203,6 +203,7 @@ export function mergeWithSystemSchema<T extends Record<string, unknown>>(userSch
203
203
  return merged;
204
204
  }
205
205
 
206
+ //#region smoo/lmao!n/lmao-entry-entry-type-definitions
206
207
  // =============================================================================
207
208
  // Entry Type Constants
208
209
  // =============================================================================
@@ -337,3 +338,4 @@ export const ENTRY_TYPE_NAMES = [
337
338
  'buffer-spans', // 23
338
339
  'buffer-capacity', // 24
339
340
  ] as const;
341
+ //#endregion smoo/lmao!n/lmao-entry-entry-type-definitions
@@ -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
@@ -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 { buildInsertParams, parseSqliteTableInfoRows, type SpanSegment } from '../sqlite-common.js';
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
+ });
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  export { SQLiteAsyncTraceWriter } from './sqlite-async-writer.js';
11
+ export type { SQLiteTableInfoRow } from './sqlite-common.js';
11
12
  export {
12
13
  buildAddColumnSql,
13
14
  extractSqliteColumnsFromTableInfo,
@@ -284,12 +284,21 @@ export function getInsertStatementCacheKey(activeUserFields: readonly string[]):
284
284
  }
285
285
 
286
286
  export function buildInsertSql(activeUserFields: readonly string[]): string {
287
- const userColsSql = activeUserFields.length > 0 ? `, ${activeUserFields.join(', ')}` : '';
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})`;
291
295
  }
292
296
 
297
+ /** Read a user schema field for one buffer row, falling back to the buffer's scope values. */
298
+ export function readSpanFieldValue(buffer: AnySpanBuffer, fieldName: string, row: number): unknown {
299
+ return readUserValue(buffer, fieldName, row) ?? readScopeValue(buffer, fieldName);
300
+ }
301
+
293
302
  export function buildInsertParams(segment: SpanSegment, row: number, activeUserFields: readonly string[]): unknown[] {
294
303
  const { buffer, traceId, spanId, parentSpanId, rowOffset } = segment;
295
304
  const entryType = buffer.entry_type[row];