@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
@@ -1,53 +1,246 @@
1
+ import type { Sink as Sink_, UnsafeSink, UnsafeSink as UnsafeSink_ } from "./Sink.js";
2
+ import type { FlattenStrategy } from "@fncts/io/Push/FlattenStrategy";
3
+ import type { IOProducer } from "@fncts/io/Push/Producer/IOProducer";
4
+
5
+ import { type SyncProducer } from "@fncts/io/Push/Producer/SyncProducer";
6
+
7
+ import { Sink } from "./Sink.js";
8
+
1
9
  export const PushVariance = Symbol.for("fncts.io.Push.Variance");
2
10
  export type PushVariance = typeof PushVariance;
3
11
 
4
12
  export const PushTypeId = Symbol.for("fncts.io.Push");
5
13
  export type PushTypeId = typeof PushTypeId;
6
14
 
15
+ export const enum PushTag {
16
+ Defer,
17
+ ProducerSync,
18
+ ProducerIO,
19
+ FailCause,
20
+ OnSuccess,
21
+ OnSuccessWithStrategy,
22
+ OnSuccessAndFailure,
23
+ External,
24
+ FromPush,
25
+ Transform,
26
+ }
27
+
7
28
  /**
8
29
  * @tsplus type fncts.io.Push
9
30
  * @tsplus companion fncts.io.PushOps
10
31
  */
11
- export class Push<R, E, A> {
12
- readonly [PushTypeId]: PushTypeId = PushTypeId;
32
+ export abstract class Push<R, E, A> {
33
+ readonly [PushTypeId]: PushTypeId = PushTypeId;
34
+ readonly _pushOpCode: PushTag | null = null;
35
+
13
36
  declare [PushVariance]: {
14
37
  readonly _R: (_: never) => R;
15
38
  readonly _E: (_: never) => E;
16
39
  readonly _A: (_: never) => A;
17
40
  };
18
- constructor(readonly run: <R1>(emitter: Sink<R1, E, A>) => IO<R | R1, never, unknown>) {}
41
+
42
+ constructor() {
43
+ this.run = this.run.bind(this);
44
+ }
45
+
46
+ run<R1>(sink: UnsafeSink<R1, E, A>): IO<R | R1, never, void> {
47
+ return this.unsafeRun(sink);
48
+ }
19
49
  }
20
50
 
21
51
  export declare namespace Push {
52
+ export type Run<R, E, A> = <R1>(emitter: UnsafeSink<R1, E, A>) => IO<R | R1, never, unknown>;
22
53
  export type EnvironmentOf<X> = [X] extends [{ [PushVariance]: { readonly _R: (_: never) => infer R } }] ? R : never;
23
54
  export type ErrorOf<X> = [X] extends [{ [PushVariance]: { readonly _E: (_: never) => infer E } }] ? E : never;
24
55
  export type ValueOf<X> = [X] extends [{ [PushVariance]: { readonly _A: (_: never) => infer A } }] ? A : never;
56
+ export type Sink<Env, R, E, A> = Sink_<Env, R, E, A>;
57
+ export type UnsafeSink<R, E, A> = UnsafeSink_<R, E, A>;
25
58
  }
26
59
 
27
60
  /**
28
- * @tsplus type fncts.io.Push.Sink
29
- * @tsplus companion fncts.io.Push.SinkOps
61
+ * @tsplus pipeable fncts.io.Push unsafeRun
30
62
  */
31
- export class Sink<R, E, A> {
32
- constructor(
33
- readonly event: (value: A) => IO<R, never, void>,
34
- readonly error: (cause: Cause<E>) => IO<R, never, void>,
35
- ) {}
63
+ export function unsafeRun<E, A, R1>(sink: UnsafeSink<R1, E, A>) {
64
+ return <R>(push: Push<R, E, A>): IO<R | R1, never, void> => unsafeRunPush(push, sink);
36
65
  }
37
66
 
38
- /**
39
- * @tsplus static fncts.io.PushOps __call
40
- */
41
- export function makePush<R, E, A>(run: <R1>(sink: Sink<R1, E, A>) => IO<R | R1, never, unknown>): Push<R, E, A> {
42
- return new Push(run);
67
+ export type PushOp<Tag extends string | number | null, Body = {}> = Push<never, any, any> &
68
+ Body & {
69
+ readonly _pushOpCode: Tag;
70
+ };
71
+
72
+ export class PushPrimitive extends Push<never, any, any> {
73
+ public i0: any = undefined;
74
+ public i1: any = undefined;
75
+ public i2: any = undefined;
76
+ public i3: any = undefined;
77
+ public i4: any = undefined;
78
+ public trace: string | undefined = undefined;
79
+ constructor(readonly _pushOpCode: PushTag | null) {
80
+ super();
81
+ }
43
82
  }
44
83
 
45
- /**
46
- * @tsplus static fncts.io.Push.SinkOps __call
47
- */
48
- export function makeSink<R, E, A>(
49
- value: (value: A) => IO<R, never, unknown>,
50
- error: (cause: Cause<E>) => IO<R, never, unknown>,
51
- ): Sink<R, E, A> {
52
- return new Sink(value, error);
84
+ export interface Base<R = never, E = any, A = any>
85
+ extends PushOp<
86
+ null,
87
+ {
88
+ readonly run: Push.Run<R, E, A>;
89
+ }
90
+ > {}
91
+
92
+ export interface Defer
93
+ extends PushOp<
94
+ PushTag.Defer,
95
+ {
96
+ readonly i0: () => Primitive;
97
+ }
98
+ > {}
99
+
100
+ export interface FromPush<R = never, E = any, A = any>
101
+ extends PushOp<
102
+ PushTag.FromPush,
103
+ {
104
+ readonly i0: Push.Run<R, E, A>;
105
+ }
106
+ > {}
107
+
108
+ export interface ProducerSync<A = any>
109
+ extends PushOp<
110
+ PushTag.ProducerSync,
111
+ {
112
+ readonly i0: SyncProducer<A>;
113
+ }
114
+ > {}
115
+
116
+ export interface ProducerIO<R = never, E = any, A = any>
117
+ extends PushOp<
118
+ PushTag.ProducerIO,
119
+ {
120
+ readonly i0: IOProducer<R, E, A>;
121
+ }
122
+ > {}
123
+
124
+ export interface Fail<E = any>
125
+ extends PushOp<
126
+ PushTag.FailCause,
127
+ {
128
+ readonly i0: () => Cause<E>;
129
+ }
130
+ > {}
131
+
132
+ export interface OnSuccess<A = any>
133
+ extends PushOp<
134
+ PushTag.OnSuccess,
135
+ {
136
+ readonly i0: Primitive;
137
+ readonly i1: (a: A) => Primitive;
138
+ }
139
+ > {}
140
+
141
+ export interface OnSuccessWithStrategy<A = any>
142
+ extends PushOp<
143
+ PushTag.OnSuccessWithStrategy,
144
+ {
145
+ readonly i0: Primitive;
146
+ readonly i1: (a: A) => Primitive;
147
+ readonly i2: FlattenStrategy;
148
+ readonly i3: ExecutionStrategy;
149
+ }
150
+ > {}
151
+
152
+ export interface OnSuccessAndFailure<E = any, A = any>
153
+ extends PushOp<
154
+ PushTag.OnSuccessAndFailure,
155
+ {
156
+ readonly i0: Primitive;
157
+ readonly i1: (cause: Cause<E>) => Primitive;
158
+ readonly i2: (a: A) => Primitive;
159
+ readonly i3: FlattenStrategy;
160
+ readonly i4: ExecutionStrategy;
161
+ }
162
+ > {}
163
+
164
+ export interface Transform
165
+ extends PushOp<
166
+ PushTag.Transform,
167
+ {
168
+ i0: Primitive;
169
+ i1: (io: IO<any, any, any>) => IO<any, never, void>;
170
+ }
171
+ > {}
172
+
173
+ type Primitive =
174
+ | Base
175
+ | ProducerSync
176
+ | ProducerIO
177
+ | Fail
178
+ | OnSuccess
179
+ | OnSuccessWithStrategy
180
+ | OnSuccessAndFailure
181
+ | FromPush
182
+ | Defer
183
+ | Transform;
184
+
185
+ export function concrete(push: Push<any, any, any>): asserts push is Primitive {
186
+ //
187
+ }
188
+
189
+ export function unsafeRunPush(push: Push<any, any, any>, sink: UnsafeSink<any, any, any>): IO<any, never, void> {
190
+ concrete(push);
191
+ switch (push._pushOpCode) {
192
+ case PushTag.Defer: {
193
+ return IO.defer(push.i0().unsafeRun(sink));
194
+ }
195
+ case PushTag.ProducerSync: {
196
+ return push.i0.runSink(sink);
197
+ }
198
+ case PushTag.ProducerIO: {
199
+ return push.i0.runSink(sink);
200
+ }
201
+ case PushTag.FailCause: {
202
+ return sink.onFailure(push.i0());
203
+ }
204
+ case PushTag.OnSuccessWithStrategy: {
205
+ return push.i2.withFork(
206
+ (fork) =>
207
+ push.i0.unsafeRun(
208
+ Sink.unsafeMake(
209
+ (value) => fork(push.i1(value).unsafeRun(sink)),
210
+ (cause) => sink.onFailure(cause),
211
+ ),
212
+ ),
213
+ push.i3,
214
+ );
215
+ }
216
+ case PushTag.OnSuccess: {
217
+ return push.i0.unsafeRun(
218
+ Sink.unsafeMake(
219
+ (value) => push.i1(value).unsafeRun(sink),
220
+ (cause) => sink.onFailure(cause),
221
+ ),
222
+ );
223
+ }
224
+ case PushTag.OnSuccessAndFailure: {
225
+ return push.i3.withFork(
226
+ (fork) =>
227
+ push.i0.unsafeRun(
228
+ Sink.unsafeMake(
229
+ (value) => fork(push.i2(value).unsafeRun(sink)),
230
+ (cause) => fork(push.i1(cause).unsafeRun(sink)),
231
+ ),
232
+ ),
233
+ push.i4,
234
+ );
235
+ }
236
+ case PushTag.FromPush: {
237
+ return IO.environmentWith((environment) => push.i0(sink).provideSomeEnvironment(environment));
238
+ }
239
+ case PushTag.Transform: {
240
+ return IO.defer(push.i1(push.i0.unsafeRun(sink)));
241
+ }
242
+ case null: {
243
+ return push.run(sink);
244
+ }
245
+ }
53
246
  }
@@ -1,5 +1,16 @@
1
1
  import type { RuntimeFiber } from "@fncts/io/Fiber";
2
2
 
3
+ export function withScope<R, E, A>(
4
+ f: (scope: Scope.Closeable) => IO<R, E, A>,
5
+ executionStrategy: ExecutionStrategy,
6
+ ): IO<R | Scope, E, A> {
7
+ return IO.bracketExit(
8
+ IO.scopeWith((scope) => scope.forkWith(executionStrategy)),
9
+ f,
10
+ (scope, exit) => scope.close(exit),
11
+ );
12
+ }
13
+
3
14
  export function withScopedFork<R, E, A>(
4
15
  f: (fork: <R, E, A>(io: IO<R, E, A>) => IO<R, never, RuntimeFiber<E, A>>) => IO<R, E, A>,
5
16
  ): IO<R, E, A> {
package/_src/Push.ts CHANGED
@@ -1,5 +1,11 @@
1
- // codegen:start { preset: barrel, include: ./Push/*.ts }
1
+ // codegen:start { preset: barrel, include: ./Push/*.ts, exclude: ./Push/Sink.ts }
2
2
  export * from "./Push/api.js";
3
+ export * from "./Push/Bounds.js";
3
4
  export * from "./Push/definition.js";
5
+ export * from "./Push/FlattenStrategy.js";
6
+ export * from "./Push/IndexedBuffer.js";
4
7
  export * from "./Push/internal.js";
8
+ export * from "./Push/MergeStrategy.js";
9
+ export * from "./Push/Operator.js";
10
+ export * from "./Push/Producer.js";
5
11
  // codegen:end
@@ -1,4 +1,4 @@
1
- import type { PRef } from "../definition.js";
1
+ import type { PRef, RefVariance } from "../definition.js";
2
2
 
3
3
  import { IO } from "@fncts/io/IO";
4
4
 
@@ -24,15 +24,59 @@ export interface PSynchronizedOps {}
24
24
  */
25
25
  export const Synchronized: PSynchronizedOps = {};
26
26
 
27
+ export interface ModifiableSynchronized<RA, RB, EA, EB, A, B> {
28
+ readonly [RefVariance]: {
29
+ readonly _RA: (_: never) => RA;
30
+ readonly _RB: (_: never) => RB;
31
+ readonly _EA: (_: never) => EA;
32
+ readonly _EB: (_: never) => EB;
33
+ readonly _A: (_: A) => void;
34
+ readonly _B: (_: never) => B;
35
+ };
36
+
37
+ modifyIO<R1, E1, C>(
38
+ f: (b: B) => IO<R1, E1, readonly [C, A]>,
39
+ __tsplusTrace?: string,
40
+ ): IO<RA | RB | R1, EA | EB | E1, C>;
41
+ }
42
+
43
+ export interface MappableSynchronized<RA, RB, EA, EB, A, B> {
44
+ readonly [RefVariance]: {
45
+ readonly _RA: (_: never) => RA;
46
+ readonly _RB: (_: never) => RB;
47
+ readonly _EA: (_: never) => EA;
48
+ readonly _EB: (_: never) => EB;
49
+ readonly _A: (_: A) => void;
50
+ readonly _B: (_: never) => B;
51
+ };
52
+
53
+ matchIO<RC, RD, EC, ED, C, D>(
54
+ mapSetError: (_: EA) => EC,
55
+ mapGetError: (_: EB) => ED,
56
+ mapSet: (_: C) => IO<RC, EC, A>,
57
+ mapGet: (_: B) => IO<RD, ED, D>,
58
+ __tsplusTrace?: string,
59
+ ): PSynchronized<RA | RC, RB | RD, EC, ED, C, D>;
60
+
61
+ matchAllIO<RC, RD, EC, ED, C, D>(
62
+ mapSetError: (_: EA) => EC,
63
+ mapGetError: (_: EB) => ED,
64
+ mapSetGetError: (_: EB) => EC,
65
+ mapSet: (_: C) => (_: B) => IO<RC, EC, A>,
66
+ mapGet: (_: B) => IO<RD, ED, D>,
67
+ __tsplusTrace?: string,
68
+ ): PSynchronized<RA | RC | RB, RB | RD, EC, ED, C, D>;
69
+ }
70
+
27
71
  /**
28
72
  * @tsplus type fncts.io.Ref.Synchronized
29
73
  */
30
74
  export class PSynchronizedInternal<RA, RB, EA, EB, A, B> extends RefInternal<RA, RB, EA, EB, A, B> {
31
75
  readonly [SynchronizedTypeId]: SynchronizedTypeId = SynchronizedTypeId;
32
76
  constructor(
33
- readonly semaphore: Semaphore,
34
- readonly unsafeGet: IO<RB, EB, B>,
35
- readonly unsafeSet: (a: A) => IO<RA, EA, void>,
77
+ protected semaphore: Semaphore,
78
+ protected unsafeGet: IO<RB, EB, B>,
79
+ protected unsafeSet: (a: A) => IO<RA, EA, void>,
36
80
  ) {
37
81
  super();
38
82
  }
@@ -57,71 +101,71 @@ export class PSynchronizedInternal<RA, RB, EA, EB, A, B> extends RefInternal<RA,
57
101
  }
58
102
 
59
103
  matchAllIO<RC, RD, EC, ED, C, D>(
60
- ea: (_: EA) => EC,
61
- eb: (_: EB) => ED,
62
- ec: (_: EB) => EC,
63
- ca: (_: C) => (_: B) => IO<RC, EC, A>,
64
- bd: (_: B) => IO<RD, ED, D>,
104
+ mapSetError: (_: EA) => EC,
105
+ mapGetError: (_: EB) => ED,
106
+ mapSetGetError: (_: EB) => EC,
107
+ mapSet: (_: C) => (_: B) => IO<RC, EC, A>,
108
+ mapGet: (_: B) => IO<RD, ED, D>,
65
109
  __tsplusTrace?: string,
66
110
  ): PSynchronizedInternal<RA | RC | RB, RB | RD, EC, ED, C, D> {
67
111
  return new PSynchronizedInternal(
68
112
  this.semaphore,
69
- this.get.matchIO((e) => IO.failNow(eb(e)), bd),
113
+ this.get.matchIO((e) => IO.failNow(mapGetError(e)), mapGet),
70
114
  (c) =>
71
115
  this.get.matchIO(
72
- (e) => IO.failNow(ec(e)),
73
- (b) => ca(c)(b).flatMap((a) => this.unsafeSet(a).mapError(ea)),
116
+ (e) => IO.failNow(mapSetGetError(e)),
117
+ (b) => mapSet(c)(b).flatMap((a) => this.unsafeSet(a).mapError(mapSetError)),
74
118
  ),
75
119
  );
76
120
  }
77
121
 
78
122
  matchIO<RC, RD, EC, ED, C, D>(
79
- ea: (_: EA) => EC,
80
- eb: (_: EB) => ED,
81
- ca: (_: C) => IO<RC, EC, A>,
82
- bd: (_: B) => IO<RD, ED, D>,
123
+ mapSetError: (_: EA) => EC,
124
+ mapGetError: (_: EB) => ED,
125
+ mapSet: (_: C) => IO<RC, EC, A>,
126
+ mapGet: (_: B) => IO<RD, ED, D>,
83
127
  __tsplusTrace?: string,
84
128
  ): PSynchronizedInternal<RA | RC, RB | RD, EC, ED, C, D> {
85
129
  return new PSynchronizedInternal(
86
130
  this.semaphore,
87
- this.unsafeGet.matchIO((e) => IO.failNow(eb(e)), bd),
88
- (c) => ca(c).flatMap((a) => this.unsafeSet(a).mapError(ea)),
131
+ this.unsafeGet.matchIO((e) => IO.failNow(mapGetError(e)), mapGet),
132
+ (c) => mapSet(c).flatMap((a) => this.unsafeSet(a).mapError(mapSetError)),
89
133
  );
90
134
  }
91
135
 
92
136
  match<EC, ED, C, D>(
93
- ea: (_: EA) => EC,
94
- eb: (_: EB) => ED,
95
- ca: (_: C) => Either<EC, A>,
96
- bd: (_: B) => Either<ED, D>,
137
+ mapSetError: (_: EA) => EC,
138
+ mapGetError: (_: EB) => ED,
139
+ mapSet: (_: C) => Either<EC, A>,
140
+ mapGet: (_: B) => Either<ED, D>,
97
141
  __tsplusTrace?: string,
98
142
  ): PSynchronizedInternal<RA, RB, EC, ED, C, D> {
99
143
  return this.matchIO(
100
- ea,
101
- eb,
102
- (c) => IO.fromEitherNow(ca(c)),
103
- (b) => IO.fromEitherNow(bd(b)),
144
+ mapSetError,
145
+ mapGetError,
146
+ (c) => IO.fromEitherNow(mapSet(c)),
147
+ (b) => IO.fromEitherNow(mapGet(b)),
104
148
  );
105
149
  }
106
150
 
107
151
  matchAll<EC, ED, C, D>(
108
- ea: (_: EA) => EC,
109
- eb: (_: EB) => ED,
110
- ec: (_: EB) => EC,
111
- ca: (_: C) => (_: B) => Either<EC, A>,
112
- bd: (_: B) => Either<ED, D>,
152
+ mapSetError: (_: EA) => EC,
153
+ mapGetError: (_: EB) => ED,
154
+ mapSetGetError: (_: EB) => EC,
155
+ mapSet: (_: C) => (_: B) => Either<EC, A>,
156
+ mapGet: (_: B) => Either<ED, D>,
113
157
  __tsplusTrace?: string,
114
158
  ): PSynchronizedInternal<RA, RB, EC, ED, C, D> {
115
159
  return this.matchAllIO(
116
- ea,
117
- eb,
118
- ec,
119
- (c) => (b) => IO.fromEitherNow(ca(c)(b)),
120
- (b) => IO.fromEitherNow(bd(b)),
160
+ mapSetError,
161
+ mapGetError,
162
+ mapSetGetError,
163
+ (c) => (b) => IO.fromEitherNow(mapSet(c)(b)),
164
+ (b) => IO.fromEitherNow(mapGet(b)),
121
165
  ) as PSynchronizedInternal<RA, RB, EC, ED, C, D>;
122
166
  }
123
167
 
124
- withPermit<R, E, A>(io: IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
168
+ protected withPermit<R, E, A>(io: IO<R, E, A>, __tsplusTrace?: string): IO<R, E, A> {
125
169
  return this.semaphore.withPermit(io);
126
170
  }
127
171
  }
@@ -75,6 +75,32 @@ export interface ModifiableRef<RA, RB, EA, EB, A, B> {
75
75
  modify<C>(f: (b: B) => readonly [C, A], __tsplusTrace?: string): IO<RA | RB, EA | EB, C>;
76
76
  }
77
77
 
78
+ export interface MappableRef<RA, RB, EA, EB, A, B> {
79
+ readonly [RefVariance]: {
80
+ readonly _RA: (_: never) => RA;
81
+ readonly _RB: (_: never) => RB;
82
+ readonly _EA: (_: never) => EA;
83
+ readonly _EB: (_: never) => EB;
84
+ readonly _A: (_: A) => void;
85
+ readonly _B: (_: never) => B;
86
+ };
87
+
88
+ match<EC, ED, C, D>(
89
+ ea: (_: EA) => EC,
90
+ eb: (_: EB) => ED,
91
+ ca: (_: C) => Either<EC, A>,
92
+ bd: (_: B) => Either<ED, D>,
93
+ ): PRef<RA, RB, EC, ED, C, D>;
94
+
95
+ matchAll<EC, ED, C, D>(
96
+ ea: (_: EA) => EC,
97
+ eb: (_: EB) => ED,
98
+ ec: (_: EB) => EC,
99
+ ca: (_: C) => (_: B) => Either<EC, A>,
100
+ bd: (_: B) => Either<ED, D>,
101
+ ): PRef<RA | RB, RB, EC, ED, C, D>;
102
+ }
103
+
78
104
  export abstract class RefInternal<RA, RB, EA, EB, A, B>
79
105
  implements
80
106
  PRef<RA, RB, EA, EB, A, B>,
package/_src/Scope/api.ts CHANGED
@@ -19,6 +19,16 @@ export function makeAddFinalizer(finalizer: Lazy<UIO<void>>, __tsplusTrace?: str
19
19
  return IO.serviceWithIO((scope) => scope.addFinalizer(finalizer), Scope.Tag);
20
20
  }
21
21
 
22
+ /**
23
+ * @tsplus static fncts.io.ScopeOps addFinalizerExit
24
+ */
25
+ export function makeAddFinalizerExit(
26
+ finalizer: (exit: Exit<any, any>) => UIO<any>,
27
+ __tsplusTrace?: string,
28
+ ): IO<Scope, never, void> {
29
+ return IO.serviceWithIO((scope) => scope.addFinalizerExit(Finalizer.get(finalizer)), Scope.Tag);
30
+ }
31
+
22
32
  /**
23
33
  * @tsplus static fncts.io.ScopeOps concurrent
24
34
  * @tsplus static fncts.io.Scope.CloseableOps concurrent
@@ -131,3 +141,15 @@ export function use<R, E, A>(io: Lazy<IO<R, E, A>>, __tsplusTrace?: string) {
131
141
  return self.extend(io).onExit((exit) => self.close(exit));
132
142
  };
133
143
  }
144
+
145
+ /**
146
+ * @tsplus getter fncts.io.Scope awaitClose
147
+ */
148
+ export function awaitClose(scope: Scope): UIO<void> {
149
+ return IO.asyncIO((cb) => scope.addFinalizer(IO(() => cb(IO.unit))));
150
+ }
151
+
152
+ /**
153
+ * @tsplus static fncts.io.ScopeOps awaitClose
154
+ */
155
+ export const wait: IO<Scope, never, void> = IO.asyncIO((cb) => Scope.addFinalizer(IO(() => cb(IO.unit))));
@@ -1,12 +1,11 @@
1
1
  /**
2
2
  * Sink is a data type that represent a channel that reads elements
3
- * of type `In`, handles input errors of type `InErr`, emits errors
4
- * of type `OutErr`, emits outputs of type `L` and ends with a value
5
- * of type `Z`.
3
+ * of type `In`, emits errors of type `OutErr`, emits outputs of type `Out` and ends with a value
4
+ * of type `Done`.
6
5
  *
7
6
  * @tsplus type fncts.io.Sink
8
7
  * @tsplus companion fncts.io.SinkOps
9
8
  */
10
- export class Sink<R, E, In, L, Z> {
11
- constructor(readonly channel: Channel<R, never, Conc<In>, unknown, E, Conc<L>, Z>) {}
9
+ export class Sink<Env, OutErr, In, Out, Done> {
10
+ constructor(readonly channel: Channel<Env, never, Conc<In>, unknown, OutErr, Conc<Out>, Done>) {}
12
11
  }
@@ -1,5 +1,4 @@
1
1
  import type { _A, _E, _R } from "@fncts/base/types";
2
-
3
2
  export const StreamVariance = Symbol.for("fncts.io.Stream.Variance");
4
3
  export type StreamVariance = typeof StreamVariance;
5
4
 
@@ -1,11 +1,16 @@
1
- import type { Sink } from "@fncts/io/Push/definition";
2
- import type { Subject } from "@fncts/io/Subject/definition";
1
+ import type { Scope } from "../Scope.js";
2
+ import type { Push } from "@fncts/io/Push";
3
+ import type { UnsafeSink } from "@fncts/io/Push/Sink";
3
4
 
4
- import { Multicast, Push } from "@fncts/io/Push";
5
+ import { HashSet as MutableHashSet } from "@fncts/base/collection/mutable/HashSet";
5
6
  import { PushTypeId, PushVariance } from "@fncts/io/Push/definition";
7
+ import { withScope } from "@fncts/io/Push/internal";
8
+ import { PSubject } from "@fncts/io/Subject/definition";
6
9
  import { SubjectTypeId } from "@fncts/io/Subject/definition";
7
10
 
8
- export class AtomicSubject<E, A> implements Subject<never, E, A> {
11
+ import { IO } from "../IO.js";
12
+
13
+ export class AtomicSubject<E, A> extends PSubject<Scope, never, E, E, A, A> {
9
14
  readonly [SubjectTypeId]: SubjectTypeId = SubjectTypeId;
10
15
  readonly [PushTypeId]: PushTypeId = PushTypeId;
11
16
  declare [PushVariance]: {
@@ -14,17 +19,69 @@ export class AtomicSubject<E, A> implements Subject<never, E, A> {
14
19
  readonly _A: (_: never) => A;
15
20
  };
16
21
 
17
- readonly stream = new Multicast<never, E, A>(Push.never);
22
+ get subscribers(): number {
23
+ return this.sinks.size;
24
+ }
25
+
26
+ protected sinks = MutableHashSet.empty<readonly [UnsafeSink<any, E, A>, Environment<any>, Scope.Closeable]>();
27
+
28
+ protected interruptScopes = IO.fiberIdWith((fiberId) =>
29
+ this.sinks.foreachDiscardIO(([, , scope]) => scope.close(Exit.interrupt(fiberId))),
30
+ );
31
+
32
+ readonly interrupt = this.interruptScopes;
33
+
34
+ run<R1>(sink: UnsafeSink<R1, E, A>): IO<Scope | R1, never, void> {
35
+ return this.addSink(sink, (scope) => scope.awaitClose);
36
+ }
37
+
38
+ onSuccess(value: A): IO<never, never, void> {
39
+ return IO.defer(this.unsafeOnSuccess(value));
40
+ }
41
+
42
+ onFailure(cause: Cause<E>): IO<never, never, void> {
43
+ return IO.defer(this.unsafeOnFailure(cause));
44
+ }
18
45
 
19
- run<R>(emitter: Sink<R, E, A>): IO<R, never, unknown> {
20
- return this.stream.run(emitter);
46
+ protected addSink<R, R1, B>(
47
+ sink: UnsafeSink<R, E, A>,
48
+ f: (scope: Scope) => IO<R1, never, B>,
49
+ ): IO<Scope | R1, never, B> {
50
+ return withScope(
51
+ (innerScope) =>
52
+ IO.environmentWithIO((environment) => {
53
+ const entry = [sink, environment, innerScope] as const;
54
+ this.sinks.add(entry);
55
+ const remove = IO(this.sinks.remove(entry));
56
+ return innerScope.addFinalizer(remove) > f(innerScope);
57
+ }),
58
+ ExecutionStrategy.sequential,
59
+ );
21
60
  }
22
61
 
23
- event(value: A): IO<never, never, void> {
24
- return this.stream.event(value);
62
+ protected unsafeOnSuccess(a: A) {
63
+ if (this.sinks.size === 0) {
64
+ return IO.unit;
65
+ } else {
66
+ return this.sinks.foreachDiscardIO(([sink, environment]) =>
67
+ sink
68
+ .onSuccess(a)
69
+ .catchAllCause((cause) => sink.onFailure(cause))
70
+ .provideSomeEnvironment(environment),
71
+ );
72
+ }
25
73
  }
26
74
 
27
- error(cause: Cause<E>): IO<never, never, void> {
28
- return this.stream.error(cause);
75
+ protected unsafeOnFailure(cause: Cause<E>) {
76
+ if (this.sinks.size === 0) {
77
+ return IO.unit;
78
+ } else {
79
+ return this.sinks.foreachDiscardIO(([sink, environment, scope]) =>
80
+ sink
81
+ .onFailure(cause)
82
+ .catchAllCause((error) => scope.close(Exit.failCause(error)))
83
+ .provideSomeEnvironment(environment),
84
+ );
85
+ }
29
86
  }
30
87
  }