brass-runtime 1.15.0 → 1.16.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 (93) hide show
  1. package/README.md +409 -137
  2. package/dist/agent/cli/main.cjs +40 -35
  3. package/dist/agent/cli/main.js +9 -4
  4. package/dist/agent/cli/main.mjs +9 -4
  5. package/dist/agent/index.cjs +8 -4
  6. package/dist/agent/index.d.ts +1 -1
  7. package/dist/agent/index.js +7 -3
  8. package/dist/agent/index.mjs +7 -3
  9. package/dist/{chunk-PPUXIH5R.js → chunk-2WC63LJK.mjs} +11 -7
  10. package/dist/chunk-3RG5ZIWI.js +10 -0
  11. package/dist/chunk-45F7OKGT.cjs +104 -0
  12. package/dist/chunk-5YOQOXEQ.cjs +2491 -0
  13. package/dist/{chunk-STVLQ3XD.cjs → chunk-7HUOJA4W.cjs} +78 -74
  14. package/dist/{chunk-BMH5AV44.js → chunk-7LVI2GIN.js} +251 -370
  15. package/dist/chunk-7TL2LHQJ.js +2491 -0
  16. package/dist/chunk-7V4KY4RL.mjs +104 -0
  17. package/dist/chunk-7XOPAB5Q.js +2143 -0
  18. package/dist/chunk-CCKHV5BT.mjs +193 -0
  19. package/dist/{chunk-AR22SXML.js → chunk-CY33PGEX.mjs} +488 -421
  20. package/dist/chunk-DJQ7OMMB.cjs +144 -0
  21. package/dist/chunk-F5EUMJL7.mjs +2143 -0
  22. package/dist/chunk-FM4W4QPL.js +193 -0
  23. package/dist/{chunk-TO7IKXYT.js → chunk-G3XGCZDQ.js} +1 -1
  24. package/dist/{chunk-BDF4AMWX.mjs → chunk-G6IQOE4P.mjs} +251 -370
  25. package/dist/chunk-GOV47PPB.mjs +552 -0
  26. package/dist/chunk-H55LI6WY.js +93 -0
  27. package/dist/chunk-IJT6RRQ5.cjs +93 -0
  28. package/dist/{chunk-ELOOF35R.mjs → chunk-J3H54ZRV.mjs} +1 -1
  29. package/dist/chunk-JF4XXPZ5.cjs +552 -0
  30. package/dist/chunk-JNFRRJYH.cjs +2143 -0
  31. package/dist/chunk-JX3LZQJH.cjs +354 -0
  32. package/dist/chunk-K2T3DV26.mjs +93 -0
  33. package/dist/chunk-KCPT2D6G.js +552 -0
  34. package/dist/chunk-MWXMNYJS.cjs +1110 -0
  35. package/dist/{chunk-VEZNF5GZ.cjs → chunk-N6VHMOWB.cjs} +130 -126
  36. package/dist/{chunk-3QMOKAS5.js → chunk-NC5SDRYE.js} +9 -5
  37. package/dist/chunk-NOYZIMUJ.mjs +144 -0
  38. package/dist/{chunk-R3R2FVLG.cjs → chunk-NYL4D7SK.cjs} +5 -5
  39. package/dist/chunk-OBGZSXTJ.cjs +10 -0
  40. package/dist/{chunk-4NHES7VK.mjs → chunk-OOGJ73B6.js} +11 -7
  41. package/dist/chunk-PNVFW245.js +144 -0
  42. package/dist/chunk-PRWCB3QL.mjs +2491 -0
  43. package/dist/{chunk-JFPU5GQI.mjs → chunk-QY5FKYEQ.js} +488 -421
  44. package/dist/chunk-ROJC3NBJ.js +104 -0
  45. package/dist/chunk-SPUEME2B.cjs +343 -0
  46. package/dist/chunk-TDVMADDN.js +343 -0
  47. package/dist/chunk-TVN5I4U6.cjs +193 -0
  48. package/dist/chunk-U5KWK3PX.mjs +343 -0
  49. package/dist/chunk-VFIUZG7J.mjs +354 -0
  50. package/dist/{chunk-TGIFUAK4.cjs → chunk-WQ5QNU5R.cjs} +459 -578
  51. package/dist/chunk-XDZOO4L5.js +354 -0
  52. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  53. package/dist/{chunk-K6M7MDZ4.mjs → chunk-ZGLD4TVZ.mjs} +9 -5
  54. package/dist/client-CtFmoDvM.d.ts +645 -0
  55. package/dist/core/index.cjs +72 -4
  56. package/dist/core/index.d.ts +92 -198
  57. package/dist/core/index.js +106 -38
  58. package/dist/core/index.mjs +106 -38
  59. package/dist/{effect-CMOQKX8y.d.ts → effect-CGNl5Rqp.d.ts} +107 -1
  60. package/dist/effectRunner-3ZHAD3LE.cjs +8 -0
  61. package/dist/effectRunner-A4CHJXJI.js +8 -0
  62. package/dist/effectRunner-OPUF6QRN.mjs +8 -0
  63. package/dist/http/index.cjs +2189 -1271
  64. package/dist/http/index.d.ts +830 -270
  65. package/dist/http/index.js +2008 -1090
  66. package/dist/http/index.mjs +2008 -1090
  67. package/dist/http/testing.cjs +159 -0
  68. package/dist/http/testing.d.ts +42 -0
  69. package/dist/http/testing.js +159 -0
  70. package/dist/http/testing.mjs +159 -0
  71. package/dist/index.cjs +246 -178
  72. package/dist/index.d.ts +9 -35
  73. package/dist/index.js +120 -52
  74. package/dist/index.mjs +120 -52
  75. package/dist/observability/index.cjs +677 -0
  76. package/dist/observability/index.d.ts +79 -0
  77. package/dist/observability/index.js +677 -0
  78. package/dist/observability/index.mjs +677 -0
  79. package/dist/schedule-Fque9Abz.d.ts +70 -0
  80. package/dist/schema/index.cjs +25 -0
  81. package/dist/schema/index.d.ts +177 -0
  82. package/dist/schema/index.js +25 -0
  83. package/dist/schema/index.mjs +25 -0
  84. package/dist/server-C8hDXA74.d.ts +674 -0
  85. package/dist/{stream-FQm9h4Mg.d.ts → stream-dvSs0QS5.d.ts} +1 -1
  86. package/dist/tracer-B5tRH9H7.d.ts +230 -0
  87. package/dist/tracing-Dt9S_6V8.d.ts +148 -0
  88. package/package.json +27 -1
  89. package/dist/chunk-BDYEENHT.js +0 -224
  90. package/dist/chunk-MS34J5LY.cjs +0 -224
  91. package/dist/chunk-UMAZLXAB.mjs +0 -224
  92. package/dist/chunk-XPZNXSVN.cjs +0 -1043
  93. package/dist/tracing-DNT9jEbr.d.ts +0 -106
@@ -1,121 +1,13 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
- // src/core/types/asyncEffect.ts
9
- var Async = {
10
- succeed: (value) => ({ _tag: "Succeed", value }),
11
- fail: (error) => ({ _tag: "Fail", error }),
12
- sync: (thunk) => ({ _tag: "Sync", thunk }),
13
- async: (register) => ({ _tag: "Async", register })
14
- };
15
- function asyncFold(fa, onFailure, onSuccess) {
16
- return {
17
- _tag: "Fold",
18
- first: fa,
19
- onFailure,
20
- onSuccess
21
- };
22
- }
23
- function asyncCatchAll(fa, handler) {
24
- return asyncFold(fa, handler, asyncSucceed);
25
- }
26
- function asyncMapError(fa, f) {
27
- return asyncFold(fa, (e) => asyncFail(f(e)), asyncSucceed);
28
- }
29
- var SUCCEED_UNDEFINED = { _tag: "Succeed", value: void 0 };
30
- var SUCCEED_TRUE = { _tag: "Succeed", value: true };
31
- var SUCCEED_FALSE = { _tag: "Succeed", value: false };
32
- var SUCCEED_NULL = { _tag: "Succeed", value: null };
33
- var unit = () => SUCCEED_UNDEFINED;
34
- var asyncSucceed = (value) => {
35
- if (value === void 0) return SUCCEED_UNDEFINED;
36
- if (value === true) return SUCCEED_TRUE;
37
- if (value === false) return SUCCEED_FALSE;
38
- if (value === null) return SUCCEED_NULL;
39
- return { _tag: "Succeed", value };
40
- };
41
- var asyncFail = (error) => ({
42
- _tag: "Fail",
43
- error
44
- });
45
- var asyncSync = (thunk) => ({
46
- _tag: "Sync",
47
- thunk
48
- });
49
- var asyncTotal = (thunk) => asyncSync(() => thunk());
50
- var asyncEffect = (register) => ({
51
- _tag: "Async",
52
- register
53
- });
54
- function asyncMap(fa, f) {
55
- return asyncFlatMap(fa, (a) => asyncSucceed(f(a)));
56
- }
57
- function asyncFlatMap(fa, f) {
58
- return {
59
- _tag: "FlatMap",
60
- first: fa,
61
- andThen: f
62
- };
63
- }
64
- function acquireRelease(acquire, release, scope) {
65
- return asyncFlatMap(acquire, (resource) => {
66
- scope.addFinalizer((exit) => release(resource, exit));
67
- return asyncSucceed(resource);
68
- });
69
- }
70
- function asyncInterruptible(register) {
71
- return asyncEffect(register);
72
- }
73
- var withAsyncPromise = (run) => (eff) => {
74
- const anyEff = eff;
75
- if (!anyEff.toPromise) {
76
- anyEff.toPromise = (env) => run(eff, env);
77
- anyEff.unsafeRunPromise = () => run(eff, {});
78
- }
79
- return anyEff;
80
- };
81
- var mapAsync = (fa, f) => asyncFlatMap(fa, (a) => asyncSucceed(f(a)));
82
- var mapTryAsync = (fa, f) => asyncFlatMap(fa, (a) => asyncSync(() => f(a)));
83
-
84
- // src/core/types/option.ts
85
- var none = { _tag: "None" };
86
- var some = (value) => ({ _tag: "Some", value });
87
-
88
- // src/core/types/effect.ts
89
- var Cause = {
90
- fail: (error) => ({ _tag: "Fail", error }),
91
- interrupt: () => ({ _tag: "Interrupt" }),
92
- die: (defect) => ({ _tag: "Die", defect })
93
- };
94
- var Exit = {
95
- succeed: (value) => ({
96
- _tag: "Success",
97
- value
98
- }),
99
- failCause: (cause) => ({
100
- _tag: "Failure",
101
- cause
102
- })
103
- };
104
- var succeed = (value) => asyncSucceed(value);
105
- var fail = (error) => asyncFail(error);
106
- var sync = (thunk) => asyncSync((env) => thunk(env));
107
- var map = (fa, f) => asyncMap(fa, f);
108
- var flatMap = (fa, f) => asyncFlatMap(fa, f);
109
- var mapError = (fa, f) => asyncMapError(fa, f);
110
- var catchAll = (fa, handler) => asyncFold(fa, handler, asyncSucceed);
111
- function orElseOptional(fa, that) {
112
- return asyncFold(
113
- fa,
114
- (opt) => opt._tag === "Some" ? asyncFail(opt) : that(),
115
- asyncSucceed
116
- );
117
- }
118
- var end = () => fail(none);
1
+ import {
2
+ Async,
3
+ Cause,
4
+ Exit,
5
+ asyncEffect
6
+ } from "./chunk-PNVFW245.js";
7
+ import {
8
+ Schema,
9
+ parseConfig
10
+ } from "./chunk-TDVMADDN.js";
119
11
 
120
12
  // src/core/runtime/ringBuffer.ts
121
13
  var PushStatus = /* @__PURE__ */ ((PushStatus3) => {
@@ -441,13 +333,47 @@ function resolveWasmScheduler() {
441
333
  var LaneState = class {
442
334
  constructor(key, initial, max) {
443
335
  this.key = key;
336
+ this.initial = initial;
337
+ this.max = max;
444
338
  this.queue = makeBoundedRingBuffer(initial, max, { engine: "ts" });
445
339
  }
446
340
  key;
341
+ initial;
342
+ max;
447
343
  queue;
344
+ tagQueue;
345
+ sharedTag;
448
346
  enqueuedTasks = 0;
449
347
  executedTasks = 0;
450
348
  droppedTasks = 0;
349
+ recordTag(tag, queuedBefore) {
350
+ if (this.tagQueue) {
351
+ this.tagQueue.push(tag);
352
+ return;
353
+ }
354
+ if (queuedBefore === 0 || this.sharedTag === void 0) {
355
+ this.sharedTag = tag;
356
+ return;
357
+ }
358
+ if (this.sharedTag === tag) return;
359
+ const tags = makeBoundedRingBuffer(this.initial, this.max, { engine: "ts" });
360
+ for (let i = 0; i < queuedBefore; i++) tags.push(this.sharedTag);
361
+ tags.push(tag);
362
+ this.tagQueue = tags;
363
+ }
364
+ shiftTag() {
365
+ if (this.tagQueue) {
366
+ const tag2 = this.tagQueue.shift() ?? this.sharedTag ?? this.key;
367
+ if (this.queue.length === 0) {
368
+ this.tagQueue = void 0;
369
+ this.sharedTag = void 0;
370
+ }
371
+ return tag2;
372
+ }
373
+ const tag = this.sharedTag ?? this.key;
374
+ if (this.queue.length === 0) this.sharedTag = void 0;
375
+ return tag;
376
+ }
451
377
  };
452
378
  var JsSchedulerState = class {
453
379
  constructor(options) {
@@ -473,6 +399,27 @@ var JsSchedulerState = class {
473
399
  return n;
474
400
  }
475
401
  };
402
+ var JsSingleSchedulerState = class {
403
+ constructor(options) {
404
+ this.options = options;
405
+ this.queue = makeBoundedRingBuffer(
406
+ options.initialCapacity ?? 1024,
407
+ options.maxCapacity ?? SCHEDULER_QUEUE_CAPACITY,
408
+ { engine: "ts" }
409
+ );
410
+ }
411
+ options;
412
+ queue;
413
+ flushing = false;
414
+ scheduled = false;
415
+ scheduledFlushes = 0;
416
+ completedFlushes = 0;
417
+ enqueuedTasks = 0;
418
+ executedTasks = 0;
419
+ droppedTasks = 0;
420
+ yieldedByBudget = 0;
421
+ totalLength = 0;
422
+ };
476
423
  var WasmSchedulerState = class {
477
424
  machine;
478
425
  nextRef = 1;
@@ -710,9 +657,9 @@ function inferLane(tag) {
710
657
  }
711
658
  function extractTaggedLane(tag, prefix) {
712
659
  if (!tag.startsWith(prefix)) return void 0;
713
- const end2 = tag.indexOf("|", prefix.length);
714
- if (end2 < 0) return void 0;
715
- const value = tag.slice(prefix.length, end2);
660
+ const end = tag.indexOf("|", prefix.length);
661
+ if (end < 0) return void 0;
662
+ const value = tag.slice(prefix.length, end);
716
663
  return value.length > 0 ? value : void 0;
717
664
  }
718
665
  function firstSeparatorIndex(value) {
@@ -726,6 +673,7 @@ function firstSeparatorIndex(value) {
726
673
  var Scheduler = class {
727
674
  engine;
728
675
  js;
676
+ jsSingle;
729
677
  wasm;
730
678
  flushBudget;
731
679
  microThreshold;
@@ -734,6 +682,7 @@ var Scheduler = class {
734
682
  maxLanes;
735
683
  fallbackUsed;
736
684
  boundFlush = () => this.flush();
685
+ shiftedTag = "anonymous";
737
686
  constructor(options = {}) {
738
687
  this.flushBudget = options.flushBudget ?? FLUSH_BUDGET;
739
688
  this.microThreshold = options.microThreshold ?? MICRO_THRESHOLD;
@@ -748,7 +697,11 @@ var Scheduler = class {
748
697
  return;
749
698
  }
750
699
  if (requested === "ts") {
751
- this.js = new JsSchedulerState({ ...options, engine: "ts" });
700
+ if (options.laneMode === "single") {
701
+ this.jsSingle = new JsSingleSchedulerState({ ...options, engine: "ts" });
702
+ } else {
703
+ this.js = new JsSchedulerState({ ...options, engine: "ts" });
704
+ }
752
705
  this.engine = "ts";
753
706
  this.fallbackUsed = false;
754
707
  return;
@@ -758,14 +711,42 @@ var Scheduler = class {
758
711
  schedule(task, tag = "anonymous") {
759
712
  if (typeof task !== "function") return "dropped";
760
713
  if (this.wasm) return this.scheduleWasm(task, tag);
714
+ if (this.jsSingle) return this.scheduleJsSingle(task);
761
715
  return this.scheduleJs(task, tag);
762
716
  }
763
717
  scheduleBatch(tasks) {
764
718
  if (this.wasm) return this.scheduleBatchWasm(tasks);
719
+ if (this.jsSingle) return this.scheduleBatchJsSingle(tasks);
765
720
  return tasks.map(({ fn, tag }) => this.schedule(fn, tag));
766
721
  }
767
722
  stats() {
768
723
  if (this.wasm) return this.wasm.stats();
724
+ if (this.jsSingle) {
725
+ const js2 = this.jsSingle;
726
+ return {
727
+ engine: "ts",
728
+ fallbackUsed: false,
729
+ data: {
730
+ len: js2.totalLength,
731
+ capacity: js2.queue.capacity,
732
+ phase: js2.flushing ? "flushing" : js2.scheduled ? "scheduled" : "idle",
733
+ scheduledFlushes: js2.scheduledFlushes,
734
+ completedFlushes: js2.completedFlushes,
735
+ enqueuedTasks: js2.enqueuedTasks,
736
+ executedTasks: js2.executedTasks,
737
+ droppedTasks: js2.droppedTasks,
738
+ yieldedByBudget: js2.yieldedByBudget,
739
+ lanes: [{
740
+ key: "single",
741
+ len: js2.queue.length,
742
+ capacity: js2.queue.capacity,
743
+ enqueuedTasks: js2.enqueuedTasks,
744
+ executedTasks: js2.executedTasks,
745
+ droppedTasks: js2.droppedTasks
746
+ }]
747
+ }
748
+ };
749
+ }
769
750
  const js = this.js;
770
751
  const lanes = Array.from(js.lanes.values()).map((lane) => ({ key: lane.key, len: lane.queue.length, capacity: lane.queue.capacity, enqueuedTasks: lane.enqueuedTasks, executedTasks: lane.executedTasks, droppedTasks: lane.droppedTasks }));
771
752
  return { engine: "ts", fallbackUsed: false, data: { len: js.totalLength, capacity: js.totalCapacity, phase: js.flushing ? "flushing" : js.scheduled ? "scheduled" : "idle", scheduledFlushes: js.scheduledFlushes, completedFlushes: js.completedFlushes, enqueuedTasks: js.enqueuedTasks, executedTasks: js.executedTasks, droppedTasks: js.droppedTasks, yieldedByBudget: js.yieldedByBudget, lanes } };
@@ -821,13 +802,44 @@ var Scheduler = class {
821
802
  const js = this.js;
822
803
  const lane = new LaneState(key, this.laneCapacity, this.laneCapacity);
823
804
  js.lanes.set(key, lane);
824
- js.laneOrder.push(key);
805
+ js.laneOrder.push(lane);
825
806
  return lane;
826
807
  }
808
+ scheduleJsSingle(task) {
809
+ const js = this.jsSingle;
810
+ const status = js.queue.push(task);
811
+ js.enqueuedTasks++;
812
+ if ((status & 2) !== 0) {
813
+ js.droppedTasks++;
814
+ if (!js.flushing && !js.scheduled && js.totalLength > 0) {
815
+ js.scheduled = true;
816
+ js.scheduledFlushes++;
817
+ this.requestFlush(js.totalLength > this.microThreshold ? "macro" : "micro");
818
+ }
819
+ return "dropped";
820
+ }
821
+ js.totalLength++;
822
+ if (js.flushing) return "accepted";
823
+ if (!js.scheduled) {
824
+ js.scheduled = true;
825
+ js.scheduledFlushes++;
826
+ this.requestFlush(js.totalLength > this.microThreshold ? "macro" : "micro");
827
+ }
828
+ return "accepted";
829
+ }
830
+ scheduleBatchJsSingle(tasks) {
831
+ const results = new Array(tasks.length);
832
+ for (let i = 0; i < tasks.length; i++) {
833
+ const task = tasks[i].fn;
834
+ results[i] = typeof task === "function" ? this.scheduleJsSingle(task) : "dropped";
835
+ }
836
+ return results;
837
+ }
827
838
  scheduleJs(task, tag) {
828
839
  const js = this.js;
829
840
  const lane = this.getOrCreateLane(inferLane(tag));
830
- const status = lane.queue.push({ task, tag });
841
+ const queuedBefore = lane.queue.length;
842
+ const status = lane.queue.push(task);
831
843
  lane.enqueuedTasks++;
832
844
  js.enqueuedTasks++;
833
845
  if ((status & 2) !== 0) {
@@ -840,6 +852,7 @@ var Scheduler = class {
840
852
  }
841
853
  return "dropped";
842
854
  }
855
+ lane.recordTag(tag, queuedBefore);
843
856
  js.totalLength++;
844
857
  if (js.flushing) return "accepted";
845
858
  if (!js.scheduled) {
@@ -855,6 +868,7 @@ var Scheduler = class {
855
868
  }
856
869
  flush() {
857
870
  if (this.wasm) return this.flushWasm();
871
+ if (this.jsSingle) return this.flushJsSingle();
858
872
  this.flushJs();
859
873
  }
860
874
  flushWasm() {
@@ -879,15 +893,47 @@ var Scheduler = class {
879
893
  else if (policy === 1) this.requestFlush("macro");
880
894
  }
881
895
  }
896
+ flushJsSingle() {
897
+ const js = this.jsSingle;
898
+ if (js.flushing) return;
899
+ js.flushing = true;
900
+ js.scheduled = false;
901
+ let ran = 0;
902
+ try {
903
+ while (ran < this.flushBudget) {
904
+ const task = js.queue.shift();
905
+ if (!task) break;
906
+ js.totalLength--;
907
+ ran++;
908
+ js.executedTasks++;
909
+ try {
910
+ task();
911
+ } catch (e) {
912
+ console.error("[Scheduler] task threw (laneMode=single)", e);
913
+ }
914
+ }
915
+ } finally {
916
+ js.flushing = false;
917
+ js.completedFlushes++;
918
+ if (js.totalLength > 0 && !js.scheduled) {
919
+ js.scheduled = true;
920
+ js.scheduledFlushes++;
921
+ const kind = ran >= this.flushBudget || js.totalLength > this.microThreshold ? "macro" : "micro";
922
+ if (ran >= this.flushBudget) js.yieldedByBudget++;
923
+ this.requestFlush(kind);
924
+ }
925
+ }
926
+ }
882
927
  shiftFromNextLane() {
883
928
  const js = this.js;
884
929
  const n = js.laneOrder.length;
885
930
  if (n === 0) return void 0;
886
931
  if (js.rrRemaining > 0) {
887
932
  const currentIdx = (js.rrIndex + n - 1) % n;
888
- const currentLane = js.lanes.get(js.laneOrder[currentIdx]);
889
- const next = currentLane?.queue.shift();
933
+ const currentLane = js.laneOrder[currentIdx];
934
+ const next = currentLane.queue.shift();
890
935
  if (next) {
936
+ this.shiftedTag = currentLane.shiftTag();
891
937
  js.rrRemaining--;
892
938
  currentLane.executedTasks++;
893
939
  js.totalLength--;
@@ -897,14 +943,15 @@ var Scheduler = class {
897
943
  }
898
944
  for (let scanned = 0; scanned < n; scanned++) {
899
945
  const idx = js.rrIndex % n;
900
- const key = js.laneOrder[idx];
946
+ const lane = js.laneOrder[idx];
901
947
  js.rrIndex = (idx + 1) % n;
902
- const lane = js.lanes.get(key);
903
- if (!lane || lane.queue.length === 0) continue;
948
+ if (lane.queue.length === 0) continue;
904
949
  js.rrRemaining = Math.max(0, this.laneBudget - 1);
905
950
  lane.executedTasks++;
906
951
  js.totalLength--;
907
- return lane.queue.shift();
952
+ const next = lane.queue.shift();
953
+ if (next) this.shiftedTag = lane.shiftTag();
954
+ return next;
908
955
  }
909
956
  return void 0;
910
957
  }
@@ -921,9 +968,9 @@ var Scheduler = class {
921
968
  ran++;
922
969
  js.executedTasks++;
923
970
  try {
924
- next.task();
971
+ next();
925
972
  } catch (e) {
926
- console.error(`[Scheduler] task threw (tag=${next.tag})`, e);
973
+ console.error(`[Scheduler] task threw (tag=${this.shiftedTag})`, e);
927
974
  }
928
975
  }
929
976
  } finally {
@@ -941,6 +988,27 @@ var Scheduler = class {
941
988
  };
942
989
  var globalScheduler = new Scheduler();
943
990
 
991
+ // src/core/runtime/contex.ts
992
+ var emptyContext = { parent: null, patch: /* @__PURE__ */ Object.create(null) };
993
+ function ctxExtend(parent, patch) {
994
+ return { parent, patch };
995
+ }
996
+ function ctxToObject(ctx) {
997
+ const out = /* @__PURE__ */ Object.create(null);
998
+ const seen = /* @__PURE__ */ new Set();
999
+ let cur = ctx;
1000
+ while (cur) {
1001
+ for (const k of Object.keys(cur.patch)) {
1002
+ if (!seen.has(k)) {
1003
+ out[k] = cur.patch[k];
1004
+ seen.add(k);
1005
+ }
1006
+ }
1007
+ cur = cur.parent;
1008
+ }
1009
+ return out;
1010
+ }
1011
+
944
1012
  // src/core/runtime/hostAction.ts
945
1013
  var DefaultHostExecutor = {
946
1014
  async execute(action) {
@@ -952,9 +1020,6 @@ var DefaultHostExecutor = {
952
1020
  }
953
1021
  };
954
1022
 
955
- // src/core/runtime/contex.ts
956
- var emptyContext = { parent: null, patch: /* @__PURE__ */ Object.create(null) };
957
-
958
1023
  // src/core/runtime/forkPolicy.ts
959
1024
  function makeForkPolicy(env, hooks) {
960
1025
  const svc = resolveForkServices(env);
@@ -978,7 +1043,16 @@ function makeForkPolicy(env, hooks) {
978
1043
  // ✅ ahora viaja
979
1044
  name: fiber.name
980
1045
  },
981
- { fiberId: parent?.id, traceId: parentCtx?.trace?.traceId, spanId: parentCtx?.trace?.spanId }
1046
+ {
1047
+ fiberId: fiber.id,
1048
+ scopeId: fiber.scopeId,
1049
+ traceId: trace?.traceId,
1050
+ spanId: trace?.spanId,
1051
+ parentSpanId: trace?.parentSpanId,
1052
+ traceState: trace?.traceState,
1053
+ baggage: trace?.baggage,
1054
+ sampled: trace?.sampled
1055
+ }
982
1056
  );
983
1057
  }
984
1058
  };
@@ -991,8 +1065,9 @@ function resolveForkServices(env) {
991
1065
  const brass = env?.brass;
992
1066
  const tracer = brass?.tracer ?? defaultTracer;
993
1067
  const seed = brass?.traceSeed;
1068
+ const baggage = brass?.baggage;
994
1069
  const childName = brass?.childName ?? ((p) => p ? `${p}/child` : void 0);
995
- return { tracer, seed, childName };
1070
+ return { tracer, seed, baggage, childName };
996
1071
  }
997
1072
  function randomRuntimeId(prefix) {
998
1073
  const cryptoLike = globalThis.crypto;
@@ -1007,11 +1082,22 @@ function forkTrace(svc, parentTrace) {
1007
1082
  traceId: parentTrace.traceId,
1008
1083
  spanId: svc.tracer.newSpanId(),
1009
1084
  parentSpanId: parentTrace.spanId,
1010
- sampled: parentTrace.sampled
1085
+ sampled: parentTrace.sampled,
1086
+ traceState: parentTrace.traceState,
1087
+ baggage: parentTrace.baggage
1011
1088
  };
1012
1089
  }
1013
- if (svc.seed) return { ...svc.seed };
1014
- return { traceId: svc.tracer.newTraceId(), spanId: svc.tracer.newSpanId(), sampled: true };
1090
+ if (svc.seed) {
1091
+ const baggage2 = svc.seed.baggage ?? svc.baggage;
1092
+ return baggage2 ? { ...svc.seed, baggage: baggage2 } : { ...svc.seed };
1093
+ }
1094
+ const baggage = svc.baggage;
1095
+ return {
1096
+ traceId: svc.tracer.newTraceId(),
1097
+ spanId: svc.tracer.newSpanId(),
1098
+ sampled: true,
1099
+ ...baggage ? { baggage } : {}
1100
+ };
1015
1101
  }
1016
1102
 
1017
1103
  // src/core/runtime/engine/opcodes.ts
@@ -1605,19 +1691,6 @@ var WasmPackFiberBridge = class {
1605
1691
  this.maxEventsPerCall = Math.max(this.maxEventsPerCall, events.length);
1606
1692
  return events;
1607
1693
  }
1608
- decodeBinary(words) {
1609
- this.binaryEventCalls += 1;
1610
- const events = decodeEventBatch(words);
1611
- this.eventsReceived += events.length;
1612
- this.maxEventsPerCall = Math.max(this.maxEventsPerCall, events.length);
1613
- return events;
1614
- }
1615
- decodeJson(json) {
1616
- this.jsonEventCalls += 1;
1617
- this.eventsReceived += 1;
1618
- this.maxEventsPerCall = Math.max(this.maxEventsPerCall, 1);
1619
- return JSON.parse(json);
1620
- }
1621
1694
  memory() {
1622
1695
  const memory = this.vm.memory?.();
1623
1696
  if (!memory?.buffer) throw new Error("brass-runtime WASM memory is not available");
@@ -1997,9 +2070,9 @@ function inferLane2(tag) {
1997
2070
  }
1998
2071
  function extractTaggedLane2(tag, prefix) {
1999
2072
  if (!tag.startsWith(prefix)) return void 0;
2000
- const end2 = tag.indexOf("|", prefix.length);
2001
- if (end2 < 0) return void 0;
2002
- const value = tag.slice(prefix.length, end2);
2073
+ const end = tag.indexOf("|", prefix.length);
2074
+ if (end < 0) return void 0;
2075
+ const value = tag.slice(prefix.length, end);
2003
2076
  return value.length > 0 ? value : void 0;
2004
2077
  }
2005
2078
  function firstSeparatorIndex2(value) {
@@ -2103,7 +2176,7 @@ var WasmFiberEngine = class {
2103
2176
  }
2104
2177
  this.kind = this.bridge.kind;
2105
2178
  this.fiberRegistry = new WasmFiberRegistryBridge();
2106
- this.readyQueue = makeFiberReadyQueue({ engine: "wasm" });
2179
+ this.readyQueue = makeFiberReadyQueue({ engine: "wasm", ...options.readyQueue });
2107
2180
  this.timerWheel = makeWasmTimerWheel({ onExpired: (events) => this.onTimerExpired(events) });
2108
2181
  }
2109
2182
  runtime;
@@ -2666,6 +2739,12 @@ function normalizeRuntimeEngineMode(value) {
2666
2739
  function unreachableEngine(value) {
2667
2740
  throw new Error(`brass-runtime unsupported engine '${String(value)}'`);
2668
2741
  }
2742
+ var runtimeOptionsSchema = Schema.object({
2743
+ env: Schema.any(),
2744
+ lane: Schema.string({ minLength: 1 }).optional(),
2745
+ inferLane: Schema.boolean().optional(),
2746
+ engine: Schema.enum(["ts", "wasm"]).optional()
2747
+ }, { unknownKeys: "passthrough" });
2669
2748
  var Runtime = class _Runtime {
2670
2749
  env;
2671
2750
  scheduler;
@@ -2681,6 +2760,7 @@ var Runtime = class _Runtime {
2681
2760
  // opcional: registry para observabilidad
2682
2761
  registry;
2683
2762
  constructor(args) {
2763
+ parseConfig("RuntimeOptions", runtimeOptionsSchema, args);
2684
2764
  this.env = args.env;
2685
2765
  this.scheduler = args.scheduler ?? globalScheduler;
2686
2766
  this.lane = args.lane;
@@ -2746,7 +2826,11 @@ var Runtime = class _Runtime {
2746
2826
  scopeId: f?.scopeId,
2747
2827
  // ✅ FIX: era f?.scope
2748
2828
  traceId: f?.fiberContext?.trace?.traceId,
2749
- spanId: f?.fiberContext?.trace?.spanId
2829
+ spanId: f?.fiberContext?.trace?.spanId,
2830
+ parentSpanId: f?.fiberContext?.trace?.parentSpanId,
2831
+ traceState: f?.fiberContext?.trace?.traceState,
2832
+ baggage: f?.fiberContext?.trace?.baggage,
2833
+ sampled: f?.fiberContext?.trace?.sampled
2750
2834
  };
2751
2835
  this.hooks.emit(ev, ctx);
2752
2836
  }
@@ -3122,7 +3206,11 @@ var RuntimeFiber = class {
3122
3206
  fiberId: this.id,
3123
3207
  scopeId: this.scopeId,
3124
3208
  traceId: this.fiberContext?.trace?.traceId,
3125
- spanId: this.fiberContext?.trace?.spanId
3209
+ spanId: this.fiberContext?.trace?.spanId,
3210
+ parentSpanId: this.fiberContext?.trace?.parentSpanId,
3211
+ traceState: this.fiberContext?.trace?.traceState,
3212
+ baggage: this.fiberContext?.trace?.baggage,
3213
+ sampled: this.fiberContext?.trace?.sampled
3126
3214
  });
3127
3215
  }
3128
3216
  addFinalizer(f) {
@@ -3514,214 +3602,7 @@ var JsFiberEngine = class {
3514
3602
  }
3515
3603
  };
3516
3604
 
3517
- // src/core/runtime/scope.ts
3518
- var nextScopeId = 1;
3519
- function awaitAll(fibers) {
3520
- return asyncEffect((_env, cb) => {
3521
- let remaining = fibers.length;
3522
- if (remaining === 0) {
3523
- cb({ _tag: "Success", value: void 0 });
3524
- return;
3525
- }
3526
- for (const f of fibers) {
3527
- f.join(() => {
3528
- remaining -= 1;
3529
- if (remaining === 0) cb({ _tag: "Success", value: void 0 });
3530
- });
3531
- }
3532
- });
3533
- }
3534
- var Scope = class _Scope {
3535
- constructor(runtime, parentScopeId) {
3536
- this.runtime = runtime;
3537
- this.parentScopeId = parentScopeId;
3538
- this.id = nextScopeId++;
3539
- const inferredParent = this.parentScopeId ?? getCurrentFiber()?.scopeId;
3540
- if (this.runtime.hasActiveHooks()) {
3541
- this.runtime.emit({
3542
- type: "scope.open",
3543
- scopeId: this.id,
3544
- parentScopeId: inferredParent
3545
- });
3546
- }
3547
- }
3548
- runtime;
3549
- parentScopeId;
3550
- id;
3551
- closed = false;
3552
- children = /* @__PURE__ */ new Set();
3553
- subScopes = /* @__PURE__ */ new Set();
3554
- finalizers = [];
3555
- /** registra un finalizer (LIFO) */
3556
- addFinalizer(f) {
3557
- if (this.closed) {
3558
- throw new Error("Trying to add finalizer to closed scope");
3559
- }
3560
- this.finalizers.push(f);
3561
- }
3562
- /** crea un sub scope (mismo runtime) */
3563
- subScope() {
3564
- if (this.closed) throw new Error("Scope closed");
3565
- const s = new _Scope(this.runtime, this.id);
3566
- this.subScopes.add(s);
3567
- return s;
3568
- }
3569
- /** ✅ fork en este scope */
3570
- fork(eff) {
3571
- if (this.closed) throw new Error("Scope closed");
3572
- const f = this.runtime.fork(eff, this.id);
3573
- this.children.add(f);
3574
- f.join(() => this.children.delete(f));
3575
- return f;
3576
- }
3577
- /** close fire-and-forget (no bloquea) */
3578
- close(exit = { _tag: "Success", value: void 0 }) {
3579
- this.runtime.fork(this.closeAsync(exit));
3580
- }
3581
- /** Emit the scope.close event if hooks are active. */
3582
- emitCloseEvent(exit) {
3583
- if (this.runtime.hasActiveHooks()) {
3584
- const status = exit._tag === "Success" ? "success" : exit.cause._tag === "Interrupt" ? "interrupted" : "failure";
3585
- this.runtime.emit({
3586
- type: "scope.close",
3587
- scopeId: this.id,
3588
- status,
3589
- error: exit._tag === "Failure" && exit.cause._tag === "Fail" ? exit.cause.error : void 0
3590
- });
3591
- }
3592
- }
3593
- /**
3594
- * Build an effect that executes finalizers in LIFO order.
3595
- *
3596
- * Optimization over the original: instead of wrapping every finalizer in
3597
- * `asyncFold(fin(exit), () => unit(), () => unit())` which creates 3 effect
3598
- * nodes per finalizer (Fold + 2 Succeed), we use a single Sync thunk per
3599
- * finalizer that catches errors inline. When the finalizer returns a
3600
- * Succeed effect (like `unit()`), the Sync thunk completes without creating
3601
- * additional effect nodes.
3602
- */
3603
- buildFinalizerEffect(exit) {
3604
- const fins = this.finalizers;
3605
- if (fins.length === 0) return unit();
3606
- let chain = unit();
3607
- for (let i = fins.length - 1; i >= 0; i--) {
3608
- const fin = fins[i];
3609
- chain = asyncFlatMap(chain, () => {
3610
- let result;
3611
- try {
3612
- result = fin(exit);
3613
- } catch {
3614
- return unit();
3615
- }
3616
- if (result._tag === "Succeed") {
3617
- return unit();
3618
- }
3619
- return asyncFold(
3620
- result,
3621
- () => unit(),
3622
- () => unit()
3623
- );
3624
- });
3625
- }
3626
- return chain;
3627
- }
3628
- closeAsync(exit = { _tag: "Success", value: void 0 }, opts = { awaitChildren: true }) {
3629
- return asyncFlatMap(
3630
- unit(),
3631
- () => asyncEffect((env, cb) => {
3632
- if (this.closed) {
3633
- cb({ _tag: "Success", value: void 0 });
3634
- return;
3635
- }
3636
- this.closed = true;
3637
- const children = Array.from(this.children);
3638
- const subScopes = Array.from(this.subScopes);
3639
- for (const child of children) {
3640
- child.interrupt();
3641
- }
3642
- const closeSubs = subScopes.reduceRight(
3643
- (acc, s) => asyncFlatMap(acc, () => s.closeAsync(exit, opts)),
3644
- unit()
3645
- );
3646
- const runFinalizers = this.buildFinalizerEffect(exit);
3647
- const needsAwait = opts.awaitChildren && children.length > 0;
3648
- const awaitChildrenEff = needsAwait ? awaitAll(children) : unit();
3649
- const hasSubScopes = subScopes.length > 0;
3650
- const hasNoFinalizers = this.finalizers.length === 0;
3651
- if (!hasSubScopes && !needsAwait && hasNoFinalizers) {
3652
- this.emitCloseEvent(exit);
3653
- cb({ _tag: "Success", value: void 0 });
3654
- return;
3655
- }
3656
- const all = asyncFlatMap(closeSubs, () => asyncFlatMap(awaitChildrenEff, () => runFinalizers));
3657
- this.runtime.fork(all).join(() => {
3658
- this.emitCloseEvent(exit);
3659
- cb({ _tag: "Success", value: void 0 });
3660
- });
3661
- })
3662
- );
3663
- }
3664
- };
3665
- function withScopeAsync(runtime, f) {
3666
- return asyncEffect((_env, cb) => {
3667
- const scope = new Scope(runtime);
3668
- let done = false;
3669
- const completeAfterClose = (exit) => {
3670
- runtime.fork(scope.closeAsync(exit)).join(() => {
3671
- if (done) return;
3672
- done = true;
3673
- cb(exit);
3674
- });
3675
- };
3676
- const fiber = runtime.fork(f(scope));
3677
- fiber.join(completeAfterClose);
3678
- return () => {
3679
- if (done) return;
3680
- fiber.interrupt();
3681
- runtime.fork(scope.closeAsync(Exit.failCause(Cause.interrupt())));
3682
- };
3683
- });
3684
- }
3685
- function withScope(runtime, f) {
3686
- return withScopeAsync(runtime, (scope) => {
3687
- const out = f(scope);
3688
- if (out && typeof out === "object" && "_tag" in out) return out;
3689
- return unit();
3690
- });
3691
- }
3692
-
3693
3605
  export {
3694
- __require,
3695
- Async,
3696
- asyncFold,
3697
- asyncCatchAll,
3698
- asyncMapError,
3699
- unit,
3700
- asyncSucceed,
3701
- asyncFail,
3702
- asyncSync,
3703
- asyncTotal,
3704
- asyncEffect,
3705
- asyncMap,
3706
- asyncFlatMap,
3707
- acquireRelease,
3708
- asyncInterruptible,
3709
- withAsyncPromise,
3710
- mapAsync,
3711
- mapTryAsync,
3712
- none,
3713
- some,
3714
- Cause,
3715
- Exit,
3716
- succeed,
3717
- fail,
3718
- sync,
3719
- map,
3720
- flatMap,
3721
- mapError,
3722
- catchAll,
3723
- orElseOptional,
3724
- end,
3725
3606
  PushStatus,
3726
3607
  RingBuffer,
3727
3608
  resolveWasmModule,
@@ -3731,6 +3612,9 @@ export {
3731
3612
  inferCallerLaneFromStack,
3732
3613
  Scheduler,
3733
3614
  globalScheduler,
3615
+ emptyContext,
3616
+ ctxExtend,
3617
+ ctxToObject,
3734
3618
  DefaultHostExecutor,
3735
3619
  JsFiberEngine,
3736
3620
  HostRegistry,
@@ -3766,8 +3650,5 @@ export {
3766
3650
  RuntimeFiber,
3767
3651
  getCurrentFiber,
3768
3652
  unsafeGetCurrentRuntime,
3769
- withCurrentFiber,
3770
- Scope,
3771
- withScopeAsync,
3772
- withScope
3653
+ withCurrentFiber
3773
3654
  };