@ngxs/store 21.0.0 → 22.0.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/ngxs-store-internals-testing.mjs +10 -10
- package/fesm2022/ngxs-store-internals-testing.mjs.map +1 -1
- package/fesm2022/ngxs-store-internals.mjs +31 -42
- 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.map +1 -1
- package/fesm2022/ngxs-store.mjs +433 -163
- package/fesm2022/ngxs-store.mjs.map +1 -1
- package/index.d.ts +123 -17
- package/internals/index.d.ts +4 -9
- package/internals/testing/index.d.ts +1 -1
- package/operators/index.d.ts +234 -14
- package/package.json +7 -16
- 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, ɵ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;
|
|
@@ -862,7 +883,6 @@ function jit_hasInjectableAnnotation(stateClass) {
|
|
|
862
883
|
|
|
863
884
|
const NGXS_DEVELOPMENT_OPTIONS =
|
|
864
885
|
/* @__PURE__ */ new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'NGXS_DEVELOPMENT_OPTIONS' : '', {
|
|
865
|
-
providedIn: 'root',
|
|
866
886
|
factory: () => ({ warnOnUnhandledActions: true })
|
|
867
887
|
});
|
|
868
888
|
|
|
@@ -898,10 +918,10 @@ class NgxsUnhandledActionsLogger {
|
|
|
898
918
|
: action.type;
|
|
899
919
|
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
920
|
}
|
|
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.
|
|
921
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledActionsLogger, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
922
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledActionsLogger });
|
|
903
923
|
}
|
|
904
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
924
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledActionsLogger, decorators: [{
|
|
905
925
|
type: Injectable
|
|
906
926
|
}], ctorParameters: () => [] });
|
|
907
927
|
|
|
@@ -922,10 +942,10 @@ class NgxsUnhandledErrorHandler {
|
|
|
922
942
|
// `handleError` (see `_callAndReportToErrorHandler`).
|
|
923
943
|
this._ngZone.runOutsideAngular(() => this._errorHandler.handleError(error));
|
|
924
944
|
}
|
|
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.
|
|
945
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledErrorHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
946
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledErrorHandler, providedIn: 'root' });
|
|
927
947
|
}
|
|
928
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
948
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsUnhandledErrorHandler, decorators: [{
|
|
929
949
|
type: Injectable,
|
|
930
950
|
args: [{ providedIn: 'root' }]
|
|
931
951
|
}] });
|
|
@@ -1023,13 +1043,13 @@ function createAllowedActionTypesMap(types) {
|
|
|
1023
1043
|
return types.reduce((filterMap, klass) => {
|
|
1024
1044
|
filterMap[getActionTypeFromInstance(klass)] = true;
|
|
1025
1045
|
return filterMap;
|
|
1026
|
-
},
|
|
1046
|
+
}, Object.create(null));
|
|
1027
1047
|
}
|
|
1028
1048
|
function createAllowedStatusesMap(statuses) {
|
|
1029
1049
|
return statuses.reduce((filterMap, status) => {
|
|
1030
1050
|
filterMap[status] = true;
|
|
1031
1051
|
return filterMap;
|
|
1032
|
-
},
|
|
1052
|
+
}, Object.create(null));
|
|
1033
1053
|
}
|
|
1034
1054
|
|
|
1035
1055
|
function simplePatch(value) {
|
|
@@ -1051,35 +1071,74 @@ function simplePatch(value) {
|
|
|
1051
1071
|
};
|
|
1052
1072
|
}
|
|
1053
1073
|
|
|
1074
|
+
class StateContextDestroyedError extends Error {
|
|
1075
|
+
path;
|
|
1076
|
+
name = 'StateContextDestroyedError';
|
|
1077
|
+
constructor(path) {
|
|
1078
|
+
super(typeof ngDevMode !== 'undefined' && ngDevMode
|
|
1079
|
+
? `Attempted to interact with state after the injector has been destroyed. State path: "${path}". ` +
|
|
1080
|
+
`This can happen in server-side rendering when the app is destroyed before all async operations complete, ` +
|
|
1081
|
+
`e.g. inside a finalize() operator that runs after the injector has been destroyed.`
|
|
1082
|
+
: path);
|
|
1083
|
+
this.path = path;
|
|
1084
|
+
Object.setPrototypeOf(this, StateContextDestroyedError.prototype);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1054
1087
|
/**
|
|
1055
|
-
*
|
|
1088
|
+
* Creates `StateContext` instances scoped to a specific state path.
|
|
1089
|
+
* Each action handler receives one of these contexts so it can read and
|
|
1090
|
+
* write only its own slice of the global state tree.
|
|
1056
1091
|
* @ignore
|
|
1057
1092
|
*/
|
|
1058
1093
|
class StateContextFactory {
|
|
1094
|
+
_injector = inject(EnvironmentInjector);
|
|
1059
1095
|
_internalStateOperations = inject(InternalStateOperations);
|
|
1096
|
+
// Resolved lazily via `setErrorHandler` to avoid a cyclic dependency when
|
|
1097
|
+
// the ErrorHandler itself injects the Store.
|
|
1098
|
+
_errorHandler = null;
|
|
1060
1099
|
/**
|
|
1061
1100
|
* Create the state context
|
|
1062
1101
|
*/
|
|
1063
1102
|
createStateContext(path, abortSignal) {
|
|
1103
|
+
const injector = this._injector;
|
|
1104
|
+
const errorHandler = this._errorHandler;
|
|
1064
1105
|
const root = this._internalStateOperations.getRootStateOperations();
|
|
1065
1106
|
return {
|
|
1066
1107
|
abortSignal,
|
|
1067
1108
|
getState() {
|
|
1109
|
+
if (injector.destroyed) {
|
|
1110
|
+
// Only report — do not return early. Returning `undefined as T` would
|
|
1111
|
+
// be a breaking change for callers that assume getState() always
|
|
1112
|
+
// returns a value. handleError is just for observability (e.g. Rollbar);
|
|
1113
|
+
// the state data is still readable even after the injector is gone.
|
|
1114
|
+
errorHandler?.handleError(new StateContextDestroyedError(path));
|
|
1115
|
+
}
|
|
1068
1116
|
const currentAppState = root.getState();
|
|
1069
1117
|
return getState(currentAppState, path);
|
|
1070
1118
|
},
|
|
1071
|
-
patchState(
|
|
1119
|
+
patchState(value) {
|
|
1120
|
+
// If the injector has been destroyed (e.g. app destroyed mid-action),
|
|
1121
|
+
// skip the state update to avoid writing to completed subjects.
|
|
1122
|
+
if (injector.destroyed) {
|
|
1123
|
+
errorHandler?.handleError(new StateContextDestroyedError(path));
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1072
1126
|
const currentAppState = root.getState();
|
|
1073
|
-
const patchOperator = simplePatch(
|
|
1127
|
+
const patchOperator = simplePatch(value);
|
|
1074
1128
|
setStateFromOperator(root, currentAppState, patchOperator, path);
|
|
1075
1129
|
},
|
|
1076
|
-
setState(
|
|
1130
|
+
setState(value) {
|
|
1131
|
+
// Same guard as patchState — no-op if the injector is already destroyed.
|
|
1132
|
+
if (injector.destroyed) {
|
|
1133
|
+
errorHandler?.handleError(new StateContextDestroyedError(path));
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1077
1136
|
const currentAppState = root.getState();
|
|
1078
|
-
if (isStateOperator(
|
|
1079
|
-
setStateFromOperator(root, currentAppState,
|
|
1137
|
+
if (isStateOperator(value)) {
|
|
1138
|
+
setStateFromOperator(root, currentAppState, value, path);
|
|
1080
1139
|
}
|
|
1081
1140
|
else {
|
|
1082
|
-
setStateValue(root, currentAppState,
|
|
1141
|
+
setStateValue(root, currentAppState, value, path);
|
|
1083
1142
|
}
|
|
1084
1143
|
},
|
|
1085
1144
|
dispatch(actions) {
|
|
@@ -1087,23 +1146,28 @@ class StateContextFactory {
|
|
|
1087
1146
|
}
|
|
1088
1147
|
};
|
|
1089
1148
|
}
|
|
1090
|
-
/** @
|
|
1091
|
-
|
|
1149
|
+
/** @internal */
|
|
1150
|
+
setErrorHandler() {
|
|
1151
|
+
// Called from `LifecycleStateManager.ngxsBootstrap` rather than at
|
|
1152
|
+
// construction time. If we injected ErrorHandler in the constructor,
|
|
1153
|
+
// an ErrorHandler that itself injects Store would create a circular
|
|
1154
|
+
// dependency — deferring the lookup breaks the cycle.
|
|
1155
|
+
this._errorHandler ??= this._injector.get(ErrorHandler);
|
|
1156
|
+
}
|
|
1157
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateContextFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1158
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateContextFactory, providedIn: 'root' });
|
|
1092
1159
|
}
|
|
1093
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateContextFactory, decorators: [{
|
|
1094
1161
|
type: Injectable,
|
|
1095
1162
|
args: [{ providedIn: 'root' }]
|
|
1096
1163
|
}] });
|
|
1097
1164
|
function setStateValue(root, currentAppState, newValue, path) {
|
|
1098
1165
|
const newAppState = setValue(currentAppState, path, newValue);
|
|
1099
1166
|
root.setState(newAppState);
|
|
1167
|
+
// Note: this returns the full app state rather than just the patched slice.
|
|
1168
|
+
// That's a long-standing quirk (present since the original state-factory.ts)
|
|
1169
|
+
// and fixing it would be a breaking change — tracked for a future release.
|
|
1100
1170
|
return newAppState;
|
|
1101
|
-
// In doing this refactoring I noticed that there is a 'bug' where the
|
|
1102
|
-
// application state is returned instead of this state slice.
|
|
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
1171
|
}
|
|
1108
1172
|
function setStateFromOperator(root, currentAppState, stateOperator, path) {
|
|
1109
1173
|
const local = getState(currentAppState, path);
|
|
@@ -1182,10 +1246,10 @@ class InternalActionHandlerFactory {
|
|
|
1182
1246
|
return result;
|
|
1183
1247
|
};
|
|
1184
1248
|
}
|
|
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.
|
|
1249
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActionHandlerFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1250
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActionHandlerFactory, providedIn: 'root' });
|
|
1187
1251
|
}
|
|
1188
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1252
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: InternalActionHandlerFactory, decorators: [{
|
|
1189
1253
|
type: Injectable,
|
|
1190
1254
|
args: [{ providedIn: 'root' }]
|
|
1191
1255
|
}] });
|
|
@@ -1229,8 +1293,8 @@ class StateFactory {
|
|
|
1229
1293
|
_actionsSubscription = null;
|
|
1230
1294
|
_ngxsUnhandledErrorHandler = null;
|
|
1231
1295
|
_states = [];
|
|
1232
|
-
_statesByName =
|
|
1233
|
-
_statePaths =
|
|
1296
|
+
_statesByName = Object.create(null);
|
|
1297
|
+
_statePaths = Object.create(null);
|
|
1234
1298
|
getRuntimeSelectorContext = _memoize(() => {
|
|
1235
1299
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1236
1300
|
const stateFactory = this;
|
|
@@ -1326,20 +1390,51 @@ class StateFactory {
|
|
|
1326
1390
|
}
|
|
1327
1391
|
connectActionHandlers() {
|
|
1328
1392
|
this._actionsSubscription = this._actions
|
|
1329
|
-
.pipe(
|
|
1393
|
+
.pipe(mergeMap(ctx => {
|
|
1394
|
+
if (ctx.status !== ActionStatus.Dispatched) {
|
|
1395
|
+
return EMPTY;
|
|
1396
|
+
}
|
|
1330
1397
|
const action = ctx.action;
|
|
1331
|
-
return
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1398
|
+
return new Observable(subscriber => this.invokeActions(action).subscribe({
|
|
1399
|
+
next: () => {
|
|
1400
|
+
subscriber.next({ action, status: ActionStatus.Successful });
|
|
1401
|
+
subscriber.complete();
|
|
1402
|
+
},
|
|
1403
|
+
error: error => {
|
|
1404
|
+
const ngxsUnhandledErrorHandler = (this._ngxsUnhandledErrorHandler ||=
|
|
1405
|
+
this._injector.get(NgxsUnhandledErrorHandler));
|
|
1406
|
+
function callback() {
|
|
1407
|
+
ngxsUnhandledErrorHandler.handleError(error, { action });
|
|
1408
|
+
}
|
|
1409
|
+
// An arrow function here would share the `[[Context]]` of the enclosing `error =>`
|
|
1410
|
+
// arrow function, which captures `this` (StateFactory), causing the error object to
|
|
1411
|
+
// retain the entire instance. A named function declaration creates its own context and
|
|
1412
|
+
// V8 only captures variables it actually references — `ngxsUnhandledErrorHandler`,
|
|
1413
|
+
// `error`, `action` — so `this` is never captured. `.bind(null)` goes one step further:
|
|
1414
|
+
// a JSBoundFunction has no `[[Context]]` slot at all, fully severing the retention chain.
|
|
1415
|
+
// This matters because the callback is stored as a value in the
|
|
1416
|
+
// `ɵɵunhandledRxjsErrorCallbacks` WeakMap, keyed by the error object. The error may be
|
|
1417
|
+
// held by third-party code (e.g. error trackers, logging) for an indeterminate duration,
|
|
1418
|
+
// and we have no control over when that key is released.
|
|
1419
|
+
const handleableError = assignUnhandledCallback(error, callback.bind(null));
|
|
1420
|
+
subscriber.next({
|
|
1421
|
+
action,
|
|
1422
|
+
status: ActionStatus.Errored,
|
|
1423
|
+
error: handleableError
|
|
1424
|
+
});
|
|
1425
|
+
subscriber.complete();
|
|
1426
|
+
},
|
|
1427
|
+
complete: () => {
|
|
1428
|
+
if (subscriber.closed)
|
|
1429
|
+
return;
|
|
1430
|
+
subscriber.next({ action, status: ActionStatus.Canceled });
|
|
1431
|
+
subscriber.complete();
|
|
1432
|
+
}
|
|
1340
1433
|
}));
|
|
1341
1434
|
}))
|
|
1342
|
-
.subscribe(ctx =>
|
|
1435
|
+
.subscribe(ctx => {
|
|
1436
|
+
this._actionResults.next(ctx);
|
|
1437
|
+
});
|
|
1343
1438
|
}
|
|
1344
1439
|
/**
|
|
1345
1440
|
* Invoke actions on the states.
|
|
@@ -1373,10 +1468,7 @@ class StateFactory {
|
|
|
1373
1468
|
// didn't return `null` so we may ensure the module has been imported.
|
|
1374
1469
|
unhandledActionsLogger?.warn(action);
|
|
1375
1470
|
}
|
|
1376
|
-
|
|
1377
|
-
results.push(of(undefined));
|
|
1378
|
-
}
|
|
1379
|
-
return forkJoin(results);
|
|
1471
|
+
return results.length > 0 ? forkJoin(results) : of(undefined);
|
|
1380
1472
|
}
|
|
1381
1473
|
addToStatesMap(stateClasses) {
|
|
1382
1474
|
const newStates = [];
|
|
@@ -1418,15 +1510,16 @@ class StateFactory {
|
|
|
1418
1510
|
}
|
|
1419
1511
|
}
|
|
1420
1512
|
}
|
|
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.
|
|
1513
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1514
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateFactory, providedIn: 'root' });
|
|
1423
1515
|
}
|
|
1424
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1516
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: StateFactory, decorators: [{
|
|
1425
1517
|
type: Injectable,
|
|
1426
1518
|
args: [{ providedIn: 'root' }]
|
|
1427
1519
|
}], ctorParameters: () => [] });
|
|
1428
1520
|
|
|
1429
1521
|
class Store {
|
|
1522
|
+
_injector;
|
|
1430
1523
|
_stateStream = inject(_StateStream);
|
|
1431
1524
|
_internalStateOperations = inject(InternalStateOperations);
|
|
1432
1525
|
_config = inject(NgxsConfig);
|
|
@@ -1440,6 +1533,9 @@ class Store {
|
|
|
1440
1533
|
_selectableStateStream = this._stateStream.pipe(leaveNgxs(this._internalExecutionStrategy), shareReplay({ bufferSize: 1, refCount: true }));
|
|
1441
1534
|
constructor() {
|
|
1442
1535
|
this.initStateStream();
|
|
1536
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1537
|
+
this._injector = inject(Injector);
|
|
1538
|
+
}
|
|
1443
1539
|
}
|
|
1444
1540
|
/**
|
|
1445
1541
|
* Dispatches action(s).
|
|
@@ -1491,6 +1587,21 @@ class Store {
|
|
|
1491
1587
|
const selectorFn = this.getStoreBoundSelectorFn(selector);
|
|
1492
1588
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1493
1589
|
return computed(() => selectorFn(this._stateStream.state()), {
|
|
1590
|
+
equal: (a, b) => {
|
|
1591
|
+
const warnOption = this._injector?.get(NGXS_DEVELOPMENT_OPTIONS, null)?.warnOnNewReferenceWithIdenticalValue;
|
|
1592
|
+
if (warnOption && !Object.is(a, b)) {
|
|
1593
|
+
try {
|
|
1594
|
+
const originalFn = selector.originalFn;
|
|
1595
|
+
if (warnOption.isEqual(a, b) && originalFn) {
|
|
1596
|
+
console.error('The selector returned the same value shape as it was before triggering signal recomputation. Selector function: ', originalFn);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
catch {
|
|
1600
|
+
// Swallow silently.
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
return a === b;
|
|
1604
|
+
},
|
|
1494
1605
|
debugName: 'NGXS selectSignal'
|
|
1495
1606
|
});
|
|
1496
1607
|
}
|
|
@@ -1532,10 +1643,10 @@ class Store {
|
|
|
1532
1643
|
this._stateStream.next(initialStateValue);
|
|
1533
1644
|
}
|
|
1534
1645
|
}
|
|
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.
|
|
1646
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Store, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1647
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Store, providedIn: 'root' });
|
|
1537
1648
|
}
|
|
1538
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1649
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: Store, decorators: [{
|
|
1539
1650
|
type: Injectable,
|
|
1540
1651
|
args: [{ providedIn: 'root' }]
|
|
1541
1652
|
}], ctorParameters: () => [] });
|
|
@@ -1570,6 +1681,125 @@ function withNgxsPreboot(prebootFn) {
|
|
|
1570
1681
|
]);
|
|
1571
1682
|
}
|
|
1572
1683
|
|
|
1684
|
+
/**
|
|
1685
|
+
* This function registers a custom global plugin for the state.
|
|
1686
|
+
*
|
|
1687
|
+
* ```ts
|
|
1688
|
+
* bootstrapApplication(AppComponent, {
|
|
1689
|
+
* providers: [
|
|
1690
|
+
* provideStore(
|
|
1691
|
+
* [CountriesState],
|
|
1692
|
+
* withNgxsPlugin(LogoutPlugin)
|
|
1693
|
+
* )
|
|
1694
|
+
* ]
|
|
1695
|
+
* });
|
|
1696
|
+
* ```
|
|
1697
|
+
*/
|
|
1698
|
+
function withNgxsPlugin(plugin) {
|
|
1699
|
+
return makeEnvironmentProviders([
|
|
1700
|
+
_isPluginClass(plugin)
|
|
1701
|
+
? { provide: NGXS_PLUGINS, useClass: plugin, multi: true }
|
|
1702
|
+
: { provide: NGXS_PLUGINS, useValue: plugin, multi: true },
|
|
1703
|
+
// We should inject the `PluginManager` to retrieve `NGXS_PLUGINS` and
|
|
1704
|
+
// register those plugins. The plugin can be added from inside the child
|
|
1705
|
+
// route, so the plugin manager should be re-injected.
|
|
1706
|
+
provideEnvironmentInitializer(() => inject(PluginManager))
|
|
1707
|
+
]);
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
const REGISTERED_PLUGINS = /* @__PURE__ */ new InjectionToken('', {
|
|
1711
|
+
factory: () => {
|
|
1712
|
+
const plugins = new Set();
|
|
1713
|
+
inject(DestroyRef).onDestroy(() => plugins.clear());
|
|
1714
|
+
return plugins;
|
|
1715
|
+
}
|
|
1716
|
+
});
|
|
1717
|
+
/**
|
|
1718
|
+
* Dynamically registers an NGXS plugin in the current injection context.
|
|
1719
|
+
*
|
|
1720
|
+
* This function allows you to register NGXS plugins at runtime, creating an isolated
|
|
1721
|
+
* environment injector for the plugin. The plugin is automatically cleaned up when
|
|
1722
|
+
* the injection context is destroyed. In development mode, the function validates
|
|
1723
|
+
* that the same plugin is not registered multiple times.
|
|
1724
|
+
*
|
|
1725
|
+
* @param plugin - The NGXS plugin to register. Can be either a class type implementing
|
|
1726
|
+
* `NgxsPlugin` or a plugin function (`NgxsPluginFn`).
|
|
1727
|
+
*
|
|
1728
|
+
* @throws {Error} Throws an error if called outside of an injection context.
|
|
1729
|
+
* @throws {Error} In development mode, throws an error if the plugin has already been registered.
|
|
1730
|
+
*
|
|
1731
|
+
* @remarks
|
|
1732
|
+
* - Must be called within an injection context (e.g., constructor, field initializer, or `runInInjectionContext`).
|
|
1733
|
+
* - The created environment injector is automatically destroyed when the parent context is destroyed.
|
|
1734
|
+
* - Duplicate plugin registration is only checked in development mode for performance reasons.
|
|
1735
|
+
*
|
|
1736
|
+
* @example
|
|
1737
|
+
* ```ts
|
|
1738
|
+
* // Register a plugin class
|
|
1739
|
+
* import { MyThirdPartyIntegrationPlugin } from './plugins/third-party.plugin';
|
|
1740
|
+
*
|
|
1741
|
+
* @Component({
|
|
1742
|
+
* selector: 'app-root',
|
|
1743
|
+
* template: '...'
|
|
1744
|
+
* })
|
|
1745
|
+
* export class AppComponent {
|
|
1746
|
+
* constructor() {
|
|
1747
|
+
* registerNgxsPlugin(MyThirdPartyIntegrationPlugin);
|
|
1748
|
+
* }
|
|
1749
|
+
* }
|
|
1750
|
+
* ```
|
|
1751
|
+
*
|
|
1752
|
+
* @example
|
|
1753
|
+
* ```ts
|
|
1754
|
+
* // Register a plugin function
|
|
1755
|
+
* import { myThirdPartyIntegrationPluginFn } from './plugins/third-party.plugin';
|
|
1756
|
+
*
|
|
1757
|
+
* @Component({
|
|
1758
|
+
* selector: 'app-feature',
|
|
1759
|
+
* template: '...'
|
|
1760
|
+
* })
|
|
1761
|
+
* export class FeatureComponent {
|
|
1762
|
+
* constructor() {
|
|
1763
|
+
* registerNgxsPlugin(myThirdPartyIntegrationPluginFn);
|
|
1764
|
+
* }
|
|
1765
|
+
* }
|
|
1766
|
+
* ```
|
|
1767
|
+
*
|
|
1768
|
+
* @example
|
|
1769
|
+
* ```ts
|
|
1770
|
+
* // Register conditionally based on environment
|
|
1771
|
+
* import { MyDevtoolsPlugin } from './plugins/devtools.plugin';
|
|
1772
|
+
*
|
|
1773
|
+
* @Component({
|
|
1774
|
+
* selector: 'app-root',
|
|
1775
|
+
* template: '...'
|
|
1776
|
+
* })
|
|
1777
|
+
* export class AppComponent {
|
|
1778
|
+
* constructor() {
|
|
1779
|
+
* if (ngDevMode) {
|
|
1780
|
+
* registerNgxsPlugin(MyDevtoolsPlugin);
|
|
1781
|
+
* }
|
|
1782
|
+
* }
|
|
1783
|
+
* }
|
|
1784
|
+
* ```
|
|
1785
|
+
*/
|
|
1786
|
+
function registerNgxsPlugin(plugin) {
|
|
1787
|
+
ngDevMode && assertInInjectionContext(registerNgxsPlugin);
|
|
1788
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1789
|
+
const registeredPlugins = inject(REGISTERED_PLUGINS);
|
|
1790
|
+
if (registeredPlugins.has(plugin)) {
|
|
1791
|
+
throw new Error('Plugin has already been registered. Each plugin should only be registered once to avoid unexpected behavior.');
|
|
1792
|
+
}
|
|
1793
|
+
registeredPlugins.add(plugin);
|
|
1794
|
+
}
|
|
1795
|
+
// Create a new environment injector with the plugin configuration.
|
|
1796
|
+
// This isolates the plugin's dependencies and providers.
|
|
1797
|
+
const injector = createEnvironmentInjector([PluginManager, withNgxsPlugin(plugin)], inject(EnvironmentInjector));
|
|
1798
|
+
// Ensure the created injector is destroyed when the injection context is destroyed.
|
|
1799
|
+
// This prevents memory leaks and ensures proper cleanup.
|
|
1800
|
+
inject(DestroyRef).onDestroy(() => injector.destroy());
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1573
1803
|
const ROOT_STORE_GUARD = /* @__PURE__ */ new InjectionToken('ROOT_STORE_GUARD', {
|
|
1574
1804
|
providedIn: 'root',
|
|
1575
1805
|
factory: () => ({ initialized: false })
|
|
@@ -1597,25 +1827,28 @@ class SelectFactory {
|
|
|
1597
1827
|
SelectFactory.config = null;
|
|
1598
1828
|
});
|
|
1599
1829
|
}
|
|
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.
|
|
1830
|
+
/** @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 });
|
|
1831
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SelectFactory, providedIn: 'root' });
|
|
1602
1832
|
}
|
|
1603
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1833
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SelectFactory, decorators: [{
|
|
1604
1834
|
type: Injectable,
|
|
1605
1835
|
args: [{ providedIn: 'root' }]
|
|
1606
1836
|
}], ctorParameters: () => [{ type: Store }, { type: NgxsConfig }] });
|
|
1607
1837
|
|
|
1608
1838
|
class LifecycleStateManager {
|
|
1839
|
+
_destroyRef = inject(DestroyRef);
|
|
1840
|
+
_injector = inject(Injector);
|
|
1609
1841
|
_store = inject(Store);
|
|
1610
1842
|
_internalStateOperations = inject(InternalStateOperations);
|
|
1611
1843
|
_stateContextFactory = inject(StateContextFactory);
|
|
1612
|
-
|
|
1844
|
+
_appBootstrapState = inject(_NGXS_APP_BOOTSTRAP_STATE);
|
|
1613
1845
|
_abortController = new AbortController();
|
|
1614
1846
|
_initStateHasBeenDispatched;
|
|
1615
1847
|
constructor() {
|
|
1616
1848
|
inject(DestroyRef).onDestroy(() => this._abortController.abort());
|
|
1617
1849
|
}
|
|
1618
1850
|
ngxsBootstrap(action, results) {
|
|
1851
|
+
this._stateContextFactory.setErrorHandler();
|
|
1619
1852
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1620
1853
|
if (action instanceof InitState) {
|
|
1621
1854
|
this._initStateHasBeenDispatched = true;
|
|
@@ -1633,22 +1866,22 @@ class LifecycleStateManager {
|
|
|
1633
1866
|
}
|
|
1634
1867
|
// It does not need to unsubscribe because it is completed when the
|
|
1635
1868
|
// root injector is destroyed.
|
|
1636
|
-
this._internalStateOperations
|
|
1637
|
-
|
|
1638
|
-
.dispatch(action)
|
|
1639
|
-
.pipe(mergeMap(() => {
|
|
1869
|
+
const rootStateOperations = this._internalStateOperations.getRootStateOperations();
|
|
1870
|
+
rootStateOperations.dispatch(action).subscribe(() => {
|
|
1640
1871
|
// If no states are provided, we safely complete the stream
|
|
1641
1872
|
// and do not proceed further.
|
|
1642
1873
|
if (!results) {
|
|
1643
|
-
return
|
|
1874
|
+
return;
|
|
1644
1875
|
}
|
|
1645
1876
|
this._invokeInitOnStates(results.states);
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1877
|
+
const options = { injector: this._injector };
|
|
1878
|
+
toObservable(this._appBootstrapState, options)
|
|
1879
|
+
.pipe(takeUntilDestroyed(this._destroyRef))
|
|
1880
|
+
.subscribe(appBootstrapped => {
|
|
1881
|
+
if (!appBootstrapped)
|
|
1882
|
+
return;
|
|
1650
1883
|
this._invokeBootstrapOnStates(results.states);
|
|
1651
|
-
}
|
|
1884
|
+
});
|
|
1652
1885
|
});
|
|
1653
1886
|
}
|
|
1654
1887
|
_invokeInitOnStates(mappedStores) {
|
|
@@ -1662,11 +1895,6 @@ class LifecycleStateManager {
|
|
|
1662
1895
|
// root injector is destroyed.
|
|
1663
1896
|
this._store
|
|
1664
1897
|
.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
1898
|
.subscribe(currentValue => {
|
|
1671
1899
|
const change = new NgxsSimpleChange(previousValue, currentValue, !mappedStore.isInitialised);
|
|
1672
1900
|
previousValue = currentValue;
|
|
@@ -1686,10 +1914,10 @@ class LifecycleStateManager {
|
|
|
1686
1914
|
_getStateContext(mappedStore) {
|
|
1687
1915
|
return this._stateContextFactory.createStateContext(mappedStore.path, this._abortController.signal);
|
|
1688
1916
|
}
|
|
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.
|
|
1917
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LifecycleStateManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1918
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LifecycleStateManager, providedIn: 'root' });
|
|
1691
1919
|
}
|
|
1692
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1920
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: LifecycleStateManager, decorators: [{
|
|
1693
1921
|
type: Injectable,
|
|
1694
1922
|
args: [{ providedIn: 'root' }]
|
|
1695
1923
|
}], ctorParameters: () => [] });
|
|
@@ -1776,11 +2004,11 @@ class NgxsRootModule {
|
|
|
1776
2004
|
constructor() {
|
|
1777
2005
|
rootStoreInitializer();
|
|
1778
2006
|
}
|
|
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.
|
|
2007
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsRootModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2008
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: NgxsRootModule });
|
|
2009
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsRootModule });
|
|
1782
2010
|
}
|
|
1783
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2011
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsRootModule, decorators: [{
|
|
1784
2012
|
type: NgModule
|
|
1785
2013
|
}], ctorParameters: () => [] });
|
|
1786
2014
|
|
|
@@ -1791,11 +2019,11 @@ class NgxsFeatureModule {
|
|
|
1791
2019
|
constructor() {
|
|
1792
2020
|
featureStatesInitializer();
|
|
1793
2021
|
}
|
|
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.
|
|
2022
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsFeatureModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2023
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: NgxsFeatureModule });
|
|
2024
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsFeatureModule });
|
|
1797
2025
|
}
|
|
1798
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2026
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsFeatureModule, decorators: [{
|
|
1799
2027
|
type: NgModule
|
|
1800
2028
|
}], ctorParameters: () => [] });
|
|
1801
2029
|
|
|
@@ -1813,8 +2041,8 @@ function getRootProviders(states, options) {
|
|
|
1813
2041
|
{
|
|
1814
2042
|
provide: APP_BOOTSTRAP_LISTENER,
|
|
1815
2043
|
useFactory: () => {
|
|
1816
|
-
const
|
|
1817
|
-
return () =>
|
|
2044
|
+
const bootstrapState = inject(_NGXS_APP_BOOTSTRAP_STATE);
|
|
2045
|
+
return () => bootstrapState.set(true);
|
|
1818
2046
|
},
|
|
1819
2047
|
multi: true
|
|
1820
2048
|
},
|
|
@@ -1841,24 +2069,33 @@ function getFeatureProviders(states) {
|
|
|
1841
2069
|
];
|
|
1842
2070
|
}
|
|
1843
2071
|
|
|
2072
|
+
/**
|
|
2073
|
+
* @deprecated Use `provideStore()` and `provideStates()` instead.
|
|
2074
|
+
*/
|
|
1844
2075
|
class NgxsModule {
|
|
2076
|
+
/**
|
|
2077
|
+
* @deprecated Use `provideStore()` instead.
|
|
2078
|
+
*/
|
|
1845
2079
|
static forRoot(states = [], options = {}) {
|
|
1846
2080
|
return {
|
|
1847
2081
|
ngModule: NgxsRootModule,
|
|
1848
2082
|
providers: getRootProviders(states, options)
|
|
1849
2083
|
};
|
|
1850
2084
|
}
|
|
2085
|
+
/**
|
|
2086
|
+
* @deprecated Use `provideStates()` instead.
|
|
2087
|
+
*/
|
|
1851
2088
|
static forFeature(states = []) {
|
|
1852
2089
|
return {
|
|
1853
2090
|
ngModule: NgxsFeatureModule,
|
|
1854
2091
|
providers: getFeatureProviders(states)
|
|
1855
2092
|
};
|
|
1856
2093
|
}
|
|
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.
|
|
2094
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2095
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: NgxsModule });
|
|
2096
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsModule });
|
|
1860
2097
|
}
|
|
1861
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2098
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsModule, decorators: [{
|
|
1862
2099
|
type: NgModule
|
|
1863
2100
|
}] });
|
|
1864
2101
|
|
|
@@ -2049,6 +2286,12 @@ function SelectorOptions(options) {
|
|
|
2049
2286
|
});
|
|
2050
2287
|
}
|
|
2051
2288
|
|
|
2289
|
+
/**
|
|
2290
|
+
* Function for creating a selector
|
|
2291
|
+
* @param selectors The selectors to use to create the arguments of this function
|
|
2292
|
+
* @param originalFn The original function being made into a selector
|
|
2293
|
+
* @param creationMetadata
|
|
2294
|
+
*/
|
|
2052
2295
|
function createSelector(selectors, projector, creationMetadata) {
|
|
2053
2296
|
const memoizedFn = createMemoizedSelectorFn(projector, creationMetadata);
|
|
2054
2297
|
const selectorMetaData = setupSelectorMetadata(projector, creationMetadata);
|
|
@@ -2065,7 +2308,7 @@ function Selector(selectors) {
|
|
|
2065
2308
|
throwSelectorDecoratorError();
|
|
2066
2309
|
}
|
|
2067
2310
|
}
|
|
2068
|
-
const memoizedFn = createSelector(selectors, originalFn, {
|
|
2311
|
+
const memoizedFn = createSelector(selectors || [], originalFn, {
|
|
2069
2312
|
containerClass: target,
|
|
2070
2313
|
selectorName: key.toString(),
|
|
2071
2314
|
getSelectorOptions() {
|
|
@@ -2091,15 +2334,21 @@ class ActionDirector {
|
|
|
2091
2334
|
const detach = this._registry.register(Action.type, actionHandler);
|
|
2092
2335
|
return { detach };
|
|
2093
2336
|
}
|
|
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.
|
|
2337
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ActionDirector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2338
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ActionDirector, providedIn: 'root' });
|
|
2096
2339
|
}
|
|
2097
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2340
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ActionDirector, decorators: [{
|
|
2098
2341
|
type: Injectable,
|
|
2099
2342
|
args: [{ providedIn: 'root' }]
|
|
2100
2343
|
}] });
|
|
2101
2344
|
|
|
2345
|
+
/**
|
|
2346
|
+
* @deprecated Use `withNgxsDevelopmentOptions()` instead.
|
|
2347
|
+
*/
|
|
2102
2348
|
class NgxsDevelopmentModule {
|
|
2349
|
+
/**
|
|
2350
|
+
* @deprecated Use `withNgxsDevelopmentOptions()` instead.
|
|
2351
|
+
*/
|
|
2103
2352
|
static forRoot(options) {
|
|
2104
2353
|
return {
|
|
2105
2354
|
ngModule: NgxsDevelopmentModule,
|
|
@@ -2109,11 +2358,11 @@ class NgxsDevelopmentModule {
|
|
|
2109
2358
|
]
|
|
2110
2359
|
};
|
|
2111
2360
|
}
|
|
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.
|
|
2361
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsDevelopmentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2362
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: NgxsDevelopmentModule });
|
|
2363
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsDevelopmentModule });
|
|
2115
2364
|
}
|
|
2116
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2365
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NgxsDevelopmentModule, decorators: [{
|
|
2117
2366
|
type: NgModule
|
|
2118
2367
|
}] });
|
|
2119
2368
|
function withNgxsDevelopmentOptions(options) {
|
|
@@ -2130,10 +2379,10 @@ class NoopNgxsExecutionStrategy {
|
|
|
2130
2379
|
leave(func) {
|
|
2131
2380
|
return func();
|
|
2132
2381
|
}
|
|
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.
|
|
2382
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NoopNgxsExecutionStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2383
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NoopNgxsExecutionStrategy, providedIn: 'root' });
|
|
2135
2384
|
}
|
|
2136
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
2385
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: NoopNgxsExecutionStrategy, decorators: [{
|
|
2137
2386
|
type: Injectable,
|
|
2138
2387
|
args: [{ providedIn: 'root' }]
|
|
2139
2388
|
}] });
|
|
@@ -2273,9 +2522,13 @@ function createPropertySelectors(parentSelector) {
|
|
|
2273
2522
|
*/
|
|
2274
2523
|
function withNgxsPendingTasks() {
|
|
2275
2524
|
return withNgxsPreboot(() => {
|
|
2525
|
+
// We silently return instead of logging a warning when not in server mode,
|
|
2526
|
+
// as `withNgxsPendingTasks` may legitimately be included in a shared
|
|
2527
|
+
// `provideStore` configuration used by both browser and server apps.
|
|
2528
|
+
// In the browser, data hydrated from the transfer state is consumed
|
|
2529
|
+
// synchronously, so there is no need to contribute to app stability.
|
|
2276
2530
|
if (typeof ngServerMode === 'undefined' || !ngServerMode) {
|
|
2277
|
-
|
|
2278
|
-
'Using it in the browser may lead to redundant change detection cycles and degraded performance.');
|
|
2531
|
+
return;
|
|
2279
2532
|
}
|
|
2280
2533
|
const actions$ = inject(Actions);
|
|
2281
2534
|
const pendingTasks = inject(PendingTasks);
|
|
@@ -2376,32 +2629,6 @@ function provideStates(states, ...features) {
|
|
|
2376
2629
|
]);
|
|
2377
2630
|
}
|
|
2378
2631
|
|
|
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
2632
|
/**
|
|
2406
2633
|
* This function serves as a utility and has multiple purposes.
|
|
2407
2634
|
* Firstly, it allows you to select properties from the state class
|
|
@@ -2419,9 +2646,39 @@ function select(selector) {
|
|
|
2419
2646
|
return inject(Store).selectSignal(selector);
|
|
2420
2647
|
}
|
|
2421
2648
|
|
|
2649
|
+
// Extends Observable so callers can subscribe to emission updates (e.g. progress, intermediate states),
|
|
2650
|
+
// while implementing PromiseLike so the JS engine treats it as a thenable when `await` is used —
|
|
2651
|
+
// without this dual nature, callers would have to choose upfront between async/await and reactive patterns.
|
|
2652
|
+
class AsyncReturnType extends Observable {
|
|
2653
|
+
dispatchResult$;
|
|
2654
|
+
constructor(dispatchResult$) {
|
|
2655
|
+
super(subscriber => dispatchResult$.subscribe(subscriber));
|
|
2656
|
+
this.dispatchResult$ = dispatchResult$;
|
|
2657
|
+
}
|
|
2658
|
+
// Called automatically by the JS engine when `await dispatch(...)` is used.
|
|
2659
|
+
// The PromiseLike contract requires full generics on TResult1/TResult2 to support
|
|
2660
|
+
// promise chaining (e.g. `await dispatch(...).then(x => transform(x))`).
|
|
2661
|
+
then(onfulfilled, onrejected) {
|
|
2662
|
+
return new Promise((resolve, reject) => {
|
|
2663
|
+
this.dispatchResult$.subscribe({
|
|
2664
|
+
// Propagate observable errors into the promise rejection path so
|
|
2665
|
+
// `try/catch` around `await dispatch(...)` works as expected.
|
|
2666
|
+
error: reject,
|
|
2667
|
+
// Resolve on complete rather than on next emission — dispatch returns void,
|
|
2668
|
+
// so the caller cares about the action finishing, not any intermediate values.
|
|
2669
|
+
complete: resolve
|
|
2670
|
+
});
|
|
2671
|
+
}).then(
|
|
2672
|
+
// Bridge void → undefined because PromiseLike<void> resolves with no value,
|
|
2673
|
+
// but `onfulfilled` still needs to be invoked to continue the chain correctly.
|
|
2674
|
+
onfulfilled ? () => onfulfilled(undefined) : undefined,
|
|
2675
|
+
// Normalize null to undefined since Promise.then doesn't accept null for rejection handler.
|
|
2676
|
+
onrejected ?? undefined);
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2422
2679
|
function dispatch(ActionType) {
|
|
2423
2680
|
const store = inject(Store);
|
|
2424
|
-
return (...args) => store.dispatch(new ActionType(...args));
|
|
2681
|
+
return (...args) => new AsyncReturnType(store.dispatch(new ActionType(...args)));
|
|
2425
2682
|
}
|
|
2426
2683
|
|
|
2427
2684
|
function createSelectMap(selectorMap) {
|
|
@@ -2515,6 +2772,19 @@ function ɵprovideNgxsInternalStateTokens() {
|
|
|
2515
2772
|
}
|
|
2516
2773
|
]);
|
|
2517
2774
|
}
|
|
2775
|
+
// For internal third-party usage only.
|
|
2776
|
+
// Provides a type-safe accessor for `StateFactory`'s private fields so that
|
|
2777
|
+
// third-party consumers do not have to cast or use bracket notation themselves.
|
|
2778
|
+
function ɵgetTypedNgxsStateFactory(stateFactory) {
|
|
2779
|
+
return {
|
|
2780
|
+
// The flat list of all registered mapped stores.
|
|
2781
|
+
states: stateFactory['_states'],
|
|
2782
|
+
// A name-keyed map of all registered states.
|
|
2783
|
+
statesByName: stateFactory['_statesByName'],
|
|
2784
|
+
// A map of dot-separated state paths (e.g. "parent.child") to each state's name.
|
|
2785
|
+
statePaths: stateFactory['_statePaths']
|
|
2786
|
+
};
|
|
2787
|
+
}
|
|
2518
2788
|
|
|
2519
2789
|
/**
|
|
2520
2790
|
* The public api for consumers of @ngxs/store
|
|
@@ -2524,5 +2794,5 @@ function ɵprovideNgxsInternalStateTokens() {
|
|
|
2524
2794
|
* Generated bundle index. Do not edit.
|
|
2525
2795
|
*/
|
|
2526
2796
|
|
|
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 };
|
|
2797
|
+
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
2798
|
//# sourceMappingURL=ngxs-store.mjs.map
|