@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.
- package/Action.d.ts +6 -0
- package/AnimationFrameAction.d.ts +11 -0
- package/AnimationFrameScheduler.d.ts +6 -0
- package/AsyncAction.d.ts +19 -0
- package/AsyncScheduler.d.ts +11 -0
- package/BehaviorSubject.d.ts +10 -0
- package/Notification.d.ts +59 -0
- package/Observable/api/connect.d.ts +10 -0
- package/Observable/api/connectable.d.ts +24 -0
- package/Observable/api/fromCallback.d.ts +11 -0
- package/Observable/api/fromEvent.d.ts +4 -0
- package/Observable/api/index.d.ts +14 -0
- package/Observable/api/race.d.ts +9 -0
- package/Observable/api/raceWith.d.ts +6 -0
- package/Observable/api/repeatWhen.d.ts +5 -0
- package/Observable/api/retryWhen.d.ts +10 -0
- package/Observable/api/share.d.ts +16 -0
- package/Observable/api/window.d.ts +8 -0
- package/Observable/api/windowCount.d.ts +6 -0
- package/Observable/api/windowTime.d.ts +12 -0
- package/Observable/api/windowToggle.d.ts +8 -0
- package/Observable/api/windowWhen.d.ts +9 -0
- package/Observable/api.d.ts +668 -0
- package/Observable/definition.d.ts +32 -0
- package/Observable/dom/animationFrames.d.ts +6 -0
- package/Observable/instances.d.ts +1 -0
- package/Observable.d.ts +19 -0
- package/Observer.d.ts +6 -0
- package/Operator.d.ts +19 -0
- package/Scheduler.d.ts +22 -0
- package/Subject.d.ts +48 -0
- package/Subscriber.d.ts +27 -0
- package/Subscription.d.ts +41 -0
- package/_cjs/Action.cjs +27 -0
- package/_cjs/Action.cjs.map +1 -0
- package/_cjs/AnimationFrameAction.cjs +48 -0
- package/_cjs/AnimationFrameAction.cjs.map +1 -0
- package/_cjs/AnimationFrameScheduler.cjs +51 -0
- package/_cjs/AnimationFrameScheduler.cjs.map +1 -0
- package/_cjs/AsyncAction.cjs +116 -0
- package/_cjs/AsyncAction.cjs.map +1 -0
- package/_cjs/AsyncScheduler.cjs +61 -0
- package/_cjs/AsyncScheduler.cjs.map +1 -0
- package/_cjs/BehaviorSubject.cjs +52 -0
- package/_cjs/BehaviorSubject.cjs.map +1 -0
- package/_cjs/Notification.cjs +110 -0
- package/_cjs/Notification.cjs.map +1 -0
- package/_cjs/Observable/api/connect.cjs +35 -0
- package/_cjs/Observable/api/connect.cjs.map +1 -0
- package/_cjs/Observable/api/connectable.cjs +64 -0
- package/_cjs/Observable/api/connectable.cjs.map +1 -0
- package/_cjs/Observable/api/fromCallback.cjs +74 -0
- package/_cjs/Observable/api/fromCallback.cjs.map +1 -0
- package/_cjs/Observable/api/fromEvent.cjs +22 -0
- package/_cjs/Observable/api/fromEvent.cjs.map +1 -0
- package/_cjs/Observable/api/index.cjs +188 -0
- package/_cjs/Observable/api/index.cjs.map +1 -0
- package/_cjs/Observable/api/race.cjs +47 -0
- package/_cjs/Observable/api/race.cjs.map +1 -0
- package/_cjs/Observable/api/raceWith.cjs +24 -0
- package/_cjs/Observable/api/raceWith.cjs.map +1 -0
- package/_cjs/Observable/api/repeatWhen.cjs +72 -0
- package/_cjs/Observable/api/repeatWhen.cjs.map +1 -0
- package/_cjs/Observable/api/retryWhen.cjs +61 -0
- package/_cjs/Observable/api/retryWhen.cjs.map +1 -0
- package/_cjs/Observable/api/share.cjs +115 -0
- package/_cjs/Observable/api/share.cjs.map +1 -0
- package/_cjs/Observable/api/window.cjs +53 -0
- package/_cjs/Observable/api/window.cjs.map +1 -0
- package/_cjs/Observable/api/windowCount.cjs +62 -0
- package/_cjs/Observable/api/windowCount.cjs.map +1 -0
- package/_cjs/Observable/api/windowTime.cjs +90 -0
- package/_cjs/Observable/api/windowTime.cjs.map +1 -0
- package/_cjs/Observable/api/windowToggle.cjs +92 -0
- package/_cjs/Observable/api/windowToggle.cjs.map +1 -0
- package/_cjs/Observable/api/windowWhen.cjs +68 -0
- package/_cjs/Observable/api/windowWhen.cjs.map +1 -0
- package/_cjs/Observable/api.cjs +2558 -0
- package/_cjs/Observable/api.cjs.map +1 -0
- package/_cjs/Observable/definition.cjs +76 -0
- package/_cjs/Observable/definition.cjs.map +1 -0
- package/_cjs/Observable/dom/animationFrames.cjs +51 -0
- package/_cjs/Observable/dom/animationFrames.cjs.map +1 -0
- package/_cjs/Observable/instances.cjs +6 -0
- package/_cjs/Observable/instances.cjs.map +1 -0
- package/_cjs/Observable.cjs +253 -0
- package/_cjs/Observable.cjs.map +1 -0
- package/_cjs/Observer.cjs +6 -0
- package/_cjs/Observer.cjs.map +1 -0
- package/_cjs/Operator.cjs +83 -0
- package/_cjs/Operator.cjs.map +1 -0
- package/_cjs/Scheduler.cjs +62 -0
- package/_cjs/Scheduler.cjs.map +1 -0
- package/_cjs/Subject.cjs +228 -0
- package/_cjs/Subject.cjs.map +1 -0
- package/_cjs/Subscriber.cjs +172 -0
- package/_cjs/Subscriber.cjs.map +1 -0
- package/_cjs/Subscription.cjs +174 -0
- package/_cjs/Subscription.cjs.map +1 -0
- package/_cjs/demo.cjs +40 -0
- package/_cjs/demo.cjs.map +1 -0
- package/_cjs/global.cjs +4 -0
- package/_cjs/global.cjs.map +1 -0
- package/_cjs/index.cjs +65 -0
- package/_cjs/index.cjs.map +1 -0
- package/_cjs/internal/animationFrameProvider.cjs +51 -0
- package/_cjs/internal/animationFrameProvider.cjs.map +1 -0
- package/_cjs/internal/args.cjs +26 -0
- package/_cjs/internal/args.cjs.map +1 -0
- package/_cjs/internal/intervalProvider.cjs +27 -0
- package/_cjs/internal/intervalProvider.cjs.map +1 -0
- package/_cjs/internal/performanceTimestampProvider.cjs +15 -0
- package/_cjs/internal/performanceTimestampProvider.cjs.map +1 -0
- package/_cjs/internal/timeoutProvider.cjs +27 -0
- package/_cjs/internal/timeoutProvider.cjs.map +1 -0
- package/_cjs/internal/timestampProvider.cjs +15 -0
- package/_cjs/internal/timestampProvider.cjs.map +1 -0
- package/_cjs/internal/util.cjs +107 -0
- package/_cjs/internal/util.cjs.map +1 -0
- package/_mjs/Action.mjs +14 -0
- package/_mjs/Action.mjs.map +1 -0
- package/_mjs/AnimationFrameAction.mjs +33 -0
- package/_mjs/AnimationFrameAction.mjs.map +1 -0
- package/_mjs/AnimationFrameScheduler.mjs +36 -0
- package/_mjs/AnimationFrameScheduler.mjs.map +1 -0
- package/_mjs/AsyncAction.mjs +99 -0
- package/_mjs/AsyncAction.mjs.map +1 -0
- package/_mjs/AsyncScheduler.mjs +45 -0
- package/_mjs/AsyncScheduler.mjs.map +1 -0
- package/_mjs/BehaviorSubject.mjs +38 -0
- package/_mjs/BehaviorSubject.mjs.map +1 -0
- package/_mjs/Notification.mjs +80 -0
- package/_mjs/Notification.mjs.map +1 -0
- package/_mjs/Observable/api/connect.mjs +21 -0
- package/_mjs/Observable/api/connect.mjs.map +1 -0
- package/_mjs/Observable/api/connectable.mjs +45 -0
- package/_mjs/Observable/api/connectable.mjs.map +1 -0
- package/_mjs/Observable/api/fromCallback.mjs +60 -0
- package/_mjs/Observable/api/fromCallback.mjs.map +1 -0
- package/_mjs/Observable/api/fromEvent.mjs +10 -0
- package/_mjs/Observable/api/fromEvent.mjs.map +1 -0
- package/_mjs/Observable/api/index.mjs +15 -0
- package/_mjs/Observable/api/index.mjs.map +1 -0
- package/_mjs/Observable/api/race.mjs +32 -0
- package/_mjs/Observable/api/race.mjs.map +1 -0
- package/_mjs/Observable/api/raceWith.mjs +12 -0
- package/_mjs/Observable/api/raceWith.mjs.map +1 -0
- package/_mjs/Observable/api/repeatWhen.mjs +57 -0
- package/_mjs/Observable/api/repeatWhen.mjs.map +1 -0
- package/_mjs/Observable/api/retryWhen.mjs +45 -0
- package/_mjs/Observable/api/retryWhen.mjs.map +1 -0
- package/_mjs/Observable/api/share.mjs +97 -0
- package/_mjs/Observable/api/share.mjs.map +1 -0
- package/_mjs/Observable/api/window.mjs +40 -0
- package/_mjs/Observable/api/window.mjs.map +1 -0
- package/_mjs/Observable/api/windowCount.mjs +50 -0
- package/_mjs/Observable/api/windowCount.mjs.map +1 -0
- package/_mjs/Observable/api/windowTime.mjs +73 -0
- package/_mjs/Observable/api/windowTime.mjs.map +1 -0
- package/_mjs/Observable/api/windowToggle.mjs +77 -0
- package/_mjs/Observable/api/windowToggle.mjs.map +1 -0
- package/_mjs/Observable/api/windowWhen.mjs +54 -0
- package/_mjs/Observable/api/windowWhen.mjs.map +1 -0
- package/_mjs/Observable/api.mjs +2291 -0
- package/_mjs/Observable/api.mjs.map +1 -0
- package/_mjs/Observable/definition.mjs +54 -0
- package/_mjs/Observable/definition.mjs.map +1 -0
- package/_mjs/Observable/dom/animationFrames.mjs +36 -0
- package/_mjs/Observable/dom/animationFrames.mjs.map +1 -0
- package/_mjs/Observable/instances.mjs +2 -0
- package/_mjs/Observable/instances.mjs.map +1 -0
- package/_mjs/Observable.mjs +25 -0
- package/_mjs/Observable.mjs.map +1 -0
- package/_mjs/Observer.mjs +2 -0
- package/_mjs/Observer.mjs.map +1 -0
- package/_mjs/Operator.mjs +63 -0
- package/_mjs/Operator.mjs.map +1 -0
- package/_mjs/Scheduler.mjs +41 -0
- package/_mjs/Scheduler.mjs.map +1 -0
- package/_mjs/Subject.mjs +204 -0
- package/_mjs/Subject.mjs.map +1 -0
- package/_mjs/Subscriber.mjs +147 -0
- package/_mjs/Subscriber.mjs.map +1 -0
- package/_mjs/Subscription.mjs +148 -0
- package/_mjs/Subscription.mjs.map +1 -0
- package/_mjs/demo.mjs +30 -0
- package/_mjs/demo.mjs.map +1 -0
- package/_mjs/global.mjs +2 -0
- package/_mjs/global.mjs.map +1 -0
- package/_mjs/index.mjs +15 -0
- package/_mjs/index.mjs.map +1 -0
- package/_mjs/internal/animationFrameProvider.mjs +38 -0
- package/_mjs/internal/animationFrameProvider.mjs.map +1 -0
- package/_mjs/internal/args.mjs +13 -0
- package/_mjs/internal/args.mjs.map +1 -0
- package/_mjs/internal/intervalProvider.mjs +20 -0
- package/_mjs/internal/intervalProvider.mjs.map +1 -0
- package/_mjs/internal/performanceTimestampProvider.mjs +8 -0
- package/_mjs/internal/performanceTimestampProvider.mjs.map +1 -0
- package/_mjs/internal/timeoutProvider.mjs +20 -0
- package/_mjs/internal/timeoutProvider.mjs.map +1 -0
- package/_mjs/internal/timestampProvider.mjs +8 -0
- package/_mjs/internal/timestampProvider.mjs.map +1 -0
- package/_mjs/internal/util.mjs +76 -0
- package/_mjs/internal/util.mjs.map +1 -0
- package/_src/Action.ts +10 -0
- package/_src/AnimationFrameAction.ts +27 -0
- package/_src/AnimationFrameScheduler.ts +30 -0
- package/_src/AsyncAction.ts +93 -0
- package/_src/AsyncScheduler.ts +41 -0
- package/_src/BehaviorSubject.ts +28 -0
- package/_src/Notification.ts +91 -0
- package/_src/Observable/api/connect.ts +23 -0
- package/_src/Observable/api/connectable.ts +52 -0
- package/_src/Observable/api/fromCallback.ts +57 -0
- package/_src/Observable/api/fromEvent.ts +12 -0
- package/_src/Observable/api/index.ts +14 -0
- package/_src/Observable/api/race.ts +31 -0
- package/_src/Observable/api/raceWith.ts +15 -0
- package/_src/Observable/api/repeatWhen.ts +63 -0
- package/_src/Observable/api/retryWhen.ts +47 -0
- package/_src/Observable/api/share.ts +107 -0
- package/_src/Observable/api/window.ts +44 -0
- package/_src/Observable/api/windowCount.ts +56 -0
- package/_src/Observable/api/windowTime.ts +102 -0
- package/_src/Observable/api/windowToggle.ts +84 -0
- package/_src/Observable/api/windowWhen.ts +59 -0
- package/_src/Observable/api.ts +2749 -0
- package/_src/Observable/definition.ts +69 -0
- package/_src/Observable/dom/animationFrames.ts +33 -0
- package/_src/Observable/instances.ts +106 -0
- package/_src/Observable.ts +27 -0
- package/_src/Observer.ts +5 -0
- package/_src/Operator.ts +73 -0
- package/_src/Scheduler.ts +52 -0
- package/_src/Subject.ts +171 -0
- package/_src/Subscriber.ts +130 -0
- package/_src/Subscription.ts +143 -0
- package/_src/demo.ts +29 -0
- package/_src/global.ts +141 -0
- package/_src/index.ts +14 -0
- package/_src/internal/animationFrameProvider.ts +37 -0
- package/_src/internal/args.ts +11 -0
- package/_src/internal/intervalProvider.ts +27 -0
- package/_src/internal/performanceTimestampProvider.ts +12 -0
- package/_src/internal/timeoutProvider.ts +27 -0
- package/_src/internal/timestampProvider.ts +14 -0
- package/_src/internal/util.ts +94 -0
- package/demo.d.ts +1 -0
- package/global.d.ts +125 -0
- package/index.d.ts +14 -0
- package/internal/animationFrameProvider.d.ts +12 -0
- package/internal/args.d.ts +3 -0
- package/internal/intervalProvider.d.ts +12 -0
- package/internal/performanceTimestampProvider.d.ts +6 -0
- package/internal/timeoutProvider.d.ts +12 -0
- package/internal/timestampProvider.d.ts +7 -0
- package/internal/util.d.ts +28 -0
- 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
|
+
}
|