@ngxs/store 21.0.0 → 22.0.0-dev.master-d79b246
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/ngxs-store-internals-testing.mjs +10 -10
- package/fesm2022/ngxs-store-internals-testing.mjs.map +1 -1
- package/fesm2022/ngxs-store-internals.mjs +72 -44
- package/fesm2022/ngxs-store-internals.mjs.map +1 -1
- package/fesm2022/ngxs-store-operators.mjs +311 -35
- package/fesm2022/ngxs-store-operators.mjs.map +1 -1
- package/fesm2022/ngxs-store-plugins.mjs +10 -1
- package/fesm2022/ngxs-store-plugins.mjs.map +1 -1
- package/fesm2022/ngxs-store.mjs +468 -183
- package/fesm2022/ngxs-store.mjs.map +1 -1
- package/index.d.ts +124 -35
- package/internals/index.d.ts +32 -11
- package/internals/testing/index.d.ts +1 -1
- package/operators/index.d.ts +234 -14
- package/package.json +3 -12
- package/schematics/src/utils/versions.json +1 -1
package/fesm2022/ngxs-store.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Injectable, DestroyRef, NgZone, Injector, runInInjectionContext, InjectionToken, ErrorHandler, ɵisPromise as _isPromise, computed, makeEnvironmentProviders, provideEnvironmentInitializer, NgModule, APP_BOOTSTRAP_LISTENER, PendingTasks, ApplicationRef
|
|
3
|
-
import { config, Observable, Subject, of, forkJoin, map, shareReplay,
|
|
4
|
-
import { ɵwrapObserverCalls as _wrapObserverCalls, ɵOrderedSubject as _OrderedSubject, ɵStateStream as _StateStream, ɵhasOwnProperty as _hasOwnProperty, ɵmemoize as _memoize, ɵgetStoreMetadata as _getStoreMetadata, ɵgetSelectorMetadata as _getSelectorMetadata, ɵMETA_KEY as _META_KEY, ɵINITIAL_STATE_TOKEN as _INITIAL_STATE_TOKEN, ɵNgxsActionRegistry as _NgxsActionRegistry,
|
|
2
|
+
import { inject, Injectable, DestroyRef, NgZone, Injector, runInInjectionContext, InjectionToken, ErrorHandler, EnvironmentInjector, ɵisPromise as _isPromise, computed, makeEnvironmentProviders, provideEnvironmentInitializer, assertInInjectionContext, createEnvironmentInjector, NgModule, APP_BOOTSTRAP_LISTENER, PendingTasks, ApplicationRef } from '@angular/core';
|
|
3
|
+
import { config, Observable, Subject, of, forkJoin, map, shareReplay, mergeMap, EMPTY, filter, from, isObservable, defaultIfEmpty, takeUntil, finalize, catchError, distinctUntilChanged, take, buffer, debounceTime } from 'rxjs';
|
|
4
|
+
import { ɵwrapObserverCalls as _wrapObserverCalls, ɵOrderedSubject as _OrderedSubject, ɵStateStream as _StateStream, ɵhasOwnProperty as _hasOwnProperty, ɵmemoize as _memoize, ɵgetStoreMetadata as _getStoreMetadata, ɵgetSelectorMetadata as _getSelectorMetadata, ɵMETA_KEY as _META_KEY, ɵNGXS_DEVELOPMENT_OPTIONS as _NGXS_DEVELOPMENT_OPTIONS, ɵINITIAL_STATE_TOKEN as _INITIAL_STATE_TOKEN, ɵNgxsActionRegistry as _NgxsActionRegistry, ɵNGXS_APP_BOOTSTRAP_STATE as _NGXS_APP_BOOTSTRAP_STATE, ɵensureStoreMetadata as _ensureStoreMetadata, ɵMETA_OPTIONS_KEY as _META_OPTIONS_KEY, ɵensureSelectorMetadata as _ensureSelectorMetadata, ɵNGXS_STATE_CONTEXT_FACTORY as _NGXS_STATE_CONTEXT_FACTORY, ɵNGXS_STATE_FACTORY as _NGXS_STATE_FACTORY } from '@ngxs/store/internals';
|
|
5
5
|
export { StateToken } from '@ngxs/store/internals';
|
|
6
6
|
import { NGXS_PLUGINS, getActionTypeFromInstance, InitState, UpdateState, setValue, getValue, ɵisPluginClass as _isPluginClass } from '@ngxs/store/plugins';
|
|
7
7
|
export { InitState, NGXS_PLUGINS, UpdateState, actionMatcher, getActionTypeFromInstance, getValue, setValue } from '@ngxs/store/plugins';
|
|
8
8
|
import { isStateOperator } from '@ngxs/store/operators';
|
|
9
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
9
|
+
import { toObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
10
10
|
|
|
11
11
|
class PluginManager {
|
|
12
12
|
plugins = [];
|
|
@@ -31,10 +31,10 @@ class PluginManager {
|
|
|
31
31
|
const handlers = this._pluginHandlers || [];
|
|
32
32
|
return handlers.map((plugin) => (plugin.handle ? plugin.handle.bind(plugin) : plugin));
|
|
33
33
|
}
|
|
34
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
35
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
34
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PluginManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
35
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PluginManager, providedIn: 'root' });
|
|
36
36
|
}
|
|
37
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
37
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PluginManager, decorators: [{
|
|
38
38
|
type: Injectable,
|
|
39
39
|
args: [{ providedIn: 'root' }]
|
|
40
40
|
}], ctorParameters: () => [] });
|
|
@@ -131,12 +131,15 @@ class InternalDispatchedActionResults extends Subject {
|
|
|
131
131
|
// Complete the subject once the root injector is destroyed to ensure
|
|
132
132
|
// there are no active subscribers that would receive events or perform
|
|
133
133
|
// any actions after the application is destroyed.
|
|
134
|
-
inject(DestroyRef).onDestroy(() =>
|
|
134
|
+
inject(DestroyRef).onDestroy(() => {
|
|
135
|
+
this.complete();
|
|
136
|
+
this.unsubscribe();
|
|
137
|
+
});
|
|
135
138
|
}
|
|
136
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
137
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
139
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalDispatchedActionResults, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
140
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalDispatchedActionResults, providedIn: 'root' });
|
|
138
141
|
}
|
|
139
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
142
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalDispatchedActionResults, decorators: [{
|
|
140
143
|
type: Injectable,
|
|
141
144
|
args: [{ providedIn: 'root' }]
|
|
142
145
|
}], ctorParameters: () => [] });
|
|
@@ -164,10 +167,10 @@ class InternalNgxsExecutionStrategy {
|
|
|
164
167
|
}
|
|
165
168
|
return func();
|
|
166
169
|
}
|
|
167
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
168
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
170
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalNgxsExecutionStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
171
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalNgxsExecutionStrategy, providedIn: 'root' });
|
|
169
172
|
}
|
|
170
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
173
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalNgxsExecutionStrategy, decorators: [{
|
|
171
174
|
type: Injectable,
|
|
172
175
|
args: [{ providedIn: 'root' }]
|
|
173
176
|
}] });
|
|
@@ -202,13 +205,15 @@ class InternalActions extends _OrderedSubject {
|
|
|
202
205
|
// there are no active subscribers that would receive events or perform
|
|
203
206
|
// any actions after the application is destroyed.
|
|
204
207
|
this.complete();
|
|
208
|
+
this.unsubscribe();
|
|
205
209
|
this.dispatched$.complete();
|
|
210
|
+
this.dispatched$.unsubscribe();
|
|
206
211
|
});
|
|
207
212
|
}
|
|
208
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
209
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
213
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
214
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActions, providedIn: 'root' });
|
|
210
215
|
}
|
|
211
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
216
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActions, decorators: [{
|
|
212
217
|
type: Injectable,
|
|
213
218
|
args: [{ providedIn: 'root' }]
|
|
214
219
|
}], ctorParameters: () => [] });
|
|
@@ -238,10 +243,10 @@ class Actions extends Observable {
|
|
|
238
243
|
observer.add(childSubscription);
|
|
239
244
|
});
|
|
240
245
|
}
|
|
241
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
242
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
246
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Actions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
247
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Actions, providedIn: 'root' });
|
|
243
248
|
}
|
|
244
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
249
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Actions, decorators: [{
|
|
245
250
|
type: Injectable,
|
|
246
251
|
args: [{ providedIn: 'root' }]
|
|
247
252
|
}], ctorParameters: () => [] });
|
|
@@ -296,7 +301,23 @@ class InternalDispatcher {
|
|
|
296
301
|
])(prevState, action).pipe(shareReplay());
|
|
297
302
|
}
|
|
298
303
|
getActionResultStream(action) {
|
|
299
|
-
|
|
304
|
+
// Hot path: avoid allocating `filter` + `take(1)` operator subscriber wrappers on every
|
|
305
|
+
// dispatch. Instead, subscribe directly and complete inline — functionally identical but
|
|
306
|
+
// without the intermediate operator chain objects.
|
|
307
|
+
// `subscriber.complete()` triggers the outer subscription's teardown synchronously, which
|
|
308
|
+
// calls `.unsubscribe()` on the inner `_actionResults` subscription (the returned
|
|
309
|
+
// TeardownLogic), so there is no leak even though unsubscription fires mid-callback.
|
|
310
|
+
return new Observable(subscriber => {
|
|
311
|
+
return this._actionResults.subscribe({
|
|
312
|
+
next: ctx => {
|
|
313
|
+
if (ctx.action === action && ctx.status !== ActionStatus.Dispatched) {
|
|
314
|
+
subscriber.next(ctx);
|
|
315
|
+
subscriber.complete();
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
complete: () => !subscriber.closed && subscriber.complete()
|
|
319
|
+
});
|
|
320
|
+
}).pipe(shareReplay());
|
|
300
321
|
}
|
|
301
322
|
createDispatchObservable(actionResult$) {
|
|
302
323
|
return actionResult$.pipe(mergeMap((ctx) => {
|
|
@@ -314,10 +335,10 @@ class InternalDispatcher {
|
|
|
314
335
|
}
|
|
315
336
|
}), shareReplay());
|
|
316
337
|
}
|
|
317
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
318
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
338
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalDispatcher, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
339
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalDispatcher, providedIn: 'root' });
|
|
319
340
|
}
|
|
320
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
341
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalDispatcher, decorators: [{
|
|
321
342
|
type: Injectable,
|
|
322
343
|
args: [{ providedIn: 'root' }]
|
|
323
344
|
}] });
|
|
@@ -384,8 +405,8 @@ class NgxsConfig {
|
|
|
384
405
|
injectContainerState: false,
|
|
385
406
|
suppressErrors: false
|
|
386
407
|
};
|
|
387
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
388
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
408
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
409
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsConfig, providedIn: 'root', useFactory: () => {
|
|
389
410
|
const defaultConfig = new NgxsConfig();
|
|
390
411
|
const config = inject(NGXS_OPTIONS);
|
|
391
412
|
return {
|
|
@@ -398,7 +419,7 @@ class NgxsConfig {
|
|
|
398
419
|
};
|
|
399
420
|
} });
|
|
400
421
|
}
|
|
401
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
422
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsConfig, decorators: [{
|
|
402
423
|
type: Injectable,
|
|
403
424
|
args: [{
|
|
404
425
|
providedIn: 'root',
|
|
@@ -482,10 +503,10 @@ class InternalStateOperations {
|
|
|
482
503
|
// Set the state to the current + new
|
|
483
504
|
stateOperations.setState({ ...currentState, ...results.defaults });
|
|
484
505
|
}
|
|
485
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
486
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
506
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalStateOperations, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
507
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalStateOperations, providedIn: 'root' });
|
|
487
508
|
}
|
|
488
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
509
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalStateOperations, decorators: [{
|
|
489
510
|
type: Injectable,
|
|
490
511
|
args: [{ providedIn: 'root' }]
|
|
491
512
|
}] });
|
|
@@ -547,7 +568,7 @@ function createMemoizedSelectorFn(originalFn, creationMetadata) {
|
|
|
547
568
|
}
|
|
548
569
|
return returnValue;
|
|
549
570
|
};
|
|
550
|
-
const memoizedFn = _memoize(wrappedFn);
|
|
571
|
+
const memoizedFn = _memoize(wrappedFn, originalFn);
|
|
551
572
|
Object.setPrototypeOf(memoizedFn, originalFn);
|
|
552
573
|
return memoizedFn;
|
|
553
574
|
}
|
|
@@ -673,7 +694,7 @@ function buildGraph(stateClasses) {
|
|
|
673
694
|
const meta = stateClass[_META_KEY];
|
|
674
695
|
graph[meta.name] = (meta.children || []).map(findName);
|
|
675
696
|
return graph;
|
|
676
|
-
},
|
|
697
|
+
}, Object.create(null));
|
|
677
698
|
}
|
|
678
699
|
/**
|
|
679
700
|
* Given a states array, returns object graph
|
|
@@ -690,7 +711,7 @@ function nameToState(states) {
|
|
|
690
711
|
const meta = stateClass[_META_KEY];
|
|
691
712
|
result[meta.name] = stateClass;
|
|
692
713
|
return result;
|
|
693
|
-
},
|
|
714
|
+
}, Object.create(null));
|
|
694
715
|
}
|
|
695
716
|
/**
|
|
696
717
|
* Given a object relationship graph will return the full path
|
|
@@ -712,7 +733,7 @@ function nameToState(states) {
|
|
|
712
733
|
*
|
|
713
734
|
* @ignore
|
|
714
735
|
*/
|
|
715
|
-
function findFullParentPath(obj, out =
|
|
736
|
+
function findFullParentPath(obj, out = Object.create(null)) {
|
|
716
737
|
// Recursively find the full dotted parent path for a given key.
|
|
717
738
|
const find = (graph, target) => {
|
|
718
739
|
for (const key in graph) {
|
|
@@ -751,7 +772,7 @@ function findFullParentPath(obj, out = {}) {
|
|
|
751
772
|
*/
|
|
752
773
|
function topologicalSort(graph) {
|
|
753
774
|
const sorted = [];
|
|
754
|
-
const visited =
|
|
775
|
+
const visited = Object.create(null);
|
|
755
776
|
// DFS (Depth-First Search) to visit each node and its dependencies.
|
|
756
777
|
const visit = (name, ancestors = []) => {
|
|
757
778
|
visited[name] = true;
|
|
@@ -860,12 +881,6 @@ function jit_hasInjectableAnnotation(stateClass) {
|
|
|
860
881
|
return annotations.some((annotation) => annotation?.ngMetadataName === 'Injectable');
|
|
861
882
|
}
|
|
862
883
|
|
|
863
|
-
const NGXS_DEVELOPMENT_OPTIONS =
|
|
864
|
-
/* @__PURE__ */ new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'NGXS_DEVELOPMENT_OPTIONS' : '', {
|
|
865
|
-
providedIn: 'root',
|
|
866
|
-
factory: () => ({ warnOnUnhandledActions: true })
|
|
867
|
-
});
|
|
868
|
-
|
|
869
884
|
class NgxsUnhandledActionsLogger {
|
|
870
885
|
/**
|
|
871
886
|
* These actions should be ignored by default; the user can increase this
|
|
@@ -873,7 +888,7 @@ class NgxsUnhandledActionsLogger {
|
|
|
873
888
|
*/
|
|
874
889
|
_ignoredActions = new Set([InitState.type, UpdateState.type]);
|
|
875
890
|
constructor() {
|
|
876
|
-
const options = inject(
|
|
891
|
+
const options = inject(_NGXS_DEVELOPMENT_OPTIONS);
|
|
877
892
|
if (typeof options.warnOnUnhandledActions === 'object') {
|
|
878
893
|
this.ignoreActions(...options.warnOnUnhandledActions.ignore);
|
|
879
894
|
}
|
|
@@ -898,10 +913,10 @@ class NgxsUnhandledActionsLogger {
|
|
|
898
913
|
: action.type;
|
|
899
914
|
console.warn(`The ${action} action has been dispatched but hasn't been handled. This may happen if the state with an action handler for this action is not registered.`);
|
|
900
915
|
}
|
|
901
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
902
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
916
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledActionsLogger, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
917
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledActionsLogger });
|
|
903
918
|
}
|
|
904
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
919
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledActionsLogger, decorators: [{
|
|
905
920
|
type: Injectable
|
|
906
921
|
}], ctorParameters: () => [] });
|
|
907
922
|
|
|
@@ -922,10 +937,10 @@ class NgxsUnhandledErrorHandler {
|
|
|
922
937
|
// `handleError` (see `_callAndReportToErrorHandler`).
|
|
923
938
|
this._ngZone.runOutsideAngular(() => this._errorHandler.handleError(error));
|
|
924
939
|
}
|
|
925
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
926
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
940
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledErrorHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
941
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledErrorHandler, providedIn: 'root' });
|
|
927
942
|
}
|
|
928
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
943
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledErrorHandler, decorators: [{
|
|
929
944
|
type: Injectable,
|
|
930
945
|
args: [{ providedIn: 'root' }]
|
|
931
946
|
}] });
|
|
@@ -1023,13 +1038,13 @@ function createAllowedActionTypesMap(types) {
|
|
|
1023
1038
|
return types.reduce((filterMap, klass) => {
|
|
1024
1039
|
filterMap[getActionTypeFromInstance(klass)] = true;
|
|
1025
1040
|
return filterMap;
|
|
1026
|
-
},
|
|
1041
|
+
}, Object.create(null));
|
|
1027
1042
|
}
|
|
1028
1043
|
function createAllowedStatusesMap(statuses) {
|
|
1029
1044
|
return statuses.reduce((filterMap, status) => {
|
|
1030
1045
|
filterMap[status] = true;
|
|
1031
1046
|
return filterMap;
|
|
1032
|
-
},
|
|
1047
|
+
}, Object.create(null));
|
|
1033
1048
|
}
|
|
1034
1049
|
|
|
1035
1050
|
function simplePatch(value) {
|
|
@@ -1051,35 +1066,74 @@ function simplePatch(value) {
|
|
|
1051
1066
|
};
|
|
1052
1067
|
}
|
|
1053
1068
|
|
|
1069
|
+
class StateContextDestroyedError extends Error {
|
|
1070
|
+
path;
|
|
1071
|
+
name = 'StateContextDestroyedError';
|
|
1072
|
+
constructor(path) {
|
|
1073
|
+
super(typeof ngDevMode !== 'undefined' && ngDevMode
|
|
1074
|
+
? `Attempted to interact with state after the injector has been destroyed. State path: "${path}". ` +
|
|
1075
|
+
`This can happen in server-side rendering when the app is destroyed before all async operations complete, ` +
|
|
1076
|
+
`e.g. inside a finalize() operator that runs after the injector has been destroyed.`
|
|
1077
|
+
: path);
|
|
1078
|
+
this.path = path;
|
|
1079
|
+
Object.setPrototypeOf(this, StateContextDestroyedError.prototype);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1054
1082
|
/**
|
|
1055
|
-
*
|
|
1083
|
+
* Creates `StateContext` instances scoped to a specific state path.
|
|
1084
|
+
* Each action handler receives one of these contexts so it can read and
|
|
1085
|
+
* write only its own slice of the global state tree.
|
|
1056
1086
|
* @ignore
|
|
1057
1087
|
*/
|
|
1058
1088
|
class StateContextFactory {
|
|
1089
|
+
_injector = inject(EnvironmentInjector);
|
|
1059
1090
|
_internalStateOperations = inject(InternalStateOperations);
|
|
1091
|
+
// Resolved lazily via `setErrorHandler` to avoid a cyclic dependency when
|
|
1092
|
+
// the ErrorHandler itself injects the Store.
|
|
1093
|
+
_errorHandler = null;
|
|
1060
1094
|
/**
|
|
1061
1095
|
* Create the state context
|
|
1062
1096
|
*/
|
|
1063
1097
|
createStateContext(path, abortSignal) {
|
|
1098
|
+
const injector = this._injector;
|
|
1099
|
+
const errorHandler = this._errorHandler;
|
|
1064
1100
|
const root = this._internalStateOperations.getRootStateOperations();
|
|
1065
1101
|
return {
|
|
1066
1102
|
abortSignal,
|
|
1067
1103
|
getState() {
|
|
1104
|
+
if (injector.destroyed) {
|
|
1105
|
+
// Only report — do not return early. Returning `undefined as T` would
|
|
1106
|
+
// be a breaking change for callers that assume getState() always
|
|
1107
|
+
// returns a value. handleError is just for observability (e.g. Rollbar);
|
|
1108
|
+
// the state data is still readable even after the injector is gone.
|
|
1109
|
+
errorHandler?.handleError(new StateContextDestroyedError(path));
|
|
1110
|
+
}
|
|
1068
1111
|
const currentAppState = root.getState();
|
|
1069
1112
|
return getState(currentAppState, path);
|
|
1070
1113
|
},
|
|
1071
|
-
patchState(
|
|
1114
|
+
patchState(value) {
|
|
1115
|
+
// If the injector has been destroyed (e.g. app destroyed mid-action),
|
|
1116
|
+
// skip the state update to avoid writing to completed subjects.
|
|
1117
|
+
if (injector.destroyed) {
|
|
1118
|
+
errorHandler?.handleError(new StateContextDestroyedError(path));
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1072
1121
|
const currentAppState = root.getState();
|
|
1073
|
-
const patchOperator = simplePatch(
|
|
1074
|
-
setStateFromOperator(root, currentAppState, patchOperator, path);
|
|
1122
|
+
const patchOperator = simplePatch(value);
|
|
1123
|
+
setStateFromOperator(root, currentAppState, patchOperator, path, injector);
|
|
1075
1124
|
},
|
|
1076
|
-
setState(
|
|
1125
|
+
setState(value) {
|
|
1126
|
+
// Same guard as patchState — no-op if the injector is already destroyed.
|
|
1127
|
+
if (injector.destroyed) {
|
|
1128
|
+
errorHandler?.handleError(new StateContextDestroyedError(path));
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1077
1131
|
const currentAppState = root.getState();
|
|
1078
|
-
if (isStateOperator(
|
|
1079
|
-
setStateFromOperator(root, currentAppState,
|
|
1132
|
+
if (isStateOperator(value)) {
|
|
1133
|
+
setStateFromOperator(root, currentAppState, value, path, injector);
|
|
1080
1134
|
}
|
|
1081
1135
|
else {
|
|
1082
|
-
setStateValue(root, currentAppState,
|
|
1136
|
+
setStateValue(root, currentAppState, value, path, injector);
|
|
1083
1137
|
}
|
|
1084
1138
|
},
|
|
1085
1139
|
dispatch(actions) {
|
|
@@ -1087,32 +1141,58 @@ class StateContextFactory {
|
|
|
1087
1141
|
}
|
|
1088
1142
|
};
|
|
1089
1143
|
}
|
|
1090
|
-
/** @
|
|
1091
|
-
|
|
1144
|
+
/** @internal */
|
|
1145
|
+
setErrorHandler() {
|
|
1146
|
+
// Called from `LifecycleStateManager.ngxsBootstrap` rather than at
|
|
1147
|
+
// construction time. If we injected ErrorHandler in the constructor,
|
|
1148
|
+
// an ErrorHandler that itself injects Store would create a circular
|
|
1149
|
+
// dependency — deferring the lookup breaks the cycle.
|
|
1150
|
+
this._errorHandler ??= this._injector.get(ErrorHandler);
|
|
1151
|
+
}
|
|
1152
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateContextFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1153
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateContextFactory, providedIn: 'root' });
|
|
1092
1154
|
}
|
|
1093
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1155
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateContextFactory, decorators: [{
|
|
1094
1156
|
type: Injectable,
|
|
1095
1157
|
args: [{ providedIn: 'root' }]
|
|
1096
1158
|
}] });
|
|
1097
|
-
function setStateValue(root, currentAppState, newValue, path) {
|
|
1159
|
+
function setStateValue(root, currentAppState, newValue, path, injector) {
|
|
1160
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1161
|
+
warnIfNewReferenceHasIdenticalValue(injector, getState(currentAppState, path), newValue, path);
|
|
1162
|
+
}
|
|
1098
1163
|
const newAppState = setValue(currentAppState, path, newValue);
|
|
1099
1164
|
root.setState(newAppState);
|
|
1165
|
+
// Note: this returns the full app state rather than just the patched slice.
|
|
1166
|
+
// That's a long-standing quirk (present since the original state-factory.ts)
|
|
1167
|
+
// and fixing it would be a breaking change — tracked for a future release.
|
|
1100
1168
|
return newAppState;
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
// This has worked this way since the beginning see:
|
|
1104
|
-
// https://github.com/ngxs/store/blame/324c667b4b7debd8eb979006c67ca0ae347d88cd/src/state-factory.ts
|
|
1105
|
-
// This needs to be fixed, but is a 'breaking' change.
|
|
1106
|
-
// I will do this fix in a subsequent PR and we can decide how to handle it.
|
|
1107
|
-
}
|
|
1108
|
-
function setStateFromOperator(root, currentAppState, stateOperator, path) {
|
|
1169
|
+
}
|
|
1170
|
+
function setStateFromOperator(root, currentAppState, stateOperator, path, injector) {
|
|
1109
1171
|
const local = getState(currentAppState, path);
|
|
1110
1172
|
const newValue = stateOperator(local);
|
|
1111
|
-
return setStateValue(root, currentAppState, newValue, path);
|
|
1173
|
+
return setStateValue(root, currentAppState, newValue, path, injector);
|
|
1112
1174
|
}
|
|
1113
1175
|
function getState(currentAppState, path) {
|
|
1114
1176
|
return getValue(currentAppState, path);
|
|
1115
1177
|
}
|
|
1178
|
+
// Mirrors `warnOnNewReferenceWithIdenticalValue` in `Store#selectSignal`, but catches the
|
|
1179
|
+
// producer side: an action handler that sets a new reference with an identical value causes
|
|
1180
|
+
// unnecessary re-emissions for every `select()`/`selectSignal()` subscriber on this slice.
|
|
1181
|
+
function warnIfNewReferenceHasIdenticalValue(injector, oldValue, newValue, path) {
|
|
1182
|
+
if (Object.is(oldValue, newValue) || injector.destroyed)
|
|
1183
|
+
return;
|
|
1184
|
+
const warnOption = injector.get(_NGXS_DEVELOPMENT_OPTIONS, null)?.warnOnNewReferenceWithIdenticalValue;
|
|
1185
|
+
if (!warnOption)
|
|
1186
|
+
return;
|
|
1187
|
+
try {
|
|
1188
|
+
if (warnOption.isEqual(oldValue, newValue)) {
|
|
1189
|
+
console.error(`A new reference with an identical value was set on the "${path}" state slice. This will cause unnecessary re-emissions for subscribers relying on reference-based equality.`);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
catch {
|
|
1193
|
+
// Swallow silently.
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1116
1196
|
|
|
1117
1197
|
class InternalActionHandlerFactory {
|
|
1118
1198
|
_actions = inject(InternalActions);
|
|
@@ -1182,10 +1262,10 @@ class InternalActionHandlerFactory {
|
|
|
1182
1262
|
return result;
|
|
1183
1263
|
};
|
|
1184
1264
|
}
|
|
1185
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1186
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
1265
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActionHandlerFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1266
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActionHandlerFactory, providedIn: 'root' });
|
|
1187
1267
|
}
|
|
1188
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1268
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActionHandlerFactory, decorators: [{
|
|
1189
1269
|
type: Injectable,
|
|
1190
1270
|
args: [{ providedIn: 'root' }]
|
|
1191
1271
|
}] });
|
|
@@ -1229,8 +1309,8 @@ class StateFactory {
|
|
|
1229
1309
|
_actionsSubscription = null;
|
|
1230
1310
|
_ngxsUnhandledErrorHandler = null;
|
|
1231
1311
|
_states = [];
|
|
1232
|
-
_statesByName =
|
|
1233
|
-
_statePaths =
|
|
1312
|
+
_statesByName = Object.create(null);
|
|
1313
|
+
_statePaths = Object.create(null);
|
|
1234
1314
|
getRuntimeSelectorContext = _memoize(() => {
|
|
1235
1315
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1236
1316
|
const stateFactory = this;
|
|
@@ -1326,20 +1406,51 @@ class StateFactory {
|
|
|
1326
1406
|
}
|
|
1327
1407
|
connectActionHandlers() {
|
|
1328
1408
|
this._actionsSubscription = this._actions
|
|
1329
|
-
.pipe(
|
|
1409
|
+
.pipe(mergeMap(ctx => {
|
|
1410
|
+
if (ctx.status !== ActionStatus.Dispatched) {
|
|
1411
|
+
return EMPTY;
|
|
1412
|
+
}
|
|
1330
1413
|
const action = ctx.action;
|
|
1331
|
-
return
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1414
|
+
return new Observable(subscriber => this.invokeActions(action).subscribe({
|
|
1415
|
+
next: () => {
|
|
1416
|
+
subscriber.next({ action, status: ActionStatus.Successful });
|
|
1417
|
+
subscriber.complete();
|
|
1418
|
+
},
|
|
1419
|
+
error: error => {
|
|
1420
|
+
const ngxsUnhandledErrorHandler = (this._ngxsUnhandledErrorHandler ||=
|
|
1421
|
+
this._injector.get(NgxsUnhandledErrorHandler));
|
|
1422
|
+
function callback() {
|
|
1423
|
+
ngxsUnhandledErrorHandler.handleError(error, { action });
|
|
1424
|
+
}
|
|
1425
|
+
// An arrow function here would share the `[[Context]]` of the enclosing `error =>`
|
|
1426
|
+
// arrow function, which captures `this` (StateFactory), causing the error object to
|
|
1427
|
+
// retain the entire instance. A named function declaration creates its own context and
|
|
1428
|
+
// V8 only captures variables it actually references — `ngxsUnhandledErrorHandler`,
|
|
1429
|
+
// `error`, `action` — so `this` is never captured. `.bind(null)` goes one step further:
|
|
1430
|
+
// a JSBoundFunction has no `[[Context]]` slot at all, fully severing the retention chain.
|
|
1431
|
+
// This matters because the callback is stored as a value in the
|
|
1432
|
+
// `ɵɵunhandledRxjsErrorCallbacks` WeakMap, keyed by the error object. The error may be
|
|
1433
|
+
// held by third-party code (e.g. error trackers, logging) for an indeterminate duration,
|
|
1434
|
+
// and we have no control over when that key is released.
|
|
1435
|
+
const handleableError = assignUnhandledCallback(error, callback.bind(null));
|
|
1436
|
+
subscriber.next({
|
|
1437
|
+
action,
|
|
1438
|
+
status: ActionStatus.Errored,
|
|
1439
|
+
error: handleableError
|
|
1440
|
+
});
|
|
1441
|
+
subscriber.complete();
|
|
1442
|
+
},
|
|
1443
|
+
complete: () => {
|
|
1444
|
+
if (subscriber.closed)
|
|
1445
|
+
return;
|
|
1446
|
+
subscriber.next({ action, status: ActionStatus.Canceled });
|
|
1447
|
+
subscriber.complete();
|
|
1448
|
+
}
|
|
1340
1449
|
}));
|
|
1341
1450
|
}))
|
|
1342
|
-
.subscribe(ctx =>
|
|
1451
|
+
.subscribe(ctx => {
|
|
1452
|
+
this._actionResults.next(ctx);
|
|
1453
|
+
});
|
|
1343
1454
|
}
|
|
1344
1455
|
/**
|
|
1345
1456
|
* Invoke actions on the states.
|
|
@@ -1373,10 +1484,7 @@ class StateFactory {
|
|
|
1373
1484
|
// didn't return `null` so we may ensure the module has been imported.
|
|
1374
1485
|
unhandledActionsLogger?.warn(action);
|
|
1375
1486
|
}
|
|
1376
|
-
|
|
1377
|
-
results.push(of(undefined));
|
|
1378
|
-
}
|
|
1379
|
-
return forkJoin(results);
|
|
1487
|
+
return results.length > 0 ? forkJoin(results) : of(undefined);
|
|
1380
1488
|
}
|
|
1381
1489
|
addToStatesMap(stateClasses) {
|
|
1382
1490
|
const newStates = [];
|
|
@@ -1409,24 +1517,23 @@ class StateFactory {
|
|
|
1409
1517
|
}
|
|
1410
1518
|
hydrateActionMetasMap({ path, actions, instance }) {
|
|
1411
1519
|
for (const actionType of Object.keys(actions)) {
|
|
1412
|
-
const
|
|
1520
|
+
for (const actionMeta of actions[actionType]) {
|
|
1413
1521
|
const handlerFn = (ctx, action) => instance[actionMeta.fn](ctx, action);
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
for (const actionHandler of actionHandlers) {
|
|
1417
|
-
this._actionRegistry.register(actionType, actionHandler);
|
|
1522
|
+
const actionHandler = this._actionHandlerFactory.createActionHandler(path, handlerFn, actionMeta.options);
|
|
1523
|
+
this._actionRegistry.register(actionType, actionHandler, actionMeta.actionClass);
|
|
1418
1524
|
}
|
|
1419
1525
|
}
|
|
1420
1526
|
}
|
|
1421
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1422
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
1527
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1528
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateFactory, providedIn: 'root' });
|
|
1423
1529
|
}
|
|
1424
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1530
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateFactory, decorators: [{
|
|
1425
1531
|
type: Injectable,
|
|
1426
1532
|
args: [{ providedIn: 'root' }]
|
|
1427
1533
|
}], ctorParameters: () => [] });
|
|
1428
1534
|
|
|
1429
1535
|
class Store {
|
|
1536
|
+
_injector;
|
|
1430
1537
|
_stateStream = inject(_StateStream);
|
|
1431
1538
|
_internalStateOperations = inject(InternalStateOperations);
|
|
1432
1539
|
_config = inject(NgxsConfig);
|
|
@@ -1440,6 +1547,9 @@ class Store {
|
|
|
1440
1547
|
_selectableStateStream = this._stateStream.pipe(leaveNgxs(this._internalExecutionStrategy), shareReplay({ bufferSize: 1, refCount: true }));
|
|
1441
1548
|
constructor() {
|
|
1442
1549
|
this.initStateStream();
|
|
1550
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1551
|
+
this._injector = inject(Injector);
|
|
1552
|
+
}
|
|
1443
1553
|
}
|
|
1444
1554
|
/**
|
|
1445
1555
|
* Dispatches action(s).
|
|
@@ -1491,6 +1601,21 @@ class Store {
|
|
|
1491
1601
|
const selectorFn = this.getStoreBoundSelectorFn(selector);
|
|
1492
1602
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1493
1603
|
return computed(() => selectorFn(this._stateStream.state()), {
|
|
1604
|
+
equal: (a, b) => {
|
|
1605
|
+
const warnOption = this._injector?.get(_NGXS_DEVELOPMENT_OPTIONS, null)?.warnOnNewReferenceWithIdenticalValue;
|
|
1606
|
+
if (warnOption && !Object.is(a, b)) {
|
|
1607
|
+
try {
|
|
1608
|
+
const originalFn = selector.originalFn;
|
|
1609
|
+
if (warnOption.isEqual(a, b) && originalFn) {
|
|
1610
|
+
console.error('The selector returned the same value shape as it was before triggering signal recomputation. Selector function: ', originalFn);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
catch {
|
|
1614
|
+
// Swallow silently.
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
return a === b;
|
|
1618
|
+
},
|
|
1494
1619
|
debugName: 'NGXS selectSignal'
|
|
1495
1620
|
});
|
|
1496
1621
|
}
|
|
@@ -1532,10 +1657,10 @@ class Store {
|
|
|
1532
1657
|
this._stateStream.next(initialStateValue);
|
|
1533
1658
|
}
|
|
1534
1659
|
}
|
|
1535
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1536
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
1660
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Store, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1661
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Store, providedIn: 'root' });
|
|
1537
1662
|
}
|
|
1538
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1663
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Store, decorators: [{
|
|
1539
1664
|
type: Injectable,
|
|
1540
1665
|
args: [{ providedIn: 'root' }]
|
|
1541
1666
|
}], ctorParameters: () => [] });
|
|
@@ -1570,6 +1695,125 @@ function withNgxsPreboot(prebootFn) {
|
|
|
1570
1695
|
]);
|
|
1571
1696
|
}
|
|
1572
1697
|
|
|
1698
|
+
/**
|
|
1699
|
+
* This function registers a custom global plugin for the state.
|
|
1700
|
+
*
|
|
1701
|
+
* ```ts
|
|
1702
|
+
* bootstrapApplication(AppComponent, {
|
|
1703
|
+
* providers: [
|
|
1704
|
+
* provideStore(
|
|
1705
|
+
* [CountriesState],
|
|
1706
|
+
* withNgxsPlugin(LogoutPlugin)
|
|
1707
|
+
* )
|
|
1708
|
+
* ]
|
|
1709
|
+
* });
|
|
1710
|
+
* ```
|
|
1711
|
+
*/
|
|
1712
|
+
function withNgxsPlugin(plugin) {
|
|
1713
|
+
return makeEnvironmentProviders([
|
|
1714
|
+
_isPluginClass(plugin)
|
|
1715
|
+
? { provide: NGXS_PLUGINS, useClass: plugin, multi: true }
|
|
1716
|
+
: { provide: NGXS_PLUGINS, useValue: plugin, multi: true },
|
|
1717
|
+
// We should inject the `PluginManager` to retrieve `NGXS_PLUGINS` and
|
|
1718
|
+
// register those plugins. The plugin can be added from inside the child
|
|
1719
|
+
// route, so the plugin manager should be re-injected.
|
|
1720
|
+
provideEnvironmentInitializer(() => inject(PluginManager))
|
|
1721
|
+
]);
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
const REGISTERED_PLUGINS = /* @__PURE__ */ new InjectionToken('', {
|
|
1725
|
+
factory: () => {
|
|
1726
|
+
const plugins = new Set();
|
|
1727
|
+
inject(DestroyRef).onDestroy(() => plugins.clear());
|
|
1728
|
+
return plugins;
|
|
1729
|
+
}
|
|
1730
|
+
});
|
|
1731
|
+
/**
|
|
1732
|
+
* Dynamically registers an NGXS plugin in the current injection context.
|
|
1733
|
+
*
|
|
1734
|
+
* This function allows you to register NGXS plugins at runtime, creating an isolated
|
|
1735
|
+
* environment injector for the plugin. The plugin is automatically cleaned up when
|
|
1736
|
+
* the injection context is destroyed. In development mode, the function validates
|
|
1737
|
+
* that the same plugin is not registered multiple times.
|
|
1738
|
+
*
|
|
1739
|
+
* @param plugin - The NGXS plugin to register. Can be either a class type implementing
|
|
1740
|
+
* `NgxsPlugin` or a plugin function (`NgxsPluginFn`).
|
|
1741
|
+
*
|
|
1742
|
+
* @throws {Error} Throws an error if called outside of an injection context.
|
|
1743
|
+
* @throws {Error} In development mode, throws an error if the plugin has already been registered.
|
|
1744
|
+
*
|
|
1745
|
+
* @remarks
|
|
1746
|
+
* - Must be called within an injection context (e.g., constructor, field initializer, or `runInInjectionContext`).
|
|
1747
|
+
* - The created environment injector is automatically destroyed when the parent context is destroyed.
|
|
1748
|
+
* - Duplicate plugin registration is only checked in development mode for performance reasons.
|
|
1749
|
+
*
|
|
1750
|
+
* @example
|
|
1751
|
+
* ```ts
|
|
1752
|
+
* // Register a plugin class
|
|
1753
|
+
* import { MyThirdPartyIntegrationPlugin } from './plugins/third-party.plugin';
|
|
1754
|
+
*
|
|
1755
|
+
* @Component({
|
|
1756
|
+
* selector: 'app-root',
|
|
1757
|
+
* template: '...'
|
|
1758
|
+
* })
|
|
1759
|
+
* export class AppComponent {
|
|
1760
|
+
* constructor() {
|
|
1761
|
+
* registerNgxsPlugin(MyThirdPartyIntegrationPlugin);
|
|
1762
|
+
* }
|
|
1763
|
+
* }
|
|
1764
|
+
* ```
|
|
1765
|
+
*
|
|
1766
|
+
* @example
|
|
1767
|
+
* ```ts
|
|
1768
|
+
* // Register a plugin function
|
|
1769
|
+
* import { myThirdPartyIntegrationPluginFn } from './plugins/third-party.plugin';
|
|
1770
|
+
*
|
|
1771
|
+
* @Component({
|
|
1772
|
+
* selector: 'app-feature',
|
|
1773
|
+
* template: '...'
|
|
1774
|
+
* })
|
|
1775
|
+
* export class FeatureComponent {
|
|
1776
|
+
* constructor() {
|
|
1777
|
+
* registerNgxsPlugin(myThirdPartyIntegrationPluginFn);
|
|
1778
|
+
* }
|
|
1779
|
+
* }
|
|
1780
|
+
* ```
|
|
1781
|
+
*
|
|
1782
|
+
* @example
|
|
1783
|
+
* ```ts
|
|
1784
|
+
* // Register conditionally based on environment
|
|
1785
|
+
* import { MyDevtoolsPlugin } from './plugins/devtools.plugin';
|
|
1786
|
+
*
|
|
1787
|
+
* @Component({
|
|
1788
|
+
* selector: 'app-root',
|
|
1789
|
+
* template: '...'
|
|
1790
|
+
* })
|
|
1791
|
+
* export class AppComponent {
|
|
1792
|
+
* constructor() {
|
|
1793
|
+
* if (ngDevMode) {
|
|
1794
|
+
* registerNgxsPlugin(MyDevtoolsPlugin);
|
|
1795
|
+
* }
|
|
1796
|
+
* }
|
|
1797
|
+
* }
|
|
1798
|
+
* ```
|
|
1799
|
+
*/
|
|
1800
|
+
function registerNgxsPlugin(plugin) {
|
|
1801
|
+
ngDevMode && assertInInjectionContext(registerNgxsPlugin);
|
|
1802
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1803
|
+
const registeredPlugins = inject(REGISTERED_PLUGINS);
|
|
1804
|
+
if (registeredPlugins.has(plugin)) {
|
|
1805
|
+
throw new Error('Plugin has already been registered. Each plugin should only be registered once to avoid unexpected behavior.');
|
|
1806
|
+
}
|
|
1807
|
+
registeredPlugins.add(plugin);
|
|
1808
|
+
}
|
|
1809
|
+
// Create a new environment injector with the plugin configuration.
|
|
1810
|
+
// This isolates the plugin's dependencies and providers.
|
|
1811
|
+
const injector = createEnvironmentInjector([PluginManager, withNgxsPlugin(plugin)], inject(EnvironmentInjector));
|
|
1812
|
+
// Ensure the created injector is destroyed when the injection context is destroyed.
|
|
1813
|
+
// This prevents memory leaks and ensures proper cleanup.
|
|
1814
|
+
inject(DestroyRef).onDestroy(() => injector.destroy());
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1573
1817
|
const ROOT_STORE_GUARD = /* @__PURE__ */ new InjectionToken('ROOT_STORE_GUARD', {
|
|
1574
1818
|
providedIn: 'root',
|
|
1575
1819
|
factory: () => ({ initialized: false })
|
|
@@ -1597,25 +1841,28 @@ class SelectFactory {
|
|
|
1597
1841
|
SelectFactory.config = null;
|
|
1598
1842
|
});
|
|
1599
1843
|
}
|
|
1600
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1601
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
1844
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SelectFactory, deps: [{ token: Store }, { token: NgxsConfig }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1845
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SelectFactory, providedIn: 'root' });
|
|
1602
1846
|
}
|
|
1603
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1847
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SelectFactory, decorators: [{
|
|
1604
1848
|
type: Injectable,
|
|
1605
1849
|
args: [{ providedIn: 'root' }]
|
|
1606
1850
|
}], ctorParameters: () => [{ type: Store }, { type: NgxsConfig }] });
|
|
1607
1851
|
|
|
1608
1852
|
class LifecycleStateManager {
|
|
1853
|
+
_destroyRef = inject(DestroyRef);
|
|
1854
|
+
_injector = inject(Injector);
|
|
1609
1855
|
_store = inject(Store);
|
|
1610
1856
|
_internalStateOperations = inject(InternalStateOperations);
|
|
1611
1857
|
_stateContextFactory = inject(StateContextFactory);
|
|
1612
|
-
|
|
1858
|
+
_appBootstrapState = inject(_NGXS_APP_BOOTSTRAP_STATE);
|
|
1613
1859
|
_abortController = new AbortController();
|
|
1614
1860
|
_initStateHasBeenDispatched;
|
|
1615
1861
|
constructor() {
|
|
1616
1862
|
inject(DestroyRef).onDestroy(() => this._abortController.abort());
|
|
1617
1863
|
}
|
|
1618
1864
|
ngxsBootstrap(action, results) {
|
|
1865
|
+
this._stateContextFactory.setErrorHandler();
|
|
1619
1866
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1620
1867
|
if (action instanceof InitState) {
|
|
1621
1868
|
this._initStateHasBeenDispatched = true;
|
|
@@ -1633,22 +1880,22 @@ class LifecycleStateManager {
|
|
|
1633
1880
|
}
|
|
1634
1881
|
// It does not need to unsubscribe because it is completed when the
|
|
1635
1882
|
// root injector is destroyed.
|
|
1636
|
-
this._internalStateOperations
|
|
1637
|
-
|
|
1638
|
-
.dispatch(action)
|
|
1639
|
-
.pipe(mergeMap(() => {
|
|
1883
|
+
const rootStateOperations = this._internalStateOperations.getRootStateOperations();
|
|
1884
|
+
rootStateOperations.dispatch(action).subscribe(() => {
|
|
1640
1885
|
// If no states are provided, we safely complete the stream
|
|
1641
1886
|
// and do not proceed further.
|
|
1642
1887
|
if (!results) {
|
|
1643
|
-
return
|
|
1888
|
+
return;
|
|
1644
1889
|
}
|
|
1645
1890
|
this._invokeInitOnStates(results.states);
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1891
|
+
const options = { injector: this._injector };
|
|
1892
|
+
toObservable(this._appBootstrapState, options)
|
|
1893
|
+
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
1894
|
+
.subscribe(appBootstrapped => {
|
|
1895
|
+
if (!appBootstrapped)
|
|
1896
|
+
return;
|
|
1650
1897
|
this._invokeBootstrapOnStates(results.states);
|
|
1651
|
-
}
|
|
1898
|
+
});
|
|
1652
1899
|
});
|
|
1653
1900
|
}
|
|
1654
1901
|
_invokeInitOnStates(mappedStores) {
|
|
@@ -1662,11 +1909,6 @@ class LifecycleStateManager {
|
|
|
1662
1909
|
// root injector is destroyed.
|
|
1663
1910
|
this._store
|
|
1664
1911
|
.select(state => getValue(state, mappedStore.path))
|
|
1665
|
-
.pipe(
|
|
1666
|
-
// Ensure initial state is captured
|
|
1667
|
-
startWith(undefined),
|
|
1668
|
-
// `skip` is using `filter` internally.
|
|
1669
|
-
skip(1))
|
|
1670
1912
|
.subscribe(currentValue => {
|
|
1671
1913
|
const change = new NgxsSimpleChange(previousValue, currentValue, !mappedStore.isInitialised);
|
|
1672
1914
|
previousValue = currentValue;
|
|
@@ -1686,10 +1928,10 @@ class LifecycleStateManager {
|
|
|
1686
1928
|
_getStateContext(mappedStore) {
|
|
1687
1929
|
return this._stateContextFactory.createStateContext(mappedStore.path, this._abortController.signal);
|
|
1688
1930
|
}
|
|
1689
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1690
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
1931
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LifecycleStateManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1932
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LifecycleStateManager, providedIn: 'root' });
|
|
1691
1933
|
}
|
|
1692
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1934
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LifecycleStateManager, decorators: [{
|
|
1693
1935
|
type: Injectable,
|
|
1694
1936
|
args: [{ providedIn: 'root' }]
|
|
1695
1937
|
}], ctorParameters: () => [] });
|
|
@@ -1776,11 +2018,11 @@ class NgxsRootModule {
|
|
|
1776
2018
|
constructor() {
|
|
1777
2019
|
rootStoreInitializer();
|
|
1778
2020
|
}
|
|
1779
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1780
|
-
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
1781
|
-
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
2021
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsRootModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2022
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: NgxsRootModule });
|
|
2023
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsRootModule });
|
|
1782
2024
|
}
|
|
1783
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2025
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsRootModule, decorators: [{
|
|
1784
2026
|
type: NgModule
|
|
1785
2027
|
}], ctorParameters: () => [] });
|
|
1786
2028
|
|
|
@@ -1791,11 +2033,11 @@ class NgxsFeatureModule {
|
|
|
1791
2033
|
constructor() {
|
|
1792
2034
|
featureStatesInitializer();
|
|
1793
2035
|
}
|
|
1794
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1795
|
-
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
1796
|
-
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
2036
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsFeatureModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2037
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: NgxsFeatureModule });
|
|
2038
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsFeatureModule });
|
|
1797
2039
|
}
|
|
1798
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2040
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsFeatureModule, decorators: [{
|
|
1799
2041
|
type: NgModule
|
|
1800
2042
|
}], ctorParameters: () => [] });
|
|
1801
2043
|
|
|
@@ -1813,8 +2055,8 @@ function getRootProviders(states, options) {
|
|
|
1813
2055
|
{
|
|
1814
2056
|
provide: APP_BOOTSTRAP_LISTENER,
|
|
1815
2057
|
useFactory: () => {
|
|
1816
|
-
const
|
|
1817
|
-
return () =>
|
|
2058
|
+
const bootstrapState = inject(_NGXS_APP_BOOTSTRAP_STATE);
|
|
2059
|
+
return () => bootstrapState.set(true);
|
|
1818
2060
|
},
|
|
1819
2061
|
multi: true
|
|
1820
2062
|
},
|
|
@@ -1841,24 +2083,33 @@ function getFeatureProviders(states) {
|
|
|
1841
2083
|
];
|
|
1842
2084
|
}
|
|
1843
2085
|
|
|
2086
|
+
/**
|
|
2087
|
+
* @deprecated Use `provideStore()` and `provideStates()` instead.
|
|
2088
|
+
*/
|
|
1844
2089
|
class NgxsModule {
|
|
2090
|
+
/**
|
|
2091
|
+
* @deprecated Use `provideStore()` instead.
|
|
2092
|
+
*/
|
|
1845
2093
|
static forRoot(states = [], options = {}) {
|
|
1846
2094
|
return {
|
|
1847
2095
|
ngModule: NgxsRootModule,
|
|
1848
2096
|
providers: getRootProviders(states, options)
|
|
1849
2097
|
};
|
|
1850
2098
|
}
|
|
2099
|
+
/**
|
|
2100
|
+
* @deprecated Use `provideStates()` instead.
|
|
2101
|
+
*/
|
|
1851
2102
|
static forFeature(states = []) {
|
|
1852
2103
|
return {
|
|
1853
2104
|
ngModule: NgxsFeatureModule,
|
|
1854
2105
|
providers: getFeatureProviders(states)
|
|
1855
2106
|
};
|
|
1856
2107
|
}
|
|
1857
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
1858
|
-
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
1859
|
-
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
2108
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2109
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: NgxsModule });
|
|
2110
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsModule });
|
|
1860
2111
|
}
|
|
1861
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsModule, decorators: [{
|
|
1862
2113
|
type: NgModule
|
|
1863
2114
|
}] });
|
|
1864
2115
|
|
|
@@ -1885,7 +2136,8 @@ function Action(actions, options) {
|
|
|
1885
2136
|
meta.actions[type].push({
|
|
1886
2137
|
fn: name,
|
|
1887
2138
|
options: options || {},
|
|
1888
|
-
type
|
|
2139
|
+
type,
|
|
2140
|
+
actionClass: action
|
|
1889
2141
|
});
|
|
1890
2142
|
}
|
|
1891
2143
|
};
|
|
@@ -2049,6 +2301,12 @@ function SelectorOptions(options) {
|
|
|
2049
2301
|
});
|
|
2050
2302
|
}
|
|
2051
2303
|
|
|
2304
|
+
/**
|
|
2305
|
+
* Function for creating a selector
|
|
2306
|
+
* @param selectors The selectors to use to create the arguments of this function
|
|
2307
|
+
* @param originalFn The original function being made into a selector
|
|
2308
|
+
* @param creationMetadata
|
|
2309
|
+
*/
|
|
2052
2310
|
function createSelector(selectors, projector, creationMetadata) {
|
|
2053
2311
|
const memoizedFn = createMemoizedSelectorFn(projector, creationMetadata);
|
|
2054
2312
|
const selectorMetaData = setupSelectorMetadata(projector, creationMetadata);
|
|
@@ -2065,7 +2323,7 @@ function Selector(selectors) {
|
|
|
2065
2323
|
throwSelectorDecoratorError();
|
|
2066
2324
|
}
|
|
2067
2325
|
}
|
|
2068
|
-
const memoizedFn = createSelector(selectors, originalFn, {
|
|
2326
|
+
const memoizedFn = createSelector(selectors || [], originalFn, {
|
|
2069
2327
|
containerClass: target,
|
|
2070
2328
|
selectorName: key.toString(),
|
|
2071
2329
|
getSelectorOptions() {
|
|
@@ -2088,38 +2346,44 @@ class ActionDirector {
|
|
|
2088
2346
|
_actionHandlerFactory = inject(InternalActionHandlerFactory);
|
|
2089
2347
|
attachAction(stateToken, Action, handlerFn, options = {}) {
|
|
2090
2348
|
const actionHandler = this._actionHandlerFactory.createActionHandler(stateToken.getName(), handlerFn, options);
|
|
2091
|
-
const detach = this._registry.register(Action.type, actionHandler);
|
|
2349
|
+
const detach = this._registry.register(Action.type, actionHandler, Action);
|
|
2092
2350
|
return { detach };
|
|
2093
2351
|
}
|
|
2094
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2095
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
2352
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ActionDirector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2353
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ActionDirector, providedIn: 'root' });
|
|
2096
2354
|
}
|
|
2097
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2355
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ActionDirector, decorators: [{
|
|
2098
2356
|
type: Injectable,
|
|
2099
2357
|
args: [{ providedIn: 'root' }]
|
|
2100
2358
|
}] });
|
|
2101
2359
|
|
|
2360
|
+
/**
|
|
2361
|
+
* @deprecated Use `withNgxsDevelopmentOptions()` instead.
|
|
2362
|
+
*/
|
|
2102
2363
|
class NgxsDevelopmentModule {
|
|
2364
|
+
/**
|
|
2365
|
+
* @deprecated Use `withNgxsDevelopmentOptions()` instead.
|
|
2366
|
+
*/
|
|
2103
2367
|
static forRoot(options) {
|
|
2104
2368
|
return {
|
|
2105
2369
|
ngModule: NgxsDevelopmentModule,
|
|
2106
2370
|
providers: [
|
|
2107
2371
|
NgxsUnhandledActionsLogger,
|
|
2108
|
-
{ provide:
|
|
2372
|
+
{ provide: _NGXS_DEVELOPMENT_OPTIONS, useValue: options }
|
|
2109
2373
|
]
|
|
2110
2374
|
};
|
|
2111
2375
|
}
|
|
2112
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2113
|
-
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
2114
|
-
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
2376
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsDevelopmentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2377
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: NgxsDevelopmentModule });
|
|
2378
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsDevelopmentModule });
|
|
2115
2379
|
}
|
|
2116
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2380
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsDevelopmentModule, decorators: [{
|
|
2117
2381
|
type: NgModule
|
|
2118
2382
|
}] });
|
|
2119
2383
|
function withNgxsDevelopmentOptions(options) {
|
|
2120
2384
|
return makeEnvironmentProviders([
|
|
2121
2385
|
NgxsUnhandledActionsLogger,
|
|
2122
|
-
{ provide:
|
|
2386
|
+
{ provide: _NGXS_DEVELOPMENT_OPTIONS, useValue: options }
|
|
2123
2387
|
]);
|
|
2124
2388
|
}
|
|
2125
2389
|
|
|
@@ -2130,10 +2394,10 @@ class NoopNgxsExecutionStrategy {
|
|
|
2130
2394
|
leave(func) {
|
|
2131
2395
|
return func();
|
|
2132
2396
|
}
|
|
2133
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
2134
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
2397
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NoopNgxsExecutionStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2398
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NoopNgxsExecutionStrategy, providedIn: 'root' });
|
|
2135
2399
|
}
|
|
2136
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2400
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NoopNgxsExecutionStrategy, decorators: [{
|
|
2137
2401
|
type: Injectable,
|
|
2138
2402
|
args: [{ providedIn: 'root' }]
|
|
2139
2403
|
}] });
|
|
@@ -2273,9 +2537,13 @@ function createPropertySelectors(parentSelector) {
|
|
|
2273
2537
|
*/
|
|
2274
2538
|
function withNgxsPendingTasks() {
|
|
2275
2539
|
return withNgxsPreboot(() => {
|
|
2540
|
+
// We silently return instead of logging a warning when not in server mode,
|
|
2541
|
+
// as `withNgxsPendingTasks` may legitimately be included in a shared
|
|
2542
|
+
// `provideStore` configuration used by both browser and server apps.
|
|
2543
|
+
// In the browser, data hydrated from the transfer state is consumed
|
|
2544
|
+
// synchronously, so there is no need to contribute to app stability.
|
|
2276
2545
|
if (typeof ngServerMode === 'undefined' || !ngServerMode) {
|
|
2277
|
-
|
|
2278
|
-
'Using it in the browser may lead to redundant change detection cycles and degraded performance.');
|
|
2546
|
+
return;
|
|
2279
2547
|
}
|
|
2280
2548
|
const actions$ = inject(Actions);
|
|
2281
2549
|
const pendingTasks = inject(PendingTasks);
|
|
@@ -2376,32 +2644,6 @@ function provideStates(states, ...features) {
|
|
|
2376
2644
|
]);
|
|
2377
2645
|
}
|
|
2378
2646
|
|
|
2379
|
-
/**
|
|
2380
|
-
* This function registers a custom global plugin for the state.
|
|
2381
|
-
*
|
|
2382
|
-
* ```ts
|
|
2383
|
-
* bootstrapApplication(AppComponent, {
|
|
2384
|
-
* providers: [
|
|
2385
|
-
* provideStore(
|
|
2386
|
-
* [CountriesState],
|
|
2387
|
-
* withNgxsPlugin(LogoutPlugin)
|
|
2388
|
-
* )
|
|
2389
|
-
* ]
|
|
2390
|
-
* });
|
|
2391
|
-
* ```
|
|
2392
|
-
*/
|
|
2393
|
-
function withNgxsPlugin(plugin) {
|
|
2394
|
-
return makeEnvironmentProviders([
|
|
2395
|
-
_isPluginClass(plugin)
|
|
2396
|
-
? { provide: NGXS_PLUGINS, useClass: plugin, multi: true }
|
|
2397
|
-
: { provide: NGXS_PLUGINS, useValue: plugin, multi: true },
|
|
2398
|
-
// We should inject the `PluginManager` to retrieve `NGXS_PLUGINS` and
|
|
2399
|
-
// register those plugins. The plugin can be added from inside the child
|
|
2400
|
-
// route, so the plugin manager should be re-injected.
|
|
2401
|
-
provideEnvironmentInitializer(() => inject(PluginManager))
|
|
2402
|
-
]);
|
|
2403
|
-
}
|
|
2404
|
-
|
|
2405
2647
|
/**
|
|
2406
2648
|
* This function serves as a utility and has multiple purposes.
|
|
2407
2649
|
* Firstly, it allows you to select properties from the state class
|
|
@@ -2419,9 +2661,39 @@ function select(selector) {
|
|
|
2419
2661
|
return inject(Store).selectSignal(selector);
|
|
2420
2662
|
}
|
|
2421
2663
|
|
|
2664
|
+
// Extends Observable so callers can subscribe to emission updates (e.g. progress, intermediate states),
|
|
2665
|
+
// while implementing PromiseLike so the JS engine treats it as a thenable when `await` is used —
|
|
2666
|
+
// without this dual nature, callers would have to choose upfront between async/await and reactive patterns.
|
|
2667
|
+
class AsyncReturnType extends Observable {
|
|
2668
|
+
dispatchResult$;
|
|
2669
|
+
constructor(dispatchResult$) {
|
|
2670
|
+
super(subscriber => dispatchResult$.subscribe(subscriber));
|
|
2671
|
+
this.dispatchResult$ = dispatchResult$;
|
|
2672
|
+
}
|
|
2673
|
+
// Called automatically by the JS engine when `await dispatch(...)` is used.
|
|
2674
|
+
// The PromiseLike contract requires full generics on TResult1/TResult2 to support
|
|
2675
|
+
// promise chaining (e.g. `await dispatch(...).then(x => transform(x))`).
|
|
2676
|
+
then(onfulfilled, onrejected) {
|
|
2677
|
+
return new Promise((resolve, reject) => {
|
|
2678
|
+
this.dispatchResult$.subscribe({
|
|
2679
|
+
// Propagate observable errors into the promise rejection path so
|
|
2680
|
+
// `try/catch` around `await dispatch(...)` works as expected.
|
|
2681
|
+
error: reject,
|
|
2682
|
+
// Resolve on complete rather than on next emission — dispatch returns void,
|
|
2683
|
+
// so the caller cares about the action finishing, not any intermediate values.
|
|
2684
|
+
complete: resolve
|
|
2685
|
+
});
|
|
2686
|
+
}).then(
|
|
2687
|
+
// Bridge void → undefined because PromiseLike<void> resolves with no value,
|
|
2688
|
+
// but `onfulfilled` still needs to be invoked to continue the chain correctly.
|
|
2689
|
+
onfulfilled ? () => onfulfilled(undefined) : undefined,
|
|
2690
|
+
// Normalize null to undefined since Promise.then doesn't accept null for rejection handler.
|
|
2691
|
+
onrejected ?? undefined);
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2422
2694
|
function dispatch(ActionType) {
|
|
2423
2695
|
const store = inject(Store);
|
|
2424
|
-
return (...args) => store.dispatch(new ActionType(...args));
|
|
2696
|
+
return (...args) => new AsyncReturnType(store.dispatch(new ActionType(...args)));
|
|
2425
2697
|
}
|
|
2426
2698
|
|
|
2427
2699
|
function createSelectMap(selectorMap) {
|
|
@@ -2515,6 +2787,19 @@ function ɵprovideNgxsInternalStateTokens() {
|
|
|
2515
2787
|
}
|
|
2516
2788
|
]);
|
|
2517
2789
|
}
|
|
2790
|
+
// For internal third-party usage only.
|
|
2791
|
+
// Provides a type-safe accessor for `StateFactory`'s private fields so that
|
|
2792
|
+
// third-party consumers do not have to cast or use bracket notation themselves.
|
|
2793
|
+
function ɵgetTypedNgxsStateFactory(stateFactory) {
|
|
2794
|
+
return {
|
|
2795
|
+
// The flat list of all registered mapped stores.
|
|
2796
|
+
states: stateFactory['_states'],
|
|
2797
|
+
// A name-keyed map of all registered states.
|
|
2798
|
+
statesByName: stateFactory['_statesByName'],
|
|
2799
|
+
// A map of dot-separated state paths (e.g. "parent.child") to each state's name.
|
|
2800
|
+
statePaths: stateFactory['_statePaths']
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2518
2803
|
|
|
2519
2804
|
/**
|
|
2520
2805
|
* The public api for consumers of @ngxs/store
|
|
@@ -2524,5 +2809,5 @@ function ɵprovideNgxsInternalStateTokens() {
|
|
|
2524
2809
|
* Generated bundle index. Do not edit.
|
|
2525
2810
|
*/
|
|
2526
2811
|
|
|
2527
|
-
export { Action, ActionDirector, ActionStatus, Actions, NgxsConfig, NgxsDevelopmentModule, NgxsModule, NgxsSimpleChange, NgxsUnhandledActionsLogger, NgxsUnhandledErrorHandler, Select, Selector, SelectorOptions, State, Store, createDispatchMap, createModelSelector, createPickSelector, createPropertySelectors, createSelectMap, createSelector, dispatch, lazyProvider, ofAction, ofActionCanceled, ofActionCompleted, ofActionDispatched, ofActionErrored, ofActionSuccessful, provideStates, provideStore, select, withNgxsDevelopmentOptions, withNgxsNoopExecutionStrategy, withNgxsPendingTasks, withNgxsPlugin, withNgxsPreboot, NgxsFeatureModule as ɵNgxsFeatureModule, NgxsRootModule as ɵNgxsRootModule, ɵprovideNgxsInternalStateTokens };
|
|
2812
|
+
export { Action, ActionDirector, ActionStatus, Actions, AsyncReturnType, NgxsConfig, NgxsDevelopmentModule, NgxsModule, NgxsSimpleChange, NgxsUnhandledActionsLogger, NgxsUnhandledErrorHandler, Select, Selector, SelectorOptions, State, StateContextDestroyedError, Store, createDispatchMap, createModelSelector, createPickSelector, createPropertySelectors, createSelectMap, createSelector, dispatch, lazyProvider, ofAction, ofActionCanceled, ofActionCompleted, ofActionDispatched, ofActionErrored, ofActionSuccessful, provideStates, provideStore, registerNgxsPlugin, select, withNgxsDevelopmentOptions, withNgxsNoopExecutionStrategy, withNgxsPendingTasks, withNgxsPlugin, withNgxsPreboot, NgxsFeatureModule as ɵNgxsFeatureModule, NgxsRootModule as ɵNgxsRootModule, ɵgetTypedNgxsStateFactory, ɵprovideNgxsInternalStateTokens };
|
|
2528
2813
|
//# sourceMappingURL=ngxs-store.mjs.map
|