@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,173 @@
1
+ import type { SyncOperator } from "./SyncOperator.js";
2
+
3
+ export const enum IOOperatorTag {
4
+ MapIO = "MapIO",
5
+ TapIO = "TapIO",
6
+ FilterIO = "FilterIO",
7
+ FilterMapIO = "FilterMapIO",
8
+ }
9
+
10
+ /**
11
+ * @tsplus type fncts.io.Push.IOOperator
12
+ * @tsplus companion fncts.io.Push.IOOperatorOps
13
+ */
14
+ export type IOOperator =
15
+ | MapIO<any, any, any, any>
16
+ | TapIO<any, any, any, any>
17
+ | FilterIO<any, any, any>
18
+ | FilterMapIO<any, any, any, any>;
19
+
20
+ export interface MapIO<R, E, A, B> {
21
+ readonly _tag: IOOperatorTag.MapIO;
22
+ readonly f: (a: A) => IO<R, E, B>;
23
+ }
24
+
25
+ export function MapIO<R, E, A, B>(f: (a: A) => IO<R, E, B>): MapIO<R, E, A, B> {
26
+ return {
27
+ _tag: IOOperatorTag.MapIO,
28
+ f,
29
+ };
30
+ }
31
+
32
+ export interface TapIO<R, E, A, B> {
33
+ readonly _tag: IOOperatorTag.TapIO;
34
+ readonly f: (a: A) => IO<R, E, B>;
35
+ }
36
+
37
+ export function TapIO<R, E, A, B>(f: (a: A) => IO<R, E, B>): TapIO<R, E, A, B> {
38
+ return {
39
+ _tag: IOOperatorTag.TapIO,
40
+ f,
41
+ };
42
+ }
43
+
44
+ export interface FilterIO<R, E, A> {
45
+ readonly _tag: IOOperatorTag.FilterIO;
46
+ readonly f: (a: A) => IO<R, E, boolean>;
47
+ }
48
+
49
+ export function FilterIO<R, E, A>(f: (a: A) => IO<R, E, boolean>): FilterIO<R, E, A> {
50
+ return {
51
+ _tag: IOOperatorTag.FilterIO,
52
+ f,
53
+ };
54
+ }
55
+
56
+ export interface FilterMapIO<R, E, A, B> {
57
+ readonly _tag: IOOperatorTag.FilterMapIO;
58
+ readonly f: (a: A) => IO<R, E, Maybe<B>>;
59
+ }
60
+
61
+ export function FilterMapIO<R, E, A, B>(f: (a: A) => IO<R, E, Maybe<B>>): FilterMapIO<R, E, A, B> {
62
+ return {
63
+ _tag: IOOperatorTag.FilterMapIO,
64
+ f,
65
+ };
66
+ }
67
+
68
+ export type IOOperatorFusionMap = {
69
+ readonly [K in IOOperator["_tag"]]: {
70
+ readonly [K2 in IOOperator["_tag"]]: (
71
+ op1: Extract<IOOperator, { readonly _tag: K }>,
72
+ op2: Extract<IOOperator, { readonly _tag: K2 }>,
73
+ ) => IOOperator;
74
+ };
75
+ };
76
+
77
+ const IOOperatorFusionMap: IOOperatorFusionMap = {
78
+ [IOOperatorTag.MapIO]: {
79
+ [IOOperatorTag.MapIO]: (op1, op2) => MapIO((a) => op1.f(a).flatMap(op2.f)),
80
+ [IOOperatorTag.TapIO]: (op1, op2) => MapIO((a) => op1.f(a).tap(op2.f)),
81
+ [IOOperatorTag.FilterIO]: (op1, op2) =>
82
+ FilterMapIO((a) => op1.f(a).flatMap((b) => op2.f(b).map((b2) => (b2 ? Just(b) : Nothing())))),
83
+ [IOOperatorTag.FilterMapIO]: (op1, op2) => FilterMapIO((a) => op1.f(a).flatMap(op2.f)),
84
+ },
85
+ [IOOperatorTag.TapIO]: {
86
+ [IOOperatorTag.MapIO]: (op1, op2) => MapIO((a) => op1.f(a).flatMap(() => op2.f(a))),
87
+ [IOOperatorTag.TapIO]: (op1, op2) => TapIO((a) => op1.f(a).tap(() => op2.f(a))),
88
+ [IOOperatorTag.FilterIO]: (op1, op2) => FilterIO((a) => op1.f(a).flatMap(() => op2.f(a))),
89
+ [IOOperatorTag.FilterMapIO]: (op1, op2) => FilterMapIO((a) => op1.f(a).flatMap(() => op2.f(a))),
90
+ },
91
+ [IOOperatorTag.FilterIO]: {
92
+ [IOOperatorTag.MapIO]: (op1, op2) =>
93
+ FilterMapIO((a) => op1.f(a).flatMap((b) => (b ? op2.f(a).map(Maybe.just) : IO.succeedNow(Nothing())))),
94
+ [IOOperatorTag.TapIO]: (op1, op2) => FilterIO((a) => op1.f(a).tap(() => op2.f(a))),
95
+ [IOOperatorTag.FilterIO]: (op1, op2) => FilterIO((a) => op1.f(a).zipWith(op2.f(a), (b1, b2) => b1 && b2)),
96
+ [IOOperatorTag.FilterMapIO]: (op1, op2) =>
97
+ FilterMapIO((a) => op1.f(a).flatMap((b) => (b ? op2.f(a) : IO.succeedNow(Nothing())))),
98
+ },
99
+ [IOOperatorTag.FilterMapIO]: {
100
+ [IOOperatorTag.MapIO]: (op1, op2) =>
101
+ FilterMapIO((a) => op1.f(a).flatMap((mb) => mb.match(() => IO.succeedNow(Nothing()), op2.f))),
102
+ [IOOperatorTag.TapIO]: (op1, op2) =>
103
+ FilterMapIO((a) =>
104
+ op1.f(a).flatMap((mb) =>
105
+ mb.match(
106
+ () => IO.succeedNow(Nothing()),
107
+ (b) => op2.f(b).as(() => a),
108
+ ),
109
+ ),
110
+ ),
111
+ [IOOperatorTag.FilterIO]: (op1, op2) =>
112
+ FilterMapIO((a) =>
113
+ op1.f(a).flatMap((mb) =>
114
+ mb.match(
115
+ () => IO.succeedNow(Nothing()),
116
+ (b) => op2.f(b).map((b2) => (b2 ? Just(b) : Nothing())),
117
+ ),
118
+ ),
119
+ ),
120
+ [IOOperatorTag.FilterMapIO]: (op1, op2) =>
121
+ FilterMapIO((a) =>
122
+ op1.f(a).flatMap((mb) =>
123
+ mb.match(
124
+ () => IO.succeedNow(Nothing()),
125
+ (b) => op2.f(b),
126
+ ),
127
+ ),
128
+ ),
129
+ },
130
+ };
131
+
132
+ /**
133
+ * @tsplus pipeable fncts.io.Push.IOOperator fuse
134
+ */
135
+ export function fuse(that: IOOperator) {
136
+ return (self: IOOperator): IOOperator => {
137
+ return IOOperatorFusionMap[self._tag][that._tag](self as any, that as any);
138
+ };
139
+ }
140
+
141
+ /**
142
+ * @tsplus static fncts.io.Push.IOOperatorOps fromSyncOperator
143
+ */
144
+ export function fromSyncOperator(op: SyncOperator): IOOperator {
145
+ return op.match({
146
+ Map: (op) => MapIO((a) => IO.succeedNow(op.f(a))),
147
+ Filter: (op) => FilterIO((a) => IO.succeedNow(op.f(a))),
148
+ FilterMap: (op) => FilterMapIO((a) => IO.succeedNow(op.f(a))),
149
+ });
150
+ }
151
+
152
+ /**
153
+ * @tsplus pipeable fncts.io.Push.IOOperator match
154
+ */
155
+ export function match<A, B, C, D>(cases: {
156
+ readonly MapIO: (f: MapIO<any, any, any, any>) => A;
157
+ readonly TapIO: (f: TapIO<any, any, any, any>) => B;
158
+ readonly FilterIO: (f: FilterIO<any, any, any>) => C;
159
+ readonly FilterMapIO: (f: FilterMapIO<any, any, any, any>) => D;
160
+ }) {
161
+ return (self: IOOperator): A | B | C | D => {
162
+ switch (self._tag) {
163
+ case IOOperatorTag.MapIO:
164
+ return cases.MapIO(self);
165
+ case IOOperatorTag.TapIO:
166
+ return cases.TapIO(self);
167
+ case IOOperatorTag.FilterIO:
168
+ return cases.FilterIO(self);
169
+ case IOOperatorTag.FilterMapIO:
170
+ return cases.FilterMapIO(self);
171
+ }
172
+ };
173
+ }
@@ -0,0 +1,242 @@
1
+ import type { Bounds } from "../Bounds.js";
2
+ import type { SyncOperator } from "./SyncOperator.js";
3
+
4
+ export const enum SyncLoopOperatorTag {
5
+ Loop = "Loop",
6
+ FilterMapLoop = "FilterMapLoop",
7
+ }
8
+
9
+ /**
10
+ * @tsplus type fncts.io.Push.SyncLoopOperator
11
+ */
12
+ export type SyncLoopOperator<B = any, A = any, C = any> = LoopOperator<B, A, C> | FilterMapLoopOperator<B, A, C>;
13
+
14
+ export interface LoopOperator<B, A, C> {
15
+ readonly _tag: SyncLoopOperatorTag.Loop;
16
+ readonly seed: B;
17
+ readonly f: (acc: B, a: A) => readonly [C, B];
18
+ }
19
+
20
+ export function LoopOperator<const B, A, C>(seed: B, f: (acc: B, a: A) => readonly [C, B]): LoopOperator<B, A, C> {
21
+ return {
22
+ _tag: SyncLoopOperatorTag.Loop,
23
+ seed,
24
+ f,
25
+ };
26
+ }
27
+
28
+ export interface FilterMapLoopOperator<B, A, C> {
29
+ readonly _tag: SyncLoopOperatorTag.FilterMapLoop;
30
+ readonly seed: B;
31
+ readonly f: (acc: B, a: A) => readonly [Maybe<C>, B];
32
+ }
33
+
34
+ export function FilterMapLoopOperator<const B, A, C>(
35
+ seed: B,
36
+ f: (acc: B, a: A) => readonly [Maybe<C>, B],
37
+ ): FilterMapLoopOperator<B, A, C> {
38
+ return {
39
+ _tag: SyncLoopOperatorTag.FilterMapLoop,
40
+ seed,
41
+ f,
42
+ };
43
+ }
44
+
45
+ export const enum SliceOperatorTag {
46
+ SliceOperator,
47
+ FilterMapSliceOperator,
48
+ }
49
+
50
+ export interface SliceOperator {
51
+ readonly _tag: SliceOperatorTag.SliceOperator;
52
+ readonly bounds: Bounds;
53
+ }
54
+
55
+ export function SliceOperator(bounds: Bounds): SliceOperator {
56
+ return {
57
+ _tag: SliceOperatorTag.SliceOperator,
58
+ bounds,
59
+ };
60
+ }
61
+
62
+ export interface FilterMapSliceOperator<A, B, C> {
63
+ readonly _tag: SliceOperatorTag.FilterMapSliceOperator;
64
+ readonly seed: B;
65
+ readonly f: (acc: B, a: A) => Either<readonly [Maybe<C>, B], Maybe<C>>;
66
+ }
67
+
68
+ export function FilterMapSliceOperator<const B, A, C>(
69
+ seed: B,
70
+ f: (acc: B, a: A) => Either<readonly [Maybe<C>, B], Maybe<C>>,
71
+ ): FilterMapSliceOperator<A, B, C> {
72
+ return {
73
+ _tag: SliceOperatorTag.FilterMapSliceOperator,
74
+ seed,
75
+ f,
76
+ };
77
+ }
78
+
79
+ /**
80
+ * @tsplus pipeable fncts.io.Push.SyncLoopOperator match
81
+ */
82
+ export function matchSyncLoopOperator<A, B, C, D, E>(matchers: {
83
+ Loop: (op: LoopOperator<A, B, C>) => D;
84
+ FilterMapLoop: (op: FilterMapLoopOperator<A, B, C>) => E;
85
+ }) {
86
+ return (self: SyncLoopOperator<A, B, C>): D | E => {
87
+ switch (self._tag) {
88
+ case SyncLoopOperatorTag.Loop:
89
+ return matchers.Loop(self);
90
+ case SyncLoopOperatorTag.FilterMapLoop:
91
+ return matchers.FilterMapLoop(self);
92
+ }
93
+ };
94
+ }
95
+
96
+ export function fuseSyncOperatorBefore(that: SyncOperator) {
97
+ return (self: SyncLoopOperator): SyncLoopOperator => {
98
+ return that.match({
99
+ Map: (op) =>
100
+ self.match({
101
+ Loop: (lop) => LoopOperator(lop.seed, (acc, a) => lop.f(acc, op.f(a))),
102
+ FilterMapLoop: (lop) => FilterMapLoopOperator(lop.seed, (acc, a) => lop.f(acc, op.f(a))),
103
+ }),
104
+ Filter: (op) =>
105
+ self.match({
106
+ Loop: (lop) =>
107
+ FilterMapLoopOperator(lop.seed, (acc, a) => {
108
+ const [b, c] = lop.f(acc, a);
109
+ if (op.f(a)) {
110
+ return [Just(b), c];
111
+ } else {
112
+ return [Nothing(), c];
113
+ }
114
+ }),
115
+ FilterMapLoop: (lop) =>
116
+ FilterMapLoopOperator(lop.seed, (acc, a) => {
117
+ if (op.f(a)) {
118
+ return [Nothing(), acc];
119
+ } else {
120
+ return lop.f(acc, a);
121
+ }
122
+ }),
123
+ }),
124
+ FilterMap: (op) =>
125
+ self.match({
126
+ Loop: (lop) =>
127
+ FilterMapLoopOperator(lop.seed, (acc, a) =>
128
+ op.f(a).match(
129
+ () => [Nothing(), acc],
130
+ (x) => {
131
+ const [b, c] = lop.f(acc, x);
132
+ return [Just(b), c];
133
+ },
134
+ ),
135
+ ),
136
+ FilterMapLoop: (lop) =>
137
+ FilterMapLoopOperator(lop.seed, (acc, a) =>
138
+ op.f(a).match(
139
+ () => [Nothing(), acc],
140
+ (x) => lop.f(acc, x.value),
141
+ ),
142
+ ),
143
+ }),
144
+ });
145
+ };
146
+ }
147
+
148
+ export function fuseSyncOperatorAfter(that: SyncOperator) {
149
+ return (self: SyncLoopOperator): SyncLoopOperator =>
150
+ self.match({
151
+ Loop: (lop) =>
152
+ that.match({
153
+ Map: (op) =>
154
+ LoopOperator(lop.seed, (acc, a) => {
155
+ const [b, c] = lop.f(acc, a);
156
+ return [op.f(b), c];
157
+ }),
158
+ Filter: (op) =>
159
+ FilterMapLoopOperator(lop.seed, (acc, a) => {
160
+ const [b, c] = lop.f(acc, a);
161
+ if (op.f(b)) {
162
+ return [Just(b), c];
163
+ } else {
164
+ return [Nothing(), c];
165
+ }
166
+ }),
167
+ FilterMap: (op) =>
168
+ FilterMapLoopOperator(lop.seed, (acc, a) => {
169
+ const [b, c] = lop.f(acc, a);
170
+ return op.f(b).match(
171
+ () => [Nothing(), c],
172
+ (d) => [Just(d), c],
173
+ );
174
+ }),
175
+ }),
176
+ FilterMapLoop: (lop) =>
177
+ that.match({
178
+ Map: (op) =>
179
+ FilterMapLoopOperator(lop.seed, (acc, a) => {
180
+ const [b, c] = lop.f(acc, a);
181
+ return [b.map(op.f), c];
182
+ }),
183
+ Filter: (op) =>
184
+ FilterMapLoopOperator(lop.seed, (acc, a) => {
185
+ const [b, c] = lop.f(acc, a);
186
+ return [b.filter(op.f), c];
187
+ }),
188
+ FilterMap: (op) =>
189
+ FilterMapLoopOperator(lop.seed, (acc, a) => {
190
+ const [b, c] = lop.f(acc, a);
191
+ return [b.flatMap(op.f), c];
192
+ }),
193
+ }),
194
+ });
195
+ }
196
+
197
+ export function fuse<C, D, E>(that: SyncLoopOperator<D, C, E>) {
198
+ return <A, B>(self: SyncLoopOperator<A, B, C>): SyncLoopOperator<readonly [A, D], B, E> => {
199
+ return self.match({
200
+ Loop: (op1) =>
201
+ that.match({
202
+ Loop: (op2) =>
203
+ LoopOperator([op1.seed, op2.seed], ([a, d], b) => {
204
+ const [c, a1] = op1.f(a, b);
205
+ const [e, d1] = op2.f(d, c);
206
+ return [e, [a1, d1]];
207
+ }),
208
+ FilterMapLoop: (op2) =>
209
+ FilterMapLoopOperator([op1.seed, op2.seed], ([a, d], b) => {
210
+ const [c, a1] = op1.f(a, b);
211
+ const [e, d1] = op2.f(d, c);
212
+ return [e, [a1, d1]];
213
+ }),
214
+ }),
215
+ FilterMapLoop: (op1) =>
216
+ that.match({
217
+ Loop: (op2) =>
218
+ FilterMapLoopOperator([op1.seed, op2.seed], ([a, d], b) => {
219
+ const [c, a1] = op1.f(a, b);
220
+ return c.match(
221
+ () => [Nothing(), [a1, d]],
222
+ (c) => {
223
+ const [e, d1] = op2.f(d, c);
224
+ return [Just(e), [a1, d1]];
225
+ },
226
+ );
227
+ }),
228
+ FilterMapLoop: (op2) =>
229
+ FilterMapLoopOperator([op1.seed, op2.seed], ([a, d], b) => {
230
+ const [c, a1] = op1.f(a, b);
231
+ return c.match(
232
+ () => [Nothing(), [a1, d]],
233
+ (c) => {
234
+ const [e, d1] = op2.f(d, c);
235
+ return [e, [a1, d1]];
236
+ },
237
+ );
238
+ }),
239
+ }),
240
+ });
241
+ };
242
+ }
@@ -0,0 +1,107 @@
1
+ export const enum SyncOperatorTag {
2
+ Map = "Map",
3
+ Filter = "Filter",
4
+ FilterMap = "FilterMap",
5
+ }
6
+
7
+ export interface Map<A, B> {
8
+ readonly _tag: SyncOperatorTag.Map;
9
+ readonly f: (a: A) => B;
10
+ }
11
+
12
+ export function Map<A, B>(f: (a: A) => B): Map<A, B> {
13
+ return {
14
+ _tag: SyncOperatorTag.Map,
15
+ f,
16
+ };
17
+ }
18
+
19
+ export interface Filter<A> {
20
+ readonly _tag: SyncOperatorTag.Filter;
21
+ readonly f: Predicate<A>;
22
+ }
23
+
24
+ export function Filter<A>(f: Predicate<A>): Filter<A> {
25
+ return {
26
+ _tag: SyncOperatorTag.Filter,
27
+ f,
28
+ };
29
+ }
30
+
31
+ export interface FilterMap<A, B> {
32
+ readonly _tag: SyncOperatorTag.FilterMap;
33
+ readonly f: (a: A) => Maybe<B>;
34
+ }
35
+
36
+ export function FilterMap<A, B>(f: (a: A) => Maybe<B>): FilterMap<A, B> {
37
+ return {
38
+ _tag: SyncOperatorTag.FilterMap,
39
+ f,
40
+ };
41
+ }
42
+
43
+ /**
44
+ * @tsplus type fncts.io.Push.SyncOperator
45
+ * @tsplus companion fncts.io.Push.SyncOperatorOps
46
+ */
47
+ export type SyncOperator<A = any, B = any> = Map<A, B> | Filter<A> | FilterMap<A, B>;
48
+
49
+ type SyncOperatorFusionMap = {
50
+ readonly [K in SyncOperator["_tag"]]: {
51
+ readonly [K2 in SyncOperator["_tag"]]: (
52
+ op1: Extract<SyncOperator, { readonly _tag: K }>,
53
+ op2: Extract<SyncOperator, { readonly _tag: K2 }>,
54
+ ) => SyncOperator;
55
+ };
56
+ };
57
+
58
+ const SyncOperatorFusionMap: SyncOperatorFusionMap = {
59
+ [SyncOperatorTag.Map]: {
60
+ [SyncOperatorTag.Map]: (op1, op2) => Map(op1.f.compose(op2.f)),
61
+ [SyncOperatorTag.Filter]: (op1, op2) =>
62
+ FilterMap((a) => {
63
+ const b = op1.f(a);
64
+ return op2.f(b) ? Just(b) : Nothing();
65
+ }),
66
+ [SyncOperatorTag.FilterMap]: (op1, op2) => FilterMap(op1.f.compose(op2.f)),
67
+ },
68
+ [SyncOperatorTag.Filter]: {
69
+ [SyncOperatorTag.Map]: (op1, op2) => FilterMap((a) => (op1.f(a) ? Just(op2.f(a)) : Nothing())),
70
+ [SyncOperatorTag.Filter]: (op1, op2) => Filter(op1.f && op2.f),
71
+ [SyncOperatorTag.FilterMap]: (op1, op2) => FilterMap((a) => (op1.f(a) ? op2.f(a) : Nothing())),
72
+ },
73
+ [SyncOperatorTag.FilterMap]: {
74
+ [SyncOperatorTag.Map]: (op1, op2) => FilterMap((a) => op1.f(a).map(op2.f)),
75
+ [SyncOperatorTag.Filter]: (op1, op2) => FilterMap((a) => op1.f(a).filter(op2.f)),
76
+ [SyncOperatorTag.FilterMap]: (op1, op2) => FilterMap((a) => op1.f(a).flatMap(op2.f)),
77
+ },
78
+ };
79
+
80
+ /**
81
+ * @tsplus pipeable fncts.io.Push.SyncOperator fuse
82
+ */
83
+ export function fuse(that: SyncOperator) {
84
+ return (self: SyncOperator) => {
85
+ return SyncOperatorFusionMap[self._tag][that._tag](self as any, that as any);
86
+ };
87
+ }
88
+
89
+ /**
90
+ * @tsplus pipeable fncts.io.Push.SyncOperator match
91
+ */
92
+ export function match<A, B, C, D, E>(cases: {
93
+ readonly Map: (f: Map<A, B>) => C;
94
+ readonly Filter: (f: Filter<A>) => D;
95
+ readonly FilterMap: (f: FilterMap<A, B>) => E;
96
+ }) {
97
+ return (self: SyncOperator<A, B>): C | D | E => {
98
+ switch (self._tag) {
99
+ case SyncOperatorTag.Map:
100
+ return cases.Map(self);
101
+ case SyncOperatorTag.Filter:
102
+ return cases.Filter(self);
103
+ case SyncOperatorTag.FilterMap:
104
+ return cases.FilterMap(self);
105
+ }
106
+ };
107
+ }
@@ -0,0 +1,7 @@
1
+ /* eslint-disable simple-import-sort/exports */
2
+ // codegen:start { preset: type-barrel, include: ./Operator/*.ts }
3
+ export type {} from "./Operator/SyncOperator.js"
4
+ export type {} from "./Operator/LoopOperator.js"
5
+ export type {} from "./Operator/IOOperator.js"
6
+ export type {} from "./Operator/IOLoopOperator.js"
7
+ // codegen:end
@@ -0,0 +1,83 @@
1
+ import type { Push } from "../definition.js";
2
+
3
+ export const enum IOProducerTag {
4
+ FromIO,
5
+ FromScheduled,
6
+ Scheduled,
7
+ }
8
+
9
+ export class FromIO<R, E, A> {
10
+ readonly _tag = IOProducerTag.FromIO;
11
+ constructor(readonly source: IO<R, E, A>) {}
12
+ }
13
+
14
+ export class FromScheduled<R, E, I, R1, O> {
15
+ readonly _tag = IOProducerTag.FromScheduled;
16
+ constructor(
17
+ readonly input: IO<R, E, I>,
18
+ readonly schedule: Schedule<R1, I, O>,
19
+ ) {}
20
+ }
21
+
22
+ export class Scheduled<R, E, A, R1, O> {
23
+ readonly _tag = IOProducerTag.Scheduled;
24
+ constructor(
25
+ readonly input: IO<R, E, A>,
26
+ readonly schedule: Schedule<R1, unknown, O>,
27
+ ) {}
28
+ }
29
+
30
+ /**
31
+ * @tsplus type fncts.io.Push.IOProducer
32
+ * @tsplus companion fncts.io.Push.IOProducerOps
33
+ */
34
+ export type IOProducer<R, E, A> = FromIO<R, E, A> | FromScheduled<R, E, any, any, A> | Scheduled<R, E, A, any, any>;
35
+
36
+ /**
37
+ * @tsplus fluent fncts.io.Push.IOProducer runSink
38
+ */
39
+ export function runSink<R, E, A, R1>(
40
+ self: IOProducer<R, E, A>,
41
+ sink: Push.UnsafeSink<R1, E, A>,
42
+ ): IO<R | R1, never, unknown> {
43
+ switch (self._tag) {
44
+ case IOProducerTag.FromIO:
45
+ return self.source.matchCauseIO(sink.onFailure, sink.onSuccess);
46
+ case IOProducerTag.Scheduled:
47
+ return self.input
48
+ .matchCauseIO(sink.onFailure, sink.onSuccess)
49
+ .schedule(self.schedule)
50
+ .catchAllCause(sink.onFailure);
51
+ case IOProducerTag.FromScheduled:
52
+ return self.input
53
+ .flatMap((i) => self.input.scheduleFrom(() => i, self.schedule.mapIO(sink.onSuccess)))
54
+ .catchAllCause(sink.onFailure);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * @tsplus fluent fncts.io.Push.IOProducer runIO
60
+ */
61
+ export function runIO<R, E, A, R1, E1, A1>(
62
+ self: IOProducer<R, E, A>,
63
+ f: (a: A) => IO<R1, E1, A1>,
64
+ ): IO<R | R1, E | E1, unknown> {
65
+ switch (self._tag) {
66
+ case IOProducerTag.FromIO:
67
+ return self.source.flatMap(f);
68
+ case IOProducerTag.FromScheduled:
69
+ return self.input.flatMap((i) =>
70
+ IO.asyncIO((resume) => {
71
+ const onFailure = (cause: Cause<E | E1>) => IO.succeedNow(resume(IO.failCauseNow(cause)));
72
+ return self.input
73
+ .scheduleFrom(
74
+ () => i,
75
+ self.schedule.mapIO((a) => f(a).catchAllCause(onFailure)),
76
+ )
77
+ .matchCauseIO(onFailure, () => IO.succeedNow(resume(IO.unit))).asUnit;
78
+ }),
79
+ );
80
+ case IOProducerTag.Scheduled:
81
+ return self.input.flatMap(f).schedule(self.schedule);
82
+ }
83
+ }