forked from markostanimirovic/ngrx-signal-store-playground
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwith-load-entities.ts
93 lines (90 loc) · 2.63 KB
/
with-load-entities.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import {
rxEffect,
SignalStoreUpdate,
withEffects,
withUpdaters,
} from '@ngrx/signals';
import {
EntityState,
setLoading,
withCallState,
} from '../../../app/users/call-state';
import { exhaustMap, Observable, pipe, tap } from 'rxjs';
import { signalStoreFeature } from '../../signal-store';
import { Signal } from '@angular/core';
import { StaticState } from '../../models';
import { withEntities } from './with-entities';
export function withLoadEntities<Entity>() {
// getAll: () => Observable<Entity[]> // or: Promise<Entity[]>
const initialState: EntityState<Entity> = { entities: {}, ids: [] };
return signalStoreFeature(
withCallState(),
withEntities<Entity>(),
withUpdaters(({ update, setAll }) => ({
setResult: (entities: Entity[]) => setAll(entities),
}))
// withEffects(({ setLoaded, setAll }) => ({
// loadEntities: rxEffect<void>(
// pipe(
// tap(() => setLoading()),
// exhaustMap(() => getAll()),
// tap((entities) => {
// setAll(entities);
// setLoaded();
// })
// )
// ),
// }))
);
}
export function withLoadEntitiesEffect<
State extends Record<string, Signal<any>>,
Computed extends Record<string, Signal<any>>,
Updaters extends Record<string, (...args: any[]) => void>,
PreviousEffects extends Record<string, (...args: any[]) => any>,
Entity extends { id: string | number }
>(
getAll: (
input: State &
Computed &
Updaters &
PreviousEffects &
SignalStoreUpdate<StaticState<State>>
) => Observable<Entity[]> // or: Promise<Entity[]>
) {
return (
feature: {
state: State;
computed: Computed;
updaters: Updaters;
effects: PreviousEffects;
} & SignalStoreUpdate<StaticState<State>>
) =>
// We could have not use signalStoreFeature to implement this hook and use the feature param types to restrict the
// use and unsure a withLoadEntities is before but the type will be more complicated
signalStoreFeature(
{
requires: withLoadEntities<Entity>(),
},
withEffects(({ setAll, setLoaded }) => ({
loadEntities: rxEffect<void>(
pipe(
tap(() => setLoading()),
exhaustMap(() =>
getAll({
...feature.state,
...feature.computed,
...feature.updaters,
...feature.effects,
update: feature.update,
})
),
tap((entities) => {
setAll(entities);
setLoaded();
})
)
),
}))
)(feature as any);
}