@smoothbricks/lmao 0.2.2 → 0.3.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 (285) hide show
  1. package/README.md +206 -206
  2. package/dist/allocator.wasm +0 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +1 -0
  6. package/dist/lib/JsBufferStrategy.d.ts +4 -3
  7. package/dist/lib/JsBufferStrategy.d.ts.map +1 -1
  8. package/dist/lib/JsBufferStrategy.js +18 -11
  9. package/dist/lib/arrow/lease.d.ts +10 -0
  10. package/dist/lib/arrow/lease.d.ts.map +1 -0
  11. package/dist/lib/arrow/lease.js +33 -0
  12. package/dist/lib/arrow/utils.d.ts +3 -4
  13. package/dist/lib/arrow/utils.d.ts.map +1 -1
  14. package/dist/lib/arrow/utils.js +12 -13
  15. package/dist/lib/arrow/vocabularyDictionary.d.ts +21 -0
  16. package/dist/lib/arrow/vocabularyDictionary.d.ts.map +1 -0
  17. package/dist/lib/arrow/vocabularyDictionary.js +95 -0
  18. package/dist/lib/bufferStrategy.d.ts +3 -2
  19. package/dist/lib/bufferStrategy.d.ts.map +1 -1
  20. package/dist/lib/cloudflare/traceRows.d.ts.map +1 -1
  21. package/dist/lib/cloudflare/traceRows.js +3 -2
  22. package/dist/lib/codegen/evaluatorGenerator.d.ts.map +1 -1
  23. package/dist/lib/codegen/evaluatorGenerator.js +12 -11
  24. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts +44 -82
  25. package/dist/lib/codegen/fixedPositionWriterGenerator.d.ts.map +1 -1
  26. package/dist/lib/codegen/fixedPositionWriterGenerator.js +223 -162
  27. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts +63 -0
  28. package/dist/lib/codegen/spanLoggerClosureMaterializer.d.ts.map +1 -0
  29. package/dist/lib/codegen/spanLoggerClosureMaterializer.js +447 -0
  30. package/dist/lib/codegen/spanLoggerGenerator.d.ts +36 -19
  31. package/dist/lib/codegen/spanLoggerGenerator.d.ts.map +1 -1
  32. package/dist/lib/codegen/spanLoggerGenerator.js +164 -158
  33. package/dist/lib/convertToArrow.d.ts +7 -2
  34. package/dist/lib/convertToArrow.d.ts.map +1 -1
  35. package/dist/lib/convertToArrow.js +499 -285
  36. package/dist/lib/defineOpContext.js +1 -1
  37. package/dist/lib/enumMetadata.d.ts +19 -0
  38. package/dist/lib/enumMetadata.d.ts.map +1 -0
  39. package/dist/lib/enumMetadata.js +86 -0
  40. package/dist/lib/flushScheduler.d.ts.map +1 -1
  41. package/dist/lib/flushScheduler.js +13 -4
  42. package/dist/lib/library.d.ts +16 -98
  43. package/dist/lib/library.d.ts.map +1 -1
  44. package/dist/lib/library.js +32 -525
  45. package/dist/lib/logBinding.d.ts +21 -27
  46. package/dist/lib/logBinding.d.ts.map +1 -1
  47. package/dist/lib/op.d.ts +30 -30
  48. package/dist/lib/op.d.ts.map +1 -1
  49. package/dist/lib/op.js +15 -22
  50. package/dist/lib/opContext/createOpGroup.d.ts +1 -1
  51. package/dist/lib/opContext/createOpGroup.d.ts.map +1 -1
  52. package/dist/lib/opContext/createOpGroup.js +22 -29
  53. package/dist/lib/opContext/defineOp.d.ts +4 -4
  54. package/dist/lib/opContext/defineOp.d.ts.map +1 -1
  55. package/dist/lib/opContext/defineOp.js +53 -10
  56. package/dist/lib/opContext/opGroupTypes.d.ts +2 -2
  57. package/dist/lib/opContext/opTypes.d.ts +1 -1
  58. package/dist/lib/opContext/opTypes.d.ts.map +1 -1
  59. package/dist/lib/opContext/spanContextTypes.d.ts +33 -18
  60. package/dist/lib/opContext/spanContextTypes.d.ts.map +1 -1
  61. package/dist/lib/opContext/types.d.ts +4 -4
  62. package/dist/lib/opContext/types.d.ts.map +1 -1
  63. package/dist/lib/physicalLayoutPlan.d.ts +89 -0
  64. package/dist/lib/physicalLayoutPlan.d.ts.map +1 -0
  65. package/dist/lib/physicalLayoutPlan.js +442 -0
  66. package/dist/lib/resolveMessage.d.ts +9 -0
  67. package/dist/lib/resolveMessage.d.ts.map +1 -0
  68. package/dist/lib/resolveMessage.js +63 -0
  69. package/dist/lib/result.d.ts +5 -7
  70. package/dist/lib/result.d.ts.map +1 -1
  71. package/dist/lib/result.js +19 -26
  72. package/dist/lib/runtimeHint.d.ts +35 -0
  73. package/dist/lib/runtimeHint.d.ts.map +1 -0
  74. package/dist/lib/runtimeHint.js +79 -0
  75. package/dist/lib/schema/typeGuards.d.ts +7 -47
  76. package/dist/lib/schema/typeGuards.d.ts.map +1 -1
  77. package/dist/lib/schema/typeGuards.js +7 -123
  78. package/dist/lib/schema/types.d.ts +1 -1
  79. package/dist/lib/schema/types.d.ts.map +1 -1
  80. package/dist/lib/span-buffer/aot/v1.d.ts +2 -0
  81. package/dist/lib/span-buffer/aot/v1.d.ts.map +1 -0
  82. package/dist/lib/span-buffer/aot/v1.js +24 -0
  83. package/dist/lib/spanBuffer.d.ts +33 -4
  84. package/dist/lib/spanBuffer.d.ts.map +1 -1
  85. package/dist/lib/spanBuffer.js +583 -91
  86. package/dist/lib/spanBufferStats.d.ts +1 -1
  87. package/dist/lib/spanBufferStats.d.ts.map +1 -1
  88. package/dist/lib/spanContext.d.ts +27 -51
  89. package/dist/lib/spanContext.d.ts.map +1 -1
  90. package/dist/lib/spanContext.js +822 -344
  91. package/dist/lib/sqlite/sqlite-common.d.ts.map +1 -1
  92. package/dist/lib/sqlite/sqlite-common.js +20 -21
  93. package/dist/lib/testing/bun-harness.d.ts +8 -3
  94. package/dist/lib/testing/bun-harness.d.ts.map +1 -1
  95. package/dist/lib/testing/bun-harness.js +30 -18
  96. package/dist/lib/testing/extractFacts.d.ts +1 -1
  97. package/dist/lib/testing/extractFacts.d.ts.map +1 -1
  98. package/dist/lib/testing/extractFacts.js +55 -63
  99. package/dist/lib/testing/facts.d.ts +1 -1
  100. package/dist/lib/testing/facts.d.ts.map +1 -1
  101. package/dist/lib/testing/queryable-span.d.ts +1 -1
  102. package/dist/lib/testing/queryable-span.d.ts.map +1 -1
  103. package/dist/lib/testing/queryable-span.js +26 -28
  104. package/dist/lib/testing/span-query.d.ts.map +1 -1
  105. package/dist/lib/testing/span-query.js +19 -22
  106. package/dist/lib/testing/stdio-replay.d.ts.map +1 -1
  107. package/dist/lib/testing/stdio-replay.js +19 -8
  108. package/dist/lib/threadId.d.ts.map +1 -1
  109. package/dist/lib/threadId.js +6 -3
  110. package/dist/lib/traceContext.d.ts.map +1 -1
  111. package/dist/lib/traceContext.js +1 -4
  112. package/dist/lib/traceRoot.d.ts +30 -8
  113. package/dist/lib/traceRoot.d.ts.map +1 -1
  114. package/dist/lib/traceRoot.es.d.ts +17 -15
  115. package/dist/lib/traceRoot.es.d.ts.map +1 -1
  116. package/dist/lib/traceRoot.es.js +68 -34
  117. package/dist/lib/traceRoot.js +11 -0
  118. package/dist/lib/traceRoot.node.d.ts +17 -19
  119. package/dist/lib/traceRoot.node.d.ts.map +1 -1
  120. package/dist/lib/traceRoot.node.js +66 -38
  121. package/dist/lib/traceTopology.d.ts +42 -0
  122. package/dist/lib/traceTopology.d.ts.map +1 -0
  123. package/dist/lib/traceTopology.js +260 -0
  124. package/dist/lib/tracer.d.ts +9 -5
  125. package/dist/lib/tracer.d.ts.map +1 -1
  126. package/dist/lib/tracer.js +65 -71
  127. package/dist/lib/tracers/ArrayQueueTracer.d.ts +1 -1
  128. package/dist/lib/tracers/ArrayQueueTracer.js +1 -1
  129. package/dist/lib/tracers/StdioTracer.d.ts.map +1 -1
  130. package/dist/lib/tracers/StdioTracer.js +15 -13
  131. package/dist/lib/tracers/TestTracer.d.ts +4 -6
  132. package/dist/lib/tracers/TestTracer.d.ts.map +1 -1
  133. package/dist/lib/tracers/TestTracer.js +6 -8
  134. package/dist/lib/types.d.ts +49 -32
  135. package/dist/lib/types.d.ts.map +1 -1
  136. package/dist/lib/vocabularyRegistry.d.ts +25 -0
  137. package/dist/lib/vocabularyRegistry.d.ts.map +1 -0
  138. package/dist/lib/vocabularyRegistry.js +372 -0
  139. package/dist/lib/wasm/WasmBufferStrategy.d.ts +6 -10
  140. package/dist/lib/wasm/WasmBufferStrategy.d.ts.map +1 -1
  141. package/dist/lib/wasm/WasmBufferStrategy.js +44 -37
  142. package/dist/lib/wasm/wasmAllocator.d.ts +27 -22
  143. package/dist/lib/wasm/wasmAllocator.d.ts.map +1 -1
  144. package/dist/lib/wasm/wasmAllocator.js +66 -44
  145. package/dist/lib/wasm/wasmPhysicalLayout.d.ts +67 -0
  146. package/dist/lib/wasm/wasmPhysicalLayout.d.ts.map +1 -0
  147. package/dist/lib/wasm/wasmPhysicalLayout.js +179 -0
  148. package/dist/lib/wasm/wasmSpanBuffer.d.ts +79 -31
  149. package/dist/lib/wasm/wasmSpanBuffer.d.ts.map +1 -1
  150. package/dist/lib/wasm/wasmSpanBuffer.js +442 -272
  151. package/dist/lib/wasm/wasmTraceRoot.d.ts +24 -22
  152. package/dist/lib/wasm/wasmTraceRoot.d.ts.map +1 -1
  153. package/dist/lib/wasm/wasmTraceRoot.js +110 -71
  154. package/dist/vocabulary/register/v1.d.ts +2 -0
  155. package/dist/vocabulary/register/v1.d.ts.map +1 -0
  156. package/dist/vocabulary/register/v1.js +1 -0
  157. package/dist/wasm.d.ts +5 -0
  158. package/dist/wasm.d.ts.map +1 -0
  159. package/dist/wasm.js +4 -0
  160. package/package.json +54 -6
  161. package/src/index.ts +1 -0
  162. package/src/lib/JsBufferStrategy.ts +27 -9
  163. package/src/lib/__tests__/arrow-builder-integration/arrow-conversion.test.ts +335 -37
  164. package/src/lib/__tests__/arrow-builder-integration/binary-arrow-conversion.test.ts +97 -26
  165. package/src/lib/__tests__/arrow-builder-integration/binary-comparison.test.ts +75 -15
  166. package/src/lib/__tests__/arrow-builder-integration/binary-format-compliance.test.ts +30 -6
  167. package/src/lib/__tests__/arrow-builder-integration/buffer-chaining.test.ts +18 -21
  168. package/src/lib/__tests__/arrow-builder-integration/foundation.test.ts +5 -2
  169. package/src/lib/__tests__/arrow-builder-integration/integration.test.ts +25 -7
  170. package/src/lib/__tests__/arrow-builder-integration/lazy-columns.test.ts +3 -2
  171. package/src/lib/__tests__/buffer-overflow.test.ts +24 -18
  172. package/src/lib/__tests__/capability-span-context.test.ts +505 -0
  173. package/src/lib/__tests__/capacity-tuning.test.ts +5 -3
  174. package/src/lib/__tests__/eager-columns.test.ts +345 -0
  175. package/src/lib/__tests__/enum-metadata-aot.test.ts +153 -0
  176. package/src/lib/__tests__/enum-metadata.test.ts +177 -0
  177. package/src/lib/__tests__/fixtures/empty-vocabulary-runtime.fixture.ts +15 -0
  178. package/src/lib/__tests__/flushScheduler.test.ts +5 -1
  179. package/src/lib/__tests__/identity-view.property.test.ts +179 -0
  180. package/src/lib/__tests__/library.test.ts +19 -235
  181. package/src/lib/__tests__/message-buffer-families.test.ts +878 -0
  182. package/src/lib/__tests__/nested-library-tasks.test.ts +14 -15
  183. package/src/lib/__tests__/op-metadata.test.ts +1 -1
  184. package/src/lib/__tests__/op-type-safety.test.ts +5 -16
  185. package/src/lib/__tests__/physical-layout-plan.test.ts +333 -0
  186. package/src/lib/__tests__/remap-descriptor-integration.test.ts +381 -0
  187. package/src/lib/__tests__/root-context-construction.test.ts +414 -0
  188. package/src/lib/__tests__/span-auto-runtime.test.ts +386 -0
  189. package/src/lib/__tests__/span-buffer-segment-stats.test.ts +221 -0
  190. package/src/lib/__tests__/span-lifecycle.test.ts +53 -25
  191. package/src/lib/__tests__/spanbuffer-materializer-parity.test.ts +266 -0
  192. package/src/lib/__tests__/sync-async-trace.test.ts +24 -23
  193. package/src/lib/__tests__/tag-writer-aot.test.ts +214 -0
  194. package/src/lib/__tests__/test-helpers.ts +67 -12
  195. package/src/lib/__tests__/threadId.test.ts +62 -0
  196. package/src/lib/__tests__/timestamp.test.ts +221 -93
  197. package/src/lib/__tests__/traceTopology.property.test.ts +383 -0
  198. package/src/lib/__tests__/type-narrowing.test.ts +63 -0
  199. package/src/lib/__tests__/vocabulary-dense-decoding.test.ts +405 -0
  200. package/src/lib/__tests__/vocabularyRegistry.test.ts +313 -0
  201. package/src/lib/arrow/lease.ts +43 -0
  202. package/src/lib/arrow/utils.ts +10 -14
  203. package/src/lib/arrow/vocabularyDictionary.ts +123 -0
  204. package/src/lib/bufferStrategy.ts +9 -1
  205. package/src/lib/cloudflare/traceRows.ts +3 -2
  206. package/src/lib/codegen/__tests__/evaluatorGenerator.test.ts +21 -141
  207. package/src/lib/codegen/__tests__/fixedPositionWriter-parity.test.ts +273 -0
  208. package/src/lib/codegen/__tests__/fixedPositionWriter-uint64.test.ts +61 -34
  209. package/src/lib/codegen/__tests__/nullBitmap.test.ts +33 -37
  210. package/src/lib/codegen/__tests__/spanLoggerGenerator.test.ts +34 -18
  211. package/src/lib/codegen/__tests__/spanLoggerMaterializerParity.test.ts +503 -0
  212. package/src/lib/codegen/evaluatorGenerator.ts +18 -13
  213. package/src/lib/codegen/fixedPositionWriterGenerator.ts +329 -245
  214. package/src/lib/codegen/spanLoggerClosureMaterializer.ts +598 -0
  215. package/src/lib/codegen/spanLoggerGenerator.ts +241 -177
  216. package/src/lib/convertToArrow.ts +598 -311
  217. package/src/lib/defineOpContext.ts +1 -1
  218. package/src/lib/enumMetadata.ts +121 -0
  219. package/src/lib/flushScheduler.ts +11 -5
  220. package/src/lib/library.ts +37 -595
  221. package/src/lib/logBinding.ts +21 -27
  222. package/src/lib/op.ts +75 -18
  223. package/src/lib/opContext/__tests__/retry.test.ts +27 -21
  224. package/src/lib/opContext/createOpGroup.ts +33 -31
  225. package/src/lib/opContext/defineOp.ts +88 -11
  226. package/src/lib/opContext/opGroupTypes.ts +2 -2
  227. package/src/lib/opContext/opTypes.ts +1 -1
  228. package/src/lib/opContext/spanContextTypes.ts +122 -24
  229. package/src/lib/opContext/types.ts +7 -3
  230. package/src/lib/physicalLayoutPlan.ts +598 -0
  231. package/src/lib/resolveMessage.ts +67 -0
  232. package/src/lib/result.ts +20 -33
  233. package/src/lib/runtimeHint.ts +98 -0
  234. package/src/lib/schema/__tests__/featureFlags.test.ts +2 -1
  235. package/src/lib/schema/builder.ts +1 -1
  236. package/src/lib/schema/typeGuards.ts +7 -151
  237. package/src/lib/schema/types.ts +1 -1
  238. package/src/lib/span-buffer/aot/v1.ts +26 -0
  239. package/src/lib/spanBuffer.ts +658 -92
  240. package/src/lib/spanBufferStats.ts +1 -1
  241. package/src/lib/spanContext.ts +1350 -861
  242. package/src/lib/sqlite/sqlite-common.ts +20 -31
  243. package/src/lib/testing/__tests__/topology-traversal.test.ts +174 -0
  244. package/src/lib/testing/__tests__/vitest-harness.test.ts +2 -1
  245. package/src/lib/testing/bun-harness.ts +94 -43
  246. package/src/lib/testing/extractFacts.ts +64 -78
  247. package/src/lib/testing/facts.ts +1 -1
  248. package/src/lib/testing/queryable-span.ts +23 -30
  249. package/src/lib/testing/span-query.ts +16 -20
  250. package/src/lib/testing/stdio-replay.ts +25 -8
  251. package/src/lib/testing/vitest-harness.ts +1 -1
  252. package/src/lib/threadId.ts +6 -3
  253. package/src/lib/traceContext.ts +1 -6
  254. package/src/lib/traceRoot.es.ts +77 -42
  255. package/src/lib/traceRoot.node.ts +75 -46
  256. package/src/lib/traceRoot.ts +41 -14
  257. package/src/lib/traceTopology.ts +279 -0
  258. package/src/lib/tracer.ts +109 -98
  259. package/src/lib/tracers/ArrayQueueTracer.ts +1 -1
  260. package/src/lib/tracers/StdioTracer.ts +15 -13
  261. package/src/lib/tracers/TestTracer.ts +6 -8
  262. package/src/lib/tracers/__tests__/ArrayQueueTracer.test.ts +15 -10
  263. package/src/lib/tracers/__tests__/CompositeTracer.test.ts +150 -0
  264. package/src/lib/tracers/__tests__/TestTracer.test.ts +23 -13
  265. package/src/lib/types.ts +64 -33
  266. package/src/lib/vocabularyRegistry.ts +439 -0
  267. package/src/lib/wasm/WasmBufferStrategy.ts +56 -48
  268. package/src/lib/wasm/__tests__/WasmBufferStrategy.test.ts +215 -11
  269. package/src/lib/wasm/__tests__/allocatorFreeBlockClamp.test.ts +86 -0
  270. package/src/lib/wasm/__tests__/wasm-identity-view.test.ts +311 -0
  271. package/src/lib/wasm/__tests__/wasm-integration.test.ts +417 -44
  272. package/src/lib/wasm/__tests__/wasm-message-buffer-families.test.ts +588 -0
  273. package/src/lib/wasm/__tests__/wasmAllocator.test.ts +100 -668
  274. package/src/lib/wasm/__tests__/wasmSpanBuffer.test.ts +419 -63
  275. package/src/lib/wasm/__tests__/wasmTraceRoot.test.ts +24 -29
  276. package/src/lib/wasm/__tests__/wasmTracer.test.ts.disabled +2 -2
  277. package/src/lib/wasm/wasmAllocator.ts +131 -96
  278. package/src/lib/wasm/wasmPhysicalLayout.ts +309 -0
  279. package/src/lib/wasm/wasmSpanBuffer.ts +597 -341
  280. package/src/lib/wasm/wasmTraceRoot.ts +140 -78
  281. package/src/vocabulary/register/v1.ts +1 -0
  282. package/src/wasm.ts +19 -0
  283. package/src/lib/__tests__/remapped-buffer-view-integration.test.ts +0 -319
  284. package/src/lib/__tests__/remapped-buffer-view.test.ts +0 -635
  285. package/src/lib/wasm/allocator.zig +0 -948
@@ -12,9 +12,8 @@
12
12
  *
13
13
  * SpanContext is implemented as a class factory pattern:
14
14
  * - `createSpanContextClass()` returns a class that closes over schema/logBinding
15
- * - Child contexts use `Object.create(parent)` for prototype inheritance
16
- * - User properties (deps, ff, env) are inherited via prototype chain
17
- * - Context overrides work by setting own properties that shadow inherited ones
15
+ * - Child contexts are constructed directly from the frozen CallsitePlan
16
+ * - User properties are copied from the parent only when an override context is requested
18
17
  *
19
18
  * ## Method Binding for Destructuring
20
19
  *
@@ -25,22 +24,30 @@
25
24
  * - const { span, ok, err } = ctx; // Just works!
26
25
  */
27
26
 
28
- import type { TagWriter } from './codegen/fixedPositionWriterGenerator.js';
29
- import { createTagWriter } from './codegen/fixedPositionWriterGenerator.js';
27
+ import type { TagWriter, WriterState } from './codegen/fixedPositionWriterGenerator.js';
30
28
  import {
31
29
  createSpanLogger as createSpanLoggerFromGenerator,
32
30
  type FluentLogEntry,
33
31
  type ScopeUpdate,
34
32
  type SpanLoggerImpl,
35
33
  } from './codegen/spanLoggerGenerator.js';
36
- import { Blocked } from './errors/Blocked.js';
37
34
  import type { RetryPolicy } from './errors/retry-policy.js';
38
35
  import { TransientError } from './errors/Transient.js';
39
- import type { RemappedViewConstructor } from './logBinding.js';
40
- import { Op } from './op.js';
36
+ import type { Op } from './op.js';
41
37
  import type { OpContext, OpMetadata, SpanContext, SpanFn, SpanLogger, SpanSyncFn } from './opContext/types.js';
38
+ import type { CallsitePlan, PhysicalLayoutPlan } from './physicalLayoutPlan.js';
42
39
  import { Err, hasErrorCode, Ok, type Result } from './result.js';
43
- import type { FeatureFlagEvaluator, InferFeatureFlagsWithContext } from './schema/evaluator.js';
40
+ import {
41
+ RUNTIME_HINT_DEPS,
42
+ RUNTIME_HINT_FF,
43
+ RUNTIME_HINT_FULL_CAPABILITIES,
44
+ RUNTIME_HINT_LOG,
45
+ RUNTIME_HINT_RESULT,
46
+ RUNTIME_HINT_SCOPE,
47
+ RUNTIME_HINT_SPAN,
48
+ RUNTIME_HINT_TAG,
49
+ } from './runtimeHint.js';
50
+ import type { FeatureFlagEvaluator, FlagEvaluator, InferFeatureFlagsWithContext } from './schema/evaluator.js';
44
51
  import {
45
52
  ENTRY_TYPE_SPAN_ERR,
46
53
  ENTRY_TYPE_SPAN_EXCEPTION,
@@ -48,8 +55,7 @@ import {
48
55
  ENTRY_TYPE_SPAN_RETRY,
49
56
  } from './schema/systemSchema.js';
50
57
  import type { InferSchema, LogSchema } from './schema/types.js';
51
- import type { SpanBufferConstructor } from './spanBuffer.js';
52
- import type { LogBinding, SpanBuffer } from './types.js';
58
+ import type { AnySpanBuffer, LogBinding, SpanBuffer } from './types.js';
53
59
 
54
60
  // Note: TraceRoot.writeSpanStart() is used instead of direct timestamp writes.
55
61
  // The platform-specific TraceRoot (traceRoot.es.ts or traceRoot.node.ts) handles
@@ -98,14 +104,23 @@ type SpanDispatchFn<Ctx extends OpContext, Args extends unknown[] = unknown[], S
98
104
  ) => Result<S, E> | Promise<Result<S, E>>;
99
105
 
100
106
  type SpanDispatchTarget<Ctx extends OpContext> = {
101
- readonly SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>;
102
- readonly remappedViewClass: RemappedViewConstructor | undefined;
107
+ readonly callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>;
103
108
  readonly opMetadata: OpMetadata;
104
109
  readonly fn: SpanDispatchFn<Ctx>;
105
110
  };
106
111
 
112
+ function isOpLike(value: unknown): value is Op<OpContext, unknown[], unknown, unknown> {
113
+ return (
114
+ typeof value === 'object' &&
115
+ value !== null &&
116
+ typeof Reflect.get(value, 'fn') === 'function' &&
117
+ typeof Reflect.get(value, 'callsitePlan') === 'object' &&
118
+ typeof Reflect.get(value, 'metadata') === 'object'
119
+ );
120
+ }
121
+
107
122
  function isOpInstance<Ctx extends OpContext>(value: unknown): value is Op<Ctx, unknown[], unknown, unknown> {
108
- return value instanceof Op;
123
+ return isOpLike(value);
109
124
  }
110
125
 
111
126
  // WHY: resolveSpanTarget() accepts either an Op instance or a raw span
@@ -115,60 +130,22 @@ function isSpanDispatchFn<Ctx extends OpContext>(value: unknown): value is SpanD
115
130
  return typeof value === 'function';
116
131
  }
117
132
 
118
- function isSpanBufferConstructorForSchema<T extends LogSchema>(
119
- value: unknown,
120
- schema: T,
121
- ): value is SpanBufferConstructor<T> {
122
- return (
123
- typeof value === 'function' &&
124
- Reflect.get(value, 'schema') === schema &&
125
- typeof Reflect.get(value, 'stats') === 'object'
126
- );
127
- }
128
-
129
- function getBufferConstructor<T extends LogSchema>(buffer: SpanBuffer<T>): SpanBufferConstructor<T> {
130
- const ctor = buffer.constructor;
131
- if (!isSpanBufferConstructorForSchema(ctor, buffer._logSchema)) {
132
- throw new TypeError('Span buffer constructor does not match the buffer schema');
133
- }
134
- return ctor;
135
- }
136
-
137
- function isSpanBufferForSchema<T extends LogSchema>(buffer: unknown, schema: T): buffer is SpanBuffer<T> {
138
- return (
139
- typeof buffer === 'object' &&
140
- buffer !== null &&
141
- Reflect.get(buffer, '_logSchema') === schema &&
142
- isSpanBufferConstructorForSchema(Reflect.get(buffer, 'constructor'), schema)
143
- );
144
- }
145
-
146
133
  function isSpanContextInstance<Ctx extends OpContext>(value: unknown): value is SpanContextInstance<Ctx> {
147
134
  return (
148
135
  isSpanContext<Ctx>(value) &&
136
+ Reflect.has(value, '_spanBuffer') &&
149
137
  Reflect.has(value, '_buffer') &&
150
- Reflect.has(value, '_spanLogger') &&
151
- Reflect.has(value, '_schema')
138
+ Reflect.has(value, '_schema') &&
139
+ Reflect.has(value, '_logBinding') &&
140
+ Reflect.has(value, '_physicalLayoutPlan')
152
141
  );
153
142
  }
154
143
 
155
- function createInheritedContext<Ctx extends OpContext>(parent: SpanContextInstance<Ctx>): SpanContextInstance<Ctx> {
156
- const child: unknown = Object.create(parent);
157
- if (!isSpanContextInstance<Ctx>(child)) {
158
- throw new TypeError('Failed to create child span context');
144
+ function asSpanContextInstance<Ctx extends OpContext>(value: object): SpanContextInstance<Ctx> {
145
+ if (!isSpanContextInstance<Ctx>(value)) {
146
+ throw new TypeError('Callsite plan created an invalid child span context');
159
147
  }
160
- return child;
161
- }
162
-
163
- function createInheritedContextWithOverrides<Ctx extends OpContext>(
164
- parent: SpanContextInstance<Ctx>,
165
- overrides: object,
166
- ): SpanContextInstance<Ctx> {
167
- const child: unknown = Object.assign(Object.create(parent), overrides);
168
- if (!isSpanContextInstance<Ctx>(child)) {
169
- throw new TypeError('Failed to create overridden child span context');
170
- }
171
- return child;
148
+ return value;
172
149
  }
173
150
 
174
151
  function readStringArgument(args: IArguments, index: number, label: string): string {
@@ -181,12 +158,12 @@ function readStringArgument(args: IArguments, index: number, label: string): str
181
158
 
182
159
  function resolveSpanTarget<Ctx extends OpContext>(
183
160
  value: unknown,
184
- fallbackBuffer: SpanBuffer<Ctx['logSchema']>,
161
+ fallbackPlan: CallsitePlan<Ctx['logSchema'], Ctx>,
162
+ fallbackMetadata: OpMetadata,
185
163
  ): SpanDispatchTarget<Ctx> {
186
164
  if (isOpInstance<Ctx>(value)) {
187
165
  return {
188
- SpanBufferClass: value.SpanBufferClass,
189
- remappedViewClass: value.remappedViewClass,
166
+ callsitePlan: value.callsitePlan,
190
167
  opMetadata: value.metadata,
191
168
  fn: value.fn,
192
169
  };
@@ -197,13 +174,21 @@ function resolveSpanTarget<Ctx extends OpContext>(
197
174
  }
198
175
 
199
176
  return {
200
- SpanBufferClass: getBufferConstructor(fallbackBuffer),
201
- remappedViewClass: undefined,
202
- opMetadata: fallbackBuffer._opMetadata,
177
+ callsitePlan: fallbackPlan,
178
+ opMetadata: fallbackMetadata,
203
179
  fn: value,
204
180
  };
205
181
  }
206
182
 
183
+ function isSynchronousResult<S, E>(value: Result<S, E> | PromiseLike<Result<S, E>>): value is Result<S, E> {
184
+ return value instanceof Ok || value instanceof Err;
185
+ }
186
+
187
+ function getRetryableError<S, E>(result: Result<S, E>, attempt: number): TransientError<string, unknown> | undefined {
188
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return undefined;
189
+ return attempt < result.error.policy.maxAttempts ? result.error : undefined;
190
+ }
191
+
207
192
  // =============================================================================
208
193
  // Helper Functions
209
194
  // =============================================================================
@@ -224,22 +209,13 @@ function resolveSpanTarget<Ctx extends OpContext>(
224
209
  */
225
210
  export function writeSpanStart<T extends LogSchema>(buffer: SpanBuffer<T>, spanName: string): void {
226
211
  // Delegate to TraceRoot - platform-specific implementation handles timestamps
227
- buffer._traceRoot.writeSpanStart(buffer, spanName);
212
+ buffer._traceRoot._writeSpanStart(buffer._traceRoot, buffer, spanName);
228
213
  }
229
214
  //#endregion smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.start
230
215
 
231
- /**
232
- * Create a SpanLogger for the given buffer.
233
- *
234
- * Per specs/lmao/01i_span_scope_attributes.md: Scope values are stored directly on buffer._scopeValues.
235
- * The SpanLogger reads/writes scope via buffer._scopeValues - no separate Scope class needed.
236
- *
237
- * @param schema - Tag attribute schema with field definitions
238
- * @param buffer - SpanBuffer to write entries to (per-span instance)
239
- * @returns SpanLogger with typed methods matching schema
240
- */
241
- export function createSpanLogger<T extends LogSchema>(schema: T, buffer: SpanBuffer<T>): SpanLoggerImpl<T> {
242
- return createSpanLoggerFromGenerator(schema, buffer);
216
+ /** Create a SpanLogger bound to an existing SpanContext writer state. */
217
+ export function createSpanLogger<T extends LogSchema>(schema: T, state: WriterState): SpanLoggerImpl<T> {
218
+ return createSpanLoggerFromGenerator(schema, state);
243
219
  }
244
220
 
245
221
  //#region smoo/lmao!n/op-retry.delay
@@ -302,9 +278,9 @@ function writeRetryEntry<T extends LogSchema>(
302
278
  // Get current write index and advance for next write
303
279
  const index = buffer._writeIndex;
304
280
 
305
- // Write entry via TraceRoot for timestamp handling
306
- // TraceRoot.writeLogEntry writes timestamp and entry_type at the given index
307
- buffer._traceRoot.writeLogEntry(buffer, ENTRY_TYPE_SPAN_RETRY);
281
+ const traceRoot = buffer._traceRoot;
282
+ const appendLogEntry = buffer._opMetadata._physicalLayoutPlan?.appendLogEntry ?? traceRoot._appendLogEntry;
283
+ appendLogEntry(traceRoot, buffer, ENTRY_TYPE_SPAN_RETRY);
308
284
 
309
285
  // Write retry-specific message: retry:op:{opName} for prefix-based querying
310
286
  const opName = buffer._opMetadata?.name ?? 'unknown';
@@ -332,68 +308,211 @@ function sleep(ms: number): Promise<void> {
332
308
  return new Promise((resolve) => setTimeout(resolve, ms));
333
309
  }
334
310
 
335
- /**
336
- * Execute function with retry loop for TransientError handling.
337
- *
338
- * Per plan 19-03: Op class handles retry loop internally.
339
- * - TransientError from op body triggers retry based on error.policy
340
- * - Retry respects maxAttempts from TransientError.policy
341
- * - span-retry entry written for each transient failure
342
- * - Only final result written as span-ok or span-err
343
- * - BlockedError returns immediately without retry
344
- *
345
- * @param buffer - SpanBuffer to write retry entries to
346
- * @param fn - Function to execute (may be retried)
347
- * @returns Final result (success, non-transient error, or exhausted transient error)
348
- */
349
- async function executeWithRetry<T extends LogSchema, S, E>(
350
- buffer: SpanBuffer<T>,
351
- fn: () => Result<S, E> | Promise<Result<S, E>>,
311
+ async function executeWithRetry0<Ctx extends OpContext, S, E>(
312
+ buffer: SpanBuffer<Ctx['logSchema']>,
313
+ fn: (ctx: SpanContext<Ctx>) => Result<S, E> | Promise<Result<S, E>>,
314
+ ctx: SpanContext<Ctx>,
352
315
  ): Promise<Result<S, E>> {
353
316
  let attempt = 0;
354
-
355
317
  while (true) {
356
318
  attempt++;
319
+ const result = await fn(ctx);
320
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
321
+ if (attempt >= result.error.policy.maxAttempts) return result;
322
+ const delay = calculateDelay(result.error.policy, attempt);
323
+ writeRetryEntry(buffer, attempt, result.error, delay);
324
+ await sleep(delay);
325
+ }
326
+ }
357
327
 
358
- // Execute the function
359
- const result = await fn();
360
-
361
- // Success - return immediately
362
- if (result instanceof Ok) {
363
- return result;
364
- }
365
-
366
- // Error result - check error type for retry behavior
367
- const error = (result as Err<E>).error;
328
+ async function executeWithRetry1<Ctx extends OpContext, S, E, A1>(
329
+ buffer: SpanBuffer<Ctx['logSchema']>,
330
+ fn: (ctx: SpanContext<Ctx>, a1: A1) => Result<S, E> | Promise<Result<S, E>>,
331
+ ctx: SpanContext<Ctx>,
332
+ a1: A1,
333
+ ): Promise<Result<S, E>> {
334
+ let attempt = 0;
335
+ while (true) {
336
+ attempt++;
337
+ const result = await fn(ctx, a1);
338
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
339
+ if (attempt >= result.error.policy.maxAttempts) return result;
340
+ const delay = calculateDelay(result.error.policy, attempt);
341
+ writeRetryEntry(buffer, attempt, result.error, delay);
342
+ await sleep(delay);
343
+ }
344
+ }
368
345
 
369
- // BlockedError - return immediately, no retry
370
- if (error instanceof Blocked) {
371
- return result;
372
- }
346
+ async function executeWithRetry2<Ctx extends OpContext, S, E, A1, A2>(
347
+ buffer: SpanBuffer<Ctx['logSchema']>,
348
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2) => Result<S, E> | Promise<Result<S, E>>,
349
+ ctx: SpanContext<Ctx>,
350
+ a1: A1,
351
+ a2: A2,
352
+ ): Promise<Result<S, E>> {
353
+ let attempt = 0;
354
+ while (true) {
355
+ attempt++;
356
+ const result = await fn(ctx, a1, a2);
357
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
358
+ if (attempt >= result.error.policy.maxAttempts) return result;
359
+ const delay = calculateDelay(result.error.policy, attempt);
360
+ writeRetryEntry(buffer, attempt, result.error, delay);
361
+ await sleep(delay);
362
+ }
363
+ }
373
364
 
374
- // TransientError - check if we should retry
375
- if (error instanceof TransientError) {
376
- const { policy } = error;
365
+ async function executeWithRetry3<Ctx extends OpContext, S, E, A1, A2, A3>(
366
+ buffer: SpanBuffer<Ctx['logSchema']>,
367
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3) => Result<S, E> | Promise<Result<S, E>>,
368
+ ctx: SpanContext<Ctx>,
369
+ a1: A1,
370
+ a2: A2,
371
+ a3: A3,
372
+ ): Promise<Result<S, E>> {
373
+ let attempt = 0;
374
+ while (true) {
375
+ attempt++;
376
+ const result = await fn(ctx, a1, a2, a3);
377
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
378
+ if (attempt >= result.error.policy.maxAttempts) return result;
379
+ const delay = calculateDelay(result.error.policy, attempt);
380
+ writeRetryEntry(buffer, attempt, result.error, delay);
381
+ await sleep(delay);
382
+ }
383
+ }
377
384
 
378
- // Check attempt limit (maxAttempts includes initial attempt)
379
- if (attempt >= policy.maxAttempts) {
380
- // Exhausted - return final error
381
- return result;
382
- }
385
+ async function executeWithRetry4<Ctx extends OpContext, S, E, A1, A2, A3, A4>(
386
+ buffer: SpanBuffer<Ctx['logSchema']>,
387
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4) => Result<S, E> | Promise<Result<S, E>>,
388
+ ctx: SpanContext<Ctx>,
389
+ a1: A1,
390
+ a2: A2,
391
+ a3: A3,
392
+ a4: A4,
393
+ ): Promise<Result<S, E>> {
394
+ let attempt = 0;
395
+ while (true) {
396
+ attempt++;
397
+ const result = await fn(ctx, a1, a2, a3, a4);
398
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
399
+ if (attempt >= result.error.policy.maxAttempts) return result;
400
+ const delay = calculateDelay(result.error.policy, attempt);
401
+ writeRetryEntry(buffer, attempt, result.error, delay);
402
+ await sleep(delay);
403
+ }
404
+ }
383
405
 
384
- // Calculate delay based on policy and attempt number
385
- const delay = calculateDelay(policy, attempt);
406
+ async function executeWithRetry5<Ctx extends OpContext, S, E, A1, A2, A3, A4, A5>(
407
+ buffer: SpanBuffer<Ctx['logSchema']>,
408
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Result<S, E> | Promise<Result<S, E>>,
409
+ ctx: SpanContext<Ctx>,
410
+ a1: A1,
411
+ a2: A2,
412
+ a3: A3,
413
+ a4: A4,
414
+ a5: A5,
415
+ ): Promise<Result<S, E>> {
416
+ let attempt = 0;
417
+ while (true) {
418
+ attempt++;
419
+ const result = await fn(ctx, a1, a2, a3, a4, a5);
420
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
421
+ if (attempt >= result.error.policy.maxAttempts) return result;
422
+ const delay = calculateDelay(result.error.policy, attempt);
423
+ writeRetryEntry(buffer, attempt, result.error, delay);
424
+ await sleep(delay);
425
+ }
426
+ }
386
427
 
387
- // Write span-retry entry to buffer for observability
388
- writeRetryEntry(buffer, attempt, error, delay);
428
+ async function executeWithRetry6<Ctx extends OpContext, S, E, A1, A2, A3, A4, A5, A6>(
429
+ buffer: SpanBuffer<Ctx['logSchema']>,
430
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => Result<S, E> | Promise<Result<S, E>>,
431
+ ctx: SpanContext<Ctx>,
432
+ a1: A1,
433
+ a2: A2,
434
+ a3: A3,
435
+ a4: A4,
436
+ a5: A5,
437
+ a6: A6,
438
+ ): Promise<Result<S, E>> {
439
+ let attempt = 0;
440
+ while (true) {
441
+ attempt++;
442
+ const result = await fn(ctx, a1, a2, a3, a4, a5, a6);
443
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
444
+ if (attempt >= result.error.policy.maxAttempts) return result;
445
+ const delay = calculateDelay(result.error.policy, attempt);
446
+ writeRetryEntry(buffer, attempt, result.error, delay);
447
+ await sleep(delay);
448
+ }
449
+ }
389
450
 
390
- // Wait before retry
391
- await sleep(delay);
392
- continue;
393
- }
451
+ async function executeWithRetry7<Ctx extends OpContext, S, E, A1, A2, A3, A4, A5, A6, A7>(
452
+ buffer: SpanBuffer<Ctx['logSchema']>,
453
+ fn: (
454
+ ctx: SpanContext<Ctx>,
455
+ a1: A1,
456
+ a2: A2,
457
+ a3: A3,
458
+ a4: A4,
459
+ a5: A5,
460
+ a6: A6,
461
+ a7: A7,
462
+ ) => Result<S, E> | Promise<Result<S, E>>,
463
+ ctx: SpanContext<Ctx>,
464
+ a1: A1,
465
+ a2: A2,
466
+ a3: A3,
467
+ a4: A4,
468
+ a5: A5,
469
+ a6: A6,
470
+ a7: A7,
471
+ ): Promise<Result<S, E>> {
472
+ let attempt = 0;
473
+ while (true) {
474
+ attempt++;
475
+ const result = await fn(ctx, a1, a2, a3, a4, a5, a6, a7);
476
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
477
+ if (attempt >= result.error.policy.maxAttempts) return result;
478
+ const delay = calculateDelay(result.error.policy, attempt);
479
+ writeRetryEntry(buffer, attempt, result.error, delay);
480
+ await sleep(delay);
481
+ }
482
+ }
394
483
 
395
- // Non-transient error - return immediately
396
- return result;
484
+ async function executeWithRetry8<Ctx extends OpContext, S, E, A1, A2, A3, A4, A5, A6, A7, A8>(
485
+ buffer: SpanBuffer<Ctx['logSchema']>,
486
+ fn: (
487
+ ctx: SpanContext<Ctx>,
488
+ a1: A1,
489
+ a2: A2,
490
+ a3: A3,
491
+ a4: A4,
492
+ a5: A5,
493
+ a6: A6,
494
+ a7: A7,
495
+ a8: A8,
496
+ ) => Result<S, E> | Promise<Result<S, E>>,
497
+ ctx: SpanContext<Ctx>,
498
+ a1: A1,
499
+ a2: A2,
500
+ a3: A3,
501
+ a4: A4,
502
+ a5: A5,
503
+ a6: A6,
504
+ a7: A7,
505
+ a8: A8,
506
+ ): Promise<Result<S, E>> {
507
+ let attempt = 0;
508
+ while (true) {
509
+ attempt++;
510
+ const result = await fn(ctx, a1, a2, a3, a4, a5, a6, a7, a8);
511
+ if (!(result instanceof Err) || !(result.error instanceof TransientError)) return result;
512
+ if (attempt >= result.error.policy.maxAttempts) return result;
513
+ const delay = calculateDelay(result.error.policy, attempt);
514
+ writeRetryEntry(buffer, attempt, result.error, delay);
515
+ await sleep(delay);
397
516
  }
398
517
  }
399
518
  //#endregion smoo/lmao!n/op-retry.loop
@@ -411,12 +530,17 @@ async function executeWithRetry<T extends LogSchema, S, E>(
411
530
  * @param buffer - SpanBuffer to write to
412
531
  * @param result - The result returned by the span function
413
532
  */
533
+ function writeSpanEndEntry<T extends LogSchema>(buffer: SpanBuffer<T>, entryType: number): void {
534
+ const appenders = buffer._opMetadata._physicalLayoutPlan?.appenders;
535
+ if (appenders === undefined) throw new TypeError('SpanBuffer metadata is missing physical lifecycle appenders');
536
+ appenders.writeSpanEnd(buffer, entryType);
537
+ }
538
+
414
539
  export function writeSpanEnd<T extends LogSchema, S, E>(buffer: SpanBuffer<T>, result: Result<S, E>): void {
415
- // Write entry_type and timestamp via TraceRoot (platform-specific)
416
540
  if (result instanceof Ok) {
417
- buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_OK);
541
+ writeSpanEndEntry(buffer, ENTRY_TYPE_SPAN_OK);
418
542
  } else if (result instanceof Err) {
419
- buffer._traceRoot.writeSpanEnd(buffer, ENTRY_TYPE_SPAN_ERR);
543
+ writeSpanEndEntry(buffer, ENTRY_TYPE_SPAN_ERR);
420
544
  // Write error_code if the error has a code property
421
545
  if (hasErrorCode(result.error)) {
422
546
  buffer.error_code(1, result.error.code);
@@ -432,147 +556,142 @@ export function writeSpanEnd<T extends LogSchema, S, E>(buffer: SpanBuffer<T>, r
432
556
  //#region smoo/lmao!n/spancontext-type
433
557
  /**
434
558
  * Constructor type for SpanContext classes created by createSpanContextClass.
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.
559
+ * The instance itself becomes the writer state after its core fields are assigned.
440
560
  */
441
- export type SpanContextClass<Ctx extends OpContext> = new (
561
+ export type SpanContextClass<Ctx extends OpContext = OpContext> = new (
442
562
  buffer: SpanBuffer<Ctx['logSchema']>,
443
563
  schema: Ctx['logSchema'],
444
- spanLogger: SpanLoggerImpl<Ctx['logSchema']>,
445
- tag: TagWriter<Ctx['logSchema']>,
564
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
565
+ contextSource?: Record<string, unknown>,
566
+ contextOverrides?: Record<string, unknown>,
567
+ deps?: Record<string, unknown>,
568
+ ffSource?: FlagEvaluator<Ctx> | (FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>),
446
569
  ) => SpanContextInstance<Ctx>;
447
570
 
448
571
  /**
449
572
  * Instance type of SpanContext class - what ops actually receive.
450
573
  * This is a type alias that extends the public SpanContext with internal properties.
451
574
  */
452
- export type SpanContextInstance<Ctx extends OpContext> = SpanContext<Ctx> & {
453
- // Internal properties
454
- _buffer: SpanBuffer<Ctx['logSchema']>;
455
- _schema: Ctx['logSchema'];
456
- _spanLogger: SpanLoggerImpl<Ctx['logSchema']>;
457
- _logBinding: LogBinding;
458
-
459
- // Internal methods
460
- _newCtx0(): SpanContextInstance<Ctx>;
461
- _newCtx1(overrides: object): SpanContextInstance<Ctx>;
462
- _spanPre(
463
- childCtx: SpanContextInstance<Ctx>,
464
- line: number,
465
- name: string,
466
- SpanBufferClass: SpanBufferConstructor,
467
- remappedViewClass: import('./logBinding.js').RemappedViewConstructor | undefined,
468
- opMetadata: import('./opContext/opTypes.js').OpMetadata,
469
- ): SpanContextInstance<Ctx>;
470
- _spanException(buffer: SpanBuffer<Ctx['logSchema']>, error: unknown): void;
471
-
472
- // Monomorphic span methods (span0-span8)
473
- // Transformer emits: ctx.span0(line, name, ctx, SpanBufferClass, remappedViewClass, opMetadata, fn, ...args)
474
- spanSync0<S, E>(
475
- line: number,
476
- name: string,
477
- childCtx: SpanContextInstance<Ctx>,
478
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
479
- remappedViewClass: RemappedViewConstructor | undefined,
480
- opMetadata: OpMetadata,
481
- fn: (ctx: SpanContext<Ctx>) => Result<S, E>,
482
- ): Result<S, E>;
483
- span0<S, E>(
484
- line: number,
485
- name: string,
486
- childCtx: SpanContextInstance<Ctx>,
487
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
488
- remappedViewClass: import('./logBinding.js').RemappedViewConstructor | undefined,
489
- opMetadata: import('./opContext/opTypes.js').OpMetadata,
490
- fn: (ctx: SpanContext<Ctx>) => Result<S, E> | Promise<Result<S, E>>,
491
- ): Promise<Result<S, E>>;
492
- span1<S, E, A1>(
493
- line: number,
494
- name: string,
495
- childCtx: SpanContextInstance<Ctx>,
496
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
497
- remappedViewClass: RemappedViewConstructor | undefined,
498
- opMetadata: OpMetadata,
499
- fn: (ctx: SpanContext<Ctx>, a1: A1) => Result<S, E> | Promise<Result<S, E>>,
500
- a1: A1,
501
- ): Promise<Result<S, E>>;
502
- span2<S, E, A1, A2>(
503
- line: number,
504
- name: string,
505
- childCtx: SpanContextInstance<Ctx>,
506
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
507
- remappedViewClass: RemappedViewConstructor | undefined,
508
- opMetadata: OpMetadata,
509
- fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2) => Result<S, E> | Promise<Result<S, E>>,
510
- a1: A1,
511
- a2: A2,
512
- ): Promise<Result<S, E>>;
513
- span3<S, E, A1, A2, A3>(
514
- line: number,
515
- name: string,
516
- childCtx: SpanContextInstance<Ctx>,
517
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
518
- remappedViewClass: RemappedViewConstructor | undefined,
519
- opMetadata: OpMetadata,
520
- fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3) => Result<S, E> | Promise<Result<S, E>>,
521
- a1: A1,
522
- a2: A2,
523
- a3: A3,
524
- ): Promise<Result<S, E>>;
525
- span4<S, E, A1, A2, A3, A4>(
526
- line: number,
527
- name: string,
528
- childCtx: SpanContextInstance<Ctx>,
529
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
530
- remappedViewClass: RemappedViewConstructor | undefined,
531
- opMetadata: OpMetadata,
532
- fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4) => Result<S, E> | Promise<Result<S, E>>,
533
- a1: A1,
534
- a2: A2,
535
- a3: A3,
536
- a4: A4,
537
- ): Promise<Result<S, E>>;
538
- span5<S, E, A1, A2, A3, A4, A5>(
539
- line: number,
540
- name: string,
541
- childCtx: SpanContextInstance<Ctx>,
542
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
543
- remappedViewClass: RemappedViewConstructor | undefined,
544
- opMetadata: OpMetadata,
545
- fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Result<S, E> | Promise<Result<S, E>>,
546
- a1: A1,
547
- a2: A2,
548
- a3: A3,
549
- a4: A4,
550
- a5: A5,
551
- ): Promise<Result<S, E>>;
552
- span6<S, E, A1, A2, A3, A4, A5, A6>(
553
- line: number,
554
- name: string,
555
- childCtx: SpanContextInstance<Ctx>,
556
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
557
- remappedViewClass: RemappedViewConstructor | undefined,
558
- opMetadata: OpMetadata,
559
- fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6) => Result<S, E> | Promise<Result<S, E>>,
560
- a1: A1,
561
- a2: A2,
562
- a3: A3,
563
- a4: A4,
564
- a5: A5,
565
- a6: A6,
566
- ): Promise<Result<S, E>>;
567
- span7<S, E, A1, A2, A3, A4, A5, A6, A7>(
568
- line: number,
569
- name: string,
570
- childCtx: SpanContextInstance<Ctx>,
571
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
572
- remappedViewClass: RemappedViewConstructor | undefined,
573
- opMetadata: OpMetadata,
574
- fn: (
575
- ctx: SpanContext<Ctx>,
575
+ export type SpanContextInstance<Ctx extends OpContext> = SpanContext<Ctx> &
576
+ WriterState & {
577
+ _spanBuffer: SpanBuffer<Ctx['logSchema']>;
578
+ _schema: Ctx['logSchema'];
579
+ _spanLogger: SpanLoggerImpl<Ctx['logSchema']>;
580
+ _logBinding: LogBinding;
581
+ _physicalLayoutPlan: CallsitePlan<Ctx['logSchema'], Ctx>;
582
+
583
+ // Internal methods
584
+ _newCtx0(): SpanContextInstance<Ctx>;
585
+ _newCtx1(overrides: object): SpanContextInstance<Ctx>;
586
+ _spanPre(
587
+ childCtx: SpanContextInstance<Ctx>,
588
+ line: number,
589
+ name: string | number,
590
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
591
+ opMetadata: OpMetadata,
592
+ ): SpanContextInstance<Ctx>;
593
+ _spanException(buffer: SpanBuffer<Ctx['logSchema']>, error: unknown): void;
594
+
595
+ spanSync0<S, E>(
596
+ line: number,
597
+ name: string | number,
598
+ childCtx: SpanContextInstance<Ctx>,
599
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
600
+ fn: (ctx: SpanContext<Ctx>) => Result<S, E> | Promise<Result<S, E>>,
601
+ ): Result<S, E>;
602
+ span0<S, E>(
603
+ line: number,
604
+ name: string | number,
605
+ childCtx: SpanContextInstance<Ctx>,
606
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
607
+ fn: (ctx: SpanContext<Ctx>) => Result<S, E> | Promise<Result<S, E>>,
608
+ ): Promise<Result<S, E>>;
609
+ span1<S, E, A1>(
610
+ line: number,
611
+ name: string | number,
612
+ childCtx: SpanContextInstance<Ctx>,
613
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
614
+ fn: (ctx: SpanContext<Ctx>, a1: A1) => Result<S, E> | Promise<Result<S, E>>,
615
+ a1: A1,
616
+ ): Promise<Result<S, E>>;
617
+ span2<S, E, A1, A2>(
618
+ line: number,
619
+ name: string | number,
620
+ childCtx: SpanContextInstance<Ctx>,
621
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
622
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2) => Result<S, E> | Promise<Result<S, E>>,
623
+ a1: A1,
624
+ a2: A2,
625
+ ): Promise<Result<S, E>>;
626
+ span3<S, E, A1, A2, A3>(
627
+ line: number,
628
+ name: string | number,
629
+ childCtx: SpanContextInstance<Ctx>,
630
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
631
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3) => Result<S, E> | Promise<Result<S, E>>,
632
+ a1: A1,
633
+ a2: A2,
634
+ a3: A3,
635
+ ): Promise<Result<S, E>>;
636
+ span4<S, E, A1, A2, A3, A4>(
637
+ line: number,
638
+ name: string | number,
639
+ childCtx: SpanContextInstance<Ctx>,
640
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
641
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4) => Result<S, E> | Promise<Result<S, E>>,
642
+ a1: A1,
643
+ a2: A2,
644
+ a3: A3,
645
+ a4: A4,
646
+ ): Promise<Result<S, E>>;
647
+ span5<S, E, A1, A2, A3, A4, A5>(
648
+ line: number,
649
+ name: string | number,
650
+ childCtx: SpanContextInstance<Ctx>,
651
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
652
+ fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Result<S, E> | Promise<Result<S, E>>,
653
+ a1: A1,
654
+ a2: A2,
655
+ a3: A3,
656
+ a4: A4,
657
+ a5: A5,
658
+ ): Promise<Result<S, E>>;
659
+ span6<S, E, A1, A2, A3, A4, A5, A6>(
660
+ line: number,
661
+ name: string | number,
662
+ childCtx: SpanContextInstance<Ctx>,
663
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
664
+ fn: (
665
+ ctx: SpanContext<Ctx>,
666
+ a1: A1,
667
+ a2: A2,
668
+ a3: A3,
669
+ a4: A4,
670
+ a5: A5,
671
+ a6: A6,
672
+ ) => Result<S, E> | Promise<Result<S, E>>,
673
+ a1: A1,
674
+ a2: A2,
675
+ a3: A3,
676
+ a4: A4,
677
+ a5: A5,
678
+ a6: A6,
679
+ ): Promise<Result<S, E>>;
680
+ span7<S, E, A1, A2, A3, A4, A5, A6, A7>(
681
+ line: number,
682
+ name: string | number,
683
+ childCtx: SpanContextInstance<Ctx>,
684
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
685
+ fn: (
686
+ ctx: SpanContext<Ctx>,
687
+ a1: A1,
688
+ a2: A2,
689
+ a3: A3,
690
+ a4: A4,
691
+ a5: A5,
692
+ a6: A6,
693
+ a7: A7,
694
+ ) => Result<S, E> | Promise<Result<S, E>>,
576
695
  a1: A1,
577
696
  a2: A2,
578
697
  a3: A3,
@@ -580,24 +699,23 @@ export type SpanContextInstance<Ctx extends OpContext> = SpanContext<Ctx> & {
580
699
  a5: A5,
581
700
  a6: A6,
582
701
  a7: A7,
583
- ) => Result<S, E> | Promise<Result<S, E>>,
584
- a1: A1,
585
- a2: A2,
586
- a3: A3,
587
- a4: A4,
588
- a5: A5,
589
- a6: A6,
590
- a7: A7,
591
- ): Promise<Result<S, E>>;
592
- span8<S, E, A1, A2, A3, A4, A5, A6, A7, A8>(
593
- line: number,
594
- name: string,
595
- childCtx: SpanContextInstance<Ctx>,
596
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
597
- remappedViewClass: RemappedViewConstructor | undefined,
598
- opMetadata: OpMetadata,
599
- fn: (
600
- ctx: SpanContext<Ctx>,
702
+ ): Promise<Result<S, E>>;
703
+ span8<S, E, A1, A2, A3, A4, A5, A6, A7, A8>(
704
+ line: number,
705
+ name: string | number,
706
+ childCtx: SpanContextInstance<Ctx>,
707
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
708
+ fn: (
709
+ ctx: SpanContext<Ctx>,
710
+ a1: A1,
711
+ a2: A2,
712
+ a3: A3,
713
+ a4: A4,
714
+ a5: A5,
715
+ a6: A6,
716
+ a7: A7,
717
+ a8: A8,
718
+ ) => Result<S, E, Ctx['logSchema']> | Promise<Result<S, E, Ctx['logSchema']>>,
601
719
  a1: A1,
602
720
  a2: A2,
603
721
  a3: A3,
@@ -606,32 +724,45 @@ export type SpanContextInstance<Ctx extends OpContext> = SpanContext<Ctx> & {
606
724
  a6: A6,
607
725
  a7: A7,
608
726
  a8: A8,
609
- ) => Result<S, E, Ctx['logSchema']> | Promise<Result<S, E, Ctx['logSchema']>>,
610
- a1: A1,
611
- a2: A2,
612
- a3: A3,
613
- a4: A4,
614
- a5: A5,
615
- a6: A6,
616
- a7: A7,
617
- a8: A8,
618
- ): Promise<Result<S, E, Ctx['logSchema']>>;
619
- };
727
+ ): Promise<Result<S, E, Ctx['logSchema']>>;
728
+ };
620
729
  //#endregion smoo/lmao!n/spancontext-type
621
730
 
622
731
  // =============================================================================
623
732
  // SpanContext Class Factory
624
733
  // =============================================================================
625
734
 
626
- /**
627
- * Create a SpanContext class for the given schema and logBinding.
735
+ const spanContextClassCaches = new WeakMap<LogBinding, Map<string, unknown>>();
736
+
737
+ function isSpanContextClass<Ctx extends OpContext>(value: unknown): value is SpanContextClass<Ctx> {
738
+ return typeof value === 'function';
739
+ }
740
+
741
+ export function isPhysicalLayoutPlanForContext<Ctx extends OpContext>(
742
+ value: unknown,
743
+ schema: Ctx['logSchema'],
744
+ ): value is PhysicalLayoutPlan<Ctx['logSchema'], Ctx> {
745
+ return (
746
+ typeof value === 'object' &&
747
+ value !== null &&
748
+ Reflect.get(value, 'schema') === schema &&
749
+ isSpanContextClass<Ctx>(Reflect.get(value, 'SpanContextClass'))
750
+ );
751
+ }
752
+
753
+ function isFlagEvaluatorForContext<Ctx extends OpContext>(value: unknown): value is FlagEvaluator<Ctx> {
754
+ return typeof value === 'object' && value !== null && typeof Reflect.get(value, 'forContext') === 'function';
755
+ }
756
+
757
+ /**
758
+ * Create a SpanContext class for the given schema and logBinding.
628
759
  *
629
760
  * The returned class:
630
761
  * - Closes over schema/logBinding (available to all methods)
631
762
  * - Constructor takes buffer, spanLogger, tag directly (no temp object allocation)
632
763
  * - Uses prototype methods for internal methods (_spanPre, _spanException, span0-span8)
633
- * - Supports context inheritance via Object.create(parent) for child spans
634
- * - Supports context overrides via own properties shadowing inherited ones
764
+ * - Reuses the parent context as the zero-override source without allocating a carrier object
765
+ * - Context overrides use the plan's schema-specific context factory
635
766
  *
636
767
  * @param schemaOnly - Tag attribute schema
637
768
  * @param logBinding - LogBinding with schema and stats
@@ -640,61 +771,111 @@ export type SpanContextInstance<Ctx extends OpContext> = SpanContext<Ctx> & {
640
771
  export function createSpanContextClass<Ctx extends OpContext>(
641
772
  _schemaOnly: Ctx['logSchema'],
642
773
  logBinding: LogBinding,
774
+ capabilities = RUNTIME_HINT_FULL_CAPABILITIES,
775
+ userContextKeys: readonly string[] = [],
643
776
  ): SpanContextClass<Ctx> {
777
+ const canonicalUserContextKeys = [...userContextKeys].sort();
778
+ const layoutKey = canonicalUserContextKeys.join('\u0000');
779
+ const cacheKey = `${capabilities}:${layoutKey}`;
780
+ let cache = spanContextClassCaches.get(logBinding);
781
+ if (!cache) {
782
+ cache = new Map();
783
+ spanContextClassCaches.set(logBinding, cache);
784
+ }
785
+ const cached = cache.get(cacheKey);
786
+ if (isSpanContextClass<Ctx>(cached)) return cached;
787
+
788
+ const hasTag = (capabilities & RUNTIME_HINT_TAG) !== 0;
789
+ const hasLog = (capabilities & RUNTIME_HINT_LOG) !== 0;
790
+ const hasFf = (capabilities & RUNTIME_HINT_FF) !== 0;
791
+ const hasSpan = (capabilities & RUNTIME_HINT_SPAN) !== 0;
792
+ const hasResult = (capabilities & RUNTIME_HINT_RESULT) !== 0;
793
+ const hasScope = (capabilities & RUNTIME_HINT_SCOPE) !== 0;
794
+ const hasDeps = (capabilities & RUNTIME_HINT_DEPS) !== 0;
795
+ const needsLogger = hasLog || hasFf || hasScope;
644
796
  /**
645
797
  * SpanContext implementation class.
646
798
  *
647
799
  * Constructor takes core values directly so arrow functions can close over them,
648
800
  * avoiding both temp object allocation and property lookups in hot paths.
649
801
  */
650
- class SpanContextImpl {
651
- // Core properties set via constructor
652
- _buffer: SpanBuffer<Ctx['logSchema']>;
653
- _schema: Ctx['logSchema'];
654
- _spanLogger: SpanLoggerImpl<Ctx['logSchema']>;
655
- _logBinding: LogBinding<Ctx['logSchema']> = logBinding;
656
802
 
657
- // User-facing properties
658
- tag: TagWriter<Ctx['logSchema']>;
659
- log: SpanLogger<Ctx['logSchema']>;
660
- ff!: FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
661
- deps!: Record<string, unknown>;
803
+ class SpanContextImpl implements WriterState {
804
+ declare readonly _spanBuffer: SpanBuffer<Ctx['logSchema']>;
805
+ declare _buffer: AnySpanBuffer;
806
+ declare readonly _appendLogEntry: WriterState['_appendLogEntry'];
807
+ declare _schema: Ctx['logSchema'];
808
+ declare _spanLogger: SpanLoggerImpl<Ctx['logSchema']>;
809
+ declare _logBinding: LogBinding<Ctx['logSchema']>;
810
+ declare _physicalLayoutPlan: CallsitePlan<Ctx['logSchema'], Ctx>;
811
+
812
+ declare tag: TagWriter<Ctx['logSchema']>;
813
+ declare log: SpanLogger<Ctx['logSchema']>;
814
+ declare ff: FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>;
815
+ declare deps: Record<string, unknown>;
662
816
 
663
- // Index signature for user context properties (env, requestId, etc.)
664
817
  [key: string]: unknown;
665
818
 
666
- // Arrow functions that close over constructor args directly
667
- setScope: (attributes: ScopeUpdate<Ctx['logSchema']> | null) => void;
668
- ok: <V>(value: V) => Ok<V, Ctx['logSchema']>;
669
- err: <E>(error: E) => Err<E, Ctx['logSchema']>;
670
- span: SpanFn<Ctx>;
671
- spanSync: SpanSyncFn<Ctx>;
819
+ declare setScope: (attributes: ScopeUpdate<Ctx['logSchema']> | null) => void;
820
+ declare ok: <V>(value: V) => Ok<V, Ctx['logSchema']>;
821
+ declare err: <E>(error: E) => Err<E, Ctx['logSchema']>;
822
+ declare span: SpanFn<Ctx>;
823
+ declare spanSync: SpanSyncFn<Ctx>;
672
824
 
673
825
  constructor(
674
826
  buffer: SpanBuffer<Ctx['logSchema']>,
675
827
  schema: Ctx['logSchema'],
676
- spanLogger: SpanLoggerImpl<Ctx['logSchema']>,
677
- tag: TagWriter<Ctx['logSchema']>,
828
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
829
+ contextSource?: Record<string, unknown>,
830
+ contextOverrides?: Record<string, unknown>,
831
+ deps?: Record<string, unknown>,
832
+ ffSource?: FlagEvaluator<Ctx> | (FeatureFlagEvaluator<Ctx> & InferFeatureFlagsWithContext<Ctx>),
678
833
  ) {
679
834
  //#region smoo/lmao!n/codegen-destructured-context
680
835
  // Destructured-context assembly (01g): every property an op destructures —
681
836
  // tag, log, scope (setScope), ok, err, span — is wired here as a closed-over
682
837
  // field/closure so `op(({ tag, log, span, ok, err }) => ...)` needs no ctx drilling.
838
+ this._spanBuffer = buffer;
683
839
  this._buffer = buffer;
840
+ this._appendLogEntry = callsitePlan.appendLogEntry;
684
841
  this._schema = schema;
685
- this._spanLogger = spanLogger;
686
- this.tag = tag;
687
- this.log = spanLogger;
842
+ this._logBinding = logBinding;
843
+ this._physicalLayoutPlan = callsitePlan;
844
+ const spanLogger = callsitePlan.newSpanLogger?.(this);
845
+ const tag = callsitePlan.newTagWriter?.(this);
846
+ if (needsLogger) {
847
+ if (!spanLogger) throw new TypeError('SpanContext capability requires a logger');
848
+ this._spanLogger = spanLogger;
849
+ }
850
+ if (hasTag) {
851
+ if (!tag) throw new TypeError('SpanContext tag capability requires a tag writer');
852
+ this.tag = tag;
853
+ }
854
+ if (hasLog && spanLogger) this.log = spanLogger;
855
+ if (hasDeps) this.deps = deps ?? {};
856
+ if (hasFf && ffSource) this.ff = ffSource.forContext(this);
857
+ for (const key of canonicalUserContextKeys) {
858
+ let value = contextSource?.[key];
859
+ if (contextOverrides && Object.prototype.propertyIsEnumerable.call(contextOverrides, key)) {
860
+ const overrideValue = contextOverrides[key];
861
+ if (overrideValue !== undefined) value = overrideValue;
862
+ }
863
+ this[key] = value;
864
+ }
688
865
 
689
866
  // Regular functions close over constructor args directly - no property lookups
690
867
  // Using regular function (not arrow) allows destructuring while closing over args
691
- this.setScope = (attributes: ScopeUpdate<Ctx['logSchema']> | null): void => {
692
- spanLogger._setScope(attributes ?? {});
693
- };
694
-
695
- this.ok = <V>(value: V): Ok<V, Ctx['logSchema']> => new Ok<V, Ctx['logSchema']>(value, schema, buffer);
868
+ if (hasScope) {
869
+ if (!spanLogger) throw new TypeError('SpanContext scope capability requires a logger');
870
+ this.setScope = (attributes: ScopeUpdate<Ctx['logSchema']> | null): void => {
871
+ spanLogger._setScope(attributes ?? {});
872
+ };
873
+ }
696
874
 
697
- this.err = <E>(error: E): Err<E, Ctx['logSchema']> => new Err<E, Ctx['logSchema']>(error, schema, buffer);
875
+ if (hasResult) {
876
+ this.ok = <V>(value: V): Ok<V, Ctx['logSchema']> => new Ok<V, Ctx['logSchema']>(value, this);
877
+ this.err = <E>(error: E): Err<E, Ctx['logSchema']> => new Err<E, Ctx['logSchema']>(error, this);
878
+ }
698
879
  //#endregion smoo/lmao!n/codegen-destructured-context
699
880
 
700
881
  //#region smoo/lmao!n/context-flow-span-promise
@@ -706,199 +887,167 @@ export function createSpanContextClass<Ctx extends OpContext>(
706
887
  // span uses regular function to access `arguments` (no ...rest spread allocation)
707
888
  // Closes over `self` for calling prototype methods
708
889
  // Named function for better stack traces
709
- const self = this;
710
- const span: SpanFn<Ctx> = function span(
711
- nameOrLine: string | number,
712
- _arg1?: unknown,
713
- _arg2?: unknown,
714
- _arg3?: unknown,
715
- _arg4?: unknown,
716
- _arg5?: unknown,
717
- _arg6?: unknown,
718
- _arg7?: unknown,
719
- _arg8?: unknown,
720
- _arg9?: unknown,
721
- _arg10?: unknown,
722
- _arg11?: unknown,
723
- ): Promise<Result<unknown, unknown>> {
724
- // Use arguments.length instead of ...rest to avoid array allocation
725
- const len = arguments.length;
726
-
727
- // Detect call pattern:
728
- // - span(name, fn) - len=2, typeof arg0 === 'string'
729
- // - span(line, name, fn) - len=3, typeof arg0 === 'number'
730
- // - span(name, overrides, fn) - len=3, typeof arg0 === 'string', typeof arg1 === 'object'
731
- // - span(line, name, overrides, fn) - len=4, typeof arg0 === 'number', typeof arg2 === 'object'
732
- // Plus additional args for span arguments
733
-
734
- const hasLine = typeof nameOrLine === 'number';
735
- const spanLine = hasLine ? nameOrLine : 0;
736
- const spanName = hasLine ? readStringArgument(arguments, 1, 'span name') : nameOrLine;
737
-
738
- // Index where fn/op or overrides starts
739
- const checkIdx = hasLine ? 2 : 1;
740
- const maybeOverrides = arguments[checkIdx];
741
-
742
- // Check if it's an overrides object (not Op, not function)
743
- const hasOverrides =
744
- maybeOverrides !== null &&
745
- typeof maybeOverrides === 'object' &&
746
- !(maybeOverrides instanceof Op) &&
747
- typeof maybeOverrides !== 'function';
748
-
749
- const fnIdx = checkIdx + (hasOverrides ? 1 : 0);
750
- const target = resolveSpanTarget<Ctx>(arguments[fnIdx], self._buffer);
751
-
752
- // Create child context - use _newCtx0 or _newCtx1 based on overrides
753
- const childCtx = hasOverrides ? self._newCtx1(maybeOverrides) : self._newCtx0();
754
-
755
- // Dispatch to monomorphic methods with all Op properties extracted
756
- const argCount = len - fnIdx - 1;
757
- switch (argCount) {
758
- case 0:
759
- return self.span0(
760
- spanLine,
761
- spanName,
762
- childCtx,
763
- target.SpanBufferClass,
764
- target.remappedViewClass,
765
- target.opMetadata,
766
- target.fn,
767
- );
768
- case 1:
769
- return self.span1(
770
- spanLine,
771
- spanName,
772
- childCtx,
773
- target.SpanBufferClass,
774
- target.remappedViewClass,
775
- target.opMetadata,
776
- target.fn,
777
- arguments[fnIdx + 1],
778
- );
779
- case 2:
780
- return self.span2(
781
- spanLine,
782
- spanName,
783
- childCtx,
784
- target.SpanBufferClass,
785
- target.remappedViewClass,
786
- target.opMetadata,
787
- target.fn,
788
- arguments[fnIdx + 1],
789
- arguments[fnIdx + 2],
790
- );
791
- case 3:
792
- return self.span3(
793
- spanLine,
794
- spanName,
795
- childCtx,
796
- target.SpanBufferClass,
797
- target.remappedViewClass,
798
- target.opMetadata,
799
- target.fn,
800
- arguments[fnIdx + 1],
801
- arguments[fnIdx + 2],
802
- arguments[fnIdx + 3],
803
- );
804
- case 4:
805
- return self.span4(
806
- spanLine,
807
- spanName,
808
- childCtx,
809
- target.SpanBufferClass,
810
- target.remappedViewClass,
811
- target.opMetadata,
812
- target.fn,
813
- arguments[fnIdx + 1],
814
- arguments[fnIdx + 2],
815
- arguments[fnIdx + 3],
816
- arguments[fnIdx + 4],
817
- );
818
- case 5:
819
- return self.span5(
820
- spanLine,
821
- spanName,
822
- childCtx,
823
- target.SpanBufferClass,
824
- target.remappedViewClass,
825
- target.opMetadata,
826
- target.fn,
827
- arguments[fnIdx + 1],
828
- arguments[fnIdx + 2],
829
- arguments[fnIdx + 3],
830
- arguments[fnIdx + 4],
831
- arguments[fnIdx + 5],
832
- );
833
- case 6:
834
- return self.span6(
835
- spanLine,
836
- spanName,
837
- childCtx,
838
- target.SpanBufferClass,
839
- target.remappedViewClass,
840
- target.opMetadata,
841
- target.fn,
842
- arguments[fnIdx + 1],
843
- arguments[fnIdx + 2],
844
- arguments[fnIdx + 3],
845
- arguments[fnIdx + 4],
846
- arguments[fnIdx + 5],
847
- arguments[fnIdx + 6],
848
- );
849
- case 7:
850
- return self.span7(
851
- spanLine,
852
- spanName,
853
- childCtx,
854
- target.SpanBufferClass,
855
- target.remappedViewClass,
856
- target.opMetadata,
857
- target.fn,
858
- arguments[fnIdx + 1],
859
- arguments[fnIdx + 2],
860
- arguments[fnIdx + 3],
861
- arguments[fnIdx + 4],
862
- arguments[fnIdx + 5],
863
- arguments[fnIdx + 6],
864
- arguments[fnIdx + 7],
865
- );
866
- case 8:
867
- return self.span8(
868
- spanLine,
869
- spanName,
870
- childCtx,
871
- target.SpanBufferClass,
872
- target.remappedViewClass,
873
- target.opMetadata,
874
- target.fn,
875
- arguments[fnIdx + 1],
876
- arguments[fnIdx + 2],
877
- arguments[fnIdx + 3],
878
- arguments[fnIdx + 4],
879
- arguments[fnIdx + 5],
880
- arguments[fnIdx + 6],
881
- arguments[fnIdx + 7],
882
- arguments[fnIdx + 8],
883
- );
884
- default:
885
- throw new Error(`span() supports up to 8 arguments, got ${argCount}`);
886
- }
887
- };
888
- this.span = span;
889
-
890
- this.spanSync = function spanSync<S, E>(name: string, fn: (ctx: SpanContext<Ctx>) => Result<S, E>): Result<S, E> {
891
- const childCtx = self._newCtx0();
892
- return self.spanSync0(
893
- 0,
894
- name,
895
- childCtx,
896
- getBufferConstructor(self._buffer),
897
- undefined,
898
- self._buffer._opMetadata,
899
- fn,
900
- );
901
- };
890
+ if (hasSpan) {
891
+ const self = this;
892
+ const span: SpanFn<Ctx> = function span(
893
+ nameOrLine: string | number,
894
+ _arg1?: unknown,
895
+ _arg2?: unknown,
896
+ _arg3?: unknown,
897
+ _arg4?: unknown,
898
+ _arg5?: unknown,
899
+ _arg6?: unknown,
900
+ _arg7?: unknown,
901
+ _arg8?: unknown,
902
+ _arg9?: unknown,
903
+ _arg10?: unknown,
904
+ _arg11?: unknown,
905
+ ): Promise<Result<unknown, unknown>> {
906
+ // Use arguments.length instead of ...rest to avoid array allocation
907
+ const len = arguments.length;
908
+
909
+ // Detect call pattern:
910
+ // - span(name, fn) - len=2, typeof arg0 === 'string'
911
+ // - span(line, name, fn) - len=3, typeof arg0 === 'number'
912
+ // - span(name, overrides, fn) - len=3, typeof arg0 === 'string', typeof arg1 === 'object'
913
+ // - span(line, name, overrides, fn) - len=4, typeof arg0 === 'number', typeof arg2 === 'object'
914
+ // Plus additional args for span arguments
915
+
916
+ const hasLine = typeof nameOrLine === 'number';
917
+ const spanLine = hasLine ? nameOrLine : 0;
918
+ const spanName = hasLine ? readStringArgument(arguments, 1, 'span name') : nameOrLine;
919
+
920
+ // Index where fn/op or overrides starts
921
+ const checkIdx = hasLine ? 2 : 1;
922
+ const maybeOverrides = arguments[checkIdx];
923
+
924
+ // Check if it's an overrides object (not Op, not function)
925
+ const hasOverrides =
926
+ maybeOverrides !== null &&
927
+ typeof maybeOverrides === 'object' &&
928
+ !isOpLike(maybeOverrides) &&
929
+ typeof maybeOverrides !== 'function';
930
+
931
+ const fnIdx = checkIdx + (hasOverrides ? 1 : 0);
932
+ const target = resolveSpanTarget<Ctx>(
933
+ arguments[fnIdx],
934
+ self._physicalLayoutPlan,
935
+ self._spanBuffer._opMetadata,
936
+ );
937
+ const childCtx = asSpanContextInstance<Ctx>(
938
+ hasOverrides ? target.callsitePlan.newCtx1(self, maybeOverrides) : target.callsitePlan.newCtx0(self),
939
+ );
940
+
941
+ // Dispatch to monomorphic methods with all Op properties extracted
942
+ const argCount = len - fnIdx - 1;
943
+ switch (argCount) {
944
+ case 0:
945
+ return self.span0(spanLine, spanName, childCtx, target.callsitePlan, target.fn);
946
+ case 1:
947
+ return self.span1(spanLine, spanName, childCtx, target.callsitePlan, target.fn, arguments[fnIdx + 1]);
948
+ case 2:
949
+ return self.span2(
950
+ spanLine,
951
+ spanName,
952
+ childCtx,
953
+ target.callsitePlan,
954
+ target.fn,
955
+ arguments[fnIdx + 1],
956
+ arguments[fnIdx + 2],
957
+ );
958
+ case 3:
959
+ return self.span3(
960
+ spanLine,
961
+ spanName,
962
+ childCtx,
963
+ target.callsitePlan,
964
+ target.fn,
965
+ arguments[fnIdx + 1],
966
+ arguments[fnIdx + 2],
967
+ arguments[fnIdx + 3],
968
+ );
969
+ case 4:
970
+ return self.span4(
971
+ spanLine,
972
+ spanName,
973
+ childCtx,
974
+ target.callsitePlan,
975
+ target.fn,
976
+ arguments[fnIdx + 1],
977
+ arguments[fnIdx + 2],
978
+ arguments[fnIdx + 3],
979
+ arguments[fnIdx + 4],
980
+ );
981
+ case 5:
982
+ return self.span5(
983
+ spanLine,
984
+ spanName,
985
+ childCtx,
986
+ target.callsitePlan,
987
+ target.fn,
988
+ arguments[fnIdx + 1],
989
+ arguments[fnIdx + 2],
990
+ arguments[fnIdx + 3],
991
+ arguments[fnIdx + 4],
992
+ arguments[fnIdx + 5],
993
+ );
994
+ case 6:
995
+ return self.span6(
996
+ spanLine,
997
+ spanName,
998
+ childCtx,
999
+ target.callsitePlan,
1000
+ target.fn,
1001
+ arguments[fnIdx + 1],
1002
+ arguments[fnIdx + 2],
1003
+ arguments[fnIdx + 3],
1004
+ arguments[fnIdx + 4],
1005
+ arguments[fnIdx + 5],
1006
+ arguments[fnIdx + 6],
1007
+ );
1008
+ case 7:
1009
+ return self.span7(
1010
+ spanLine,
1011
+ spanName,
1012
+ childCtx,
1013
+ target.callsitePlan,
1014
+ target.fn,
1015
+ arguments[fnIdx + 1],
1016
+ arguments[fnIdx + 2],
1017
+ arguments[fnIdx + 3],
1018
+ arguments[fnIdx + 4],
1019
+ arguments[fnIdx + 5],
1020
+ arguments[fnIdx + 6],
1021
+ arguments[fnIdx + 7],
1022
+ );
1023
+ case 8:
1024
+ return self.span8(
1025
+ spanLine,
1026
+ spanName,
1027
+ childCtx,
1028
+ target.callsitePlan,
1029
+ target.fn,
1030
+ arguments[fnIdx + 1],
1031
+ arguments[fnIdx + 2],
1032
+ arguments[fnIdx + 3],
1033
+ arguments[fnIdx + 4],
1034
+ arguments[fnIdx + 5],
1035
+ arguments[fnIdx + 6],
1036
+ arguments[fnIdx + 7],
1037
+ arguments[fnIdx + 8],
1038
+ );
1039
+ default:
1040
+ throw new Error(`span() supports up to 8 arguments, got ${argCount}`);
1041
+ }
1042
+ };
1043
+ this.span = span;
1044
+
1045
+ this.spanSync = function spanSync<S, E>(name: string, op: Op<Ctx, [], S, E>): Result<S, E> {
1046
+ const callsitePlan = op.callsitePlan;
1047
+ const childCtx = asSpanContextInstance<Ctx>(callsitePlan.newCtx0(self));
1048
+ return self.spanSync0(0, name, childCtx, callsitePlan, op.fn);
1049
+ };
1050
+ }
902
1051
  //#endregion smoo/lmao!n/context-flow-span-promise
903
1052
  }
904
1053
 
@@ -911,36 +1060,36 @@ export function createSpanContextClass<Ctx extends OpContext>(
911
1060
  }
912
1061
 
913
1062
  get module(): import('./opContext/opTypes.js').OpMetadata {
914
- return this._buffer._opMetadata;
1063
+ return this._spanBuffer._opMetadata;
915
1064
  }
916
1065
 
917
1066
  get callee_package(): string {
918
- return this._buffer._opMetadata.package_name;
1067
+ return this._spanBuffer._opMetadata.package_name;
919
1068
  }
920
1069
 
921
1070
  get callee_file(): string {
922
- return this._buffer._opMetadata.package_file;
1071
+ return this._spanBuffer._opMetadata.package_file;
923
1072
  }
924
1073
 
925
1074
  get callee_line(): number {
926
1075
  // Access the line_values array directly to read line number at row 0
927
1076
  // line_values is a Float64Array per the system schema (LazyNumberSchema)
928
- return this._buffer.line_values[0];
1077
+ return this._spanBuffer.line_values[0];
929
1078
  }
930
1079
 
931
1080
  get callee_git_sha(): string {
932
- return this._buffer._opMetadata.git_sha;
1081
+ return this._spanBuffer._opMetadata.git_sha;
933
1082
  }
934
1083
 
935
1084
  get buffer(): SpanBuffer<Ctx['logSchema']> {
936
- return this._buffer;
1085
+ return this._spanBuffer;
937
1086
  }
938
1087
 
939
1088
  //#region smoo/lmao!n/scope-attributes.read
940
1089
  // 01i read-only scope view: the immutable _scopeValues snapshot (setScope is wired in the
941
1090
  // destructured-context region; the immutable merge is _setScope in spanLoggerGenerator).
942
1091
  get scope(): Readonly<Partial<InferSchema<Ctx['logSchema']>>> {
943
- return this._buffer._scopeValues;
1092
+ return this._spanBuffer._scopeValues;
944
1093
  }
945
1094
  //#endregion smoo/lmao!n/scope-attributes.read
946
1095
 
@@ -948,6 +1097,15 @@ export function createSpanContextClass<Ctx extends OpContext>(
948
1097
  // Internal methods (on prototype)
949
1098
  // =========================================================================
950
1099
 
1100
+ _appendWriterEntry(entryType: number): number {
1101
+ if (this._buffer._writeIndex >= this._buffer._capacity) {
1102
+ this._buffer = this._buffer.getOrCreateOverflow();
1103
+ this._spanLogger._prefillScopedAttributesOn(this._buffer);
1104
+ }
1105
+ const traceRoot = this._buffer._traceRoot;
1106
+ return this._appendLogEntry(traceRoot, this._buffer, entryType);
1107
+ }
1108
+
951
1109
  /**
952
1110
  * Create a new child context with prototype chain inheritance.
953
1111
  * Called by transformer for spans without overrides.
@@ -955,7 +1113,7 @@ export function createSpanContextClass<Ctx extends OpContext>(
955
1113
  * Transformer emits: ctx.span0(line, name, ctx._newCtx0(), fn)
956
1114
  */
957
1115
  _newCtx0(): SpanContextInstance<Ctx> {
958
- return createInheritedContext(this);
1116
+ return asSpanContextInstance<Ctx>(this._physicalLayoutPlan.newCtx0(this));
959
1117
  }
960
1118
 
961
1119
  /**
@@ -965,7 +1123,7 @@ export function createSpanContextClass<Ctx extends OpContext>(
965
1123
  * Transformer emits: ctx.span0(line, name, ctx._newCtx1({ requestId }), fn)
966
1124
  */
967
1125
  _newCtx1(overrides: object): SpanContextInstance<Ctx> {
968
- return createInheritedContextWithOverrides(this, overrides);
1126
+ return asSpanContextInstance<Ctx>(this._physicalLayoutPlan.newCtx1(this, overrides));
969
1127
  }
970
1128
 
971
1129
  /**
@@ -979,273 +1137,49 @@ export function createSpanContextClass<Ctx extends OpContext>(
979
1137
  * @param line - Source line number (0 if not provided by transformer)
980
1138
  * @param name - Child span name
981
1139
  * @param SpanBufferClass - Buffer class to use (Op's class or parent's class for plain functions)
982
- * @param remappedViewClass - Optional view class for prefixed ops (wraps buffer for Arrow conversion)
1140
+ * @param remapDescriptor - Optional immutable cold-path output mapping
983
1141
  * @param opMetadata - Metadata for the executing op (Op's metadata or parent's for plain functions)
984
1142
  */
985
1143
  //#region smoo/lmao!n/context-flow-child-span
986
1144
  // 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.
1145
+ // _spanPre creates the child through the planned schema/capacity, attaches the immutable
1146
+ // cold-path remap descriptor to the raw buffer, registers it, and writes row 0.
991
1147
  _spanPre(
992
1148
  childCtx: SpanContextInstance<Ctx>,
993
1149
  line: number,
994
- name: string,
995
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
996
- remappedViewClass: RemappedViewConstructor | undefined,
1150
+ name: string | number,
1151
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
997
1152
  opMetadata: OpMetadata,
998
1153
  ): SpanContextInstance<Ctx> {
999
- // Get Op's schema for cross-library calls (child may have different schema than parent)
1000
- const childSchema = SpanBufferClass.schema;
1001
-
1002
- // Use buffer strategy for child span creation (supports both JS and WASM buffers)
1003
- // Pass schema for cross-library calls where child has different schema than parent
1004
- const createdBuffer = this._buffer._traceRoot.tracer.bufferStrategy.createChildSpanBuffer(
1005
- this._buffer, // parentBuffer
1006
- this._buffer._opMetadata, // callsiteMetadata - WHO called span() (for row 0)
1007
- opMetadata, // opMetadata - WHICH op is executing (for rows 1+)
1008
- undefined, // capacity - use default
1009
- childSchema, // schema - Op's schema for correct tag methods
1154
+ const childSchema = callsitePlan.schema;
1155
+ const createdBuffer = this._spanBuffer._traceRoot.tracer.bufferStrategy.createChildSpanBuffer(
1156
+ this._spanBuffer,
1157
+ this._spanBuffer._opMetadata,
1158
+ opMetadata,
1159
+ callsitePlan.capacityTier,
1160
+ childSchema,
1161
+ callsitePlan.SpanBufferClass,
1010
1162
  );
1011
- if (!isSpanBufferForSchema(createdBuffer, childSchema)) {
1012
- throw new TypeError('Child span buffer does not match the requested schema');
1013
- }
1014
1163
  const childBuffer = createdBuffer;
1015
-
1016
- // Why wrap buffer: RemappedBufferView translates prefixed column names during Arrow conversion
1017
- // Parent sees remapped names, child sees unprefixed names (transparent to child)
1018
- const bufferOrView = remappedViewClass ? new remappedViewClass(childBuffer) : childBuffer;
1019
-
1020
- // Why push wrapped buffer: Parent's _children see remapped names for Arrow conversion
1021
- this._buffer._children.push(bufferOrView);
1022
-
1023
- // Write span-start for child span (row 0) and pre-initialize span-end (row 1)
1024
- writeSpanStart(childBuffer, name);
1025
-
1026
- // Write line number to row 0 (line() takes pos and value)
1164
+ childBuffer._remapDescriptor = callsitePlan.remapDescriptor ?? undefined;
1165
+ callsitePlan.appenders.writeSpanStart(childBuffer, name);
1027
1166
  childBuffer.line(0, line);
1028
- const childLogger = createSpanLogger(childSchema, childBuffer);
1029
- const childTagAPI = createTagWriter(childSchema, childBuffer);
1030
-
1031
- // Cast to impl for property assignment
1032
- const ctx = childCtx;
1033
-
1034
- // ═══════════════════════════════════════════════════════════════════
1035
- // PROPERTY ASSIGNMENT ORDER: HOT → COLD (V8 in-object slots optimization)
1036
- // First ~10-12 properties get fast in-object slots per spec
1037
- // ═══════════════════════════════════════════════════════════════════
1038
-
1039
- // SLOT 1-4: HOTTEST - accessed on every span operation
1040
- ctx._buffer = childBuffer;
1041
- ctx._spanLogger = childLogger;
1042
- ctx.tag = childTagAPI;
1043
- ctx.log = childLogger;
1044
-
1045
- // SLOT 5-7: HOT - reserved keys copied from parent for O(1) access
1046
- ctx.deps = this.deps;
1047
- // Create child-bound FF evaluator so flag access logs to child buffer
1048
- // If no evaluator (ff is EMPTY_SCOPE), just copy the reference
1049
- ctx.ff = this.ff.forContext ? this.ff.forContext(ctx) : this.ff;
1050
- // Note: user-defined extras (env, requestId, etc.) inherited via prototype chain
1051
-
1052
- // SLOT 8-11: WARM - function properties (created per-context for destructuring)
1053
- // Regular functions close over local variables directly - no property lookups
1054
- const childSpan: SpanFn<Ctx> = function span(
1055
- nameOrLine: string | number,
1056
- _arg1?: unknown,
1057
- _arg2?: unknown,
1058
- _arg3?: unknown,
1059
- _arg4?: unknown,
1060
- _arg5?: unknown,
1061
- _arg6?: unknown,
1062
- _arg7?: unknown,
1063
- _arg8?: unknown,
1064
- _arg9?: unknown,
1065
- _arg10?: unknown,
1066
- _arg11?: unknown,
1067
- ): Promise<Result<unknown, unknown>> {
1068
- const len = arguments.length;
1069
- const hasLine = typeof nameOrLine === 'number';
1070
- const spanLine = hasLine ? nameOrLine : 0;
1071
- const spanName = hasLine ? readStringArgument(arguments, 1, 'span name') : nameOrLine;
1072
- const checkIdx = hasLine ? 2 : 1;
1073
- const maybeOverrides = arguments[checkIdx];
1074
- const hasOverrides =
1075
- maybeOverrides !== null &&
1076
- typeof maybeOverrides === 'object' &&
1077
- !(maybeOverrides instanceof Op) &&
1078
- typeof maybeOverrides !== 'function';
1079
- const fnIdx = checkIdx + (hasOverrides ? 1 : 0);
1080
- const target = resolveSpanTarget<Ctx>(arguments[fnIdx], childBuffer);
1081
-
1082
- // Create child context - use _newCtx0 or _newCtx1 based on overrides
1083
- const newChildCtx = hasOverrides ? ctx._newCtx1(maybeOverrides) : ctx._newCtx0();
1084
- const argCount = len - fnIdx - 1;
1085
- switch (argCount) {
1086
- case 0:
1087
- return ctx.span0(
1088
- spanLine,
1089
- spanName,
1090
- newChildCtx,
1091
- target.SpanBufferClass,
1092
- target.remappedViewClass,
1093
- target.opMetadata,
1094
- target.fn,
1095
- );
1096
- case 1:
1097
- return ctx.span1(
1098
- spanLine,
1099
- spanName,
1100
- newChildCtx,
1101
- target.SpanBufferClass,
1102
- target.remappedViewClass,
1103
- target.opMetadata,
1104
- target.fn,
1105
- arguments[fnIdx + 1],
1106
- );
1107
- case 2:
1108
- return ctx.span2(
1109
- spanLine,
1110
- spanName,
1111
- newChildCtx,
1112
- target.SpanBufferClass,
1113
- target.remappedViewClass,
1114
- target.opMetadata,
1115
- target.fn,
1116
- arguments[fnIdx + 1],
1117
- arguments[fnIdx + 2],
1118
- );
1119
- case 3:
1120
- return ctx.span3(
1121
- spanLine,
1122
- spanName,
1123
- newChildCtx,
1124
- target.SpanBufferClass,
1125
- target.remappedViewClass,
1126
- target.opMetadata,
1127
- target.fn,
1128
- arguments[fnIdx + 1],
1129
- arguments[fnIdx + 2],
1130
- arguments[fnIdx + 3],
1131
- );
1132
- case 4:
1133
- return ctx.span4(
1134
- spanLine,
1135
- spanName,
1136
- newChildCtx,
1137
- target.SpanBufferClass,
1138
- target.remappedViewClass,
1139
- target.opMetadata,
1140
- target.fn,
1141
- arguments[fnIdx + 1],
1142
- arguments[fnIdx + 2],
1143
- arguments[fnIdx + 3],
1144
- arguments[fnIdx + 4],
1145
- );
1146
- case 5:
1147
- return ctx.span5(
1148
- spanLine,
1149
- spanName,
1150
- newChildCtx,
1151
- target.SpanBufferClass,
1152
- target.remappedViewClass,
1153
- target.opMetadata,
1154
- target.fn,
1155
- arguments[fnIdx + 1],
1156
- arguments[fnIdx + 2],
1157
- arguments[fnIdx + 3],
1158
- arguments[fnIdx + 4],
1159
- arguments[fnIdx + 5],
1160
- );
1161
- case 6:
1162
- return ctx.span6(
1163
- spanLine,
1164
- spanName,
1165
- newChildCtx,
1166
- target.SpanBufferClass,
1167
- target.remappedViewClass,
1168
- target.opMetadata,
1169
- target.fn,
1170
- arguments[fnIdx + 1],
1171
- arguments[fnIdx + 2],
1172
- arguments[fnIdx + 3],
1173
- arguments[fnIdx + 4],
1174
- arguments[fnIdx + 5],
1175
- arguments[fnIdx + 6],
1176
- );
1177
- case 7:
1178
- return ctx.span7(
1179
- spanLine,
1180
- spanName,
1181
- newChildCtx,
1182
- target.SpanBufferClass,
1183
- target.remappedViewClass,
1184
- target.opMetadata,
1185
- target.fn,
1186
- arguments[fnIdx + 1],
1187
- arguments[fnIdx + 2],
1188
- arguments[fnIdx + 3],
1189
- arguments[fnIdx + 4],
1190
- arguments[fnIdx + 5],
1191
- arguments[fnIdx + 6],
1192
- arguments[fnIdx + 7],
1193
- );
1194
- case 8:
1195
- return ctx.span8(
1196
- spanLine,
1197
- spanName,
1198
- newChildCtx,
1199
- target.SpanBufferClass,
1200
- target.remappedViewClass,
1201
- target.opMetadata,
1202
- target.fn,
1203
- arguments[fnIdx + 1],
1204
- arguments[fnIdx + 2],
1205
- arguments[fnIdx + 3],
1206
- arguments[fnIdx + 4],
1207
- arguments[fnIdx + 5],
1208
- arguments[fnIdx + 6],
1209
- arguments[fnIdx + 7],
1210
- arguments[fnIdx + 8],
1211
- );
1212
- default:
1213
- throw new Error(`span() supports up to 8 arguments, got ${argCount}`);
1214
- }
1215
- };
1216
- ctx.span = childSpan;
1217
-
1218
- ctx.spanSync = function spanSync<S, E>(
1219
- name: string,
1220
- fn: (syncCtx: SpanContext<Ctx>) => Result<S, E>,
1221
- ): Result<S, E> {
1222
- const newChildCtx = ctx._newCtx0();
1223
- return ctx.spanSync0(
1224
- 0,
1225
- name,
1226
- newChildCtx,
1227
- getBufferConstructor(childBuffer),
1228
- undefined,
1229
- childBuffer._opMetadata,
1230
- fn,
1231
- );
1232
- };
1233
-
1234
- ctx.ok = function ok<V>(value: V): Ok<V, Ctx['logSchema']> {
1235
- return new Ok<V, Ctx['logSchema']>(value, childSchema, childBuffer);
1236
- };
1237
- ctx.err = function err<E>(error: E): Err<E, Ctx['logSchema']> {
1238
- return new Err<E, Ctx['logSchema']>(error, childSchema, childBuffer);
1239
- };
1240
- ctx.setScope = function setScope(attributes: ScopeUpdate<Ctx['logSchema']> | null): void {
1241
- childLogger._setScope(attributes ?? {});
1242
- };
1243
-
1244
- // SLOT 12+: COLD - internal/rarely accessed
1245
- ctx._schema = childSchema;
1246
- ctx._logBinding = logBinding;
1247
-
1248
- return ctx;
1167
+
1168
+ const childFfSource = Object.hasOwn(this, 'ff')
1169
+ ? this.ff
1170
+ : this._spanBuffer._traceRoot.tracer.getFlagEvaluatorForContext();
1171
+ if (!isFlagEvaluatorForContext<Ctx>(childFfSource)) {
1172
+ throw new TypeError('Span context requires a context evaluator');
1173
+ }
1174
+ return new callsitePlan.SpanContextClass(
1175
+ childBuffer,
1176
+ childSchema,
1177
+ callsitePlan,
1178
+ childCtx,
1179
+ undefined,
1180
+ this.deps,
1181
+ childFfSource,
1182
+ );
1249
1183
  }
1250
1184
  //#endregion smoo/lmao!n/context-flow-child-span
1251
1185
 
@@ -1255,8 +1189,7 @@ export function createSpanContextClass<Ctx extends OpContext>(
1255
1189
  * Called in catch blocks of span methods.
1256
1190
  */
1257
1191
  _spanException(childBuffer: SpanBuffer<Ctx['logSchema']>, error: unknown): void {
1258
- // Write entry_type and timestamp via TraceRoot (platform-specific)
1259
- childBuffer._traceRoot.writeSpanEnd(childBuffer, ENTRY_TYPE_SPAN_EXCEPTION);
1192
+ writeSpanEndEntry(childBuffer, ENTRY_TYPE_SPAN_EXCEPTION);
1260
1193
  const errorMessage = error instanceof Error ? error.message : String(error);
1261
1194
  const errorStack = error instanceof Error ? error.stack : undefined;
1262
1195
  childBuffer.message(1, errorMessage);
@@ -1266,27 +1199,600 @@ export function createSpanContextClass<Ctx extends OpContext>(
1266
1199
  }
1267
1200
  //#endregion smoo/lmao!n/lmao-entry-span-lifecycle-entry-types.exception
1268
1201
 
1202
+ private _spanAutoPre<Args extends unknown[], S, E>(
1203
+ line: number,
1204
+ name: string,
1205
+ op: Op<Ctx, Args, S, E>,
1206
+ ): SpanContextInstance<Ctx> {
1207
+ const child = asSpanContextInstance<Ctx>(op.callsitePlan.newCtx0(this));
1208
+ return this._spanPre(child, line, name, op.callsitePlan, op.metadata);
1209
+ }
1210
+
1211
+ spanAuto0<S, E>(line: number, name: string, op: Op<Ctx, [], S, E>): Result<S, E> | Promise<Result<S, E>> {
1212
+ const ctx = this._spanAutoPre(line, name, op);
1213
+ const buffer = ctx._spanBuffer;
1214
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1215
+ let isAsync = false;
1216
+ try {
1217
+ const result = op.fn(ctx);
1218
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1219
+ isAsync = true;
1220
+ return this._spanAutoAsync0(ctx, buffer, op, result);
1221
+ }
1222
+ writeSpanEnd(buffer, result);
1223
+ return result;
1224
+ } catch (error) {
1225
+ this._spanException(buffer, error);
1226
+ throw error;
1227
+ } finally {
1228
+ if (!isAsync) {
1229
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1230
+ }
1231
+ }
1232
+ }
1233
+
1234
+ private async _spanAutoAsync0<S, E>(
1235
+ ctx: SpanContextInstance<Ctx>,
1236
+ buffer: SpanBuffer<Ctx['logSchema']>,
1237
+ op: Op<Ctx, [], S, E>,
1238
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1239
+ ): Promise<Result<S, E>> {
1240
+ try {
1241
+ let attempt = 1;
1242
+ let result = await first;
1243
+ while (true) {
1244
+ const retryError = getRetryableError(result, attempt);
1245
+ if (!retryError) break;
1246
+ const delay = calculateDelay(retryError.policy, attempt);
1247
+ writeRetryEntry(buffer, attempt, retryError, delay);
1248
+ await sleep(delay);
1249
+ attempt++;
1250
+ result = await op.fn(ctx);
1251
+ }
1252
+ writeSpanEnd(buffer, result);
1253
+ return result;
1254
+ } catch (error) {
1255
+ this._spanException(buffer, error);
1256
+ throw error;
1257
+ } finally {
1258
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1259
+ }
1260
+ }
1261
+
1262
+ spanAuto1<S, E, A1>(
1263
+ line: number,
1264
+ name: string,
1265
+ op: Op<Ctx, [A1], S, E>,
1266
+ a1: A1,
1267
+ ): Result<S, E> | Promise<Result<S, E>> {
1268
+ const ctx = this._spanAutoPre(line, name, op);
1269
+ const buffer = ctx._spanBuffer;
1270
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1271
+ let isAsync = false;
1272
+ try {
1273
+ const result = op.fn(ctx, a1);
1274
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1275
+ isAsync = true;
1276
+ return this._spanAutoAsync1(ctx, buffer, op, result, a1);
1277
+ }
1278
+ writeSpanEnd(buffer, result);
1279
+ return result;
1280
+ } catch (error) {
1281
+ this._spanException(buffer, error);
1282
+ throw error;
1283
+ } finally {
1284
+ if (!isAsync) {
1285
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1286
+ }
1287
+ }
1288
+ }
1289
+
1290
+ private async _spanAutoAsync1<S, E, A1>(
1291
+ ctx: SpanContextInstance<Ctx>,
1292
+ buffer: SpanBuffer<Ctx['logSchema']>,
1293
+ op: Op<Ctx, [A1], S, E>,
1294
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1295
+ a1: A1,
1296
+ ): Promise<Result<S, E>> {
1297
+ try {
1298
+ let attempt = 1;
1299
+ let result = await first;
1300
+ while (true) {
1301
+ const retryError = getRetryableError(result, attempt);
1302
+ if (!retryError) break;
1303
+ const delay = calculateDelay(retryError.policy, attempt);
1304
+ writeRetryEntry(buffer, attempt, retryError, delay);
1305
+ await sleep(delay);
1306
+ attempt++;
1307
+ result = await op.fn(ctx, a1);
1308
+ }
1309
+ writeSpanEnd(buffer, result);
1310
+ return result;
1311
+ } catch (error) {
1312
+ this._spanException(buffer, error);
1313
+ throw error;
1314
+ } finally {
1315
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1316
+ }
1317
+ }
1318
+
1319
+ spanAuto2<S, E, A1, A2>(
1320
+ line: number,
1321
+ name: string,
1322
+ op: Op<Ctx, [A1, A2], S, E>,
1323
+ a1: A1,
1324
+ a2: A2,
1325
+ ): Result<S, E> | Promise<Result<S, E>> {
1326
+ const ctx = this._spanAutoPre(line, name, op);
1327
+ const buffer = ctx._spanBuffer;
1328
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1329
+ let isAsync = false;
1330
+ try {
1331
+ const result = op.fn(ctx, a1, a2);
1332
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1333
+ isAsync = true;
1334
+ return this._spanAutoAsync2(ctx, buffer, op, result, a1, a2);
1335
+ }
1336
+ writeSpanEnd(buffer, result);
1337
+ return result;
1338
+ } catch (error) {
1339
+ this._spanException(buffer, error);
1340
+ throw error;
1341
+ } finally {
1342
+ if (!isAsync) {
1343
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1344
+ }
1345
+ }
1346
+ }
1347
+
1348
+ private async _spanAutoAsync2<S, E, A1, A2>(
1349
+ ctx: SpanContextInstance<Ctx>,
1350
+ buffer: SpanBuffer<Ctx['logSchema']>,
1351
+ op: Op<Ctx, [A1, A2], S, E>,
1352
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1353
+ a1: A1,
1354
+ a2: A2,
1355
+ ): Promise<Result<S, E>> {
1356
+ try {
1357
+ let attempt = 1;
1358
+ let result = await first;
1359
+ while (true) {
1360
+ const retryError = getRetryableError(result, attempt);
1361
+ if (!retryError) break;
1362
+ const delay = calculateDelay(retryError.policy, attempt);
1363
+ writeRetryEntry(buffer, attempt, retryError, delay);
1364
+ await sleep(delay);
1365
+ attempt++;
1366
+ result = await op.fn(ctx, a1, a2);
1367
+ }
1368
+ writeSpanEnd(buffer, result);
1369
+ return result;
1370
+ } catch (error) {
1371
+ this._spanException(buffer, error);
1372
+ throw error;
1373
+ } finally {
1374
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1375
+ }
1376
+ }
1377
+
1378
+ spanAuto3<S, E, A1, A2, A3>(
1379
+ line: number,
1380
+ name: string,
1381
+ op: Op<Ctx, [A1, A2, A3], S, E>,
1382
+ a1: A1,
1383
+ a2: A2,
1384
+ a3: A3,
1385
+ ): Result<S, E> | Promise<Result<S, E>> {
1386
+ const ctx = this._spanAutoPre(line, name, op);
1387
+ const buffer = ctx._spanBuffer;
1388
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1389
+ let isAsync = false;
1390
+ try {
1391
+ const result = op.fn(ctx, a1, a2, a3);
1392
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1393
+ isAsync = true;
1394
+ return this._spanAutoAsync3(ctx, buffer, op, result, a1, a2, a3);
1395
+ }
1396
+ writeSpanEnd(buffer, result);
1397
+ return result;
1398
+ } catch (error) {
1399
+ this._spanException(buffer, error);
1400
+ throw error;
1401
+ } finally {
1402
+ if (!isAsync) {
1403
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1404
+ }
1405
+ }
1406
+ }
1407
+
1408
+ private async _spanAutoAsync3<S, E, A1, A2, A3>(
1409
+ ctx: SpanContextInstance<Ctx>,
1410
+ buffer: SpanBuffer<Ctx['logSchema']>,
1411
+ op: Op<Ctx, [A1, A2, A3], S, E>,
1412
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1413
+ a1: A1,
1414
+ a2: A2,
1415
+ a3: A3,
1416
+ ): Promise<Result<S, E>> {
1417
+ try {
1418
+ let attempt = 1;
1419
+ let result = await first;
1420
+ while (true) {
1421
+ const retryError = getRetryableError(result, attempt);
1422
+ if (!retryError) break;
1423
+ const delay = calculateDelay(retryError.policy, attempt);
1424
+ writeRetryEntry(buffer, attempt, retryError, delay);
1425
+ await sleep(delay);
1426
+ attempt++;
1427
+ result = await op.fn(ctx, a1, a2, a3);
1428
+ }
1429
+ writeSpanEnd(buffer, result);
1430
+ return result;
1431
+ } catch (error) {
1432
+ this._spanException(buffer, error);
1433
+ throw error;
1434
+ } finally {
1435
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1436
+ }
1437
+ }
1438
+
1439
+ spanAuto4<S, E, A1, A2, A3, A4>(
1440
+ line: number,
1441
+ name: string,
1442
+ op: Op<Ctx, [A1, A2, A3, A4], S, E>,
1443
+ a1: A1,
1444
+ a2: A2,
1445
+ a3: A3,
1446
+ a4: A4,
1447
+ ): Result<S, E> | Promise<Result<S, E>> {
1448
+ const ctx = this._spanAutoPre(line, name, op);
1449
+ const buffer = ctx._spanBuffer;
1450
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1451
+ let isAsync = false;
1452
+ try {
1453
+ const result = op.fn(ctx, a1, a2, a3, a4);
1454
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1455
+ isAsync = true;
1456
+ return this._spanAutoAsync4(ctx, buffer, op, result, a1, a2, a3, a4);
1457
+ }
1458
+ writeSpanEnd(buffer, result);
1459
+ return result;
1460
+ } catch (error) {
1461
+ this._spanException(buffer, error);
1462
+ throw error;
1463
+ } finally {
1464
+ if (!isAsync) {
1465
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1466
+ }
1467
+ }
1468
+ }
1469
+
1470
+ private async _spanAutoAsync4<S, E, A1, A2, A3, A4>(
1471
+ ctx: SpanContextInstance<Ctx>,
1472
+ buffer: SpanBuffer<Ctx['logSchema']>,
1473
+ op: Op<Ctx, [A1, A2, A3, A4], S, E>,
1474
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1475
+ a1: A1,
1476
+ a2: A2,
1477
+ a3: A3,
1478
+ a4: A4,
1479
+ ): Promise<Result<S, E>> {
1480
+ try {
1481
+ let attempt = 1;
1482
+ let result = await first;
1483
+ while (true) {
1484
+ const retryError = getRetryableError(result, attempt);
1485
+ if (!retryError) break;
1486
+ const delay = calculateDelay(retryError.policy, attempt);
1487
+ writeRetryEntry(buffer, attempt, retryError, delay);
1488
+ await sleep(delay);
1489
+ attempt++;
1490
+ result = await op.fn(ctx, a1, a2, a3, a4);
1491
+ }
1492
+ writeSpanEnd(buffer, result);
1493
+ return result;
1494
+ } catch (error) {
1495
+ this._spanException(buffer, error);
1496
+ throw error;
1497
+ } finally {
1498
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1499
+ }
1500
+ }
1501
+
1502
+ spanAuto5<S, E, A1, A2, A3, A4, A5>(
1503
+ line: number,
1504
+ name: string,
1505
+ op: Op<Ctx, [A1, A2, A3, A4, A5], S, E>,
1506
+ a1: A1,
1507
+ a2: A2,
1508
+ a3: A3,
1509
+ a4: A4,
1510
+ a5: A5,
1511
+ ): Result<S, E> | Promise<Result<S, E>> {
1512
+ const ctx = this._spanAutoPre(line, name, op);
1513
+ const buffer = ctx._spanBuffer;
1514
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1515
+ let isAsync = false;
1516
+ try {
1517
+ const result = op.fn(ctx, a1, a2, a3, a4, a5);
1518
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1519
+ isAsync = true;
1520
+ return this._spanAutoAsync5(ctx, buffer, op, result, a1, a2, a3, a4, a5);
1521
+ }
1522
+ writeSpanEnd(buffer, result);
1523
+ return result;
1524
+ } catch (error) {
1525
+ this._spanException(buffer, error);
1526
+ throw error;
1527
+ } finally {
1528
+ if (!isAsync) {
1529
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1530
+ }
1531
+ }
1532
+ }
1533
+
1534
+ private async _spanAutoAsync5<S, E, A1, A2, A3, A4, A5>(
1535
+ ctx: SpanContextInstance<Ctx>,
1536
+ buffer: SpanBuffer<Ctx['logSchema']>,
1537
+ op: Op<Ctx, [A1, A2, A3, A4, A5], S, E>,
1538
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1539
+ a1: A1,
1540
+ a2: A2,
1541
+ a3: A3,
1542
+ a4: A4,
1543
+ a5: A5,
1544
+ ): Promise<Result<S, E>> {
1545
+ try {
1546
+ let attempt = 1;
1547
+ let result = await first;
1548
+ while (true) {
1549
+ const retryError = getRetryableError(result, attempt);
1550
+ if (!retryError) break;
1551
+ const delay = calculateDelay(retryError.policy, attempt);
1552
+ writeRetryEntry(buffer, attempt, retryError, delay);
1553
+ await sleep(delay);
1554
+ attempt++;
1555
+ result = await op.fn(ctx, a1, a2, a3, a4, a5);
1556
+ }
1557
+ writeSpanEnd(buffer, result);
1558
+ return result;
1559
+ } catch (error) {
1560
+ this._spanException(buffer, error);
1561
+ throw error;
1562
+ } finally {
1563
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1564
+ }
1565
+ }
1566
+
1567
+ spanAuto6<S, E, A1, A2, A3, A4, A5, A6>(
1568
+ line: number,
1569
+ name: string,
1570
+ op: Op<Ctx, [A1, A2, A3, A4, A5, A6], S, E>,
1571
+ a1: A1,
1572
+ a2: A2,
1573
+ a3: A3,
1574
+ a4: A4,
1575
+ a5: A5,
1576
+ a6: A6,
1577
+ ): Result<S, E> | Promise<Result<S, E>> {
1578
+ const ctx = this._spanAutoPre(line, name, op);
1579
+ const buffer = ctx._spanBuffer;
1580
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1581
+ let isAsync = false;
1582
+ try {
1583
+ const result = op.fn(ctx, a1, a2, a3, a4, a5, a6);
1584
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1585
+ isAsync = true;
1586
+ return this._spanAutoAsync6(ctx, buffer, op, result, a1, a2, a3, a4, a5, a6);
1587
+ }
1588
+ writeSpanEnd(buffer, result);
1589
+ return result;
1590
+ } catch (error) {
1591
+ this._spanException(buffer, error);
1592
+ throw error;
1593
+ } finally {
1594
+ if (!isAsync) {
1595
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1596
+ }
1597
+ }
1598
+ }
1599
+
1600
+ private async _spanAutoAsync6<S, E, A1, A2, A3, A4, A5, A6>(
1601
+ ctx: SpanContextInstance<Ctx>,
1602
+ buffer: SpanBuffer<Ctx['logSchema']>,
1603
+ op: Op<Ctx, [A1, A2, A3, A4, A5, A6], S, E>,
1604
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1605
+ a1: A1,
1606
+ a2: A2,
1607
+ a3: A3,
1608
+ a4: A4,
1609
+ a5: A5,
1610
+ a6: A6,
1611
+ ): Promise<Result<S, E>> {
1612
+ try {
1613
+ let attempt = 1;
1614
+ let result = await first;
1615
+ while (true) {
1616
+ const retryError = getRetryableError(result, attempt);
1617
+ if (!retryError) break;
1618
+ const delay = calculateDelay(retryError.policy, attempt);
1619
+ writeRetryEntry(buffer, attempt, retryError, delay);
1620
+ await sleep(delay);
1621
+ attempt++;
1622
+ result = await op.fn(ctx, a1, a2, a3, a4, a5, a6);
1623
+ }
1624
+ writeSpanEnd(buffer, result);
1625
+ return result;
1626
+ } catch (error) {
1627
+ this._spanException(buffer, error);
1628
+ throw error;
1629
+ } finally {
1630
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1631
+ }
1632
+ }
1633
+
1634
+ spanAuto7<S, E, A1, A2, A3, A4, A5, A6, A7>(
1635
+ line: number,
1636
+ name: string,
1637
+ op: Op<Ctx, [A1, A2, A3, A4, A5, A6, A7], S, E>,
1638
+ a1: A1,
1639
+ a2: A2,
1640
+ a3: A3,
1641
+ a4: A4,
1642
+ a5: A5,
1643
+ a6: A6,
1644
+ a7: A7,
1645
+ ): Result<S, E> | Promise<Result<S, E>> {
1646
+ const ctx = this._spanAutoPre(line, name, op);
1647
+ const buffer = ctx._spanBuffer;
1648
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1649
+ let isAsync = false;
1650
+ try {
1651
+ const result = op.fn(ctx, a1, a2, a3, a4, a5, a6, a7);
1652
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1653
+ isAsync = true;
1654
+ return this._spanAutoAsync7(ctx, buffer, op, result, a1, a2, a3, a4, a5, a6, a7);
1655
+ }
1656
+ writeSpanEnd(buffer, result);
1657
+ return result;
1658
+ } catch (error) {
1659
+ this._spanException(buffer, error);
1660
+ throw error;
1661
+ } finally {
1662
+ if (!isAsync) {
1663
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1664
+ }
1665
+ }
1666
+ }
1667
+
1668
+ private async _spanAutoAsync7<S, E, A1, A2, A3, A4, A5, A6, A7>(
1669
+ ctx: SpanContextInstance<Ctx>,
1670
+ buffer: SpanBuffer<Ctx['logSchema']>,
1671
+ op: Op<Ctx, [A1, A2, A3, A4, A5, A6, A7], S, E>,
1672
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1673
+ a1: A1,
1674
+ a2: A2,
1675
+ a3: A3,
1676
+ a4: A4,
1677
+ a5: A5,
1678
+ a6: A6,
1679
+ a7: A7,
1680
+ ): Promise<Result<S, E>> {
1681
+ try {
1682
+ let attempt = 1;
1683
+ let result = await first;
1684
+ while (true) {
1685
+ const retryError = getRetryableError(result, attempt);
1686
+ if (!retryError) break;
1687
+ const delay = calculateDelay(retryError.policy, attempt);
1688
+ writeRetryEntry(buffer, attempt, retryError, delay);
1689
+ await sleep(delay);
1690
+ attempt++;
1691
+ result = await op.fn(ctx, a1, a2, a3, a4, a5, a6, a7);
1692
+ }
1693
+ writeSpanEnd(buffer, result);
1694
+ return result;
1695
+ } catch (error) {
1696
+ this._spanException(buffer, error);
1697
+ throw error;
1698
+ } finally {
1699
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1700
+ }
1701
+ }
1702
+
1703
+ spanAuto8<S, E, A1, A2, A3, A4, A5, A6, A7, A8>(
1704
+ line: number,
1705
+ name: string,
1706
+ op: Op<Ctx, [A1, A2, A3, A4, A5, A6, A7, A8], S, E>,
1707
+ a1: A1,
1708
+ a2: A2,
1709
+ a3: A3,
1710
+ a4: A4,
1711
+ a5: A5,
1712
+ a6: A6,
1713
+ a7: A7,
1714
+ a8: A8,
1715
+ ): Result<S, E> | Promise<Result<S, E>> {
1716
+ const ctx = this._spanAutoPre(line, name, op);
1717
+ const buffer = ctx._spanBuffer;
1718
+ buffer._traceRoot.tracer.onSpanStart(buffer);
1719
+ let isAsync = false;
1720
+ try {
1721
+ const result = op.fn(ctx, a1, a2, a3, a4, a5, a6, a7, a8);
1722
+ if (!isSynchronousResult(result) || getRetryableError(result, 1) !== undefined) {
1723
+ isAsync = true;
1724
+ return this._spanAutoAsync8(ctx, buffer, op, result, a1, a2, a3, a4, a5, a6, a7, a8);
1725
+ }
1726
+ writeSpanEnd(buffer, result);
1727
+ return result;
1728
+ } catch (error) {
1729
+ this._spanException(buffer, error);
1730
+ throw error;
1731
+ } finally {
1732
+ if (!isAsync) {
1733
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1734
+ }
1735
+ }
1736
+ }
1737
+
1738
+ private async _spanAutoAsync8<S, E, A1, A2, A3, A4, A5, A6, A7, A8>(
1739
+ ctx: SpanContextInstance<Ctx>,
1740
+ buffer: SpanBuffer<Ctx['logSchema']>,
1741
+ op: Op<Ctx, [A1, A2, A3, A4, A5, A6, A7, A8], S, E>,
1742
+ first: Result<S, E> | PromiseLike<Result<S, E>>,
1743
+ a1: A1,
1744
+ a2: A2,
1745
+ a3: A3,
1746
+ a4: A4,
1747
+ a5: A5,
1748
+ a6: A6,
1749
+ a7: A7,
1750
+ a8: A8,
1751
+ ): Promise<Result<S, E>> {
1752
+ try {
1753
+ let attempt = 1;
1754
+ let result = await first;
1755
+ while (true) {
1756
+ const retryError = getRetryableError(result, attempt);
1757
+ if (!retryError) break;
1758
+ const delay = calculateDelay(retryError.policy, attempt);
1759
+ writeRetryEntry(buffer, attempt, retryError, delay);
1760
+ await sleep(delay);
1761
+ attempt++;
1762
+ result = await op.fn(ctx, a1, a2, a3, a4, a5, a6, a7, a8);
1763
+ }
1764
+ writeSpanEnd(buffer, result);
1765
+ return result;
1766
+ } catch (error) {
1767
+ this._spanException(buffer, error);
1768
+ throw error;
1769
+ } finally {
1770
+ buffer._traceRoot.tracer.onSpanEnd(buffer);
1771
+ }
1772
+ }
1773
+
1269
1774
  // =========================================================================
1270
1775
  // Monomorphic span methods (for transformer output)
1271
- // Transformer emits: ctx.span0(line, name, ctx, fn) or
1272
- // ctx.span0(line, name, Object.assign(Object.create(ctx), overrides), fn)
1273
- // childCtx inherits from parent via prototype chain, may have user overrides as own properties
1776
+ // Transformer emits: ctx.span0(line, name, plan.newCtx0(ctx), plan, fn)
1777
+ // The frozen plan supplies the exact context source factory for each callsite.
1778
+ // User overrides are materialized by plan.newCtx1 without prototype allocation.
1274
1779
  // =========================================================================
1275
1780
 
1276
1781
  spanSync0<S, E>(
1277
1782
  line: number,
1278
- name: string,
1783
+ name: string | number,
1279
1784
  childCtx: SpanContextInstance<Ctx>,
1280
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1281
- remappedViewClass: RemappedViewConstructor | undefined,
1282
- opMetadata: OpMetadata,
1283
- fn: (ctx: SpanContext<Ctx>) => Result<S, E>,
1785
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1786
+ fn: (ctx: SpanContext<Ctx>) => Result<S, E> | Promise<Result<S, E>>,
1284
1787
  ): Result<S, E> {
1285
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1286
- const buffer = ctx._buffer;
1788
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
1789
+ const buffer = ctx._spanBuffer;
1287
1790
  buffer._traceRoot.tracer.onSpanStart(buffer);
1288
1791
  try {
1289
1792
  const result = fn(ctx);
1793
+ if (!isSynchronousResult(result)) {
1794
+ throw new TypeError('spanSync operation returned a Promise');
1795
+ }
1290
1796
  writeSpanEnd(buffer, result);
1291
1797
  return result;
1292
1798
  } catch (error) {
@@ -1299,19 +1805,17 @@ export function createSpanContextClass<Ctx extends OpContext>(
1299
1805
 
1300
1806
  async span0<S, E>(
1301
1807
  line: number,
1302
- name: string,
1808
+ name: string | number,
1303
1809
  childCtx: SpanContextInstance<Ctx>,
1304
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1305
- remappedViewClass: RemappedViewConstructor | undefined,
1306
- opMetadata: OpMetadata,
1810
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1307
1811
  fn: (ctx: SpanContext<Ctx>) => Result<S, E> | Promise<Result<S, E>>,
1308
1812
  ): Promise<Result<S, E>> {
1309
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1310
- const buffer = ctx._buffer;
1813
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
1814
+ const buffer = ctx._spanBuffer;
1311
1815
  buffer._traceRoot.tracer.onSpanStart(buffer);
1312
1816
  try {
1313
1817
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1314
- const result = await executeWithRetry(buffer, () => fn(ctx));
1818
+ const result = await executeWithRetry0(buffer, fn, ctx);
1315
1819
  writeSpanEnd(buffer, result);
1316
1820
  return result;
1317
1821
  } catch (error) {
@@ -1324,20 +1828,18 @@ export function createSpanContextClass<Ctx extends OpContext>(
1324
1828
 
1325
1829
  async span1<S, E, A1>(
1326
1830
  line: number,
1327
- name: string,
1831
+ name: string | number,
1328
1832
  childCtx: SpanContextInstance<Ctx>,
1329
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1330
- remappedViewClass: RemappedViewConstructor | undefined,
1331
- opMetadata: OpMetadata,
1833
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1332
1834
  fn: (ctx: SpanContext<Ctx>, a1: A1) => Result<S, E> | Promise<Result<S, E>>,
1333
1835
  a1: A1,
1334
1836
  ): Promise<Result<S, E>> {
1335
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1336
- const buffer = ctx._buffer;
1837
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
1838
+ const buffer = ctx._spanBuffer;
1337
1839
  buffer._traceRoot.tracer.onSpanStart(buffer);
1338
1840
  try {
1339
1841
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1340
- const result = await executeWithRetry(buffer, () => fn(ctx, a1));
1842
+ const result = await executeWithRetry1(buffer, fn, ctx, a1);
1341
1843
  writeSpanEnd(buffer, result);
1342
1844
  return result;
1343
1845
  } catch (error) {
@@ -1350,21 +1852,19 @@ export function createSpanContextClass<Ctx extends OpContext>(
1350
1852
 
1351
1853
  async span2<S, E, A1, A2>(
1352
1854
  line: number,
1353
- name: string,
1855
+ name: string | number,
1354
1856
  childCtx: SpanContextInstance<Ctx>,
1355
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1356
- remappedViewClass: RemappedViewConstructor | undefined,
1357
- opMetadata: OpMetadata,
1857
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1358
1858
  fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2) => Result<S, E> | Promise<Result<S, E>>,
1359
1859
  a1: A1,
1360
1860
  a2: A2,
1361
1861
  ): Promise<Result<S, E>> {
1362
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1363
- const buffer = ctx._buffer;
1862
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
1863
+ const buffer = ctx._spanBuffer;
1364
1864
  buffer._traceRoot.tracer.onSpanStart(buffer);
1365
1865
  try {
1366
1866
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1367
- const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2));
1867
+ const result = await executeWithRetry2(buffer, fn, ctx, a1, a2);
1368
1868
  writeSpanEnd(buffer, result);
1369
1869
  return result;
1370
1870
  } catch (error) {
@@ -1377,22 +1877,20 @@ export function createSpanContextClass<Ctx extends OpContext>(
1377
1877
 
1378
1878
  async span3<S, E, A1, A2, A3>(
1379
1879
  line: number,
1380
- name: string,
1880
+ name: string | number,
1381
1881
  childCtx: SpanContextInstance<Ctx>,
1382
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1383
- remappedViewClass: RemappedViewConstructor | undefined,
1384
- opMetadata: OpMetadata,
1882
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1385
1883
  fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3) => Result<S, E> | Promise<Result<S, E>>,
1386
1884
  a1: A1,
1387
1885
  a2: A2,
1388
1886
  a3: A3,
1389
1887
  ): Promise<Result<S, E>> {
1390
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1391
- const buffer = ctx._buffer;
1888
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
1889
+ const buffer = ctx._spanBuffer;
1392
1890
  buffer._traceRoot.tracer.onSpanStart(buffer);
1393
1891
  try {
1394
1892
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1395
- const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3));
1893
+ const result = await executeWithRetry3(buffer, fn, ctx, a1, a2, a3);
1396
1894
  writeSpanEnd(buffer, result);
1397
1895
  return result;
1398
1896
  } catch (error) {
@@ -1405,23 +1903,21 @@ export function createSpanContextClass<Ctx extends OpContext>(
1405
1903
 
1406
1904
  async span4<S, E, A1, A2, A3, A4>(
1407
1905
  line: number,
1408
- name: string,
1906
+ name: string | number,
1409
1907
  childCtx: SpanContextInstance<Ctx>,
1410
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1411
- remappedViewClass: RemappedViewConstructor | undefined,
1412
- opMetadata: OpMetadata,
1908
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1413
1909
  fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4) => Result<S, E> | Promise<Result<S, E>>,
1414
1910
  a1: A1,
1415
1911
  a2: A2,
1416
1912
  a3: A3,
1417
1913
  a4: A4,
1418
1914
  ): Promise<Result<S, E>> {
1419
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1420
- const buffer = ctx._buffer;
1915
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
1916
+ const buffer = ctx._spanBuffer;
1421
1917
  buffer._traceRoot.tracer.onSpanStart(buffer);
1422
1918
  try {
1423
1919
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1424
- const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4));
1920
+ const result = await executeWithRetry4(buffer, fn, ctx, a1, a2, a3, a4);
1425
1921
  writeSpanEnd(buffer, result);
1426
1922
  return result;
1427
1923
  } catch (error) {
@@ -1434,11 +1930,9 @@ export function createSpanContextClass<Ctx extends OpContext>(
1434
1930
 
1435
1931
  async span5<S, E, A1, A2, A3, A4, A5>(
1436
1932
  line: number,
1437
- name: string,
1933
+ name: string | number,
1438
1934
  childCtx: SpanContextInstance<Ctx>,
1439
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1440
- remappedViewClass: RemappedViewConstructor | undefined,
1441
- opMetadata: OpMetadata,
1935
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1442
1936
  fn: (ctx: SpanContext<Ctx>, a1: A1, a2: A2, a3: A3, a4: A4, a5: A5) => Result<S, E> | Promise<Result<S, E>>,
1443
1937
  a1: A1,
1444
1938
  a2: A2,
@@ -1446,12 +1940,12 @@ export function createSpanContextClass<Ctx extends OpContext>(
1446
1940
  a4: A4,
1447
1941
  a5: A5,
1448
1942
  ): Promise<Result<S, E>> {
1449
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1450
- const buffer = ctx._buffer;
1943
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
1944
+ const buffer = ctx._spanBuffer;
1451
1945
  buffer._traceRoot.tracer.onSpanStart(buffer);
1452
1946
  try {
1453
1947
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1454
- const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4, a5));
1948
+ const result = await executeWithRetry5(buffer, fn, ctx, a1, a2, a3, a4, a5);
1455
1949
  writeSpanEnd(buffer, result);
1456
1950
  return result;
1457
1951
  } catch (error) {
@@ -1464,11 +1958,9 @@ export function createSpanContextClass<Ctx extends OpContext>(
1464
1958
 
1465
1959
  async span6<S, E, A1, A2, A3, A4, A5, A6>(
1466
1960
  line: number,
1467
- name: string,
1961
+ name: string | number,
1468
1962
  childCtx: SpanContextInstance<Ctx>,
1469
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1470
- remappedViewClass: RemappedViewConstructor | undefined,
1471
- opMetadata: OpMetadata,
1963
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1472
1964
  fn: (
1473
1965
  ctx: SpanContext<Ctx>,
1474
1966
  a1: A1,
@@ -1485,12 +1977,12 @@ export function createSpanContextClass<Ctx extends OpContext>(
1485
1977
  a5: A5,
1486
1978
  a6: A6,
1487
1979
  ): Promise<Result<S, E>> {
1488
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1489
- const buffer = ctx._buffer;
1980
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
1981
+ const buffer = ctx._spanBuffer;
1490
1982
  buffer._traceRoot.tracer.onSpanStart(buffer);
1491
1983
  try {
1492
1984
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1493
- const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4, a5, a6));
1985
+ const result = await executeWithRetry6(buffer, fn, ctx, a1, a2, a3, a4, a5, a6);
1494
1986
  writeSpanEnd(buffer, result);
1495
1987
  return result;
1496
1988
  } catch (error) {
@@ -1503,11 +1995,9 @@ export function createSpanContextClass<Ctx extends OpContext>(
1503
1995
 
1504
1996
  async span7<S, E, A1, A2, A3, A4, A5, A6, A7>(
1505
1997
  line: number,
1506
- name: string,
1998
+ name: string | number,
1507
1999
  childCtx: SpanContextInstance<Ctx>,
1508
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1509
- remappedViewClass: RemappedViewConstructor | undefined,
1510
- opMetadata: OpMetadata,
2000
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1511
2001
  fn: (
1512
2002
  ctx: SpanContext<Ctx>,
1513
2003
  a1: A1,
@@ -1526,12 +2016,12 @@ export function createSpanContextClass<Ctx extends OpContext>(
1526
2016
  a6: A6,
1527
2017
  a7: A7,
1528
2018
  ): Promise<Result<S, E>> {
1529
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1530
- const buffer = ctx._buffer;
2019
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
2020
+ const buffer = ctx._spanBuffer;
1531
2021
  buffer._traceRoot.tracer.onSpanStart(buffer);
1532
2022
  try {
1533
2023
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1534
- const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4, a5, a6, a7));
2024
+ const result = await executeWithRetry7(buffer, fn, ctx, a1, a2, a3, a4, a5, a6, a7);
1535
2025
  writeSpanEnd(buffer, result);
1536
2026
  return result;
1537
2027
  } catch (error) {
@@ -1544,11 +2034,9 @@ export function createSpanContextClass<Ctx extends OpContext>(
1544
2034
 
1545
2035
  async span8<S, E, A1, A2, A3, A4, A5, A6, A7, A8>(
1546
2036
  line: number,
1547
- name: string,
2037
+ name: string | number,
1548
2038
  childCtx: SpanContextInstance<Ctx>,
1549
- SpanBufferClass: SpanBufferConstructor<Ctx['logSchema']>,
1550
- remappedViewClass: RemappedViewConstructor | undefined,
1551
- opMetadata: OpMetadata,
2039
+ callsitePlan: CallsitePlan<Ctx['logSchema'], Ctx>,
1552
2040
  fn: (
1553
2041
  ctx: SpanContext<Ctx>,
1554
2042
  a1: A1,
@@ -1569,12 +2057,12 @@ export function createSpanContextClass<Ctx extends OpContext>(
1569
2057
  a7: A7,
1570
2058
  a8: A8,
1571
2059
  ): Promise<Result<S, E, Ctx['logSchema']>> {
1572
- const ctx = this._spanPre(childCtx, line, name, SpanBufferClass, remappedViewClass, opMetadata);
1573
- const buffer = ctx._buffer;
2060
+ const ctx = this._spanPre(childCtx, line, name, callsitePlan, callsitePlan.metadata);
2061
+ const buffer = ctx._spanBuffer;
1574
2062
  buffer._traceRoot.tracer.onSpanStart(buffer);
1575
2063
  try {
1576
2064
  // Execute with retry loop - TransientError triggers retry, BlockedError returns immediately
1577
- const result = await executeWithRetry(buffer, () => fn(ctx, a1, a2, a3, a4, a5, a6, a7, a8));
2065
+ const result = await executeWithRetry8(buffer, fn, ctx, a1, a2, a3, a4, a5, a6, a7, a8);
1578
2066
  writeSpanEnd(buffer, result);
1579
2067
  return result;
1580
2068
  } catch (error) {
@@ -1587,6 +2075,7 @@ export function createSpanContextClass<Ctx extends OpContext>(
1587
2075
  }
1588
2076
 
1589
2077
  const SpanContextCtor: SpanContextClass<Ctx> = SpanContextImpl;
2078
+ cache.set(cacheKey, SpanContextCtor);
1590
2079
  return SpanContextCtor;
1591
2080
  }
1592
2081