@fncts/observable 0.0.1

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 (259) hide show
  1. package/Action.d.ts +6 -0
  2. package/AnimationFrameAction.d.ts +11 -0
  3. package/AnimationFrameScheduler.d.ts +6 -0
  4. package/AsyncAction.d.ts +19 -0
  5. package/AsyncScheduler.d.ts +11 -0
  6. package/BehaviorSubject.d.ts +10 -0
  7. package/Notification.d.ts +59 -0
  8. package/Observable/api/connect.d.ts +10 -0
  9. package/Observable/api/connectable.d.ts +24 -0
  10. package/Observable/api/fromCallback.d.ts +11 -0
  11. package/Observable/api/fromEvent.d.ts +4 -0
  12. package/Observable/api/index.d.ts +14 -0
  13. package/Observable/api/race.d.ts +9 -0
  14. package/Observable/api/raceWith.d.ts +6 -0
  15. package/Observable/api/repeatWhen.d.ts +5 -0
  16. package/Observable/api/retryWhen.d.ts +10 -0
  17. package/Observable/api/share.d.ts +16 -0
  18. package/Observable/api/window.d.ts +8 -0
  19. package/Observable/api/windowCount.d.ts +6 -0
  20. package/Observable/api/windowTime.d.ts +12 -0
  21. package/Observable/api/windowToggle.d.ts +8 -0
  22. package/Observable/api/windowWhen.d.ts +9 -0
  23. package/Observable/api.d.ts +668 -0
  24. package/Observable/definition.d.ts +32 -0
  25. package/Observable/dom/animationFrames.d.ts +6 -0
  26. package/Observable/instances.d.ts +1 -0
  27. package/Observable.d.ts +19 -0
  28. package/Observer.d.ts +6 -0
  29. package/Operator.d.ts +19 -0
  30. package/Scheduler.d.ts +22 -0
  31. package/Subject.d.ts +48 -0
  32. package/Subscriber.d.ts +27 -0
  33. package/Subscription.d.ts +41 -0
  34. package/_cjs/Action.cjs +27 -0
  35. package/_cjs/Action.cjs.map +1 -0
  36. package/_cjs/AnimationFrameAction.cjs +48 -0
  37. package/_cjs/AnimationFrameAction.cjs.map +1 -0
  38. package/_cjs/AnimationFrameScheduler.cjs +51 -0
  39. package/_cjs/AnimationFrameScheduler.cjs.map +1 -0
  40. package/_cjs/AsyncAction.cjs +116 -0
  41. package/_cjs/AsyncAction.cjs.map +1 -0
  42. package/_cjs/AsyncScheduler.cjs +61 -0
  43. package/_cjs/AsyncScheduler.cjs.map +1 -0
  44. package/_cjs/BehaviorSubject.cjs +52 -0
  45. package/_cjs/BehaviorSubject.cjs.map +1 -0
  46. package/_cjs/Notification.cjs +110 -0
  47. package/_cjs/Notification.cjs.map +1 -0
  48. package/_cjs/Observable/api/connect.cjs +35 -0
  49. package/_cjs/Observable/api/connect.cjs.map +1 -0
  50. package/_cjs/Observable/api/connectable.cjs +64 -0
  51. package/_cjs/Observable/api/connectable.cjs.map +1 -0
  52. package/_cjs/Observable/api/fromCallback.cjs +74 -0
  53. package/_cjs/Observable/api/fromCallback.cjs.map +1 -0
  54. package/_cjs/Observable/api/fromEvent.cjs +22 -0
  55. package/_cjs/Observable/api/fromEvent.cjs.map +1 -0
  56. package/_cjs/Observable/api/index.cjs +188 -0
  57. package/_cjs/Observable/api/index.cjs.map +1 -0
  58. package/_cjs/Observable/api/race.cjs +47 -0
  59. package/_cjs/Observable/api/race.cjs.map +1 -0
  60. package/_cjs/Observable/api/raceWith.cjs +24 -0
  61. package/_cjs/Observable/api/raceWith.cjs.map +1 -0
  62. package/_cjs/Observable/api/repeatWhen.cjs +72 -0
  63. package/_cjs/Observable/api/repeatWhen.cjs.map +1 -0
  64. package/_cjs/Observable/api/retryWhen.cjs +61 -0
  65. package/_cjs/Observable/api/retryWhen.cjs.map +1 -0
  66. package/_cjs/Observable/api/share.cjs +115 -0
  67. package/_cjs/Observable/api/share.cjs.map +1 -0
  68. package/_cjs/Observable/api/window.cjs +53 -0
  69. package/_cjs/Observable/api/window.cjs.map +1 -0
  70. package/_cjs/Observable/api/windowCount.cjs +62 -0
  71. package/_cjs/Observable/api/windowCount.cjs.map +1 -0
  72. package/_cjs/Observable/api/windowTime.cjs +90 -0
  73. package/_cjs/Observable/api/windowTime.cjs.map +1 -0
  74. package/_cjs/Observable/api/windowToggle.cjs +92 -0
  75. package/_cjs/Observable/api/windowToggle.cjs.map +1 -0
  76. package/_cjs/Observable/api/windowWhen.cjs +68 -0
  77. package/_cjs/Observable/api/windowWhen.cjs.map +1 -0
  78. package/_cjs/Observable/api.cjs +2558 -0
  79. package/_cjs/Observable/api.cjs.map +1 -0
  80. package/_cjs/Observable/definition.cjs +76 -0
  81. package/_cjs/Observable/definition.cjs.map +1 -0
  82. package/_cjs/Observable/dom/animationFrames.cjs +51 -0
  83. package/_cjs/Observable/dom/animationFrames.cjs.map +1 -0
  84. package/_cjs/Observable/instances.cjs +6 -0
  85. package/_cjs/Observable/instances.cjs.map +1 -0
  86. package/_cjs/Observable.cjs +253 -0
  87. package/_cjs/Observable.cjs.map +1 -0
  88. package/_cjs/Observer.cjs +6 -0
  89. package/_cjs/Observer.cjs.map +1 -0
  90. package/_cjs/Operator.cjs +83 -0
  91. package/_cjs/Operator.cjs.map +1 -0
  92. package/_cjs/Scheduler.cjs +62 -0
  93. package/_cjs/Scheduler.cjs.map +1 -0
  94. package/_cjs/Subject.cjs +228 -0
  95. package/_cjs/Subject.cjs.map +1 -0
  96. package/_cjs/Subscriber.cjs +172 -0
  97. package/_cjs/Subscriber.cjs.map +1 -0
  98. package/_cjs/Subscription.cjs +174 -0
  99. package/_cjs/Subscription.cjs.map +1 -0
  100. package/_cjs/demo.cjs +40 -0
  101. package/_cjs/demo.cjs.map +1 -0
  102. package/_cjs/global.cjs +4 -0
  103. package/_cjs/global.cjs.map +1 -0
  104. package/_cjs/index.cjs +65 -0
  105. package/_cjs/index.cjs.map +1 -0
  106. package/_cjs/internal/animationFrameProvider.cjs +51 -0
  107. package/_cjs/internal/animationFrameProvider.cjs.map +1 -0
  108. package/_cjs/internal/args.cjs +26 -0
  109. package/_cjs/internal/args.cjs.map +1 -0
  110. package/_cjs/internal/intervalProvider.cjs +27 -0
  111. package/_cjs/internal/intervalProvider.cjs.map +1 -0
  112. package/_cjs/internal/performanceTimestampProvider.cjs +15 -0
  113. package/_cjs/internal/performanceTimestampProvider.cjs.map +1 -0
  114. package/_cjs/internal/timeoutProvider.cjs +27 -0
  115. package/_cjs/internal/timeoutProvider.cjs.map +1 -0
  116. package/_cjs/internal/timestampProvider.cjs +15 -0
  117. package/_cjs/internal/timestampProvider.cjs.map +1 -0
  118. package/_cjs/internal/util.cjs +107 -0
  119. package/_cjs/internal/util.cjs.map +1 -0
  120. package/_mjs/Action.mjs +14 -0
  121. package/_mjs/Action.mjs.map +1 -0
  122. package/_mjs/AnimationFrameAction.mjs +33 -0
  123. package/_mjs/AnimationFrameAction.mjs.map +1 -0
  124. package/_mjs/AnimationFrameScheduler.mjs +36 -0
  125. package/_mjs/AnimationFrameScheduler.mjs.map +1 -0
  126. package/_mjs/AsyncAction.mjs +99 -0
  127. package/_mjs/AsyncAction.mjs.map +1 -0
  128. package/_mjs/AsyncScheduler.mjs +45 -0
  129. package/_mjs/AsyncScheduler.mjs.map +1 -0
  130. package/_mjs/BehaviorSubject.mjs +38 -0
  131. package/_mjs/BehaviorSubject.mjs.map +1 -0
  132. package/_mjs/Notification.mjs +80 -0
  133. package/_mjs/Notification.mjs.map +1 -0
  134. package/_mjs/Observable/api/connect.mjs +21 -0
  135. package/_mjs/Observable/api/connect.mjs.map +1 -0
  136. package/_mjs/Observable/api/connectable.mjs +45 -0
  137. package/_mjs/Observable/api/connectable.mjs.map +1 -0
  138. package/_mjs/Observable/api/fromCallback.mjs +60 -0
  139. package/_mjs/Observable/api/fromCallback.mjs.map +1 -0
  140. package/_mjs/Observable/api/fromEvent.mjs +10 -0
  141. package/_mjs/Observable/api/fromEvent.mjs.map +1 -0
  142. package/_mjs/Observable/api/index.mjs +15 -0
  143. package/_mjs/Observable/api/index.mjs.map +1 -0
  144. package/_mjs/Observable/api/race.mjs +32 -0
  145. package/_mjs/Observable/api/race.mjs.map +1 -0
  146. package/_mjs/Observable/api/raceWith.mjs +12 -0
  147. package/_mjs/Observable/api/raceWith.mjs.map +1 -0
  148. package/_mjs/Observable/api/repeatWhen.mjs +57 -0
  149. package/_mjs/Observable/api/repeatWhen.mjs.map +1 -0
  150. package/_mjs/Observable/api/retryWhen.mjs +45 -0
  151. package/_mjs/Observable/api/retryWhen.mjs.map +1 -0
  152. package/_mjs/Observable/api/share.mjs +97 -0
  153. package/_mjs/Observable/api/share.mjs.map +1 -0
  154. package/_mjs/Observable/api/window.mjs +40 -0
  155. package/_mjs/Observable/api/window.mjs.map +1 -0
  156. package/_mjs/Observable/api/windowCount.mjs +50 -0
  157. package/_mjs/Observable/api/windowCount.mjs.map +1 -0
  158. package/_mjs/Observable/api/windowTime.mjs +73 -0
  159. package/_mjs/Observable/api/windowTime.mjs.map +1 -0
  160. package/_mjs/Observable/api/windowToggle.mjs +77 -0
  161. package/_mjs/Observable/api/windowToggle.mjs.map +1 -0
  162. package/_mjs/Observable/api/windowWhen.mjs +54 -0
  163. package/_mjs/Observable/api/windowWhen.mjs.map +1 -0
  164. package/_mjs/Observable/api.mjs +2291 -0
  165. package/_mjs/Observable/api.mjs.map +1 -0
  166. package/_mjs/Observable/definition.mjs +54 -0
  167. package/_mjs/Observable/definition.mjs.map +1 -0
  168. package/_mjs/Observable/dom/animationFrames.mjs +36 -0
  169. package/_mjs/Observable/dom/animationFrames.mjs.map +1 -0
  170. package/_mjs/Observable/instances.mjs +2 -0
  171. package/_mjs/Observable/instances.mjs.map +1 -0
  172. package/_mjs/Observable.mjs +25 -0
  173. package/_mjs/Observable.mjs.map +1 -0
  174. package/_mjs/Observer.mjs +2 -0
  175. package/_mjs/Observer.mjs.map +1 -0
  176. package/_mjs/Operator.mjs +63 -0
  177. package/_mjs/Operator.mjs.map +1 -0
  178. package/_mjs/Scheduler.mjs +41 -0
  179. package/_mjs/Scheduler.mjs.map +1 -0
  180. package/_mjs/Subject.mjs +204 -0
  181. package/_mjs/Subject.mjs.map +1 -0
  182. package/_mjs/Subscriber.mjs +147 -0
  183. package/_mjs/Subscriber.mjs.map +1 -0
  184. package/_mjs/Subscription.mjs +148 -0
  185. package/_mjs/Subscription.mjs.map +1 -0
  186. package/_mjs/demo.mjs +30 -0
  187. package/_mjs/demo.mjs.map +1 -0
  188. package/_mjs/global.mjs +2 -0
  189. package/_mjs/global.mjs.map +1 -0
  190. package/_mjs/index.mjs +15 -0
  191. package/_mjs/index.mjs.map +1 -0
  192. package/_mjs/internal/animationFrameProvider.mjs +38 -0
  193. package/_mjs/internal/animationFrameProvider.mjs.map +1 -0
  194. package/_mjs/internal/args.mjs +13 -0
  195. package/_mjs/internal/args.mjs.map +1 -0
  196. package/_mjs/internal/intervalProvider.mjs +20 -0
  197. package/_mjs/internal/intervalProvider.mjs.map +1 -0
  198. package/_mjs/internal/performanceTimestampProvider.mjs +8 -0
  199. package/_mjs/internal/performanceTimestampProvider.mjs.map +1 -0
  200. package/_mjs/internal/timeoutProvider.mjs +20 -0
  201. package/_mjs/internal/timeoutProvider.mjs.map +1 -0
  202. package/_mjs/internal/timestampProvider.mjs +8 -0
  203. package/_mjs/internal/timestampProvider.mjs.map +1 -0
  204. package/_mjs/internal/util.mjs +76 -0
  205. package/_mjs/internal/util.mjs.map +1 -0
  206. package/_src/Action.ts +10 -0
  207. package/_src/AnimationFrameAction.ts +27 -0
  208. package/_src/AnimationFrameScheduler.ts +30 -0
  209. package/_src/AsyncAction.ts +93 -0
  210. package/_src/AsyncScheduler.ts +41 -0
  211. package/_src/BehaviorSubject.ts +28 -0
  212. package/_src/Notification.ts +91 -0
  213. package/_src/Observable/api/connect.ts +23 -0
  214. package/_src/Observable/api/connectable.ts +52 -0
  215. package/_src/Observable/api/fromCallback.ts +57 -0
  216. package/_src/Observable/api/fromEvent.ts +12 -0
  217. package/_src/Observable/api/index.ts +14 -0
  218. package/_src/Observable/api/race.ts +31 -0
  219. package/_src/Observable/api/raceWith.ts +15 -0
  220. package/_src/Observable/api/repeatWhen.ts +63 -0
  221. package/_src/Observable/api/retryWhen.ts +47 -0
  222. package/_src/Observable/api/share.ts +107 -0
  223. package/_src/Observable/api/window.ts +44 -0
  224. package/_src/Observable/api/windowCount.ts +56 -0
  225. package/_src/Observable/api/windowTime.ts +102 -0
  226. package/_src/Observable/api/windowToggle.ts +84 -0
  227. package/_src/Observable/api/windowWhen.ts +59 -0
  228. package/_src/Observable/api.ts +2749 -0
  229. package/_src/Observable/definition.ts +69 -0
  230. package/_src/Observable/dom/animationFrames.ts +33 -0
  231. package/_src/Observable/instances.ts +106 -0
  232. package/_src/Observable.ts +27 -0
  233. package/_src/Observer.ts +5 -0
  234. package/_src/Operator.ts +73 -0
  235. package/_src/Scheduler.ts +52 -0
  236. package/_src/Subject.ts +171 -0
  237. package/_src/Subscriber.ts +130 -0
  238. package/_src/Subscription.ts +143 -0
  239. package/_src/demo.ts +29 -0
  240. package/_src/global.ts +141 -0
  241. package/_src/index.ts +14 -0
  242. package/_src/internal/animationFrameProvider.ts +37 -0
  243. package/_src/internal/args.ts +11 -0
  244. package/_src/internal/intervalProvider.ts +27 -0
  245. package/_src/internal/performanceTimestampProvider.ts +12 -0
  246. package/_src/internal/timeoutProvider.ts +27 -0
  247. package/_src/internal/timestampProvider.ts +14 -0
  248. package/_src/internal/util.ts +94 -0
  249. package/demo.d.ts +1 -0
  250. package/global.d.ts +125 -0
  251. package/index.d.ts +14 -0
  252. package/internal/animationFrameProvider.d.ts +12 -0
  253. package/internal/args.d.ts +3 -0
  254. package/internal/intervalProvider.d.ts +12 -0
  255. package/internal/performanceTimestampProvider.d.ts +6 -0
  256. package/internal/timeoutProvider.d.ts +12 -0
  257. package/internal/timestampProvider.d.ts +7 -0
  258. package/internal/util.d.ts +28 -0
  259. package/package.json +16 -0
@@ -0,0 +1,2749 @@
1
+ import { popNumber } from "@fncts/observable/internal/args";
2
+ import { arrayOrObject, arrayRemove, readableStreamToAsyncGenerator } from "@fncts/observable/internal/util";
3
+ import { Notification } from "@fncts/observable/Notification";
4
+ import { EMPTY } from "@fncts/observable/Observable/definition";
5
+ import { caughtSchedule } from "@fncts/observable/Scheduler";
6
+
7
+ export interface Subscribable<E, A> {
8
+ subscribe(observer: Partial<Observer<E, A>>): Unsubscribable;
9
+ }
10
+
11
+ export type ObservableInput<E = never, A = never> =
12
+ | Observable<E, A>
13
+ | Subscribable<E, A>
14
+ | AsyncIterable<A>
15
+ | PromiseLike<A>
16
+ | ArrayLike<A>
17
+ | Iterable<A>
18
+ | ReadableStreamLike<A>
19
+ | IO<IOEnv, E, A>;
20
+
21
+ /*
22
+ * -------------------------------------------------------------------------------------------------
23
+ * constructors
24
+ * -------------------------------------------------------------------------------------------------
25
+ */
26
+
27
+ /**
28
+ * @tsplus static fncts.observable.ObservableOps halt
29
+ */
30
+ export function halt(defect: unknown): Observable<never, never> {
31
+ return new Observable((s) => s.error(Cause.halt(defect)));
32
+ }
33
+
34
+ /**
35
+ * @tsplus static fncts.observable.ObservableOps defer
36
+ */
37
+ export function defer<E, A>(observable: Lazy<ObservableInput<E, A>>): Observable<E, A> {
38
+ return new Observable((s) => {
39
+ from(observable()).subscribe(s);
40
+ });
41
+ }
42
+
43
+ /**
44
+ * @tsplus static fncts.observable.ObservableOps empty
45
+ */
46
+ export function empty<A>(): Observable<never, A> {
47
+ return EMPTY;
48
+ }
49
+
50
+ /**
51
+ * @tsplus static fncts.observable.ObservableOps failCause
52
+ */
53
+ export function failCause<E>(cause: Cause<E>): Observable<E, never> {
54
+ return new Observable((s) => s.error(cause));
55
+ }
56
+
57
+ /**
58
+ * @tsplus static fncts.observable.ObservableOps fail
59
+ */
60
+ export function fail<E>(e: E): Observable<E, never> {
61
+ return new Observable((s) => s.error(Cause.fail(e)));
62
+ }
63
+
64
+ /**
65
+ * @tsplus static fncts.observable.ObservableOps from
66
+ */
67
+ export function from<E = never, A = never>(input: ObservableInput<E, A>): Observable<E, A> {
68
+ if (input instanceof Observable) {
69
+ return input;
70
+ }
71
+ if (isArrayLike(input)) {
72
+ return fromArrayLike(input);
73
+ }
74
+ if (isPromiseLike(input)) {
75
+ return fromPromise(input);
76
+ }
77
+ if (isAsyncIterable(input)) {
78
+ return fromAsyncIterable(input);
79
+ }
80
+ if (isIterable(input)) {
81
+ return fromIterable(input);
82
+ }
83
+ if (isReadableStream(input)) {
84
+ return fromReadableStreamLike(input);
85
+ }
86
+ if (isIO(input)) {
87
+ return fromIO(input);
88
+ }
89
+ if ("subscribe" in input) {
90
+ return fromSubscribable(input);
91
+ }
92
+ throw new TypeError("Invalid Observable input");
93
+ }
94
+
95
+ export function fromArrayLike<A>(input: ArrayLike<A>): Observable<never, A> {
96
+ return new Observable((s) => {
97
+ for (let i = 0; i < input.length && !s.closed; i++) {
98
+ s.next(input[i]!);
99
+ }
100
+ s.complete();
101
+ });
102
+ }
103
+
104
+ export function fromAsyncIterable<A>(asyncIterable: AsyncIterable<A>): Observable<never, A> {
105
+ return new Observable((s) => {
106
+ process(asyncIterable, s).catch((err) => s.error(Cause.halt(err)));
107
+ });
108
+ }
109
+
110
+ export function fromIterable<A>(iterable: Iterable<A>): Observable<never, A> {
111
+ return new Observable((s) => {
112
+ for (const value of iterable) {
113
+ s.next(value);
114
+ if (s.closed) {
115
+ return;
116
+ }
117
+ }
118
+ s.complete();
119
+ });
120
+ }
121
+
122
+ export function fromPromise<A>(promise: PromiseLike<A>): Observable<never, A> {
123
+ return new Observable((s) => {
124
+ promise
125
+ .then(
126
+ (value) => {
127
+ if (!s.closed) {
128
+ s.next(value);
129
+ s.complete();
130
+ }
131
+ },
132
+ (err) => s.error(Cause.halt(err)),
133
+ )
134
+ .then(null, reportUnhandledError);
135
+ });
136
+ }
137
+
138
+ export function fromReadableStreamLike<A>(readableStream: ReadableStreamLike<A>): Observable<never, A> {
139
+ return fromAsyncIterable(readableStreamToAsyncGenerator(readableStream));
140
+ }
141
+
142
+ /**
143
+ * @tsplus static fncts.observable.ObservableOps fromSubscribable
144
+ */
145
+ export function fromSubscribable<E, A>(subscribable: Subscribable<E, A>): Observable<E, A> {
146
+ return new Observable((subscriber) => subscribable.subscribe(subscriber));
147
+ }
148
+
149
+ export function fromInterop<A>(subscribable: {
150
+ subscribe: (observer: {
151
+ next: (value: A) => void;
152
+ error: (err: unknown) => void;
153
+ complete: () => void;
154
+ }) => Unsubscribable;
155
+ }): Observable<unknown, A> {
156
+ return new Observable((subscriber) =>
157
+ subscribable.subscribe({
158
+ next: (value) => subscriber.next(value),
159
+ error: (err) => subscriber.error(Cause.halt(err)),
160
+ complete: () => subscriber.complete(),
161
+ }),
162
+ );
163
+ }
164
+
165
+ function _if<E, A, E1, B>(
166
+ condition: () => boolean,
167
+ onTrue: ObservableInput<E, A>,
168
+ onFalse: ObservableInput<E1, B>,
169
+ ): Observable<E | E1, A | B> {
170
+ return defer<E | E1, A | B>(() => (condition() ? onTrue : onFalse));
171
+ }
172
+
173
+ export { _if as if };
174
+
175
+ export interface IterateOptions<S> {
176
+ readonly initialState: S;
177
+ readonly cont?: (state: S) => boolean;
178
+ readonly iterate: (state: S) => S;
179
+ readonly scheduler?: SchedulerLike;
180
+ }
181
+
182
+ export function iterate<S>(options: IterateOptions<S>): Observable<never, S> {
183
+ const { initialState, cont, iterate, scheduler } = options;
184
+
185
+ function* gen() {
186
+ for (let state = initialState; !cont || cont(state); state = iterate(state)) {
187
+ yield state;
188
+ }
189
+ }
190
+
191
+ return defer(scheduler ? () => scheduleIterable(gen(), scheduler!) : gen);
192
+ }
193
+
194
+ async function process<A>(asyncIterable: AsyncIterable<A>, subscriber: Subscriber<never, A>) {
195
+ for await (const value of asyncIterable) {
196
+ subscriber.next(value);
197
+ if (subscriber.closed) {
198
+ return;
199
+ }
200
+ }
201
+ subscriber.complete();
202
+ }
203
+
204
+ /**
205
+ * @tsplus static fncts.obervable.ObservableOps interval
206
+ */
207
+ export function interval(period = 0, scheduler: SchedulerLike = asyncScheduler): Observable<never, number> {
208
+ if (period < 0) {
209
+ // eslint-disable-next-line no-param-reassign
210
+ period = 0;
211
+ }
212
+
213
+ return timer(period, period, scheduler);
214
+ }
215
+
216
+ /**
217
+ * @tsplus static fncts.obervable.ObservableOps merge
218
+ */
219
+ export function merge<O extends ReadonlyArray<ObservableInput<any, any>>>(
220
+ ...sources: O
221
+ ): Observable<Observable.ErrorOf<O[number]>, Observable.TypeOf<O[number]>>;
222
+ export function merge<O extends ReadonlyArray<ObservableInput<any, any>>>(
223
+ ...sources: [...O, number?]
224
+ ): Observable<Observable.ErrorOf<O[number]>, Observable.TypeOf<O[number]>>;
225
+ export function merge<O extends ReadonlyArray<ObservableInput<any, any>>>(
226
+ ...sources: [...O, number?]
227
+ ): Observable<Observable.ErrorOf<O[number]>, Observable.TypeOf<O[number]>> {
228
+ const concurrency = popNumber(sources, Infinity);
229
+ return !sources.length
230
+ ? empty()
231
+ : sources.length === 1
232
+ ? from(sources[0] as ObservableInput<any, any>)
233
+ : mergeAll_(fromArrayLike(sources as ReadonlyArray<ObservableInput<any, any>>), concurrency);
234
+ }
235
+
236
+ /**
237
+ * @tsplus static fncts.observable.ObservableOps of
238
+ */
239
+ export function of<A>(...items: ReadonlyArray<A>): Observable<never, A> {
240
+ return fromArrayLike(items);
241
+ }
242
+
243
+ /**
244
+ * @tsplus static fncts.observable.ObservableOps single
245
+ */
246
+ export function single<A>(a: A): Observable<never, A> {
247
+ return new Observable((s) => {
248
+ s.next(a);
249
+ s.complete();
250
+ });
251
+ }
252
+
253
+ /**
254
+ * @tsplus fluent fncts.observable.Observable scheduled
255
+ * @tsplus static fncts.observable.ObservableOps scheduled
256
+ */
257
+ export function scheduled<E, A>(input: ObservableInput<E, A>, scheduler: SchedulerLike): Observable<E, A> {
258
+ if (isArrayLike(input)) {
259
+ return scheduleArray(input, scheduler);
260
+ }
261
+ if (isPromiseLike(input)) {
262
+ return schedulePromise(input, scheduler);
263
+ }
264
+ if (isIterable(input)) {
265
+ return scheduleIterable(input, scheduler);
266
+ }
267
+ if (isAsyncIterable(input)) {
268
+ return scheduleAsyncIterable(input, scheduler);
269
+ }
270
+ if (isReadableStream(input)) {
271
+ return scheduleReadableStreamLike(input, scheduler);
272
+ }
273
+ return scheduleObservable(from(input), scheduler);
274
+ }
275
+
276
+ export function scheduleArray<A>(input: ArrayLike<A>, scheduler: SchedulerLike): Observable<never, A> {
277
+ return new Observable<never, A>((s) => {
278
+ let i = 0;
279
+ return scheduler.schedule(function () {
280
+ if (i === input.length) {
281
+ s.complete();
282
+ } else {
283
+ s.next(input[i++]!);
284
+ if (!s.closed) {
285
+ this.schedule();
286
+ }
287
+ }
288
+ });
289
+ });
290
+ }
291
+
292
+ export function scheduleAsyncIterable<A>(input: AsyncIterable<A>, scheduler: SchedulerLike): Observable<never, A> {
293
+ return new Observable((subscriber) => {
294
+ const sub = new Subscription();
295
+ sub.add(
296
+ scheduler.schedule(() => {
297
+ const iterator = input[Symbol.asyncIterator]();
298
+ sub.add(
299
+ scheduler.schedule(function () {
300
+ iterator.next().then((result) => {
301
+ if (result.done) {
302
+ subscriber.complete();
303
+ } else {
304
+ subscriber.next(result.value);
305
+ this.schedule();
306
+ }
307
+ });
308
+ }),
309
+ );
310
+ }),
311
+ );
312
+ return sub;
313
+ });
314
+ }
315
+
316
+ export function scheduleIterable<A>(input: Iterable<A>, scheduler: SchedulerLike): Observable<never, A> {
317
+ return new Observable((s) => {
318
+ let iterator: Iterator<A, A>;
319
+ s.add(
320
+ scheduler.schedule(() => {
321
+ iterator = input[Symbol.iterator]();
322
+ caughtSchedule(s, scheduler, function () {
323
+ const { value, done } = iterator.next();
324
+ if (done) {
325
+ s.complete();
326
+ } else {
327
+ s.next(value);
328
+ this.schedule();
329
+ }
330
+ });
331
+ }),
332
+ );
333
+
334
+ return () => isFunction(iterator?.return) && iterator.return();
335
+ });
336
+ }
337
+
338
+ export function scheduleObservable<E, A>(input: Observable<E, A>, scheduler: SchedulerLike): Observable<E, A> {
339
+ return new Observable((subscriber) => {
340
+ const sub = new Subscription();
341
+ sub.add(
342
+ scheduler.schedule(() => {
343
+ sub.add(
344
+ input.subscribe({
345
+ next: (value) => {
346
+ sub.add(scheduler.schedule(() => subscriber.next(value)));
347
+ },
348
+ error: (err) => {
349
+ sub.add(scheduler.schedule(() => subscriber.error(err)));
350
+ },
351
+ complete: () => {
352
+ sub.add(scheduler.schedule(() => subscriber.complete()));
353
+ },
354
+ }),
355
+ );
356
+ }),
357
+ );
358
+ });
359
+ }
360
+
361
+ export function schedulePromise<A>(input: PromiseLike<A>, scheduler: SchedulerLike): Observable<never, A> {
362
+ return new Observable((subscriber) => {
363
+ return scheduler.schedule(() => {
364
+ input.then(
365
+ (value) => {
366
+ subscriber.add(
367
+ scheduler.schedule(() => {
368
+ subscriber.next(value);
369
+ subscriber.add(scheduler.schedule(() => subscriber.complete()));
370
+ }),
371
+ );
372
+ },
373
+ (err) => {
374
+ subscriber.add(scheduler.schedule(() => subscriber.error(Cause.halt(err))));
375
+ },
376
+ );
377
+ });
378
+ });
379
+ }
380
+
381
+ export function scheduleReadableStreamLike<A>(
382
+ input: ReadableStreamLike<A>,
383
+ scheduler: SchedulerLike,
384
+ ): Observable<never, A> {
385
+ return scheduleAsyncIterable(readableStreamToAsyncGenerator(input), scheduler);
386
+ }
387
+
388
+ /**
389
+ * @tsplus static fncts.observable.ObservableOps timer
390
+ */
391
+ export function timer(time: number | Date, interval?: number, scheduler?: SchedulerLike): Observable<never, number>;
392
+ export function timer(time: number | Date, scheduler?: SchedulerLike): Observable<never, number>;
393
+ export function timer(
394
+ time: number | Date = 0,
395
+ intervalOrScheduler?: number | SchedulerLike,
396
+ scheduler: SchedulerLike = asyncScheduler,
397
+ ): Observable<never, number> {
398
+ let intervalDuration = -1;
399
+ if (intervalOrScheduler != null) {
400
+ if (isScheduler(intervalOrScheduler)) {
401
+ // eslint-disable-next-line no-param-reassign
402
+ scheduler = intervalOrScheduler;
403
+ } else {
404
+ intervalDuration = intervalOrScheduler as number;
405
+ }
406
+ }
407
+ return new Observable((s) => {
408
+ let due = isValidDate(time) ? +time - scheduler.now() : time;
409
+ if (due < 0) {
410
+ due = 0;
411
+ }
412
+ let n = 0;
413
+ return scheduler.schedule(function () {
414
+ if (!s.closed) {
415
+ s.next(n++);
416
+ if (0 <= intervalDuration) {
417
+ this.schedule(undefined, intervalDuration);
418
+ } else {
419
+ s.complete();
420
+ }
421
+ }
422
+ }, due);
423
+ });
424
+ }
425
+
426
+ /**
427
+ * @tsplus static fncts.observable.ObservableOps zip
428
+ */
429
+ export function makeZip<O extends ReadonlyArray<ObservableInput<any, any>>>(
430
+ ...sources: O
431
+ ): Observable<Observable.ErrorOf<O[number]>, { [K in keyof O]: Observable.TypeOf<O[K]> }> {
432
+ return sources.length
433
+ ? new Observable((subscriber) => {
434
+ let buffers: unknown[][] = sources.map(() => []);
435
+ let completed = sources.map(() => false);
436
+ subscriber.add(() => {
437
+ buffers = completed = null!;
438
+ });
439
+ for (let sourceIndex = 0; !subscriber.closed && sourceIndex < sources.length; sourceIndex++) {
440
+ from(sources[sourceIndex]!).subscribe(
441
+ operatorSubscriber(subscriber, {
442
+ next: (value) => {
443
+ buffers[sourceIndex]!.push(value);
444
+ if (buffers.every((buffer) => buffer.length)) {
445
+ const result: any = buffers.map((buffer) => buffer.shift()!);
446
+ subscriber.next(result);
447
+ if (buffers.some((buffer, i) => !buffer.length && completed[i])) {
448
+ subscriber.complete();
449
+ }
450
+ }
451
+ },
452
+ complete: () => {
453
+ completed[sourceIndex] = true;
454
+ !buffers[sourceIndex]!.length && subscriber.complete();
455
+ },
456
+ }),
457
+ );
458
+ }
459
+ return () => {
460
+ buffers = completed = null!;
461
+ };
462
+ })
463
+ : empty();
464
+ }
465
+
466
+ /**
467
+ * @tsplus static fncts.observable.ObservableOps fromIO
468
+ */
469
+ export function fromIO<E, A>(io: IO<unknown, E, A>, scheduler: SchedulerLike = asyncScheduler): Observable<E, A> {
470
+ return new Observable((s) => {
471
+ let fiber: FiberContext<E, A>;
472
+ const scheduled = scheduler.schedule(() => {
473
+ fiber = io.unsafeRunFiber();
474
+ fiber.unsafeOnDone((exit) => {
475
+ if (!s.closed) {
476
+ exit.flatten.match(
477
+ (cause) => s.error(cause),
478
+ (a) => s.next(a),
479
+ );
480
+ s.complete();
481
+ }
482
+ });
483
+ });
484
+ return () => {
485
+ scheduled.unsubscribe();
486
+ fiber && fiber.interrupt.unsafeRunAsync();
487
+ };
488
+ });
489
+ }
490
+
491
+ /*
492
+ * -------------------------------------------------------------------------------------------------
493
+ * Applicative
494
+ * -------------------------------------------------------------------------------------------------
495
+ */
496
+
497
+ /**
498
+ * @tsplus static fncts.observable.ObservableOps unit
499
+ */
500
+ export const unit: Observable<never, void> = Observable.single(undefined);
501
+
502
+ /*
503
+ * -------------------------------------------------------------------------------------------------
504
+ * Apply
505
+ * -------------------------------------------------------------------------------------------------
506
+ */
507
+
508
+ /**
509
+ * @tsplus fluent fncts.observable.Observable zipWith
510
+ */
511
+ export function zipWith<E, A, E1, B, C>(
512
+ fa: Observable<E, A>,
513
+ fb: Observable<E1, B>,
514
+ f: (a: A, b: B) => C,
515
+ ): Observable<E | E1, C> {
516
+ return fa.mergeMap((a) => fb.map((b) => f(a, b)));
517
+ }
518
+
519
+ /**
520
+ * @tsplus fluent fncts.observable.Observable zip
521
+ */
522
+ export function zip<E, A, E1, B>(fa: Observable<E, A>, fb: Observable<E1, B>): Observable<E | E1, readonly [A, B]> {
523
+ return zipWith(fa, fb, Function.tuple);
524
+ }
525
+
526
+ /**
527
+ * @tsplus fluent fncts.observable.Observable ap
528
+ */
529
+ export function ap<E, A, E1, B>(fab: Observable<E, (a: A) => B>, fa: Observable<E1, A>): Observable<E | E1, B> {
530
+ return zipWith(fab, fa, (f, a) => f(a));
531
+ }
532
+
533
+ /*
534
+ * -------------------------------------------------------------------------------------------------
535
+ * Functor
536
+ * -------------------------------------------------------------------------------------------------
537
+ */
538
+
539
+ /**
540
+ * @tsplus fluent fncts.observable.Observable mapWithIndex
541
+ */
542
+ export function mapWithIndex<E, A, B>(fa: Observable<E, A>, f: (i: number, a: A) => B): Observable<E, B> {
543
+ return fa.operate((source, subscriber) => {
544
+ let i = 0;
545
+ source.subscribe(
546
+ new OperatorSubscriber(subscriber, {
547
+ next: (value) => {
548
+ subscriber.next(f(i++, value));
549
+ },
550
+ }),
551
+ );
552
+ });
553
+ }
554
+
555
+ /**
556
+ * @tsplus fluent fncts.observable.Observable map
557
+ */
558
+ export function map_<E, A, B>(fa: Observable<E, A>, f: (a: A) => B): Observable<E, B> {
559
+ return fa.mapWithIndex((_, a) => f(a));
560
+ }
561
+
562
+ /**
563
+ * @tsplus fluent fncts.observable.Observable as
564
+ */
565
+ export function as_<E, A, B>(fa: Observable<E, A>, b: Lazy<B>): Observable<E, B> {
566
+ return map_(fa, b);
567
+ }
568
+
569
+ /*
570
+ * -------------------------------------------------------------------------------------------------
571
+ * Bifunctor
572
+ * -------------------------------------------------------------------------------------------------
573
+ */
574
+
575
+ /**
576
+ * @tsplus fluent fncts.observable.Observable mapError
577
+ */
578
+ export function mapError_<E, A, E1>(fa: Observable<E, A>, f: (e: E) => E1): Observable<E1, A> {
579
+ return fa.operate((source, subscriber) => {
580
+ source.subscribe(
581
+ new OperatorSubscriber(subscriber, {
582
+ error: (err) => {
583
+ subscriber.error(err.map(f));
584
+ },
585
+ }),
586
+ );
587
+ });
588
+ }
589
+
590
+ /**
591
+ * @tsplus getter fncts.observable.Observable swap
592
+ */
593
+ export function swap<E, A>(fa: Observable<E, A>): Observable<A, E> {
594
+ return operate_(fa, (source, subscriber) => {
595
+ source.subscribe(
596
+ new OperatorSubscriber(subscriber, {
597
+ next: (value) => {
598
+ subscriber.error(Cause.fail(value));
599
+ },
600
+ error: (err) => {
601
+ err.failureOrCause.match(
602
+ (e) => {
603
+ subscriber.next(e);
604
+ },
605
+ (cause) => {
606
+ subscriber.error(cause);
607
+ },
608
+ );
609
+ },
610
+ }),
611
+ );
612
+ });
613
+ }
614
+
615
+ /*
616
+ * -------------------------------------------------------------------------------------------------
617
+ * Filterable
618
+ * -------------------------------------------------------------------------------------------------
619
+ */
620
+
621
+ /**
622
+ * @tsplus fluent fncts.observable.Observable filterWithIndex
623
+ */
624
+ export function filterWithIndex_<E, A, B extends A>(
625
+ fa: Observable<E, A>,
626
+ refinement: RefinementWithIndex<number, A, B>,
627
+ ): Observable<E, B>;
628
+ export function filterWithIndex_<E, A>(
629
+ fa: Observable<E, A>,
630
+ predicate: PredicateWithIndex<number, A>,
631
+ ): Observable<E, A>;
632
+ export function filterWithIndex_<E, A>(
633
+ fa: Observable<E, A>,
634
+ predicate: PredicateWithIndex<number, A>,
635
+ ): Observable<E, A> {
636
+ return operate_(fa, (source, subscriber) => {
637
+ let index = 0;
638
+ source.subscribe(
639
+ operatorSubscriber(subscriber, { next: (value) => predicate(index++, value) && subscriber.next(value) }),
640
+ );
641
+ });
642
+ }
643
+
644
+ /**
645
+ * @tsplus fluent fncts.observable.Observable filter
646
+ */
647
+ export function filter_<E, A, B extends A>(fa: Observable<E, A>, refinement: Refinement<A, B>): Observable<E, B>;
648
+ export function filter_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>): Observable<E, A>;
649
+ export function filter_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>): Observable<E, A> {
650
+ return fa.filterWithIndex((_, a) => predicate(a));
651
+ }
652
+
653
+ /**
654
+ * @tsplus fluent fncts.observable.Observable filterMapWithIndex
655
+ */
656
+ export function filterMapWithIndex<E, A, B>(fa: Observable<E, A>, f: (i: number, a: A) => Maybe<B>): Observable<E, B> {
657
+ return operate_(fa, (source, subscriber) => {
658
+ let index = 0;
659
+ source.subscribe(
660
+ operatorSubscriber(subscriber, {
661
+ next: (value) =>
662
+ f(index++, value).match(
663
+ () => noop,
664
+ (b) => subscriber.next(b),
665
+ ),
666
+ }),
667
+ );
668
+ });
669
+ }
670
+
671
+ /**
672
+ * @tsplus fluent fncts.observable.Observable filterMap
673
+ */
674
+ export function filterMap_<E, A, B>(fa: Observable<E, A>, f: (a: A) => Maybe<B>): Observable<E, B> {
675
+ return fa.filterMapWithIndex((_, a) => f(a));
676
+ }
677
+
678
+ /**
679
+ * @tsplus fluent fncts.observable.Observable partitionWithIndex
680
+ */
681
+ export function partitionWithIndex<E, A, B extends A>(
682
+ fa: Observable<E, A>,
683
+ refinement: RefinementWithIndex<number, A, B>,
684
+ ): readonly [Observable<E, Exclude<A, B>>, Observable<E, B>];
685
+ export function partitionWithIndex<E, A>(
686
+ fa: Observable<E, A>,
687
+ predicate: PredicateWithIndex<number, A>,
688
+ ): readonly [Observable<E, A>, Observable<E, A>];
689
+ export function partitionWithIndex<E, A>(
690
+ fa: Observable<E, A>,
691
+ predicate: PredicateWithIndex<number, A>,
692
+ ): readonly [Observable<E, A>, Observable<E, A>] {
693
+ return [fa.filterWithIndex((i, a) => !predicate(i, a)), fa.filterWithIndex(predicate)];
694
+ }
695
+
696
+ /**
697
+ * @tsplus fluent fncts.observable.Observable partition
698
+ */
699
+ export function partition_<E, A, B extends A>(
700
+ fa: Observable<E, A>,
701
+ refinement: Refinement<A, B>,
702
+ ): readonly [Observable<E, Exclude<A, B>>, Observable<E, B>];
703
+ export function partition_<E, A>(
704
+ fa: Observable<E, A>,
705
+ predicate: Predicate<A>,
706
+ ): readonly [Observable<E, A>, Observable<E, A>];
707
+ export function partition_<E, A>(
708
+ fa: Observable<E, A>,
709
+ predicate: Predicate<A>,
710
+ ): readonly [Observable<E, A>, Observable<E, A>] {
711
+ return fa.partitionWithIndex((_, a) => predicate(a));
712
+ }
713
+
714
+ /**
715
+ * @tsplus fluent fncts.observable.Observable partitionMapWithIndex
716
+ */
717
+ export function partitionMapWithIndex_<E, A, B, C>(
718
+ fa: Observable<E, A>,
719
+ f: (i: number, a: A) => Either<B, C>,
720
+ ): readonly [Observable<E, B>, Observable<E, C>] {
721
+ return [
722
+ operate_(fa, (source, subscriber) => {
723
+ let index = 0;
724
+ source.subscribe(
725
+ operatorSubscriber(subscriber, {
726
+ next: (value) => {
727
+ f(index++, value).match((b) => subscriber.next(b), noop);
728
+ },
729
+ }),
730
+ );
731
+ }),
732
+ operate_(fa, (source, subscriber) => {
733
+ let index = 0;
734
+ source.subscribe(
735
+ operatorSubscriber(subscriber, {
736
+ next: (value) => {
737
+ f(index++, value).match(noop, (c) => subscriber.next(c));
738
+ },
739
+ }),
740
+ );
741
+ }),
742
+ ];
743
+ }
744
+
745
+ /**
746
+ * @tsplus fluent fncts.observable.Observable partitionMap
747
+ */
748
+ export function partitionMap_<E, A, B, C>(
749
+ fa: Observable<E, A>,
750
+ f: (a: A) => Either<B, C>,
751
+ ): readonly [Observable<E, B>, Observable<E, C>] {
752
+ return fa.partitionMapWithIndex((_, a) => f(a));
753
+ }
754
+
755
+ /*
756
+ * -------------------------------------------------------------------------------------------------
757
+ * Monad
758
+ * -------------------------------------------------------------------------------------------------
759
+ */
760
+
761
+ /**
762
+ * @tsplus fluent fncts.observable.Observable mergeMapWithIndex
763
+ */
764
+ export function mergeMapWithIndex<E, A, E1, B>(
765
+ ma: Observable<E, A>,
766
+ f: (i: number, a: A) => ObservableInput<E1, B>,
767
+ concurrent = Infinity,
768
+ ): Observable<E | E1, B> {
769
+ return operate_(ma, (source, sub) => mergeInternal(source, sub, f, concurrent));
770
+ }
771
+
772
+ /**
773
+ * @tsplus fluent fncts.observable.Observable mergeMap
774
+ */
775
+ export function mergeMap_<E, A, E1, B>(
776
+ ma: Observable<E, A>,
777
+ f: (a: A) => ObservableInput<E1, B>,
778
+ concurrent = Infinity,
779
+ ): Observable<E | E1, B> {
780
+ return ma.mergeMapWithIndex((_, a) => f(a), concurrent);
781
+ }
782
+
783
+ /**
784
+ * @tsplus fluent fncts.observable.Observable concatMapWithIndex
785
+ */
786
+ export function concatMapWithIndex<E, A, E1, B>(
787
+ ma: Observable<E, A>,
788
+ f: (i: number, a: A) => ObservableInput<E1, B>,
789
+ ): Observable<E | E1, B> {
790
+ return ma.mergeMapWithIndex(f, 1);
791
+ }
792
+
793
+ /**
794
+ * @tsplus fluent fncts.observable.Observable concatMap
795
+ */
796
+ export function concatMap_<E, A, E1, B>(
797
+ ma: Observable<E, A>,
798
+ f: (a: A) => ObservableInput<E1, B>,
799
+ ): Observable<E | E1, B> {
800
+ return ma.mergeMapWithIndex((_, a) => f(a), 1);
801
+ }
802
+
803
+ /**
804
+ * @tsplus getter fncts.observable.Observable flatten
805
+ */
806
+ export function flatten<E, E1, A>(mma: Observable<E, Observable<E1, A>>): Observable<E | E1, A> {
807
+ return mma.concatAll;
808
+ }
809
+
810
+ /*
811
+ * -------------------------------------------------------------------------------------------------
812
+ * Foldable
813
+ * -------------------------------------------------------------------------------------------------
814
+ */
815
+
816
+ /**
817
+ * @tsplus fluent fncts.observable.Observable foldLeftWithIndex
818
+ */
819
+ export function foldLeftWithIndex<E, A, B>(
820
+ fa: Observable<E, A>,
821
+ initial: B,
822
+ f: (index: number, acc: B, value: A) => B,
823
+ ): Observable<E, B> {
824
+ return fa.operate(scanInternal(f, initial, true, false, true));
825
+ }
826
+
827
+ /**
828
+ * @tsplus fluent fncts.observable.Observable foldLeft
829
+ */
830
+ export function foldLeft<E, A, B>(fa: Observable<E, A>, initial: B, f: (acc: B, value: A) => B): Observable<E, B> {
831
+ return fa.foldLeftWithIndex(initial, (_, b, a) => f(b, a));
832
+ }
833
+
834
+ /*
835
+ * -------------------------------------------------------------------------------------------------
836
+ * combinators
837
+ * -------------------------------------------------------------------------------------------------
838
+ */
839
+
840
+ /**
841
+ * @tsplus fluent fncts.observable.Observable at
842
+ */
843
+ export function at_<E, A>(fa: Observable<E, A>, index: number): Observable<E, Maybe<A>> {
844
+ return fa
845
+ .filterWithIndex((i) => i === index)
846
+ .take(1)
847
+ .map(Maybe.just)
848
+ .onEmpty(() => Nothing());
849
+ }
850
+
851
+ /**
852
+ * @tsplus fluent fncts.observable.Observable audit
853
+ */
854
+ export function audit_<E, A, E1>(
855
+ fa: Observable<E, A>,
856
+ durationSelector: (value: A) => ObservableInput<E1, any>,
857
+ ): Observable<E | E1, A> {
858
+ return fa.operate((source, subscriber) => {
859
+ let lastValue: Maybe<A> = Nothing();
860
+ let durationSubscriber: Subscriber<any, any> | null = null;
861
+ let isComplete = false;
862
+ const endDuration = () => {
863
+ durationSubscriber?.unsubscribe();
864
+ durationSubscriber = null;
865
+ if (lastValue.isJust()) {
866
+ const { value } = lastValue;
867
+ lastValue = Nothing();
868
+ subscriber.next(value);
869
+ }
870
+ isComplete && subscriber.complete();
871
+ };
872
+
873
+ const cleanupDuration = () => {
874
+ durationSubscriber = null;
875
+ isComplete && subscriber.complete();
876
+ };
877
+
878
+ source.subscribe(
879
+ operatorSubscriber(subscriber, {
880
+ next: (value) => {
881
+ lastValue = Just(value);
882
+ if (!durationSubscriber) {
883
+ from(durationSelector(value)).subscribe(
884
+ (durationSubscriber = operatorSubscriber(subscriber, { next: endDuration, complete: cleanupDuration })),
885
+ );
886
+ }
887
+ },
888
+ complete: () => {
889
+ isComplete = true;
890
+ (lastValue.isNothing() || !durationSubscriber || durationSubscriber.closed) && subscriber.complete();
891
+ },
892
+ }),
893
+ );
894
+ });
895
+ }
896
+
897
+ /**
898
+ * @tsplus fluent fncts.observable.Observable auditTime
899
+ */
900
+ export function auditTime_<E, A>(
901
+ fa: Observable<E, A>,
902
+ duration: number,
903
+ scheduler: SchedulerLike = asyncScheduler,
904
+ ): Observable<E, A> {
905
+ return fa.audit(() => timer(duration, scheduler));
906
+ }
907
+
908
+ /**
909
+ * @tsplus fluent fncts.observable.Observable buffer
910
+ */
911
+ export function buffer_<E, A, E1>(
912
+ fa: Observable<E, A>,
913
+ closingNotifier: Observable<E1, any>,
914
+ ): Observable<E | E1, ReadonlyArray<A>> {
915
+ return fa.operate((source, subscriber) => {
916
+ let buffer: A[] = [];
917
+ source.subscribe(
918
+ operatorSubscriber(subscriber, {
919
+ next: (value) => buffer.push(value),
920
+ complete: () => {
921
+ subscriber.next(buffer);
922
+ subscriber.complete();
923
+ },
924
+ }),
925
+ );
926
+ closingNotifier.subscribe(
927
+ operatorSubscriber(subscriber, {
928
+ next: () => {
929
+ const b = buffer;
930
+ buffer = [];
931
+ subscriber.next(b);
932
+ },
933
+ complete: noop,
934
+ }),
935
+ );
936
+ return () => {
937
+ buffer = null!;
938
+ };
939
+ });
940
+ }
941
+
942
+ /**
943
+ * @tsplus fluent fncts.observable.Observable bufferCount
944
+ */
945
+ export function bufferCount_<E, A>(
946
+ fa: Observable<E, A>,
947
+ bufferSize: number,
948
+ startBufferEvery?: number,
949
+ ): Observable<E, ReadonlyArray<A>> {
950
+ // eslint-disable-next-line no-param-reassign
951
+ startBufferEvery = startBufferEvery ?? bufferSize;
952
+ return fa.operate((source, subscriber) => {
953
+ let buffers: A[][] = [];
954
+ let count = 0;
955
+ source.subscribe(
956
+ operatorSubscriber(
957
+ subscriber,
958
+ {
959
+ next: (value) => {
960
+ let toEmit: A[][] | null = null;
961
+ if (count++ % startBufferEvery! === 0) {
962
+ buffers.push([]);
963
+ }
964
+ for (const buffer of buffers) {
965
+ buffer.push(value);
966
+ if (bufferSize <= buffer.length) {
967
+ toEmit = toEmit ?? [];
968
+ toEmit.push(buffer);
969
+ }
970
+ }
971
+ if (toEmit) {
972
+ for (const buffer of toEmit) {
973
+ arrayRemove(buffers, buffer);
974
+ subscriber.next(buffer);
975
+ }
976
+ }
977
+ },
978
+ complete: () => {
979
+ for (const buffer of buffers) {
980
+ subscriber.next(buffer);
981
+ }
982
+ subscriber.complete();
983
+ },
984
+ },
985
+ () => {
986
+ buffers = null!;
987
+ },
988
+ ),
989
+ );
990
+ });
991
+ }
992
+
993
+ export interface BufferTimeConfig {
994
+ readonly bufferTimeSpan: number;
995
+ readonly bufferCreationInterval?: number;
996
+ readonly maxBufferSize?: number;
997
+ readonly scheduler?: SchedulerLike;
998
+ }
999
+
1000
+ /**
1001
+ * @tsplus fluent fncts.observable.Observable bufferTime
1002
+ */
1003
+ export function bufferTime_<E, A>(fa: Observable<E, A>, config: BufferTimeConfig): Observable<E, ReadonlyArray<A>> {
1004
+ const {
1005
+ bufferTimeSpan,
1006
+ bufferCreationInterval = null,
1007
+ maxBufferSize = Infinity,
1008
+ scheduler = asyncScheduler,
1009
+ } = config;
1010
+ return fa.operate((source, subscriber) => {
1011
+ let bufferRecords: { buffer: A[]; subs: Subscription }[] | null = [];
1012
+ let restartOnEmit = true;
1013
+ const emit = (record: { buffer: A[]; subs: Subscription }) => {
1014
+ const { buffer, subs } = record;
1015
+ subs.unsubscribe();
1016
+ arrayRemove(bufferRecords, record);
1017
+ subscriber.next(buffer);
1018
+ restartOnEmit && startBuffer();
1019
+ };
1020
+ const startBuffer = () => {
1021
+ if (bufferRecords) {
1022
+ const subs = new Subscription();
1023
+ subscriber.add(subs);
1024
+ const buffer: A[] = [];
1025
+ const record = {
1026
+ buffer,
1027
+ subs,
1028
+ };
1029
+ bufferRecords.push(record);
1030
+ subs.add(scheduler.schedule(() => emit(record), bufferTimeSpan));
1031
+ }
1032
+ };
1033
+ bufferCreationInterval !== null && bufferCreationInterval >= 0
1034
+ ? subscriber.add(
1035
+ scheduler.schedule(function () {
1036
+ startBuffer();
1037
+ !this.closed && subscriber.add(this.schedule(null, bufferCreationInterval));
1038
+ }, bufferCreationInterval),
1039
+ )
1040
+ : (restartOnEmit = true);
1041
+ startBuffer();
1042
+ const bufferTimeSubscriber = operatorSubscriber(
1043
+ subscriber,
1044
+ {
1045
+ next: (value: A) => {
1046
+ const recordsCopy = bufferRecords!.slice();
1047
+ for (const record of recordsCopy) {
1048
+ const { buffer } = record;
1049
+ buffer.push(value);
1050
+ maxBufferSize <= buffer.length && emit(record);
1051
+ }
1052
+ },
1053
+ complete: () => {
1054
+ while (bufferRecords?.length) {
1055
+ subscriber.next(bufferRecords.shift()!.buffer);
1056
+ }
1057
+ bufferTimeSubscriber?.unsubscribe();
1058
+ subscriber.complete();
1059
+ subscriber.unsubscribe();
1060
+ },
1061
+ },
1062
+ () => (bufferRecords = null),
1063
+ );
1064
+ source.subscribe(bufferTimeSubscriber);
1065
+ });
1066
+ }
1067
+
1068
+ /**
1069
+ * @tsplus fluent fncts.observable.Observable bufferToggle
1070
+ */
1071
+ export function bufferToggle_<E, A, E1, B, E2>(
1072
+ fa: Observable<E, A>,
1073
+ openings: ObservableInput<E1, B>,
1074
+ closingSelector: (value: B) => ObservableInput<E2, any>,
1075
+ ): Observable<E | E1 | E2, ReadonlyArray<A>> {
1076
+ return fa.operate((source, subscriber) => {
1077
+ const buffers: A[][] = [];
1078
+ from(openings).subscribe(
1079
+ operatorSubscriber(subscriber, {
1080
+ next: (openValue) => {
1081
+ const buffer: A[] = [];
1082
+ buffers.push(buffer);
1083
+ const closingSubscription = new Subscription();
1084
+ const emitBuffer = () => {
1085
+ arrayRemove(buffers, buffer);
1086
+ subscriber.next(buffer);
1087
+ closingSubscription.unsubscribe();
1088
+ };
1089
+ closingSubscription.add(
1090
+ from(closingSelector(openValue)).subscribe(
1091
+ operatorSubscriber(subscriber, { next: emitBuffer, complete: noop }),
1092
+ ),
1093
+ );
1094
+ },
1095
+ complete: noop,
1096
+ }),
1097
+ );
1098
+ source.subscribe(
1099
+ operatorSubscriber(subscriber, {
1100
+ next: (value) => {
1101
+ for (const buffer of buffers) {
1102
+ buffer.push(value);
1103
+ }
1104
+ },
1105
+ complete: () => {
1106
+ while (buffers.length > 0) {
1107
+ subscriber.next(buffers.shift()!);
1108
+ }
1109
+ subscriber.complete();
1110
+ },
1111
+ }),
1112
+ );
1113
+ });
1114
+ }
1115
+
1116
+ /**
1117
+ * @tsplus fluent fncts.observable.Observable bufferWhen
1118
+ */
1119
+ export function bufferWhen_<E, A, E1>(
1120
+ fa: Observable<E, A>,
1121
+ closingSelector: () => ObservableInput<E1, any>,
1122
+ ): Observable<E | E1, ReadonlyArray<A>> {
1123
+ return fa.operate((source, subscriber) => {
1124
+ let buffer: A[] | null = null;
1125
+ let closingSubscriber: Subscriber<E | E1, A> | null = null;
1126
+ const openBuffer = () => {
1127
+ closingSubscriber?.unsubscribe();
1128
+ const b = buffer;
1129
+ buffer = [];
1130
+ b && subscriber.next(b);
1131
+ from(closingSelector()).subscribe(
1132
+ (closingSubscriber = operatorSubscriber(subscriber, { next: openBuffer, complete: noop })),
1133
+ );
1134
+ };
1135
+ openBuffer();
1136
+ source.subscribe(
1137
+ operatorSubscriber(
1138
+ subscriber,
1139
+ {
1140
+ next: (value) => buffer?.push(value),
1141
+ complete: () => {
1142
+ buffer && subscriber.next(buffer);
1143
+ subscriber.complete();
1144
+ },
1145
+ },
1146
+ () => (buffer = closingSubscriber = null),
1147
+ ),
1148
+ );
1149
+ });
1150
+ }
1151
+
1152
+ export function bufferWhen<E1>(
1153
+ closingSelector: () => ObservableInput<E1, any>,
1154
+ ): <E, A>(fa: Observable<E, A>) => Observable<E | E1, ReadonlyArray<A>> {
1155
+ return (fa) => bufferWhen_(fa, closingSelector);
1156
+ }
1157
+
1158
+ /**
1159
+ * @tsplus fluent fncts.observable.Observable catchAllCause
1160
+ */
1161
+ export function catchAllCause<E, A, E1, B>(
1162
+ self: Observable<E, A>,
1163
+ f: (cause: Cause<E>, caught: Observable<E | E1, A | B>) => ObservableInput<E1, B>,
1164
+ ): Observable<E1, A | B> {
1165
+ return self.operate((source, subscriber) => {
1166
+ let innerSub: Subscription | null = null;
1167
+ let syncUnsub = false;
1168
+ let handledResult: Observable<E1, B>;
1169
+ innerSub = source.subscribe(
1170
+ operatorSubscriber(subscriber, {
1171
+ error: (cause) => {
1172
+ handledResult = from(f(cause, source.catchAllCause(f)));
1173
+ if (innerSub) {
1174
+ innerSub.unsubscribe();
1175
+ innerSub = null;
1176
+ handledResult.subscribe(subscriber);
1177
+ } else {
1178
+ syncUnsub = true;
1179
+ }
1180
+ },
1181
+ }),
1182
+ );
1183
+ if (syncUnsub) {
1184
+ innerSub.unsubscribe();
1185
+ innerSub = null;
1186
+ handledResult!.subscribe(subscriber);
1187
+ }
1188
+ });
1189
+ }
1190
+
1191
+ /**
1192
+ * @tsplus getter fncts.observable.Observable concatAll
1193
+ */
1194
+ export function concatAll<E, E1, A>(ffa: Observable<E, ObservableInput<E1, A>>): Observable<E | E1, A> {
1195
+ return mergeAll_(ffa, 1);
1196
+ }
1197
+
1198
+ /**
1199
+ * @tsplus fluent fncts.observable.Observable concat
1200
+ */
1201
+ export function concat_<E, A, O extends ReadonlyArray<ObservableInput<any, any>>>(
1202
+ fa: Observable<E, A>,
1203
+ ...sources: O
1204
+ ): Observable<E | Observable.ErrorOf<O[number]>, A | Observable.TypeOf<O[number]>> {
1205
+ return fa.operate((source, subscriber) => {
1206
+ fromArrayLike([source, ...sources]).concatAll.subscribe(subscriber);
1207
+ });
1208
+ }
1209
+
1210
+ /**
1211
+ * @tsplus getter fncts.observable.Observable count
1212
+ */
1213
+ export function count<E, A>(fa: Observable<E, A>): Observable<E, number> {
1214
+ return fa.foldLeft(0, (total, _) => total + 1);
1215
+ }
1216
+
1217
+ /**
1218
+ * @tsplus fluent fncts.observable.Observable countWithIndex
1219
+ */
1220
+ export function countWithIndex<E, A>(
1221
+ fa: Observable<E, A>,
1222
+ predicate: PredicateWithIndex<number, A>,
1223
+ ): Observable<E, number> {
1224
+ return fa.foldLeftWithIndex(0, (i, total, v) => (predicate(i, v) ? total + 1 : total));
1225
+ }
1226
+
1227
+ /**
1228
+ * @tsplus fluent fncts.observable.Observable countWith
1229
+ */
1230
+ export function countWith_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>): Observable<E, number> {
1231
+ return fa.countWithIndex((_, a) => predicate(a));
1232
+ }
1233
+
1234
+ /**
1235
+ * @tsplus getter fncts.observable.Observable combineLatestAll
1236
+ */
1237
+ export function combineLatestAll<E, E1, A>(
1238
+ fa: Observable<E, ObservableInput<E1, A>>,
1239
+ ): Observable<E | E1, ReadonlyArray<A>> {
1240
+ return joinAllInternal(fa, (sources) =>
1241
+ !sources.length ? empty() : (combineLatest_(sources[0]!, ...sources.slice(1)) as any),
1242
+ );
1243
+ }
1244
+
1245
+ /**
1246
+ * @tsplus fluent fncts.observable.Observable combineLatest
1247
+ */
1248
+ export function combineLatest_<E, A, O extends ReadonlyArray<ObservableInput<any, any>>>(
1249
+ self: ObservableInput<E, A>,
1250
+ ...sources: O
1251
+ ): Observable<E | Observable.ErrorOf<O[number]>, [A, ...{ [K in keyof O]: Observable.TypeOf<O[K]> }]> {
1252
+ if (!sources.length) {
1253
+ return Function.unsafeCoerce(from(self));
1254
+ }
1255
+ return from(self).operate((source, subscriber) => {
1256
+ combineLatestInternal(subscriber, [source, ...sources]);
1257
+ });
1258
+ }
1259
+
1260
+ /**
1261
+ * @tsplus fluent fncts.observable.Observable debounceWith
1262
+ */
1263
+ export function debounceWith_<E, A, E1>(
1264
+ fa: Observable<E, A>,
1265
+ durationSelector: (value: A) => ObservableInput<E1, any>,
1266
+ ): Observable<E | E1, A> {
1267
+ return fa.operate((source, subscriber) => {
1268
+ let lastValue: Maybe<A> = Nothing();
1269
+ let durationSubscriber: Subscriber<E1, any> | null = null;
1270
+ const emit = () => {
1271
+ durationSubscriber?.unsubscribe();
1272
+ durationSubscriber = null;
1273
+ if (lastValue.isJust()) {
1274
+ const { value } = lastValue;
1275
+ lastValue = Nothing();
1276
+ subscriber.next(value);
1277
+ }
1278
+ };
1279
+ source.subscribe(
1280
+ operatorSubscriber(
1281
+ subscriber,
1282
+ {
1283
+ next: (value) => {
1284
+ durationSubscriber?.unsubscribe();
1285
+ lastValue = Just(value);
1286
+ durationSubscriber = operatorSubscriber(subscriber, { next: emit, complete: noop });
1287
+ from(durationSelector(value)).subscribe(durationSubscriber);
1288
+ },
1289
+ complete: () => {
1290
+ emit();
1291
+ subscriber.complete();
1292
+ },
1293
+ },
1294
+ () => {
1295
+ lastValue = durationSubscriber = null!;
1296
+ },
1297
+ ),
1298
+ );
1299
+ });
1300
+ }
1301
+
1302
+ /**
1303
+ * @tsplus fluent fncts.observable.Observable debounce
1304
+ */
1305
+ export function debounce_<E, A>(
1306
+ fa: Observable<E, A>,
1307
+ dueTime: number,
1308
+ scheduler: SchedulerLike = asyncScheduler,
1309
+ ): Observable<E, A> {
1310
+ return fa.operate((source, subscriber) => {
1311
+ let activeTask: Subscription | null = null;
1312
+ let lastValue: A | null = null;
1313
+ let lastTime: number | null = null;
1314
+
1315
+ const emit = () => {
1316
+ if (activeTask) {
1317
+ activeTask.unsubscribe();
1318
+ activeTask = null;
1319
+ const value = lastValue!;
1320
+ lastValue = null;
1321
+ subscriber.next(value);
1322
+ }
1323
+ };
1324
+ function emitWhenIdle(this: SchedulerAction<unknown>) {
1325
+ const targetTime = lastTime! + dueTime;
1326
+ const now = scheduler.now();
1327
+ if (now < targetTime) {
1328
+ activeTask = this.schedule(undefined, targetTime - now);
1329
+ subscriber.add(activeTask);
1330
+ return;
1331
+ }
1332
+ emit();
1333
+ }
1334
+ source.subscribe(
1335
+ operatorSubscriber(
1336
+ subscriber,
1337
+ {
1338
+ next: (value) => {
1339
+ lastValue = value;
1340
+ lastTime = scheduler.now();
1341
+ if (!activeTask) {
1342
+ activeTask = scheduler.schedule(emitWhenIdle, dueTime);
1343
+ subscriber.add(activeTask);
1344
+ }
1345
+ },
1346
+ complete: () => {
1347
+ emit();
1348
+ subscriber.complete();
1349
+ },
1350
+ },
1351
+ () => {
1352
+ lastValue = activeTask = null;
1353
+ },
1354
+ ),
1355
+ );
1356
+ });
1357
+ }
1358
+
1359
+ /**
1360
+ * @tsplus getter fncts.observable.Observable either
1361
+ */
1362
+ export function either<E, A>(fa: Observable<E, A>): Observable<never, Either<E, A>> {
1363
+ return fa.operate((source, subscriber) => {
1364
+ source.subscribe(
1365
+ operatorSubscriber(subscriber, {
1366
+ next: (value) => {
1367
+ subscriber.next(Either.right(value));
1368
+ },
1369
+ error: (error) => {
1370
+ error.failureOrCause.match(
1371
+ (e) => subscriber.next(Either.left(e)),
1372
+ (cause) => subscriber.error(cause),
1373
+ );
1374
+ },
1375
+ }),
1376
+ );
1377
+ });
1378
+ }
1379
+
1380
+ /**
1381
+ * @tsplus fluent fncts.observable.Observable delayWithIndex
1382
+ */
1383
+ export function delayWithIndex<E, A, E1>(
1384
+ fa: Observable<E, A>,
1385
+ f: (index: number, value: A) => Observable<E1, any>,
1386
+ ): Observable<E | E1, A> {
1387
+ return fa.mergeMapWithIndex((i, a) => f(i, a).take(1).as(a));
1388
+ }
1389
+
1390
+ /**
1391
+ * @tsplus fluent fncts.observable.Observable delayWith
1392
+ */
1393
+ export function delayWith_<E, A, E1>(
1394
+ fa: Observable<E, A>,
1395
+ f: (value: A) => Observable<E1, any>,
1396
+ ): Observable<E | E1, A> {
1397
+ return fa.delayWithIndex((_, a) => f(a));
1398
+ }
1399
+
1400
+ /**
1401
+ * @tsplus fluent fncts.observable.Observable delay
1402
+ */
1403
+ export function delay_<E, A>(
1404
+ fa: Observable<E, A>,
1405
+ due: number | Date,
1406
+ scheduler: SchedulerLike = asyncScheduler,
1407
+ ): Observable<E, A> {
1408
+ const duration = timer(due, scheduler);
1409
+ return delayWith_(fa, () => duration);
1410
+ }
1411
+
1412
+ /**
1413
+ * @tsplus getter fncts.observable.Observable dematerialize
1414
+ */
1415
+ export function dematerialize<E, E1, A>(fa: Observable<E, Notification<E1, A>>): Observable<E | E1, A> {
1416
+ return fa.operate((source, subscriber) => {
1417
+ source.subscribe(operatorSubscriber(subscriber, { next: (notification) => notification.observe(subscriber) }));
1418
+ });
1419
+ }
1420
+
1421
+ /**
1422
+ * @tsplus fluent fncts.observable.Observable ensuring
1423
+ */
1424
+ export function ensuring_<E, A>(fa: Observable<E, A>, finalizer: () => void): Observable<E, A> {
1425
+ return fa.operate((source, subscriber) => {
1426
+ source.subscribe(subscriber);
1427
+ subscriber.add(finalizer);
1428
+ });
1429
+ }
1430
+
1431
+ /**
1432
+ * @tsplus getter fncts.observable.Observable exhaustAll
1433
+ */
1434
+ export function exhaustAll<E, E1, A>(ffa: Observable<E, ObservableInput<E1, A>>): Observable<E | E1, A> {
1435
+ return ffa.operate((source, subscriber) => {
1436
+ let isComplete = false;
1437
+ let innerSub: Subscription | null = null;
1438
+ source.subscribe(
1439
+ operatorSubscriber(subscriber, {
1440
+ next: (inner) => {
1441
+ if (!innerSub) {
1442
+ innerSub = from(inner).subscribe(
1443
+ operatorSubscriber(subscriber, {
1444
+ complete: () => {
1445
+ innerSub = null;
1446
+ isComplete && subscriber.complete();
1447
+ },
1448
+ }),
1449
+ );
1450
+ }
1451
+ },
1452
+ complete: () => {
1453
+ isComplete = true;
1454
+ !innerSub && subscriber.complete();
1455
+ },
1456
+ }),
1457
+ );
1458
+ });
1459
+ }
1460
+
1461
+ /**
1462
+ * @tsplus fluent fncts.observable.Observable exhaustMapWithIndex
1463
+ */
1464
+ export function exhaustMapWithIndex<E, A, E1, B>(
1465
+ self: Observable<E, A>,
1466
+ f: (i: number, a: A) => ObservableInput<E1, B>,
1467
+ ): Observable<E | E1, B> {
1468
+ return self.operate((source, subscriber) => {
1469
+ let index = 0;
1470
+ let innerSub: Subscriber<E1, B> | null = null;
1471
+ let isComplete = false;
1472
+ source.subscribe(
1473
+ operatorSubscriber(subscriber, {
1474
+ next: (outerValue) => {
1475
+ if (!innerSub) {
1476
+ innerSub = operatorSubscriber(subscriber, {
1477
+ complete: () => {
1478
+ innerSub = null;
1479
+ isComplete && subscriber.complete();
1480
+ },
1481
+ });
1482
+ from(f(index++, outerValue)).subscribe(innerSub);
1483
+ }
1484
+ },
1485
+ complete: () => {
1486
+ isComplete = true;
1487
+ !innerSub && subscriber.complete();
1488
+ },
1489
+ }),
1490
+ );
1491
+ });
1492
+ }
1493
+
1494
+ /**
1495
+ * @tsplus fluent fncts.observable.Observable exhaustMap
1496
+ */
1497
+ export function exhaustMap_<E, A, E1, B>(
1498
+ self: Observable<E, A>,
1499
+ f: (a: A) => ObservableInput<E1, B>,
1500
+ ): Observable<E | E1, B> {
1501
+ return self.exhaustMapWithIndex((_, a) => f(a));
1502
+ }
1503
+
1504
+ /**
1505
+ * @tsplus fluent fncts.observable.Observable expandWithIndex
1506
+ */
1507
+ export function expandWithIndex<E, A, E1, B>(
1508
+ fa: Observable<E, A>,
1509
+ f: (i: number, a: A) => ObservableInput<E1, B>,
1510
+ concurrent = Infinity,
1511
+ ): Observable<E | E1, B> {
1512
+ // eslint-disable-next-line no-param-reassign
1513
+ concurrent = (concurrent || 0) < 1 ? Infinity : concurrent;
1514
+ return fa.operate((source, subscriber) => mergeInternal(source, subscriber, f, concurrent, undefined, true));
1515
+ }
1516
+
1517
+ /**
1518
+ * @tsplus fluent fncts.observable.Observable expand
1519
+ */
1520
+ export function expand_<E, A, E1, B>(
1521
+ fa: Observable<E, A>,
1522
+ f: (a: A) => ObservableInput<E1, B>,
1523
+ concurrent = Infinity,
1524
+ ): Observable<E | E1, B> {
1525
+ return fa.expandWithIndex((_, a) => f(a), concurrent);
1526
+ }
1527
+
1528
+ /**
1529
+ * @tsplus fluent fncts.observable.Observable findWithIndex
1530
+ */
1531
+ export function findWithIndex<E, A, B extends A>(
1532
+ fa: Observable<E, A>,
1533
+ refinement: RefinementWithIndex<number, A, B>,
1534
+ ): Observable<E, Maybe<B>>;
1535
+ export function findWithIndex<E, A>(
1536
+ fa: Observable<E, A>,
1537
+ predicate: PredicateWithIndex<number, A>,
1538
+ ): Observable<E, Maybe<A>>;
1539
+ export function findWithIndex<E, A>(
1540
+ fa: Observable<E, A>,
1541
+ predicate: PredicateWithIndex<number, A>,
1542
+ ): Observable<E, Maybe<A>> {
1543
+ return fa.operate(findInternal(predicate, "value"));
1544
+ }
1545
+
1546
+ /**
1547
+ * @tsplus fluent fncts.observable.Observable find
1548
+ */
1549
+ export function find_<E, A, B extends A>(fa: Observable<E, A>, refinement: Refinement<A, B>): Observable<E, Maybe<B>>;
1550
+ export function find_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>): Observable<E, Maybe<A>>;
1551
+ export function find_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>): Observable<E, Maybe<A>> {
1552
+ return fa.findWithIndex((_, a) => predicate(a));
1553
+ }
1554
+
1555
+ /**
1556
+ * @tsplus fluent fncts.observable.Observable findIndexWithIndex
1557
+ */
1558
+ export function findIndexWithIndex<E, A, B extends A>(
1559
+ fa: Observable<E, A>,
1560
+ refinement: RefinementWithIndex<number, A, B>,
1561
+ ): Observable<E, number>;
1562
+ export function findIndexWithIndex<E, A>(
1563
+ fa: Observable<E, A>,
1564
+ predicate: PredicateWithIndex<number, A>,
1565
+ ): Observable<E, number>;
1566
+ export function findIndexWithIndex<E, A>(
1567
+ fa: Observable<E, A>,
1568
+ predicate: PredicateWithIndex<number, A>,
1569
+ ): Observable<E, number> {
1570
+ return fa.operate(findInternal(predicate, "index"));
1571
+ }
1572
+
1573
+ /**
1574
+ * @tsplus fluent fncts.observable.Observable findIndex
1575
+ */
1576
+ export function findIndex_<E, A, B extends A>(
1577
+ fa: Observable<E, A>,
1578
+ refinement: Refinement<A, B>,
1579
+ ): Observable<E, number>;
1580
+ export function findIndex_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>): Observable<E, number>;
1581
+ export function findIndex_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>): Observable<E, number> {
1582
+ return findIndexWithIndex(fa, (_, a) => predicate(a));
1583
+ }
1584
+
1585
+ /**
1586
+ * @tsplus static fncts.observable.ObservableOps forkJoin
1587
+ */
1588
+ export function forkJoin<S extends Record<string, ObservableInput<any, any>>>(
1589
+ sources: S,
1590
+ ): Observable<Observable.ErrorOf<S[keyof S]>, { [K in keyof S]: Observable.TypeOf<S[K]> }>;
1591
+ export function forkJoin<A extends ReadonlyArray<ObservableInput<any, any>>>(
1592
+ ...sources: A
1593
+ ): Observable<Observable.ErrorOf<A[number]>, { [K in keyof A]: Observable.TypeOf<A[K]> }>;
1594
+ export function forkJoin(...args: any[]): Observable<any, any> {
1595
+ const { args: sources, keys } = arrayOrObject(args);
1596
+ return new Observable((s) => {
1597
+ const length = sources.length;
1598
+ if (!length) {
1599
+ s.complete();
1600
+ return;
1601
+ }
1602
+ const values = new Array(length);
1603
+ let remainingCompletions = length;
1604
+ let remainingEmissions = length;
1605
+ for (let sourceIndex = 0; sourceIndex < length; sourceIndex++) {
1606
+ let hasValue = false;
1607
+ from(sources[sourceIndex]).subscribe(
1608
+ operatorSubscriber(s, {
1609
+ next: (value: any) => {
1610
+ if (!hasValue) {
1611
+ hasValue = true;
1612
+ remainingEmissions--;
1613
+ }
1614
+ values[sourceIndex] = value;
1615
+ },
1616
+ complete: () => {
1617
+ if (!--remainingCompletions || !hasValue) {
1618
+ if (!remainingEmissions) {
1619
+ s.next(
1620
+ keys
1621
+ ? keys.reduce((b, k, i) => {
1622
+ b[k] = values[i];
1623
+ return b;
1624
+ }, {})
1625
+ : values,
1626
+ );
1627
+ }
1628
+ s.complete();
1629
+ }
1630
+ },
1631
+ }),
1632
+ );
1633
+ }
1634
+ });
1635
+ }
1636
+
1637
+ /**
1638
+ * @tsplus getter fncts.observable.Observable ignore
1639
+ */
1640
+ export function ignore<E, A>(fa: Observable<E, A>): Observable<E, never> {
1641
+ return fa.operate((source, subscriber) => {
1642
+ source.subscribe(
1643
+ operatorSubscriber(subscriber, {
1644
+ next: noop,
1645
+ }),
1646
+ );
1647
+ });
1648
+ }
1649
+
1650
+ /**
1651
+ * @tsplus getter fncts.observable.Observable isEmpty
1652
+ */
1653
+ export function isEmpty<E, A>(fa: Observable<E, A>): Observable<E, boolean> {
1654
+ return fa.operate((source, subscriber) => {
1655
+ source.subscribe(
1656
+ operatorSubscriber(subscriber, {
1657
+ next: () => {
1658
+ subscriber.next(false);
1659
+ subscriber.complete();
1660
+ },
1661
+ complete: () => {
1662
+ subscriber.next(true);
1663
+ subscriber.complete();
1664
+ },
1665
+ }),
1666
+ );
1667
+ });
1668
+ }
1669
+
1670
+ /**
1671
+ * @tsplus getter fncts.observable.Observable materialize
1672
+ */
1673
+ export function materialize<E, A>(fa: Observable<E, A>): Observable<never, Notification<E, A>> {
1674
+ return fa.operate((source, subscriber) => {
1675
+ source.subscribe(
1676
+ operatorSubscriber(subscriber, {
1677
+ next: (value) => {
1678
+ subscriber.next(Notification.next(value));
1679
+ },
1680
+ error: (error) => {
1681
+ subscriber.next(Notification.error(error));
1682
+ },
1683
+ complete: () => {
1684
+ subscriber.next(Notification.complete());
1685
+ },
1686
+ }),
1687
+ );
1688
+ });
1689
+ }
1690
+
1691
+ /**
1692
+ * @tsplus fluent fncts.observable.Observable mergeAll
1693
+ */
1694
+ export function mergeAll_<E, E1, A>(
1695
+ self: Observable<E, ObservableInput<E1, A>>,
1696
+ concurrent = Infinity,
1697
+ ): Observable<E | E1, A> {
1698
+ return self.mergeMap(Function.identity, concurrent);
1699
+ }
1700
+
1701
+ /**
1702
+ * @tsplus fluent fncts.observable.Observable mergeScanWithIndex
1703
+ */
1704
+ export function mergeScanWithIndex<E, A, E1, B>(
1705
+ fa: Observable<E, A>,
1706
+ initial: B,
1707
+ f: (index: number, acc: B, value: A) => ObservableInput<E1, B>,
1708
+ concurrent = Infinity,
1709
+ ): Observable<E | E1, B> {
1710
+ return fa.operate((source, subscriber) => {
1711
+ let state = initial;
1712
+ return mergeInternal(
1713
+ source,
1714
+ subscriber,
1715
+ (index, value) => f(index, state, value),
1716
+ concurrent,
1717
+ (value) => {
1718
+ state = value;
1719
+ },
1720
+ false,
1721
+ undefined,
1722
+ () => (state = null!),
1723
+ );
1724
+ });
1725
+ }
1726
+
1727
+ /**
1728
+ * @tsplus fluent fncts.observable.Observable mergeScan
1729
+ */
1730
+ export function mergeScan_<E, A, E1, B>(
1731
+ fa: Observable<E, A>,
1732
+ initial: B,
1733
+ f: (acc: B, value: A) => ObservableInput<E1, B>,
1734
+ concurrent = Infinity,
1735
+ ): Observable<E | E1, B> {
1736
+ return fa.mergeScanWithIndex(initial, (_, b, a) => f(b, a), concurrent);
1737
+ }
1738
+
1739
+ export function onErrorResumeNext<E, A, O extends ReadonlyArray<ObservableInput<any, any>>>(
1740
+ fa: Observable<E, A>,
1741
+ ...sources: O
1742
+ ): Observable<E | Observable.ErrorOf<O[number]>, A | Observable.TypeOf<O[number]>> {
1743
+ return fa.operate((source, subscriber) => {
1744
+ const remaining = [source, ...sources];
1745
+ const subscribeNext = () => {
1746
+ if (!subscriber.closed) {
1747
+ if (remaining.length > 0) {
1748
+ let nextSource: Observable<E | Observable.ErrorOf<O[number]>, A | Observable.TypeOf<O[number]>>;
1749
+ try {
1750
+ nextSource = from(remaining.shift()!);
1751
+ } catch (err) {
1752
+ subscribeNext();
1753
+ return;
1754
+ }
1755
+ const innerSub = operatorSubscriber(subscriber, { error: noop, complete: noop });
1756
+ subscriber.add(nextSource.subscribe(innerSub));
1757
+ innerSub.add(subscribeNext);
1758
+ } else {
1759
+ subscriber.complete();
1760
+ }
1761
+ }
1762
+ };
1763
+ subscribeNext();
1764
+ });
1765
+ }
1766
+
1767
+ /**
1768
+ * @tsplus fluent fncts.observable.Observable onEmpty
1769
+ */
1770
+ export function onEmpty_<E, A, B>(fa: Observable<E, A>, f: Lazy<B>): Observable<E, A | B> {
1771
+ return fa.operate((source, subscriber) => {
1772
+ let hasValue = false;
1773
+ source.subscribe(
1774
+ operatorSubscriber(subscriber, {
1775
+ next: (value) => {
1776
+ hasValue = true;
1777
+ subscriber.next(value);
1778
+ },
1779
+ complete: () => {
1780
+ if (!hasValue) {
1781
+ subscriber.next(f());
1782
+ }
1783
+ subscriber.complete();
1784
+ },
1785
+ }),
1786
+ );
1787
+ });
1788
+ }
1789
+
1790
+ /**
1791
+ * @tsplus fluent fncts.observable.Observable repeat
1792
+ */
1793
+ export function repeat_<E, A>(fa: Observable<E, A>, count = Infinity): Observable<E, A> {
1794
+ return count <= 0
1795
+ ? empty()
1796
+ : fa.operate((source, subscriber) => {
1797
+ let repeats = 0;
1798
+ let innerSub: Subscription | null;
1799
+ const loop = () => {
1800
+ let syncUnsub = false;
1801
+ innerSub = source.subscribe(
1802
+ operatorSubscriber(subscriber, {
1803
+ complete: () => {
1804
+ if (++repeats < count) {
1805
+ if (innerSub) {
1806
+ innerSub.unsubscribe();
1807
+ innerSub = null;
1808
+ loop();
1809
+ } else {
1810
+ syncUnsub = true;
1811
+ }
1812
+ } else {
1813
+ subscriber.complete;
1814
+ }
1815
+ },
1816
+ }),
1817
+ );
1818
+
1819
+ if (syncUnsub) {
1820
+ innerSub.unsubscribe();
1821
+ innerSub = null;
1822
+ loop();
1823
+ }
1824
+ };
1825
+ loop();
1826
+ });
1827
+ }
1828
+
1829
+ export interface RetryConfig {
1830
+ readonly count: number;
1831
+ readonly resetOnSuccess?: boolean;
1832
+ }
1833
+
1834
+ /**
1835
+ * @tsplus fluent fncts.observable.Observable retry
1836
+ */
1837
+ export function retry_<E, A>(fa: Observable<E, A>, count?: number): Observable<E, A>;
1838
+ export function retry_<E, A>(fa: Observable<E, A>, config: RetryConfig): Observable<E, A>;
1839
+ export function retry_<E, A>(fa: Observable<E, A>, configOrCount: number | RetryConfig = Infinity): Observable<E, A> {
1840
+ let config: RetryConfig;
1841
+ if (configOrCount && typeof configOrCount === "object") {
1842
+ config = configOrCount;
1843
+ } else {
1844
+ config = {
1845
+ count: configOrCount,
1846
+ };
1847
+ }
1848
+
1849
+ const { count, resetOnSuccess = false } = config;
1850
+
1851
+ return count <= 0
1852
+ ? fa
1853
+ : fa.operate((source, subscriber) => {
1854
+ let retries = 0;
1855
+ let innerSub: Subscription | null;
1856
+ const loop = () => {
1857
+ let syncUnsub = false;
1858
+ innerSub = source.subscribe(
1859
+ operatorSubscriber(subscriber, {
1860
+ next: (value) => {
1861
+ if (resetOnSuccess) {
1862
+ retries = 0;
1863
+ }
1864
+ subscriber.next(value);
1865
+ },
1866
+ error: (err) => {
1867
+ if (retries++ < count) {
1868
+ if (innerSub) {
1869
+ innerSub.unsubscribe();
1870
+ innerSub = null;
1871
+ loop();
1872
+ } else {
1873
+ syncUnsub = true;
1874
+ }
1875
+ } else {
1876
+ subscriber.error(err);
1877
+ }
1878
+ },
1879
+ }),
1880
+ );
1881
+ if (syncUnsub) {
1882
+ innerSub.unsubscribe();
1883
+ innerSub = null;
1884
+ loop();
1885
+ }
1886
+ };
1887
+ loop();
1888
+ });
1889
+ }
1890
+
1891
+ /**
1892
+ * @tsplus fluent fncts.observable.Observable sample
1893
+ */
1894
+ export function sample_<E, A, E1>(fa: Observable<E, A>, notifier: Observable<E1, any>): Observable<E | E1, A> {
1895
+ return fa.operate((source, subscriber) => {
1896
+ let hasValue = false;
1897
+ let lastValue: A | null = null;
1898
+ source.subscribe(
1899
+ operatorSubscriber(subscriber, {
1900
+ next: (value) => {
1901
+ hasValue = true;
1902
+ lastValue = value;
1903
+ },
1904
+ }),
1905
+ );
1906
+ const emit = () => {
1907
+ if (hasValue) {
1908
+ hasValue = false;
1909
+ const value = lastValue!;
1910
+ lastValue = null;
1911
+ subscriber.next(value);
1912
+ }
1913
+ };
1914
+ notifier.subscribe(operatorSubscriber(subscriber, { next: emit, complete: noop }));
1915
+ });
1916
+ }
1917
+
1918
+ /**
1919
+ * @tsplus fluent fncts.observable.Observable sampleTime
1920
+ */
1921
+ export function sampleTime_<E, A>(
1922
+ fa: Observable<E, A>,
1923
+ period: number,
1924
+ scheduler: SchedulerLike = asyncScheduler,
1925
+ ): Observable<E, A> {
1926
+ return sample_(fa, interval(period, scheduler));
1927
+ }
1928
+
1929
+ /**
1930
+ * @tsplus fluent fncts.observable.Observable scanLeftWithIndex
1931
+ */
1932
+ export function scanLeftWithIndex<E, A, B>(
1933
+ fa: Observable<E, A>,
1934
+ initial: B,
1935
+ f: (index: number, acc: B, value: A) => B,
1936
+ ): Observable<E, B> {
1937
+ return fa.operate(scanInternal(f, initial, true, true));
1938
+ }
1939
+
1940
+ /**
1941
+ * @tsplus fluent fncts.observable.Observable scanLeft
1942
+ */
1943
+ export function scanLeft<E, A, B>(fa: Observable<E, A>, initial: B, f: (acc: B, value: A) => B): Observable<E, B> {
1944
+ return fa.scanLeftWithIndex(initial, (_, b, a) => f(b, a));
1945
+ }
1946
+
1947
+ /**
1948
+ * @tsplus fluent fncts.observable.Observable skip
1949
+ */
1950
+ export function skip_<E, A>(fa: Observable<E, A>, count: number): Observable<E, A> {
1951
+ return fa.filterWithIndex((index, _) => count <= index);
1952
+ }
1953
+
1954
+ /**
1955
+ * @tsplus fluent fncts.observable.Observable skipLast
1956
+ */
1957
+ export function skipLast_<E, A>(fa: Observable<E, A>, skipCount: number): Observable<E, A> {
1958
+ return skipCount <= 0
1959
+ ? fa
1960
+ : fa.operate((source, subscriber) => {
1961
+ let ring: A[] = new Array(skipCount);
1962
+ let seen = 0;
1963
+ source.subscribe(
1964
+ operatorSubscriber(subscriber, {
1965
+ next: (value) => {
1966
+ const valueIndex = seen++;
1967
+ if (valueIndex < skipCount) {
1968
+ ring[valueIndex] = value;
1969
+ } else {
1970
+ const index = valueIndex % skipCount;
1971
+ const oldValue = ring[index];
1972
+ ring[index] = value;
1973
+ subscriber.next(oldValue!);
1974
+ }
1975
+ },
1976
+ }),
1977
+ );
1978
+
1979
+ return () => {
1980
+ ring = null!;
1981
+ };
1982
+ });
1983
+ }
1984
+
1985
+ /**
1986
+ * @tsplus fluent fncts.observable.Observable skipUntil
1987
+ */
1988
+ export function skipUntil_<E, A, E1>(fa: Observable<E, A>, notifier: Observable<E1, any>): Observable<E | E1, A> {
1989
+ return fa.operate((source, subscriber) => {
1990
+ let taking = false;
1991
+ const skipSubscriber = operatorSubscriber(subscriber, {
1992
+ next: () => {
1993
+ skipSubscriber?.unsubscribe();
1994
+ taking = true;
1995
+ },
1996
+ complete: noop,
1997
+ });
1998
+
1999
+ from(notifier).subscribe(skipSubscriber);
2000
+
2001
+ source.subscribe(
2002
+ operatorSubscriber(subscriber, {
2003
+ next: (value) => taking && subscriber.next(value),
2004
+ }),
2005
+ );
2006
+ });
2007
+ }
2008
+
2009
+ /**
2010
+ * @tsplus fluent fncts.observable.Observable skipWhile
2011
+ */
2012
+ export function skipWhile_<E, A>(fa: Observable<E, A>, predicate: PredicateWithIndex<number, A>): Observable<E, A> {
2013
+ return fa.operate((source, subscriber) => {
2014
+ let taking = false;
2015
+ let index = 0;
2016
+ source.subscribe(
2017
+ operatorSubscriber(subscriber, {
2018
+ next: (value) => (taking || (taking = !predicate(index++, value))) && subscriber.next(value),
2019
+ }),
2020
+ );
2021
+ });
2022
+ }
2023
+
2024
+ /**
2025
+ * @tsplus fluent fncts.observable.Observable startWith
2026
+ */
2027
+ export function startWith_<E, A, B extends ReadonlyArray<unknown>>(
2028
+ fa: Observable<E, A>,
2029
+ ...values: B
2030
+ ): Observable<E, A | B[number]> {
2031
+ return operate_(fa, (source, subscriber) => {
2032
+ // @ts-expect-error
2033
+ source.concat(values).subscribe(subscriber);
2034
+ });
2035
+ }
2036
+
2037
+ /**
2038
+ * @tsplus fluent fncts.observable.Observable subscribeOn
2039
+ */
2040
+ export function subscribeOn_<E, A>(fa: Observable<E, A>, scheduler: SchedulerLike, delay = 0): Observable<E, A> {
2041
+ return fa.operate((source, subscriber) => {
2042
+ subscriber.add(scheduler.schedule(() => source.subscribe(subscriber), delay));
2043
+ });
2044
+ }
2045
+
2046
+ /**
2047
+ * @tsplus getter fncts.observable.Observable switchAll
2048
+ */
2049
+ export function switchAll<E, E1, A>(ffa: Observable<E, ObservableInput<E1, A>>): Observable<E | E1, A> {
2050
+ return switchMap_(ffa, Function.identity);
2051
+ }
2052
+
2053
+ /**
2054
+ * @tsplus fluent fncts.observable.Observable switchMapWithIndex
2055
+ */
2056
+ export function switchMapWithIndex<E, A, E1, B>(
2057
+ fa: Observable<E, A>,
2058
+ f: (index: number, value: A) => ObservableInput<E1, B>,
2059
+ ): Observable<E | E1, B> {
2060
+ return operate_(fa, (source, subscriber) => {
2061
+ let innerSubscriber: Subscriber<E | E1, B> | null = null;
2062
+ let index = 0;
2063
+ let isComplete = false;
2064
+
2065
+ const checkComplete = () => isComplete && !innerSubscriber && subscriber.complete();
2066
+
2067
+ source.subscribe(
2068
+ operatorSubscriber(
2069
+ subscriber,
2070
+ {
2071
+ next: (value) => {
2072
+ innerSubscriber?.unsubscribe();
2073
+ const outerIndex = index++;
2074
+ from(f(outerIndex, value)).subscribe(
2075
+ (innerSubscriber = operatorSubscriber(subscriber, {
2076
+ next: (innerValue) => subscriber.next(innerValue),
2077
+ complete: () => {
2078
+ innerSubscriber = null!;
2079
+ checkComplete();
2080
+ },
2081
+ })),
2082
+ );
2083
+ },
2084
+ },
2085
+ () => {
2086
+ isComplete = true;
2087
+ checkComplete();
2088
+ },
2089
+ ),
2090
+ );
2091
+ });
2092
+ }
2093
+
2094
+ /**
2095
+ * @tsplus fluent fncts.observable.Observable switchMap
2096
+ */
2097
+ export function switchMap_<E, A, E1, B>(
2098
+ fa: Observable<E, A>,
2099
+ f: (value: A) => ObservableInput<E1, B>,
2100
+ ): Observable<E | E1, B> {
2101
+ return fa.switchMapWithIndex((_, a) => f(a));
2102
+ }
2103
+
2104
+ /**
2105
+ * @tsplus fluent fncts.observable.Observable switchScanWithIndex
2106
+ */
2107
+ export function switchScanWithIndex<E, A, E1, B>(
2108
+ fa: Observable<E, A>,
2109
+ initial: B,
2110
+ f: (index: number, acc: B, value: A) => ObservableInput<E1, B>,
2111
+ ): Observable<E | E1, B> {
2112
+ return operate_(fa, (source, subscriber) => {
2113
+ let state = initial;
2114
+ switchMapWithIndex(source, (index, value) => from(f(index, state, value)).map((b) => ((state = b), b))).subscribe(
2115
+ subscriber,
2116
+ );
2117
+ return () => {
2118
+ state = null!;
2119
+ };
2120
+ });
2121
+ }
2122
+
2123
+ /**
2124
+ * @tsplus fluent fncts.observable.Observable switchScan
2125
+ */
2126
+ export function switchScan_<E, A, E1, B>(
2127
+ fa: Observable<E, A>,
2128
+ initial: B,
2129
+ f: (acc: B, value: A) => ObservableInput<E1, B>,
2130
+ ): Observable<E | E1, B> {
2131
+ return fa.switchScanWithIndex(initial, (_, b, a) => f(b, a));
2132
+ }
2133
+
2134
+ /**
2135
+ * @tsplus fluent fncts.observable.Observable take
2136
+ */
2137
+ export function take_<E, A>(fa: Observable<E, A>, count: number): Observable<E, A> {
2138
+ return count <= 0
2139
+ ? empty()
2140
+ : fa.operate((source, sub) => {
2141
+ let seen = 0;
2142
+ source.subscribe(
2143
+ new OperatorSubscriber(sub, {
2144
+ next: (value) => {
2145
+ if (++seen <= count) {
2146
+ sub.next(value);
2147
+ if (count <= seen) {
2148
+ sub.complete();
2149
+ }
2150
+ }
2151
+ },
2152
+ }),
2153
+ );
2154
+ });
2155
+ }
2156
+
2157
+ /**
2158
+ * @tsplus fluent fncts.observable.Observable takeLast
2159
+ */
2160
+ export function takeLast_<E, A>(fa: Observable<E, A>, count: number): Observable<E, A> {
2161
+ return count <= 0
2162
+ ? empty()
2163
+ : fa.operate((source, subscriber) => {
2164
+ let buffer: A[] = [];
2165
+ source.subscribe(
2166
+ operatorSubscriber(
2167
+ subscriber,
2168
+ {
2169
+ next: (value) => {
2170
+ buffer.push(value);
2171
+ count < buffer.length && buffer.shift();
2172
+ },
2173
+ complete: () => {
2174
+ for (const value of buffer) {
2175
+ subscriber.next(value);
2176
+ }
2177
+ subscriber.complete();
2178
+ },
2179
+ },
2180
+ () => {
2181
+ buffer = null!;
2182
+ },
2183
+ ),
2184
+ );
2185
+ });
2186
+ }
2187
+
2188
+ /**
2189
+ * @tsplus fluent fncts.observable.Observable takeUntil
2190
+ */
2191
+ export function takeUntil_<E, A, E1>(fa: Observable<E, A>, notifier: ObservableInput<E1, any>): Observable<E | E1, A> {
2192
+ return fa.operate((source, subscriber) => {
2193
+ from(notifier).subscribe(operatorSubscriber(subscriber, { next: () => subscriber.complete(), complete: noop }));
2194
+ !subscriber.closed && source.subscribe(subscriber);
2195
+ });
2196
+ }
2197
+
2198
+ /**
2199
+ * @tsplus fluent fncts.observable.Observable takeWhileWithIndex
2200
+ */
2201
+ export function takeWhileWithIndex<E, A, B extends A>(
2202
+ fa: Observable<E, A>,
2203
+ refinement: RefinementWithIndex<number, A, B>,
2204
+ inclusive?: boolean,
2205
+ ): Observable<E, B>;
2206
+ export function takeWhileWithIndex<E, A>(
2207
+ fa: Observable<E, A>,
2208
+ predicate: PredicateWithIndex<number, A>,
2209
+ inclusive?: boolean,
2210
+ ): Observable<E, A>;
2211
+ export function takeWhileWithIndex<E, A>(
2212
+ fa: Observable<E, A>,
2213
+ predicate: PredicateWithIndex<number, A>,
2214
+ inclusive?: boolean,
2215
+ ): Observable<E, A> {
2216
+ return fa.operate((source, subscriber) => {
2217
+ let index = 0;
2218
+ source.subscribe(
2219
+ operatorSubscriber(subscriber, {
2220
+ next: (value) => {
2221
+ const result = predicate(index++, value);
2222
+ (result || inclusive) && subscriber.next(value);
2223
+ !result && subscriber.complete();
2224
+ },
2225
+ }),
2226
+ );
2227
+ });
2228
+ }
2229
+
2230
+ /**
2231
+ * @tsplus fluent fncts.observable.Observable takeWhile
2232
+ */
2233
+ export function takeWhile_<E, A, B extends A>(
2234
+ fa: Observable<E, A>,
2235
+ refinement: Refinement<A, B>,
2236
+ inclusive?: boolean,
2237
+ ): Observable<E, B>;
2238
+ export function takeWhile_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>, inclusive?: boolean): Observable<E, A>;
2239
+ export function takeWhile_<E, A>(fa: Observable<E, A>, predicate: Predicate<A>, inclusive?: boolean): Observable<E, A> {
2240
+ return fa.takeWhileWithIndex((_, a) => predicate(a), inclusive);
2241
+ }
2242
+
2243
+ /**
2244
+ * @tsplus fluent fncts.observable.Observable tap
2245
+ */
2246
+ export function tap_<E, A>(fa: Observable<E, A>, observer: Partial<Observer<E, A>>): Observable<E, A> {
2247
+ return fa.operate((source, subscriber) => {
2248
+ source.subscribe(
2249
+ operatorSubscriber(subscriber, {
2250
+ next: (value) => {
2251
+ observer.next?.(value);
2252
+ subscriber.next(value);
2253
+ },
2254
+ error: (err) => {
2255
+ observer.error?.(err);
2256
+ subscriber.error(err);
2257
+ },
2258
+ complete: () => {
2259
+ observer.complete?.();
2260
+ subscriber.complete();
2261
+ },
2262
+ }),
2263
+ );
2264
+ });
2265
+ }
2266
+
2267
+ export interface ThrottleConfig {
2268
+ readonly leading?: boolean;
2269
+ readonly trailing?: boolean;
2270
+ }
2271
+
2272
+ export const defaultThrottleConfig: ThrottleConfig = {
2273
+ leading: true,
2274
+ trailing: false,
2275
+ };
2276
+
2277
+ /**
2278
+ * @tsplus fluent fncts.observable.Observable throttle
2279
+ */
2280
+ export function throttle_<E, A, E1>(
2281
+ fa: Observable<E, A>,
2282
+ durationSelector: (a: A) => ObservableInput<E1, any>,
2283
+ { leading, trailing }: ThrottleConfig = defaultThrottleConfig,
2284
+ ): Observable<E | E1, A> {
2285
+ return fa.operate((source, subscriber) => {
2286
+ let sendValue: Maybe<A> = Nothing();
2287
+ let throttled: Subscription | null = null;
2288
+ let isComplete = false;
2289
+
2290
+ const endThrottling = () => {
2291
+ throttled?.unsubscribe();
2292
+ throttled = null;
2293
+ if (trailing) {
2294
+ send();
2295
+ isComplete && subscriber.complete();
2296
+ }
2297
+ };
2298
+
2299
+ const cleanupThrottling = () => {
2300
+ throttled = null;
2301
+ isComplete && subscriber.complete();
2302
+ };
2303
+
2304
+ const startThrottling = (value: A) =>
2305
+ (throttled = from(durationSelector(value)).subscribe(
2306
+ operatorSubscriber(subscriber, { next: endThrottling, complete: cleanupThrottling }),
2307
+ ));
2308
+
2309
+ const send = () => {
2310
+ if (sendValue.isJust()) {
2311
+ const { value } = sendValue;
2312
+ sendValue = Nothing();
2313
+ subscriber.next(value);
2314
+ !isComplete && startThrottling(value);
2315
+ }
2316
+ };
2317
+
2318
+ source.subscribe(
2319
+ operatorSubscriber(subscriber, {
2320
+ next: (value) => {
2321
+ sendValue = Just(value);
2322
+ !(throttled && !throttled.closed) && (leading ? send() : startThrottling(value));
2323
+ },
2324
+ complete: () => {
2325
+ isComplete = true;
2326
+ !(trailing && sendValue.isJust() && throttled && !throttled.closed) && subscriber.complete();
2327
+ },
2328
+ }),
2329
+ );
2330
+ });
2331
+ }
2332
+
2333
+ /**
2334
+ * @tsplus fluent fncts.observable.Observable throttleTime
2335
+ */
2336
+ export function throttleTime_<E, A>(
2337
+ fa: Observable<E, A>,
2338
+ duration: number,
2339
+ scheduler: SchedulerLike = asyncScheduler,
2340
+ config = defaultThrottleConfig,
2341
+ ): Observable<E, A> {
2342
+ const duration$ = timer(duration, scheduler);
2343
+ return throttle_(fa, () => duration$, config);
2344
+ }
2345
+
2346
+ export type TimeoutConfig<A, E, B, M = unknown> = (
2347
+ | { readonly each: number; readonly first?: number | Date }
2348
+ | { readonly each?: number; readonly first: number | Date }
2349
+ ) & {
2350
+ readonly scheduler?: SchedulerLike;
2351
+ readonly with?: (info: TimeoutInfo<A, M>) => ObservableInput<E, B>;
2352
+ meta?: M;
2353
+ };
2354
+
2355
+ export interface TimeoutInfo<A, M> {
2356
+ readonly meta?: M;
2357
+ readonly seen: number;
2358
+ readonly lastValue: Maybe<A>;
2359
+ }
2360
+
2361
+ export class TimeoutError<A, M> extends Error {
2362
+ constructor(readonly info: TimeoutInfo<A, M> | null) {
2363
+ super("Timeout has occurred");
2364
+ this.name = "TimeoutError";
2365
+ }
2366
+ }
2367
+
2368
+ /**
2369
+ * @tsplus fluent fncts.observable.Observable timeout
2370
+ */
2371
+ export function timeout_<E, A, E1, B, M = unknown>(
2372
+ fa: Observable<E, A>,
2373
+ config: TimeoutConfig<A, E1, B, M> & { readonly with: (info: TimeoutInfo<A, M>) => ObservableInput<E1, B> },
2374
+ ): Observable<E | E1, A | B>;
2375
+ export function timeout_<E, A, M = unknown>(
2376
+ fa: Observable<E, A>,
2377
+ config: Omit<TimeoutConfig<A, never, any, M>, "with">,
2378
+ ): Observable<E | TimeoutError<A, M>, A>;
2379
+ export function timeout_<E, A, E1, B, M = unknown>(
2380
+ fa: Observable<E, A>,
2381
+ config: any,
2382
+ ): Observable<E | E1 | TimeoutError<A, M>, A | B> {
2383
+ const {
2384
+ first,
2385
+ each,
2386
+ with: _with = timeoutError,
2387
+ scheduler = asyncScheduler,
2388
+ meta = null!,
2389
+ } = config as TimeoutConfig<A, E1, B, M>;
2390
+ return operate_(fa, (source, subscriber) => {
2391
+ // eslint-disable-next-line prefer-const
2392
+ let originalSourceSubscription: Subscription;
2393
+ let timerSubscription: Subscription;
2394
+ let lastValue: Maybe<A> = Nothing();
2395
+ let seen = 0;
2396
+ const startTimer = (delay: number) => {
2397
+ timerSubscription = caughtSchedule(
2398
+ subscriber,
2399
+ scheduler,
2400
+ () => {
2401
+ originalSourceSubscription.unsubscribe();
2402
+ from<E1 | TimeoutError<A, M>, B>(
2403
+ _with({
2404
+ meta,
2405
+ lastValue,
2406
+ seen,
2407
+ }),
2408
+ ).subscribe(subscriber);
2409
+ },
2410
+ delay,
2411
+ );
2412
+ };
2413
+
2414
+ originalSourceSubscription = source.subscribe(
2415
+ operatorSubscriber(
2416
+ subscriber,
2417
+ {
2418
+ next: (value) => {
2419
+ timerSubscription?.unsubscribe();
2420
+ seen++;
2421
+ lastValue = Just(value);
2422
+ subscriber.next(value);
2423
+ each! > 0 && startTimer(each!);
2424
+ },
2425
+ },
2426
+ () => {
2427
+ if (!timerSubscription?.closed) {
2428
+ timerSubscription?.unsubscribe();
2429
+ }
2430
+ lastValue = Nothing();
2431
+ },
2432
+ ),
2433
+ );
2434
+
2435
+ startTimer(first != null ? (typeof first === "number" ? first : +first - scheduler.now()) : each!);
2436
+ });
2437
+ }
2438
+
2439
+ function timeoutError<A, M>(info: TimeoutInfo<A, M>): Observable<TimeoutError<A, M>, never> {
2440
+ return fail(new TimeoutError(info));
2441
+ }
2442
+
2443
+ function toArrayAccumulator(arr: any[], value: any) {
2444
+ return arr.push(value), arr;
2445
+ }
2446
+
2447
+ /**
2448
+ * @tsplus getter fncts.observable.Observable toArray
2449
+ */
2450
+ export function toArray<E, A>(fa: Observable<E, A>): Observable<E, ReadonlyArray<A>> {
2451
+ return operate_(fa, (source, subscriber) => {
2452
+ source.foldLeft([] as A[], toArrayAccumulator).subscribe(subscriber);
2453
+ });
2454
+ }
2455
+
2456
+ /**
2457
+ * @tsplus fluent fncts.observable.Observable unique
2458
+ */
2459
+ export function unique_<E, A, K, E1 = never>(
2460
+ fa: Observable<E, A>,
2461
+ toKey?: (value: A) => K,
2462
+ flushes?: Observable<E1, any>,
2463
+ ): Observable<E | E1, A> {
2464
+ return operate_(fa, (source, subscriber) => {
2465
+ let distinctKeys = HashSet.makeDefault<A | K>();
2466
+ source.subscribe(
2467
+ operatorSubscriber(subscriber, {
2468
+ next: (value) => {
2469
+ const key = toKey ? toKey(value) : value;
2470
+ if (!distinctKeys.has(key)) {
2471
+ distinctKeys.add(key);
2472
+ subscriber.next(value);
2473
+ }
2474
+ },
2475
+ }),
2476
+ );
2477
+ flushes?.subscribe(
2478
+ operatorSubscriber(subscriber, { next: () => (distinctKeys = HashSet.makeDefault()), complete: noop }),
2479
+ );
2480
+ });
2481
+ }
2482
+
2483
+ /**
2484
+ * @tsplus fluent fncts.observable.Observable uniqueUntilChanged
2485
+ */
2486
+ export function uniqueUntilChanged_<E, A, K>(
2487
+ fa: Observable<E, A>,
2488
+ E: Eq<K>,
2489
+ keySelector: (value: A) => K,
2490
+ ): Observable<E, A>;
2491
+ export function uniqueUntilChanged_<E, A, K>(
2492
+ fa: Observable<E, A>,
2493
+ equals: (x: K, y: K) => boolean,
2494
+ keySelector: (value: A) => K,
2495
+ ): Observable<E, A>;
2496
+ export function uniqueUntilChanged_<E, A>(fa: Observable<E, A>, E: Eq<A>): Observable<E, A>;
2497
+ export function uniqueUntilChanged_<E, A>(fa: Observable<E, A>, equals: (x: A, y: A) => boolean): Observable<E, A>;
2498
+ export function uniqueUntilChanged_<E, A, K = A>(
2499
+ fa: Observable<E, A>,
2500
+ E: Eq<K> | ((x: K, y: K) => boolean),
2501
+ keySelector: (value: A) => K = Function.identity as (_: A) => K,
2502
+ ): Observable<E, A> {
2503
+ const compare = "equals" in E ? E.equals : E;
2504
+ return fa.operate((source, subscriber) => {
2505
+ let previousKey: K;
2506
+ let first = true;
2507
+ source.subscribe(
2508
+ operatorSubscriber(subscriber, {
2509
+ next: (value) => {
2510
+ const currentKey = keySelector(value);
2511
+ if (first || !compare(previousKey, currentKey)) {
2512
+ first = false;
2513
+ previousKey = currentKey;
2514
+ subscriber.next(value);
2515
+ }
2516
+ },
2517
+ }),
2518
+ );
2519
+ });
2520
+ }
2521
+
2522
+ /**
2523
+ * @tsplus fluent fncts.observable.Observable uniqueUntilKeyChanged
2524
+ */
2525
+ export function uniqueUntilKeyChanged_<E, A, K extends keyof A>(
2526
+ fa: Observable<E, A>,
2527
+ key: K,
2528
+ E: Eq<A[K]>,
2529
+ ): Observable<E, A>;
2530
+ export function uniqueUntilKeyChanged_<E, A, K extends keyof A>(
2531
+ fa: Observable<E, A>,
2532
+ key: K,
2533
+ equals: (x: A[K], y: A[K]) => boolean,
2534
+ ): Observable<E, A>;
2535
+ export function uniqueUntilKeyChanged_<E, A, K extends keyof A>(
2536
+ fa: Observable<E, A>,
2537
+ key: K,
2538
+ equals: Eq<A[K]> | ((x: A[K], y: A[K]) => boolean),
2539
+ ): Observable<E, A> {
2540
+ const compare = "equals" in equals ? equals.equals : equals;
2541
+ return fa.uniqueUntilChanged((x, y) => compare(x[key], y[key]));
2542
+ }
2543
+
2544
+ /*
2545
+ * -------------------------------------------------------------------------------------------------
2546
+ * internal
2547
+ * -------------------------------------------------------------------------------------------------
2548
+ */
2549
+
2550
+ function combineLatestInternal(
2551
+ subscriber: Subscriber<any, any>,
2552
+ observables: ObservableInput<any, any>[],
2553
+ scheduler?: SchedulerLike,
2554
+ valueTransform: (values: any[]) => any = Function.identity,
2555
+ ) {
2556
+ return maybeSchedule(subscriber, scheduler, () => {
2557
+ const { length } = observables;
2558
+ const values = new Array(length);
2559
+ let active = length;
2560
+ let remainingFirstValues = length;
2561
+ for (let i = 0; i < length; i++) {
2562
+ maybeSchedule(subscriber, scheduler, () => {
2563
+ const source = scheduler ? scheduled(observables[i]!, scheduler) : from(observables[i]!);
2564
+ let hasFirstValue = false;
2565
+ source.subscribe(
2566
+ operatorSubscriber(subscriber, {
2567
+ next: (value) => {
2568
+ values[i] = value;
2569
+ if (!hasFirstValue) {
2570
+ hasFirstValue = true;
2571
+ remainingFirstValues--;
2572
+ }
2573
+ if (!remainingFirstValues) {
2574
+ subscriber.next(valueTransform(values.slice()));
2575
+ }
2576
+ },
2577
+ complete: () => {
2578
+ if (!--active) {
2579
+ subscriber.complete();
2580
+ }
2581
+ },
2582
+ }),
2583
+ );
2584
+ });
2585
+ }
2586
+ });
2587
+ }
2588
+
2589
+ function findInternal<A>(
2590
+ predicate: PredicateWithIndex<number, A>,
2591
+ emit: "value" | "index",
2592
+ ): <E>(source: Observable<E, A>, subscriber: Subscriber<E, any>) => void {
2593
+ const findIndex = emit === "index";
2594
+ return (source, subscriber) => {
2595
+ let index = 0;
2596
+ source.subscribe(
2597
+ operatorSubscriber(subscriber, {
2598
+ next: (value) => {
2599
+ const i = index++;
2600
+ if (predicate(index++, value)) {
2601
+ subscriber.next(findIndex ? i : Just(value));
2602
+ subscriber.complete();
2603
+ }
2604
+ },
2605
+ complete: () => {
2606
+ subscriber.next(findIndex ? -1 : Nothing());
2607
+ subscriber.complete();
2608
+ },
2609
+ }),
2610
+ );
2611
+ };
2612
+ }
2613
+
2614
+ export function joinAllInternal<E, E1, A, E2, B>(
2615
+ fa: Observable<E, ObservableInput<E1, A>>,
2616
+ joiner: (sources: ReadonlyArray<ObservableInput<E1, A>>) => Observable<E2, B>,
2617
+ ): Observable<E | E1 | E2, B> {
2618
+ return fa.toArray.mergeMap(joiner);
2619
+ }
2620
+
2621
+ function maybeSchedule(subscription: Subscription, scheduler: SchedulerLike | undefined, execute: () => void) {
2622
+ if (scheduler) {
2623
+ subscription.add(scheduler.schedule(execute));
2624
+ } else {
2625
+ execute();
2626
+ }
2627
+ }
2628
+
2629
+ function mergeInternal<E, A, E1, B>(
2630
+ source: Observable<E, A>,
2631
+ subscriber: Subscriber<E | E1, B>,
2632
+ f: (i: number, a: A) => ObservableInput<E1, B>,
2633
+ concurrent: number,
2634
+ onBeforeNext?: (innerValue: B) => void,
2635
+ expand?: boolean,
2636
+ innerSubScheduler?: SchedulerLike,
2637
+ additionalTeardown?: () => void,
2638
+ ) {
2639
+ const buffer: Array<A> = [];
2640
+ let active = 0;
2641
+ let index = 0;
2642
+ let isComplete = false;
2643
+
2644
+ const checkComplete = () => {
2645
+ if (isComplete && !buffer.length && !active) {
2646
+ subscriber.complete();
2647
+ }
2648
+ };
2649
+
2650
+ const outerNext = (a: A) => (active < concurrent ? doInnerSub(a) : buffer.push(a));
2651
+
2652
+ const doInnerSub = (a: A) => {
2653
+ expand && subscriber.next(a as any);
2654
+ active++;
2655
+ let innerComplete = false;
2656
+ from(f(index++, a)).subscribe(
2657
+ new OperatorSubscriber(
2658
+ subscriber,
2659
+ {
2660
+ next: (b) => {
2661
+ onBeforeNext?.(b);
2662
+
2663
+ if (expand) {
2664
+ outerNext(b as any);
2665
+ } else {
2666
+ subscriber.next(b);
2667
+ }
2668
+ },
2669
+ complete: () => {
2670
+ innerComplete = true;
2671
+ },
2672
+ },
2673
+ () => {
2674
+ if (innerComplete) {
2675
+ try {
2676
+ active--;
2677
+ while (buffer.length && active < concurrent) {
2678
+ const bufferedValue = buffer.shift()!;
2679
+ innerSubScheduler
2680
+ ? subscriber.add(innerSubScheduler.schedule(() => doInnerSub(bufferedValue)))
2681
+ : doInnerSub(bufferedValue);
2682
+ }
2683
+ checkComplete();
2684
+ } catch (err) {
2685
+ subscriber.error(Cause.halt(err));
2686
+ }
2687
+ }
2688
+ },
2689
+ ),
2690
+ );
2691
+ };
2692
+
2693
+ source.subscribe(
2694
+ new OperatorSubscriber(subscriber, {
2695
+ next: outerNext,
2696
+ complete: () => {
2697
+ isComplete = true;
2698
+ checkComplete();
2699
+ },
2700
+ }),
2701
+ );
2702
+
2703
+ return () => {
2704
+ additionalTeardown?.();
2705
+ };
2706
+ }
2707
+
2708
+ export function scanInternal<E, A, B>(
2709
+ f: (index: number, acc: A, value: A) => B,
2710
+ initial: B,
2711
+ hasInitial: false,
2712
+ emitOnNext: boolean,
2713
+ emitBeforeComplete?: undefined | true,
2714
+ ): (source: Observable<E, A>, subscriber: Subscriber<any, any>) => void;
2715
+ export function scanInternal<E, A, B>(
2716
+ f: (index: number, acc: B, value: A) => B,
2717
+ initial: B,
2718
+ hasInitial: true,
2719
+ emitOnNext: boolean,
2720
+ emitBeforeComplete?: undefined | true,
2721
+ ): (source: Observable<E, A>, subscriber: Subscriber<any, any>) => void;
2722
+ export function scanInternal<E, A, B>(
2723
+ f: (index: number, acc: A | B, value: A) => B,
2724
+ initial: B,
2725
+ hasInitial: boolean,
2726
+ emitOnNext: boolean,
2727
+ emitBeforeComplete?: undefined | true,
2728
+ ): (source: Observable<E, A>, subscriber: Subscriber<any, any>) => void {
2729
+ return (source, subscriber) => {
2730
+ let hasState = hasInitial;
2731
+ let state: any = initial;
2732
+ let index = 0;
2733
+ source.subscribe(
2734
+ operatorSubscriber(subscriber, {
2735
+ next: (value) => {
2736
+ const i = index++;
2737
+ state = hasState ? f(i, state, value) : ((hasState = true), value);
2738
+ emitOnNext && subscriber.next(state);
2739
+ },
2740
+ complete:
2741
+ emitBeforeComplete &&
2742
+ (() => {
2743
+ hasState && subscriber.next(state);
2744
+ subscriber.complete();
2745
+ }),
2746
+ }),
2747
+ );
2748
+ };
2749
+ }