@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,107 @@
1
+ export interface ShareConfig<E, A, E1 = never, E2 = never, E3 = never> {
2
+ readonly connector?: () => SubjectLike<E, A>;
3
+ readonly resetOnDefect?: boolean | ((err: unknown) => Observable<E1, any>);
4
+ readonly resetOnComplete?: boolean | (() => Observable<E2, any>);
5
+ readonly resetOnRefCountZero?: boolean | (() => Observable<E3, any>);
6
+ }
7
+
8
+ /**
9
+ * @tsplus fluent fncts.observable.Observable share
10
+ */
11
+ export function share_<E, A, E1 = never, E2 = never, E3 = never>(
12
+ fa: Observable<E, A>,
13
+ options: ShareConfig<E, A, E1, E2, E3> = {},
14
+ ): Observable<E | E1 | E2 | E3, A> {
15
+ const {
16
+ connector = () => new Subject<E, A>(),
17
+ resetOnDefect = true,
18
+ resetOnComplete = true,
19
+ resetOnRefCountZero = true,
20
+ } = options;
21
+
22
+ let connection: SafeSubscriber<E, A> | null = null;
23
+ let resetConnection: Subscription | null = null;
24
+ let subject: SubjectLike<E, A> | null = null;
25
+ let refCount = 0;
26
+ let hasCompleted = false;
27
+ let hasErrored = false;
28
+
29
+ const cancelReset = () => {
30
+ resetConnection?.unsubscribe();
31
+ resetConnection = null;
32
+ };
33
+
34
+ const reset = () => {
35
+ cancelReset();
36
+ connection = subject = null;
37
+ hasCompleted = hasErrored = false;
38
+ };
39
+
40
+ const resetAndUnsubscribe = () => {
41
+ const conn = connection;
42
+ reset();
43
+ conn?.unsubscribe();
44
+ };
45
+
46
+ return operate_(fa, (source, subscriber) => {
47
+ refCount++;
48
+ if (!hasErrored && !hasCompleted) {
49
+ cancelReset();
50
+ }
51
+
52
+ const dest = (subject ||= connector());
53
+
54
+ subscriber.add(() => {
55
+ refCount--;
56
+ if (refCount === 0 && !hasErrored && !hasCompleted) {
57
+ resetConnection = handleReset(resetAndUnsubscribe, resetOnRefCountZero);
58
+ }
59
+ });
60
+
61
+ dest.subscribe(subscriber);
62
+
63
+ if (!connection) {
64
+ connection = new SafeSubscriber({
65
+ next: (value) => dest.next(value),
66
+ error: (defect) => {
67
+ hasErrored = true;
68
+ cancelReset();
69
+ resetConnection = handleReset(reset, resetOnDefect, defect);
70
+ dest.error(defect);
71
+ },
72
+ complete: () => {
73
+ hasCompleted = true;
74
+ cancelReset();
75
+ resetConnection = handleReset(reset, resetOnComplete);
76
+ dest.complete();
77
+ },
78
+ });
79
+ Observable.from(source).subscribe(connection);
80
+ }
81
+ });
82
+ }
83
+
84
+ export function share<E, A, E1, E2, E3>(
85
+ options: ShareConfig<E, A, E1, E2, E3> = {},
86
+ ): (fa: Observable<E, A>) => Observable<E | E1 | E2 | E3, A> {
87
+ return (fa) => share_(fa, options);
88
+ }
89
+
90
+ function handleReset<T extends unknown[] = never[]>(
91
+ reset: () => void,
92
+ on: boolean | ((...args: T) => Observable<any, any>),
93
+ ...args: T
94
+ ): Subscription | null {
95
+ if (on === true) {
96
+ reset();
97
+ return null;
98
+ }
99
+
100
+ if (on === false) {
101
+ return null;
102
+ }
103
+
104
+ return on(...args)
105
+ .take(1)
106
+ .subscribe({ next: () => reset() });
107
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @tsplus fluent fncts.observable.Observable window
3
+ */
4
+ export function window_<E, A>(
5
+ fa: Observable<E, A>,
6
+ windowBoundaries: Observable<never, any>,
7
+ ): Observable<E, Observable<E, A>> {
8
+ return operate_(fa, (source, subscriber) => {
9
+ let windowSubject: Subject<E, A> = new Subject();
10
+ subscriber.next(windowSubject.asObservable());
11
+
12
+ const errorHandler = (err: Cause<E>) => {
13
+ windowSubject.error(err);
14
+ subscriber.error(err);
15
+ };
16
+
17
+ source.subscribe(
18
+ operatorSubscriber(subscriber, {
19
+ next: (value) => windowSubject.next(value),
20
+ error: errorHandler,
21
+ complete: () => {
22
+ windowSubject.complete();
23
+ subscriber.complete();
24
+ },
25
+ }),
26
+ );
27
+
28
+ windowBoundaries.subscribe(
29
+ operatorSubscriber(subscriber, {
30
+ next: () => {
31
+ windowSubject.complete();
32
+ subscriber.next((windowSubject = new Subject()));
33
+ },
34
+ complete: noop,
35
+ error: errorHandler,
36
+ }),
37
+ );
38
+
39
+ return () => {
40
+ windowSubject.unsubscribe();
41
+ windowSubject = null!;
42
+ };
43
+ });
44
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @tsplus fluent fncts.observable.Observable windowCount
3
+ */
4
+ export function windowCount_<E, A>(
5
+ fa: Observable<E, A>,
6
+ windowSize: number,
7
+ startWindowEvery = 0,
8
+ ): Observable<E, Observable<E, A>> {
9
+ const startEvery = startWindowEvery > 0 ? startWindowEvery : windowSize;
10
+
11
+ return operate_(fa, (source, subscriber) => {
12
+ let windows = [new Subject<E, A>()];
13
+ let count = 0;
14
+
15
+ subscriber.next(windows[0]!.asObservable());
16
+
17
+ source.subscribe(
18
+ operatorSubscriber(
19
+ subscriber,
20
+ {
21
+ next: (value) => {
22
+ for (const window of windows) {
23
+ window.next(value);
24
+ }
25
+
26
+ const c = count - windowSize + 1;
27
+ if (c >= 0 && c % startEvery === 0) {
28
+ windows.shift()!.complete();
29
+ }
30
+
31
+ if (++count && startEvery === 0) {
32
+ const window = new Subject<E, A>();
33
+ windows.push(window);
34
+ subscriber.next(window.asObservable());
35
+ }
36
+ },
37
+ complete: () => {
38
+ while (windows.length > 0) {
39
+ windows.shift()!.complete();
40
+ }
41
+ subscriber.complete();
42
+ },
43
+ error: (err) => {
44
+ while (windows.length > 0) {
45
+ windows.shift()!.error(err);
46
+ }
47
+ subscriber.error(err);
48
+ },
49
+ },
50
+ () => {
51
+ windows = null!;
52
+ },
53
+ ),
54
+ );
55
+ });
56
+ }
@@ -0,0 +1,102 @@
1
+ import { popScheduler } from "@fncts/observable/internal/args";
2
+ import { arrayRemove } from "@fncts/observable/internal/util";
3
+
4
+ interface WindowRecord<E, A> {
5
+ seen: number;
6
+ window: Subject<E, A>;
7
+ subs: Subscription;
8
+ }
9
+
10
+ /**
11
+ * @tsplus fluent fncts.observable.Observable windowTime
12
+ */
13
+ export function windowTime_<E, A>(
14
+ fa: Observable<E, A>,
15
+ windowTimeSpan: number,
16
+ scheduler?: SchedulerLike,
17
+ ): Observable<E, Observable<E, A>>;
18
+ export function windowTime_<E, A>(
19
+ fa: Observable<E, A>,
20
+ windowTimeSpan: number,
21
+ windowCreationInterval: number,
22
+ scheduler?: SchedulerLike,
23
+ ): Observable<E, Observable<E, A>>;
24
+ export function windowTime_<E, A>(
25
+ fa: Observable<E, A>,
26
+ windowTimeSpan: number,
27
+ windowCreationInterval: number,
28
+ maxWindowSize: number,
29
+ scheduler?: SchedulerLike,
30
+ ): Observable<E, Observable<E, A>>;
31
+ export function windowTime_<E, A>(
32
+ fa: Observable<E, A>,
33
+ windowTimeSpan: number,
34
+ ...args: any[]
35
+ ): Observable<E, Observable<E, A>> {
36
+ const scheduler = popScheduler(args) ?? asyncScheduler;
37
+ const windowCreationInterval: number | null = args[0] ?? null;
38
+ const maxWindowSize: number = args[1] || Infinity;
39
+
40
+ return operate_(fa, (source, subscriber) => {
41
+ let windowRecords: WindowRecord<E, A>[] | null = [];
42
+ let restartOnClose = false;
43
+ const closeWindow = (record: { window: Subject<E, A>; subs: Subscription }) => {
44
+ const { window, subs } = record;
45
+ window.complete();
46
+ subs.unsubscribe();
47
+ arrayRemove(windowRecords, record);
48
+ restartOnClose && startWindow();
49
+ };
50
+ const startWindow = () => {
51
+ if (windowRecords) {
52
+ const subs = new Subscription();
53
+ subscriber.add(subs);
54
+ const window = new Subject<E, A>();
55
+ const record = {
56
+ window,
57
+ subs,
58
+ seen: 0,
59
+ };
60
+ windowRecords.push(record);
61
+ subscriber.next(window.asObservable());
62
+ subs.add(scheduler.schedule(() => closeWindow(record), windowTimeSpan));
63
+ }
64
+ };
65
+
66
+ windowCreationInterval !== null && windowCreationInterval >= 0
67
+ ? subscriber.add(
68
+ scheduler.schedule(function () {
69
+ startWindow();
70
+ !this.closed && subscriber.add(this.schedule(null, windowCreationInterval));
71
+ }, windowCreationInterval),
72
+ )
73
+ : (restartOnClose = true);
74
+
75
+ startWindow();
76
+
77
+ const loop = (cb: (record: WindowRecord<E, A>) => void) => windowRecords!.slice().forEach(cb);
78
+
79
+ const terminate = (cb: (consumer: Observer<E, any>) => void) => {
80
+ loop(({ window }) => cb(window));
81
+ cb(subscriber);
82
+ subscriber.unsubscribe();
83
+ };
84
+
85
+ source.subscribe(
86
+ operatorSubscriber(subscriber, {
87
+ next: (value) => {
88
+ loop((record) => {
89
+ record.window.next(value);
90
+ maxWindowSize <= ++record.seen && closeWindow(record);
91
+ });
92
+ },
93
+ error: (err) => terminate((consumer) => consumer.error(err)),
94
+ complete: () => terminate((consumer) => consumer.complete()),
95
+ }),
96
+ );
97
+
98
+ return () => {
99
+ windowRecords = null!;
100
+ };
101
+ });
102
+ }
@@ -0,0 +1,84 @@
1
+ import { arrayRemove } from "@fncts/observable/internal/util";
2
+
3
+ /**
4
+ * @tsplus fluent fncts.observable.Observable windowToggle
5
+ */
6
+ export function windowToggle_<E, A, E1, B, E2>(
7
+ fa: Observable<E, A>,
8
+ openings: ObservableInput<E1, B>,
9
+ closingSelector: (openValue: B) => ObservableInput<E2, any>,
10
+ ): Observable<E | E1 | E2, Observable<E, A>> {
11
+ return operate_(fa, (source, subscriber) => {
12
+ const windows: Subject<E, A>[] = [];
13
+
14
+ const handleError = (err: Cause<E>) => {
15
+ while (0 < windows.length) {
16
+ windows.shift()!.error(err);
17
+ }
18
+ subscriber.error(err);
19
+ };
20
+
21
+ Observable.from(openings).subscribe(
22
+ operatorSubscriber(subscriber, {
23
+ next: (openValue) => {
24
+ const window = new Subject<E, A>();
25
+ windows.push(window);
26
+ const closingSubscription = new Subscription();
27
+ const closeWindow = () => {
28
+ arrayRemove(windows, window);
29
+ window.complete();
30
+ closingSubscription.unsubscribe();
31
+ };
32
+
33
+ let closingNotifier: Observable<E2, any>;
34
+
35
+ try {
36
+ closingNotifier = Observable.from(closingSelector(openValue));
37
+ } catch (err) {
38
+ handleError(Cause.halt(err));
39
+ return;
40
+ }
41
+
42
+ subscriber.next(window.asObservable());
43
+
44
+ closingSubscription.add(
45
+ closingNotifier.subscribe(
46
+ operatorSubscriber(subscriber, {
47
+ next: closeWindow,
48
+ complete: noop,
49
+ error: closeWindow,
50
+ }),
51
+ ),
52
+ );
53
+ },
54
+ complete: noop,
55
+ }),
56
+ );
57
+
58
+ source.subscribe(
59
+ operatorSubscriber(
60
+ subscriber,
61
+ {
62
+ next: (value) => {
63
+ const windowsCopy = windows.slice();
64
+ for (const window of windowsCopy) {
65
+ window.next(value);
66
+ }
67
+ },
68
+ error: handleError,
69
+ complete: () => {
70
+ while (0 < windows.length) {
71
+ windows.shift()!.complete();
72
+ }
73
+ subscriber.complete();
74
+ },
75
+ },
76
+ () => {
77
+ while (0 < windows.length) {
78
+ windows.shift()!.unsubscribe();
79
+ }
80
+ },
81
+ ),
82
+ );
83
+ });
84
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @tsplus fluent fncts.observable.Observable windowWhen
3
+ */
4
+ export function windowWhen_<E, A>(
5
+ fa: Observable<E, A>,
6
+ closingSelector: () => ObservableInput<never, any>,
7
+ ): Observable<E, Observable<E, A>> {
8
+ return operate_(fa, (source, subscriber) => {
9
+ let window: Subject<E, A> | null;
10
+ let closingSubscriber: Subscriber<E, any> | undefined;
11
+
12
+ const handleError = (err: Cause<E>) => {
13
+ window!.error(err);
14
+ subscriber.error(err);
15
+ };
16
+
17
+ const openWindow = () => {
18
+ closingSubscriber?.unsubscribe();
19
+ window?.complete();
20
+ window = new Subject();
21
+ subscriber.next(window.asObservable());
22
+ let closingNotifier: Observable<never, any>;
23
+ try {
24
+ closingNotifier = Observable.from(closingSelector());
25
+ } catch (err) {
26
+ handleError(Cause.halt(err));
27
+ return;
28
+ }
29
+
30
+ closingNotifier.subscribe(
31
+ (closingSubscriber = operatorSubscriber(subscriber, {
32
+ next: openWindow,
33
+ complete: openWindow,
34
+ error: handleError,
35
+ })),
36
+ );
37
+ };
38
+
39
+ openWindow();
40
+
41
+ source.subscribe(
42
+ operatorSubscriber(
43
+ subscriber,
44
+ {
45
+ next: (value) => window!.next(value),
46
+ error: handleError,
47
+ complete: () => {
48
+ window!.complete();
49
+ subscriber.complete();
50
+ },
51
+ },
52
+ () => {
53
+ closingSubscriber?.unsubscribe();
54
+ window = null!;
55
+ },
56
+ ),
57
+ );
58
+ });
59
+ }