@fncts/io 0.0.24 → 0.0.26
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/FiberRef/api.d.ts +0 -63
- package/FiberRef/operations.d.ts +64 -0
- package/FiberRef.d.ts +1 -0
- package/FiberRefs/api.d.ts +6 -1
- package/FiberRefs.d.ts +0 -1
- package/IO/api/daemonChildren.d.ts +6 -0
- package/IO/api/disconnect.d.ts +17 -0
- package/IO/api/fork.d.ts +4 -0
- package/IO/api/forkDaemon.d.ts +10 -0
- package/IO/api/interrupt.d.ts +1 -20
- package/IO/api/race.d.ts +7 -1
- package/IO/api/raceWith.d.ts +17 -0
- package/IO/api/transplant.d.ts +13 -0
- package/IO/api/whenFiberRef.d.ts +10 -0
- package/IO/api/whenRef.d.ts +10 -0
- package/IO/api/zipConcurrent.d.ts +5 -4
- package/IO/api.d.ts +12 -1
- package/IO.d.ts +7 -1
- package/RefSubject/Atomic.d.ts +1 -1
- package/_cjs/Cached/api.cjs +1 -1
- package/_cjs/Channel/api/mergeAllWith.cjs +1 -1
- package/_cjs/Channel/api/mergeWith.cjs +17 -16
- package/_cjs/Channel/api/mergeWith.cjs.map +1 -1
- package/_cjs/Channel/api.cjs +1 -3
- package/_cjs/Channel/api.cjs.map +1 -1
- package/_cjs/Fiber/FiberRuntime.cjs +16 -17
- package/_cjs/Fiber/FiberRuntime.cjs.map +1 -1
- package/_cjs/FiberRef/api/locallyScoped.cjs +1 -1
- package/_cjs/FiberRef/api/locallyScopedWith.cjs +1 -1
- package/_cjs/FiberRef/api.cjs +0 -124
- package/_cjs/FiberRef/api.cjs.map +1 -1
- package/_cjs/FiberRef/constructors.cjs +1 -1
- package/_cjs/FiberRef/operations.cjs +130 -0
- package/_cjs/FiberRef/operations.cjs.map +1 -0
- package/_cjs/FiberRef.cjs +11 -0
- package/_cjs/FiberRef.cjs.map +1 -1
- package/_cjs/FiberRefs/api.cjs +90 -0
- package/_cjs/FiberRefs/api.cjs.map +1 -1
- package/_cjs/FiberRefs.cjs +0 -11
- package/_cjs/FiberRefs.cjs.map +1 -1
- package/_cjs/Future/api.cjs +1 -3
- package/_cjs/Future/api.cjs.map +1 -1
- package/_cjs/IO/api/asyncIO.cjs +1 -3
- package/_cjs/IO/api/asyncIO.cjs.map +1 -1
- package/_cjs/IO/api/bracketExit.cjs +1 -3
- package/_cjs/IO/api/bracketExit.cjs.map +1 -1
- package/_cjs/IO/api/clockWith.cjs +1 -1
- package/_cjs/IO/api/concurrency.cjs +1 -1
- package/_cjs/IO/api/consoleWith.cjs +1 -1
- package/_cjs/IO/api/daemonChildren.cjs +19 -0
- package/_cjs/IO/api/daemonChildren.cjs.map +1 -0
- package/_cjs/IO/api/disconnect.cjs +31 -0
- package/_cjs/IO/api/disconnect.cjs.map +1 -0
- package/_cjs/IO/api/environment.cjs +1 -1
- package/_cjs/IO/api/foreachConcurrent.cjs +19 -20
- package/_cjs/IO/api/foreachConcurrent.cjs.map +1 -1
- package/_cjs/IO/api/fork.cjs +8 -3
- package/_cjs/IO/api/fork.cjs.map +1 -1
- package/_cjs/IO/api/forkDaemon.cjs +21 -0
- package/_cjs/IO/api/forkDaemon.cjs.map +1 -0
- package/_cjs/IO/api/forkIn.cjs +2 -4
- package/_cjs/IO/api/forkIn.cjs.map +1 -1
- package/_cjs/IO/api/forkScoped.cjs +2 -4
- package/_cjs/IO/api/forkScoped.cjs.map +1 -1
- package/_cjs/IO/api/fulfill.cjs +1 -3
- package/_cjs/IO/api/fulfill.cjs.map +1 -1
- package/_cjs/IO/api/interrupt.cjs +8 -59
- package/_cjs/IO/api/interrupt.cjs.map +1 -1
- package/_cjs/IO/api/race.cjs +24 -12
- package/_cjs/IO/api/race.cjs.map +1 -1
- package/_cjs/IO/api/{core-scope.cjs → raceWith.cjs} +15 -56
- package/_cjs/IO/api/raceWith.cjs.map +1 -0
- package/_cjs/IO/api/randomWith.cjs +1 -1
- package/_cjs/IO/api/supervised.cjs +1 -1
- package/_cjs/IO/api/transplant.cjs +31 -0
- package/_cjs/IO/api/transplant.cjs.map +1 -0
- package/_cjs/IO/api/whenFiberRef.cjs +20 -0
- package/_cjs/IO/api/whenFiberRef.cjs.map +1 -0
- package/_cjs/IO/api/whenRef.cjs +21 -0
- package/_cjs/IO/api/whenRef.cjs.map +1 -0
- package/_cjs/IO/api/zipConcurrent.cjs +25 -19
- package/_cjs/IO/api/zipConcurrent.cjs.map +1 -1
- package/_cjs/IO/api.cjs +21 -5
- package/_cjs/IO/api.cjs.map +1 -1
- package/_cjs/IO.cjs +70 -4
- package/_cjs/IO.cjs.map +1 -1
- package/_cjs/Layer/MemoMap.cjs +1 -3
- package/_cjs/Layer/MemoMap.cjs.map +1 -1
- package/_cjs/RefSubject/Atomic.cjs +2 -2
- package/_cjs/RefSubject/Atomic.cjs.map +1 -1
- package/_cjs/Reloadable/constructors.cjs +1 -1
- package/_cjs/Reloadable/definition.cjs +1 -1
- package/_cjs/STM/api/atomically.cjs +2 -4
- package/_cjs/STM/api/atomically.cjs.map +1 -1
- package/_cjs/ScopedRef/api.cjs +2 -6
- package/_cjs/ScopedRef/api.cjs.map +1 -1
- package/_cjs/State/api.cjs +1 -1
- package/_cjs/Stream/api.cjs +137 -135
- package/_cjs/Stream/api.cjs.map +1 -1
- package/_cjs/TReentrantLock/api.cjs +2 -6
- package/_cjs/TReentrantLock/api.cjs.map +1 -1
- package/_cjs/TSemaphore/api.cjs +1 -3
- package/_cjs/TSemaphore/api.cjs.map +1 -1
- package/_mjs/Cached/api.mjs +1 -1
- package/_mjs/Channel/api/mergeAllWith.mjs +1 -1
- package/_mjs/Channel/api/mergeWith.mjs +17 -16
- package/_mjs/Channel/api/mergeWith.mjs.map +1 -1
- package/_mjs/Channel/api.mjs +1 -3
- package/_mjs/Channel/api.mjs.map +1 -1
- package/_mjs/Fiber/FiberRuntime.mjs +16 -17
- package/_mjs/Fiber/FiberRuntime.mjs.map +1 -1
- package/_mjs/FiberRef/api/locallyScoped.mjs +1 -1
- package/_mjs/FiberRef/api/locallyScopedWith.mjs +1 -1
- package/_mjs/FiberRef/api.mjs +0 -107
- package/_mjs/FiberRef/api.mjs.map +1 -1
- package/_mjs/FiberRef/constructors.mjs +1 -1
- package/_mjs/FiberRef/operations.mjs +109 -0
- package/_mjs/FiberRef/operations.mjs.map +1 -0
- package/_mjs/FiberRef.mjs +1 -0
- package/_mjs/FiberRef.mjs.map +1 -1
- package/_mjs/FiberRefs/api.mjs +89 -0
- package/_mjs/FiberRefs/api.mjs.map +1 -1
- package/_mjs/FiberRefs.mjs +0 -1
- package/_mjs/FiberRefs.mjs.map +1 -1
- package/_mjs/Future/api.mjs +1 -3
- package/_mjs/Future/api.mjs.map +1 -1
- package/_mjs/IO/api/asyncIO.mjs +1 -3
- package/_mjs/IO/api/asyncIO.mjs.map +1 -1
- package/_mjs/IO/api/bracketExit.mjs +1 -3
- package/_mjs/IO/api/bracketExit.mjs.map +1 -1
- package/_mjs/IO/api/clockWith.mjs +1 -1
- package/_mjs/IO/api/concurrency.mjs +1 -1
- package/_mjs/IO/api/consoleWith.mjs +1 -1
- package/_mjs/IO/api/daemonChildren.mjs +11 -0
- package/_mjs/IO/api/daemonChildren.mjs.map +1 -0
- package/_mjs/IO/api/disconnect.mjs +23 -0
- package/_mjs/IO/api/disconnect.mjs.map +1 -0
- package/_mjs/IO/api/environment.mjs +1 -1
- package/_mjs/IO/api/foreachConcurrent.mjs +19 -20
- package/_mjs/IO/api/foreachConcurrent.mjs.map +1 -1
- package/_mjs/IO/api/fork.mjs +6 -2
- package/_mjs/IO/api/fork.mjs.map +1 -1
- package/_mjs/IO/api/forkDaemon.mjs +13 -0
- package/_mjs/IO/api/forkDaemon.mjs.map +1 -0
- package/_mjs/IO/api/forkIn.mjs +2 -4
- package/_mjs/IO/api/forkIn.mjs.map +1 -1
- package/_mjs/IO/api/forkScoped.mjs +2 -4
- package/_mjs/IO/api/forkScoped.mjs.map +1 -1
- package/_mjs/IO/api/fulfill.mjs +1 -3
- package/_mjs/IO/api/fulfill.mjs.map +1 -1
- package/_mjs/IO/api/interrupt.mjs +6 -55
- package/_mjs/IO/api/interrupt.mjs.map +1 -1
- package/_mjs/IO/api/race.mjs +22 -12
- package/_mjs/IO/api/race.mjs.map +1 -1
- package/_mjs/IO/api/raceWith.mjs +59 -0
- package/_mjs/IO/api/raceWith.mjs.map +1 -0
- package/_mjs/IO/api/randomWith.mjs +1 -1
- package/_mjs/IO/api/supervised.mjs +1 -1
- package/_mjs/IO/api/transplant.mjs +23 -0
- package/_mjs/IO/api/transplant.mjs.map +1 -0
- package/_mjs/IO/api/whenFiberRef.mjs +12 -0
- package/_mjs/IO/api/whenFiberRef.mjs.map +1 -0
- package/_mjs/IO/api/whenRef.mjs +13 -0
- package/_mjs/IO/api/whenRef.mjs.map +1 -0
- package/_mjs/IO/api/zipConcurrent.mjs +23 -17
- package/_mjs/IO/api/zipConcurrent.mjs.map +1 -1
- package/_mjs/IO/api.mjs +16 -3
- package/_mjs/IO/api.mjs.map +1 -1
- package/_mjs/IO.mjs +7 -1
- package/_mjs/IO.mjs.map +1 -1
- package/_mjs/Layer/MemoMap.mjs +1 -3
- package/_mjs/Layer/MemoMap.mjs.map +1 -1
- package/_mjs/RefSubject/Atomic.mjs +1 -1
- package/_mjs/RefSubject/Atomic.mjs.map +1 -1
- package/_mjs/Reloadable/constructors.mjs +1 -1
- package/_mjs/Reloadable/definition.mjs +1 -1
- package/_mjs/STM/api/atomically.mjs +2 -4
- package/_mjs/STM/api/atomically.mjs.map +1 -1
- package/_mjs/ScopedRef/api.mjs +2 -6
- package/_mjs/ScopedRef/api.mjs.map +1 -1
- package/_mjs/State/api.mjs +1 -1
- package/_mjs/Stream/api.mjs +137 -135
- package/_mjs/Stream/api.mjs.map +1 -1
- package/_mjs/TReentrantLock/api.mjs +2 -6
- package/_mjs/TReentrantLock/api.mjs.map +1 -1
- package/_mjs/TSemaphore/api.mjs +1 -3
- package/_mjs/TSemaphore/api.mjs.map +1 -1
- package/_src/Channel/api.ts +1 -1
- package/_src/FiberRef/api.ts +0 -114
- package/_src/FiberRef/operations.ts +115 -0
- package/_src/FiberRef.ts +1 -0
- package/_src/FiberRefs/api.ts +72 -0
- package/_src/FiberRefs.ts +0 -1
- package/_src/Future/api.ts +1 -1
- package/_src/IO/api/asyncIO.ts +1 -1
- package/_src/IO/api/bracketExit.ts +1 -1
- package/_src/IO/api/daemonChildren.ts +6 -0
- package/_src/IO/api/disconnect.ts +25 -0
- package/_src/IO/api/foreachConcurrent.ts +1 -1
- package/_src/IO/api/fork.ts +3 -0
- package/_src/IO/api/forkDaemon.ts +12 -0
- package/_src/IO/api/forkIn.ts +1 -1
- package/_src/IO/api/forkScoped.ts +1 -3
- package/_src/IO/api/fulfill.ts +1 -1
- package/_src/IO/api/interrupt.ts +5 -56
- package/_src/IO/api/race.ts +18 -8
- package/_src/IO/api/{core-scope.ts → raceWith.ts} +2 -44
- package/_src/IO/api/transplant.ts +19 -0
- package/_src/IO/api/whenFiberRef.ts +9 -0
- package/_src/IO/api/whenRef.ts +9 -0
- package/_src/IO/api/zipConcurrent.ts +41 -43
- package/_src/IO/api.ts +18 -2
- package/_src/IO.ts +7 -1
- package/_src/Layer/MemoMap.ts +1 -1
- package/_src/RefSubject/Atomic.ts +1 -1
- package/_src/STM/api/atomically.ts +1 -1
- package/_src/ScopedRef/api.ts +2 -2
- package/_src/TReentrantLock/api.ts +2 -2
- package/_src/TSemaphore/api.ts +1 -1
- package/package.json +2 -2
- package/FiberRefs/join.d.ts +0 -9
- package/IO/api/core-scope.d.ts +0 -43
- package/_cjs/FiberRefs/join.cjs +0 -104
- package/_cjs/FiberRefs/join.cjs.map +0 -1
- package/_cjs/IO/api/core-scope.cjs.map +0 -1
- package/_mjs/FiberRefs/join.mjs +0 -96
- package/_mjs/FiberRefs/join.mjs.map +0 -1
- package/_mjs/IO/api/core-scope.mjs +0 -97
- package/_mjs/IO/api/core-scope.mjs.map +0 -1
- package/_src/FiberRefs/join.ts +0 -71
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { concrete } from "@fncts/io/FiberRef/definition";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @tsplus pipeable fncts.io.FiberRef modify
|
|
5
|
+
*/
|
|
6
|
+
export function modify<A, B>(f: (a: A) => readonly [B, A], __tsplusTrace?: string) {
|
|
7
|
+
return (self: FiberRef<A>): UIO<B> => {
|
|
8
|
+
concrete(self);
|
|
9
|
+
return IO.withFiberRuntime((fiber) =>
|
|
10
|
+
IO(() => {
|
|
11
|
+
const [result, newValue] = f(fiber.getFiberRef(self));
|
|
12
|
+
fiber.setFiberRef(self, newValue);
|
|
13
|
+
return result;
|
|
14
|
+
}),
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @tsplus pipeable fncts.io.FiberRef update
|
|
21
|
+
*/
|
|
22
|
+
export function update<A>(f: (a: A) => A, __tsplusTrace?: string) {
|
|
23
|
+
return (fiberRef: FiberRef<A>): UIO<void> => {
|
|
24
|
+
return fiberRef.modify((a) => [undefined, f(a)]);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @tsplus pipeable fncts.io.FiberRef set
|
|
30
|
+
*/
|
|
31
|
+
export function set<A>(a: A, __tsplusTrace?: string) {
|
|
32
|
+
return (fiberRef: FiberRef<A>): UIO<void> => {
|
|
33
|
+
return fiberRef.modify(() => [undefined, a]);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @tsplus getter fncts.io.FiberRef get
|
|
39
|
+
*/
|
|
40
|
+
export function get<A>(fiberRef: FiberRef<A>, __tsplusTrace?: string): UIO<A> {
|
|
41
|
+
return fiberRef.modify((a) => [a, a]);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @tsplus pipeable fncts.io.FiberRef getAndSet
|
|
46
|
+
*/
|
|
47
|
+
export function getAndSet<A>(a: A, __tsplusTrace?: string) {
|
|
48
|
+
return (fiberRef: FiberRef<A>): UIO<A> => {
|
|
49
|
+
return fiberRef.modify((v) => [v, a]);
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @tsplus pipeable fncts.io.FiberRef getAndUpdate
|
|
55
|
+
*/
|
|
56
|
+
export function getAndUpdate<A>(f: (a: A) => A, __tsplusTrace?: string) {
|
|
57
|
+
return (fiberRef: FiberRef<A>): UIO<A> => {
|
|
58
|
+
return fiberRef.modify((a) => [a, f(a)]);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @tsplus pipeable fncts.io.FiberRef getAndUpdateJust
|
|
64
|
+
*/
|
|
65
|
+
export function getAndUpdateJust<A>(f: (a: A) => Maybe<A>, __tsplusTrace?: string) {
|
|
66
|
+
return (fiberRef: FiberRef<A>): UIO<A> => {
|
|
67
|
+
return fiberRef.modify((a) => [a, f(a).getOrElse(a)]);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Returns an `IO` that runs with `value` bound to the current fiber.
|
|
73
|
+
*
|
|
74
|
+
* Guarantees that fiber data is properly restored via `bracket`.
|
|
75
|
+
*
|
|
76
|
+
* @tsplus fluent fncts.io.FiberRef locally
|
|
77
|
+
*/
|
|
78
|
+
export function locally<A>(fiberRef: FiberRef<A>, value: A, __tsplusTrace?: string) {
|
|
79
|
+
return <R1, E1, B>(use: IO<R1, E1, B>): IO<R1, E1, B> =>
|
|
80
|
+
IO.withFiberRuntime((fiberState) => {
|
|
81
|
+
const oldValue = fiberState.getFiberRef(fiberRef);
|
|
82
|
+
fiberState.setFiberRef(fiberRef, value);
|
|
83
|
+
return use.ensuring(IO.succeed(fiberState.setFiberRef(fiberRef, oldValue)));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Returns an `IO` that runs with `f` applied to the current fiber.
|
|
89
|
+
*
|
|
90
|
+
* Guarantees that fiber data is properly restored via `bracket`.
|
|
91
|
+
*
|
|
92
|
+
* @tsplus fluent fncts.io.FiberRef locallyWith
|
|
93
|
+
*/
|
|
94
|
+
export function locallyWith<A>(self: FiberRef<A>, f: (a: A) => A, __tsplusTrace?: string) {
|
|
95
|
+
return <R1, E1, B>(use: IO<R1, E1, B>): IO<R1, E1, B> => self.getWith((a) => self.locally(f(a))(use));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @tsplus pipeable fncts.io.FiberRef getWith
|
|
100
|
+
*/
|
|
101
|
+
export function getWith<A, R, E, B>(f: (a: A) => IO<R, E, B>, __tsplusTrace?: string) {
|
|
102
|
+
return (fiberRef: FiberRef<A>): IO<R, E, B> => {
|
|
103
|
+
return fiberRef.get.flatMap(f);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @tsplus getter fncts.io.FiberRef remove
|
|
109
|
+
*/
|
|
110
|
+
export function remove<A>(self: FiberRef<A>, __tsplusTrace?: string): UIO<void> {
|
|
111
|
+
return IO.withFiberRuntime((fiberState) => {
|
|
112
|
+
fiberState.deleteFiberRef(self);
|
|
113
|
+
return IO.unit;
|
|
114
|
+
});
|
|
115
|
+
}
|
package/_src/FiberRef.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
export * from "./FiberRef/api.js";
|
|
3
3
|
export * from "./FiberRef/constructors.js";
|
|
4
4
|
export * from "./FiberRef/definition.js";
|
|
5
|
+
export * from "./FiberRef/operations.js";
|
|
5
6
|
export * from "./FiberRef/unsafe.js";
|
|
6
7
|
// codegen:end
|
|
7
8
|
// codegen:start { preset: barrel, include: ./FiberRef/api/*.ts }
|
package/_src/FiberRefs/api.ts
CHANGED
|
@@ -84,3 +84,75 @@ export function remove(self: FiberRefs, fiberRef: FiberRef<any>): FiberRefs {
|
|
|
84
84
|
export function unFiberRefs(self: FiberRefs): HashMap<FiberRef<any>, Cons<readonly [FiberId.Runtime, unknown]>> {
|
|
85
85
|
return FiberRefs.reverseGet(self);
|
|
86
86
|
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @tsplus pipeable fncts.io.FiberRefs join
|
|
90
|
+
*/
|
|
91
|
+
export function join(fiberId: FiberId.Runtime, that: FiberRefs) {
|
|
92
|
+
return (self: FiberRefs): FiberRefs => {
|
|
93
|
+
const parentFiberRefs = FiberRefs.reverseGet(self);
|
|
94
|
+
const childFiberRefs = FiberRefs.reverseGet(that);
|
|
95
|
+
const fiberRefLocals = childFiberRefs.foldLeftWithIndex(parentFiberRefs, (ref, parentFiberRefs, childStack) => {
|
|
96
|
+
const childValue = childStack.head[1];
|
|
97
|
+
if (childStack.head[0] == fiberId) {
|
|
98
|
+
return parentFiberRefs;
|
|
99
|
+
}
|
|
100
|
+
return parentFiberRefs.get(ref).match(
|
|
101
|
+
() => {
|
|
102
|
+
if (Equatable.strictEquals(childValue, ref.initial)) return parentFiberRefs;
|
|
103
|
+
return parentFiberRefs.set(ref, Cons([fiberId, childValue] as const));
|
|
104
|
+
},
|
|
105
|
+
(parentStack) => {
|
|
106
|
+
const [ancestor, wasModified] = findAncestor(ref, parentStack, childStack);
|
|
107
|
+
if (!wasModified) return parentFiberRefs;
|
|
108
|
+
const patch = ref.diff(ancestor, childValue);
|
|
109
|
+
const oldValue = parentStack.head[1];
|
|
110
|
+
const newValue = ref.join(oldValue, ref.patch(patch)(oldValue));
|
|
111
|
+
if (oldValue === newValue) return parentFiberRefs;
|
|
112
|
+
let newStack: Cons<readonly [FiberId.Runtime, unknown]>;
|
|
113
|
+
if (parentStack.isEmpty()) {
|
|
114
|
+
newStack = Cons([fiberId, newValue] as const);
|
|
115
|
+
} else {
|
|
116
|
+
const [parentFiberId] = parentStack.head;
|
|
117
|
+
if (parentFiberId == fiberId) {
|
|
118
|
+
newStack = Cons([parentFiberId, newValue], parentStack.tail);
|
|
119
|
+
} else {
|
|
120
|
+
newStack = Cons([fiberId, newValue], parentStack);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return parentFiberRefs.set(ref, newStack);
|
|
124
|
+
},
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
return FiberRefs.get(fiberRefLocals);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function compareFiberId(left: FiberId.Runtime, right: FiberId.Runtime): number {
|
|
132
|
+
const compare = Number.Ord.compare(right.startTime)(left.startTime);
|
|
133
|
+
return compare === 0 ? Number.Ord.compare(right.id)(left.id) : compare;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @tsplus tailRec
|
|
138
|
+
*/
|
|
139
|
+
function findAncestor(
|
|
140
|
+
ref: FiberRef<any>,
|
|
141
|
+
parentStack: List<readonly [FiberId.Runtime, any]>,
|
|
142
|
+
childStack: List<readonly [FiberId.Runtime, any]>,
|
|
143
|
+
childModified = false,
|
|
144
|
+
): readonly [any, boolean] {
|
|
145
|
+
if (parentStack.isNonEmpty() && childStack.isNonEmpty()) {
|
|
146
|
+
const [parentFiberId] = parentStack.head;
|
|
147
|
+
const [childFiberId, childValue] = childStack.head;
|
|
148
|
+
const compare = compareFiberId(parentFiberId, childFiberId);
|
|
149
|
+
if (compare < 0) {
|
|
150
|
+
return findAncestor(ref, parentStack, childStack.tail, true);
|
|
151
|
+
} else if (compare > 0) {
|
|
152
|
+
return findAncestor(ref, parentStack.tail, childStack, childModified);
|
|
153
|
+
} else {
|
|
154
|
+
return [childValue, childModified];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return [ref.initial, true];
|
|
158
|
+
}
|
package/_src/FiberRefs.ts
CHANGED
package/_src/Future/api.ts
CHANGED
|
@@ -49,7 +49,7 @@ export function failCause<E>(cause: Cause<E>, __tsplusTrace?: string) {
|
|
|
49
49
|
*/
|
|
50
50
|
export function fulfill<R, E, A>(io: IO<R, E, A>, __tsplusTrace?: string) {
|
|
51
51
|
return (future: Future<E, A>): IO<R, never, boolean> => {
|
|
52
|
-
return IO.uninterruptibleMask((
|
|
52
|
+
return IO.uninterruptibleMask((restore) => restore(io).result.flatMap((exit) => future.done(exit)));
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
|
package/_src/IO/api/asyncIO.ts
CHANGED
|
@@ -9,7 +9,7 @@ export function asyncIO<R, E, A>(
|
|
|
9
9
|
const f = Δ(Future.make<E, A>());
|
|
10
10
|
const r = Δ(IO.runtime<R>());
|
|
11
11
|
const a = Δ(
|
|
12
|
-
IO.uninterruptibleMask((
|
|
12
|
+
IO.uninterruptibleMask((restore) => {
|
|
13
13
|
const io = register((k) => r.unsafeRunAsync(k.fulfill(f)));
|
|
14
14
|
return restore(io.catchAllCause((cause) => f.failCause(cause))).fork > restore(f.await);
|
|
15
15
|
}),
|
|
@@ -14,7 +14,7 @@ export function bracketExit<R, E, A, E1, R1, A1, R2, E2>(
|
|
|
14
14
|
release: (a: A, e: Exit<E1, A1>) => IO<R2, E2, any>,
|
|
15
15
|
__tsplusTrace?: string,
|
|
16
16
|
): IO<R | R1 | R2, E | E1 | E2, A1> {
|
|
17
|
-
return IO.uninterruptibleMask((
|
|
17
|
+
return IO.uninterruptibleMask((restore) =>
|
|
18
18
|
acquire().flatMap((a) =>
|
|
19
19
|
IO.defer(restore(use(a))).result.flatMap((exit) =>
|
|
20
20
|
IO.defer(release(a, exit)).matchCauseIO(
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns an IO whose interruption will be disconnected from the
|
|
3
|
+
* fiber's own interruption, being performed in the background without
|
|
4
|
+
* slowing down the fiber's interruption.
|
|
5
|
+
*
|
|
6
|
+
* This method is useful to create "fast interrupting" effects. For
|
|
7
|
+
* example, if you call this on a bracketed effect, then even if the
|
|
8
|
+
* effect is "stuck" in acquire or release, its interruption will return
|
|
9
|
+
* immediately, while the acquire / release are performed in the
|
|
10
|
+
* background.
|
|
11
|
+
*
|
|
12
|
+
* See timeout and race for other applications.
|
|
13
|
+
*
|
|
14
|
+
* @tsplus getter fncts.io.IO disconnect
|
|
15
|
+
*/
|
|
16
|
+
export function disconnect<R, E, A>(self: IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
|
|
17
|
+
return IO.uninterruptibleMask((restore) =>
|
|
18
|
+
IO.fiberId.flatMap((fiberId) =>
|
|
19
|
+
Do((Δ) => {
|
|
20
|
+
const fiber = Δ(restore(self).forkDaemon);
|
|
21
|
+
return Δ(restore(fiber.join).onInterrupt(fiber.interruptAsFork(fiberId)));
|
|
22
|
+
}),
|
|
23
|
+
),
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -62,7 +62,7 @@ function foreachConcurrentUnboundedDiscard<R, E, A>(
|
|
|
62
62
|
if (size === 0) {
|
|
63
63
|
return IO.unit;
|
|
64
64
|
}
|
|
65
|
-
return IO.uninterruptibleMask((
|
|
65
|
+
return IO.uninterruptibleMask((restore) => {
|
|
66
66
|
const future = Future.unsafeMake<void, void>(FiberId.none);
|
|
67
67
|
const ref = new AtomicNumber(0);
|
|
68
68
|
return IO.transplant((graft) =>
|
package/_src/IO/api/fork.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FiberRuntime } from "@fncts/io/Fiber/FiberRuntime";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Forks the effect into a new fiber attached to the global scope. Because the
|
|
5
|
+
* new fiber is attached to the global scope, when the fiber executing the
|
|
6
|
+
* returned effect terminates, the forked fiber will continue running.
|
|
7
|
+
*
|
|
8
|
+
* @tsplus getter fncts.io.IO forkDaemon
|
|
9
|
+
*/
|
|
10
|
+
export function forkDaemon<R, E, A>(ma: IO<R, E, A>, __tsplusTrace?: string): URIO<R, FiberRuntime<E, A>> {
|
|
11
|
+
return ma.fork.daemonChildren;
|
|
12
|
+
}
|
package/_src/IO/api/forkIn.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export function forkIn(scope: Scope, __tsplusTrace?: string) {
|
|
8
8
|
return <R, E, A>(self: IO<R, E, A>): URIO<R, Fiber.Runtime<E, A>> => {
|
|
9
|
-
return IO.uninterruptibleMask((
|
|
9
|
+
return IO.uninterruptibleMask((restore) =>
|
|
10
10
|
restore(self).forkDaemon.tap((fiber) => scope.addFinalizer(fiber.interrupt)),
|
|
11
11
|
);
|
|
12
12
|
};
|
|
@@ -5,7 +5,5 @@ export function forkScoped<R, E, A>(
|
|
|
5
5
|
self: IO<R, E, A>,
|
|
6
6
|
__tsplusTrace?: string,
|
|
7
7
|
): IO<R | Scope, never, Fiber.Runtime<E, A>> {
|
|
8
|
-
return IO.uninterruptibleMask((
|
|
9
|
-
restore(self).forkDaemon.tap((fiber) => IO.addFinalizer(fiber.interrupt)),
|
|
10
|
-
);
|
|
8
|
+
return IO.uninterruptibleMask((restore) => restore(self).forkDaemon.tap((fiber) => IO.addFinalizer(fiber.interrupt)));
|
|
11
9
|
}
|
package/_src/IO/api/fulfill.ts
CHANGED
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export function fulfill<E, A>(p: Future<E, A>, __tsplusTrace?: string) {
|
|
9
9
|
return <R>(effect: IO<R, E, A>): IO<R, never, boolean> => {
|
|
10
|
-
return IO.uninterruptibleMask((
|
|
10
|
+
return IO.uninterruptibleMask((restore) => restore(effect).result.flatMap((exit) => p.done(exit)));
|
|
11
11
|
};
|
|
12
12
|
}
|
package/_src/IO/api/interrupt.ts
CHANGED
|
@@ -2,20 +2,11 @@ import { Dynamic, Interruptible, Uninterruptible } from "@fncts/io/IO/definition
|
|
|
2
2
|
import { RuntimeFlag } from "@fncts/io/RuntimeFlag";
|
|
3
3
|
import { RuntimeFlags } from "@fncts/io/RuntimeFlags";
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
readonly restore: <R, E, A>(io: IO<R, E, A>, __tsplusTrace?: string) => IO<R, E, A>;
|
|
7
|
-
readonly force: <R, E, A>(io: IO<R, E, A>, __tsplusTrace?: string) => IO<R, E, A>;
|
|
8
|
-
}
|
|
5
|
+
export type InterruptibilityRestorer = <R, E, A>(io: IO<R, E, A>, __tsplusTrace?: string) => IO<R, E, A>;
|
|
9
6
|
|
|
10
|
-
const RestoreInterruptible: InterruptibilityRestorer =
|
|
11
|
-
restore: (io, __tsplusTrace) => io.interruptible,
|
|
12
|
-
force: (io, __tsplusTrace) => io.interruptible,
|
|
13
|
-
};
|
|
7
|
+
const RestoreInterruptible: InterruptibilityRestorer = (io, __tsplusTrace) => io.interruptible;
|
|
14
8
|
|
|
15
|
-
const RestoreUninterruptible: InterruptibilityRestorer =
|
|
16
|
-
restore: (io, __tsplusTrace) => io.uninterruptible,
|
|
17
|
-
force: (io, __tsplusTrace) => io.uninterruptible.disconnect.interruptible,
|
|
18
|
-
};
|
|
9
|
+
const RestoreUninterruptible: InterruptibilityRestorer = (io, __tsplusTrace) => io.uninterruptible;
|
|
19
10
|
|
|
20
11
|
/**
|
|
21
12
|
* Returns an effect that is interrupted as if by the specified fiber.
|
|
@@ -34,22 +25,6 @@ export function interruptAs(fiberId: FiberId, __tsplusTrace?: string): FIO<never
|
|
|
34
25
|
*/
|
|
35
26
|
export const interrupt: IO<never, never, never> = IO.fiberId.flatMap(IO.interruptAs);
|
|
36
27
|
|
|
37
|
-
// /**
|
|
38
|
-
// * Switches the interrupt status for this effect. If `true` is used, then the
|
|
39
|
-
// * effect becomes interruptible (the default), while if `false` is used, then
|
|
40
|
-
// * the effect becomes uninterruptible. These changes are compositional, so
|
|
41
|
-
// * they only affect regions of the effect.
|
|
42
|
-
// *
|
|
43
|
-
// * @tsplus fluent fncts.io.IO setInterruptStatus
|
|
44
|
-
// */
|
|
45
|
-
// export function setInterruptStatus_<R, E, A>(
|
|
46
|
-
// self: IO<R, E, A>,
|
|
47
|
-
// flag: InterruptStatus,
|
|
48
|
-
// __tsplusTrace?: string,
|
|
49
|
-
// ): IO<R, E, A> {
|
|
50
|
-
// return new SetInterrupt(self, flag, __tsplusTrace);
|
|
51
|
-
// }
|
|
52
|
-
|
|
53
28
|
/**
|
|
54
29
|
* Returns a new effect that performs the same operations as this effect, but
|
|
55
30
|
* interruptibly, even if composed inside of an uninterruptible region.
|
|
@@ -101,7 +76,7 @@ export function uninterruptibleMask<R, E, A>(f: (restore: InterruptibilityRestor
|
|
|
101
76
|
*/
|
|
102
77
|
export function ensuring<R1>(finalizer: IO<R1, never, any>, __tsplusTrace?: string) {
|
|
103
78
|
return <R, E, A>(self: IO<R, E, A>): IO<R | R1, E, A> => {
|
|
104
|
-
return IO.uninterruptibleMask((
|
|
79
|
+
return IO.uninterruptibleMask((restore) =>
|
|
105
80
|
restore(self).matchCauseIO(
|
|
106
81
|
(cause1) =>
|
|
107
82
|
finalizer.matchCauseIO(
|
|
@@ -172,7 +147,7 @@ export function onInterruptWith<R1, E1>(
|
|
|
172
147
|
*/
|
|
173
148
|
export function onExit<E, A, R1, E1>(cleanup: (exit: Exit<E, A>) => IO<R1, E1, any>, __tsplusTrace?: string) {
|
|
174
149
|
return <R>(self: IO<R, E, A>): IO<R | R1, E | E1, A> => {
|
|
175
|
-
return IO.uninterruptibleMask((
|
|
150
|
+
return IO.uninterruptibleMask((restore) =>
|
|
176
151
|
restore(self).matchCauseIO(
|
|
177
152
|
(failure1) => {
|
|
178
153
|
const result = Exit.failCause(failure1);
|
|
@@ -189,29 +164,3 @@ export function onExit<E, A, R1, E1>(cleanup: (exit: Exit<E, A>) => IO<R1, E1, a
|
|
|
189
164
|
);
|
|
190
165
|
};
|
|
191
166
|
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Returns an IO whose interruption will be disconnected from the
|
|
195
|
-
* fiber's own interruption, being performed in the background without
|
|
196
|
-
* slowing down the fiber's interruption.
|
|
197
|
-
*
|
|
198
|
-
* This method is useful to create "fast interrupting" effects. For
|
|
199
|
-
* example, if you call this on a bracketed effect, then even if the
|
|
200
|
-
* effect is "stuck" in acquire or release, its interruption will return
|
|
201
|
-
* immediately, while the acquire / release are performed in the
|
|
202
|
-
* background.
|
|
203
|
-
*
|
|
204
|
-
* See timeout and race for other applications.
|
|
205
|
-
*
|
|
206
|
-
* @tsplus getter fncts.io.IO disconnect
|
|
207
|
-
*/
|
|
208
|
-
export function disconnect<R, E, A>(self: IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
|
|
209
|
-
return uninterruptibleMask(({ restore }) =>
|
|
210
|
-
IO.fiberId.flatMap((fiberId) =>
|
|
211
|
-
Do((Δ) => {
|
|
212
|
-
const fiber = Δ(restore(self).forkDaemon);
|
|
213
|
-
return Δ(restore(fiber.join).onInterrupt(fiber.interruptAsFork(fiberId)));
|
|
214
|
-
}),
|
|
215
|
-
),
|
|
216
|
-
);
|
|
217
|
-
}
|
package/_src/IO/api/race.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
function maybeDisconnect<R, E, A>(io: IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
|
|
2
|
-
return IO.uninterruptibleMask((restore) => restore.force(io));
|
|
3
|
-
}
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
2
|
* Returns an IO that races this effect with the specified effect,
|
|
7
3
|
* returning the first successful `A` from the faster side. If one effect
|
|
@@ -14,10 +10,24 @@ function maybeDisconnect<R, E, A>(io: IO<R, E, A>, __tsplusTrace?: string): IO<R
|
|
|
14
10
|
* @tsplus pipeable fncts.io.IO race
|
|
15
11
|
*/
|
|
16
12
|
export function race<R1, E1, A1>(that: IO<R1, E1, A1>) {
|
|
17
|
-
return <R, E, A>(
|
|
18
|
-
return IO.
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
return <R, E, A>(self: IO<R, E, A>): IO<R | R1, E | E1, A | A1> => {
|
|
14
|
+
return IO.checkInterruptible((status) => disconnect(self, status).raceAwait(disconnect(that, status)));
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function disconnect<R, E, A>(io: IO<R, E, A>, interruptStatus: InterruptStatus, __tsplusTrace?: string): IO<R, E, A> {
|
|
19
|
+
if (interruptStatus.isInterruptible) return io.disconnect;
|
|
20
|
+
else return io.uninterruptible.disconnect.interruptible;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @tsplus pipeable fncts.io.IO raceAwait
|
|
25
|
+
*/
|
|
26
|
+
export function raceAwait<R1, E1, A1>(that: IO<R1, E1, A1>) {
|
|
27
|
+
return <R, E, A>(self: IO<R, E, A>): IO<R | R1, E | E1, A | A1> => {
|
|
28
|
+
return IO.fiberIdWith((id) =>
|
|
29
|
+
self.raceWith(
|
|
30
|
+
that,
|
|
21
31
|
(exit, right) =>
|
|
22
32
|
exit.match(
|
|
23
33
|
(cause) => right.join.mapErrorCause((c) => Cause.both(cause, c)),
|
|
@@ -2,17 +2,6 @@ import type { FiberRuntime } from "@fncts/io/Fiber/FiberRuntime";
|
|
|
2
2
|
|
|
3
3
|
import { ExitTag } from "@fncts/base/data/Exit";
|
|
4
4
|
import { AtomicBoolean } from "@fncts/base/internal/AtomicBoolean";
|
|
5
|
-
import { unsafeMakeChildFiber } from "@fncts/io/IO/api/fork";
|
|
6
|
-
|
|
7
|
-
import { FiberScope } from "../../FiberScope.js";
|
|
8
|
-
import { IO } from "../definition.js";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @tsplus getter fncts.io.IO daemonChildren
|
|
12
|
-
*/
|
|
13
|
-
export function daemonChildren<R, E, A>(self: IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
|
|
14
|
-
return FiberRef.forkScopeOverride.locally(Just(FiberScope.global))(self);
|
|
15
|
-
}
|
|
16
5
|
|
|
17
6
|
/**
|
|
18
7
|
* @tsplus pipeable fncts.io.IO raceFibersWith
|
|
@@ -40,8 +29,8 @@ export function raceFibersWith<R, E, A, R1, E1, B, R2, E2, C, R3, E3, D>(
|
|
|
40
29
|
}
|
|
41
30
|
|
|
42
31
|
const raceIndicator = new AtomicBoolean(true);
|
|
43
|
-
const leftFiber = unsafeMakeChildFiber(left, parentState, parentRuntimeFlags, null, __tsplusTrace);
|
|
44
|
-
const rightFiber = unsafeMakeChildFiber(right0, parentState, parentRuntimeFlags, null, __tsplusTrace);
|
|
32
|
+
const leftFiber = IO.unsafeMakeChildFiber(left, parentState, parentRuntimeFlags, null, __tsplusTrace);
|
|
33
|
+
const rightFiber = IO.unsafeMakeChildFiber(right0, parentState, parentRuntimeFlags, null, __tsplusTrace);
|
|
45
34
|
leftFiber.setFiberRef(FiberRef.forkScopeOverride, Just(parentState.scope));
|
|
46
35
|
rightFiber.setFiberRef(FiberRef.forkScopeOverride, Just(parentState.scope));
|
|
47
36
|
|
|
@@ -91,34 +80,3 @@ export function raceWith<R, E, A, R1, E1, A1, R2, E2, A2, R3, E3, A3>(
|
|
|
91
80
|
);
|
|
92
81
|
};
|
|
93
82
|
}
|
|
94
|
-
|
|
95
|
-
export type Grafter = <R, E, A>(effect: IO<R, E, A>) => IO<R, E, A>;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Transplants specified effects so that when those effects fork other
|
|
99
|
-
* effects, the forked effects will be governed by the scope of the
|
|
100
|
-
* fiber that executes this effect.
|
|
101
|
-
*
|
|
102
|
-
* This can be used to "graft" deep grandchildren onto a higher-level
|
|
103
|
-
* scope, effectively extending their lifespans into the parent scope.
|
|
104
|
-
*
|
|
105
|
-
* @tsplus static fncts.io.IOOps transplant
|
|
106
|
-
*/
|
|
107
|
-
export function transplant<R, E, A>(f: (_: Grafter) => IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
|
|
108
|
-
return IO.withFiberRuntime((fiberState) => {
|
|
109
|
-
const scopeOverride = fiberState.getFiberRef(FiberRef.forkScopeOverride);
|
|
110
|
-
const scope = scopeOverride.getOrElse(fiberState.scope);
|
|
111
|
-
return f(FiberRef.forkScopeOverride.locally(Just(scope)));
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Forks the effect into a new fiber attached to the global scope. Because the
|
|
117
|
-
* new fiber is attached to the global scope, when the fiber executing the
|
|
118
|
-
* returned effect terminates, the forked fiber will continue running.
|
|
119
|
-
*
|
|
120
|
-
* @tsplus getter fncts.io.IO forkDaemon
|
|
121
|
-
*/
|
|
122
|
-
export function forkDaemon<R, E, A>(ma: IO<R, E, A>, __tsplusTrace?: string): URIO<R, FiberRuntime<E, A>> {
|
|
123
|
-
return ma.fork.daemonChildren;
|
|
124
|
-
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type Grafter = <R, E, A>(effect: IO<R, E, A>) => IO<R, E, A>;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Transplants specified effects so that when those effects fork other
|
|
5
|
+
* effects, the forked effects will be governed by the scope of the
|
|
6
|
+
* fiber that executes this effect.
|
|
7
|
+
*
|
|
8
|
+
* This can be used to "graft" deep grandchildren onto a higher-level
|
|
9
|
+
* scope, effectively extending their lifespans into the parent scope.
|
|
10
|
+
*
|
|
11
|
+
* @tsplus static fncts.io.IOOps transplant
|
|
12
|
+
*/
|
|
13
|
+
export function transplant<R, E, A>(f: (_: Grafter) => IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
|
|
14
|
+
return IO.withFiberRuntime((fiberState) => {
|
|
15
|
+
const scopeOverride = fiberState.getFiberRef(FiberRef.forkScopeOverride);
|
|
16
|
+
const scope = scopeOverride.getOrElse(fiberState.scope);
|
|
17
|
+
return f(FiberRef.forkScopeOverride.locally(Just(scope)));
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @tsplus pipeable fncts.io.IO whenFiberRef
|
|
3
|
+
* @tsplus static fncts.io.IOOps whenFiberRef
|
|
4
|
+
*/
|
|
5
|
+
export function whenFiberRef<S>(ref: FiberRef<S>, f: Predicate<S>, __tsplusTrace?: string) {
|
|
6
|
+
return <R, E, A>(self: IO<R, E, A>): IO<R, E, Maybe<A>> => {
|
|
7
|
+
return self.whenIO(ref.get.map(f));
|
|
8
|
+
};
|
|
9
|
+
}
|