@fncts/io 0.0.49 → 0.0.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/IO/api/foreachExec.d.ts +18 -0
  2. package/Push/Bounds.d.ts +4 -0
  3. package/Push/FlattenStrategy.d.ts +47 -0
  4. package/Push/IndexedBuffer.d.ts +19 -0
  5. package/Push/MergeStrategy.d.ts +19 -0
  6. package/Push/Operator/IOLoopOperator.d.ts +61 -0
  7. package/Push/Operator/IOOperator.d.ts +63 -0
  8. package/Push/Operator/LoopOperator.d.ts +50 -0
  9. package/Push/Operator/SyncOperator.d.ts +41 -0
  10. package/Push/Operator.d.ts +4 -0
  11. package/Push/Producer/IOProducer.d.ts +41 -0
  12. package/Push/Producer/SyncProducer.d.ts +61 -0
  13. package/Push/Producer.d.ts +1 -0
  14. package/Push/Sink.d.ts +65 -0
  15. package/Push/api.d.ts +78 -161
  16. package/Push/definition.d.ts +92 -19
  17. package/Push/internal.d.ts +3 -0
  18. package/Push.d.ts +6 -0
  19. package/Ref/Synchronized/definition.d.ts +32 -9
  20. package/Ref/definition.d.ts +12 -0
  21. package/Scope/api.d.ts +16 -1
  22. package/Sink/definition.d.ts +5 -6
  23. package/Subject/Atomic.d.ts +19 -9
  24. package/Subject/DeferredRef.d.ts +17 -0
  25. package/Subject/Hold.d.ts +19 -0
  26. package/Subject/RefSubject/Atomic.d.ts +41 -0
  27. package/Subject/RefSubject/Derived.d.ts +43 -0
  28. package/Subject/RefSubject/RefSubject.d.ts +27 -0
  29. package/Subject/definition.d.ts +14 -2
  30. package/Subject.d.ts +2 -0
  31. package/SubscriptionRef.d.ts +0 -1
  32. package/_cjs/IO/api/foreachExec.cjs +29 -4
  33. package/_cjs/IO/api/foreachExec.cjs.map +1 -1
  34. package/_cjs/Push/Bounds.cjs +2 -0
  35. package/_cjs/Push/Bounds.cjs.map +1 -0
  36. package/_cjs/Push/FlattenStrategy.cjs +95 -0
  37. package/_cjs/Push/FlattenStrategy.cjs.map +1 -0
  38. package/_cjs/Push/IndexedBuffer.cjs +70 -0
  39. package/_cjs/Push/IndexedBuffer.cjs.map +1 -0
  40. package/_cjs/Push/MergeStrategy.cjs +45 -0
  41. package/_cjs/Push/MergeStrategy.cjs.map +1 -0
  42. package/_cjs/Push/Operator/IOLoopOperator.cjs +225 -0
  43. package/_cjs/Push/Operator/IOLoopOperator.cjs.map +1 -0
  44. package/_cjs/Push/Operator/IOOperator.cjs +104 -0
  45. package/_cjs/Push/Operator/IOOperator.cjs.map +1 -0
  46. package/_cjs/Push/Operator/LoopOperator.cjs +165 -0
  47. package/_cjs/Push/Operator/LoopOperator.cjs.map +1 -0
  48. package/_cjs/Push/Operator/SyncOperator.cjs +78 -0
  49. package/_cjs/Push/Operator/SyncOperator.cjs.map +1 -0
  50. package/_cjs/Push/Operator.cjs +2 -0
  51. package/_cjs/Push/Operator.cjs.map +1 -0
  52. package/_cjs/Push/Producer/IOProducer.cjs +67 -0
  53. package/_cjs/Push/Producer/IOProducer.cjs.map +1 -0
  54. package/_cjs/Push/Producer/SyncProducer.cjs +107 -0
  55. package/_cjs/Push/Producer/SyncProducer.cjs.map +1 -0
  56. package/_cjs/Push/Producer.cjs +2 -0
  57. package/_cjs/Push/Producer.cjs.map +1 -0
  58. package/_cjs/Push/Sink.cjs +219 -0
  59. package/_cjs/Push/Sink.cjs.map +1 -0
  60. package/_cjs/Push/api.cjs +339 -383
  61. package/_cjs/Push/api.cjs.map +1 -1
  62. package/_cjs/Push/definition.cjs +79 -22
  63. package/_cjs/Push/definition.cjs.map +1 -1
  64. package/_cjs/Push/internal.cjs +31 -26
  65. package/_cjs/Push/internal.cjs.map +1 -1
  66. package/_cjs/Push.cjs +66 -0
  67. package/_cjs/Push.cjs.map +1 -1
  68. package/_cjs/Ref/Synchronized/definition.cjs +12 -12
  69. package/_cjs/Ref/Synchronized/definition.cjs.map +1 -1
  70. package/_cjs/Ref/definition.cjs.map +1 -1
  71. package/_cjs/Scope/api.cjs +28 -7
  72. package/_cjs/Scope/api.cjs.map +1 -1
  73. package/_cjs/Sink/definition.cjs +2 -3
  74. package/_cjs/Sink/definition.cjs.map +1 -1
  75. package/_cjs/Stream/definition.cjs.map +1 -1
  76. package/_cjs/Subject/Atomic.cjs +45 -10
  77. package/_cjs/Subject/Atomic.cjs.map +1 -1
  78. package/_cjs/Subject/DeferredRef.cjs +53 -0
  79. package/_cjs/Subject/DeferredRef.cjs.map +1 -0
  80. package/_cjs/Subject/Hold.cjs +41 -0
  81. package/_cjs/Subject/Hold.cjs.map +1 -0
  82. package/_cjs/Subject/RefSubject/Atomic.cjs +130 -0
  83. package/_cjs/Subject/RefSubject/Atomic.cjs.map +1 -0
  84. package/_cjs/Subject/RefSubject/Derived.cjs +98 -0
  85. package/_cjs/Subject/RefSubject/Derived.cjs.map +1 -0
  86. package/_cjs/Subject/RefSubject/RefSubject.cjs +19 -0
  87. package/_cjs/Subject/RefSubject/RefSubject.cjs.map +1 -0
  88. package/_cjs/Subject/definition.cjs +16 -1
  89. package/_cjs/Subject/definition.cjs.map +1 -1
  90. package/_cjs/Subject.cjs +22 -0
  91. package/_cjs/Subject.cjs.map +1 -1
  92. package/_cjs/SubscriptionRef.cjs +0 -1
  93. package/_cjs/SubscriptionRef.cjs.map +1 -1
  94. package/_mjs/IO/api/foreachExec.mjs +27 -4
  95. package/_mjs/IO/api/foreachExec.mjs.map +1 -1
  96. package/_mjs/Push/Bounds.mjs +2 -0
  97. package/_mjs/Push/Bounds.mjs.map +1 -0
  98. package/_mjs/Push/FlattenStrategy.mjs +86 -0
  99. package/_mjs/Push/FlattenStrategy.mjs.map +1 -0
  100. package/_mjs/Push/IndexedBuffer.mjs +61 -0
  101. package/_mjs/Push/IndexedBuffer.mjs.map +1 -0
  102. package/_mjs/Push/MergeStrategy.mjs +34 -0
  103. package/_mjs/Push/MergeStrategy.mjs.map +1 -0
  104. package/_mjs/Push/Operator/IOLoopOperator.mjs +208 -0
  105. package/_mjs/Push/Operator/IOLoopOperator.mjs.map +1 -0
  106. package/_mjs/Push/Operator/IOOperator.mjs +91 -0
  107. package/_mjs/Push/Operator/IOOperator.mjs.map +1 -0
  108. package/_mjs/Push/Operator/LoopOperator.mjs +151 -0
  109. package/_mjs/Push/Operator/LoopOperator.mjs.map +1 -0
  110. package/_mjs/Push/Operator/SyncOperator.mjs +67 -0
  111. package/_mjs/Push/Operator/SyncOperator.mjs.map +1 -0
  112. package/_mjs/Push/Operator.mjs +2 -0
  113. package/_mjs/Push/Operator.mjs.map +1 -0
  114. package/_mjs/Push/Producer/IOProducer.mjs +55 -0
  115. package/_mjs/Push/Producer/IOProducer.mjs.map +1 -0
  116. package/_mjs/Push/Producer/SyncProducer.mjs +90 -0
  117. package/_mjs/Push/Producer/SyncProducer.mjs.map +1 -0
  118. package/_mjs/Push/Producer.mjs +2 -0
  119. package/_mjs/Push/Producer.mjs.map +1 -0
  120. package/_mjs/Push/Sink.mjs +206 -0
  121. package/_mjs/Push/Sink.mjs.map +1 -0
  122. package/_mjs/Push/api.mjs +311 -344
  123. package/_mjs/Push/api.mjs.map +1 -1
  124. package/_mjs/Push/definition.mjs +73 -18
  125. package/_mjs/Push/definition.mjs.map +1 -1
  126. package/_mjs/Push/internal.mjs +30 -26
  127. package/_mjs/Push/internal.mjs.map +1 -1
  128. package/_mjs/Push.mjs +7 -1
  129. package/_mjs/Push.mjs.map +1 -1
  130. package/_mjs/Ref/Synchronized/definition.mjs +12 -12
  131. package/_mjs/Ref/Synchronized/definition.mjs.map +1 -1
  132. package/_mjs/Ref/definition.mjs.map +1 -1
  133. package/_mjs/Scope/api.mjs +22 -4
  134. package/_mjs/Scope/api.mjs.map +1 -1
  135. package/_mjs/Sink/definition.mjs +2 -3
  136. package/_mjs/Sink/definition.mjs.map +1 -1
  137. package/_mjs/Stream/definition.mjs.map +1 -1
  138. package/_mjs/Subject/Atomic.mjs +46 -10
  139. package/_mjs/Subject/Atomic.mjs.map +1 -1
  140. package/_mjs/Subject/DeferredRef.mjs +45 -0
  141. package/_mjs/Subject/DeferredRef.mjs.map +1 -0
  142. package/_mjs/Subject/Hold.mjs +33 -0
  143. package/_mjs/Subject/Hold.mjs.map +1 -0
  144. package/_mjs/Subject/RefSubject/Atomic.mjs +122 -0
  145. package/_mjs/Subject/RefSubject/Atomic.mjs.map +1 -0
  146. package/_mjs/Subject/RefSubject/Derived.mjs +90 -0
  147. package/_mjs/Subject/RefSubject/Derived.mjs.map +1 -0
  148. package/_mjs/Subject/RefSubject/RefSubject.mjs +12 -0
  149. package/_mjs/Subject/RefSubject/RefSubject.mjs.map +1 -0
  150. package/_mjs/Subject/definition.mjs +14 -0
  151. package/_mjs/Subject/definition.mjs.map +1 -1
  152. package/_mjs/Subject.mjs +2 -0
  153. package/_mjs/Subject.mjs.map +1 -1
  154. package/_mjs/SubscriptionRef.mjs +0 -1
  155. package/_mjs/SubscriptionRef.mjs.map +1 -1
  156. package/_src/IO/api/foreachExec.ts +47 -0
  157. package/_src/Push/Bounds.ts +4 -0
  158. package/_src/Push/FlattenStrategy.ts +137 -0
  159. package/_src/Push/IndexedBuffer.ts +79 -0
  160. package/_src/Push/MergeStrategy.ts +59 -0
  161. package/_src/Push/Operator/IOLoopOperator.ts +413 -0
  162. package/_src/Push/Operator/IOOperator.ts +173 -0
  163. package/_src/Push/Operator/LoopOperator.ts +242 -0
  164. package/_src/Push/Operator/SyncOperator.ts +107 -0
  165. package/_src/Push/Operator.ts +7 -0
  166. package/_src/Push/Producer/IOProducer.ts +83 -0
  167. package/_src/Push/Producer/SyncProducer.ts +105 -0
  168. package/_src/Push/Producer.ts +0 -0
  169. package/_src/Push/Sink.ts +302 -0
  170. package/_src/Push/api.ts +387 -513
  171. package/_src/Push/definition.ts +216 -23
  172. package/_src/Push/internal.ts +11 -0
  173. package/_src/Push.ts +7 -1
  174. package/_src/Ref/Synchronized/definition.ts +81 -37
  175. package/_src/Ref/definition.ts +26 -0
  176. package/_src/Scope/api.ts +22 -0
  177. package/_src/Sink/definition.ts +4 -5
  178. package/_src/Stream/definition.ts +0 -1
  179. package/_src/Subject/Atomic.ts +68 -11
  180. package/_src/Subject/DeferredRef.ts +44 -0
  181. package/_src/Subject/Hold.ts +48 -0
  182. package/_src/Subject/RefSubject/Atomic.ts +193 -0
  183. package/_src/Subject/RefSubject/Derived.ts +179 -0
  184. package/_src/Subject/RefSubject/RefSubject.ts +90 -0
  185. package/_src/Subject/definition.ts +21 -3
  186. package/_src/Subject.ts +5 -3
  187. package/_src/SubscriptionRef.ts +1 -1
  188. package/_src/index.ts +49 -50
  189. package/index.d.ts +0 -1
  190. package/package.json +4 -4
  191. package/RefSubject/Atomic.d.ts +0 -34
  192. package/RefSubject/Synchronized/api.d.ts +0 -9
  193. package/RefSubject/Synchronized/definition.d.ts +0 -39
  194. package/RefSubject/api.d.ts +0 -120
  195. package/RefSubject/definition.d.ts +0 -52
  196. package/RefSubject.d.ts +0 -3
  197. package/_cjs/RefSubject/Atomic.cjs +0 -107
  198. package/_cjs/RefSubject/Atomic.cjs.map +0 -1
  199. package/_cjs/RefSubject/Synchronized/api.cjs +0 -22
  200. package/_cjs/RefSubject/Synchronized/api.cjs.map +0 -1
  201. package/_cjs/RefSubject/Synchronized/definition.cjs +0 -55
  202. package/_cjs/RefSubject/Synchronized/definition.cjs.map +0 -1
  203. package/_cjs/RefSubject/api.cjs +0 -251
  204. package/_cjs/RefSubject/api.cjs.map +0 -1
  205. package/_cjs/RefSubject/definition.cjs +0 -26
  206. package/_cjs/RefSubject/definition.cjs.map +0 -1
  207. package/_cjs/RefSubject.cjs +0 -39
  208. package/_cjs/RefSubject.cjs.map +0 -1
  209. package/_mjs/RefSubject/Atomic.mjs +0 -99
  210. package/_mjs/RefSubject/Atomic.mjs.map +0 -1
  211. package/_mjs/RefSubject/Synchronized/api.mjs +0 -15
  212. package/_mjs/RefSubject/Synchronized/api.mjs.map +0 -1
  213. package/_mjs/RefSubject/Synchronized/definition.mjs +0 -47
  214. package/_mjs/RefSubject/Synchronized/definition.mjs.map +0 -1
  215. package/_mjs/RefSubject/api.mjs +0 -229
  216. package/_mjs/RefSubject/api.mjs.map +0 -1
  217. package/_mjs/RefSubject/definition.mjs +0 -19
  218. package/_mjs/RefSubject/definition.mjs.map +0 -1
  219. package/_mjs/RefSubject.mjs +0 -5
  220. package/_mjs/RefSubject.mjs.map +0 -1
  221. package/_src/RefSubject/Atomic.ts +0 -129
  222. package/_src/RefSubject/Synchronized/api.ts +0 -14
  223. package/_src/RefSubject/Synchronized/definition.ts +0 -76
  224. package/_src/RefSubject/api.ts +0 -253
  225. package/_src/RefSubject/definition.ts +0 -70
  226. package/_src/RefSubject.ts +0 -5
@@ -0,0 +1,44 @@
1
+ import type { AtomicReference } from "@fncts/base/internal/AtomicReference";
2
+
3
+ import { External, IO } from "../IO.js";
4
+
5
+ export class FutureRef<E, A> extends External<never, E, A> {
6
+ public version = -1;
7
+ public future!: Future<E, A>;
8
+
9
+ constructor(
10
+ readonly fiberId: FiberId,
11
+ readonly current: AtomicReference<Maybe<Exit<E, A>>>,
12
+ ) {
13
+ super();
14
+ this.reset();
15
+ }
16
+
17
+ toIO: IO<never, E, A> = IO.defer(() => {
18
+ const current = this.current.get;
19
+ if (current.isNothing()) {
20
+ return this.future.await;
21
+ } else {
22
+ return current.value!;
23
+ }
24
+ });
25
+
26
+ done(exit: Exit<E, A>) {
27
+ const current = this.current.get;
28
+ if (current.isJust() && Equatable.strictEquals(current.value, exit)) {
29
+ return false;
30
+ }
31
+ this.future.unsafeDone(exit);
32
+ this.version += 1;
33
+ return true;
34
+ }
35
+
36
+ reset() {
37
+ this.current.set(Nothing());
38
+ this.version = -1;
39
+ if (this.future) {
40
+ this.future.unsafeDone(Exit.interrupt(this.fiberId));
41
+ }
42
+ this.future = Future.unsafeMake(this.fiberId);
43
+ }
44
+ }
@@ -0,0 +1,48 @@
1
+ import type { Scope } from "../Scope.js";
2
+ import type { Subject } from "../Subject.js";
3
+ import type { Cause } from "@fncts/base/data/Cause";
4
+ import type { UnsafeSink } from "@fncts/io/Push/Sink";
5
+
6
+ import { AtomicReference } from "@fncts/base/internal/AtomicReference";
7
+
8
+ import { IO } from "../IO.js";
9
+ import { AtomicSubject } from "./Atomic.js";
10
+
11
+ export interface Hold<E, A> extends Subject<never, E, A> {
12
+ value: AtomicReference<Maybe<Exit<E, A>>>;
13
+ }
14
+
15
+ export class HoldSubject<E, A> extends AtomicSubject<E, A> implements Hold<E, A> {
16
+ readonly value: AtomicReference<Maybe<Exit<E, A>>> = new AtomicReference(Nothing());
17
+
18
+ onSuccess(value: A): IO<never, never, void> {
19
+ return IO.defer(() => {
20
+ this.value.set(Just(Exit.succeed(value)));
21
+ return this.unsafeOnSuccess(value);
22
+ });
23
+ }
24
+
25
+ onFailure(cause: Cause<E>): IO<never, never, void> {
26
+ return IO.defer(() => {
27
+ this.value.set(Just(Exit.failCause(cause)));
28
+ return this.unsafeOnFailure(cause);
29
+ });
30
+ }
31
+
32
+ run<R1>(sink: UnsafeSink<R1, E, A>): IO<Scope | R1, never, void> {
33
+ return this.addSink(
34
+ sink,
35
+ (scope) =>
36
+ this.value.get.match(
37
+ () => IO.unit,
38
+ (exit) =>
39
+ exit.match(
40
+ (cause) => sink.onFailure(cause),
41
+ (value) => sink.onSuccess(value),
42
+ ),
43
+ ) > scope.awaitClose,
44
+ );
45
+ }
46
+
47
+ interrupt: IO<never, never, void> = this.interruptScopes > IO(this.value.set(Nothing()));
48
+ }
@@ -0,0 +1,193 @@
1
+ import type { Runtime } from "@fncts/io/IO/runtime";
2
+ import type { UnsafeSink } from "@fncts/io/Push/Sink";
3
+ import type { Scope } from "@fncts/io/Scope";
4
+
5
+ import { IO } from "@fncts/io/IO";
6
+ import { PSynchronizedInternal } from "@fncts/io/Ref/Synchronized/definition";
7
+
8
+ import { FutureRef } from "../DeferredRef.js";
9
+ import { HoldSubject } from "../Hold.js";
10
+ import { Derived } from "./Derived.js";
11
+ import { PRefSubject } from "./RefSubject.js";
12
+
13
+ export class Atomic<R, E, A> extends PRefSubject<never, never, E, E, E, A, A> {
14
+ constructor(
15
+ readonly fiberId: FiberId,
16
+ readonly initial: IO<R, E, A>,
17
+ readonly runtime: Runtime<R>,
18
+ readonly scope: Scope.Closeable,
19
+ ) {
20
+ super();
21
+ }
22
+
23
+ readonly semaphore = Semaphore.unsafeMake(1);
24
+ private subject = new HoldSubject<E, A>();
25
+ private futureRef = new FutureRef(this.fiberId, this.subject.value);
26
+ private fiber: Fiber<E, A> | null = null;
27
+
28
+ readonly interrupt = IO.fiberIdWith((fiberId) => {
29
+ this.futureRef.reset();
30
+ return this.scope.close(Exit.interrupt(fiberId)) > this.interruptFiber > this.subject.interrupt;
31
+ });
32
+
33
+ readonly subscribers = this.subject.subscribers;
34
+
35
+ run<R1>(sink: UnsafeSink<R1, E, A>): IO<Scope | R1, never, void> {
36
+ return this.subject.run(sink);
37
+ }
38
+
39
+ onFailure(cause: Cause<E>): IO<never, never, void> {
40
+ const exit = Exit.failCause(cause);
41
+ return IO.defer(() => {
42
+ if (this.futureRef.done(exit)) {
43
+ return this.sendEvent(exit);
44
+ } else {
45
+ return IO.unit;
46
+ }
47
+ });
48
+ }
49
+
50
+ onSuccess = this.set;
51
+
52
+ modify<C>(f: (a: A) => readonly [C, A], __tsplusTrace?: string): IO<never, E, C> {
53
+ return this.get.flatMap((a) => {
54
+ const [c, a1] = f(a);
55
+ return this.set(a1).as(c);
56
+ });
57
+ }
58
+
59
+ modifyIO<R1, E1, B>(f: (a: A) => IO<R1, E1, readonly [B, A]>, __tsplusTrace?: string): IO<R1, E1 | E, B> {
60
+ return this.get.flatMap(f).flatMap(([b, a]) => this.set(a).as(b));
61
+ }
62
+
63
+ match<EC, ED, C, D>(
64
+ setError: (_: E) => EC,
65
+ getError: (_: E) => ED,
66
+ set: (_: C) => Either<EC, A>,
67
+ get: (_: A) => Either<ED, D>,
68
+ __tsplusTrace?: string,
69
+ ): PSynchronizedInternal<never, never, EC, ED, C, D> {
70
+ return this.matchIO(setError, getError, set, get);
71
+ }
72
+
73
+ matchAll<EC, ED, C, D>(
74
+ setError: (_: E) => EC,
75
+ getError: (_: E) => ED,
76
+ setGetError: (_: E) => EC,
77
+ set: (_: C) => (_: A) => Either<EC, A>,
78
+ get: (_: A) => Either<ED, D>,
79
+ __tsplusTrace?: string,
80
+ ): PSynchronizedInternal<never, never, EC, ED, C, D> {
81
+ return this.matchAllIO(setError, getError, setGetError, set, get);
82
+ }
83
+
84
+ matchIO<RC, RD, EC, ED, C, D>(
85
+ setError: (_: E) => EC,
86
+ getError: (_: E) => ED,
87
+ set: (_: C) => IO<RC, EC, A>,
88
+ get: (_: A) => IO<RD, ED, D>,
89
+ __tsplusTrace?: string,
90
+ ): PSynchronizedInternal<RC, RD, EC, ED, C, D> {
91
+ return new PSynchronizedInternal(
92
+ this.semaphore,
93
+ this.get.matchIO((e) => IO.failNow(getError(e)), get),
94
+ (c) => set(c).flatMap((a) => this.set(a).mapError(setError)),
95
+ );
96
+ }
97
+
98
+ matchAllIO<RC, RD, EC, ED, C, D>(
99
+ setError: (_: E) => EC,
100
+ getError: (_: E) => ED,
101
+ setGetError: (_: E) => EC,
102
+ set: (_: C) => (_: A) => IO<RC, EC, A>,
103
+ get: (_: A) => IO<RD, ED, D>,
104
+ __tsplusTrace?: string,
105
+ ): PSynchronizedInternal<RC, RD, EC, ED, C, D> {
106
+ return new PSynchronizedInternal(
107
+ this.semaphore,
108
+ this.get.matchIO((e) => IO.failNow(getError(e)), get),
109
+ (c) =>
110
+ this.get.matchIO(
111
+ (e) => IO.failNow(setGetError(e)),
112
+ (b) => set(c)(b).flatMap((a) => this.set(a).mapError(setError)),
113
+ ),
114
+ );
115
+ }
116
+
117
+ matchIOSubject<RC, RD, EI, EC, ED, C, D>(
118
+ mapSetError: (_: E) => EC,
119
+ mapGetError: (_: E) => ED,
120
+ mapErrorInput: (_: EI) => E,
121
+ mapSetErrorInput: (_: EC) => E,
122
+ mapSet: (_: C) => IO<RC, EC, A>,
123
+ mapGet: (_: A) => IO<RD, ED, D>,
124
+ __tsplusTrace?: string,
125
+ ): PRefSubject<RC, RD, EI, ED, EC, C, D> {
126
+ return new Derived((f) =>
127
+ f({
128
+ ref: this,
129
+ mapSetError,
130
+ mapGetError,
131
+ mapErrorInput,
132
+ mapSetErrorInput,
133
+ mapSet,
134
+ mapGet,
135
+ }),
136
+ );
137
+ }
138
+
139
+ set(a: A, __tsplusTrace?: string): IO<never, never, void> {
140
+ const exit = Exit.succeed(a);
141
+ return IO.defer(() => {
142
+ if (this.futureRef.done(exit)) {
143
+ return this.sendEvent(exit);
144
+ } else {
145
+ return IO.unit;
146
+ }
147
+ });
148
+ }
149
+
150
+ get get(): IO<never, E, A> {
151
+ return this.getOrInit(false);
152
+ }
153
+
154
+ private sendEvent(exit: Exit<E, A>) {
155
+ return exit.match(
156
+ (cause) => this.subject.onFailure(cause).provideEnvironment(this.runtime.environment),
157
+ (value) => this.subject.onSuccess(value).provideEnvironment(this.runtime.environment),
158
+ );
159
+ }
160
+
161
+ private getOrInit(lock: boolean) {
162
+ return IO.defer(() => {
163
+ if (this.fiber === null && this.futureRef.current.get.isNothing()) {
164
+ return this.init(lock) > this.futureRef;
165
+ } else {
166
+ return this.futureRef;
167
+ }
168
+ });
169
+ }
170
+
171
+ private interruptFiber = IO.defer(() => {
172
+ if (this.fiber) {
173
+ return this.fiber.interrupt;
174
+ } else {
175
+ return IO.unit;
176
+ }
177
+ });
178
+
179
+ private init(lock: boolean) {
180
+ const maybeWithLock = lock ? this.semaphore.withPermits(1) : Function.identity;
181
+
182
+ const initialize = maybeWithLock(
183
+ this.initial.provideEnvironment(this.runtime.environment).onExit((exit) =>
184
+ IO(() => {
185
+ this.fiber = null;
186
+ this.futureRef.done(exit);
187
+ }),
188
+ ),
189
+ );
190
+
191
+ return initialize.forkIn(this.scope).flatMap((fiber) => IO((this.fiber = fiber)));
192
+ }
193
+ }
@@ -0,0 +1,179 @@
1
+ import type { Atomic } from "./Atomic.js";
2
+ import type { Cause } from "@fncts/base/data/Cause";
3
+ import type { Either } from "@fncts/base/data/Either";
4
+ import type { UnsafeSink } from "@fncts/io/Push/Sink";
5
+ import type { PRef } from "@fncts/io/Ref";
6
+ import type { Scope } from "@fncts/io/Scope";
7
+
8
+ import { IO } from "@fncts/io/IO";
9
+ import { Sink } from "@fncts/io/Push/Sink";
10
+ import { type PSynchronized, PSynchronizedInternal } from "@fncts/io/Ref";
11
+
12
+ import { PRefSubject } from "./RefSubject.js";
13
+
14
+ export class Derived<EnvIn, EnvOut, ErrIn, ErrOut, ErrInRef, In, Out> extends PRefSubject<
15
+ EnvIn,
16
+ EnvOut,
17
+ ErrIn,
18
+ ErrOut,
19
+ ErrInRef,
20
+ In,
21
+ Out
22
+ > {
23
+ constructor(
24
+ readonly use: <X>(
25
+ f: <R, E0, A0>(_: {
26
+ ref: Atomic<R, E0, A0>;
27
+ mapSetError: (_: E0) => ErrInRef;
28
+ mapGetError: (_: E0) => ErrOut;
29
+ mapErrorInput: (_: ErrIn) => E0;
30
+ mapSetErrorInput: (_: ErrInRef) => E0;
31
+ mapSet: (a: In) => IO<EnvIn, ErrInRef, A0>;
32
+ mapGet: (a: A0) => IO<EnvOut, ErrOut, Out>;
33
+ }) => X,
34
+ ) => X,
35
+ ) {
36
+ super();
37
+ }
38
+
39
+ subscribers = this.use(({ ref }) => ref.subscribers);
40
+ interrupt = this.use(({ ref }) => ref.interrupt);
41
+
42
+ onSuccess(value: In): IO<EnvIn, never, void> {
43
+ return this.use(({ ref, mapSetErrorInput, mapSet }) =>
44
+ mapSet(value).matchCauseIO(
45
+ (cause) => ref.onFailure(cause.map(mapSetErrorInput)),
46
+ (a0) => ref.onSuccess(a0),
47
+ ),
48
+ );
49
+ }
50
+
51
+ onFailure(cause: Cause<ErrIn>): IO<EnvIn, never, void> {
52
+ return this.use(({ ref, mapErrorInput }) => ref.onFailure(cause.map(mapErrorInput)));
53
+ }
54
+
55
+ get get(): IO<EnvOut, ErrOut, Out> {
56
+ return this.use(({ ref, mapGetError, mapGet }) => ref.get.matchIO((e) => IO.failNow(mapGetError(e)), mapGet));
57
+ }
58
+
59
+ set(a: In, __tsplusTrace?: string): IO<EnvIn, ErrInRef, void> {
60
+ return this.use(({ ref, mapSet }) => mapSet(a).flatMap((a0) => ref.set(a0)));
61
+ }
62
+
63
+ modify<C>(f: (b: Out) => readonly [C, In], __tsplusTrace?: string): IO<EnvIn | EnvOut, ErrOut | ErrInRef, C> {
64
+ return this.modifyIO((out) => IO.succeedNow(f(out)));
65
+ }
66
+
67
+ modifyIO<R1, E1, C>(
68
+ f: (b: Out) => IO<R1, E1, readonly [C, In]>,
69
+ __tsplusTrace?: string,
70
+ ): IO<EnvIn | EnvOut | R1, ErrOut | ErrInRef | E1, C> {
71
+ return this.use(({ ref, mapGetError, mapSet, mapGet }) =>
72
+ ref.get.mapError(mapGetError).flatMap((a0) =>
73
+ mapGet(a0)
74
+ .flatMap(f)
75
+ .flatMap(([c, a]) =>
76
+ mapSet(a)
77
+ .flatMap((a0) => ref.set(a0))
78
+ .as(c),
79
+ ),
80
+ ),
81
+ );
82
+ }
83
+
84
+ match<EC, ED, C, D>(
85
+ ea: (_: ErrInRef) => EC,
86
+ eb: (_: ErrOut) => ED,
87
+ ca: (_: C) => Either<EC, In>,
88
+ bd: (_: Out) => Either<ED, D>,
89
+ __tsplusTrace?: string,
90
+ ): PRef<EnvIn, EnvOut, EC, ED, C, D> {
91
+ return this.matchIO(ea, eb, ca, bd);
92
+ }
93
+
94
+ matchAll<EC, ED, C, D>(
95
+ ea: (_: ErrInRef) => EC,
96
+ eb: (_: ErrOut) => ED,
97
+ ec: (_: ErrOut) => EC,
98
+ ca: (_: C) => (_: Out) => Either<EC, In>,
99
+ bd: (_: Out) => Either<ED, D>,
100
+ __tsplusTrace?: string,
101
+ ): PRef<EnvIn | EnvOut, EnvOut, EC, ED, C, D> {
102
+ return this.matchAllIO(ea, eb, ec, ca, bd);
103
+ }
104
+
105
+ matchIO<RC, RD, EC, ED, C, D>(
106
+ mapSetError: (_: ErrInRef) => EC,
107
+ mapGetError: (_: ErrOut) => ED,
108
+ mapSet: (_: C) => IO<RC, EC, In>,
109
+ mapGet: (_: Out) => IO<RD, ED, D>,
110
+ __tsplusTrace?: string,
111
+ ): PSynchronized<EnvIn | RC, EnvOut | RD, EC, ED, C, D> {
112
+ return this.use(
113
+ ({ ref }) =>
114
+ new PSynchronizedInternal(
115
+ ref.semaphore,
116
+ this.get.matchIO((e) => IO.failNow(mapGetError(e)), mapGet),
117
+ (c) => mapSet(c).flatMap((a) => this.set(a).mapError(mapSetError)),
118
+ ),
119
+ );
120
+ }
121
+
122
+ matchAllIO<RC, RD, EC, ED, C, D>(
123
+ mapSetError: (_: ErrInRef) => EC,
124
+ mapGetError: (_: ErrOut) => ED,
125
+ mapSetGetError: (_: ErrOut) => EC,
126
+ mapSet: (_: C) => (_: Out) => IO<RC, EC, In>,
127
+ mapGet: (_: Out) => IO<RD, ED, D>,
128
+ __tsplusTrace?: string,
129
+ ): PSynchronized<EnvIn | EnvOut | RC, EnvOut | RD, EC, ED, C, D> {
130
+ return this.use(
131
+ ({ ref }) =>
132
+ new PSynchronizedInternal(
133
+ ref.semaphore,
134
+ this.get.matchIO((e) => IO.failNow(mapGetError(e)), mapGet),
135
+ (c) =>
136
+ this.get.matchIO(
137
+ (e) => IO.failNow(mapSetGetError(e)),
138
+ (b) => mapSet(c)(b).flatMap((a) => this.set(a).mapError(mapSetError)),
139
+ ),
140
+ ),
141
+ );
142
+ }
143
+
144
+ matchIOSubject<RC, RD, EI, EC, ED, C, D>(
145
+ mapSetError: (_: ErrInRef) => EC,
146
+ mapGetError: (_: ErrOut) => ED,
147
+ mapErrorInput: (_: EI) => ErrIn,
148
+ mapSetErrorInput: (_: EC) => ErrInRef,
149
+ mapSet: (_: C) => IO<RC, EC, In>,
150
+ mapGet: (_: Out) => IO<RD, ED, D>,
151
+ __tsplusTrace?: string,
152
+ ): PRefSubject<EnvIn | RC, EnvOut | RD, EI, ED, EC, C, D> {
153
+ return this.use(
154
+ (r) =>
155
+ new Derived<EnvIn | RC, EnvOut | RD, EI, ED, EC, C, D>((f) =>
156
+ f({
157
+ ref: r.ref,
158
+ mapSetError: (e0) => mapSetError(r.mapSetError(e0)),
159
+ mapGetError: (e0) => mapGetError(r.mapGetError(e0)),
160
+ mapErrorInput: (ei) => r.mapErrorInput(mapErrorInput(ei)),
161
+ mapSetErrorInput: (ec) => r.mapSetErrorInput(mapSetErrorInput(ec)),
162
+ mapSet: (c) => mapSet(c).flatMap((inp) => r.mapSet(inp).mapError(mapSetError)),
163
+ mapGet: (a0) => r.mapGet(a0).mapError(mapGetError).flatMap(mapGet),
164
+ }),
165
+ ),
166
+ );
167
+ }
168
+
169
+ run<R1>(sink: UnsafeSink<R1, ErrOut, Out>): IO<Scope | EnvOut | R1, never, void> {
170
+ return this.use(({ ref, mapGet, mapGetError }) =>
171
+ ref.run(
172
+ Sink.unsafeMake(
173
+ (a0) => mapGet(a0).matchCauseIO(sink.onFailure, sink.onSuccess),
174
+ (cause) => sink.onFailure(cause.map(mapGetError)),
175
+ ),
176
+ ),
177
+ );
178
+ }
179
+ }
@@ -0,0 +1,90 @@
1
+ import type {
2
+ MappableRef,
3
+ MappableSynchronized,
4
+ ModifiableRef,
5
+ ModifiableSynchronized,
6
+ PSynchronized,
7
+ ReadableRef,
8
+ WritableRef,
9
+ } from "../../Ref.js";
10
+ import type { IO } from "@fncts/io/IO";
11
+
12
+ import { RefTypeId, RefVariance, SynchronizedTypeId } from "../../Ref.js";
13
+ import { PSubject } from "../definition.js";
14
+
15
+ export abstract class PRefSubject<EnvIn, EnvOut, ErrIn, ErrOut, ErrInRef, In, Out>
16
+ extends PSubject<EnvIn, EnvOut, ErrIn, ErrOut, In, Out>
17
+ implements
18
+ PRef<EnvIn, EnvOut, ErrInRef, ErrOut, In, Out>,
19
+ PSynchronized<EnvIn, EnvOut, ErrInRef, ErrOut, In, Out>,
20
+ ReadableRef<EnvOut, ErrOut, Out>,
21
+ WritableRef<EnvIn, ErrInRef, In>,
22
+ ModifiableRef<EnvIn, EnvOut, ErrInRef, ErrOut, In, Out>,
23
+ MappableRef<EnvIn, EnvOut, ErrInRef, ErrOut, In, Out>,
24
+ ModifiableSynchronized<EnvIn, EnvOut, ErrInRef, ErrOut, In, Out>,
25
+ MappableSynchronized<EnvIn, EnvOut, ErrInRef, ErrOut, In, Out>
26
+ {
27
+ readonly [SynchronizedTypeId]: SynchronizedTypeId = SynchronizedTypeId;
28
+ readonly [RefTypeId]: RefTypeId = RefTypeId;
29
+ declare [RefVariance]: {
30
+ readonly _RA: (_: never) => EnvIn;
31
+ readonly _RB: (_: never) => EnvOut;
32
+ readonly _EA: (_: never) => ErrInRef;
33
+ readonly _EB: (_: never) => ErrOut;
34
+ readonly _A: (_: In) => void;
35
+ readonly _B: (_: never) => Out;
36
+ };
37
+
38
+ abstract get: IO<EnvOut, ErrOut, Out>;
39
+
40
+ abstract set(a: In, __tsplusTrace?: string): IO<EnvIn, ErrInRef, void>;
41
+
42
+ abstract modify<C>(f: (b: Out) => readonly [C, In], __tsplusTrace?: string): IO<EnvIn | EnvOut, ErrOut | ErrInRef, C>;
43
+
44
+ abstract modifyIO<R1, E1, C>(
45
+ f: (b: Out) => IO<R1, E1, readonly [C, In]>,
46
+ __tsplusTrace?: string,
47
+ ): IO<EnvIn | EnvOut | R1, ErrOut | ErrInRef | E1, C>;
48
+
49
+ abstract match<EC, ED, C, D>(
50
+ ea: (_: ErrInRef) => EC,
51
+ eb: (_: ErrOut) => ED,
52
+ ca: (_: C) => Either<EC, In>,
53
+ bd: (_: Out) => Either<ED, D>,
54
+ ): PRef<EnvIn, EnvOut, EC, ED, C, D>;
55
+
56
+ abstract matchAll<EC, ED, C, D>(
57
+ ea: (_: ErrInRef) => EC,
58
+ eb: (_: ErrOut) => ED,
59
+ ec: (_: ErrOut) => EC,
60
+ ca: (_: C) => (_: Out) => Either<EC, In>,
61
+ bd: (_: Out) => Either<ED, D>,
62
+ ): PRef<EnvIn | EnvOut, EnvOut, EC, ED, C, D>;
63
+
64
+ abstract matchIO<RC, RD, EC, ED, C, D>(
65
+ mapSetError: (_: ErrInRef) => EC,
66
+ mapGetError: (_: ErrOut) => ED,
67
+ mapSet: (_: C) => IO<RC, EC, In>,
68
+ mapGet: (_: Out) => IO<RD, ED, D>,
69
+ __tsplusTrace?: string,
70
+ ): PSynchronized<EnvIn | RC, EnvOut | RD, EC, ED, C, D>;
71
+
72
+ abstract matchAllIO<RC, RD, EC, ED, C, D>(
73
+ mapSetError: (_: ErrInRef) => EC,
74
+ mapGetError: (_: ErrOut) => ED,
75
+ mapSetGetError: (_: ErrOut) => EC,
76
+ mapSet: (_: C) => (_: Out) => IO<RC, EC, In>,
77
+ mapGet: (_: Out) => IO<RD, ED, D>,
78
+ __tsplusTrace?: string,
79
+ ): PSynchronized<EnvIn | EnvOut | RC, EnvOut | RD, EC, ED, C, D>;
80
+
81
+ abstract matchIOSubject<RC, RD, EI, EC, ED, C, D>(
82
+ mapSetError: (_: ErrInRef) => EC,
83
+ mapGetError: (_: ErrOut) => ED,
84
+ mapErrorInput: (_: EI) => ErrIn,
85
+ mapSetErrorInput: (_: EC) => ErrInRef,
86
+ mapSet: (_: C) => IO<RC, EC, In>,
87
+ mapGet: (_: Out) => IO<RD, ED, D>,
88
+ __tsplusTrace?: string,
89
+ ): PRefSubject<EnvIn | RC, EnvOut | RD, EI, ED, EC, C, D>;
90
+ }
@@ -1,4 +1,8 @@
1
- import type { Push, Sink } from "../Push.js";
1
+ import type { UnsafeSink } from "../Push/Sink.js";
2
+ import type { Cause } from "@fncts/base/data/Cause";
3
+ import type { IO } from "@fncts/io/IO";
4
+
5
+ import { Push, PushTypeId } from "../Push.js";
2
6
 
3
7
  export const SubjectTypeId = Symbol.for("fncts.io.Push.Subject");
4
8
  export type SubjectTypeId = typeof SubjectTypeId;
@@ -6,10 +10,24 @@ export type SubjectTypeId = typeof SubjectTypeId;
6
10
  /**
7
11
  * @tsplus type fncts.io.Push.Subject
8
12
  */
9
- export interface Subject<R, E, A> extends Push<R, E, A>, Sink<R, E, A> {
10
- readonly [SubjectTypeId]: SubjectTypeId;
13
+ export abstract class PSubject<out EnvIn, out EnvOut, in ErrIn, out ErrOut, in In, Out>
14
+ extends Push<EnvOut | Scope, ErrOut, Out>
15
+ implements Push<EnvOut | Scope, ErrOut, Out>, UnsafeSink<EnvIn, ErrIn, In>
16
+ {
17
+ readonly _pushOpCode = null;
18
+ readonly [PushTypeId]: PushTypeId = PushTypeId;
19
+ readonly [SubjectTypeId]: SubjectTypeId = SubjectTypeId;
20
+
21
+ abstract onSuccess(value: In): IO<EnvIn, never, void>;
22
+ abstract onFailure(cause: Cause<ErrIn>): IO<EnvIn, never, void>;
23
+
24
+ abstract interrupt: URIO<EnvIn, void>;
25
+
26
+ abstract subscribers: number;
11
27
  }
12
28
 
29
+ export type Subject<R, E, A> = PSubject<R, R, E, E, A, A>;
30
+
13
31
  /**
14
32
  * @tsplus type fncts.io.Push.SubjectOps
15
33
  */
package/_src/Subject.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  // codegen:start { preset: barrel, include: ./Subject/*.ts }
2
- export * from "./Subject/api.js";
3
- export * from "./Subject/Atomic.js";
4
- export * from "./Subject/definition.js";
2
+ export * from "./Subject/api.js"
3
+ export * from "./Subject/Atomic.js"
4
+ export * from "./Subject/DeferredRef.js"
5
+ export * from "./Subject/definition.js"
6
+ export * from "./Subject/Hold.js"
5
7
  // codegen:end
@@ -7,7 +7,7 @@ export type SubscriptionRefTypeId = typeof SubscriptionRefTypeId;
7
7
  export class SubscriptionRefInternal<A> extends PSynchronizedInternal<never, never, never, never, A, A> {
8
8
  readonly [SubscriptionRefTypeId]: SubscriptionRefTypeId = SubscriptionRefTypeId;
9
9
  constructor(
10
- readonly semaphore: Semaphore,
10
+ semaphore: Semaphore,
11
11
  readonly hub: Hub<A>,
12
12
  readonly ref: Ref<A>,
13
13
  ) {