Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5187d63

Browse files
edbznhoebbelsB
authored andcommitted
refactor: drop publish, publishReplay, and ConnectableObservable
1 parent baa678f commit 5187d63

File tree

6 files changed

+95
-91
lines changed

6 files changed

+95
-91
lines changed

apps/demos/src/app/features/experiments/state/composition/parent.component.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ export class RxStateParentCompositionComponent implements OnDestroy {
2626
shareReplay(1)
2727
);
2828

29-
constructor(private source: SourceService) {
30-
// this.hotComposition1$ = this.composition1$.pipe(publishReplay(1)) as ConnectableObservable<any>
31-
// this.subscription = this.hotComposition1$.connect();
32-
}
29+
constructor(private source: SourceService) {}
3330

3431
ngOnDestroy(): void {
3532
this.subscription.unsubscribe();

apps/demos/src/app/features/experiments/state/subscription-less-interaction/parent.component.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,6 @@ export class RxStateParentSubscriptionLessComponent implements OnDestroy {
4242
});
4343
}
4444

45-
/*
46-
(this.state$ as any).connect();
47-
this.stateSources$.next(this.source1$.pipe(tap(console.log)));
48-
49-
state$ = this.stateSources$.pipe(
50-
map(o => isObservable(o) ? o : of(o)),
51-
mergeAll(),
52-
scan((state: ComponentState, slices: Partial<ComponentState>) => ({...state, ...slices}), {}),
53-
publishReplay(1)
54-
);
55-
*/
56-
5745
ngOnDestroy(): void {
5846
this.subscription.unsubscribe();
5947
}

apps/demos/src/app/rx-angular-pocs/cdk/render-aware/render-aware.ts

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
import { ChangeDetectorRef } from '@angular/core';
2-
import { RxCustomStrategyCredentials, RxStrategyCredentials, strategyHandling } from '@rx-angular/cdk/render-strategies';
3-
import { ConnectableObservable, EMPTY, isObservable, Observable, of, ReplaySubject, Subject } from 'rxjs';
2+
import {
3+
RxCustomStrategyCredentials,
4+
RxStrategyCredentials,
5+
strategyHandling,
6+
} from '@rx-angular/cdk/render-strategies';
7+
import {
8+
Connectable,
9+
connectable,
10+
EMPTY,
11+
isObservable,
12+
Observable,
13+
of,
14+
ReplaySubject,
15+
Subject,
16+
} from 'rxjs';
417
import {
518
catchError,
619
distinctUntilChanged,
720
map,
8-
merge as mergeWith,
21+
mergeWith,
922
mergeAll,
10-
publishReplay,
1123
switchAll,
1224
} from 'rxjs/operators';
1325

@@ -39,34 +51,33 @@ export function createRenderAware<U>(cfg: {
3951
getCdRef: (k: RxNotification<U>) => ChangeDetectorRef;
4052
getContext: (k?: RxNotification<U>) => any;
4153
}): RenderAware<U | undefined | null> {
42-
4354
const strategyName$ = new ReplaySubject<Observable<string>>(1);
4455
const strategyHandling$ = strategyHandling(
4556
cfg.defaultStrategyName,
4657
cfg.strategies
4758
);
4859
const templateTriggerSubject = new Subject<Observable<RxNotification<U>>>();
49-
const templateTrigger$ = templateTriggerSubject.pipe(
50-
mergeAll()
51-
);
60+
const templateTrigger$ = templateTriggerSubject.pipe(mergeAll());
5261

5362
const observablesFromTemplate$ = new ReplaySubject<Observable<U>>(1);
54-
const renderingEffect$ =
63+
const renderingEffect$ = connectable(
5564
observablesFromTemplate$.pipe(
56-
map(o => isObservable(o) ? o : of(o)),
65+
map((o) => (isObservable(o) ? o : of(o))),
5766
distinctUntilChanged(),
5867
switchAll(),
5968
distinctUntilChanged(),
6069
rxMaterialize(),
6170
mergeWith(templateTrigger$ || EMPTY),
62-
/*observeTemplateByNotificationKind(cfg.templateObserver),
63-
applyStrategy(strategy$, cfg.getContext, cfg.getCdRef),*/
64-
catchError(e => {
71+
catchError((e) => {
6572
console.error(e);
6673
return EMPTY;
67-
}),
68-
publishReplay()
69-
);
74+
})
75+
),
76+
{
77+
connector: () => new ReplaySubject(),
78+
resetOnDisconnect: false,
79+
}
80+
);
7081

7182
return {
7283
strategy$: strategyHandling$.strategy$,
@@ -80,8 +91,8 @@ export function createRenderAware<U>(cfg: {
8091
templateTriggerSubject.next(trigger$);
8192
},
8293
subscribe: () => {
83-
return (renderingEffect$ as ConnectableObservable<any>).connect();
94+
return (renderingEffect$ as Connectable<any>).connect();
8495
},
85-
rendered$: renderingEffect$ as any
96+
rendered$: renderingEffect$ as any,
8697
};
8798
}

apps/demos/src/app/rx-angular-pocs/cdk/utils/rxjs/observable/stateful-observable.ts

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import {
22
BehaviorSubject,
3-
ConnectableObservable,
3+
connectable,
4+
Connectable,
45
EMPTY,
56
merge,
67
Observable,
78
queueScheduler,
9+
ReplaySubject,
810
Subject,
911
Subscribable,
1012
Subscription,
@@ -14,8 +16,6 @@ import {
1416
distinctUntilChanged,
1517
mergeAll,
1618
observeOn,
17-
publish,
18-
publishReplay,
1919
scan,
2020
tap,
2121
withLatestFrom,
@@ -41,28 +41,35 @@ export function createAccumulationObservable<T extends object>(
4141
stateSlices = new Subject<Partial<T>>(),
4242
accumulatorObservable = new BehaviorSubject(defaultAccumulator)
4343
): Accumulator<T> {
44-
const signal$ = merge(
45-
stateObservables.pipe(
46-
distinctUntilChanged(),
47-
mergeAll(),
48-
observeOn(queueScheduler)
44+
const signal$ = connectable(
45+
merge(
46+
stateObservables.pipe(
47+
distinctUntilChanged(),
48+
mergeAll(),
49+
observeOn(queueScheduler)
50+
),
51+
stateSlices.pipe(observeOn(queueScheduler))
52+
).pipe(
53+
withLatestFrom(accumulatorObservable.pipe(observeOn(queueScheduler))),
54+
scan(
55+
(state, [slice, stateAccumulator]) => stateAccumulator(state, slice),
56+
{} as T
57+
),
58+
tap(
59+
(newState) => (compositionObservable.state = newState),
60+
(error) => console.error(error)
61+
),
62+
catchError((e) => EMPTY)
4963
),
50-
stateSlices.pipe(observeOn(queueScheduler))
51-
).pipe(
52-
withLatestFrom(accumulatorObservable.pipe(observeOn(queueScheduler))),
53-
scan(
54-
(state, [slice, stateAccumulator]) => stateAccumulator(state, slice),
55-
{} as T
56-
),
57-
tap(
58-
(newState) => (compositionObservable.state = newState),
59-
(error) => console.error(error)
60-
),
61-
// @Notice We catch the error here as it get lost in between `publish` and `publishReplay`. We return empty to
62-
catchError((e) => EMPTY),
63-
publish()
64+
{
65+
connector: () => new Subject<T>(),
66+
resetOnDisconnect: false,
67+
}
6468
);
65-
const state$: Observable<T> = signal$.pipe(publishReplay(1));
69+
const state$: Observable<T> = connectable(signal$, {
70+
connector: () => new ReplaySubject<T>(1),
71+
resetOnDisconnect: false,
72+
});
6673
const compositionObservable: Accumulator<T> = {
6774
state: {} as T,
6875
signal$,
@@ -92,10 +99,8 @@ export function createAccumulationObservable<T extends object>(
9299
}
93100

94101
function subscribe(): Subscription {
95-
const sub = (compositionObservable.signal$ as ConnectableObservable<T>).connect();
96-
sub.add(
97-
(compositionObservable.state$ as ConnectableObservable<T>).connect()
98-
);
102+
const sub = (compositionObservable.signal$ as Connectable<T>).connect();
103+
sub.add((compositionObservable.state$ as Connectable<T>).connect());
99104
sub.add(() => {
100105
accumulatorObservable.complete();
101106
stateObservables.complete();

libs/state/effects/src/lib/effects.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class RxEffects implements OnDestroy, OnDestroy$ {
7474
private static nextId = 0;
7575
readonly _hooks$ = new Subject<DestroyProp>();
7676
private readonly observables$ = new Subject<Observable<unknown>>();
77-
// we have to use publish here to make it hot (composition happens without subscriber)
77+
// we have to use share here to make it hot (composition happens without subscriber)
7878
private readonly effects$ = this.observables$.pipe(mergeAll(), share());
7979
private readonly subscription = this.effects$.subscribe();
8080
onDestroy$: Observable<boolean> = this._hooks$.pipe(toHook('destroy'));

libs/state/selections/src/lib/accumulation-observable.ts

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import {
22
BehaviorSubject,
3-
ConnectableObservable,
3+
Connectable,
4+
connectable,
45
EMPTY,
56
merge,
67
Observable,
78
queueScheduler,
9+
ReplaySubject,
810
Subject,
911
Subscription,
1012
} from 'rxjs';
@@ -13,8 +15,6 @@ import {
1315
distinctUntilChanged,
1416
mergeAll,
1517
observeOn,
16-
publish,
17-
publishReplay,
1818
scan,
1919
tap,
2020
withLatestFrom,
@@ -30,28 +30,35 @@ export function createAccumulationObservable<T extends object>(
3030
stateSlices = new Subject<Partial<T>>(),
3131
accumulatorObservable = new BehaviorSubject(defaultAccumulator)
3232
): Accumulator<T> {
33-
const signal$ = merge(
34-
stateObservables.pipe(
35-
distinctUntilChanged(),
36-
mergeAll(),
37-
observeOn(queueScheduler)
33+
const signal$ = connectable(
34+
merge(
35+
stateObservables.pipe(
36+
distinctUntilChanged(),
37+
mergeAll(),
38+
observeOn(queueScheduler)
39+
),
40+
stateSlices.pipe(observeOn(queueScheduler))
41+
).pipe(
42+
withLatestFrom(accumulatorObservable.pipe(observeOn(queueScheduler))),
43+
scan(
44+
(state, [slice, stateAccumulator]) => stateAccumulator(state, slice),
45+
{} as T
46+
),
47+
tap(
48+
(newState) => (compositionObservable.state = newState),
49+
(error) => console.error(error)
50+
),
51+
catchError((e) => EMPTY)
3852
),
39-
stateSlices.pipe(observeOn(queueScheduler))
40-
).pipe(
41-
withLatestFrom(accumulatorObservable.pipe(observeOn(queueScheduler))),
42-
scan(
43-
(state, [slice, stateAccumulator]) => stateAccumulator(state, slice),
44-
{} as T
45-
),
46-
tap(
47-
(newState) => (compositionObservable.state = newState),
48-
(error) => console.error(error)
49-
),
50-
// @Notice We catch the error here as it get lost in between `publish` and `publishReplay`. We return empty to
51-
catchError((e) => EMPTY),
52-
publish()
53+
{
54+
connector: () => new Subject<T>(),
55+
resetOnDisconnect: false,
56+
}
5357
);
54-
const state$: Observable<T> = signal$.pipe(publishReplay(1));
58+
const state$: Observable<T> = connectable(signal$, {
59+
connector: () => new ReplaySubject<T>(1),
60+
resetOnDisconnect: false,
61+
});
5562
const compositionObservable: Accumulator<T> = {
5663
state: {} as T,
5764
signal$,
@@ -81,12 +88,8 @@ export function createAccumulationObservable<T extends object>(
8188
}
8289

8390
function subscribe(): Subscription {
84-
const sub = (
85-
compositionObservable.signal$ as ConnectableObservable<T>
86-
).connect();
87-
sub.add(
88-
(compositionObservable.state$ as ConnectableObservable<T>).connect()
89-
);
91+
const sub = (compositionObservable.signal$ as Connectable<T>).connect();
92+
sub.add((compositionObservable.state$ as Connectable<T>).connect());
9093
sub.add(() => {
9194
accumulatorObservable.complete();
9295
stateObservables.complete();

0 commit comments

Comments
 (0)