effect 3.6.7 → 3.7.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.
- package/dist/cjs/Array.js +1 -1
- package/dist/cjs/Array.js.map +1 -1
- package/dist/cjs/Config.js +8 -1
- package/dist/cjs/Config.js.map +1 -1
- package/dist/cjs/Context.js +9 -1
- package/dist/cjs/Context.js.map +1 -1
- package/dist/cjs/Effect.js +26 -4
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/Fiber.js.map +1 -1
- package/dist/cjs/FiberHandle.js +20 -8
- package/dist/cjs/FiberHandle.js.map +1 -1
- package/dist/cjs/FiberMap.js +22 -11
- package/dist/cjs/FiberMap.js.map +1 -1
- package/dist/cjs/FiberSet.js +23 -9
- package/dist/cjs/FiberSet.js.map +1 -1
- package/dist/cjs/Micro.js +9 -2
- package/dist/cjs/Micro.js.map +1 -1
- package/dist/cjs/Stream.js +30 -2
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/internal/config.js +7 -1
- package/dist/cjs/internal/config.js.map +1 -1
- package/dist/cjs/internal/context.js +8 -1
- package/dist/cjs/internal/context.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +3 -1
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js +23 -15
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/logger.js +4 -4
- package/dist/cjs/internal/logger.js.map +1 -1
- package/dist/cjs/internal/stream.js +6 -3
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/Array.d.ts +9 -9
- package/dist/dts/Array.d.ts.map +1 -1
- package/dist/dts/Config.d.ts +7 -0
- package/dist/dts/Config.d.ts.map +1 -1
- package/dist/dts/Context.d.ts +12 -0
- package/dist/dts/Context.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +84 -4
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Fiber.d.ts +5 -1
- package/dist/dts/Fiber.d.ts.map +1 -1
- package/dist/dts/FiberHandle.d.ts +7 -0
- package/dist/dts/FiberHandle.d.ts.map +1 -1
- package/dist/dts/FiberMap.d.ts +7 -0
- package/dist/dts/FiberMap.d.ts.map +1 -1
- package/dist/dts/FiberSet.d.ts +17 -5
- package/dist/dts/FiberSet.d.ts.map +1 -1
- package/dist/dts/Micro.d.ts +6 -0
- package/dist/dts/Micro.d.ts.map +1 -1
- package/dist/dts/Stream.d.ts +30 -0
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/internal/stream.d.ts +0 -1
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/Array.js +1 -1
- package/dist/esm/Array.js.map +1 -1
- package/dist/esm/Config.js +7 -0
- package/dist/esm/Config.js.map +1 -1
- package/dist/esm/Context.js +8 -0
- package/dist/esm/Context.js.map +1 -1
- package/dist/esm/Effect.js +22 -0
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/Fiber.js.map +1 -1
- package/dist/esm/FiberHandle.js +20 -8
- package/dist/esm/FiberHandle.js.map +1 -1
- package/dist/esm/FiberMap.js +22 -11
- package/dist/esm/FiberMap.js.map +1 -1
- package/dist/esm/FiberSet.js +23 -9
- package/dist/esm/FiberSet.js.map +1 -1
- package/dist/esm/Micro.js +7 -1
- package/dist/esm/Micro.js.map +1 -1
- package/dist/esm/Stream.js +27 -0
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/internal/config.js +5 -0
- package/dist/esm/internal/config.js.map +1 -1
- package/dist/esm/internal/context.js +7 -0
- package/dist/esm/internal/context.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +2 -0
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js +20 -13
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/logger.js +4 -4
- package/dist/esm/internal/logger.js.map +1 -1
- package/dist/esm/internal/stream.js +3 -0
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +1 -1
- package/src/Array.ts +39 -9
- package/src/Config.ts +8 -0
- package/src/Context.ts +13 -0
- package/src/Effect.ts +172 -19
- package/src/Fiber.ts +8 -1
- package/src/FiberHandle.ts +46 -10
- package/src/FiberMap.ts +48 -13
- package/src/FiberSet.ts +65 -24
- package/src/Micro.ts +8 -1
- package/src/Stream.ts +36 -0
- package/src/internal/config.ts +10 -0
- package/src/internal/context.ts +12 -0
- package/src/internal/effect/circular.ts +91 -0
- package/src/internal/fiberRuntime.ts +101 -30
- package/src/internal/logger.ts +5 -8
- package/src/internal/stream.ts +18 -0
- package/src/internal/version.ts +1 -1
package/src/FiberHandle.ts
CHANGED
|
@@ -10,7 +10,8 @@ import * as Exit from "./Exit.js"
|
|
|
10
10
|
import * as Fiber from "./Fiber.js"
|
|
11
11
|
import * as FiberId from "./FiberId.js"
|
|
12
12
|
import * as FiberRef from "./FiberRef.js"
|
|
13
|
-
import { dual } from "./Function.js"
|
|
13
|
+
import { constFalse, dual } from "./Function.js"
|
|
14
|
+
import * as HashSet from "./HashSet.js"
|
|
14
15
|
import * as Inspectable from "./Inspectable.js"
|
|
15
16
|
import type { FiberRuntime } from "./internal/fiberRuntime.js"
|
|
16
17
|
import * as Option from "./Option.js"
|
|
@@ -142,6 +143,17 @@ export const makeRuntime = <R, E = unknown, A = unknown>(): Effect.Effect<
|
|
|
142
143
|
(self) => runtime(self)<R>()
|
|
143
144
|
)
|
|
144
145
|
|
|
146
|
+
const internalFiberIdId = -1
|
|
147
|
+
const internalFiberId = FiberId.make(internalFiberIdId, 0)
|
|
148
|
+
const isInternalInterruption = Cause.reduceWithContext(undefined, {
|
|
149
|
+
emptyCase: constFalse,
|
|
150
|
+
failCase: constFalse,
|
|
151
|
+
dieCase: constFalse,
|
|
152
|
+
interruptCase: (_, fiberId) => HashSet.has(FiberId.ids(fiberId), internalFiberIdId),
|
|
153
|
+
sequentialCase: (_, left, right) => left || right,
|
|
154
|
+
parallelCase: (_, left, right) => left || right
|
|
155
|
+
})
|
|
156
|
+
|
|
145
157
|
/**
|
|
146
158
|
* Set the fiber in a FiberHandle. When the fiber completes, it will be removed from the FiberHandle.
|
|
147
159
|
* If a fiber is already running, it will be interrupted unless `options.onlyIfMissing` is set.
|
|
@@ -155,6 +167,7 @@ export const unsafeSet: {
|
|
|
155
167
|
options?: {
|
|
156
168
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
157
169
|
readonly onlyIfMissing?: boolean | undefined
|
|
170
|
+
readonly propagateInterruption?: boolean | undefined
|
|
158
171
|
}
|
|
159
172
|
): (self: FiberHandle<A, E>) => void
|
|
160
173
|
<A, E, XE extends E, XA extends A>(
|
|
@@ -163,6 +176,7 @@ export const unsafeSet: {
|
|
|
163
176
|
options?: {
|
|
164
177
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
165
178
|
readonly onlyIfMissing?: boolean | undefined
|
|
179
|
+
readonly propagateInterruption?: boolean | undefined
|
|
166
180
|
}
|
|
167
181
|
): void
|
|
168
182
|
} = dual((args) => isFiberHandle(args[0]), <A, E, XE extends E, XA extends A>(
|
|
@@ -171,19 +185,20 @@ export const unsafeSet: {
|
|
|
171
185
|
options?: {
|
|
172
186
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
173
187
|
readonly onlyIfMissing?: boolean | undefined
|
|
188
|
+
readonly propagateInterruption?: boolean | undefined
|
|
174
189
|
}
|
|
175
190
|
): void => {
|
|
176
191
|
if (self.state._tag === "Closed") {
|
|
177
|
-
fiber.unsafeInterruptAsFork(options?.interruptAs ?? FiberId.none)
|
|
192
|
+
fiber.unsafeInterruptAsFork(FiberId.combine(options?.interruptAs ?? FiberId.none, internalFiberId))
|
|
178
193
|
return
|
|
179
194
|
} else if (self.state.fiber !== undefined) {
|
|
180
195
|
if (options?.onlyIfMissing === true) {
|
|
181
|
-
fiber.unsafeInterruptAsFork(options?.interruptAs ?? FiberId.none)
|
|
196
|
+
fiber.unsafeInterruptAsFork(FiberId.combine(options?.interruptAs ?? FiberId.none, internalFiberId))
|
|
182
197
|
return
|
|
183
198
|
} else if (self.state.fiber === fiber) {
|
|
184
199
|
return
|
|
185
200
|
}
|
|
186
|
-
self.state.fiber.unsafeInterruptAsFork(options?.interruptAs ?? FiberId.none)
|
|
201
|
+
self.state.fiber.unsafeInterruptAsFork(FiberId.combine(options?.interruptAs ?? FiberId.none, internalFiberId))
|
|
187
202
|
self.state.fiber = undefined
|
|
188
203
|
}
|
|
189
204
|
|
|
@@ -193,7 +208,14 @@ export const unsafeSet: {
|
|
|
193
208
|
if (self.state._tag === "Open" && fiber === self.state.fiber) {
|
|
194
209
|
self.state.fiber = undefined
|
|
195
210
|
}
|
|
196
|
-
if (
|
|
211
|
+
if (
|
|
212
|
+
Exit.isFailure(exit) &&
|
|
213
|
+
(
|
|
214
|
+
options?.propagateInterruption === true ?
|
|
215
|
+
!isInternalInterruption(exit.cause) :
|
|
216
|
+
!Cause.isInterruptedOnly(exit.cause)
|
|
217
|
+
)
|
|
218
|
+
) {
|
|
197
219
|
Deferred.unsafeDone(self.deferred, exit as any)
|
|
198
220
|
}
|
|
199
221
|
})
|
|
@@ -211,6 +233,7 @@ export const set: {
|
|
|
211
233
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
212
234
|
options?: {
|
|
213
235
|
readonly onlyIfMissing?: boolean
|
|
236
|
+
readonly propagateInterruption?: boolean | undefined
|
|
214
237
|
}
|
|
215
238
|
): (self: FiberHandle<A, E>) => Effect.Effect<void>
|
|
216
239
|
<A, E, XE extends E, XA extends A>(
|
|
@@ -218,6 +241,7 @@ export const set: {
|
|
|
218
241
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
219
242
|
options?: {
|
|
220
243
|
readonly onlyIfMissing?: boolean
|
|
244
|
+
readonly propagateInterruption?: boolean | undefined
|
|
221
245
|
}
|
|
222
246
|
): Effect.Effect<void>
|
|
223
247
|
} = dual((args) => isFiberHandle(args[0]), <A, E, XE extends E, XA extends A>(
|
|
@@ -225,6 +249,7 @@ export const set: {
|
|
|
225
249
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
226
250
|
options?: {
|
|
227
251
|
readonly onlyIfMissing?: boolean
|
|
252
|
+
readonly propagateInterruption?: boolean | undefined
|
|
228
253
|
}
|
|
229
254
|
): Effect.Effect<void> =>
|
|
230
255
|
Effect.fiberIdWith(
|
|
@@ -232,7 +257,8 @@ export const set: {
|
|
|
232
257
|
Effect.sync(() =>
|
|
233
258
|
unsafeSet(self, fiber, {
|
|
234
259
|
interruptAs: fiberId,
|
|
235
|
-
onlyIfMissing: options?.onlyIfMissing
|
|
260
|
+
onlyIfMissing: options?.onlyIfMissing,
|
|
261
|
+
propagateInterruption: options?.propagateInterruption
|
|
236
262
|
})
|
|
237
263
|
)
|
|
238
264
|
))
|
|
@@ -261,12 +287,12 @@ export const get = <A, E>(self: FiberHandle<A, E>): Effect.Effect<Fiber.RuntimeF
|
|
|
261
287
|
*/
|
|
262
288
|
export const clear = <A, E>(self: FiberHandle<A, E>): Effect.Effect<void> =>
|
|
263
289
|
Effect.uninterruptibleMask((restore) =>
|
|
264
|
-
Effect.
|
|
290
|
+
Effect.withFiberRuntime((fiber) => {
|
|
265
291
|
if (self.state._tag === "Closed" || self.state.fiber === undefined) {
|
|
266
292
|
return Effect.void
|
|
267
293
|
}
|
|
268
294
|
return Effect.zipRight(
|
|
269
|
-
restore(Fiber.
|
|
295
|
+
restore(Fiber.interruptAs(self.state.fiber, FiberId.combine(fiber.id(), internalFiberId))),
|
|
270
296
|
Effect.sync(() => {
|
|
271
297
|
if (self.state._tag === "Open") {
|
|
272
298
|
self.state.fiber = undefined
|
|
@@ -298,6 +324,7 @@ export const run: {
|
|
|
298
324
|
self: FiberHandle<A, E>,
|
|
299
325
|
options?: {
|
|
300
326
|
readonly onlyIfMissing?: boolean
|
|
327
|
+
readonly propagateInterruption?: boolean | undefined
|
|
301
328
|
}
|
|
302
329
|
): <R, XE extends E, XA extends A>(
|
|
303
330
|
effect: Effect.Effect<XA, XE, R>
|
|
@@ -307,13 +334,17 @@ export const run: {
|
|
|
307
334
|
effect: Effect.Effect<XA, XE, R>,
|
|
308
335
|
options?: {
|
|
309
336
|
readonly onlyIfMissing?: boolean
|
|
337
|
+
readonly propagateInterruption?: boolean | undefined
|
|
310
338
|
}
|
|
311
339
|
): Effect.Effect<Fiber.RuntimeFiber<XA, XE>, never, R>
|
|
312
340
|
} = function() {
|
|
313
341
|
const self = arguments[0] as FiberHandle
|
|
314
342
|
if (Effect.isEffect(arguments[1])) {
|
|
315
343
|
const effect = arguments[1]
|
|
316
|
-
const options = arguments[2] as {
|
|
344
|
+
const options = arguments[2] as {
|
|
345
|
+
readonly onlyIfMissing?: boolean
|
|
346
|
+
readonly propagateInterruption?: boolean | undefined
|
|
347
|
+
} | undefined
|
|
317
348
|
return Effect.suspend(() => {
|
|
318
349
|
if (self.state._tag === "Closed") {
|
|
319
350
|
return Effect.interrupt
|
|
@@ -328,7 +359,10 @@ export const run: {
|
|
|
328
359
|
)
|
|
329
360
|
}) as any
|
|
330
361
|
}
|
|
331
|
-
const options = arguments[1] as {
|
|
362
|
+
const options = arguments[1] as {
|
|
363
|
+
readonly onlyIfMissing?: boolean
|
|
364
|
+
readonly propagateInterruption?: boolean | undefined
|
|
365
|
+
} | undefined
|
|
332
366
|
return (effect: Effect.Effect<unknown, unknown, any>) =>
|
|
333
367
|
Effect.suspend(() => {
|
|
334
368
|
if (self.state._tag === "Closed") {
|
|
@@ -382,6 +416,7 @@ export const runtime: <A, E>(
|
|
|
382
416
|
options?:
|
|
383
417
|
| Runtime.RunForkOptions & {
|
|
384
418
|
readonly onlyIfMissing?: boolean | undefined
|
|
419
|
+
readonly propagateInterruption?: boolean | undefined
|
|
385
420
|
}
|
|
386
421
|
| undefined
|
|
387
422
|
) => Fiber.RuntimeFiber<XA, XE>,
|
|
@@ -397,6 +432,7 @@ export const runtime: <A, E>(
|
|
|
397
432
|
options?:
|
|
398
433
|
| Runtime.RunForkOptions & {
|
|
399
434
|
readonly onlyIfMissing?: boolean | undefined
|
|
435
|
+
readonly propagateInterruption?: boolean | undefined
|
|
400
436
|
}
|
|
401
437
|
| undefined
|
|
402
438
|
) => {
|
package/src/FiberMap.ts
CHANGED
|
@@ -10,7 +10,8 @@ import * as Exit from "./Exit.js"
|
|
|
10
10
|
import * as Fiber from "./Fiber.js"
|
|
11
11
|
import * as FiberId from "./FiberId.js"
|
|
12
12
|
import * as FiberRef from "./FiberRef.js"
|
|
13
|
-
import { dual } from "./Function.js"
|
|
13
|
+
import { constFalse, dual } from "./Function.js"
|
|
14
|
+
import * as HashSet from "./HashSet.js"
|
|
14
15
|
import * as Inspectable from "./Inspectable.js"
|
|
15
16
|
import type { FiberRuntime } from "./internal/fiberRuntime.js"
|
|
16
17
|
import * as Iterable from "./Iterable.js"
|
|
@@ -157,6 +158,17 @@ export const makeRuntime = <R, K, E = unknown, A = unknown>(): Effect.Effect<
|
|
|
157
158
|
(self) => runtime(self)<R>()
|
|
158
159
|
)
|
|
159
160
|
|
|
161
|
+
const internalFiberIdId = -1
|
|
162
|
+
const internalFiberId = FiberId.make(internalFiberIdId, 0)
|
|
163
|
+
const isInternalInterruption = Cause.reduceWithContext(undefined, {
|
|
164
|
+
emptyCase: constFalse,
|
|
165
|
+
failCase: constFalse,
|
|
166
|
+
dieCase: constFalse,
|
|
167
|
+
interruptCase: (_, fiberId) => HashSet.has(FiberId.ids(fiberId), internalFiberIdId),
|
|
168
|
+
sequentialCase: (_, left, right) => left || right,
|
|
169
|
+
parallelCase: (_, left, right) => left || right
|
|
170
|
+
})
|
|
171
|
+
|
|
160
172
|
/**
|
|
161
173
|
* Add a fiber to the FiberMap. When the fiber completes, it will be removed from the FiberMap.
|
|
162
174
|
* If the key already exists in the FiberMap, the previous fiber will be interrupted.
|
|
@@ -171,6 +183,7 @@ export const unsafeSet: {
|
|
|
171
183
|
options?: {
|
|
172
184
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
173
185
|
readonly onlyIfMissing?: boolean | undefined
|
|
186
|
+
readonly propagateInterruption?: boolean | undefined
|
|
174
187
|
} | undefined
|
|
175
188
|
): (self: FiberMap<K, A, E>) => void
|
|
176
189
|
<K, A, E, XE extends E, XA extends A>(
|
|
@@ -180,6 +193,7 @@ export const unsafeSet: {
|
|
|
180
193
|
options?: {
|
|
181
194
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
182
195
|
readonly onlyIfMissing?: boolean | undefined
|
|
196
|
+
readonly propagateInterruption?: boolean | undefined
|
|
183
197
|
} | undefined
|
|
184
198
|
): void
|
|
185
199
|
} = dual((args) => isFiberMap(args[0]), <K, A, E, XE extends E, XA extends A>(
|
|
@@ -189,22 +203,23 @@ export const unsafeSet: {
|
|
|
189
203
|
options?: {
|
|
190
204
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
191
205
|
readonly onlyIfMissing?: boolean | undefined
|
|
206
|
+
readonly propagateInterruption?: boolean | undefined
|
|
192
207
|
} | undefined
|
|
193
208
|
): void => {
|
|
194
209
|
if (self.state._tag === "Closed") {
|
|
195
|
-
fiber.unsafeInterruptAsFork(options?.interruptAs ?? FiberId.none)
|
|
210
|
+
fiber.unsafeInterruptAsFork(FiberId.combine(options?.interruptAs ?? FiberId.none, internalFiberId))
|
|
196
211
|
return
|
|
197
212
|
}
|
|
198
213
|
|
|
199
214
|
const previous = MutableHashMap.get(self.state.backing, key)
|
|
200
215
|
if (previous._tag === "Some") {
|
|
201
216
|
if (options?.onlyIfMissing === true) {
|
|
202
|
-
fiber.unsafeInterruptAsFork(options?.interruptAs ?? FiberId.none)
|
|
217
|
+
fiber.unsafeInterruptAsFork(FiberId.combine(options?.interruptAs ?? FiberId.none, internalFiberId))
|
|
203
218
|
return
|
|
204
219
|
} else if (previous.value === fiber) {
|
|
205
220
|
return
|
|
206
221
|
}
|
|
207
|
-
previous.value.unsafeInterruptAsFork(options?.interruptAs ?? FiberId.none)
|
|
222
|
+
previous.value.unsafeInterruptAsFork(FiberId.combine(options?.interruptAs ?? FiberId.none, internalFiberId))
|
|
208
223
|
}
|
|
209
224
|
|
|
210
225
|
;(fiber as FiberRuntime<unknown, unknown>).setFiberRef(FiberRef.unhandledErrorLogLevel, Option.none())
|
|
@@ -217,7 +232,14 @@ export const unsafeSet: {
|
|
|
217
232
|
if (Option.isSome(current) && fiber === current.value) {
|
|
218
233
|
MutableHashMap.remove(self.state.backing, key)
|
|
219
234
|
}
|
|
220
|
-
if (
|
|
235
|
+
if (
|
|
236
|
+
Exit.isFailure(exit) &&
|
|
237
|
+
(
|
|
238
|
+
options?.propagateInterruption === true ?
|
|
239
|
+
!isInternalInterruption(exit.cause) :
|
|
240
|
+
!Cause.isInterruptedOnly(exit.cause)
|
|
241
|
+
)
|
|
242
|
+
) {
|
|
221
243
|
Deferred.unsafeDone(self.deferred, exit as any)
|
|
222
244
|
}
|
|
223
245
|
})
|
|
@@ -236,6 +258,7 @@ export const set: {
|
|
|
236
258
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
237
259
|
options?: {
|
|
238
260
|
readonly onlyIfMissing?: boolean | undefined
|
|
261
|
+
readonly propagateInterruption?: boolean | undefined
|
|
239
262
|
} | undefined
|
|
240
263
|
): (self: FiberMap<K, A, E>) => Effect.Effect<void>
|
|
241
264
|
<K, A, E, XE extends E, XA extends A>(
|
|
@@ -244,6 +267,7 @@ export const set: {
|
|
|
244
267
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
245
268
|
options?: {
|
|
246
269
|
readonly onlyIfMissing?: boolean | undefined
|
|
270
|
+
readonly propagateInterruption?: boolean | undefined
|
|
247
271
|
} | undefined
|
|
248
272
|
): Effect.Effect<void>
|
|
249
273
|
} = dual((args) => isFiberMap(args[0]), <K, A, E, XE extends E, XA extends A>(
|
|
@@ -252,14 +276,15 @@ export const set: {
|
|
|
252
276
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
253
277
|
options?: {
|
|
254
278
|
readonly onlyIfMissing?: boolean | undefined
|
|
279
|
+
readonly propagateInterruption?: boolean | undefined
|
|
255
280
|
} | undefined
|
|
256
281
|
): Effect.Effect<void> =>
|
|
257
282
|
Effect.fiberIdWith(
|
|
258
283
|
(fiberId) =>
|
|
259
284
|
Effect.sync(() =>
|
|
260
285
|
unsafeSet(self, key, fiber, {
|
|
261
|
-
|
|
262
|
-
|
|
286
|
+
...options,
|
|
287
|
+
interruptAs: fiberId
|
|
263
288
|
})
|
|
264
289
|
)
|
|
265
290
|
))
|
|
@@ -349,7 +374,7 @@ export const remove: {
|
|
|
349
374
|
key: K
|
|
350
375
|
) => Effect.Effect<void>
|
|
351
376
|
>(2, (self, key) =>
|
|
352
|
-
Effect.
|
|
377
|
+
Effect.withFiberRuntime((removeFiber) => {
|
|
353
378
|
if (self.state._tag === "Closed") {
|
|
354
379
|
return Effect.void
|
|
355
380
|
}
|
|
@@ -358,7 +383,7 @@ export const remove: {
|
|
|
358
383
|
return Effect.void
|
|
359
384
|
}
|
|
360
385
|
// will be removed by the observer
|
|
361
|
-
return Fiber.
|
|
386
|
+
return Fiber.interruptAs(fiber.value, FiberId.combine(removeFiber.id(), internalFiberId))
|
|
362
387
|
}))
|
|
363
388
|
|
|
364
389
|
/**
|
|
@@ -366,14 +391,14 @@ export const remove: {
|
|
|
366
391
|
* @categories combinators
|
|
367
392
|
*/
|
|
368
393
|
export const clear = <K, A, E>(self: FiberMap<K, A, E>): Effect.Effect<void> =>
|
|
369
|
-
Effect.
|
|
394
|
+
Effect.withFiberRuntime((clearFiber) => {
|
|
370
395
|
if (self.state._tag === "Closed") {
|
|
371
396
|
return Effect.void
|
|
372
397
|
}
|
|
373
398
|
|
|
374
399
|
return Effect.forEach(self.state.backing, ([, fiber]) =>
|
|
375
400
|
// will be removed by the observer
|
|
376
|
-
Fiber.
|
|
401
|
+
Fiber.interruptAs(fiber, FiberId.combine(clearFiber.id(), internalFiberId)))
|
|
377
402
|
})
|
|
378
403
|
|
|
379
404
|
const constInterruptedFiber = (function() {
|
|
@@ -399,6 +424,7 @@ export const run: {
|
|
|
399
424
|
key: K,
|
|
400
425
|
options?: {
|
|
401
426
|
readonly onlyIfMissing?: boolean | undefined
|
|
427
|
+
readonly propagateInterruption?: boolean | undefined
|
|
402
428
|
} | undefined
|
|
403
429
|
): <R, XE extends E, XA extends A>(
|
|
404
430
|
effect: Effect.Effect<XA, XE, R>
|
|
@@ -409,6 +435,7 @@ export const run: {
|
|
|
409
435
|
effect: Effect.Effect<XA, XE, R>,
|
|
410
436
|
options?: {
|
|
411
437
|
readonly onlyIfMissing?: boolean | undefined
|
|
438
|
+
readonly propagateInterruption?: boolean | undefined
|
|
412
439
|
} | undefined
|
|
413
440
|
): Effect.Effect<Fiber.RuntimeFiber<XA, XE>, never, R>
|
|
414
441
|
} = function() {
|
|
@@ -416,7 +443,10 @@ export const run: {
|
|
|
416
443
|
const self = arguments[0] as FiberMap<any>
|
|
417
444
|
const key = arguments[1]
|
|
418
445
|
const effect = arguments[2] as Effect.Effect<any, any, any>
|
|
419
|
-
const options = arguments[3] as {
|
|
446
|
+
const options = arguments[3] as {
|
|
447
|
+
readonly onlyIfMissing?: boolean
|
|
448
|
+
readonly propagateInterruption?: boolean | undefined
|
|
449
|
+
} | undefined
|
|
420
450
|
return Effect.suspend(() => {
|
|
421
451
|
if (self.state._tag === "Closed") {
|
|
422
452
|
return Effect.interrupt
|
|
@@ -433,7 +463,10 @@ export const run: {
|
|
|
433
463
|
}
|
|
434
464
|
const self = arguments[0] as FiberMap<any>
|
|
435
465
|
const key = arguments[1]
|
|
436
|
-
const options = arguments[2] as {
|
|
466
|
+
const options = arguments[2] as {
|
|
467
|
+
readonly onlyIfMissing?: boolean
|
|
468
|
+
readonly propagateInterruption?: boolean | undefined
|
|
469
|
+
} | undefined
|
|
437
470
|
return (effect: Effect.Effect<any, any, any>) =>
|
|
438
471
|
Effect.suspend(() => {
|
|
439
472
|
if (self.state._tag === "Closed") {
|
|
@@ -486,6 +519,7 @@ export const runtime: <K, A, E>(
|
|
|
486
519
|
options?:
|
|
487
520
|
| Runtime.RunForkOptions & {
|
|
488
521
|
readonly onlyIfMissing?: boolean | undefined
|
|
522
|
+
readonly propagateInterruption?: boolean | undefined
|
|
489
523
|
}
|
|
490
524
|
| undefined
|
|
491
525
|
) => Fiber.RuntimeFiber<XA, XE>,
|
|
@@ -502,6 +536,7 @@ export const runtime: <K, A, E>(
|
|
|
502
536
|
options?:
|
|
503
537
|
| Runtime.RunForkOptions & {
|
|
504
538
|
readonly onlyIfMissing?: boolean | undefined
|
|
539
|
+
readonly propagateInterruption?: boolean | undefined
|
|
505
540
|
}
|
|
506
541
|
| undefined
|
|
507
542
|
) => {
|
package/src/FiberSet.ts
CHANGED
|
@@ -9,7 +9,8 @@ import * as Deferred from "./Deferred.js"
|
|
|
9
9
|
import * as Exit from "./Exit.js"
|
|
10
10
|
import * as Fiber from "./Fiber.js"
|
|
11
11
|
import * as FiberRef from "./FiberRef.js"
|
|
12
|
-
import { dual } from "./Function.js"
|
|
12
|
+
import { constFalse, dual } from "./Function.js"
|
|
13
|
+
import * as HashSet from "./HashSet.js"
|
|
13
14
|
import * as Inspectable from "./Inspectable.js"
|
|
14
15
|
import type { FiberRuntime } from "./internal/fiberRuntime.js"
|
|
15
16
|
import * as Iterable from "./Iterable.js"
|
|
@@ -146,6 +147,17 @@ export const makeRuntime = <R = never, A = unknown, E = unknown>(): Effect.Effec
|
|
|
146
147
|
(self) => runtime(self)<R>()
|
|
147
148
|
)
|
|
148
149
|
|
|
150
|
+
const internalFiberIdId = -1
|
|
151
|
+
const internalFiberId = FiberId.make(internalFiberIdId, 0)
|
|
152
|
+
const isInternalInterruption = Cause.reduceWithContext(undefined, {
|
|
153
|
+
emptyCase: constFalse,
|
|
154
|
+
failCase: constFalse,
|
|
155
|
+
dieCase: constFalse,
|
|
156
|
+
interruptCase: (_, fiberId) => HashSet.has(FiberId.ids(fiberId), internalFiberIdId),
|
|
157
|
+
sequentialCase: (_, left, right) => left || right,
|
|
158
|
+
parallelCase: (_, left, right) => left || right
|
|
159
|
+
})
|
|
160
|
+
|
|
149
161
|
/**
|
|
150
162
|
* Add a fiber to the FiberSet. When the fiber completes, it will be removed.
|
|
151
163
|
*
|
|
@@ -157,6 +169,7 @@ export const unsafeAdd: {
|
|
|
157
169
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
158
170
|
options?: {
|
|
159
171
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
172
|
+
readonly propagateInterruption?: boolean | undefined
|
|
160
173
|
} | undefined
|
|
161
174
|
): (self: FiberSet<A, E>) => void
|
|
162
175
|
<A, E, XE extends E, XA extends A>(
|
|
@@ -164,6 +177,7 @@ export const unsafeAdd: {
|
|
|
164
177
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
165
178
|
options?: {
|
|
166
179
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
180
|
+
readonly propagateInterruption?: boolean | undefined
|
|
167
181
|
} | undefined
|
|
168
182
|
): void
|
|
169
183
|
} = dual((args) => isFiberSet(args[0]), <A, E, XE extends E, XA extends A>(
|
|
@@ -171,10 +185,11 @@ export const unsafeAdd: {
|
|
|
171
185
|
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
172
186
|
options?: {
|
|
173
187
|
readonly interruptAs?: FiberId.FiberId | undefined
|
|
188
|
+
readonly propagateInterruption?: boolean | undefined
|
|
174
189
|
} | undefined
|
|
175
190
|
): void => {
|
|
176
191
|
if (self.state._tag === "Closed") {
|
|
177
|
-
fiber.unsafeInterruptAsFork(options?.interruptAs ?? FiberId.none)
|
|
192
|
+
fiber.unsafeInterruptAsFork(FiberId.combine(options?.interruptAs ?? FiberId.none, internalFiberId))
|
|
178
193
|
return
|
|
179
194
|
} else if (self.state.backing.has(fiber)) {
|
|
180
195
|
return
|
|
@@ -186,7 +201,14 @@ export const unsafeAdd: {
|
|
|
186
201
|
return
|
|
187
202
|
}
|
|
188
203
|
self.state.backing.delete(fiber)
|
|
189
|
-
if (
|
|
204
|
+
if (
|
|
205
|
+
Exit.isFailure(exit) &&
|
|
206
|
+
(
|
|
207
|
+
options?.propagateInterruption === true ?
|
|
208
|
+
!isInternalInterruption(exit.cause) :
|
|
209
|
+
!Cause.isInterruptedOnly(exit.cause)
|
|
210
|
+
)
|
|
211
|
+
) {
|
|
190
212
|
Deferred.unsafeDone(self.deferred, exit as any)
|
|
191
213
|
}
|
|
192
214
|
})
|
|
@@ -200,26 +222,31 @@ export const unsafeAdd: {
|
|
|
200
222
|
*/
|
|
201
223
|
export const add: {
|
|
202
224
|
<A, E, XE extends E, XA extends A>(
|
|
203
|
-
fiber: Fiber.RuntimeFiber<XA, XE
|
|
225
|
+
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
226
|
+
options?: {
|
|
227
|
+
readonly propagateInterruption?: boolean | undefined
|
|
228
|
+
} | undefined
|
|
204
229
|
): (self: FiberSet<A, E>) => Effect.Effect<void>
|
|
205
230
|
<A, E, XE extends E, XA extends A>(
|
|
206
231
|
self: FiberSet<A, E>,
|
|
207
|
-
fiber: Fiber.RuntimeFiber<XA, XE
|
|
232
|
+
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
233
|
+
options?: {
|
|
234
|
+
readonly propagateInterruption?: boolean | undefined
|
|
235
|
+
} | undefined
|
|
208
236
|
): Effect.Effect<void>
|
|
209
|
-
} = dual
|
|
210
|
-
|
|
211
|
-
fiber: Fiber.RuntimeFiber<XA, XE>
|
|
212
|
-
) => (self: FiberSet<A, E>) => Effect.Effect<void>,
|
|
237
|
+
} = dual(
|
|
238
|
+
(args) => isFiberSet(args[0]),
|
|
213
239
|
<A, E, XE extends E, XA extends A>(
|
|
214
240
|
self: FiberSet<A, E>,
|
|
215
|
-
fiber: Fiber.RuntimeFiber<XA, XE
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
241
|
+
fiber: Fiber.RuntimeFiber<XA, XE>,
|
|
242
|
+
options?: {
|
|
243
|
+
readonly propagateInterruption?: boolean | undefined
|
|
244
|
+
} | undefined
|
|
245
|
+
): Effect.Effect<void> =>
|
|
220
246
|
Effect.fiberIdWith((fiberId) =>
|
|
221
247
|
Effect.sync(() =>
|
|
222
248
|
unsafeAdd(self, fiber, {
|
|
249
|
+
...options,
|
|
223
250
|
interruptAs: fiberId
|
|
224
251
|
})
|
|
225
252
|
)
|
|
@@ -231,13 +258,13 @@ export const add: {
|
|
|
231
258
|
* @categories combinators
|
|
232
259
|
*/
|
|
233
260
|
export const clear = <A, E>(self: FiberSet<A, E>): Effect.Effect<void> =>
|
|
234
|
-
Effect.
|
|
261
|
+
Effect.withFiberRuntime((clearFiber) => {
|
|
235
262
|
if (self.state._tag === "Closed") {
|
|
236
263
|
return Effect.void
|
|
237
264
|
}
|
|
238
265
|
return Effect.forEach(self.state.backing, (fiber) =>
|
|
239
266
|
// will be removed by the observer
|
|
240
|
-
Fiber.
|
|
267
|
+
Fiber.interruptAs(fiber, FiberId.combine(clearFiber.id(), internalFiberId)))
|
|
241
268
|
})
|
|
242
269
|
|
|
243
270
|
/**
|
|
@@ -248,16 +275,25 @@ export const clear = <A, E>(self: FiberSet<A, E>): Effect.Effect<void> =>
|
|
|
248
275
|
* @categories combinators
|
|
249
276
|
*/
|
|
250
277
|
export const run: {
|
|
251
|
-
<A, E>(
|
|
278
|
+
<A, E>(
|
|
279
|
+
self: FiberSet<A, E>,
|
|
280
|
+
options?: {
|
|
281
|
+
readonly propagateInterruption?: boolean | undefined
|
|
282
|
+
} | undefined
|
|
283
|
+
): <R, XE extends E, XA extends A>(
|
|
252
284
|
effect: Effect.Effect<XA, XE, R>
|
|
253
285
|
) => Effect.Effect<Fiber.RuntimeFiber<XA, XE>, never, R>
|
|
254
286
|
<A, E, R, XE extends E, XA extends A>(
|
|
255
287
|
self: FiberSet<A, E>,
|
|
256
|
-
effect: Effect.Effect<XA, XE, R
|
|
288
|
+
effect: Effect.Effect<XA, XE, R>,
|
|
289
|
+
options?: {
|
|
290
|
+
readonly propagateInterruption?: boolean | undefined
|
|
291
|
+
} | undefined
|
|
257
292
|
): Effect.Effect<Fiber.RuntimeFiber<XA, XE>, never, R>
|
|
258
293
|
} = function() {
|
|
259
294
|
const self = arguments[0] as FiberSet<any, any>
|
|
260
|
-
if (arguments
|
|
295
|
+
if (!Effect.isEffect(arguments[1])) {
|
|
296
|
+
const options = arguments[1] as { readonly propagateInterruption?: boolean | undefined } | undefined
|
|
261
297
|
return (effect: Effect.Effect<any, any, any>) =>
|
|
262
298
|
Effect.suspend(() => {
|
|
263
299
|
if (self.state._tag === "Closed") {
|
|
@@ -266,12 +302,13 @@ export const run: {
|
|
|
266
302
|
return Effect.uninterruptibleMask((restore) =>
|
|
267
303
|
Effect.tap(
|
|
268
304
|
restore(Effect.forkDaemon(effect)),
|
|
269
|
-
(fiber) => add(self, fiber)
|
|
305
|
+
(fiber) => add(self, fiber, options)
|
|
270
306
|
)
|
|
271
307
|
)
|
|
272
308
|
})
|
|
273
309
|
}
|
|
274
|
-
const effect = arguments[1]
|
|
310
|
+
const effect = arguments[1]
|
|
311
|
+
const options = arguments[2] as { readonly propagateInterruption?: boolean | undefined } | undefined
|
|
275
312
|
return Effect.suspend(() => {
|
|
276
313
|
if (self.state._tag === "Closed") {
|
|
277
314
|
return Effect.interrupt
|
|
@@ -279,7 +316,7 @@ export const run: {
|
|
|
279
316
|
return Effect.uninterruptibleMask((restore) =>
|
|
280
317
|
Effect.tap(
|
|
281
318
|
restore(Effect.forkDaemon(effect)),
|
|
282
|
-
(fiber) => add(self, fiber)
|
|
319
|
+
(fiber) => add(self, fiber, options)
|
|
283
320
|
)
|
|
284
321
|
)
|
|
285
322
|
}) as any
|
|
@@ -316,7 +353,9 @@ export const runtime: <A, E>(
|
|
|
316
353
|
) => <R = never>() => Effect.Effect<
|
|
317
354
|
<XE extends E, XA extends A>(
|
|
318
355
|
effect: Effect.Effect<XA, XE, R>,
|
|
319
|
-
options?:
|
|
356
|
+
options?:
|
|
357
|
+
| Runtime.RunForkOptions & { readonly propagateInterruption?: boolean | undefined }
|
|
358
|
+
| undefined
|
|
320
359
|
) => Fiber.RuntimeFiber<XA, XE>,
|
|
321
360
|
never,
|
|
322
361
|
R
|
|
@@ -327,7 +366,9 @@ export const runtime: <A, E>(
|
|
|
327
366
|
const runFork = Runtime.runFork(runtime)
|
|
328
367
|
return <XE extends E, XA extends A>(
|
|
329
368
|
effect: Effect.Effect<XA, XE, R>,
|
|
330
|
-
options?:
|
|
369
|
+
options?:
|
|
370
|
+
| Runtime.RunForkOptions & { readonly propagateInterruption?: boolean | undefined }
|
|
371
|
+
| undefined
|
|
331
372
|
) => {
|
|
332
373
|
const fiber = runFork(effect, options)
|
|
333
374
|
unsafeAdd(self, fiber)
|
package/src/Micro.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { StructuralPrototype } from "./internal/effectable.js"
|
|
|
19
19
|
import { SingleShotGen } from "./internal/singleShotGen.js"
|
|
20
20
|
import * as Option from "./Option.js"
|
|
21
21
|
import { type Pipeable, pipeArguments } from "./Pipeable.js"
|
|
22
|
-
import { isIterable, isTagged, type Predicate, type Refinement } from "./Predicate.js"
|
|
22
|
+
import { hasProperty, isIterable, isTagged, type Predicate, type Refinement } from "./Predicate.js"
|
|
23
23
|
import type { ReadonlyRecord } from "./Record.js"
|
|
24
24
|
import type { Sink, SinkTypeId } from "./Sink.js"
|
|
25
25
|
import type { Stream, StreamTypeId } from "./Stream.js"
|
|
@@ -171,6 +171,13 @@ export type MicroCauseTypeId = typeof MicroCauseTypeId
|
|
|
171
171
|
*/
|
|
172
172
|
export type MicroCause<E> = MicroCause.Die | MicroCause.Fail<E> | MicroCause.Interrupt
|
|
173
173
|
|
|
174
|
+
/**
|
|
175
|
+
* @since 3.6.6
|
|
176
|
+
* @experimental
|
|
177
|
+
* @category guards
|
|
178
|
+
*/
|
|
179
|
+
export const isMicroCause = (self: unknown): self is MicroCause<unknown> => hasProperty(self, MicroCauseTypeId)
|
|
180
|
+
|
|
174
181
|
/**
|
|
175
182
|
* @since 3.4.6
|
|
176
183
|
* @experimental
|
package/src/Stream.ts
CHANGED
|
@@ -3472,6 +3472,42 @@ export const provideSomeLayer: {
|
|
|
3472
3472
|
): Stream<A, E | E2, RIn | Exclude<R, ROut>>
|
|
3473
3473
|
} = internal.provideSomeLayer
|
|
3474
3474
|
|
|
3475
|
+
/**
|
|
3476
|
+
* Returns a stream that mirrors the first upstream to emit an item.
|
|
3477
|
+
* As soon as one of the upstream emits a first value, the other is interrupted.
|
|
3478
|
+
* The resulting stream will forward all items from the "winning" source stream.
|
|
3479
|
+
* Any upstream failures will cause the returned stream to fail.
|
|
3480
|
+
*
|
|
3481
|
+
* @example
|
|
3482
|
+
* import { Stream, Schedule, Console, Effect } from "effect"
|
|
3483
|
+
*
|
|
3484
|
+
* const stream = Stream.fromSchedule(Schedule.spaced('2 millis')).pipe(
|
|
3485
|
+
* Stream.race(Stream.fromSchedule(Schedule.spaced('1 millis'))),
|
|
3486
|
+
* Stream.take(6),
|
|
3487
|
+
* Stream.tap(Console.log)
|
|
3488
|
+
* )
|
|
3489
|
+
*
|
|
3490
|
+
* Effect.runPromise(Stream.runDrain(stream))
|
|
3491
|
+
* // Output each millisecond from the first stream, the rest streams are interrupted
|
|
3492
|
+
* // 0
|
|
3493
|
+
* // 1
|
|
3494
|
+
* // 2
|
|
3495
|
+
* // 3
|
|
3496
|
+
* // 4
|
|
3497
|
+
* // 5
|
|
3498
|
+
* @since 3.7.0
|
|
3499
|
+
* @category racing
|
|
3500
|
+
*/
|
|
3501
|
+
export const race: {
|
|
3502
|
+
<AR, ER, RR>(
|
|
3503
|
+
right: Stream<AR, ER, RR>
|
|
3504
|
+
): <AL, EL, RL>(left: Stream<AL, EL, RL>) => Stream<AL | AR, EL | ER, RL | RR>
|
|
3505
|
+
<AL, EL, RL, AR, ER, RR>(
|
|
3506
|
+
left: Stream<AL, EL, RL>,
|
|
3507
|
+
right: Stream<AR, ER, RR>
|
|
3508
|
+
): Stream<AL | AR, EL | ER, RL | RR>
|
|
3509
|
+
} = internal.race
|
|
3510
|
+
|
|
3475
3511
|
/**
|
|
3476
3512
|
* Returns a stream that mirrors the first upstream to emit an item.
|
|
3477
3513
|
* As soon as one of the upstream emits a first value, all the others are interrupted.
|
package/src/internal/config.ts
CHANGED
|
@@ -447,6 +447,16 @@ export const string = (name?: string): Config.Config<string> => {
|
|
|
447
447
|
return name === undefined ? config : nested(config, name)
|
|
448
448
|
}
|
|
449
449
|
|
|
450
|
+
/** @internal */
|
|
451
|
+
export const nonEmptyString = (name?: string): Config.Config<string> => {
|
|
452
|
+
const config = primitive(
|
|
453
|
+
"a non-empty text property",
|
|
454
|
+
Either.liftPredicate((text) => text.length > 0, () => configError.MissingData([], "Expected a non-empty string"))
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
return name === undefined ? config : nested(config, name)
|
|
458
|
+
}
|
|
459
|
+
|
|
450
460
|
/** @internal */
|
|
451
461
|
export const all = <const Arg extends Iterable<Config.Config<any>> | Record<string, Config.Config<any>>>(
|
|
452
462
|
arg: Arg
|