-
Notifications
You must be signed in to change notification settings - Fork 9
/
feature-store.ts
80 lines (70 loc) · 2.52 KB
/
feature-store.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
import { DestroyRef, inject, Signal } from '@angular/core';
import {
Action,
createFeatureStoreReducer,
createMiniRxActionType,
FeatureStoreConfig,
generateId,
MiniRxAction,
miniRxError,
OperationType,
StateOrCallback,
undo,
UpdateStateCallback,
} from '@mini-rx/common';
import { addFeature, dispatch, hasUndoExtension, removeFeature, select } from './store-core';
import { createSelectableSignalState } from './selectable-signal-state';
import { ComponentStoreLike } from './models';
import { createRxEffectFn } from './rx-effect';
import { createConnectFn } from './connect';
import { createUpdateFn } from './update';
export class FeatureStore<StateType extends object> implements ComponentStoreLike<StateType> {
private readonly featureId: string;
private readonly _featureKey: string;
get featureKey(): string {
return this._featureKey;
}
private _state: Signal<StateType> = select((state) => state[this.featureKey]);
get state(): StateType {
return this._state();
}
private updateState: UpdateStateCallback<StateType> = (
stateOrCallback: StateOrCallback<StateType>,
operationType: OperationType,
name: string | undefined
): MiniRxAction<StateType> => {
return dispatch({
type: createMiniRxActionType(operationType, this.featureKey, name),
stateOrCallback,
featureId: this.featureId,
});
};
constructor(featureKey: string, initialState: StateType, config: FeatureStoreConfig = {}) {
this.featureId = generateId();
this._featureKey = config.multi ? featureKey + '-' + this.featureId : featureKey;
addFeature<StateType>(
this._featureKey,
createFeatureStoreReducer(this.featureId, initialState)
);
inject(DestroyRef).onDestroy(() => this.destroy());
}
undo(action: Action): void {
hasUndoExtension
? dispatch(undo(action))
: miniRxError('UndoExtension is not initialized.');
}
setState = createUpdateFn(this.updateState);
connect = createConnectFn(this.updateState);
rxEffect = createRxEffectFn();
select = createSelectableSignalState(this._state).select;
private destroy(): void {
removeFeature(this._featureKey);
}
}
export function createFeatureStore<T extends object>(
featureKey: string,
initialState: T,
config: FeatureStoreConfig = {}
): FeatureStore<T> {
return new FeatureStore<T>(featureKey, initialState, config);
}