UNPKG

@ngxs/store

Version:
1 lines 189 kB
{"version":3,"file":"ngxs-store.mjs","sources":["../../../packages/store/src/plugin-manager.ts","../../../packages/store/src/operators/leave-ngxs.ts","../../../packages/store/src/internal/unhandled-rxjs-error-callback.ts","../../../packages/store/src/internal/fallback-subscriber.ts","../../../packages/store/src/internal/action-results.ts","../../../packages/store/src/execution/execution-strategy.ts","../../../packages/store/src/actions-stream.ts","../../../packages/store/src/internal/dispatcher.ts","../../../packages/store/src/symbols.ts","../../../packages/store/src/utils/freeze.ts","../../../packages/store/src/internal/state-operations.ts","../../../packages/store/src/selectors/selector-utils.ts","../../../packages/store/src/internal/internals.ts","../../../packages/store/src/configs/messages.config.ts","../../../packages/store/src/utils/store-validators.ts","../../../packages/store/src/ivy/ivy-enabled-in-dev-mode.ts","../../../packages/store/src/dev-features/symbols.ts","../../../packages/store/src/dev-features/ngxs-unhandled-actions-logger.ts","../../../packages/store/src/ngxs-unhandled-error-handler.ts","../../../packages/store/src/operators/of-action.ts","../../../packages/store/src/internal/state-operators.ts","../../../packages/store/src/internal/state-context-factory.ts","../../../packages/store/src/internal/action-handler-factory.ts","../../../packages/store/src/internal/state-factory.ts","../../../packages/store/src/store.ts","../../../packages/store/src/standalone-features/preboot.ts","../../../packages/store/src/standalone-features/root-guard.ts","../../../packages/store/src/decorators/select/select-factory.ts","../../../packages/store/src/internal/lifecycle-state-manager.ts","../../../packages/store/src/standalone-features/initializers.ts","../../../packages/store/src/modules/ngxs-root.module.ts","../../../packages/store/src/modules/ngxs-feature.module.ts","../../../packages/store/src/standalone-features/root-providers.ts","../../../packages/store/src/standalone-features/feature-providers.ts","../../../packages/store/src/module.ts","../../../packages/store/src/decorators/action.ts","../../../packages/store/src/decorators/state.ts","../../../packages/store/src/decorators/select/symbols.ts","../../../packages/store/src/decorators/select/select.ts","../../../packages/store/src/selectors/selector-metadata.ts","../../../packages/store/src/decorators/selector-options.ts","../../../packages/store/src/selectors/create-selector.ts","../../../packages/store/src/decorators/selector/selector.ts","../../../packages/store/src/actions/action-director.ts","../../../packages/store/src/dev-features/ngxs-development.module.ts","../../../packages/store/src/execution/noop-execution-strategy.ts","../../../packages/store/src/selectors/selector-checks.util.ts","../../../packages/store/src/selectors/create-model-selector.ts","../../../packages/store/src/selectors/create-pick-selector.ts","../../../packages/store/src/selectors/create-property-selectors.ts","../../../packages/store/src/pending-tasks.ts","../../../packages/store/src/standalone-features/provide-store.ts","../../../packages/store/src/standalone-features/provide-states.ts","../../../packages/store/src/standalone-features/plugin.ts","../../../packages/store/src/utils/select.ts","../../../packages/store/src/utils/dispatch.ts","../../../packages/store/src/utils/create-select-map.ts","../../../packages/store/src/utils/create-dispatch-map.ts","../../../packages/store/src/utils/lazy-provider.ts","../../../packages/store/src/internal/provide-internal-tokens.ts","../../../packages/store/index.ts","../../../packages/store/ngxs-store.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { NGXS_PLUGINS, NgxsPlugin, NgxsPluginFn } from '@ngxs/store/plugins';\n\n@Injectable({ providedIn: 'root' })\nexport class PluginManager {\n readonly plugins: NgxsPluginFn[] = [];\n\n private readonly _parentManager = inject(PluginManager, {\n optional: true,\n skipSelf: true\n });\n\n private readonly _pluginHandlers = inject<NgxsPlugin[]>(NGXS_PLUGINS, {\n optional: true\n });\n\n constructor() {\n this.registerHandlers();\n }\n\n private get _rootPlugins(): NgxsPluginFn[] {\n return this._parentManager?.plugins || this.plugins;\n }\n\n private registerHandlers(): void {\n const pluginHandlers: NgxsPluginFn[] = this.getPluginHandlers();\n this._rootPlugins.push(...pluginHandlers);\n }\n\n private getPluginHandlers(): NgxsPluginFn[] {\n const handlers: NgxsPlugin[] = this._pluginHandlers || [];\n return handlers.map(\n (plugin: NgxsPlugin) =>\n (plugin.handle ? plugin.handle.bind(plugin) : plugin) as NgxsPluginFn\n );\n }\n}\n","import { ɵwrapObserverCalls } from '@ngxs/store/internals';\n\nimport { InternalNgxsExecutionStrategy } from '../execution/execution-strategy';\n\n/**\n * Returns operator that will run\n * `subscribe` outside of the ngxs execution context\n */\nexport function leaveNgxs<T>(ngxsExecutionStrategy: InternalNgxsExecutionStrategy) {\n return ɵwrapObserverCalls<T>(fn => ngxsExecutionStrategy.leave(fn));\n}\n","import { config } from 'rxjs';\n\nconst ɵɵunhandledRxjsErrorCallbacks = new WeakMap<object, VoidFunction>();\n\nlet installed = false;\nexport function installOnUnhandhedErrorHandler(): void {\n if (installed) {\n return;\n }\n\n const existingHandler = config.onUnhandledError;\n config.onUnhandledError = function (error: any) {\n const unhandledErrorCallback = ɵɵunhandledRxjsErrorCallbacks.get(error);\n if (unhandledErrorCallback) {\n unhandledErrorCallback();\n } else if (existingHandler) {\n existingHandler.call(this, error);\n } else {\n throw error;\n }\n };\n\n installed = true;\n}\n\nexport function executeUnhandledCallback(error: any) {\n const unhandledErrorCallback = ɵɵunhandledRxjsErrorCallbacks.get(error);\n if (unhandledErrorCallback) {\n unhandledErrorCallback();\n return true;\n }\n return false;\n}\n\nexport function assignUnhandledCallback(error: any, callback: VoidFunction) {\n // Since the error can be essentially anything, we must ensure that we only\n // handle objects, as weak maps do not allow any other key type besides objects.\n // The error can also be a string if thrown in the following manner: `throwError('My Error')`.\n if (error && typeof error === 'object') {\n let hasBeenCalled = false;\n ɵɵunhandledRxjsErrorCallbacks.set(error, () => {\n if (!hasBeenCalled) {\n hasBeenCalled = true;\n callback();\n }\n });\n }\n return error;\n}\n","import { NgZone } from '@angular/core';\nimport { Observable, type Subscription } from 'rxjs';\n\nimport { executeUnhandledCallback } from './unhandled-rxjs-error-callback';\n\nexport function fallbackSubscriber<T>(ngZone: NgZone) {\n return (source: Observable<T>) => {\n let subscription: Subscription | null = source.subscribe({\n error: error => {\n ngZone.runOutsideAngular(() => {\n // This is necessary to schedule a microtask to ensure that synchronous\n // errors are not reported before the real subscriber arrives. If an error\n // is thrown synchronously in any action, it will be reported to the error\n // handler regardless. Since RxJS reports unhandled errors asynchronously,\n // implementing a microtask ensures that we are also safe in this scenario.\n queueMicrotask(() => {\n if (subscription) {\n executeUnhandledCallback(error);\n }\n });\n });\n }\n });\n\n return new Observable<T>(subscriber => {\n // Now that there is a real subscriber, we can unsubscribe our pro-active subscription\n subscription?.unsubscribe();\n subscription = null;\n\n return source.subscribe(subscriber);\n });\n };\n}\n","import { DestroyRef, inject, Injectable } from '@angular/core';\nimport { Subject } from 'rxjs';\n\nimport type { ActionContext } from '../actions-stream';\n\n/**\n * Internal Action result stream that is emitted when an action is completed.\n * This is used as a method of returning the action result to the dispatcher\n * for the observable returned by the dispatch(...) call.\n * The dispatcher then asynchronously pushes the result from this stream onto the main action stream as a result.\n */\n@Injectable({ providedIn: 'root' })\nexport class InternalDispatchedActionResults extends Subject<ActionContext> {\n constructor() {\n super();\n // Complete the subject once the root injector is destroyed to ensure\n // there are no active subscribers that would receive events or perform\n // any actions after the application is destroyed.\n inject(DestroyRef).onDestroy(() => this.complete());\n }\n}\n","import { inject, Injectable, NgZone } from '@angular/core';\nimport { NgxsExecutionStrategy } from './symbols';\n\n@Injectable({ providedIn: 'root' })\nexport class InternalNgxsExecutionStrategy implements NgxsExecutionStrategy {\n private _ngZone = inject(NgZone);\n\n enter<T>(func: () => T): T {\n if (typeof ngServerMode !== 'undefined' && ngServerMode) {\n return this._runInsideAngular(func);\n }\n return this._runOutsideAngular(func);\n }\n\n leave<T>(func: () => T): T {\n return this._runInsideAngular(func);\n }\n\n private _runInsideAngular<T>(func: () => T): T {\n if (NgZone.isInAngularZone()) {\n return func();\n }\n return this._ngZone.run(func);\n }\n\n private _runOutsideAngular<T>(func: () => T): T {\n if (NgZone.isInAngularZone()) {\n return this._ngZone.runOutsideAngular(func);\n }\n return func();\n }\n}\n","import { DestroyRef, inject, Injectable } from '@angular/core';\nimport { ɵOrderedSubject } from '@ngxs/store/internals';\nimport { Observable, Subject } from 'rxjs';\n\nimport { leaveNgxs } from './operators/leave-ngxs';\nimport { InternalNgxsExecutionStrategy } from './execution/execution-strategy';\n\n/**\n * Status of a dispatched action\n */\nexport enum ActionStatus {\n Dispatched = 'DISPATCHED',\n Successful = 'SUCCESSFUL',\n Canceled = 'CANCELED',\n Errored = 'ERRORED'\n}\n\nexport interface ActionContext<T = any> {\n status: ActionStatus;\n action: T;\n error?: Error;\n}\n\n/**\n * Internal Action stream that is emitted anytime an action is dispatched.\n */\n@Injectable({ providedIn: 'root' })\nexport class InternalActions extends ɵOrderedSubject<ActionContext> {\n // This subject will be the first to know about the dispatched action, its purpose is for\n // any logic that must be executed before action handlers are invoked (i.e., cancelation).\n readonly dispatched$ = new Subject<ActionContext>();\n\n constructor() {\n super();\n\n this.subscribe(ctx => {\n if (ctx.status === ActionStatus.Dispatched) {\n this.dispatched$.next(ctx);\n }\n });\n\n const destroyRef = inject(DestroyRef);\n destroyRef.onDestroy(() => {\n // Complete the subject once the root injector is destroyed to ensure\n // there are no active subscribers that would receive events or perform\n // any actions after the application is destroyed.\n this.complete();\n this.dispatched$.complete();\n });\n }\n}\n\n/**\n * Action stream that is emitted anytime an action is dispatched.\n *\n * You can listen to this in services to react without stores.\n */\n@Injectable({ providedIn: 'root' })\nexport class Actions extends Observable<ActionContext> {\n constructor() {\n const internalActions$ = inject(InternalActions);\n const internalExecutionStrategy = inject(InternalNgxsExecutionStrategy);\n\n // The `InternalActions` subject emits outside of the Angular zone.\n // We have to re-enter the Angular zone for any incoming consumer.\n // The shared `Subject` reduces the number of change detections.\n // This would call leave only once for any stream emission across all active subscribers.\n const sharedInternalActions$ = new Subject<ActionContext>();\n\n internalActions$\n .pipe(leaveNgxs(internalExecutionStrategy))\n .subscribe(sharedInternalActions$);\n\n super(observer => {\n const childSubscription = sharedInternalActions$.subscribe({\n next: ctx => observer.next(ctx),\n error: error => observer.error(error),\n complete: () => observer.complete()\n });\n\n observer.add(childSubscription);\n });\n }\n}\n","import { inject, Injectable, Injector, NgZone, runInInjectionContext } from '@angular/core';\nimport {\n EMPTY,\n forkJoin,\n Observable,\n filter,\n map,\n mergeMap,\n shareReplay,\n take,\n of\n} from 'rxjs';\n\nimport { getActionTypeFromInstance } from '@ngxs/store/plugins';\nimport { ɵPlainObject, ɵStateStream } from '@ngxs/store/internals';\n\nimport { PluginManager } from '../plugin-manager';\nimport { leaveNgxs } from '../operators/leave-ngxs';\nimport { fallbackSubscriber } from './fallback-subscriber';\nimport { InternalDispatchedActionResults } from './action-results';\nimport { ActionContext, ActionStatus, InternalActions } from '../actions-stream';\nimport { InternalNgxsExecutionStrategy } from '../execution/execution-strategy';\n\n@Injectable({ providedIn: 'root' })\nexport class InternalDispatcher {\n private _ngZone = inject(NgZone);\n private _actions = inject(InternalActions);\n private _actionResults = inject(InternalDispatchedActionResults);\n private _pluginManager = inject(PluginManager);\n private _stateStream = inject(ɵStateStream);\n private _ngxsExecutionStrategy = inject(InternalNgxsExecutionStrategy);\n private _injector = inject(Injector);\n\n /**\n * Dispatches event(s).\n */\n dispatch(actionOrActions: any | any[]): Observable<void> {\n const result = this._ngxsExecutionStrategy.enter(() =>\n this.dispatchByEvents(actionOrActions)\n );\n\n return result.pipe(\n fallbackSubscriber(this._ngZone),\n leaveNgxs(this._ngxsExecutionStrategy)\n );\n }\n\n private dispatchByEvents(actionOrActions: any | any[]): Observable<void> {\n if (Array.isArray(actionOrActions)) {\n if (actionOrActions.length === 0) return of(undefined);\n\n return forkJoin(actionOrActions.map(action => this.dispatchSingle(action))).pipe(\n map(() => undefined)\n );\n } else {\n return this.dispatchSingle(actionOrActions);\n }\n }\n\n private dispatchSingle(action: any): Observable<void> {\n if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n const type: string | undefined = getActionTypeFromInstance(action);\n if (!type) {\n const error = new Error(\n `This action doesn't have a type property: ${action.constructor.name}`\n );\n return new Observable(subscriber => subscriber.error(error));\n }\n }\n\n const prevState = this._stateStream.getValue();\n const plugins = this._pluginManager.plugins;\n\n return compose(this._injector, [\n ...plugins,\n (nextState: any, nextAction: any) => {\n if (nextState !== prevState) {\n this._stateStream.next(nextState);\n }\n const actionResult$ = this.getActionResultStream(nextAction);\n actionResult$.subscribe(ctx => this._actions.next(ctx));\n this._actions.next({ action: nextAction, status: ActionStatus.Dispatched });\n return this.createDispatchObservable(actionResult$);\n }\n ])(prevState, action).pipe(shareReplay());\n }\n\n private getActionResultStream(action: any): Observable<ActionContext> {\n return this._actionResults.pipe(\n filter(\n (ctx: ActionContext) => ctx.action === action && ctx.status !== ActionStatus.Dispatched\n ),\n take(1),\n shareReplay()\n );\n }\n\n private createDispatchObservable(\n actionResult$: Observable<ActionContext>\n ): Observable<ɵPlainObject> {\n return actionResult$.pipe(\n mergeMap((ctx: ActionContext) => {\n switch (ctx.status) {\n case ActionStatus.Successful:\n // The `createDispatchObservable` function should return the\n // state, as its result is used by plugins.\n return of(this._stateStream.getValue());\n case ActionStatus.Errored:\n throw ctx.error;\n default:\n // Once dispatched or canceled, we complete it immediately because\n // `dispatch()` should emit (or error, or complete) as soon as it succeeds or fails.\n return EMPTY;\n }\n }),\n shareReplay()\n );\n }\n}\n\ntype StateFn = (...args: any[]) => any;\n\n/**\n * Composes a array of functions from left to right. Example:\n *\n * compose([fn, final])(state, action);\n *\n * then the funcs have a signature like:\n *\n * function fn (state, action, next) {\n * console.log('here', state, action, next);\n * return next(state, action);\n * }\n *\n * function final (state, action) {\n * console.log('here', state, action);\n * return state;\n * }\n *\n * the last function should not call `next`.\n */\nconst compose =\n (injector: Injector, funcs: StateFn[]) =>\n (...args: any[]) => {\n const curr = funcs.shift()!;\n return runInInjectionContext(injector, () =>\n curr(...args, (...nextArgs: any[]) => compose(injector, funcs)(...nextArgs))\n );\n };\n","import { Injectable, InjectionToken, inject } from '@angular/core';\nimport type { Observable } from 'rxjs';\n\nimport { StateOperator } from '@ngxs/store/operators';\nimport { ɵSharedSelectorOptions, ɵStateClass } from '@ngxs/store/internals';\n\n// The injection token is used to resolve a list of states provided at\n// the root level through either `NgxsModule.forRoot` or `provideStore`.\nexport const ROOT_STATE_TOKEN = new InjectionToken<Array<ɵStateClass>>(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'ROOT_STATE_TOKEN' : ''\n);\n\n// The injection token is used to resolve a list of states provided at\n// the feature level through either `NgxsModule.forFeature` or `provideStates`.\n// The Array<Array> is used to overload the resolved value of the token because\n// it is a multi-provider token.\nexport const FEATURE_STATE_TOKEN = new InjectionToken<Array<Array<ɵStateClass>>>(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'FEATURE_STATE_TOKEN' : ''\n);\n\n// The injection token is used to resolve to options provided at the root\n// level through either `NgxsModule.forRoot` or `provideStore`.\nexport const NGXS_OPTIONS = new InjectionToken<NgxsModuleOptions>(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'NGXS_OPTIONS' : ''\n);\n\nexport type NgxsLifeCycle = Partial<NgxsOnChanges> &\n Partial<NgxsOnInit> &\n Partial<NgxsAfterBootstrap>;\n\n/**\n * The NGXS config settings.\n */\n@Injectable({\n providedIn: 'root',\n useFactory: (): NgxsConfig => {\n const defaultConfig = new NgxsConfig();\n const config = inject(NGXS_OPTIONS);\n return {\n ...defaultConfig,\n ...config,\n selectorOptions: {\n ...defaultConfig.selectorOptions,\n ...config.selectorOptions\n }\n };\n }\n})\nexport class NgxsConfig {\n /**\n * Run in development mode. This will add additional debugging features:\n * - Object.freeze on the state and actions to guarantee immutability\n * (default: false)\n *\n * Note: this property will be accounted only in development mode.\n * It makes sense to use it only during development to ensure there're no state mutations.\n * When building for production, the `Object.freeze` will be tree-shaken away.\n */\n developmentMode!: boolean;\n compatibility: {\n /**\n * Support a strict Content Security Policy.\n * This will circumvent some optimisations that violate a strict CSP through the use of `new Function(...)`.\n * (default: false)\n */\n strictContentSecurityPolicy: boolean;\n } = {\n strictContentSecurityPolicy: false\n };\n /**\n * Defining shared selector options\n */\n selectorOptions: ɵSharedSelectorOptions = {\n injectContainerState: false,\n suppressErrors: false\n };\n}\n\nexport type { StateOperator };\n\n/**\n * State context provided to the actions in the state.\n */\nexport interface StateContext<T> {\n /**\n * Get the current state.\n */\n getState(): T;\n\n /**\n * Reset the state to a new value.\n */\n setState(val: T | StateOperator<T>): void;\n\n /**\n * Patch the existing state with the provided value.\n */\n patchState(val: Partial<T>): void;\n\n /**\n * Dispatch a new action and return the dispatched observable.\n */\n dispatch(actions: any | any[]): Observable<void>;\n}\n\n/**\n * Represents a basic change from a previous to a new value for a single state instance.\n * Passed as a value in a NgxsSimpleChanges object to the ngxsOnChanges hook.\n */\nexport class NgxsSimpleChange<T = any> {\n constructor(\n public readonly previousValue: T,\n public readonly currentValue: T,\n public readonly firstChange: boolean\n ) {}\n}\n\n/**\n * On init interface\n */\nexport interface NgxsOnInit {\n ngxsOnInit(ctx: StateContext<any>): void;\n}\n\n/**\n * On change interface\n */\nexport interface NgxsOnChanges {\n ngxsOnChanges(change: NgxsSimpleChange): void;\n}\n\n/**\n * After bootstrap interface\n */\nexport interface NgxsAfterBootstrap {\n ngxsAfterBootstrap(ctx: StateContext<any>): void;\n}\n\nexport type NgxsModuleOptions = Partial<NgxsConfig>;\n","import { ɵhasOwnProperty } from '@ngxs/store/internals';\n\n/**\n * Object freeze code\n * https://github.com/jsdf/deep-freeze\n */\nexport const deepFreeze = (o: any) => {\n Object.freeze(o);\n\n const oIsFunction = typeof o === 'function';\n\n Object.getOwnPropertyNames(o).forEach(function (prop) {\n if (\n ɵhasOwnProperty(o, prop) &&\n (oIsFunction ? prop !== 'caller' && prop !== 'callee' && prop !== 'arguments' : true) &&\n o[prop] !== null &&\n (typeof o[prop] === 'object' || typeof o[prop] === 'function') &&\n !Object.isFrozen(o[prop])\n ) {\n deepFreeze(o[prop]);\n }\n });\n\n return o;\n};\n","import { inject, Injectable } from '@angular/core';\nimport { ɵStateStream } from '@ngxs/store/internals';\n\nimport { StateOperations, StatesAndDefaults } from '../internal/internals';\nimport { InternalDispatcher } from '../internal/dispatcher';\nimport { NgxsConfig } from '../symbols';\nimport { deepFreeze } from '../utils/freeze';\n\n/**\n * @ignore\n */\n@Injectable({ providedIn: 'root' })\nexport class InternalStateOperations {\n private _stateStream = inject(ɵStateStream);\n private _dispatcher = inject(InternalDispatcher);\n private _config = inject(NgxsConfig);\n\n /**\n * Returns the root state operators.\n */\n getRootStateOperations(): StateOperations<any> {\n const rootStateOperations = {\n getState: () => this._stateStream.getValue(),\n setState: (newState: any) => this._stateStream.next(newState),\n dispatch: (actionOrActions: any | any[]) => this._dispatcher.dispatch(actionOrActions)\n };\n\n if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n return this._config.developmentMode\n ? ensureStateAndActionsAreImmutable(rootStateOperations)\n : rootStateOperations;\n } else {\n return rootStateOperations;\n }\n }\n\n setStateToTheCurrentWithNew(results: StatesAndDefaults): void {\n const stateOperations: StateOperations<any> = this.getRootStateOperations();\n\n // Get our current stream\n const currentState = stateOperations.getState();\n // Set the state to the current + new\n stateOperations.setState({ ...currentState, ...results.defaults });\n }\n}\n\nfunction ensureStateAndActionsAreImmutable(root: StateOperations<any>): StateOperations<any> {\n return {\n getState: () => root.getState(),\n setState: value => {\n const frozenValue = deepFreeze(value);\n return root.setState(frozenValue);\n },\n dispatch: actions => {\n return root.dispatch(actions);\n }\n };\n}\n","import {\n ɵmemoize,\n ɵRuntimeSelectorContext,\n ɵSelectorFactory,\n ɵgetStoreMetadata,\n ɵgetSelectorMetadata,\n ɵSelectorMetaDataModel,\n ɵSharedSelectorOptions\n} from '@ngxs/store/internals';\n\nimport { CreationMetadata, RuntimeSelectorInfo } from './selector-models';\n\ndeclare const ngDevMode: boolean;\n\nexport function createRootSelectorFactory<T extends (...args: any[]) => any>(\n selectorMetaData: ɵSelectorMetaDataModel,\n selectors: any[] | undefined,\n memoizedSelectorFn: T\n): ɵSelectorFactory {\n return (context: ɵRuntimeSelectorContext) => {\n const { argumentSelectorFunctions, selectorOptions } = getRuntimeSelectorInfo(\n context,\n selectorMetaData,\n selectors\n );\n\n const { suppressErrors } = selectorOptions;\n\n return function selectFromRoot(rootState: any) {\n // Determine arguments from the app state using the selectors\n const results = argumentSelectorFunctions.map(argFn => argFn(rootState));\n\n // If the lambda attempts to access something in the state that doesn't exist,\n // it will throw a `TypeError`. Since this behavior is common, we simply return\n // `undefined` in such cases.\n try {\n return memoizedSelectorFn(...results);\n } catch (ex) {\n if (suppressErrors && ex instanceof TypeError) {\n return undefined;\n }\n\n // We're logging an error in this function because it may be used by `select`,\n // `selectSignal`, and `selectSnapshot`. Therefore, there's no need to catch\n // exceptions there to log errors.\n if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n const message =\n 'The selector below has thrown an error upon invocation. ' +\n 'Please check for any unsafe property access that may result in null ' +\n 'or undefined values.';\n\n // Avoid concatenating the message with the original function, as this will\n // invoke `toString()` on the function. Instead, log it as the second argument.\n // This way, developers will be able to navigate to the actual code in the browser.\n console.error(message, selectorMetaData.originalFn);\n }\n\n throw ex;\n }\n };\n };\n}\n\nexport function createMemoizedSelectorFn<T extends (...args: any[]) => any>(\n originalFn: T,\n creationMetadata: Partial<CreationMetadata> | undefined\n) {\n const containerClass = creationMetadata?.containerClass;\n const wrappedFn = function wrappedSelectorFn() {\n // eslint-disable-next-line prefer-rest-params\n const returnValue = originalFn.apply(containerClass, <any>arguments);\n if (typeof returnValue === 'function') {\n const innerMemoizedFn = ɵmemoize.apply(null, [returnValue]);\n return innerMemoizedFn;\n }\n return returnValue;\n } as T;\n const memoizedFn = ɵmemoize(wrappedFn);\n Object.setPrototypeOf(memoizedFn, originalFn);\n return memoizedFn;\n}\n\nfunction getRuntimeSelectorInfo(\n context: ɵRuntimeSelectorContext,\n selectorMetaData: ɵSelectorMetaDataModel,\n selectors: any[] | undefined = []\n): RuntimeSelectorInfo {\n const localSelectorOptions = selectorMetaData.getSelectorOptions();\n const selectorOptions = context.getSelectorOptions(localSelectorOptions);\n const selectorsToApply = getSelectorsToApply(\n selectors,\n selectorOptions,\n selectorMetaData.containerClass\n );\n\n const argumentSelectorFunctions = selectorsToApply.map(selector => {\n const factory = getRootSelectorFactory(selector);\n return factory(context);\n });\n return {\n selectorOptions,\n argumentSelectorFunctions\n };\n}\n\nfunction getSelectorsToApply(\n selectors: any[] | undefined = [],\n selectorOptions: ɵSharedSelectorOptions,\n containerClass: any\n) {\n const selectorsToApply = [];\n // The container state refers to the state class that includes the\n // definition of the selector function, for example:\n // @State()\n // class AnimalsState {\n // @Selector()\n // static getAnimals(state: AnimalsStateModel) {}\n // }\n // The `AnimalsState` serves as the container state. Additionally, the\n // selector may reside within a namespace or another class lacking the\n // `@State` decorator, thus not being treated as the container state.\n const canInjectContainerState =\n selectorOptions.injectContainerState || selectors.length === 0;\n\n if (containerClass && canInjectContainerState) {\n // If we are on a state class, add it as the first selector parameter\n const metadata = ɵgetStoreMetadata(containerClass);\n if (metadata) {\n selectorsToApply.push(containerClass);\n }\n }\n selectorsToApply.push(...selectors);\n return selectorsToApply;\n}\n\n/**\n * This function gets the factory function to create the selector to get the selected slice from the app state\n * @ignore\n */\nexport function getRootSelectorFactory(selector: any): ɵSelectorFactory {\n const metadata = ɵgetSelectorMetadata(selector) || ɵgetStoreMetadata(selector);\n return metadata?.makeRootSelector || (() => selector);\n}\n","import { InjectionToken, inject } from '@angular/core';\nimport type { Observable } from 'rxjs';\n\nimport {\n ɵMETA_KEY,\n ɵPlainObjectOf,\n ɵStateClassInternal,\n ɵActionHandlerMetaData\n} from '@ngxs/store/internals';\n\nimport { NgxsConfig } from '../symbols';\n\ndeclare const ngDevMode: boolean;\n\nexport type StateKeyGraph = ɵPlainObjectOf<string[]>;\nexport type StatesByName = ɵPlainObjectOf<ɵStateClassInternal>;\n\nexport interface StateOperations<T> {\n getState(): T;\n\n setState(val: T): void;\n\n dispatch(actionOrActions: any | any[]): Observable<void>;\n}\n\nexport interface MappedStore {\n name: string;\n isInitialised: boolean;\n actions: ɵPlainObjectOf<ɵActionHandlerMetaData[]>;\n defaults: any;\n instance: any;\n path: string;\n}\n\nexport interface StatesAndDefaults {\n defaults: any;\n states: MappedStore[];\n}\n\n/**\n * Get a deeply nested value. Example:\n *\n * getValue({ foo: bar: [] }, 'foo.bar') //=> []\n *\n * Note: This is not as fast as the `fastPropGetter` but is strict Content Security Policy compliant.\n * See perf hit: https://jsperf.com/fast-value-getter-given-path/1\n *\n * @ignore\n */\nexport function compliantPropGetter(paths: string[]): (x: any) => any {\n return obj => {\n for (let i = 0; i < paths.length; i++) {\n if (!obj) return undefined;\n obj = obj[paths[i]];\n }\n return obj;\n };\n}\n\n/**\n * The generated function is faster than:\n * - pluck (Observable operator)\n * - memoize\n *\n * @ignore\n */\nexport function fastPropGetter(paths: string[]): (x: any) => any {\n const segments = paths;\n let seg = 'store.' + segments[0];\n let i = 0;\n const l = segments.length;\n\n let expr = seg;\n while (++i < l) {\n expr = expr + ' && ' + (seg = seg + '.' + segments[i]);\n }\n\n const fn = new Function('store', 'return ' + expr + ';');\n\n return <(x: any) => any>fn;\n}\n\nexport const ɵPROP_GETTER = new InjectionToken<(paths: string[]) => (x: any) => any>(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'PROP_GETTER' : '',\n {\n providedIn: 'root',\n factory: () =>\n inject(NgxsConfig).compatibility?.strictContentSecurityPolicy\n ? compliantPropGetter\n : fastPropGetter\n }\n);\n\n/**\n * Given an array of states, it will return a object graph. Example:\n * const states = [\n * Cart,\n * CartSaved,\n * CartSavedItems\n * ]\n *\n * would return:\n *\n * const graph = {\n * cart: ['saved'],\n * saved: ['items'],\n * items: []\n * };\n *\n * @ignore\n */\nexport function buildGraph(stateClasses: ɵStateClassInternal[]): StateKeyGraph {\n // Resolve a state's name from the class reference.\n const findName = (stateClass: ɵStateClassInternal): string => {\n const meta = stateClasses.find(s => s === stateClass);\n if (typeof ngDevMode !== 'undefined' && ngDevMode && !meta) {\n throw new Error(\n `Child state not found: ${stateClass}. \\r\\nYou may have forgotten to add states to module`\n );\n }\n return meta![ɵMETA_KEY]!.name!;\n };\n\n // Build the dependency graph.\n return stateClasses.reduce((graph: StateKeyGraph, stateClass) => {\n const meta = stateClass[ɵMETA_KEY]!;\n graph[meta.name!] = (meta.children || []).map(findName);\n return graph;\n }, {});\n}\n\n/**\n * Given a states array, returns object graph\n * returning the name and state metadata. Example:\n *\n * const graph = {\n * cart: { metadata }\n * };\n *\n * @ignore\n */\nexport function nameToState(\n states: ɵStateClassInternal[]\n): ɵPlainObjectOf<ɵStateClassInternal> {\n return states.reduce<ɵPlainObjectOf<ɵStateClassInternal>>(\n (result: ɵPlainObjectOf<ɵStateClassInternal>, stateClass: ɵStateClassInternal) => {\n const meta = stateClass[ɵMETA_KEY]!;\n result[meta.name!] = stateClass;\n return result;\n },\n {}\n );\n}\n\n/**\n * Given a object relationship graph will return the full path\n * for the child items. Example:\n *\n * const graph = {\n * cart: ['saved'],\n * saved: ['items'],\n * items: []\n * };\n *\n * would return:\n *\n * const r = {\n * cart: 'cart',\n * saved: 'cart.saved',\n * items: 'cart.saved.items'\n * };\n *\n * @ignore\n */\nexport function findFullParentPath(\n obj: StateKeyGraph,\n out: ɵPlainObjectOf<string> = {}\n): ɵPlainObjectOf<string> {\n // Recursively find the full dotted parent path for a given key.\n const find = (graph: StateKeyGraph, target: string): string | null => {\n for (const key in graph) {\n if (graph[key]?.includes(target)) {\n const parent = find(graph, key);\n return parent ? `${parent}.${key}` : key;\n }\n }\n return null;\n };\n\n // Build full path for each key\n for (const key in obj) {\n const parent = find(obj, key);\n out[key] = parent ? `${parent}.${key}` : key;\n }\n\n return out;\n}\n\n/**\n * Given a object graph, it will return the items topologically sorted Example:\n *\n * const graph = {\n * cart: ['saved'],\n * saved: ['items'],\n * items: []\n * };\n *\n * would return:\n *\n * const results = [\n * 'items',\n * 'saved',\n * 'cart'\n * ];\n *\n * @ignore\n */\nexport function topologicalSort(graph: StateKeyGraph): string[] {\n const sorted: string[] = [];\n const visited: ɵPlainObjectOf<boolean> = {};\n\n // DFS (Depth-First Search) to visit each node and its dependencies.\n const visit = (name: string, ancestors: string[] = []) => {\n visited[name] = true;\n ancestors.push(name);\n\n for (const dep of graph[name]) {\n if (typeof ngDevMode !== 'undefined' && ngDevMode && ancestors.includes(dep)) {\n throw new Error(\n `Circular dependency '${dep}' is required by '${name}': ${ancestors.join(' -> ')}`\n );\n }\n\n if (!visited[dep]) visit(dep, ancestors.slice());\n }\n\n // Add to sorted list if not already included.\n if (!sorted.includes(name)) sorted.push(name);\n };\n\n // Start DFS from each key\n for (const key in graph) visit(key);\n\n return sorted.reverse();\n}\n","import { ɵPlainObject } from '@ngxs/store/internals';\n\nexport function throwStateNameError(name: string): never {\n throw new Error(\n `${name} is not a valid state name. It needs to be a valid object property name.`\n );\n}\n\nexport function throwStateNamePropertyError(): never {\n throw new Error(`States must register a 'name' property.`);\n}\n\nexport function throwStateUniqueError(\n current: string,\n newName: string,\n oldName: string\n): never {\n throw new Error(`State name '${current}' from ${newName} already exists in ${oldName}.`);\n}\n\nexport function throwStateDecoratorError(name: string): never {\n throw new Error(`States must be decorated with @State() decorator, but \"${name}\" isn't.`);\n}\n\nexport function throwActionDecoratorError(): never {\n throw new Error('@Action() decorator cannot be used with static methods.');\n}\n\nexport function throwSelectorDecoratorError(): never {\n throw new Error('Selectors only work on methods.');\n}\n\nexport function getUndecoratedStateWithInjectableWarningMessage(name: string): string {\n return `'${name}' class should be decorated with @Injectable() right after the @State() decorator`;\n}\n\nexport function getInvalidInitializationOrderMessage(addedStates?: ɵPlainObject) {\n let message =\n 'You have an invalid state initialization order. This typically occurs when `NgxsModule.forFeature`\\n' +\n 'or `provideStates` is called before `NgxsModule.forRoot` or `provideStore`.\\n' +\n 'One example is when `NgxsRouterPluginModule.forRoot` is called before `NgxsModule.forRoot`.';\n\n if (addedStates) {\n const stateNames = Object.keys(addedStates).map(stateName => `\"${stateName}\"`);\n\n message +=\n '\\nFeature states added before the store initialization is complete: ' +\n `${stateNames.join(', ')}.`;\n }\n\n return message;\n}\n\nexport function throwPatchingArrayError(): never {\n throw new Error('Patching arrays is not supported.');\n}\n\nexport function throwPatchingPrimitiveError(): never {\n throw new Error('Patching primitives is not supported.');\n}\n","import { ɵStateClassInternal, ɵgetStoreMetadata } from '@ngxs/store/internals';\n\nimport { StatesByName } from '../internal/internals';\nimport {\n throwStateDecoratorError,\n throwStateNameError,\n throwStateNamePropertyError,\n throwStateUniqueError\n} from '../configs/messages.config';\n\nconst stateNameRegex = /* @__PURE__ */ new RegExp('^[a-zA-Z0-9_]+$');\n\nexport function ensureStateNameIsValid(name: string | null): void | never {\n if (!name) {\n throwStateNamePropertyError();\n } else if (!stateNameRegex.test(name)) {\n throwStateNameError(name);\n }\n}\n\nexport function ensureStateNameIsUnique(\n stateName: string,\n state: ɵStateClassInternal,\n statesByName: StatesByName\n): void | never {\n const existingState = statesByName[stateName];\n if (existingState && existingState !== state) {\n throwStateUniqueError(stateName, state.name, existingState.name);\n }\n}\n\nexport function ensureStatesAreDecorated(stateClasses: ɵStateClassInternal[]): void | never {\n stateClasses.forEach((stateClass: ɵStateClassInternal) => {\n if (!ɵgetStoreMetadata(stateClass)) {\n throwStateDecoratorError(stateClass.name);\n }\n });\n}\n","import { getUndecoratedStateWithInjectableWarningMessage } from '../configs/messages.config';\n\n/**\n * All provided or injected tokens must have `@Injectable` decorator\n * (previously, injected tokens without `@Injectable` were allowed\n * if another decorator was used, e.g. pipes).\n */\nexport function ensureStateClassIsInjectable(stateClass: any): void {\n if (jit_hasInjectableAnnotation(stateClass) || aot_hasNgInjectableDef(stateClass)) {\n return;\n }\n\n console.warn(getUndecoratedStateWithInjectableWarningMessage(stateClass.name));\n}\n\nfunction aot_hasNgInjectableDef(stateClass: any): boolean {\n // `ɵprov` is a static property added by the NGCC compiler. It always exists in\n // AOT mode because this property is added before runtime. If an application is running in\n // JIT mode then this property can be added by the `@Injectable()` decorator. The `@Injectable()`\n // decorator has to go after the `@State()` decorator, thus we prevent users from unwanted DI errors.\n return !!stateClass.ɵprov;\n}\n\nfunction jit_hasInjectableAnnotation(stateClass: any): boolean {\n // `ɵprov` doesn't exist in JIT mode (for instance when running unit tests with Jest).\n const annotations = stateClass.__annotations__ || [];\n return annotations.some((annotation: any) => annotation?.ngMetadataName === 'Injectable');\n}\n","import { InjectionToken } from '@angular/core';\n\nimport { ActionType } from '../actions/symbols';\n\nexport interface NgxsDevelopmentOptions {\n // This allows setting only `true` because there's no reason to set `false`.\n // Developers may just skip importing the development module at all.\n warnOnUnhandledActions:\n | true\n | {\n ignore: ActionType[];\n };\n}\n\nexport const NGXS_DEVELOPMENT_OPTIONS =\n /* @__PURE__ */ new InjectionToken<NgxsDevelopmentOptions>(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'NGXS_DEVELOPMENT_OPTIONS' : '',\n {\n providedIn: 'root',\n factory: () => ({ warnOnUnhandledActions: true })\n }\n );\n","import { inject, Injectable } from '@angular/core';\nimport { InitState, UpdateState, getActionTypeFromInstance } from '@ngxs/store/plugins';\n\nimport { ActionType } from '../actions/symbols';\nimport { NGXS_DEVELOPMENT_OPTIONS } from './symbols';\n\n@Injectable()\nexport class NgxsUnhandledActionsLogger {\n /**\n * These actions should be ignored by default; the user can increase this\n * list in the future via the `ignoreActions` method.\n */\n private _ignoredActions = new Set<string>([InitState.type, UpdateState.type]);\n\n constructor() {\n const options = inject(NGXS_DEVELOPMENT_OPTIONS);\n if (typeof options.warnOnUnhandledActions === 'object') {\n this.ignoreActions(...options.warnOnUnhandledActions.ignore);\n }\n }\n\n /**\n * Adds actions to the internal list of actions that should be ignored.\n */\n ignoreActions(...actions: ActionType[]): void {\n for (const action of actions) {\n this._ignoredActions.add(action.type);\n }\n }\n\n /** @internal */\n warn(action: any): void {\n const actionShouldBeIgnored = Array.from(this._ignoredActions).some(\n type => type === getActionTypeFromInstance(action)\n );\n\n if (actionShouldBeIgnored) {\n return;\n }\n\n action =\n action.constructor && action.constructor.name !== 'Object'\n ? action.constructor.name\n : action.type;\n\n console.warn(\n `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.`\n );\n }\n}\n","import { ErrorHandler, Injectable, NgZone, inject } from '@angular/core';\n\nexport interface NgxsUnhandledErrorContext {\n action: any;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class NgxsUnhandledErrorHandler {\n private _ngZone = inject(NgZone);\n private _errorHandler = inject(ErrorHandler);\n\n /**\n * The `_unhandledErrorContext` is left unused internally since we do not\n * require it for internal operations. However, developers who wish to provide\n * their own custom error handler may utilize this context information.\n */\n handleError(error: any, _unhandledErrorContext: NgxsUnhandledErrorContext): void {\n // In order to avoid duplicate error handling, it is necessary to leave\n // the Angular zone to ensure that errors are not caught twice. The `handleError`\n // method may contain a `throw error` statement, which is used to re-throw the error.\n // If the error is re-thrown within the Angular zone, it will be caught again by the\n // Angular zone. By default, `@angular/core` leaves the Angular zone when invoking\n // `handleError` (see `_callAndReportToErrorHandler`).\n this._ngZone.runOutsideAngular(() => this._errorHandler.handleError(error));\n }\n}\n","import { getActionTypeFromInstance } from '@ngxs/store/plugins';\nimport { type OperatorFunction, type Observable, map, filter } from 'rxjs';\n\nimport { ActionType } from '../actions/symbols';\nimport { ActionContext, ActionStatus } from '../actions-stream';\n\ntype TupleKeys<T extends any[]> = Exclude<keyof T, keyof []>;\n\n/**\n * Given a POJO, returns the POJO type, given a class constructor object, returns the type of the class.\n *\n * This utility type exists due to the complexity of ActionType being either an ActionDef class or the plain\n * `{ type: string }` type (or similar compatible POJO types).\n */\ntype Constructed<T> = T extends new (...args: any[]) => infer U ? U : T;\n\nexport interface ActionCompletion<T = any, E = Error> {\n action: T;\n result: {\n successful: boolean;\n canceled: boolean;\n error?: E;\n };\n}\n\n/**\n * RxJS operator for selecting out specific actions.\n *\n * This will grab actions that have just been dispatched as well as actions that have completed\n */\nexport function ofAction<T extends ActionType[]>(\n ...allowedTypes: T\n): OperatorFunction<\n ActionContext<Constructed<T[TupleKeys<T>]>>,\n Constructed<T[TupleKeys<T>]>\n> {\n return ofActionOperator(allowedTypes);\n}\n\n/**\n * RxJS operator for selecting out specific actions.\n *\n * This will ONLY grab actions that have just been dispatched\n */\nexport function ofActionDispatched<T extends ActionType[]>(\n ...allowedTypes: T\n): OperatorFunction<\n ActionContext<Constructed<T[TupleKeys<T>]>>,\n Constructed<T[TupleKeys<T>]>\n> {\n return ofActionOperator(allowedTypes, [ActionStatus.Dispatched]);\n}\n\n/**\n * RxJS operator for selecting out specific actions.\n *\n * This will ONLY grab actions that have just been successfully completed\n */\nexport function ofActionSuccessful<T extends ActionType[]>(\n ...allowedTypes: T\n): OperatorFunction<\n ActionContext<Constructed<T[TupleKeys<T>]>>,\n Constructed<T[TupleKeys<T>]>\n> {\n return ofActionOperator(allowedTypes, [ActionStatus.Successful]);\n}\n\n/**\n * RxJS operator for selecting out specific actions.\n *\n * This will ONLY grab actions that have just been canceled\n */\nexport function ofActionCanceled<T extends ActionType[]>(\n ...allowedTypes: T\n): OperatorFunction<\n ActionContext<Constructed<T[TupleKeys<T>]>>,\n Constructed<T[TupleKeys<T>]>\n> {\n return ofActionOperator(allowedTypes, [ActionStatus.Canceled]);\n}\n\n/**\n * RxJS operator for selecting out specific actions.\n *\n * This will ONLY grab actions that have just been completed\n */\nexport function ofActionCompleted<T extends ActionType[]>(\n ...allowedTypes: T\n): OperatorFunction<\n ActionContext<Constructed<T[TupleKeys<T>]>>,\n ActionCompletion<Constructed<T[TupleKeys<T>]>>\n> {\n const allowedStatuses = [\n ActionStatus.Successful,\n ActionStatus.Canceled,\n ActionStatus.Errored\n ];\n return ofActionOperator(allowedTypes, allowedStatuses, mapActionResult);\n}\n\n/**\n * RxJS operator for selecting out specific actions.\n *\n * This will ONLY grab actions that have just thrown an error\n */\nexport function ofActionErrored<T extends ActionType[]>(\n ...allowedTypes: T\n): OperatorFunction<\n ActionContext<Constructed<T[TupleKeys<T>]>>,\n ActionCompletion<Constructed<T[TupleKeys<T>]>>\n> {\n return ofActionOperator(allowedTypes, [ActionStatus.Errored], mapActionResult);\n}\n\nfunction ofActionOperator(\n allowedTypes: ActionType[],\n statuses?: ActionStatus[],\n // This could have been written as\n // `OperatorFunction<ActionContext, ActionCompletion | any>`, as it maps\n // either to `ctx.action` or to `ActionCompletion`. However,\n // `ActionCompletion | any` defaults to `any`, rendering the union\n // type meaningless.\n mapOperator: () => OperatorFunction<ActionContext, any> = mapAction\n): OperatorFunction<ActionContext, any> {\n const allowedMap = createAllowedActionTypesMap(allowedTypes);\n const allowedStatusMap = statuses && createAllowedStatusesMap(statuses);\n return function (o: Observable<ActionContext>) {\n return o.pipe(filterStatus(allowedMap, allowedStatusMap), mapOperator());\n };\n}\n\nfunction filterStatus(allowedTypes: FilterMap, allowedStatuses?: FilterMap) {\n return filter((ctx: ActionContext) => {\n const actionType = getActionTypeFromInstance(ctx.action)!;\n const typeMatch = allowedTypes[actionType];\n const statusMatch = allowedStatuses ? allowedStatuses[ctx.status] : true;\n return typeMatch && statusMatch;\n });\n}\n\nfunction mapActionResult(): OperatorFunction<ActionContext, ActionCompletion> {\n return map(({ action, status, error }: ActionContext) => {\n return <ActionCompletion>{\n action,\n result: {\n successful: ActionStatus.Successful === status,\n canceled: ActionStatus.Canceled === status,\n error\n }\n };\n });\n}\n\nfunction mapAction<T = any>(): OperatorFunction<ActionContext, T> {\n return map((ctx: ActionContext) => <T>ctx.action);\n}\n\ninterface FilterMap {\n [key: string]: boolean;\n}\n\nfunction createAllowedActionTypesMap(types: ActionType[]): FilterMap {\n return types.reduce(\n (filterMap: FilterMap, klass: any) => {\n filterMap[getActionTypeFromInstance(klass)!] = true;\n return filterMap;\n },\n <FilterMap>{}\n );\n}\n\nfunction createAllowedStatusesMap(statuses: ActionStatus[]): FilterMap {\n return statuses.reduce(\n (filterMap: FilterMap, status: ActionStatus) => {\n filterMap[status] = true;\n return filterMap;\n },\n <FilterMap>{}\n );\n}\n","import {\n throwPatchingArrayError,\n throwPatchingPrimitiveError\n} from '../configs/messages.config';\nimport { ExistingState, StateOperator } from '@ngxs/store/operators';\n\nexport function simplePatch<T>(value: Partial<T>): StateOperator<T> {\n return (existingState: ExistingState<T>) => {\n if (typeof ngDevMode !== 'undefined' && ngDevMode) {\n if (Array.isArray(value)) {\n throwPatchingArrayError();\n } else if (typeof value !== 'object') {\n throwPatchingPrimitiveError();\n }\n }\n\n const newState: any = { ...(existingState as any) };\n for (const key in value) {\n // deep clone for patch compatibility\n newState[key] = (value as any)[key];\n }\n\n return newState as T;\n };\n}\n","import { inject, Injectable } from '@angular/core';\nimport { getValue, setValue } from '@ngxs/store/plugins';\nimport { ExistingState, StateOperator, isStateOperator } from '@