@angular-architects/ngrx-toolkit 20.0.2 → 20.1.0
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/fesm2022/angular-architects-ngrx-toolkit-redux-connector.mjs +119 -0
- package/fesm2022/angular-architects-ngrx-toolkit-redux-connector.mjs.map +1 -0
- package/fesm2022/angular-architects-ngrx-toolkit.mjs +1888 -0
- package/fesm2022/angular-architects-ngrx-toolkit.mjs.map +1 -0
- package/index.d.ts +1084 -0
- package/package.json +21 -4
- package/redux-connector/index.d.ts +59 -0
- package/eslint.config.cjs +0 -43
- package/jest.config.ts +0 -22
- package/ng-package.json +0 -7
- package/project.json +0 -37
- package/redux-connector/docs/README.md +0 -131
- package/redux-connector/index.ts +0 -6
- package/redux-connector/ng-package.json +0 -5
- package/redux-connector/src/lib/create-redux.ts +0 -102
- package/redux-connector/src/lib/model.ts +0 -89
- package/redux-connector/src/lib/rxjs-interop/redux-method.ts +0 -66
- package/redux-connector/src/lib/signal-redux-store.ts +0 -59
- package/redux-connector/src/lib/util.ts +0 -22
- package/src/index.ts +0 -43
- package/src/lib/assertions/assertions.ts +0 -9
- package/src/lib/devtools/features/with-disabled-name-indicies.ts +0 -31
- package/src/lib/devtools/features/with-glitch-tracking.ts +0 -35
- package/src/lib/devtools/features/with-mapper.ts +0 -34
- package/src/lib/devtools/internal/current-action-names.ts +0 -1
- package/src/lib/devtools/internal/default-tracker.ts +0 -60
- package/src/lib/devtools/internal/devtools-feature.ts +0 -37
- package/src/lib/devtools/internal/devtools-syncer.service.ts +0 -202
- package/src/lib/devtools/internal/glitch-tracker.service.ts +0 -61
- package/src/lib/devtools/internal/models.ts +0 -29
- package/src/lib/devtools/provide-devtools-config.ts +0 -32
- package/src/lib/devtools/rename-devtools-name.ts +0 -21
- package/src/lib/devtools/tests/action-name.spec.ts +0 -48
- package/src/lib/devtools/tests/basic.spec.ts +0 -111
- package/src/lib/devtools/tests/connecting.spec.ts +0 -37
- package/src/lib/devtools/tests/helpers.spec.ts +0 -43
- package/src/lib/devtools/tests/naming.spec.ts +0 -216
- package/src/lib/devtools/tests/provide-devtools-config.spec.ts +0 -25
- package/src/lib/devtools/tests/types.spec.ts +0 -19
- package/src/lib/devtools/tests/update-state.spec.ts +0 -29
- package/src/lib/devtools/tests/with-devtools.spec.ts +0 -5
- package/src/lib/devtools/tests/with-glitch-tracking.spec.ts +0 -272
- package/src/lib/devtools/tests/with-mapper.spec.ts +0 -69
- package/src/lib/devtools/update-state.ts +0 -38
- package/src/lib/devtools/with-dev-tools-stub.ts +0 -6
- package/src/lib/devtools/with-devtools.ts +0 -81
- package/src/lib/immutable-state/deep-freeze.ts +0 -43
- package/src/lib/immutable-state/is-dev-mode.ts +0 -6
- package/src/lib/immutable-state/tests/with-immutable-state.spec.ts +0 -278
- package/src/lib/immutable-state/with-immutable-state.ts +0 -150
- package/src/lib/shared/prettify.ts +0 -3
- package/src/lib/shared/signal-store-models.ts +0 -30
- package/src/lib/shared/throw-if-null.ts +0 -7
- package/src/lib/storage-sync/features/with-indexed-db.ts +0 -81
- package/src/lib/storage-sync/features/with-local-storage.ts +0 -58
- package/src/lib/storage-sync/internal/indexeddb.service.ts +0 -124
- package/src/lib/storage-sync/internal/local-storage.service.ts +0 -19
- package/src/lib/storage-sync/internal/models.ts +0 -62
- package/src/lib/storage-sync/internal/session-storage.service.ts +0 -18
- package/src/lib/storage-sync/tests/indexeddb.service.spec.ts +0 -99
- package/src/lib/storage-sync/tests/with-storage-async.spec.ts +0 -305
- package/src/lib/storage-sync/tests/with-storage-sync.spec.ts +0 -273
- package/src/lib/storage-sync/with-storage-sync.ts +0 -236
- package/src/lib/with-call-state.spec.ts +0 -42
- package/src/lib/with-call-state.ts +0 -195
- package/src/lib/with-conditional.spec.ts +0 -125
- package/src/lib/with-conditional.ts +0 -74
- package/src/lib/with-data-service.spec.ts +0 -564
- package/src/lib/with-data-service.ts +0 -433
- package/src/lib/with-feature-factory.spec.ts +0 -69
- package/src/lib/with-feature-factory.ts +0 -56
- package/src/lib/with-pagination.spec.ts +0 -135
- package/src/lib/with-pagination.ts +0 -373
- package/src/lib/with-redux.spec.ts +0 -258
- package/src/lib/with-redux.ts +0 -387
- package/src/lib/with-reset.spec.ts +0 -112
- package/src/lib/with-reset.ts +0 -62
- package/src/lib/with-undo-redo.spec.ts +0 -274
- package/src/lib/with-undo-redo.ts +0 -200
- package/src/test-setup.ts +0 -6
- package/tsconfig.json +0 -29
- package/tsconfig.lib.json +0 -17
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-architects/ngrx-toolkit",
|
|
3
|
-
"version": "20.0
|
|
3
|
+
"version": "20.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "GitHub",
|
|
@@ -18,6 +18,23 @@
|
|
|
18
18
|
"optional": true
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
-
"dependencies": {
|
|
22
|
-
|
|
23
|
-
}
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"tslib": "^2.3.0"
|
|
23
|
+
},
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"module": "fesm2022/angular-architects-ngrx-toolkit.mjs",
|
|
26
|
+
"typings": "index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
"./package.json": {
|
|
29
|
+
"default": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./index.d.ts",
|
|
33
|
+
"default": "./fesm2022/angular-architects-ngrx-toolkit.mjs"
|
|
34
|
+
},
|
|
35
|
+
"./redux-connector": {
|
|
36
|
+
"types": "./redux-connector/index.d.ts",
|
|
37
|
+
"default": "./fesm2022/angular-architects-ngrx-toolkit-redux-connector.mjs"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ActionCreator, ActionType, Prettify, Action } from '@ngrx/store/src/models';
|
|
2
|
+
import { Type, EnvironmentProviders, Signal, Injector } from '@angular/core';
|
|
3
|
+
import { DeepSignal } from '@ngrx/signals/src/deep-signal';
|
|
4
|
+
import { StateSignals, SignalStoreFeatureResult } from '@ngrx/signals/src/signal-store-models';
|
|
5
|
+
import { Observable, Unsubscribable } from 'rxjs';
|
|
6
|
+
|
|
7
|
+
type IncludePropType<T, V, WithNevers = {
|
|
8
|
+
[K in keyof T]: Exclude<T[K], undefined> extends V ? T[K] extends Record<string, unknown> ? IncludePropType<T[K], V> : T[K] : never;
|
|
9
|
+
}> = Prettify<Pick<WithNevers, {
|
|
10
|
+
[K in keyof WithNevers]: WithNevers[K] extends never ? never : K extends string ? K : never;
|
|
11
|
+
}[keyof WithNevers]>>;
|
|
12
|
+
type Store = Type<Record<string, unknown> & StateSignals<SignalStoreFeatureResult['state']>>;
|
|
13
|
+
type CreateReduxState<StoreName extends string, STORE extends Store> = {
|
|
14
|
+
[K in StoreName as `provide${Capitalize<K>}Store`]: (connectReduxDevtools?: boolean) => EnvironmentProviders;
|
|
15
|
+
} & {
|
|
16
|
+
[K in StoreName as `inject${Capitalize<K>}Store`]: () => InjectableReduxSlice<STORE>;
|
|
17
|
+
};
|
|
18
|
+
type Selectors<STORE extends Store> = IncludePropType<InstanceType<STORE>, Signal<unknown> | DeepSignal<unknown>>;
|
|
19
|
+
type Dispatch = {
|
|
20
|
+
dispatch: (input: Action | Observable<Action> | Signal<Action>) => Unsubscribable;
|
|
21
|
+
};
|
|
22
|
+
type InjectableReduxSlice<STORE extends Store> = Selectors<STORE> & Dispatch;
|
|
23
|
+
type ExtractActionTypes<Creators extends readonly ActionCreator[]> = {
|
|
24
|
+
[Key in keyof Creators]: Creators[Key] extends ActionCreator<infer T> ? T : never;
|
|
25
|
+
};
|
|
26
|
+
interface StoreMethod<Creators extends readonly ActionCreator[], ResultState = unknown> {
|
|
27
|
+
(action: ActionType<Creators[number]>): ResultState;
|
|
28
|
+
}
|
|
29
|
+
interface MapperTypes<Creators extends readonly ActionCreator[]> {
|
|
30
|
+
types: ExtractActionTypes<Creators>;
|
|
31
|
+
storeMethod: StoreMethod<Creators>;
|
|
32
|
+
resultMethod?: (...args: unknown[]) => unknown;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
declare function mapAction<Creators extends readonly ActionCreator[]>(...args: [
|
|
36
|
+
...creators: Creators,
|
|
37
|
+
storeMethod: (action: ActionType<Creators[number]>) => unknown
|
|
38
|
+
]): MapperTypes<Creators>;
|
|
39
|
+
declare function mapAction<Creators extends readonly ActionCreator[], T>(...args: [
|
|
40
|
+
...creators: Creators,
|
|
41
|
+
storeMethod: (action: ActionType<Creators[number]>, resultMethod: (input: T) => unknown) => unknown,
|
|
42
|
+
resultMethod: (input: T) => unknown
|
|
43
|
+
]): MapperTypes<Creators>;
|
|
44
|
+
declare function withActionMappers(...mappers: MapperTypes<ActionCreator[]>[]): MapperTypes<ActionCreator[]>[];
|
|
45
|
+
declare function createReduxState<StoreName extends string, STORE extends Store>(storeName: StoreName, signalStore: STORE, withActionMappers: (store: InstanceType<STORE>) => MapperTypes<ActionCreator[]>[]): CreateReduxState<StoreName, STORE>;
|
|
46
|
+
|
|
47
|
+
type RxMethodInput<Input> = Input | Observable<Input> | Signal<Input>;
|
|
48
|
+
type RxMethodRef = {
|
|
49
|
+
destroy: () => void;
|
|
50
|
+
};
|
|
51
|
+
type RxMethod<Input, MethodInput = Input, MethodResult = unknown> = ((input: RxMethodInput<Input>, resultMethod: (input: MethodInput) => MethodResult) => RxMethodRef) & RxMethodRef;
|
|
52
|
+
declare function reduxMethod<Input, MethodInput = Input>(generator: (source$: Observable<Input>) => Observable<MethodInput>, config?: {
|
|
53
|
+
injector?: Injector;
|
|
54
|
+
}): RxMethod<Input, MethodInput>;
|
|
55
|
+
declare function reduxMethod<Input, MethodInput = Input, MethodResult = unknown>(generator: (source$: Observable<Input>) => Observable<MethodInput>, resultMethod: (input: MethodInput) => MethodResult, config?: {
|
|
56
|
+
injector?: Injector;
|
|
57
|
+
}): RxMethod<Input, MethodInput, MethodResult>;
|
|
58
|
+
|
|
59
|
+
export { createReduxState, mapAction, reduxMethod, withActionMappers };
|
package/eslint.config.cjs
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
const nx = require('@nx/eslint-plugin');
|
|
2
|
-
const baseConfig = require('../../eslint.config.cjs');
|
|
3
|
-
|
|
4
|
-
module.exports = [
|
|
5
|
-
...baseConfig,
|
|
6
|
-
{
|
|
7
|
-
files: ['**/*.json'],
|
|
8
|
-
rules: {
|
|
9
|
-
'@nx/dependency-checks': [
|
|
10
|
-
'error',
|
|
11
|
-
{
|
|
12
|
-
ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs}'],
|
|
13
|
-
},
|
|
14
|
-
],
|
|
15
|
-
},
|
|
16
|
-
languageOptions: {
|
|
17
|
-
parser: require('jsonc-eslint-parser'),
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
...nx.configs['flat/angular'],
|
|
21
|
-
...nx.configs['flat/angular-template'],
|
|
22
|
-
{
|
|
23
|
-
files: ['**/*.ts'],
|
|
24
|
-
rules: {
|
|
25
|
-
'@angular-eslint/directive-selector': [
|
|
26
|
-
'error',
|
|
27
|
-
{
|
|
28
|
-
type: 'attribute',
|
|
29
|
-
prefix: 'lib',
|
|
30
|
-
style: 'camelCase',
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
'@angular-eslint/component-selector': [
|
|
34
|
-
'error',
|
|
35
|
-
{
|
|
36
|
-
type: 'element',
|
|
37
|
-
prefix: 'lib',
|
|
38
|
-
style: 'kebab-case',
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
}
|
|
43
|
-
];
|
package/jest.config.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
displayName: 'ngrx-toolkit',
|
|
3
|
-
setupFiles: ['core-js'],
|
|
4
|
-
preset: '../../jest.preset.js',
|
|
5
|
-
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
|
6
|
-
coverageDirectory: '../../coverage/libs/ngrx-toolkit',
|
|
7
|
-
transform: {
|
|
8
|
-
'^.+\\.(ts|mjs|js|html)$': [
|
|
9
|
-
'jest-preset-angular',
|
|
10
|
-
{
|
|
11
|
-
tsconfig: '<rootDir>/tsconfig.spec.json',
|
|
12
|
-
stringifyContentPathRegex: '\\.(html|svg)$',
|
|
13
|
-
},
|
|
14
|
-
],
|
|
15
|
-
},
|
|
16
|
-
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
|
17
|
-
snapshotSerializers: [
|
|
18
|
-
'jest-preset-angular/build/serializers/no-ng-attributes',
|
|
19
|
-
'jest-preset-angular/build/serializers/ng-snapshot',
|
|
20
|
-
'jest-preset-angular/build/serializers/html-comment',
|
|
21
|
-
],
|
|
22
|
-
};
|
package/ng-package.json
DELETED
package/project.json
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "ngrx-toolkit",
|
|
3
|
-
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
-
"sourceRoot": "libs/ngrx-toolkit/src",
|
|
5
|
-
"prefix": "ngrx-toolkit",
|
|
6
|
-
"projectType": "library",
|
|
7
|
-
"tags": [],
|
|
8
|
-
"targets": {
|
|
9
|
-
"build": {
|
|
10
|
-
"executor": "@nx/angular:package",
|
|
11
|
-
"outputs": ["{workspaceRoot}/dist/{projectRoot}"],
|
|
12
|
-
"options": {
|
|
13
|
-
"project": "libs/ngrx-toolkit/ng-package.json"
|
|
14
|
-
},
|
|
15
|
-
"configurations": {
|
|
16
|
-
"production": {
|
|
17
|
-
"tsConfig": "libs/ngrx-toolkit/tsconfig.lib.prod.json"
|
|
18
|
-
},
|
|
19
|
-
"development": {
|
|
20
|
-
"tsConfig": "libs/ngrx-toolkit/tsconfig.lib.json"
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
"defaultConfiguration": "production"
|
|
24
|
-
},
|
|
25
|
-
"test": {
|
|
26
|
-
"executor": "@nx/jest:jest",
|
|
27
|
-
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
|
28
|
-
"options": {
|
|
29
|
-
"jestConfig": "libs/ngrx-toolkit/jest.config.ts"
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
"lint": {
|
|
33
|
-
"executor": "@nx/eslint:lint",
|
|
34
|
-
"outputs": ["{options.outputFile}"]
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
# Redux Connector for the NgRx Signal Store `createReduxState()`
|
|
2
|
-
|
|
3
|
-
The Redux Connector turns any `signalStore()` into a Global State Management Slice following the Redux pattern. It is available as secondary entry point, i.e. `import { createReduxState } from '@angular-architects/ngrx-toolkit/redux-connector'` and has a dependency to `@ngrx/store`.
|
|
4
|
-
|
|
5
|
-
It supports:
|
|
6
|
-
|
|
7
|
-
✅ Well-known NgRx Store Actions \
|
|
8
|
-
✅ Global Action `dispatch()` \
|
|
9
|
-
✅ Angular Lazy Loading \
|
|
10
|
-
✅ Auto-generated `provideNamedStore()` & `injectNamedStore()` Functions \
|
|
11
|
-
✅ Global Action to Store Method Mappers \
|
|
12
|
-
|
|
13
|
-
- [Redux Connector for the NgRx Signal Store `createReduxState()`](#redux-connector-for-the-ngrx-signal-store-createreduxstate)
|
|
14
|
-
- [Use a present Signal Store](#use-a-present-signal-store)
|
|
15
|
-
- [Use well-known NgRx Store Actions](#use-well-known-ngrx-store-actions)
|
|
16
|
-
- [Map Actions to Methods](#map-actions-to-methods)
|
|
17
|
-
- [Register an Angular Dependency Injection Provider](#register-an-angular-dependency-injection-provider)
|
|
18
|
-
- [Use the Store in your Component](#use-the-store-in-your-component)
|
|
19
|
-
|
|
20
|
-
## Use a present Signal Store
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
export const FlightStore = signalStore(
|
|
24
|
-
// State
|
|
25
|
-
withEntities({ entity: type<Flight>(), collection: 'flight' }),
|
|
26
|
-
withEntities({ entity: type<number>(), collection: 'hide' }),
|
|
27
|
-
// Selectors
|
|
28
|
-
withComputed(({ flightEntities, hideEntities }) => ({
|
|
29
|
-
filteredFlights: computed(() => flightEntities().filter((flight) => !hideEntities().includes(flight.id))),
|
|
30
|
-
flightCount: computed(() => flightEntities().length),
|
|
31
|
-
})),
|
|
32
|
-
// Updater
|
|
33
|
-
withMethods((store) => ({
|
|
34
|
-
setFlights: (state: { flights: Flight[] }) => patchState(store, setAllEntities(state.flights, { collection: 'flight' })),
|
|
35
|
-
updateFlight: (state: { flight: Flight }) => patchState(store, updateEntity({ id: state.flight.id, changes: state.flight }, { collection: 'flight' })),
|
|
36
|
-
clearFlights: () => patchState(store, removeAllEntities({ collection: 'flight' })),
|
|
37
|
-
})),
|
|
38
|
-
// Effects
|
|
39
|
-
withMethods((store, flightService = inject(FlightService)) => ({
|
|
40
|
-
loadFlights: reduxMethod<FlightFilter, { flights: Flight[] }>(
|
|
41
|
-
pipe(
|
|
42
|
-
switchMap((filter) => from(flightService.load({ from: filter.from, to: filter.to }))),
|
|
43
|
-
map((flights) => ({ flights })),
|
|
44
|
-
),
|
|
45
|
-
store.setFlights,
|
|
46
|
-
),
|
|
47
|
-
})),
|
|
48
|
-
);
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Use well-known NgRx Store Actions
|
|
52
|
-
|
|
53
|
-
```typescript
|
|
54
|
-
export const ticketActions = createActionGroup({
|
|
55
|
-
source: 'tickets',
|
|
56
|
-
events: {
|
|
57
|
-
'flights load': props<FlightFilter>(),
|
|
58
|
-
'flights loaded': props<{ flights: Flight[] }>(),
|
|
59
|
-
'flights loaded by passenger': props<{ flights: Flight[] }>(),
|
|
60
|
-
'flight update': props<{ flight: Flight }>(),
|
|
61
|
-
'flights clear': emptyProps(),
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Map Actions to Methods
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
export const { provideFlightStore, injectFlightStore } = createReduxState('flight', FlightStore, (store) =>
|
|
70
|
-
withActionMappers(
|
|
71
|
-
mapAction(
|
|
72
|
-
// Filtered Action
|
|
73
|
-
ticketActions.flightsLoad,
|
|
74
|
-
// Side-Effect
|
|
75
|
-
store.loadFlights,
|
|
76
|
-
// Result Action
|
|
77
|
-
ticketActions.flightsLoaded,
|
|
78
|
-
),
|
|
79
|
-
mapAction(
|
|
80
|
-
// Filtered Actions
|
|
81
|
-
ticketActions.flightsLoaded,
|
|
82
|
-
ticketActions.flightsLoadedByPassenger,
|
|
83
|
-
// State Updater Method (like Reducers)
|
|
84
|
-
store.setFlights,
|
|
85
|
-
),
|
|
86
|
-
mapAction(ticketActions.flightUpdate, store.updateFlight),
|
|
87
|
-
mapAction(ticketActions.flightsClear, store.clearFlights),
|
|
88
|
-
),
|
|
89
|
-
);
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Register an Angular Dependency Injection Provider
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
export const appRoutes: Route[] = [
|
|
96
|
-
{
|
|
97
|
-
path: 'flight-search-redux-connector',
|
|
98
|
-
providers: [provideFlightStore()],
|
|
99
|
-
component: FlightSearchReducConnectorComponent,
|
|
100
|
-
},
|
|
101
|
-
];
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Use the Store in your Component
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
@Component({
|
|
108
|
-
standalone: true,
|
|
109
|
-
imports: [JsonPipe, RouterLink, FormsModule, FlightCardComponent],
|
|
110
|
-
selector: 'demo-flight-search-redux-connector',
|
|
111
|
-
templateUrl: './flight-search.component.html',
|
|
112
|
-
})
|
|
113
|
-
export class FlightSearchReducConnectorComponent {
|
|
114
|
-
private store = injectFlightStore();
|
|
115
|
-
|
|
116
|
-
protected flights = this.store.flightEntities;
|
|
117
|
-
|
|
118
|
-
protected search() {
|
|
119
|
-
this.store.dispatch(
|
|
120
|
-
ticketActions.flightsLoad({
|
|
121
|
-
from: this.localState.filter.from(),
|
|
122
|
-
to: this.localState.filter.to(),
|
|
123
|
-
}),
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
protected reset(): void {
|
|
128
|
-
this.store.dispatch(ticketActions.flightsClear());
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
package/redux-connector/index.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
inject,
|
|
3
|
-
makeEnvironmentProviders,
|
|
4
|
-
provideEnvironmentInitializer,
|
|
5
|
-
} from '@angular/core';
|
|
6
|
-
import { ActionCreator, ActionType } from '@ngrx/store/src/models';
|
|
7
|
-
import {
|
|
8
|
-
CreateReduxState,
|
|
9
|
-
ExtractActionTypes,
|
|
10
|
-
MapperTypes,
|
|
11
|
-
ServiceWithDecorator,
|
|
12
|
-
Store,
|
|
13
|
-
} from './model';
|
|
14
|
-
import { SignalReduxStore, injectReduxDispatch } from './signal-redux-store';
|
|
15
|
-
import { capitalize, isActionCreator } from './util';
|
|
16
|
-
|
|
17
|
-
export function mapAction<Creators extends readonly ActionCreator[]>(
|
|
18
|
-
...args: [
|
|
19
|
-
...creators: Creators,
|
|
20
|
-
storeMethod: (action: ActionType<Creators[number]>) => unknown,
|
|
21
|
-
]
|
|
22
|
-
): MapperTypes<Creators>;
|
|
23
|
-
export function mapAction<Creators extends readonly ActionCreator[], T>(
|
|
24
|
-
...args: [
|
|
25
|
-
...creators: Creators,
|
|
26
|
-
storeMethod: (
|
|
27
|
-
action: ActionType<Creators[number]>,
|
|
28
|
-
resultMethod: (input: T) => unknown,
|
|
29
|
-
) => unknown,
|
|
30
|
-
resultMethod: (input: T) => unknown,
|
|
31
|
-
]
|
|
32
|
-
): MapperTypes<Creators>;
|
|
33
|
-
export function mapAction<Creators extends readonly ActionCreator[]>(
|
|
34
|
-
...args: [
|
|
35
|
-
...creators: Creators,
|
|
36
|
-
storeMethod: (action: ActionType<Creators[number]>) => unknown,
|
|
37
|
-
resultMethod?: (input: unknown) => unknown,
|
|
38
|
-
]
|
|
39
|
-
): MapperTypes<Creators> {
|
|
40
|
-
let resultMethod = args.pop() as unknown as
|
|
41
|
-
| ((input: unknown) => unknown)
|
|
42
|
-
| undefined;
|
|
43
|
-
let storeMethod = args.pop() as unknown as (
|
|
44
|
-
action: ActionType<Creators[number]>,
|
|
45
|
-
) => unknown;
|
|
46
|
-
|
|
47
|
-
if (isActionCreator(storeMethod)) {
|
|
48
|
-
args.push(storeMethod);
|
|
49
|
-
storeMethod = resultMethod || storeMethod;
|
|
50
|
-
resultMethod = undefined;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const types = (args as unknown as Creators).map(
|
|
54
|
-
(creator) => creator.type,
|
|
55
|
-
) as unknown as ExtractActionTypes<Creators>;
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
types,
|
|
59
|
-
storeMethod,
|
|
60
|
-
resultMethod,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function withActionMappers(
|
|
65
|
-
...mappers: MapperTypes<ActionCreator[]>[]
|
|
66
|
-
): MapperTypes<ActionCreator[]>[] {
|
|
67
|
-
return mappers;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function createReduxState<StoreName extends string, STORE extends Store>(
|
|
71
|
-
storeName: StoreName,
|
|
72
|
-
signalStore: STORE,
|
|
73
|
-
withActionMappers: (
|
|
74
|
-
store: InstanceType<STORE>,
|
|
75
|
-
) => MapperTypes<ActionCreator[]>[],
|
|
76
|
-
): CreateReduxState<StoreName, STORE> {
|
|
77
|
-
const isRootProvider =
|
|
78
|
-
(signalStore as ServiceWithDecorator)?.ɵprov?.providedIn === 'root';
|
|
79
|
-
return {
|
|
80
|
-
[`provide${capitalize(storeName)}Store`]: (connectReduxDevtools = false) =>
|
|
81
|
-
makeEnvironmentProviders([
|
|
82
|
-
isRootProvider ? [] : signalStore,
|
|
83
|
-
provideEnvironmentInitializer(() => {
|
|
84
|
-
const initializerFn = (
|
|
85
|
-
(
|
|
86
|
-
signalReduxStore = inject(SignalReduxStore),
|
|
87
|
-
store = inject(signalStore),
|
|
88
|
-
) =>
|
|
89
|
-
() => {
|
|
90
|
-
if (connectReduxDevtools) {
|
|
91
|
-
// addStoreToReduxDevtools(store, storeName, false);
|
|
92
|
-
}
|
|
93
|
-
signalReduxStore.connectFeatureStore(withActionMappers(store));
|
|
94
|
-
}
|
|
95
|
-
)();
|
|
96
|
-
return initializerFn();
|
|
97
|
-
}),
|
|
98
|
-
]),
|
|
99
|
-
[`inject${capitalize(storeName)}Store`]: () =>
|
|
100
|
-
Object.assign(inject(signalStore), { dispatch: injectReduxDispatch() }),
|
|
101
|
-
} as CreateReduxState<StoreName, STORE>;
|
|
102
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { EnvironmentProviders, Signal, Type } from '@angular/core';
|
|
2
|
-
import { DeepSignal } from '@ngrx/signals/src/deep-signal';
|
|
3
|
-
import {
|
|
4
|
-
SignalStoreFeatureResult,
|
|
5
|
-
StateSignals,
|
|
6
|
-
} from '@ngrx/signals/src/signal-store-models';
|
|
7
|
-
import {
|
|
8
|
-
Action,
|
|
9
|
-
ActionCreator,
|
|
10
|
-
ActionType,
|
|
11
|
-
Prettify,
|
|
12
|
-
} from '@ngrx/store/src/models';
|
|
13
|
-
import { Observable, Unsubscribable } from 'rxjs';
|
|
14
|
-
|
|
15
|
-
export type IncludePropType<
|
|
16
|
-
T,
|
|
17
|
-
V,
|
|
18
|
-
WithNevers = {
|
|
19
|
-
[K in keyof T]: Exclude<T[K], undefined> extends V
|
|
20
|
-
? T[K] extends Record<string, unknown>
|
|
21
|
-
? IncludePropType<T[K], V>
|
|
22
|
-
: T[K]
|
|
23
|
-
: never;
|
|
24
|
-
},
|
|
25
|
-
> = Prettify<
|
|
26
|
-
Pick<
|
|
27
|
-
WithNevers,
|
|
28
|
-
{
|
|
29
|
-
[K in keyof WithNevers]: WithNevers[K] extends never
|
|
30
|
-
? never
|
|
31
|
-
: K extends string
|
|
32
|
-
? K
|
|
33
|
-
: never;
|
|
34
|
-
}[keyof WithNevers]
|
|
35
|
-
>
|
|
36
|
-
>;
|
|
37
|
-
|
|
38
|
-
export type Store = Type<
|
|
39
|
-
Record<string, unknown> & StateSignals<SignalStoreFeatureResult['state']>
|
|
40
|
-
>;
|
|
41
|
-
|
|
42
|
-
export type CreateReduxState<StoreName extends string, STORE extends Store> = {
|
|
43
|
-
[K in StoreName as `provide${Capitalize<K>}Store`]: (
|
|
44
|
-
connectReduxDevtools?: boolean,
|
|
45
|
-
) => EnvironmentProviders;
|
|
46
|
-
} & {
|
|
47
|
-
[K in StoreName as `inject${Capitalize<K>}Store`]: () => InjectableReduxSlice<STORE>;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export type Selectors<STORE extends Store> = IncludePropType<
|
|
51
|
-
InstanceType<STORE>,
|
|
52
|
-
Signal<unknown> | DeepSignal<unknown>
|
|
53
|
-
>;
|
|
54
|
-
export type Dispatch = {
|
|
55
|
-
dispatch: (
|
|
56
|
-
input: Action | Observable<Action> | Signal<Action>,
|
|
57
|
-
) => Unsubscribable;
|
|
58
|
-
};
|
|
59
|
-
export type InjectableReduxSlice<STORE extends Store> = Selectors<STORE> &
|
|
60
|
-
Dispatch;
|
|
61
|
-
|
|
62
|
-
export type ExtractActionTypes<Creators extends readonly ActionCreator[]> = {
|
|
63
|
-
[Key in keyof Creators]: Creators[Key] extends ActionCreator<infer T>
|
|
64
|
-
? T
|
|
65
|
-
: never;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export interface ActionMethod<T, V extends Action = Action> {
|
|
69
|
-
(action: V): T;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface StoreMethod<
|
|
73
|
-
Creators extends readonly ActionCreator[],
|
|
74
|
-
ResultState = unknown,
|
|
75
|
-
> {
|
|
76
|
-
(action: ActionType<Creators[number]>): ResultState;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface MapperTypes<Creators extends readonly ActionCreator[]> {
|
|
80
|
-
types: ExtractActionTypes<Creators>;
|
|
81
|
-
storeMethod: StoreMethod<Creators>;
|
|
82
|
-
resultMethod?: (...args: unknown[]) => unknown;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export type ServiceWithDecorator = {
|
|
86
|
-
ɵprov?: {
|
|
87
|
-
providedIn?: string;
|
|
88
|
-
};
|
|
89
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Injector, Signal, inject } from '@angular/core';
|
|
2
|
-
import { rxMethod } from '@ngrx/signals/rxjs-interop';
|
|
3
|
-
import { Observable, Unsubscribable, map, pipe } from 'rxjs';
|
|
4
|
-
|
|
5
|
-
type RxMethodInput<Input> = Input | Observable<Input> | Signal<Input>;
|
|
6
|
-
|
|
7
|
-
type RxMethodRef = {
|
|
8
|
-
destroy: () => void;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
type RxMethod<Input, MethodInput = Input, MethodResult = unknown> = ((
|
|
12
|
-
input: RxMethodInput<Input>,
|
|
13
|
-
resultMethod: (input: MethodInput) => MethodResult,
|
|
14
|
-
) => RxMethodRef) &
|
|
15
|
-
RxMethodRef;
|
|
16
|
-
|
|
17
|
-
export function reduxMethod<Input, MethodInput = Input>(
|
|
18
|
-
generator: (source$: Observable<Input>) => Observable<MethodInput>,
|
|
19
|
-
config?: { injector?: Injector },
|
|
20
|
-
): RxMethod<Input, MethodInput>;
|
|
21
|
-
export function reduxMethod<Input, MethodInput = Input, MethodResult = unknown>(
|
|
22
|
-
generator: (source$: Observable<Input>) => Observable<MethodInput>,
|
|
23
|
-
resultMethod: (input: MethodInput) => MethodResult,
|
|
24
|
-
config?: {
|
|
25
|
-
injector?: Injector;
|
|
26
|
-
},
|
|
27
|
-
): RxMethod<Input, MethodInput, MethodResult>;
|
|
28
|
-
export function reduxMethod<Input, MethodInput = Input, MethodResult = unknown>(
|
|
29
|
-
generator: (source$: Observable<Input>) => Observable<MethodInput>,
|
|
30
|
-
resultMethodOrConfig?:
|
|
31
|
-
| ((input: MethodInput) => MethodResult)
|
|
32
|
-
| {
|
|
33
|
-
injector?: Injector;
|
|
34
|
-
},
|
|
35
|
-
config?: {
|
|
36
|
-
injector?: Injector;
|
|
37
|
-
},
|
|
38
|
-
): RxMethod<Input, MethodInput, MethodResult> {
|
|
39
|
-
const injector = inject(Injector);
|
|
40
|
-
|
|
41
|
-
if (typeof resultMethodOrConfig === 'function') {
|
|
42
|
-
let unsubscribable: Unsubscribable;
|
|
43
|
-
const inputResultFn = ((
|
|
44
|
-
input: RxMethodInput<Input>,
|
|
45
|
-
resultMethod = resultMethodOrConfig,
|
|
46
|
-
) => {
|
|
47
|
-
const rxMethodWithResult = rxMethod<Input>(
|
|
48
|
-
pipe(generator, map(resultMethod)),
|
|
49
|
-
{
|
|
50
|
-
...(config || {}),
|
|
51
|
-
injector: config?.injector || injector,
|
|
52
|
-
},
|
|
53
|
-
);
|
|
54
|
-
const rxWithInput = rxMethodWithResult(input);
|
|
55
|
-
unsubscribable = { unsubscribe: rxWithInput.destroy.bind(rxWithInput) };
|
|
56
|
-
|
|
57
|
-
return rxWithInput;
|
|
58
|
-
}) as RxMethod<Input, MethodInput, MethodResult>;
|
|
59
|
-
|
|
60
|
-
inputResultFn.destroy = () => unsubscribable?.unsubscribe();
|
|
61
|
-
|
|
62
|
-
return inputResultFn;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return rxMethod<Input>(generator, resultMethodOrConfig);
|
|
66
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Injectable, inject } from '@angular/core';
|
|
2
|
-
import { rxMethod } from '@ngrx/signals/rxjs-interop';
|
|
3
|
-
import { Action, ActionCreator } from '@ngrx/store';
|
|
4
|
-
import { pipe, tap } from 'rxjs';
|
|
5
|
-
import { MapperTypes } from './model';
|
|
6
|
-
import { isUnsubscribable } from './util';
|
|
7
|
-
|
|
8
|
-
@Injectable({
|
|
9
|
-
providedIn: 'root',
|
|
10
|
-
})
|
|
11
|
-
export class SignalReduxStore {
|
|
12
|
-
private mapperDict: Record<
|
|
13
|
-
string,
|
|
14
|
-
{
|
|
15
|
-
storeMethod: (...args: unknown[]) => unknown;
|
|
16
|
-
resultMethod?: (...args: unknown[]) => unknown;
|
|
17
|
-
}
|
|
18
|
-
> = {};
|
|
19
|
-
|
|
20
|
-
dispatch = rxMethod<Action>(
|
|
21
|
-
pipe(
|
|
22
|
-
tap((action: Action) => {
|
|
23
|
-
const callbacks = this.mapperDict[action.type];
|
|
24
|
-
if (callbacks?.storeMethod) {
|
|
25
|
-
if (
|
|
26
|
-
isUnsubscribable(callbacks.storeMethod) &&
|
|
27
|
-
callbacks.resultMethod
|
|
28
|
-
) {
|
|
29
|
-
return callbacks.storeMethod(action, (a: Action) => {
|
|
30
|
-
const resultAction = callbacks.resultMethod?.(a) as Action;
|
|
31
|
-
this.dispatch(resultAction);
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return callbacks?.storeMethod(action);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return;
|
|
39
|
-
}),
|
|
40
|
-
),
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
-
connectFeatureStore(mappers: MapperTypes<ActionCreator<any, any>[]>[]): void {
|
|
45
|
-
mappers.forEach((mapper) =>
|
|
46
|
-
mapper.types.forEach(
|
|
47
|
-
(action) =>
|
|
48
|
-
(this.mapperDict[action] = {
|
|
49
|
-
storeMethod: mapper.storeMethod,
|
|
50
|
-
resultMethod: mapper.resultMethod,
|
|
51
|
-
}),
|
|
52
|
-
),
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function injectReduxDispatch() {
|
|
58
|
-
return inject(SignalReduxStore).dispatch;
|
|
59
|
-
}
|