@ngxs/store 20.1.0 → 21.0.0-dev.master-05cbecf
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.mjs +9 -9
- package/fesm2022/ngxs-store-internals.mjs.map +1 -1
- package/fesm2022/ngxs-store.mjs +132 -106
- package/fesm2022/ngxs-store.mjs.map +1 -1
- package/index.d.ts +9 -1
- package/package.json +3 -3
- package/schematics/src/utils/versions.json +1 -1
- package/experimental/package.json +0 -3
- package/internals/package.json +0 -3
- package/internals/testing/package.json +0 -3
- package/operators/package.json +0 -3
- package/plugins/package.json +0 -3
package/fesm2022/ngxs-store.mjs
CHANGED
|
@@ -1,11 +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,
|
|
2
|
+
import { inject, Injectable, DestroyRef, NgZone, Injector, runInInjectionContext, InjectionToken, ErrorHandler, ɵisPromise as _isPromise, computed, makeEnvironmentProviders, provideEnvironmentInitializer, NgModule, APP_BOOTSTRAP_LISTENER, PendingTasks, ApplicationRef, assertInInjectionContext, EnvironmentInjector, createEnvironmentInjector } from '@angular/core';
|
|
3
3
|
import { config, Observable, Subject, of, forkJoin, map, shareReplay, filter, take, mergeMap, EMPTY, from, isObservable, defaultIfEmpty, takeUntil, finalize, catchError, distinctUntilChanged, startWith, skip, buffer, debounceTime } from 'rxjs';
|
|
4
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, ɵNgxsAppBootstrappedState as _NgxsAppBootstrappedState, ɵ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
10
|
|
|
10
11
|
class PluginManager {
|
|
11
12
|
plugins = [];
|
|
@@ -30,10 +31,10 @@ class PluginManager {
|
|
|
30
31
|
const handlers = this._pluginHandlers || [];
|
|
31
32
|
return handlers.map((plugin) => (plugin.handle ? plugin.handle.bind(plugin) : plugin));
|
|
32
33
|
}
|
|
33
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
34
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
34
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: PluginManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
35
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: PluginManager, providedIn: 'root' });
|
|
35
36
|
}
|
|
36
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
37
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: PluginManager, decorators: [{
|
|
37
38
|
type: Injectable,
|
|
38
39
|
args: [{ providedIn: 'root' }]
|
|
39
40
|
}], ctorParameters: () => [] });
|
|
@@ -132,10 +133,10 @@ class InternalDispatchedActionResults extends Subject {
|
|
|
132
133
|
// any actions after the application is destroyed.
|
|
133
134
|
inject(DestroyRef).onDestroy(() => this.complete());
|
|
134
135
|
}
|
|
135
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
136
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
136
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalDispatchedActionResults, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
137
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalDispatchedActionResults, providedIn: 'root' });
|
|
137
138
|
}
|
|
138
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
139
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalDispatchedActionResults, decorators: [{
|
|
139
140
|
type: Injectable,
|
|
140
141
|
args: [{ providedIn: 'root' }]
|
|
141
142
|
}], ctorParameters: () => [] });
|
|
@@ -163,10 +164,10 @@ class InternalNgxsExecutionStrategy {
|
|
|
163
164
|
}
|
|
164
165
|
return func();
|
|
165
166
|
}
|
|
166
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
167
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
167
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalNgxsExecutionStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
168
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalNgxsExecutionStrategy, providedIn: 'root' });
|
|
168
169
|
}
|
|
169
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
170
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalNgxsExecutionStrategy, decorators: [{
|
|
170
171
|
type: Injectable,
|
|
171
172
|
args: [{ providedIn: 'root' }]
|
|
172
173
|
}] });
|
|
@@ -204,10 +205,10 @@ class InternalActions extends _OrderedSubject {
|
|
|
204
205
|
this.dispatched$.complete();
|
|
205
206
|
});
|
|
206
207
|
}
|
|
207
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
208
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
208
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalActions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
209
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalActions, providedIn: 'root' });
|
|
209
210
|
}
|
|
210
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
211
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalActions, decorators: [{
|
|
211
212
|
type: Injectable,
|
|
212
213
|
args: [{ providedIn: 'root' }]
|
|
213
214
|
}], ctorParameters: () => [] });
|
|
@@ -237,10 +238,10 @@ class Actions extends Observable {
|
|
|
237
238
|
observer.add(childSubscription);
|
|
238
239
|
});
|
|
239
240
|
}
|
|
240
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
241
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
241
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: Actions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
242
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: Actions, providedIn: 'root' });
|
|
242
243
|
}
|
|
243
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
244
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: Actions, decorators: [{
|
|
244
245
|
type: Injectable,
|
|
245
246
|
args: [{ providedIn: 'root' }]
|
|
246
247
|
}], ctorParameters: () => [] });
|
|
@@ -253,6 +254,7 @@ class InternalDispatcher {
|
|
|
253
254
|
_stateStream = inject(_StateStream);
|
|
254
255
|
_ngxsExecutionStrategy = inject(InternalNgxsExecutionStrategy);
|
|
255
256
|
_injector = inject(Injector);
|
|
257
|
+
_destroyRef = inject(DestroyRef);
|
|
256
258
|
/**
|
|
257
259
|
* Dispatches event(s).
|
|
258
260
|
*/
|
|
@@ -280,7 +282,7 @@ class InternalDispatcher {
|
|
|
280
282
|
}
|
|
281
283
|
const prevState = this._stateStream.getValue();
|
|
282
284
|
const plugins = this._pluginManager.plugins;
|
|
283
|
-
return compose(this._injector, [
|
|
285
|
+
return compose(this._injector, this._destroyRef, [
|
|
284
286
|
...plugins,
|
|
285
287
|
(nextState, nextAction) => {
|
|
286
288
|
if (nextState !== prevState) {
|
|
@@ -312,10 +314,10 @@ class InternalDispatcher {
|
|
|
312
314
|
}
|
|
313
315
|
}), shareReplay());
|
|
314
316
|
}
|
|
315
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
316
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
317
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalDispatcher, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
318
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalDispatcher, providedIn: 'root' });
|
|
317
319
|
}
|
|
318
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
320
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalDispatcher, decorators: [{
|
|
319
321
|
type: Injectable,
|
|
320
322
|
args: [{ providedIn: 'root' }]
|
|
321
323
|
}] });
|
|
@@ -338,9 +340,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.3", ngImpor
|
|
|
338
340
|
*
|
|
339
341
|
* the last function should not call `next`.
|
|
340
342
|
*/
|
|
341
|
-
const compose = (injector,
|
|
342
|
-
const
|
|
343
|
-
|
|
343
|
+
const compose = (injector, destroyRef, fns) => (...args) => {
|
|
344
|
+
const fn = fns.shift();
|
|
345
|
+
if (destroyRef.destroyed || !fn) {
|
|
346
|
+
// Injector was already destroyed → no-op
|
|
347
|
+
return EMPTY;
|
|
348
|
+
}
|
|
349
|
+
return runInInjectionContext(injector, () => fn(...args, (...nextArgs) => compose(injector, destroyRef, fns)(...nextArgs)));
|
|
344
350
|
};
|
|
345
351
|
|
|
346
352
|
// The injection token is used to resolve a list of states provided at
|
|
@@ -378,8 +384,8 @@ class NgxsConfig {
|
|
|
378
384
|
injectContainerState: false,
|
|
379
385
|
suppressErrors: false
|
|
380
386
|
};
|
|
381
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
382
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
387
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
388
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsConfig, providedIn: 'root', useFactory: () => {
|
|
383
389
|
const defaultConfig = new NgxsConfig();
|
|
384
390
|
const config = inject(NGXS_OPTIONS);
|
|
385
391
|
return {
|
|
@@ -392,7 +398,7 @@ class NgxsConfig {
|
|
|
392
398
|
};
|
|
393
399
|
} });
|
|
394
400
|
}
|
|
395
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
401
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsConfig, decorators: [{
|
|
396
402
|
type: Injectable,
|
|
397
403
|
args: [{
|
|
398
404
|
providedIn: 'root',
|
|
@@ -476,10 +482,10 @@ class InternalStateOperations {
|
|
|
476
482
|
// Set the state to the current + new
|
|
477
483
|
stateOperations.setState({ ...currentState, ...results.defaults });
|
|
478
484
|
}
|
|
479
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
480
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
485
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalStateOperations, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
486
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalStateOperations, providedIn: 'root' });
|
|
481
487
|
}
|
|
482
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
488
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalStateOperations, decorators: [{
|
|
483
489
|
type: Injectable,
|
|
484
490
|
args: [{ providedIn: 'root' }]
|
|
485
491
|
}] });
|
|
@@ -892,10 +898,10 @@ class NgxsUnhandledActionsLogger {
|
|
|
892
898
|
: action.type;
|
|
893
899
|
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.`);
|
|
894
900
|
}
|
|
895
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
896
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
901
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsUnhandledActionsLogger, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
902
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsUnhandledActionsLogger });
|
|
897
903
|
}
|
|
898
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
904
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsUnhandledActionsLogger, decorators: [{
|
|
899
905
|
type: Injectable
|
|
900
906
|
}], ctorParameters: () => [] });
|
|
901
907
|
|
|
@@ -916,10 +922,10 @@ class NgxsUnhandledErrorHandler {
|
|
|
916
922
|
// `handleError` (see `_callAndReportToErrorHandler`).
|
|
917
923
|
this._ngZone.runOutsideAngular(() => this._errorHandler.handleError(error));
|
|
918
924
|
}
|
|
919
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
920
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
925
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsUnhandledErrorHandler, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
926
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsUnhandledErrorHandler, providedIn: 'root' });
|
|
921
927
|
}
|
|
922
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
928
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsUnhandledErrorHandler, decorators: [{
|
|
923
929
|
type: Injectable,
|
|
924
930
|
args: [{ providedIn: 'root' }]
|
|
925
931
|
}] });
|
|
@@ -1054,9 +1060,10 @@ class StateContextFactory {
|
|
|
1054
1060
|
/**
|
|
1055
1061
|
* Create the state context
|
|
1056
1062
|
*/
|
|
1057
|
-
createStateContext(path) {
|
|
1063
|
+
createStateContext(path, abortSignal) {
|
|
1058
1064
|
const root = this._internalStateOperations.getRootStateOperations();
|
|
1059
1065
|
return {
|
|
1066
|
+
abortSignal,
|
|
1060
1067
|
getState() {
|
|
1061
1068
|
const currentAppState = root.getState();
|
|
1062
1069
|
return getState(currentAppState, path);
|
|
@@ -1080,10 +1087,10 @@ class StateContextFactory {
|
|
|
1080
1087
|
}
|
|
1081
1088
|
};
|
|
1082
1089
|
}
|
|
1083
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1084
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
1090
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: StateContextFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1091
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: StateContextFactory, providedIn: 'root' });
|
|
1085
1092
|
}
|
|
1086
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1093
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: StateContextFactory, decorators: [{
|
|
1087
1094
|
type: Injectable,
|
|
1088
1095
|
args: [{ providedIn: 'root' }]
|
|
1089
1096
|
}] });
|
|
@@ -1113,7 +1120,8 @@ class InternalActionHandlerFactory {
|
|
|
1113
1120
|
createActionHandler(path, handlerFn, options) {
|
|
1114
1121
|
const { dispatched$ } = this._actions;
|
|
1115
1122
|
return (action) => {
|
|
1116
|
-
const
|
|
1123
|
+
const abortController = new AbortController();
|
|
1124
|
+
const stateContext = this._stateContextFactory.createStateContext(path, abortController.signal);
|
|
1117
1125
|
let result = handlerFn(stateContext, action);
|
|
1118
1126
|
// We need to use `isPromise` instead of checking whether
|
|
1119
1127
|
// `result instanceof Promise`. In zone.js patched environments, `global.Promise`
|
|
@@ -1132,12 +1140,18 @@ class InternalActionHandlerFactory {
|
|
|
1132
1140
|
// For instance, if any action handler had a statement like
|
|
1133
1141
|
// `handler(ctx) { return EMPTY; }`, then the action would be canceled.
|
|
1134
1142
|
// See https://github.com/ngxs/store/issues/1568
|
|
1135
|
-
// Note that we actually don't care about the return type; we only care
|
|
1136
|
-
// about emission, and thus `undefined` is applicable by the framework.
|
|
1137
1143
|
defaultIfEmpty(undefined));
|
|
1138
1144
|
if (options.cancelUncompleted) {
|
|
1139
1145
|
const canceled = dispatched$.pipe(ofActionDispatched(action));
|
|
1140
|
-
result = result.pipe(takeUntil(
|
|
1146
|
+
result = result.pipe(takeUntil(new Observable(subscriber => {
|
|
1147
|
+
return canceled.subscribe(() => {
|
|
1148
|
+
// Note that we shouldn't use `catchError` to catch abort errors
|
|
1149
|
+
// because the observable is canceled before the error is thrown,
|
|
1150
|
+
// so we don't need to handle it.
|
|
1151
|
+
abortController.abort();
|
|
1152
|
+
subscriber.next();
|
|
1153
|
+
});
|
|
1154
|
+
})));
|
|
1141
1155
|
}
|
|
1142
1156
|
result = result.pipe(
|
|
1143
1157
|
// Note that we use the `finalize` operator only when the action handler
|
|
@@ -1168,10 +1182,10 @@ class InternalActionHandlerFactory {
|
|
|
1168
1182
|
return result;
|
|
1169
1183
|
};
|
|
1170
1184
|
}
|
|
1171
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1172
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
1185
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalActionHandlerFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1186
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalActionHandlerFactory, providedIn: 'root' });
|
|
1173
1187
|
}
|
|
1174
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1188
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: InternalActionHandlerFactory, decorators: [{
|
|
1175
1189
|
type: Injectable,
|
|
1176
1190
|
args: [{ providedIn: 'root' }]
|
|
1177
1191
|
}] });
|
|
@@ -1252,7 +1266,12 @@ class StateFactory {
|
|
|
1252
1266
|
return context;
|
|
1253
1267
|
});
|
|
1254
1268
|
constructor() {
|
|
1255
|
-
inject(DestroyRef).onDestroy(() =>
|
|
1269
|
+
inject(DestroyRef).onDestroy(() => {
|
|
1270
|
+
// Clear state references to help the garbage collector in SSR
|
|
1271
|
+
// environments under high load, preventing memory leaks.
|
|
1272
|
+
this._states = [];
|
|
1273
|
+
this._actionsSubscription?.unsubscribe();
|
|
1274
|
+
});
|
|
1256
1275
|
}
|
|
1257
1276
|
/**
|
|
1258
1277
|
* Add a new state to the global defs.
|
|
@@ -1399,10 +1418,10 @@ class StateFactory {
|
|
|
1399
1418
|
}
|
|
1400
1419
|
}
|
|
1401
1420
|
}
|
|
1402
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1403
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
1421
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: StateFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1422
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: StateFactory, providedIn: 'root' });
|
|
1404
1423
|
}
|
|
1405
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1424
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: StateFactory, decorators: [{
|
|
1406
1425
|
type: Injectable,
|
|
1407
1426
|
args: [{ providedIn: 'root' }]
|
|
1408
1427
|
}], ctorParameters: () => [] });
|
|
@@ -1470,7 +1489,14 @@ class Store {
|
|
|
1470
1489
|
*/
|
|
1471
1490
|
selectSignal(selector) {
|
|
1472
1491
|
const selectorFn = this.getStoreBoundSelectorFn(selector);
|
|
1473
|
-
|
|
1492
|
+
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1493
|
+
return computed(() => selectorFn(this._stateStream.state()), {
|
|
1494
|
+
debugName: 'NGXS selectSignal'
|
|
1495
|
+
});
|
|
1496
|
+
}
|
|
1497
|
+
else {
|
|
1498
|
+
return computed(() => selectorFn(this._stateStream.state()));
|
|
1499
|
+
}
|
|
1474
1500
|
}
|
|
1475
1501
|
/**
|
|
1476
1502
|
* Allow the user to subscribe to the root of the state
|
|
@@ -1506,10 +1532,10 @@ class Store {
|
|
|
1506
1532
|
this._stateStream.next(initialStateValue);
|
|
1507
1533
|
}
|
|
1508
1534
|
}
|
|
1509
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1510
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
1535
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: Store, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1536
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: Store, providedIn: 'root' });
|
|
1511
1537
|
}
|
|
1512
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1538
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: Store, decorators: [{
|
|
1513
1539
|
type: Injectable,
|
|
1514
1540
|
args: [{ providedIn: 'root' }]
|
|
1515
1541
|
}], ctorParameters: () => [] });
|
|
@@ -1571,10 +1597,10 @@ class SelectFactory {
|
|
|
1571
1597
|
SelectFactory.config = null;
|
|
1572
1598
|
});
|
|
1573
1599
|
}
|
|
1574
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1575
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
1600
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: SelectFactory, deps: [{ token: Store }, { token: NgxsConfig }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1601
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: SelectFactory, providedIn: 'root' });
|
|
1576
1602
|
}
|
|
1577
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1603
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: SelectFactory, decorators: [{
|
|
1578
1604
|
type: Injectable,
|
|
1579
1605
|
args: [{ providedIn: 'root' }]
|
|
1580
1606
|
}], ctorParameters: () => [{ type: Store }, { type: NgxsConfig }] });
|
|
@@ -1584,7 +1610,11 @@ class LifecycleStateManager {
|
|
|
1584
1610
|
_internalStateOperations = inject(InternalStateOperations);
|
|
1585
1611
|
_stateContextFactory = inject(StateContextFactory);
|
|
1586
1612
|
_appBootstrappedState = inject(_NgxsAppBootstrappedState);
|
|
1613
|
+
_abortController = new AbortController();
|
|
1587
1614
|
_initStateHasBeenDispatched;
|
|
1615
|
+
constructor() {
|
|
1616
|
+
inject(DestroyRef).onDestroy(() => this._abortController.abort());
|
|
1617
|
+
}
|
|
1588
1618
|
ngxsBootstrap(action, results) {
|
|
1589
1619
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
1590
1620
|
if (action instanceof InitState) {
|
|
@@ -1643,30 +1673,26 @@ class LifecycleStateManager {
|
|
|
1643
1673
|
instance.ngxsOnChanges(change);
|
|
1644
1674
|
});
|
|
1645
1675
|
}
|
|
1646
|
-
|
|
1647
|
-
instance.ngxsOnInit(this._getStateContext(mappedStore));
|
|
1648
|
-
}
|
|
1676
|
+
instance.ngxsOnInit?.(this._getStateContext(mappedStore));
|
|
1649
1677
|
mappedStore.isInitialised = true;
|
|
1650
1678
|
}
|
|
1651
1679
|
}
|
|
1652
1680
|
_invokeBootstrapOnStates(mappedStores) {
|
|
1653
1681
|
for (const mappedStore of mappedStores) {
|
|
1654
1682
|
const instance = mappedStore.instance;
|
|
1655
|
-
|
|
1656
|
-
instance.ngxsAfterBootstrap(this._getStateContext(mappedStore));
|
|
1657
|
-
}
|
|
1683
|
+
instance.ngxsAfterBootstrap?.(this._getStateContext(mappedStore));
|
|
1658
1684
|
}
|
|
1659
1685
|
}
|
|
1660
1686
|
_getStateContext(mappedStore) {
|
|
1661
|
-
return this._stateContextFactory.createStateContext(mappedStore.path);
|
|
1687
|
+
return this._stateContextFactory.createStateContext(mappedStore.path, this._abortController.signal);
|
|
1662
1688
|
}
|
|
1663
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1664
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
1689
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LifecycleStateManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1690
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LifecycleStateManager, providedIn: 'root' });
|
|
1665
1691
|
}
|
|
1666
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1692
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: LifecycleStateManager, decorators: [{
|
|
1667
1693
|
type: Injectable,
|
|
1668
1694
|
args: [{ providedIn: 'root' }]
|
|
1669
|
-
}] });
|
|
1695
|
+
}], ctorParameters: () => [] });
|
|
1670
1696
|
|
|
1671
1697
|
/**
|
|
1672
1698
|
* This function is shared by both NgModule and standalone features.
|
|
@@ -1750,11 +1776,11 @@ class NgxsRootModule {
|
|
|
1750
1776
|
constructor() {
|
|
1751
1777
|
rootStoreInitializer();
|
|
1752
1778
|
}
|
|
1753
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1754
|
-
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.
|
|
1755
|
-
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.
|
|
1779
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsRootModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1780
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.2", ngImport: i0, type: NgxsRootModule });
|
|
1781
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsRootModule });
|
|
1756
1782
|
}
|
|
1757
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1783
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsRootModule, decorators: [{
|
|
1758
1784
|
type: NgModule
|
|
1759
1785
|
}], ctorParameters: () => [] });
|
|
1760
1786
|
|
|
@@ -1765,11 +1791,11 @@ class NgxsFeatureModule {
|
|
|
1765
1791
|
constructor() {
|
|
1766
1792
|
featureStatesInitializer();
|
|
1767
1793
|
}
|
|
1768
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1769
|
-
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.
|
|
1770
|
-
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.
|
|
1794
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsFeatureModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1795
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.2", ngImport: i0, type: NgxsFeatureModule });
|
|
1796
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsFeatureModule });
|
|
1771
1797
|
}
|
|
1772
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1798
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsFeatureModule, decorators: [{
|
|
1773
1799
|
type: NgModule
|
|
1774
1800
|
}], ctorParameters: () => [] });
|
|
1775
1801
|
|
|
@@ -1828,11 +1854,11 @@ class NgxsModule {
|
|
|
1828
1854
|
providers: getFeatureProviders(states)
|
|
1829
1855
|
};
|
|
1830
1856
|
}
|
|
1831
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
1832
|
-
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.
|
|
1833
|
-
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.
|
|
1857
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
1858
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.2", ngImport: i0, type: NgxsModule });
|
|
1859
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsModule });
|
|
1834
1860
|
}
|
|
1835
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
1861
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsModule, decorators: [{
|
|
1836
1862
|
type: NgModule
|
|
1837
1863
|
}] });
|
|
1838
1864
|
|
|
@@ -2065,10 +2091,10 @@ class ActionDirector {
|
|
|
2065
2091
|
const detach = this._registry.register(Action.type, actionHandler);
|
|
2066
2092
|
return { detach };
|
|
2067
2093
|
}
|
|
2068
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
2069
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
2094
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ActionDirector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2095
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ActionDirector, providedIn: 'root' });
|
|
2070
2096
|
}
|
|
2071
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
2097
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: ActionDirector, decorators: [{
|
|
2072
2098
|
type: Injectable,
|
|
2073
2099
|
args: [{ providedIn: 'root' }]
|
|
2074
2100
|
}] });
|
|
@@ -2083,11 +2109,11 @@ class NgxsDevelopmentModule {
|
|
|
2083
2109
|
]
|
|
2084
2110
|
};
|
|
2085
2111
|
}
|
|
2086
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
2087
|
-
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.
|
|
2088
|
-
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.
|
|
2112
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsDevelopmentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
2113
|
+
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.2", ngImport: i0, type: NgxsDevelopmentModule });
|
|
2114
|
+
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsDevelopmentModule });
|
|
2089
2115
|
}
|
|
2090
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
2116
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NgxsDevelopmentModule, decorators: [{
|
|
2091
2117
|
type: NgModule
|
|
2092
2118
|
}] });
|
|
2093
2119
|
function withNgxsDevelopmentOptions(options) {
|
|
@@ -2104,10 +2130,10 @@ class NoopNgxsExecutionStrategy {
|
|
|
2104
2130
|
leave(func) {
|
|
2105
2131
|
return func();
|
|
2106
2132
|
}
|
|
2107
|
-
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.
|
|
2108
|
-
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.
|
|
2133
|
+
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NoopNgxsExecutionStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2134
|
+
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NoopNgxsExecutionStrategy, providedIn: 'root' });
|
|
2109
2135
|
}
|
|
2110
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.
|
|
2136
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: NoopNgxsExecutionStrategy, decorators: [{
|
|
2111
2137
|
type: Injectable,
|
|
2112
2138
|
args: [{ providedIn: 'root' }]
|
|
2113
2139
|
}] });
|
|
@@ -2204,7 +2230,10 @@ function createPickSelector(selector, keys) {
|
|
|
2204
2230
|
ensureValidSelector(selector, { prefix: '[createPickSelector]' });
|
|
2205
2231
|
}
|
|
2206
2232
|
const validKeys = keys.filter(Boolean);
|
|
2207
|
-
const selectors = validKeys.map(key =>
|
|
2233
|
+
const selectors = validKeys.map(key =>
|
|
2234
|
+
// Optional chaining is used because the state being selected may not be
|
|
2235
|
+
// registered yet — for example, if the selector is called before `provideStates()`.
|
|
2236
|
+
createSelector([selector], (state) => state?.[key]));
|
|
2208
2237
|
return createSelector([...selectors], (...props) => {
|
|
2209
2238
|
return validKeys.reduce((acc, key, index) => {
|
|
2210
2239
|
acc[key] = props[index];
|
|
@@ -2224,7 +2253,10 @@ function createPropertySelectors(parentSelector) {
|
|
|
2224
2253
|
return new Proxy({}, {
|
|
2225
2254
|
get(_target, prop) {
|
|
2226
2255
|
const selector = cache[prop] ||
|
|
2227
|
-
createSelector([parentSelector],
|
|
2256
|
+
createSelector([parentSelector],
|
|
2257
|
+
// Optional chaining is used because the state being selected may not be
|
|
2258
|
+
// registered yet — for example, if the selector is called before `provideStates()`.
|
|
2259
|
+
(state) => state?.[prop]);
|
|
2228
2260
|
cache[prop] = selector;
|
|
2229
2261
|
return selector;
|
|
2230
2262
|
}
|
|
@@ -2241,9 +2273,13 @@ function createPropertySelectors(parentSelector) {
|
|
|
2241
2273
|
*/
|
|
2242
2274
|
function withNgxsPendingTasks() {
|
|
2243
2275
|
return withNgxsPreboot(() => {
|
|
2276
|
+
if (typeof ngServerMode === 'undefined' || !ngServerMode) {
|
|
2277
|
+
console.warn('[withNgxsPendingTasks] This setup is recommended for server-side rendering only. ' +
|
|
2278
|
+
'Using it in the browser may lead to redundant change detection cycles and degraded performance.');
|
|
2279
|
+
}
|
|
2244
2280
|
const actions$ = inject(Actions);
|
|
2245
|
-
const appRef = inject(ApplicationRef);
|
|
2246
2281
|
const pendingTasks = inject(PendingTasks);
|
|
2282
|
+
const destroyRef = inject(DestroyRef);
|
|
2247
2283
|
// Removing a pending task via the public API forces a scheduled tick, ensuring that
|
|
2248
2284
|
// stability is async and delayed until there was at least an opportunity to run
|
|
2249
2285
|
// app synchronization.
|
|
@@ -2258,12 +2294,8 @@ function withNgxsPendingTasks() {
|
|
|
2258
2294
|
// If the app is forcely destroyed before all actions are completed,
|
|
2259
2295
|
// we clean up the set of actions being executed to prevent memory leaks
|
|
2260
2296
|
// and remove the pending task to stabilize the app.
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
appRef.whenStable().then(() => {
|
|
2264
|
-
isStable = true;
|
|
2265
|
-
});
|
|
2266
|
-
const subscription = actions$
|
|
2297
|
+
destroyRef.onDestroy(() => executedActions.clear());
|
|
2298
|
+
actions$
|
|
2267
2299
|
.pipe(filter(context => {
|
|
2268
2300
|
if (context.status === ActionStatus.Dispatched) {
|
|
2269
2301
|
executedActions.add(context.action);
|
|
@@ -2278,7 +2310,7 @@ function withNgxsPendingTasks() {
|
|
|
2278
2310
|
// task is removed, even if multiple synchronous actions are completed in a row.
|
|
2279
2311
|
// We use `buffer` to collect action contexts because, if we only use
|
|
2280
2312
|
// `debounceTime(0)`, we may lose action contexts that are never removed from the set.
|
|
2281
|
-
buffer(actions$.pipe(debounceTime(0))))
|
|
2313
|
+
buffer(actions$.pipe(debounceTime(0))), takeUntilDestroyed(destroyRef))
|
|
2282
2314
|
.subscribe(contexts => {
|
|
2283
2315
|
for (const context of contexts) {
|
|
2284
2316
|
if (!executedActions.has(context.action)) {
|
|
@@ -2289,12 +2321,6 @@ function withNgxsPendingTasks() {
|
|
|
2289
2321
|
if (executedActions.size === 0) {
|
|
2290
2322
|
removeTask?.();
|
|
2291
2323
|
removeTask = null;
|
|
2292
|
-
if (isStable) {
|
|
2293
|
-
// Stop contributing to stability once the application has become stable,
|
|
2294
|
-
// which may happen on the server before the platform is destroyed or in
|
|
2295
|
-
// the browser once hydration is complete.
|
|
2296
|
-
subscription.unsubscribe();
|
|
2297
|
-
}
|
|
2298
2324
|
}
|
|
2299
2325
|
}
|
|
2300
2326
|
});
|