@fncts/io 0.0.23 → 0.0.25

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. package/FiberRef/api.d.ts +0 -63
  2. package/FiberRef/operations.d.ts +64 -0
  3. package/FiberRef.d.ts +1 -0
  4. package/FiberRefs/api.d.ts +6 -1
  5. package/FiberRefs.d.ts +0 -1
  6. package/IO/api/daemonChildren.d.ts +6 -0
  7. package/IO/api/descriptor.d.ts +12 -0
  8. package/IO/api/disconnect.d.ts +17 -0
  9. package/IO/api/fork.d.ts +4 -0
  10. package/IO/api/forkDaemon.d.ts +10 -0
  11. package/IO/api/interrupt.d.ts +1 -20
  12. package/IO/api/race.d.ts +7 -1
  13. package/IO/api/raceWith.d.ts +17 -0
  14. package/IO/api/transplant.d.ts +13 -0
  15. package/IO/api.d.ts +1 -12
  16. package/IO.d.ts +6 -1
  17. package/RefSubject/Atomic.d.ts +1 -1
  18. package/_cjs/Cached/api.cjs +1 -1
  19. package/_cjs/Channel/api/mergeAllWith.cjs +1 -1
  20. package/_cjs/Channel/api/mergeWith.cjs +17 -16
  21. package/_cjs/Channel/api/mergeWith.cjs.map +1 -1
  22. package/_cjs/Channel/api.cjs +1 -3
  23. package/_cjs/Channel/api.cjs.map +1 -1
  24. package/_cjs/Fiber/FiberRuntime.cjs +16 -17
  25. package/_cjs/Fiber/FiberRuntime.cjs.map +1 -1
  26. package/_cjs/FiberRef/api/locallyScoped.cjs +1 -1
  27. package/_cjs/FiberRef/api/locallyScopedWith.cjs +1 -1
  28. package/_cjs/FiberRef/api.cjs +0 -124
  29. package/_cjs/FiberRef/api.cjs.map +1 -1
  30. package/_cjs/FiberRef/constructors.cjs +1 -1
  31. package/_cjs/FiberRef/operations.cjs +130 -0
  32. package/_cjs/FiberRef/operations.cjs.map +1 -0
  33. package/_cjs/FiberRef.cjs +11 -0
  34. package/_cjs/FiberRef.cjs.map +1 -1
  35. package/_cjs/FiberRefs/api.cjs +90 -0
  36. package/_cjs/FiberRefs/api.cjs.map +1 -1
  37. package/_cjs/FiberRefs.cjs +0 -11
  38. package/_cjs/FiberRefs.cjs.map +1 -1
  39. package/_cjs/Future/api.cjs +1 -3
  40. package/_cjs/Future/api.cjs.map +1 -1
  41. package/_cjs/IO/api/asyncIO.cjs +1 -3
  42. package/_cjs/IO/api/asyncIO.cjs.map +1 -1
  43. package/_cjs/IO/api/bracketExit.cjs +1 -3
  44. package/_cjs/IO/api/bracketExit.cjs.map +1 -1
  45. package/_cjs/IO/api/clockWith.cjs +1 -1
  46. package/_cjs/IO/api/concurrency.cjs +1 -1
  47. package/_cjs/IO/api/consoleWith.cjs +1 -1
  48. package/_cjs/IO/api/daemonChildren.cjs +19 -0
  49. package/_cjs/IO/api/daemonChildren.cjs.map +1 -0
  50. package/_cjs/IO/api/descriptor.cjs +30 -0
  51. package/_cjs/IO/api/descriptor.cjs.map +1 -0
  52. package/_cjs/IO/api/disconnect.cjs +31 -0
  53. package/_cjs/IO/api/disconnect.cjs.map +1 -0
  54. package/_cjs/IO/api/environment.cjs +1 -1
  55. package/_cjs/IO/api/foreachConcurrent.cjs +19 -20
  56. package/_cjs/IO/api/foreachConcurrent.cjs.map +1 -1
  57. package/_cjs/IO/api/fork.cjs +8 -3
  58. package/_cjs/IO/api/fork.cjs.map +1 -1
  59. package/_cjs/IO/api/forkDaemon.cjs +21 -0
  60. package/_cjs/IO/api/forkDaemon.cjs.map +1 -0
  61. package/_cjs/IO/api/forkIn.cjs +2 -4
  62. package/_cjs/IO/api/forkIn.cjs.map +1 -1
  63. package/_cjs/IO/api/forkScoped.cjs +2 -4
  64. package/_cjs/IO/api/forkScoped.cjs.map +1 -1
  65. package/_cjs/IO/api/fulfill.cjs +1 -3
  66. package/_cjs/IO/api/fulfill.cjs.map +1 -1
  67. package/_cjs/IO/api/interrupt.cjs +8 -59
  68. package/_cjs/IO/api/interrupt.cjs.map +1 -1
  69. package/_cjs/IO/api/race.cjs +24 -12
  70. package/_cjs/IO/api/race.cjs.map +1 -1
  71. package/_cjs/IO/api/{core-scope.cjs → raceWith.cjs} +15 -56
  72. package/_cjs/IO/api/raceWith.cjs.map +1 -0
  73. package/_cjs/IO/api/randomWith.cjs +1 -1
  74. package/_cjs/IO/api/supervised.cjs +1 -1
  75. package/_cjs/IO/api/transplant.cjs +31 -0
  76. package/_cjs/IO/api/transplant.cjs.map +1 -0
  77. package/_cjs/IO/api/zipConcurrent.cjs +5 -6
  78. package/_cjs/IO/api/zipConcurrent.cjs.map +1 -1
  79. package/_cjs/IO/api.cjs +52 -70
  80. package/_cjs/IO/api.cjs.map +1 -1
  81. package/_cjs/IO.cjs +59 -4
  82. package/_cjs/IO.cjs.map +1 -1
  83. package/_cjs/Layer/MemoMap.cjs +1 -3
  84. package/_cjs/Layer/MemoMap.cjs.map +1 -1
  85. package/_cjs/RefSubject/Atomic.cjs +2 -2
  86. package/_cjs/RefSubject/Atomic.cjs.map +1 -1
  87. package/_cjs/Reloadable/constructors.cjs +1 -1
  88. package/_cjs/Reloadable/definition.cjs +1 -1
  89. package/_cjs/STM/api/atomically.cjs +2 -4
  90. package/_cjs/STM/api/atomically.cjs.map +1 -1
  91. package/_cjs/ScopedRef/api.cjs +2 -6
  92. package/_cjs/ScopedRef/api.cjs.map +1 -1
  93. package/_cjs/State/api.cjs +1 -1
  94. package/_cjs/Stream/api.cjs +137 -135
  95. package/_cjs/Stream/api.cjs.map +1 -1
  96. package/_cjs/TReentrantLock/api.cjs +2 -6
  97. package/_cjs/TReentrantLock/api.cjs.map +1 -1
  98. package/_cjs/TSemaphore/api.cjs +1 -3
  99. package/_cjs/TSemaphore/api.cjs.map +1 -1
  100. package/_mjs/Cached/api.mjs +1 -1
  101. package/_mjs/Channel/api/mergeAllWith.mjs +1 -1
  102. package/_mjs/Channel/api/mergeWith.mjs +17 -16
  103. package/_mjs/Channel/api/mergeWith.mjs.map +1 -1
  104. package/_mjs/Channel/api.mjs +1 -3
  105. package/_mjs/Channel/api.mjs.map +1 -1
  106. package/_mjs/Fiber/FiberRuntime.mjs +16 -17
  107. package/_mjs/Fiber/FiberRuntime.mjs.map +1 -1
  108. package/_mjs/FiberRef/api/locallyScoped.mjs +1 -1
  109. package/_mjs/FiberRef/api/locallyScopedWith.mjs +1 -1
  110. package/_mjs/FiberRef/api.mjs +0 -107
  111. package/_mjs/FiberRef/api.mjs.map +1 -1
  112. package/_mjs/FiberRef/constructors.mjs +1 -1
  113. package/_mjs/FiberRef/operations.mjs +109 -0
  114. package/_mjs/FiberRef/operations.mjs.map +1 -0
  115. package/_mjs/FiberRef.mjs +1 -0
  116. package/_mjs/FiberRef.mjs.map +1 -1
  117. package/_mjs/FiberRefs/api.mjs +89 -0
  118. package/_mjs/FiberRefs/api.mjs.map +1 -1
  119. package/_mjs/FiberRefs.mjs +0 -1
  120. package/_mjs/FiberRefs.mjs.map +1 -1
  121. package/_mjs/Future/api.mjs +1 -3
  122. package/_mjs/Future/api.mjs.map +1 -1
  123. package/_mjs/IO/api/asyncIO.mjs +1 -3
  124. package/_mjs/IO/api/asyncIO.mjs.map +1 -1
  125. package/_mjs/IO/api/bracketExit.mjs +1 -3
  126. package/_mjs/IO/api/bracketExit.mjs.map +1 -1
  127. package/_mjs/IO/api/clockWith.mjs +1 -1
  128. package/_mjs/IO/api/concurrency.mjs +1 -1
  129. package/_mjs/IO/api/consoleWith.mjs +1 -1
  130. package/_mjs/IO/api/daemonChildren.mjs +11 -0
  131. package/_mjs/IO/api/daemonChildren.mjs.map +1 -0
  132. package/_mjs/IO/api/descriptor.mjs +20 -0
  133. package/_mjs/IO/api/descriptor.mjs.map +1 -0
  134. package/_mjs/IO/api/disconnect.mjs +23 -0
  135. package/_mjs/IO/api/disconnect.mjs.map +1 -0
  136. package/_mjs/IO/api/environment.mjs +1 -1
  137. package/_mjs/IO/api/foreachConcurrent.mjs +19 -20
  138. package/_mjs/IO/api/foreachConcurrent.mjs.map +1 -1
  139. package/_mjs/IO/api/fork.mjs +6 -2
  140. package/_mjs/IO/api/fork.mjs.map +1 -1
  141. package/_mjs/IO/api/forkDaemon.mjs +13 -0
  142. package/_mjs/IO/api/forkDaemon.mjs.map +1 -0
  143. package/_mjs/IO/api/forkIn.mjs +2 -4
  144. package/_mjs/IO/api/forkIn.mjs.map +1 -1
  145. package/_mjs/IO/api/forkScoped.mjs +2 -4
  146. package/_mjs/IO/api/forkScoped.mjs.map +1 -1
  147. package/_mjs/IO/api/fulfill.mjs +1 -3
  148. package/_mjs/IO/api/fulfill.mjs.map +1 -1
  149. package/_mjs/IO/api/interrupt.mjs +6 -55
  150. package/_mjs/IO/api/interrupt.mjs.map +1 -1
  151. package/_mjs/IO/api/race.mjs +22 -12
  152. package/_mjs/IO/api/race.mjs.map +1 -1
  153. package/_mjs/IO/api/raceWith.mjs +59 -0
  154. package/_mjs/IO/api/raceWith.mjs.map +1 -0
  155. package/_mjs/IO/api/randomWith.mjs +1 -1
  156. package/_mjs/IO/api/supervised.mjs +1 -1
  157. package/_mjs/IO/api/transplant.mjs +23 -0
  158. package/_mjs/IO/api/transplant.mjs.map +1 -0
  159. package/_mjs/IO/api/zipConcurrent.mjs +5 -6
  160. package/_mjs/IO/api/zipConcurrent.mjs.map +1 -1
  161. package/_mjs/IO/api.mjs +51 -67
  162. package/_mjs/IO/api.mjs.map +1 -1
  163. package/_mjs/IO.mjs +6 -1
  164. package/_mjs/IO.mjs.map +1 -1
  165. package/_mjs/Layer/MemoMap.mjs +1 -3
  166. package/_mjs/Layer/MemoMap.mjs.map +1 -1
  167. package/_mjs/RefSubject/Atomic.mjs +1 -1
  168. package/_mjs/RefSubject/Atomic.mjs.map +1 -1
  169. package/_mjs/Reloadable/constructors.mjs +1 -1
  170. package/_mjs/Reloadable/definition.mjs +1 -1
  171. package/_mjs/STM/api/atomically.mjs +2 -4
  172. package/_mjs/STM/api/atomically.mjs.map +1 -1
  173. package/_mjs/ScopedRef/api.mjs +2 -6
  174. package/_mjs/ScopedRef/api.mjs.map +1 -1
  175. package/_mjs/State/api.mjs +1 -1
  176. package/_mjs/Stream/api.mjs +137 -135
  177. package/_mjs/Stream/api.mjs.map +1 -1
  178. package/_mjs/TReentrantLock/api.mjs +2 -6
  179. package/_mjs/TReentrantLock/api.mjs.map +1 -1
  180. package/_mjs/TSemaphore/api.mjs +1 -3
  181. package/_mjs/TSemaphore/api.mjs.map +1 -1
  182. package/_src/Channel/api.ts +1 -1
  183. package/_src/FiberRef/api.ts +0 -114
  184. package/_src/FiberRef/operations.ts +115 -0
  185. package/_src/FiberRef.ts +1 -0
  186. package/_src/FiberRefs/api.ts +72 -0
  187. package/_src/FiberRefs.ts +0 -1
  188. package/_src/Future/api.ts +1 -1
  189. package/_src/IO/api/asyncIO.ts +1 -1
  190. package/_src/IO/api/bracketExit.ts +1 -1
  191. package/_src/IO/api/daemonChildren.ts +6 -0
  192. package/_src/IO/api/descriptor.ts +14 -0
  193. package/_src/IO/api/disconnect.ts +25 -0
  194. package/_src/IO/api/foreachConcurrent.ts +1 -1
  195. package/_src/IO/api/fork.ts +3 -0
  196. package/_src/IO/api/forkDaemon.ts +12 -0
  197. package/_src/IO/api/forkIn.ts +1 -1
  198. package/_src/IO/api/forkScoped.ts +1 -3
  199. package/_src/IO/api/fulfill.ts +1 -1
  200. package/_src/IO/api/interrupt.ts +5 -56
  201. package/_src/IO/api/race.ts +18 -8
  202. package/_src/IO/api/{core-scope.ts → raceWith.ts} +2 -44
  203. package/_src/IO/api/transplant.ts +19 -0
  204. package/_src/IO/api/zipConcurrent.ts +1 -1
  205. package/_src/IO/api.ts +0 -15
  206. package/_src/IO.ts +6 -1
  207. package/_src/Layer/MemoMap.ts +1 -1
  208. package/_src/RefSubject/Atomic.ts +1 -1
  209. package/_src/STM/api/atomically.ts +1 -1
  210. package/_src/ScopedRef/api.ts +2 -2
  211. package/_src/TReentrantLock/api.ts +2 -2
  212. package/_src/TSemaphore/api.ts +1 -1
  213. package/package.json +1 -1
  214. package/FiberRefs/join.d.ts +0 -9
  215. package/IO/api/core-scope.d.ts +0 -43
  216. package/_cjs/FiberRefs/join.cjs +0 -104
  217. package/_cjs/FiberRefs/join.cjs.map +0 -1
  218. package/_cjs/IO/api/core-scope.cjs.map +0 -1
  219. package/_mjs/FiberRefs/join.mjs +0 -96
  220. package/_mjs/FiberRefs/join.mjs.map +0 -1
  221. package/_mjs/IO/api/core-scope.mjs +0 -97
  222. package/_mjs/IO/api/core-scope.mjs.map +0 -1
  223. 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 }
@@ -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
@@ -1,5 +1,4 @@
1
1
  // codegen:start { preset: barrel, include: ./FiberRefs/*.ts }
2
2
  export * from "./FiberRefs/api.js";
3
3
  export * from "./FiberRefs/definition.js";
4
- export * from "./FiberRefs/join.js";
5
4
  // codegen:end
@@ -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(({ restore }) => restore(io).result.flatMap((exit) => future.done(exit)));
52
+ return IO.uninterruptibleMask((restore) => restore(io).result.flatMap((exit) => future.done(exit)));
53
53
  };
54
54
  }
55
55
 
@@ -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(({ restore }) => {
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(({ restore }) =>
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,6 @@
1
+ /**
2
+ * @tsplus getter fncts.io.IO daemonChildren
3
+ */
4
+ export function daemonChildren<R, E, A>(self: IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
5
+ return FiberRef.forkScopeOverride.locally(Just(FiberScope.global))(self);
6
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @tsplus static fncts.io.IOOps descriptorWith
3
+ */
4
+ export function descriptorWith<R, E, A>(f: (descriptor: FiberDescriptor) => IO<R, E, A>): IO<R, E, A> {
5
+ return IO.withFiberRuntime((fiber, status) => {
6
+ const descriptor = new FiberDescriptor(fiber.id, status, fiber.getFiberRef(FiberRef.interruptedCause).interruptors);
7
+ return f(descriptor);
8
+ });
9
+ }
10
+
11
+ /**
12
+ * @tsplus static fncts.io.IOOps descriptor
13
+ */
14
+ export const descriptor: UIO<FiberDescriptor> = IO.descriptorWith((descriptor) => IO.succeedNow(descriptor));
@@ -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(({ restore }) => {
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) =>
@@ -55,6 +55,9 @@ export function unsafeFork<R, E, A, E1, B>(
55
55
  return fiber;
56
56
  }
57
57
 
58
+ /**
59
+ * @tsplus static fncts.io.IOOps unsafeMakeChildFiber
60
+ */
58
61
  export function unsafeMakeChildFiber<R, E, A, E1, B>(
59
62
  effect: IO<R, E, A>,
60
63
  parentFiber: FiberRuntime<E1, B>,
@@ -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
+ }
@@ -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(({ restore }) =>
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(({ restore }) =>
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
  }
@@ -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(({ restore }) => restore(effect).result.flatMap((exit) => p.done(exit)));
10
+ return IO.uninterruptibleMask((restore) => restore(effect).result.flatMap((exit) => p.done(exit)));
11
11
  };
12
12
  }
@@ -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 interface InterruptibilityRestorer {
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(({ restore }) =>
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(({ restore }) =>
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
- }
@@ -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>(io: IO<R, E, A>): IO<R | R1, E | E1, A | A1> => {
18
- return IO.fiberId.flatMap((id) =>
19
- maybeDisconnect(io).raceWith(
20
- maybeDisconnect(that),
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
+ }
@@ -16,7 +16,7 @@ export function zipConcurrent<R1, E1, B>(that: IO<R1, E1, B>, __tsplusTrace?: st
16
16
  export function zipWithConcurrent<A, R1, E1, B, C>(that: IO<R1, E1, B>, f: (a: A, b: B) => C, __tsplusTrace?: string) {
17
17
  return <R, E>(self: IO<R, E, A>): IO<R | R1, E | E1, C> => {
18
18
  return IO.fiberId.flatMap((fiberId) =>
19
- IO.uninterruptibleMask(({ restore }) => {
19
+ IO.uninterruptibleMask((restore) => {
20
20
  const future = Future.unsafeMake<void, C>(FiberId.none);
21
21
  const ref = new AtomicReference<Maybe<Either<A, B>>>(Nothing());
22
22
  return IO.transplant((graft) =>
package/_src/IO/api.ts CHANGED
@@ -410,21 +410,6 @@ export function deferTryCatch<R, E, A, E1>(
410
410
  });
411
411
  }
412
412
 
413
- /**
414
- * @tsplus static fncts.io.IOOps descriptorWith
415
- */
416
- export function descriptorWith<R, E, A>(f: (descriptor: FiberDescriptor) => IO<R, E, A>): IO<R, E, A> {
417
- return IO.withFiberRuntime((fiber, status) => {
418
- const descriptor = new FiberDescriptor(fiber.id, status, fiber.getFiberRef(FiberRef.interruptedCause).interruptors);
419
- return f(descriptor);
420
- });
421
- }
422
-
423
- /**
424
- * @tsplus static fncts.io.IOOps descriptor
425
- */
426
- export const descriptor: UIO<FiberDescriptor> = IO.descriptorWith((descriptor) => IO.succeedNow(descriptor));
427
-
428
413
  /**
429
414
  * Folds an `IO` that may fail with `E` or succeed with `A` into one that never fails but succeeds with `Either<E, A>`
430
415
  *
package/_src/IO.ts CHANGED
@@ -19,14 +19,17 @@ export * from "./IO/api/clockWith.js";
19
19
  export * from "./IO/api/concurrency.js";
20
20
  export * from "./IO/api/concurrentFinalizers.js";
21
21
  export * from "./IO/api/consoleWith.js";
22
- export * from "./IO/api/core-scope.js";
22
+ export * from "./IO/api/daemonChildren.js";
23
23
  export * from "./IO/api/delay.js";
24
+ export * from "./IO/api/descriptor.js";
25
+ export * from "./IO/api/disconnect.js";
24
26
  export * from "./IO/api/ensuringChildren.js";
25
27
  export * from "./IO/api/environment.js";
26
28
  export * from "./IO/api/foreachConcurrent.js";
27
29
  export * from "./IO/api/foreachExec.js";
28
30
  export * from "./IO/api/fork.js";
29
31
  export * from "./IO/api/forkAll.js";
32
+ export * from "./IO/api/forkDaemon.js";
30
33
  export * from "./IO/api/forkIn.js";
31
34
  export * from "./IO/api/forkScoped.js";
32
35
  export * from "./IO/api/fulfill.js";
@@ -38,6 +41,7 @@ export * from "./IO/api/provideLayer.js";
38
41
  export * from "./IO/api/provideSomeLayer.js";
39
42
  export * from "./IO/api/race.js";
40
43
  export * from "./IO/api/raceFirst.js";
44
+ export * from "./IO/api/raceWith.js";
41
45
  export * from "./IO/api/randomWith.js";
42
46
  export * from "./IO/api/repeat.js";
43
47
  export * from "./IO/api/retry.js";
@@ -50,6 +54,7 @@ export * from "./IO/api/sleep.js";
50
54
  export * from "./IO/api/stateful.js";
51
55
  export * from "./IO/api/supervised.js";
52
56
  export * from "./IO/api/timeout.js";
57
+ export * from "./IO/api/transplant.js";
53
58
  export * from "./IO/api/withChildren.js";
54
59
  export * from "./IO/api/withEarlyRelease.js";
55
60
  export * from "./IO/api/withFinalizer.js";
@@ -35,7 +35,7 @@ export class MemoMap {
35
35
  const observers = _(Ref.make(0));
36
36
  const future = _(Future.make<E, Environment<A>>());
37
37
  const finalizerRef = _(Ref.make<Finalizer>(Finalizer.noop));
38
- const resource = IO.uninterruptibleMask(({ restore }) =>
38
+ const resource = IO.uninterruptibleMask((restore) =>
39
39
  Do((_) => {
40
40
  const outerScope = scope;
41
41
  const innerScope = _(Scope.make);
@@ -3,7 +3,7 @@ import type { Emitter } from "@fncts/io/Push";
3
3
  import { AtomicReference } from "@fncts/base/internal/AtomicReference";
4
4
  import { Hold, Push } from "@fncts/io/Push";
5
5
  import { Atomic } from "@fncts/io/Ref";
6
- import { RefSubjectInternal } from "@fncts/io/RefSubject";
6
+ import { RefSubjectInternal } from "@fncts/io/RefSubject/definition";
7
7
 
8
8
  export class AtomicRefSubject<E, A> extends RefSubjectInternal<never, E, A, A> {
9
9
  readonly stream = new Hold<never, E, A>(Push.never);