@fncts/io 0.0.24 → 0.0.26
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|