brass-runtime 1.15.0 → 1.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +673 -136
  3. package/dist/agent/cli/main.cjs +40 -35
  4. package/dist/agent/cli/main.js +9 -4
  5. package/dist/agent/cli/main.mjs +9 -4
  6. package/dist/agent/index.cjs +8 -4
  7. package/dist/agent/index.d.ts +1 -1
  8. package/dist/agent/index.js +7 -3
  9. package/dist/agent/index.mjs +7 -3
  10. package/dist/chunk-2HQTDLHF.mjs +683 -0
  11. package/dist/chunk-36I3M4UC.mjs +370 -0
  12. package/dist/chunk-3AYM6WPJ.js +1629 -0
  13. package/dist/chunk-3LOYJFRR.cjs +300 -0
  14. package/dist/chunk-3RG5ZIWI.js +10 -0
  15. package/dist/chunk-3Y2RIUMM.js +300 -0
  16. package/dist/{chunk-VEZNF5GZ.cjs → chunk-4ROBZFL6.cjs} +130 -126
  17. package/dist/{chunk-3QMOKAS5.js → chunk-52OB2ROS.js} +9 -5
  18. package/dist/chunk-52PPNNI4.cjs +416 -0
  19. package/dist/chunk-5EC274J5.cjs +2874 -0
  20. package/dist/chunk-5QC7LRZ3.js +229 -0
  21. package/dist/chunk-5VRJNBLZ.mjs +2874 -0
  22. package/dist/chunk-62AZW6UT.cjs +313 -0
  23. package/dist/chunk-6IXXWIUM.js +683 -0
  24. package/dist/chunk-74ZTY6CP.js +2871 -0
  25. package/dist/chunk-76YMRMH2.cjs +777 -0
  26. package/dist/chunk-7CMJS3QE.mjs +2871 -0
  27. package/dist/{chunk-4NHES7VK.mjs → chunk-7JIJOVCT.js} +27 -13
  28. package/dist/chunk-A2OM6NEH.mjs +194 -0
  29. package/dist/chunk-AGR5B2BC.cjs +683 -0
  30. package/dist/chunk-AVNQLJ5V.js +777 -0
  31. package/dist/chunk-B33ICAKP.js +313 -0
  32. package/dist/{chunk-ELOOF35R.mjs → chunk-B5JD23U7.mjs} +1 -1
  33. package/dist/chunk-BABBZK4Y.js +2024 -0
  34. package/dist/chunk-C3MDXTRZ.js +354 -0
  35. package/dist/chunk-CIZFIMK5.js +2193 -0
  36. package/dist/chunk-CZIVE6NT.cjs +354 -0
  37. package/dist/chunk-DNFJLJMW.mjs +354 -0
  38. package/dist/chunk-DNFO2EIZ.mjs +777 -0
  39. package/dist/chunk-EJ6BPYVR.mjs +416 -0
  40. package/dist/chunk-ENKODRU3.cjs +2193 -0
  41. package/dist/chunk-EOC4UHBS.mjs +229 -0
  42. package/dist/{chunk-BMH5AV44.js → chunk-FH2X7BVP.js} +756 -440
  43. package/dist/{chunk-PPUXIH5R.js → chunk-FHQGHPMO.mjs} +27 -13
  44. package/dist/{chunk-TGIFUAK4.cjs → chunk-GLE2WY7Z.cjs} +951 -635
  45. package/dist/{chunk-BDF4AMWX.mjs → chunk-GYM3LLGS.mjs} +756 -440
  46. package/dist/chunk-HLWLMW2F.mjs +2024 -0
  47. package/dist/chunk-JF5WGYJJ.cjs +194 -0
  48. package/dist/chunk-KH4SYAOS.mjs +1629 -0
  49. package/dist/chunk-KN32XNTH.mjs +313 -0
  50. package/dist/chunk-KQLYONSE.cjs +2871 -0
  51. package/dist/{chunk-STVLQ3XD.cjs → chunk-KZJQ723N.cjs} +92 -78
  52. package/dist/chunk-L2SYFEBS.js +194 -0
  53. package/dist/chunk-L6VB5N7Q.cjs +104 -0
  54. package/dist/{chunk-K6M7MDZ4.mjs → chunk-MBEJI5HF.mjs} +9 -5
  55. package/dist/chunk-MIIYDLGM.js +2874 -0
  56. package/dist/chunk-MOO4L7F4.mjs +104 -0
  57. package/dist/chunk-MT3OWDPC.mjs +2193 -0
  58. package/dist/chunk-MVGUEJ5Z.cjs +370 -0
  59. package/dist/chunk-OBGZSXTJ.cjs +10 -0
  60. package/dist/chunk-PD4EJTQC.cjs +229 -0
  61. package/dist/chunk-PWC3RBQE.mjs +300 -0
  62. package/dist/chunk-Q2I37RP3.cjs +1629 -0
  63. package/dist/chunk-RKGKFN2A.js +416 -0
  64. package/dist/{chunk-R3R2FVLG.cjs → chunk-SA6HUJVI.cjs} +5 -5
  65. package/dist/chunk-TRM4JUZQ.js +104 -0
  66. package/dist/chunk-UB4B6OFY.js +370 -0
  67. package/dist/{chunk-TO7IKXYT.js → chunk-UCUBNWM2.js} +1 -1
  68. package/dist/chunk-VN44DYYT.cjs +2024 -0
  69. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  70. package/dist/client-CZHU674n.d.ts +820 -0
  71. package/dist/core/index.cjs +198 -4
  72. package/dist/core/index.d.ts +311 -212
  73. package/dist/core/index.js +237 -43
  74. package/dist/core/index.mjs +237 -43
  75. package/dist/{effect-CMOQKX8y.d.ts → effect-DIUHZ9IN.d.ts} +195 -1
  76. package/dist/effectRunner-CFLC32IK.cjs +8 -0
  77. package/dist/effectRunner-L4S7IPT3.js +8 -0
  78. package/dist/effectRunner-NNGG75QA.mjs +8 -0
  79. package/dist/http/index.cjs +1227 -2971
  80. package/dist/http/index.d.ts +826 -280
  81. package/dist/http/index.js +1089 -2833
  82. package/dist/http/index.mjs +1089 -2833
  83. package/dist/http/testing.cjs +161 -0
  84. package/dist/http/testing.d.ts +43 -0
  85. package/dist/http/testing.js +161 -0
  86. package/dist/http/testing.mjs +161 -0
  87. package/dist/index.cjs +486 -250
  88. package/dist/index.d.ts +87 -95
  89. package/dist/index.js +391 -155
  90. package/dist/index.mjs +391 -155
  91. package/dist/observability/index.cjs +162 -0
  92. package/dist/observability/index.d.ts +152 -0
  93. package/dist/observability/index.js +162 -0
  94. package/dist/observability/index.mjs +162 -0
  95. package/dist/perf/cli.cjs +401 -0
  96. package/dist/perf/cli.d.ts +1 -0
  97. package/dist/perf/cli.js +401 -0
  98. package/dist/perf/cli.mjs +401 -0
  99. package/dist/perf/index.cjs +141 -0
  100. package/dist/perf/index.d.ts +483 -0
  101. package/dist/perf/index.js +141 -0
  102. package/dist/perf/index.mjs +141 -0
  103. package/dist/schedule-CK3Ml_7p.d.ts +259 -0
  104. package/dist/schema/index.cjs +29 -0
  105. package/dist/schema/index.d.ts +179 -0
  106. package/dist/schema/index.js +29 -0
  107. package/dist/schema/index.mjs +29 -0
  108. package/dist/server-GJPg8ZSG.d.ts +675 -0
  109. package/dist/{stream-FQm9h4Mg.d.ts → stream-B4oK9JFP.d.ts} +1 -1
  110. package/dist/tracer-Hwt1cl7h.d.ts +189 -0
  111. package/dist/tracing-DqbTKGcf.d.ts +148 -0
  112. package/docs/ARCHITECTURE.md +292 -0
  113. package/docs/README.md +63 -0
  114. package/docs/adr/0001-ai-context-pack.md +32 -0
  115. package/docs/agent-apply-mode.md +104 -0
  116. package/docs/agent-approvals.md +110 -0
  117. package/docs/agent-batch.md +185 -0
  118. package/docs/agent-boundaries.md +112 -0
  119. package/docs/agent-chat-sessions.md +160 -0
  120. package/docs/agent-ci.md +17 -0
  121. package/docs/agent-cli.md +405 -0
  122. package/docs/agent-config.md +480 -0
  123. package/docs/agent-context-discovery.md +159 -0
  124. package/docs/agent-copilot-like-dx.md +126 -0
  125. package/docs/agent-declarative-optimized-planning.md +138 -0
  126. package/docs/agent-dx.md +224 -0
  127. package/docs/agent-env-files.md +126 -0
  128. package/docs/agent-follow-up-context.md +43 -0
  129. package/docs/agent-global-usage.md +180 -0
  130. package/docs/agent-init.md +109 -0
  131. package/docs/agent-install-and-configure.md +516 -0
  132. package/docs/agent-language-workspace-ux.md +99 -0
  133. package/docs/agent-llm-adapters.md +123 -0
  134. package/docs/agent-local-install.md +190 -0
  135. package/docs/agent-local-tests.md +51 -0
  136. package/docs/agent-observability.md +155 -0
  137. package/docs/agent-patch-quality-loop.md +162 -0
  138. package/docs/agent-presets.md +22 -0
  139. package/docs/agent-project-commands.md +237 -0
  140. package/docs/agent-project-intelligence.md +156 -0
  141. package/docs/agent-redaction.md +18 -0
  142. package/docs/agent-release-readiness.md +76 -0
  143. package/docs/agent-rollback-safety.md +162 -0
  144. package/docs/agent-rollback.md +23 -0
  145. package/docs/agent-run-artifacts.md +16 -0
  146. package/docs/agent-vscode-auto-discovery.md +137 -0
  147. package/docs/agent-vscode-batch-runner.md +100 -0
  148. package/docs/agent-vscode-chat-layout.md +90 -0
  149. package/docs/agent-vscode-clean-install.md +147 -0
  150. package/docs/agent-vscode-code-actions.md +70 -0
  151. package/docs/agent-vscode-diff-preview.md +45 -0
  152. package/docs/agent-vscode-inline-assist.md +56 -0
  153. package/docs/agent-vscode-install.md +186 -0
  154. package/docs/agent-vscode-model-setup.md +97 -0
  155. package/docs/agent-vscode-patch-preview.md +92 -0
  156. package/docs/agent-vscode-problems.md +79 -0
  157. package/docs/agent-vscode-project-dashboard.md +106 -0
  158. package/docs/agent-vscode-run-history.md +92 -0
  159. package/docs/agent-vscode-ux.md +73 -0
  160. package/docs/ai/INVARIANTS.md +84 -0
  161. package/docs/ai/PROJECT_MAP.md +338 -0
  162. package/docs/ai/PUBLIC_API.md +336 -0
  163. package/docs/ai/VALIDATION_MATRIX.md +67 -0
  164. package/docs/api-polish.md +37 -0
  165. package/docs/cancellation.md +162 -0
  166. package/docs/coverage.md +46 -0
  167. package/docs/getting-started.md +159 -0
  168. package/docs/guides/README.md +40 -0
  169. package/docs/guides/circuit-breaker.md +89 -0
  170. package/docs/guides/error-handling.md +91 -0
  171. package/docs/guides/getting-started.md +107 -0
  172. package/docs/guides/layers.md +189 -0
  173. package/docs/guides/metrics.md +101 -0
  174. package/docs/guides/resource-management.md +141 -0
  175. package/docs/guides/retry.md +215 -0
  176. package/docs/guides/semaphore.md +66 -0
  177. package/docs/guides/streams.md +117 -0
  178. package/docs/guides/supervisors.md +98 -0
  179. package/docs/guides/testing.md +162 -0
  180. package/docs/guides/tracing.md +71 -0
  181. package/docs/http-recipes.md +399 -0
  182. package/docs/http.md +749 -0
  183. package/docs/modules.md +285 -0
  184. package/docs/observability-collector-smoke.md +31 -0
  185. package/docs/observability-framework-examples.md +98 -0
  186. package/docs/observability.md +542 -0
  187. package/docs/otel-collector-smoke.yaml +27 -0
  188. package/docs/performance-profiler.md +199 -0
  189. package/docs/production-readiness.md +73 -0
  190. package/docs/recipes/README.md +12 -0
  191. package/docs/recipes/http-server.md +45 -0
  192. package/docs/recipes/layers.md +44 -0
  193. package/docs/recipes/performance.md +47 -0
  194. package/docs/recipes/runtime.md +41 -0
  195. package/docs/recipes/testing.md +41 -0
  196. package/docs/release.md +53 -0
  197. package/docs/wasm-bounded-queues.md +44 -0
  198. package/docs/wasm-engine-observability-benchmarks.md +85 -0
  199. package/docs/wasm-fiber-engine.md +117 -0
  200. package/docs/wasm-scheduler-state-machine.md +122 -0
  201. package/docs/wasm-stream-chunks.md +54 -0
  202. package/package.json +48 -2
  203. package/dist/chunk-AR22SXML.js +0 -1043
  204. package/dist/chunk-BDYEENHT.js +0 -224
  205. package/dist/chunk-JFPU5GQI.mjs +0 -1043
  206. package/dist/chunk-MS34J5LY.cjs +0 -224
  207. package/dist/chunk-UMAZLXAB.mjs +0 -224
  208. package/dist/chunk-XPZNXSVN.cjs +0 -1043
  209. package/dist/tracing-DNT9jEbr.d.ts +0 -106
@@ -1,10 +1,17 @@
1
1
  import {
2
2
  raceWith
3
- } from "./chunk-ELOOF35R.mjs";
3
+ } from "./chunk-UCUBNWM2.js";
4
+ import {
5
+ Scope
6
+ } from "./chunk-L2SYFEBS.js";
7
+ import {
8
+ getCurrentFiber,
9
+ unsafeGetCurrentRuntime,
10
+ unsafeRunFoldWithEnv
11
+ } from "./chunk-FH2X7BVP.js";
4
12
  import {
5
13
  Cause,
6
14
  Exit,
7
- Scope,
8
15
  asyncEffect,
9
16
  asyncFail,
10
17
  asyncFlatMap,
@@ -14,17 +21,14 @@ import {
14
21
  asyncSync,
15
22
  fail,
16
23
  flatMap,
17
- getCurrentFiber,
18
24
  map,
19
25
  mapError,
20
26
  none,
21
27
  orElseOptional,
22
28
  some,
23
29
  succeed,
24
- sync,
25
- unsafeGetCurrentRuntime,
26
- unsafeRunFoldWithEnv
27
- } from "./chunk-BDF4AMWX.mjs";
30
+ sync
31
+ } from "./chunk-UB4B6OFY.js";
28
32
 
29
33
  // src/core/stream/stream.ts
30
34
  var widenOpt = (opt) => opt._tag === "None" ? none : some(opt.value);
@@ -74,12 +78,18 @@ function streamToRaceWithHandler(winnerSide, leftStream, rightStream, flip, id)
74
78
  const next = winnerSide === "L" ? fromPull(makeMergePull(tailWin, rightStream, !flip, id)) : fromPull(makeMergePull(leftStream, tailWin, !flip, id));
75
79
  return asyncSucceed([a, next]);
76
80
  }
77
- if (exit.cause._tag === "Interrupt") {
81
+ if (Cause.isInterruptedOnly(exit.cause)) {
78
82
  return asyncEffect((_env, cb) => {
79
83
  cb(Exit.failCause(Cause.interrupt()));
80
84
  });
81
85
  }
82
- const opt = exit.cause.error;
86
+ const failure = Cause.firstFailure(exit.cause);
87
+ if (failure._tag === "None") {
88
+ return asyncEffect((_env, cb) => {
89
+ cb(Exit.failCause(exit.cause));
90
+ });
91
+ }
92
+ const opt = failure.value;
83
93
  if (opt._tag === "None") {
84
94
  return winnerSide === "L" ? uncons(rightStream) : uncons(leftStream);
85
95
  }
@@ -163,7 +173,8 @@ function uncons(self) {
163
173
  });
164
174
  const closeWith = (exit) => {
165
175
  if (exit._tag === "Failure") {
166
- const err = exit.cause.error;
176
+ const failure = Cause.firstFailure(exit.cause);
177
+ const err = failure._tag === "Some" ? failure.value : void 0;
167
178
  if (err && typeof err === "object" && err._tag === "None") {
168
179
  scope.close({ _tag: "Success", value: void 0 });
169
180
  return;
@@ -191,7 +202,8 @@ function uncons(self) {
191
202
  scope.fork(self.acquire).join((ex) => {
192
203
  if (ex._tag === "Failure") {
193
204
  closeWith(ex);
194
- cb({ _tag: "Failure", cause: { _tag: "Fail", error: some(ex.cause.error) } });
205
+ const failure = Cause.firstFailure(ex.cause);
206
+ cb(failure._tag === "Some" ? { _tag: "Failure", cause: Cause.fail(some(failure.value)) } : { _tag: "Failure", cause: ex.cause });
195
207
  return;
196
208
  }
197
209
  scope.addFinalizer((exit) => self.release(exit));
@@ -211,7 +223,8 @@ function uncons(self) {
211
223
  });
212
224
  const closeWith = (exit) => {
213
225
  if (exit._tag === "Failure") {
214
- const err = exit.cause.error;
226
+ const failure = Cause.firstFailure(exit.cause);
227
+ const err = failure._tag === "Some" ? failure.value : void 0;
215
228
  if (err && typeof err === "object" && err._tag === "None") {
216
229
  scope.close({ _tag: "Success", value: void 0 });
217
230
  return;
@@ -222,7 +235,8 @@ function uncons(self) {
222
235
  scope.fork(self.acquire).join((ex) => {
223
236
  if (ex._tag === "Failure") {
224
237
  scope.close(ex);
225
- cb({ _tag: "Failure", cause: { _tag: "Fail", error: some(ex.cause.error) } });
238
+ const failure = Cause.firstFailure(ex.cause);
239
+ cb(failure._tag === "Some" ? { _tag: "Failure", cause: Cause.fail(some(failure.value)) } : { _tag: "Failure", cause: ex.cause });
226
240
  return;
227
241
  }
228
242
  const { stream: inner, release } = ex.value;
@@ -0,0 +1,194 @@
1
+ import {
2
+ getCurrentFiber
3
+ } from "./chunk-GYM3LLGS.mjs";
4
+ import {
5
+ Cause,
6
+ Exit,
7
+ asyncEffect,
8
+ asyncFlatMap,
9
+ asyncFold,
10
+ unit
11
+ } from "./chunk-36I3M4UC.mjs";
12
+
13
+ // src/core/runtime/scope.ts
14
+ var nextScopeId = 1;
15
+ function awaitAll(fibers) {
16
+ return asyncEffect((_env, cb) => {
17
+ let remaining = fibers.length;
18
+ if (remaining === 0) {
19
+ cb({ _tag: "Success", value: void 0 });
20
+ return;
21
+ }
22
+ for (const f of fibers) {
23
+ f.join(() => {
24
+ remaining -= 1;
25
+ if (remaining === 0) cb({ _tag: "Success", value: void 0 });
26
+ });
27
+ }
28
+ });
29
+ }
30
+ var Scope = class _Scope {
31
+ constructor(runtime, parentScopeId) {
32
+ this.runtime = runtime;
33
+ this.parentScopeId = parentScopeId;
34
+ this.id = nextScopeId++;
35
+ const inferredParent = this.parentScopeId ?? getCurrentFiber()?.scopeId;
36
+ if (this.runtime.hasActiveHooks()) {
37
+ this.runtime.emit({
38
+ type: "scope.open",
39
+ scopeId: this.id,
40
+ parentScopeId: inferredParent
41
+ });
42
+ }
43
+ }
44
+ runtime;
45
+ parentScopeId;
46
+ id;
47
+ closed = false;
48
+ children = /* @__PURE__ */ new Set();
49
+ subScopes = /* @__PURE__ */ new Set();
50
+ finalizers = [];
51
+ /** registra un finalizer (LIFO) */
52
+ addFinalizer(f) {
53
+ if (this.closed) {
54
+ throw new Error("Trying to add finalizer to closed scope");
55
+ }
56
+ this.finalizers.push(f);
57
+ }
58
+ /** crea un sub scope (mismo runtime) */
59
+ subScope() {
60
+ if (this.closed) throw new Error("Scope closed");
61
+ const s = new _Scope(this.runtime, this.id);
62
+ this.subScopes.add(s);
63
+ return s;
64
+ }
65
+ /** ✅ fork en este scope */
66
+ fork(eff) {
67
+ if (this.closed) throw new Error("Scope closed");
68
+ const f = this.runtime.fork(eff, this.id);
69
+ this.children.add(f);
70
+ f.join(() => this.children.delete(f));
71
+ return f;
72
+ }
73
+ /** close fire-and-forget (no bloquea) */
74
+ close(exit = { _tag: "Success", value: void 0 }) {
75
+ this.runtime.fork(this.closeAsync(exit));
76
+ }
77
+ /** Emit the scope.close event if hooks are active. */
78
+ emitCloseEvent(exit) {
79
+ if (this.runtime.hasActiveHooks()) {
80
+ const status = exit._tag === "Success" ? "success" : Cause.isInterruptedOnly(exit.cause) ? "interrupted" : "failure";
81
+ const failure = exit._tag === "Failure" ? Cause.firstFailure(exit.cause) : void 0;
82
+ this.runtime.emit({
83
+ type: "scope.close",
84
+ scopeId: this.id,
85
+ status,
86
+ error: failure?._tag === "Some" ? failure.value : exit._tag === "Failure" ? exit.cause : void 0
87
+ });
88
+ }
89
+ }
90
+ /**
91
+ * Build an effect that executes finalizers in LIFO order.
92
+ *
93
+ * Optimization over the original: instead of wrapping every finalizer in
94
+ * `asyncFold(fin(exit), () => unit(), () => unit())` which creates 3 effect
95
+ * nodes per finalizer (Fold + 2 Succeed), we use a single Sync thunk per
96
+ * finalizer that catches errors inline. When the finalizer returns a
97
+ * Succeed effect (like `unit()`), the Sync thunk completes without creating
98
+ * additional effect nodes.
99
+ */
100
+ buildFinalizerEffect(exit) {
101
+ const fins = this.finalizers;
102
+ if (fins.length === 0) return unit();
103
+ let chain = unit();
104
+ for (let i = fins.length - 1; i >= 0; i--) {
105
+ const fin = fins[i];
106
+ chain = asyncFlatMap(chain, () => {
107
+ let result;
108
+ try {
109
+ result = fin(exit);
110
+ } catch {
111
+ return unit();
112
+ }
113
+ if (result._tag === "Succeed") {
114
+ return unit();
115
+ }
116
+ return asyncFold(
117
+ result,
118
+ () => unit(),
119
+ () => unit()
120
+ );
121
+ });
122
+ }
123
+ return chain;
124
+ }
125
+ closeAsync(exit = { _tag: "Success", value: void 0 }, opts = { awaitChildren: true }) {
126
+ return asyncFlatMap(
127
+ unit(),
128
+ () => asyncEffect((env, cb) => {
129
+ if (this.closed) {
130
+ cb({ _tag: "Success", value: void 0 });
131
+ return;
132
+ }
133
+ this.closed = true;
134
+ const children = Array.from(this.children);
135
+ const subScopes = Array.from(this.subScopes);
136
+ for (const child of children) {
137
+ child.interrupt();
138
+ }
139
+ const closeSubs = subScopes.reduceRight(
140
+ (acc, s) => asyncFlatMap(acc, () => s.closeAsync(exit, opts)),
141
+ unit()
142
+ );
143
+ const runFinalizers = this.buildFinalizerEffect(exit);
144
+ const needsAwait = opts.awaitChildren && children.length > 0;
145
+ const awaitChildrenEff = needsAwait ? awaitAll(children) : unit();
146
+ const hasSubScopes = subScopes.length > 0;
147
+ const hasNoFinalizers = this.finalizers.length === 0;
148
+ if (!hasSubScopes && !needsAwait && hasNoFinalizers) {
149
+ this.emitCloseEvent(exit);
150
+ cb({ _tag: "Success", value: void 0 });
151
+ return;
152
+ }
153
+ const all = asyncFlatMap(closeSubs, () => asyncFlatMap(awaitChildrenEff, () => runFinalizers));
154
+ this.runtime.fork(all).join(() => {
155
+ this.emitCloseEvent(exit);
156
+ cb({ _tag: "Success", value: void 0 });
157
+ });
158
+ })
159
+ );
160
+ }
161
+ };
162
+ function withScopeAsync(runtime, f) {
163
+ return asyncEffect((_env, cb) => {
164
+ const scope = new Scope(runtime);
165
+ let done = false;
166
+ const completeAfterClose = (exit) => {
167
+ runtime.fork(scope.closeAsync(exit)).join(() => {
168
+ if (done) return;
169
+ done = true;
170
+ cb(exit);
171
+ });
172
+ };
173
+ const fiber = runtime.fork(f(scope));
174
+ fiber.join(completeAfterClose);
175
+ return () => {
176
+ if (done) return;
177
+ fiber.interrupt();
178
+ runtime.fork(scope.closeAsync(Exit.failCause(Cause.interrupt())));
179
+ };
180
+ });
181
+ }
182
+ function withScope(runtime, f) {
183
+ return withScopeAsync(runtime, (scope) => {
184
+ const out = f(scope);
185
+ if (out && typeof out === "object" && "_tag" in out) return out;
186
+ return unit();
187
+ });
188
+ }
189
+
190
+ export {
191
+ Scope,
192
+ withScopeAsync,
193
+ withScope
194
+ };