@ngrx/signals 21.0.0 → 21.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngrx-signals-entities.mjs +282 -0
- package/fesm2022/ngrx-signals-entities.mjs.map +1 -1
- package/fesm2022/ngrx-signals-events.mjs +4 -4
- package/fesm2022/ngrx-signals-events.mjs.map +1 -1
- package/fesm2022/ngrx-signals-rxjs-interop.mjs +40 -1
- package/fesm2022/ngrx-signals-rxjs-interop.mjs.map +1 -1
- package/fesm2022/ngrx-signals-testing.mjs +35 -0
- package/fesm2022/ngrx-signals-testing.mjs.map +1 -1
- package/fesm2022/ngrx-signals.mjs +353 -21
- package/fesm2022/ngrx-signals.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics-core/utility/libs-version.js +1 -1
- package/schematics-core/utility/libs-version.js.map +1 -1
- package/types/ngrx-signals-events.d.ts +4 -4
- package/types/ngrx-signals-rxjs-interop.d.ts +39 -0
- package/types/ngrx-signals-testing.d.ts +35 -0
- package/types/ngrx-signals.d.ts +243 -20
|
@@ -48,7 +48,7 @@ class BaseEvents {
|
|
|
48
48
|
*
|
|
49
49
|
* const increment = event('[Counter Page] Increment');
|
|
50
50
|
*
|
|
51
|
-
* \@Component(
|
|
51
|
+
* \@Component(...)
|
|
52
52
|
* class Counter {
|
|
53
53
|
* readonly #events = inject(Events);
|
|
54
54
|
*
|
|
@@ -119,7 +119,7 @@ function withSourceType() {
|
|
|
119
119
|
*
|
|
120
120
|
* const increment = event('[Counter Page] Increment');
|
|
121
121
|
*
|
|
122
|
-
* \@Component(
|
|
122
|
+
* \@Component(...)
|
|
123
123
|
* class Counter {
|
|
124
124
|
* readonly #dispatcher = inject(Dispatcher);
|
|
125
125
|
*
|
|
@@ -166,7 +166,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.1", ngImpor
|
|
|
166
166
|
* const increment = event('[Counter Page] Increment');
|
|
167
167
|
*
|
|
168
168
|
* \@Component({
|
|
169
|
-
*
|
|
169
|
+
* // ...
|
|
170
170
|
* providers: [provideDispatcher()],
|
|
171
171
|
* })
|
|
172
172
|
* class Counter {
|
|
@@ -355,7 +355,7 @@ function mapToScope(scope) {
|
|
|
355
355
|
* },
|
|
356
356
|
* });
|
|
357
357
|
*
|
|
358
|
-
* \@Component(
|
|
358
|
+
* \@Component(...)
|
|
359
359
|
* class Counter {
|
|
360
360
|
* readonly dispatch = injectDispatch(counterPageEvents);
|
|
361
361
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngrx-signals-events.mjs","sources":["../../../../modules/signals/events/src/case-reducer.ts","../../../../modules/signals/events/src/events-service.ts","../../../../modules/signals/events/src/dispatcher.ts","../../../../modules/signals/events/src/event-creator.ts","../../../../modules/signals/events/src/event-creator-group.ts","../../../../modules/signals/events/src/event-scope.ts","../../../../modules/signals/events/src/inject-dispatch.ts","../../../../modules/signals/events/src/event-instance.ts","../../../../modules/signals/events/src/with-event-handlers.ts","../../../../modules/signals/events/src/with-reducer.ts","../../../../modules/signals/events/ngrx-signals-events.ts"],"sourcesContent":["import { PartialStateUpdater } from '@ngrx/signals';\nimport { EventCreator } from './event-creator';\n\nexport type CaseReducerResult<\n State extends object,\n EventCreators extends EventCreator<string, any>[],\n> = {\n reducer: CaseReducer<State, EventCreators>;\n events: EventCreators;\n};\n\ntype CaseReducer<\n State extends object,\n EventCreators extends EventCreator<string, any>[],\n> = (\n event: { [K in keyof EventCreators]: ReturnType<EventCreators[K]> }[number],\n state: State\n) =>\n | Partial<State>\n | PartialStateUpdater<State>\n | Array<Partial<State> | PartialStateUpdater<State>>;\n\n/**\n * @description\n *\n * Creates a case reducer that can be used with the `withReducer` feature.\n */\nexport function on<\n State extends object,\n EventCreators extends EventCreator<string, any>[],\n>(\n ...args: [\n ...events: [...EventCreators],\n reducer: CaseReducer<NoInfer<State>, NoInfer<EventCreators>>,\n ]\n): CaseReducerResult<State, EventCreators> {\n const reducer = args.pop() as CaseReducer<State, EventCreators>;\n const events = args as unknown as EventCreators;\n\n return { reducer, events };\n}\n","import { inject, Injectable, Type } from '@angular/core';\nimport {\n filter,\n map,\n merge,\n MonoTypeOperatorFunction,\n Observable,\n Subject,\n} from 'rxjs';\nimport { EventInstance } from './event-instance';\nimport { EventCreator } from './event-creator';\n\nexport const EVENTS = Symbol(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'EVENTS' : ''\n);\nexport const SOURCE_TYPE = Symbol(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'SOURCE_TYPE' : ''\n);\n\nabstract class BaseEvents {\n /**\n * @internal\n */\n readonly [EVENTS] = new Subject<EventInstance<string, unknown>>();\n protected readonly events$: Observable<EventInstance<string, unknown>>;\n\n protected constructor(parentEventsToken: Type<BaseEvents>) {\n const parentEvents = inject(parentEventsToken, {\n skipSelf: true,\n optional: true,\n });\n this.events$ = parentEvents\n ? merge(parentEvents.events$, this[EVENTS])\n : this[EVENTS].asObservable();\n }\n\n on(): Observable<EventInstance<string, unknown>>;\n on<EventCreators extends EventCreator<string, any>[]>(\n ...events: [...EventCreators]\n ): Observable<\n { [K in keyof EventCreators]: ReturnType<EventCreators[K]> }[number]\n >;\n on(\n ...events: EventCreator<string, unknown>[]\n ): Observable<EventInstance<string, unknown>> {\n return this.events$.pipe(filterByType(events), withSourceType());\n }\n}\n\n/**\n * @description\n *\n * Globally provided service for listening to dispatched events.\n *\n * @usageNotes\n *\n * ```ts\n * import { event, Events } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n *\n * \\@Component({ /* ... *\\/ })\n * class Counter {\n * readonly #events = inject(Events);\n *\n * constructor() {\n * this.#events\n * .on(increment)\n * .pipe(takeUntilDestroyed())\n * .subscribe(() => /* handle increment event *\\/);\n * }\n * }\n * ```\n */\n@Injectable({ providedIn: 'platform' })\nexport class Events extends BaseEvents {\n constructor() {\n super(Events);\n }\n}\n\n/**\n * @description\n *\n * Globally provided service for listening to dispatched events.\n * Receives events before the `Events` service and is primarily used for\n * handling state transitions.\n */\n@Injectable({ providedIn: 'platform' })\nexport class ReducerEvents extends BaseEvents {\n constructor() {\n super(ReducerEvents);\n }\n}\n\nfunction filterByType<T extends EventInstance<string, unknown>>(\n events: EventCreator<string, unknown>[]\n): MonoTypeOperatorFunction<T> {\n if (events.length === 0) {\n return (source$) => source$;\n }\n\n const eventMap = toEventCreatorMap(events);\n return filter<T>(({ type }) => !!eventMap[type]);\n}\n\nfunction toEventCreatorMap(\n events: EventCreator<string, unknown>[]\n): Record<string, EventCreator<string, unknown>> {\n return events.reduce((acc, event) => ({ ...acc, [event.type]: event }), {});\n}\n\nfunction withSourceType<\n T extends EventInstance<string, unknown>,\n>(): MonoTypeOperatorFunction<T> {\n return map(({ ...event }) => {\n Object.defineProperty(event, SOURCE_TYPE, { value: event.type });\n return event;\n });\n}\n","import { inject, Injectable, Provider } from '@angular/core';\nimport { queueScheduler } from 'rxjs';\nimport { EventInstance } from './event-instance';\nimport { EventScope, EventScopeConfig } from './event-scope';\nimport { Events, EVENTS, ReducerEvents } from './events-service';\n\n/**\n * @description\n *\n * Globally provided service for dispatching events.\n *\n * @usageNotes\n *\n * ```ts\n * import { Dispatcher, event } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n *\n * \\@Component({ /* ... *\\/ })\n * class Counter {\n * readonly #dispatcher = inject(Dispatcher);\n *\n * increment(): void {\n * this.#dispatcher.dispatch(increment());\n * }\n * }\n * ```\n */\n@Injectable({ providedIn: 'platform' })\nexport class Dispatcher {\n protected readonly reducerEvents = inject(ReducerEvents);\n protected readonly events = inject(Events);\n protected readonly parentDispatcher = inject(Dispatcher, {\n skipSelf: true,\n optional: true,\n });\n\n dispatch(\n event: EventInstance<string, unknown>,\n config?: EventScopeConfig\n ): void {\n if (this.parentDispatcher && hasParentOrGlobalScope(config)) {\n this.parentDispatcher.dispatch(\n event,\n config.scope === 'global' ? config : undefined\n );\n } else {\n this.reducerEvents[EVENTS].next(event);\n queueScheduler.schedule(() => this.events[EVENTS].next(event));\n }\n }\n}\n\n/**\n * @description\n *\n * Provides scoped instances of Dispatcher and Events services.\n * Enables event dispatching within a specific component or feature scope.\n *\n * @usageNotes\n *\n * ```ts\n * import { Dispatcher, event } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n *\n * \\@Component({\n * /* ... *\\/\n * providers: [provideDispatcher()],\n * })\n * class Counter {\n * readonly #dispatcher = inject(Dispatcher);\n *\n * increment(): void {\n * // Dispatching an event to the local Dispatcher.\n * this.#dispatcher.dispatch(increment());\n *\n * // Dispatching an event to the parent Dispatcher.\n * this.#dispatcher.dispatch(increment(), { scope: 'parent' });\n *\n * // Dispatching an event to the global Dispatcher.\n * this.#dispatcher.dispatch(increment(), { scope: 'global' });\n * }\n * }\n * ```\n */\nexport function provideDispatcher(): Provider[] {\n return [Events, ReducerEvents, Dispatcher];\n}\n\nfunction hasParentOrGlobalScope(\n config?: EventScopeConfig\n): config is { scope: Exclude<EventScope, 'self'> } {\n return config?.scope === 'parent' || config?.scope === 'global';\n}\n","import { EventInstance } from './event-instance';\n\nexport type EventCreator<Type extends string, Payload> = ((\n payload: Payload\n) => EventInstance<Type, Payload>) & { type: Type };\n\nexport function event<Type extends string>(\n type: Type\n): EventCreator<Type, void>;\nexport function event<Type extends string, Payload>(\n type: Type,\n payload: Payload\n): EventCreator<Type, Payload>;\n/**\n * @description\n *\n * Creates an event creator.\n *\n * @usageNotes\n *\n * ### Creating an event creator without payload\n *\n * ```ts\n * import { event } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n * ```\n *\n * ### Creating an event creator with payload\n *\n * ```ts\n * import { type } from '@ngrx/signals';\n * import { event } from '@ngrx/signals/events';\n *\n * const set = event('[Counter Page] Set', type<number>());\n * ```\n */\nexport function event(type: string): EventCreator<string, any> {\n const creator = (payload?: unknown) => ({ type, payload });\n (creator as any).type = type;\n\n return creator as EventCreator<string, unknown>;\n}\n","import { Prettify } from '@ngrx/signals';\nimport { event, EventCreator } from './event-creator';\n\ntype EventType<\n Source extends string,\n EventName extends string,\n> = `[${Source}] ${EventName}`;\n\ntype EventCreatorGroup<\n Source extends string,\n Events extends Record<string, any>,\n> = {\n readonly [EventName in keyof Events]: EventName extends string\n ? EventCreator<EventType<Source, EventName>, Events[EventName]>\n : never;\n};\n\n/**\n * @description\n *\n * Creates a group of event creators.\n *\n * @usageNotes\n *\n * ```ts\n * import { type } from '@ngrx/signals';\n * import { eventGroup } from '@ngrx/signals/events';\n *\n * const counterPageEvents = eventGroup({\n * source: 'Counter Page',\n * events: {\n * increment: type<void>(),\n * decrement: type<void>(),\n * set: type<number>(),\n * },\n * });\n * ```\n */\nexport function eventGroup<\n Source extends string,\n Events extends Record<string, unknown>,\n>(config: {\n source: Source;\n events: Events;\n}): Prettify<EventCreatorGroup<Source, Events>> {\n return Object.entries(config.events).reduce(\n (acc, [eventName]) => {\n const eventType = `[${config.source}] ${eventName}`;\n return { ...acc, [eventName]: event(eventType) };\n },\n {} as EventCreatorGroup<Source, Events>\n );\n}\n","import { map, OperatorFunction } from 'rxjs';\nimport { EventInstance } from './event-instance';\n\nexport type EventScope = 'self' | 'parent' | 'global';\n\nexport type EventScopeConfig = { scope: EventScope };\n\n/**\n * @description\n *\n * Marks a single event to be dispatched in the specified scope.\n * Used in a tuple alongside an event to indicate its dispatch scope.\n *\n * @usageNotes\n *\n * ```ts\n * import { signalStore, type } from '@ngrx/signals';\n * import { event, Events, withEffects } from '@ngrx/signals/events';\n * import { mapResponse } from '@ngrx/operators';\n *\n * const opened = event('[Users Page] Opened');\n * const loadedSuccess = event('[Users API] Loaded Success', type<User[]>());\n * const loadedFailure = event('[Users API] Loaded Failure', type<string>());\n *\n * const UsersStore = signalStore(\n * withEffects((\n * _,\n * events = inject(Events),\n * usersService = inject(UsersService)\n * ) => ({\n * loadUsers$: events.on(opened).pipe(\n * exhaustMap(() =>\n * usersService.getAll().pipe(\n * mapResponse({\n * next: (users) => loadedSuccess(users),\n * error: (error: { message: string }) => [\n * loadedFailure(error.message),\n * toScope('global'),\n * ],\n * }),\n * ),\n * ),\n * ),\n * })),\n * );\n * ```\n */\nexport function toScope(scope: EventScope): EventScopeConfig {\n return { scope };\n}\n\n/**\n * @description\n *\n * RxJS operator that maps all emitted events in the stream to be dispatched\n * in the specified scope.\n *\n * @usageNotes\n *\n * ```ts\n * import { signalStore, type } from '@ngrx/signals';\n * import { event, Events, withEffects } from '@ngrx/signals/events';\n * import { mapResponse } from '@ngrx/operators';\n *\n * const opened = event('[Users Page] Opened');\n * const loadedSuccess = event('[Users API] Loaded Success', type<User[]>());\n * const loadedFailure = event('[Users API] Loaded Failure', type<string>());\n *\n * const UsersStore = signalStore(\n * withEffects((\n * _,\n * events = inject(Events),\n * usersService = inject(UsersService)\n * ) => ({\n * loadUsers$: events.on(opened).pipe(\n * exhaustMap(() =>\n * usersService.getAll().pipe(\n * mapResponse({\n * next: (users) => loadedSuccess(users),\n * error: (error: { message: string }) =>\n * loadedFailure(error.message),\n * }),\n * mapToScope('parent'),\n * ),\n * ),\n * ),\n * })),\n * );\n * ```\n */\nexport function mapToScope<T extends EventInstance<string, unknown>>(\n scope: EventScope\n): OperatorFunction<T, [T, EventScopeConfig]> {\n return map((event) => [event, toScope(scope)]);\n}\n","import {\n assertInInjectionContext,\n inject,\n Injector,\n untracked,\n} from '@angular/core';\nimport { Prettify } from '@ngrx/signals';\nimport { Dispatcher } from './dispatcher';\nimport { EventCreator } from './event-creator';\nimport { EventScope, EventScopeConfig } from './event-scope';\n\ntype SelfDispatchingEvents<\n EventGroup extends Record<string, EventCreator<string, any>>,\n> = {\n readonly [EventName in keyof EventGroup]: Parameters<\n EventGroup[EventName]\n > extends [infer Payload]\n ? (payload: Payload) => void\n : () => void;\n};\n\n/**\n * @description\n *\n * Creates self-dispatching events for a given event group.\n *\n * @usageNotes\n *\n * ```ts\n * import { type } from '@ngrx/signals';\n * import { eventGroup, injectDispatch } from '@ngrx/signals/events';\n *\n * const counterPageEvents = eventGroup({\n * source: 'Counter Page',\n * events: {\n * increment: type<void>(),\n * decrement: type<void>(),\n * },\n * });\n *\n * \\@Component({ /* ... *\\/ })\n * class Counter {\n * readonly dispatch = injectDispatch(counterPageEvents);\n *\n * increment(): void {\n * this.dispatch.increment();\n * }\n *\n * decrement(): void {\n * this.dispatch.decrement();\n * }\n * }\n * ```\n */\nexport function injectDispatch<\n EventGroup extends Record<string, EventCreator<string, any>>,\n>(\n events: EventGroup,\n config?: { injector?: Injector }\n): ((config: EventScopeConfig) => Prettify<SelfDispatchingEvents<EventGroup>>) &\n Prettify<SelfDispatchingEvents<EventGroup>> {\n if (typeof ngDevMode !== 'undefined' && ngDevMode && !config?.injector) {\n assertInInjectionContext(injectDispatch);\n }\n\n const injector = config?.injector ?? inject(Injector);\n const dispatcher = injector.get(Dispatcher);\n\n const eventsCache = {} as Record<\n EventScope,\n SelfDispatchingEvents<EventGroup>\n >;\n\n const dispatch = (config: EventScopeConfig) => {\n if (!eventsCache[config.scope]) {\n eventsCache[config.scope] = Object.entries(events).reduce(\n (acc, [eventName, eventCreator]) => ({\n ...acc,\n [eventName]: (payload?: unknown) =>\n untracked(() => dispatcher.dispatch(eventCreator(payload), config)),\n }),\n {} as SelfDispatchingEvents<EventGroup>\n );\n }\n\n return eventsCache[config.scope];\n };\n\n const defaultEventGroup = dispatch({ scope: 'self' });\n const defaultEventGroupProps = Object.keys(defaultEventGroup).reduce(\n (acc, eventName) => ({\n ...acc,\n [eventName]: {\n value: defaultEventGroup[eventName],\n enumerable: true,\n },\n }),\n {} as PropertyDescriptorMap\n );\n Object.defineProperties(dispatch, defaultEventGroupProps);\n\n return dispatch as ReturnType<typeof injectDispatch<EventGroup>>;\n}\n","export type EventInstance<Type extends string, Payload> = {\n type: Type;\n payload: Payload;\n};\n\nexport function isEventInstance(\n value: unknown\n): value is EventInstance<string, unknown> {\n return typeof value === 'object' && value !== null && 'type' in value;\n}\n","import { inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { merge, Observable, tap } from 'rxjs';\nimport {\n EmptyFeatureResult,\n Prettify,\n signalStoreFeature,\n SignalStoreFeature,\n SignalStoreFeatureResult,\n StateSignals,\n type,\n withHooks,\n WritableStateSource,\n} from '@ngrx/signals';\nimport { Dispatcher } from './dispatcher';\nimport { isEventInstance } from './event-instance';\nimport { SOURCE_TYPE } from './events-service';\n\n/**\n * @description\n *\n * SignalStore feature for defining event handlers.\n *\n * @usageNotes\n *\n * ```ts\n * import { signalStore, withState } from '@ngrx/signals';\n * import { event, Events, withEventHandlers } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n * const decrement = event('[Counter Page] Decrement');\n *\n * const CounterStore = signalStore(\n * withState({ count: 0 }),\n * withEventHandlers(({ count }, events = inject(Events)) => ({\n * logCount$: events.on(increment, decrement).pipe(\n * tap(({ type }) => console.log(type, count())),\n * ),\n * })),\n * );\n * ```\n */\nexport function withEventHandlers<Input extends SignalStoreFeatureResult>(\n handlersFactory: (\n store: Prettify<\n StateSignals<Input['state']> &\n Input['props'] &\n Input['methods'] &\n WritableStateSource<Prettify<Input['state']>>\n >\n ) => Record<string, Observable<unknown>> | Observable<unknown>[]\n): SignalStoreFeature<Input, EmptyFeatureResult> {\n return signalStoreFeature(\n type<Input>(),\n withHooks({\n onInit(store, dispatcher = inject(Dispatcher)) {\n const handlerSources = handlersFactory(store);\n const handlers = Object.values(handlerSources).map((handlerSource$) =>\n handlerSource$.pipe(\n tap((result) => {\n const [potentialEvent, config] = Array.isArray(result)\n ? result\n : [result];\n\n if (\n isEventInstance(potentialEvent) &&\n !(SOURCE_TYPE in potentialEvent)\n ) {\n dispatcher.dispatch(potentialEvent, config);\n }\n })\n )\n );\n\n merge(...handlers)\n .pipe(takeUntilDestroyed())\n .subscribe();\n },\n })\n );\n}\n","import { inject, untracked } from '@angular/core';\nimport { tap } from 'rxjs';\nimport {\n EmptyFeatureResult,\n getState,\n patchState,\n SignalStoreFeature,\n signalStoreFeature,\n type,\n} from '@ngrx/signals';\nimport { CaseReducerResult } from './case-reducer';\nimport { EventCreator } from './event-creator';\nimport { ReducerEvents } from './events-service';\nimport { withEventHandlers } from './with-event-handlers';\n\n/**\n * @description\n *\n * SignalStore feature for defining state transitions based on dispatched events.\n *\n * @usageNotes\n *\n * ```ts\n * import { signalStore, type, withState } from '@ngrx/signals';\n * import { event, on, withReducer } from '@ngrx/signals/events';\n *\n * const set = event('[Counter Page] Set', type<number>());\n *\n * const CounterStore = signalStore(\n * withState({ count: 0 }),\n * withReducer(\n * on(set, ({ payload }) => ({ count: payload })),\n * ),\n * );\n * ```\n */\nexport function withReducer<State extends object>(\n ...caseReducers: CaseReducerResult<State, EventCreator<string, any>[]>[]\n): SignalStoreFeature<\n { state: State; props: {}; methods: {} },\n EmptyFeatureResult\n> {\n return signalStoreFeature(\n { state: type<State>() },\n withEventHandlers((store, events = inject(ReducerEvents)) =>\n caseReducers.map((caseReducer) =>\n events.on(...caseReducer.events).pipe(\n tap((event) => {\n const state = untracked(() => getState(store));\n const result = caseReducer.reducer(event, state);\n const updaters = Array.isArray(result) ? result : [result];\n\n patchState(store, ...updaters);\n })\n )\n )\n )\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAsBA;;;;AAIG;AACG,SAAU,EAAE,CAIhB,GAAG,IAGF,EAAA;AAED,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAuC;IAC/D,MAAM,MAAM,GAAG,IAAgC;AAE/C,IAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE;AAC5B;;AC5BO,MAAM,MAAM,GAAG,MAAM,CAC1B,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,GAAG,QAAQ,GAAG,EAAE,CAC9D;AACM,MAAM,WAAW,GAAG,MAAM,CAC/B,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,GAAG,aAAa,GAAG,EAAE,CACnE;AAED,MAAe,UAAU,CAAA;AACvB;;AAEG;AACM,IAAA,CAAC,MAAM,IAAI,IAAI,OAAO,EAAkC;AAC9C,IAAA,OAAO;AAE1B,IAAA,WAAA,CAAsB,iBAAmC,EAAA;AACvD,QAAA,MAAM,YAAY,GAAG,MAAM,CAAC,iBAAiB,EAAE;AAC7C,YAAA,QAAQ,EAAE,IAAI;AACd,YAAA,QAAQ,EAAE,IAAI;AACf,SAAA,CAAC;QACF,IAAI,CAAC,OAAO,GAAG;cACX,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;cACxC,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE;IACjC;IAQA,EAAE,CACA,GAAG,MAAuC,EAAA;AAE1C,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,CAAC;IAClE;AACD;AAED;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;AAEG,MAAO,MAAO,SAAQ,UAAU,CAAA;AACpC,IAAA,WAAA,GAAA;QACE,KAAK,CAAC,MAAM,CAAC;IACf;0HAHW,MAAM,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAN,uBAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAM,cADO,UAAU,EAAA,CAAA;;2FACvB,MAAM,EAAA,UAAA,EAAA,CAAA;kBADlB,UAAU;mBAAC,EAAE,UAAU,EAAE,UAAU,EAAE;;AAOtC;;;;;;AAMG;AAEG,MAAO,aAAc,SAAQ,UAAU,CAAA;AAC3C,IAAA,WAAA,GAAA;QACE,KAAK,CAAC,aAAa,CAAC;IACtB;0HAHW,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAb,uBAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,cADA,UAAU,EAAA,CAAA;;2FACvB,aAAa,EAAA,UAAA,EAAA,CAAA;kBADzB,UAAU;mBAAC,EAAE,UAAU,EAAE,UAAU,EAAE;;AAOtC,SAAS,YAAY,CACnB,MAAuC,EAAA;AAEvC,IAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;AACvB,QAAA,OAAO,CAAC,OAAO,KAAK,OAAO;IAC7B;AAEA,IAAA,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC;AAC1C,IAAA,OAAO,MAAM,CAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAClD;AAEA,SAAS,iBAAiB,CACxB,MAAuC,EAAA;AAEvC,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;AAC7E;AAEA,SAAS,cAAc,GAAA;IAGrB,OAAO,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,KAAI;AAC1B,QAAA,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AAChE,QAAA,OAAO,KAAK;AACd,IAAA,CAAC,CAAC;AACJ;;ACjHA;;;;;;;;;;;;;;;;;;;;;AAqBG;MAEU,UAAU,CAAA;AACF,IAAA,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;AACrC,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,IAAA,gBAAgB,GAAG,MAAM,CAAC,UAAU,EAAE;AACvD,QAAA,QAAQ,EAAE,IAAI;AACd,QAAA,QAAQ,EAAE,IAAI;AACf,KAAA,CAAC;IAEF,QAAQ,CACN,KAAqC,EACrC,MAAyB,EAAA;QAEzB,IAAI,IAAI,CAAC,gBAAgB,IAAI,sBAAsB,CAAC,MAAM,CAAC,EAAE;YAC3D,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAC5B,KAAK,EACL,MAAM,CAAC,KAAK,KAAK,QAAQ,GAAG,MAAM,GAAG,SAAS,CAC/C;QACH;aAAO;YACL,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;AACtC,YAAA,cAAc,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChE;IACF;0HArBW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAV,uBAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAU,cADG,UAAU,EAAA,CAAA;;2FACvB,UAAU,EAAA,UAAA,EAAA,CAAA;kBADtB,UAAU;mBAAC,EAAE,UAAU,EAAE,UAAU,EAAE;;AAyBtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCG;SACa,iBAAiB,GAAA;AAC/B,IAAA,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC;AAC5C;AAEA,SAAS,sBAAsB,CAC7B,MAAyB,EAAA;IAEzB,OAAO,MAAM,EAAE,KAAK,KAAK,QAAQ,IAAI,MAAM,EAAE,KAAK,KAAK,QAAQ;AACjE;;ACjFA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACG,SAAU,KAAK,CAAC,IAAY,EAAA;AAChC,IAAA,MAAM,OAAO,GAAG,CAAC,OAAiB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACzD,IAAA,OAAe,CAAC,IAAI,GAAG,IAAI;AAE5B,IAAA,OAAO,OAAwC;AACjD;;ACzBA;;;;;;;;;;;;;;;;;;;;AAoBG;AACG,SAAU,UAAU,CAGxB,MAGD,EAAA;AACC,IAAA,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CACzC,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAI;QACnB,MAAM,SAAS,GAAG,CAAA,CAAA,EAAI,MAAM,CAAC,MAAM,CAAA,EAAA,EAAK,SAAS,CAAA,CAAE;AACnD,QAAA,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE;IAClD,CAAC,EACD,EAAuC,CACxC;AACH;;AC7CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCG;AACG,SAAU,OAAO,CAAC,KAAiB,EAAA;IACvC,OAAO,EAAE,KAAK,EAAE;AAClB;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCG;AACG,SAAU,UAAU,CACxB,KAAiB,EAAA;AAEjB,IAAA,OAAO,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAChD;;ACzEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCG;AACG,SAAU,cAAc,CAG5B,MAAkB,EAClB,MAAgC,EAAA;AAGhC,IAAA,IAAI,OAAO,SAAS,KAAK,WAAW,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE;QACtE,wBAAwB,CAAC,cAAc,CAAC;IAC1C;IAEA,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC;IACrD,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC;IAE3C,MAAM,WAAW,GAAG,EAGnB;AAED,IAAA,MAAM,QAAQ,GAAG,CAAC,MAAwB,KAAI;QAC5C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC9B,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CACvD,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,MAAM;AACnC,gBAAA,GAAG,GAAG;gBACN,CAAC,SAAS,GAAG,CAAC,OAAiB,KAC7B,SAAS,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;aACtE,CAAC,EACF,EAAuC,CACxC;QACH;AAEA,QAAA,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;AAClC,IAAA,CAAC;IAED,MAAM,iBAAiB,GAAG,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACrD,IAAA,MAAM,sBAAsB,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAClE,CAAC,GAAG,EAAE,SAAS,MAAM;AACnB,QAAA,GAAG,GAAG;QACN,CAAC,SAAS,GAAG;AACX,YAAA,KAAK,EAAE,iBAAiB,CAAC,SAAS,CAAC;AACnC,YAAA,UAAU,EAAE,IAAI;AACjB,SAAA;KACF,CAAC,EACF,EAA2B,CAC5B;AACD,IAAA,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,sBAAsB,CAAC;AAEzD,IAAA,OAAO,QAAyD;AAClE;;ACjGM,SAAU,eAAe,CAC7B,KAAc,EAAA;AAEd,IAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK;AACvE;;ACSA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACG,SAAU,iBAAiB,CAC/B,eAOgE,EAAA;AAEhE,IAAA,OAAO,kBAAkB,CACvB,IAAI,EAAS,EACb,SAAS,CAAC;QACR,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,EAAA;AAC3C,YAAA,MAAM,cAAc,GAAG,eAAe,CAAC,KAAK,CAAC;YAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,cAAc,KAChE,cAAc,CAAC,IAAI,CACjB,GAAG,CAAC,CAAC,MAAM,KAAI;gBACb,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM;AACnD,sBAAE;AACF,sBAAE,CAAC,MAAM,CAAC;gBAEZ,IACE,eAAe,CAAC,cAAc,CAAC;AAC/B,oBAAA,EAAE,WAAW,IAAI,cAAc,CAAC,EAChC;AACA,oBAAA,UAAU,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;gBAC7C;YACF,CAAC,CAAC,CACH,CACF;YAED,KAAK,CAAC,GAAG,QAAQ;iBACd,IAAI,CAAC,kBAAkB,EAAE;AACzB,iBAAA,SAAS,EAAE;QAChB,CAAC;AACF,KAAA,CAAC,CACH;AACH;;ACjEA;;;;;;;;;;;;;;;;;;;;AAoBG;AACG,SAAU,WAAW,CACzB,GAAG,YAAqE,EAAA;IAKxE,OAAO,kBAAkB,CACvB,EAAE,KAAK,EAAE,IAAI,EAAS,EAAE,EACxB,iBAAiB,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC,KACtD,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,KAC3B,MAAM,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CACnC,GAAG,CAAC,CAAC,KAAK,KAAI;AACZ,QAAA,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;AAChD,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC;AAE1D,QAAA,UAAU,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC;AAChC,IAAA,CAAC,CAAC,CACH,CACF,CACF,CACF;AACH;;AC1DA;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ngrx-signals-events.mjs","sources":["../../../../modules/signals/events/src/case-reducer.ts","../../../../modules/signals/events/src/events-service.ts","../../../../modules/signals/events/src/dispatcher.ts","../../../../modules/signals/events/src/event-creator.ts","../../../../modules/signals/events/src/event-creator-group.ts","../../../../modules/signals/events/src/event-scope.ts","../../../../modules/signals/events/src/inject-dispatch.ts","../../../../modules/signals/events/src/event-instance.ts","../../../../modules/signals/events/src/with-event-handlers.ts","../../../../modules/signals/events/src/with-reducer.ts","../../../../modules/signals/events/ngrx-signals-events.ts"],"sourcesContent":["import { PartialStateUpdater } from '@ngrx/signals';\nimport { EventCreator } from './event-creator';\n\nexport type CaseReducerResult<\n State extends object,\n EventCreators extends EventCreator<string, any>[],\n> = {\n reducer: CaseReducer<State, EventCreators>;\n events: EventCreators;\n};\n\ntype CaseReducer<\n State extends object,\n EventCreators extends EventCreator<string, any>[],\n> = (\n event: { [K in keyof EventCreators]: ReturnType<EventCreators[K]> }[number],\n state: State\n) =>\n | Partial<State>\n | PartialStateUpdater<State>\n | Array<Partial<State> | PartialStateUpdater<State>>;\n\n/**\n * @description\n *\n * Creates a case reducer that can be used with the `withReducer` feature.\n */\nexport function on<\n State extends object,\n EventCreators extends EventCreator<string, any>[],\n>(\n ...args: [\n ...events: [...EventCreators],\n reducer: CaseReducer<NoInfer<State>, NoInfer<EventCreators>>,\n ]\n): CaseReducerResult<State, EventCreators> {\n const reducer = args.pop() as CaseReducer<State, EventCreators>;\n const events = args as unknown as EventCreators;\n\n return { reducer, events };\n}\n","import { inject, Injectable, Type } from '@angular/core';\nimport {\n filter,\n map,\n merge,\n MonoTypeOperatorFunction,\n Observable,\n Subject,\n} from 'rxjs';\nimport { EventInstance } from './event-instance';\nimport { EventCreator } from './event-creator';\n\nexport const EVENTS = Symbol(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'EVENTS' : ''\n);\nexport const SOURCE_TYPE = Symbol(\n typeof ngDevMode !== 'undefined' && ngDevMode ? 'SOURCE_TYPE' : ''\n);\n\nabstract class BaseEvents {\n /**\n * @internal\n */\n readonly [EVENTS] = new Subject<EventInstance<string, unknown>>();\n protected readonly events$: Observable<EventInstance<string, unknown>>;\n\n protected constructor(parentEventsToken: Type<BaseEvents>) {\n const parentEvents = inject(parentEventsToken, {\n skipSelf: true,\n optional: true,\n });\n this.events$ = parentEvents\n ? merge(parentEvents.events$, this[EVENTS])\n : this[EVENTS].asObservable();\n }\n\n on(): Observable<EventInstance<string, unknown>>;\n on<EventCreators extends EventCreator<string, any>[]>(\n ...events: [...EventCreators]\n ): Observable<\n { [K in keyof EventCreators]: ReturnType<EventCreators[K]> }[number]\n >;\n on(\n ...events: EventCreator<string, unknown>[]\n ): Observable<EventInstance<string, unknown>> {\n return this.events$.pipe(filterByType(events), withSourceType());\n }\n}\n\n/**\n * @description\n *\n * Globally provided service for listening to dispatched events.\n *\n * @usageNotes\n *\n * ```ts\n * import { event, Events } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n *\n * \\@Component(...)\n * class Counter {\n * readonly #events = inject(Events);\n *\n * constructor() {\n * this.#events\n * .on(increment)\n * .pipe(takeUntilDestroyed())\n * .subscribe(() => /* handle increment event *\\/);\n * }\n * }\n * ```\n */\n@Injectable({ providedIn: 'platform' })\nexport class Events extends BaseEvents {\n constructor() {\n super(Events);\n }\n}\n\n/**\n * @description\n *\n * Globally provided service for listening to dispatched events.\n * Receives events before the `Events` service and is primarily used for\n * handling state transitions.\n */\n@Injectable({ providedIn: 'platform' })\nexport class ReducerEvents extends BaseEvents {\n constructor() {\n super(ReducerEvents);\n }\n}\n\nfunction filterByType<T extends EventInstance<string, unknown>>(\n events: EventCreator<string, unknown>[]\n): MonoTypeOperatorFunction<T> {\n if (events.length === 0) {\n return (source$) => source$;\n }\n\n const eventMap = toEventCreatorMap(events);\n return filter<T>(({ type }) => !!eventMap[type]);\n}\n\nfunction toEventCreatorMap(\n events: EventCreator<string, unknown>[]\n): Record<string, EventCreator<string, unknown>> {\n return events.reduce((acc, event) => ({ ...acc, [event.type]: event }), {});\n}\n\nfunction withSourceType<\n T extends EventInstance<string, unknown>,\n>(): MonoTypeOperatorFunction<T> {\n return map(({ ...event }) => {\n Object.defineProperty(event, SOURCE_TYPE, { value: event.type });\n return event;\n });\n}\n","import { inject, Injectable, Provider } from '@angular/core';\nimport { queueScheduler } from 'rxjs';\nimport { EventInstance } from './event-instance';\nimport { EventScope, EventScopeConfig } from './event-scope';\nimport { Events, EVENTS, ReducerEvents } from './events-service';\n\n/**\n * @description\n *\n * Globally provided service for dispatching events.\n *\n * @usageNotes\n *\n * ```ts\n * import { Dispatcher, event } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n *\n * \\@Component(...)\n * class Counter {\n * readonly #dispatcher = inject(Dispatcher);\n *\n * increment(): void {\n * this.#dispatcher.dispatch(increment());\n * }\n * }\n * ```\n */\n@Injectable({ providedIn: 'platform' })\nexport class Dispatcher {\n protected readonly reducerEvents = inject(ReducerEvents);\n protected readonly events = inject(Events);\n protected readonly parentDispatcher = inject(Dispatcher, {\n skipSelf: true,\n optional: true,\n });\n\n dispatch(\n event: EventInstance<string, unknown>,\n config?: EventScopeConfig\n ): void {\n if (this.parentDispatcher && hasParentOrGlobalScope(config)) {\n this.parentDispatcher.dispatch(\n event,\n config.scope === 'global' ? config : undefined\n );\n } else {\n this.reducerEvents[EVENTS].next(event);\n queueScheduler.schedule(() => this.events[EVENTS].next(event));\n }\n }\n}\n\n/**\n * @description\n *\n * Provides scoped instances of Dispatcher and Events services.\n * Enables event dispatching within a specific component or feature scope.\n *\n * @usageNotes\n *\n * ```ts\n * import { Dispatcher, event } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n *\n * \\@Component({\n * // ...\n * providers: [provideDispatcher()],\n * })\n * class Counter {\n * readonly #dispatcher = inject(Dispatcher);\n *\n * increment(): void {\n * // Dispatching an event to the local Dispatcher.\n * this.#dispatcher.dispatch(increment());\n *\n * // Dispatching an event to the parent Dispatcher.\n * this.#dispatcher.dispatch(increment(), { scope: 'parent' });\n *\n * // Dispatching an event to the global Dispatcher.\n * this.#dispatcher.dispatch(increment(), { scope: 'global' });\n * }\n * }\n * ```\n */\nexport function provideDispatcher(): Provider[] {\n return [Events, ReducerEvents, Dispatcher];\n}\n\nfunction hasParentOrGlobalScope(\n config?: EventScopeConfig\n): config is { scope: Exclude<EventScope, 'self'> } {\n return config?.scope === 'parent' || config?.scope === 'global';\n}\n","import { EventInstance } from './event-instance';\n\nexport type EventCreator<Type extends string, Payload> = ((\n payload: Payload\n) => EventInstance<Type, Payload>) & { type: Type };\n\nexport function event<Type extends string>(\n type: Type\n): EventCreator<Type, void>;\nexport function event<Type extends string, Payload>(\n type: Type,\n payload: Payload\n): EventCreator<Type, Payload>;\n/**\n * @description\n *\n * Creates an event creator.\n *\n * @usageNotes\n *\n * ### Creating an event creator without payload\n *\n * ```ts\n * import { event } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n * ```\n *\n * ### Creating an event creator with payload\n *\n * ```ts\n * import { type } from '@ngrx/signals';\n * import { event } from '@ngrx/signals/events';\n *\n * const set = event('[Counter Page] Set', type<number>());\n * ```\n */\nexport function event(type: string): EventCreator<string, any> {\n const creator = (payload?: unknown) => ({ type, payload });\n (creator as any).type = type;\n\n return creator as EventCreator<string, unknown>;\n}\n","import { Prettify } from '@ngrx/signals';\nimport { event, EventCreator } from './event-creator';\n\ntype EventType<\n Source extends string,\n EventName extends string,\n> = `[${Source}] ${EventName}`;\n\ntype EventCreatorGroup<\n Source extends string,\n Events extends Record<string, any>,\n> = {\n readonly [EventName in keyof Events]: EventName extends string\n ? EventCreator<EventType<Source, EventName>, Events[EventName]>\n : never;\n};\n\n/**\n * @description\n *\n * Creates a group of event creators.\n *\n * @usageNotes\n *\n * ```ts\n * import { type } from '@ngrx/signals';\n * import { eventGroup } from '@ngrx/signals/events';\n *\n * const counterPageEvents = eventGroup({\n * source: 'Counter Page',\n * events: {\n * increment: type<void>(),\n * decrement: type<void>(),\n * set: type<number>(),\n * },\n * });\n * ```\n */\nexport function eventGroup<\n Source extends string,\n Events extends Record<string, unknown>,\n>(config: {\n source: Source;\n events: Events;\n}): Prettify<EventCreatorGroup<Source, Events>> {\n return Object.entries(config.events).reduce(\n (acc, [eventName]) => {\n const eventType = `[${config.source}] ${eventName}`;\n return { ...acc, [eventName]: event(eventType) };\n },\n {} as EventCreatorGroup<Source, Events>\n );\n}\n","import { map, OperatorFunction } from 'rxjs';\nimport { EventInstance } from './event-instance';\n\nexport type EventScope = 'self' | 'parent' | 'global';\n\nexport type EventScopeConfig = { scope: EventScope };\n\n/**\n * @description\n *\n * Marks a single event to be dispatched in the specified scope.\n * Used in a tuple alongside an event to indicate its dispatch scope.\n *\n * @usageNotes\n *\n * ```ts\n * import { signalStore, type } from '@ngrx/signals';\n * import { event, Events, withEffects } from '@ngrx/signals/events';\n * import { mapResponse } from '@ngrx/operators';\n *\n * const opened = event('[Users Page] Opened');\n * const loadedSuccess = event('[Users API] Loaded Success', type<User[]>());\n * const loadedFailure = event('[Users API] Loaded Failure', type<string>());\n *\n * const UsersStore = signalStore(\n * withEffects((\n * _,\n * events = inject(Events),\n * usersService = inject(UsersService)\n * ) => ({\n * loadUsers$: events.on(opened).pipe(\n * exhaustMap(() =>\n * usersService.getAll().pipe(\n * mapResponse({\n * next: (users) => loadedSuccess(users),\n * error: (error: { message: string }) => [\n * loadedFailure(error.message),\n * toScope('global'),\n * ],\n * }),\n * ),\n * ),\n * ),\n * })),\n * );\n * ```\n */\nexport function toScope(scope: EventScope): EventScopeConfig {\n return { scope };\n}\n\n/**\n * @description\n *\n * RxJS operator that maps all emitted events in the stream to be dispatched\n * in the specified scope.\n *\n * @usageNotes\n *\n * ```ts\n * import { signalStore, type } from '@ngrx/signals';\n * import { event, Events, withEffects } from '@ngrx/signals/events';\n * import { mapResponse } from '@ngrx/operators';\n *\n * const opened = event('[Users Page] Opened');\n * const loadedSuccess = event('[Users API] Loaded Success', type<User[]>());\n * const loadedFailure = event('[Users API] Loaded Failure', type<string>());\n *\n * const UsersStore = signalStore(\n * withEffects((\n * _,\n * events = inject(Events),\n * usersService = inject(UsersService)\n * ) => ({\n * loadUsers$: events.on(opened).pipe(\n * exhaustMap(() =>\n * usersService.getAll().pipe(\n * mapResponse({\n * next: (users) => loadedSuccess(users),\n * error: (error: { message: string }) =>\n * loadedFailure(error.message),\n * }),\n * mapToScope('parent'),\n * ),\n * ),\n * ),\n * })),\n * );\n * ```\n */\nexport function mapToScope<T extends EventInstance<string, unknown>>(\n scope: EventScope\n): OperatorFunction<T, [T, EventScopeConfig]> {\n return map((event) => [event, toScope(scope)]);\n}\n","import {\n assertInInjectionContext,\n inject,\n Injector,\n untracked,\n} from '@angular/core';\nimport { Prettify } from '@ngrx/signals';\nimport { Dispatcher } from './dispatcher';\nimport { EventCreator } from './event-creator';\nimport { EventScope, EventScopeConfig } from './event-scope';\n\ntype SelfDispatchingEvents<\n EventGroup extends Record<string, EventCreator<string, any>>,\n> = {\n readonly [EventName in keyof EventGroup]: Parameters<\n EventGroup[EventName]\n > extends [infer Payload]\n ? (payload: Payload) => void\n : () => void;\n};\n\n/**\n * @description\n *\n * Creates self-dispatching events for a given event group.\n *\n * @usageNotes\n *\n * ```ts\n * import { type } from '@ngrx/signals';\n * import { eventGroup, injectDispatch } from '@ngrx/signals/events';\n *\n * const counterPageEvents = eventGroup({\n * source: 'Counter Page',\n * events: {\n * increment: type<void>(),\n * decrement: type<void>(),\n * },\n * });\n *\n * \\@Component(...)\n * class Counter {\n * readonly dispatch = injectDispatch(counterPageEvents);\n *\n * increment(): void {\n * this.dispatch.increment();\n * }\n *\n * decrement(): void {\n * this.dispatch.decrement();\n * }\n * }\n * ```\n */\nexport function injectDispatch<\n EventGroup extends Record<string, EventCreator<string, any>>,\n>(\n events: EventGroup,\n config?: { injector?: Injector }\n): ((config: EventScopeConfig) => Prettify<SelfDispatchingEvents<EventGroup>>) &\n Prettify<SelfDispatchingEvents<EventGroup>> {\n if (typeof ngDevMode !== 'undefined' && ngDevMode && !config?.injector) {\n assertInInjectionContext(injectDispatch);\n }\n\n const injector = config?.injector ?? inject(Injector);\n const dispatcher = injector.get(Dispatcher);\n\n const eventsCache = {} as Record<\n EventScope,\n SelfDispatchingEvents<EventGroup>\n >;\n\n const dispatch = (config: EventScopeConfig) => {\n if (!eventsCache[config.scope]) {\n eventsCache[config.scope] = Object.entries(events).reduce(\n (acc, [eventName, eventCreator]) => ({\n ...acc,\n [eventName]: (payload?: unknown) =>\n untracked(() => dispatcher.dispatch(eventCreator(payload), config)),\n }),\n {} as SelfDispatchingEvents<EventGroup>\n );\n }\n\n return eventsCache[config.scope];\n };\n\n const defaultEventGroup = dispatch({ scope: 'self' });\n const defaultEventGroupProps = Object.keys(defaultEventGroup).reduce(\n (acc, eventName) => ({\n ...acc,\n [eventName]: {\n value: defaultEventGroup[eventName],\n enumerable: true,\n },\n }),\n {} as PropertyDescriptorMap\n );\n Object.defineProperties(dispatch, defaultEventGroupProps);\n\n return dispatch as ReturnType<typeof injectDispatch<EventGroup>>;\n}\n","export type EventInstance<Type extends string, Payload> = {\n type: Type;\n payload: Payload;\n};\n\nexport function isEventInstance(\n value: unknown\n): value is EventInstance<string, unknown> {\n return typeof value === 'object' && value !== null && 'type' in value;\n}\n","import { inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { merge, Observable, tap } from 'rxjs';\nimport {\n EmptyFeatureResult,\n Prettify,\n signalStoreFeature,\n SignalStoreFeature,\n SignalStoreFeatureResult,\n StateSignals,\n type,\n withHooks,\n WritableStateSource,\n} from '@ngrx/signals';\nimport { Dispatcher } from './dispatcher';\nimport { isEventInstance } from './event-instance';\nimport { SOURCE_TYPE } from './events-service';\n\n/**\n * @description\n *\n * SignalStore feature for defining event handlers.\n *\n * @usageNotes\n *\n * ```ts\n * import { signalStore, withState } from '@ngrx/signals';\n * import { event, Events, withEventHandlers } from '@ngrx/signals/events';\n *\n * const increment = event('[Counter Page] Increment');\n * const decrement = event('[Counter Page] Decrement');\n *\n * const CounterStore = signalStore(\n * withState({ count: 0 }),\n * withEventHandlers(({ count }, events = inject(Events)) => ({\n * logCount$: events.on(increment, decrement).pipe(\n * tap(({ type }) => console.log(type, count())),\n * ),\n * })),\n * );\n * ```\n */\nexport function withEventHandlers<Input extends SignalStoreFeatureResult>(\n handlersFactory: (\n store: Prettify<\n StateSignals<Input['state']> &\n Input['props'] &\n Input['methods'] &\n WritableStateSource<Prettify<Input['state']>>\n >\n ) => Record<string, Observable<unknown>> | Observable<unknown>[]\n): SignalStoreFeature<Input, EmptyFeatureResult> {\n return signalStoreFeature(\n type<Input>(),\n withHooks({\n onInit(store, dispatcher = inject(Dispatcher)) {\n const handlerSources = handlersFactory(store);\n const handlers = Object.values(handlerSources).map((handlerSource$) =>\n handlerSource$.pipe(\n tap((result) => {\n const [potentialEvent, config] = Array.isArray(result)\n ? result\n : [result];\n\n if (\n isEventInstance(potentialEvent) &&\n !(SOURCE_TYPE in potentialEvent)\n ) {\n dispatcher.dispatch(potentialEvent, config);\n }\n })\n )\n );\n\n merge(...handlers)\n .pipe(takeUntilDestroyed())\n .subscribe();\n },\n })\n );\n}\n","import { inject, untracked } from '@angular/core';\nimport { tap } from 'rxjs';\nimport {\n EmptyFeatureResult,\n getState,\n patchState,\n SignalStoreFeature,\n signalStoreFeature,\n type,\n} from '@ngrx/signals';\nimport { CaseReducerResult } from './case-reducer';\nimport { EventCreator } from './event-creator';\nimport { ReducerEvents } from './events-service';\nimport { withEventHandlers } from './with-event-handlers';\n\n/**\n * @description\n *\n * SignalStore feature for defining state transitions based on dispatched events.\n *\n * @usageNotes\n *\n * ```ts\n * import { signalStore, type, withState } from '@ngrx/signals';\n * import { event, on, withReducer } from '@ngrx/signals/events';\n *\n * const set = event('[Counter Page] Set', type<number>());\n *\n * const CounterStore = signalStore(\n * withState({ count: 0 }),\n * withReducer(\n * on(set, ({ payload }) => ({ count: payload })),\n * ),\n * );\n * ```\n */\nexport function withReducer<State extends object>(\n ...caseReducers: CaseReducerResult<State, EventCreator<string, any>[]>[]\n): SignalStoreFeature<\n { state: State; props: {}; methods: {} },\n EmptyFeatureResult\n> {\n return signalStoreFeature(\n { state: type<State>() },\n withEventHandlers((store, events = inject(ReducerEvents)) =>\n caseReducers.map((caseReducer) =>\n events.on(...caseReducer.events).pipe(\n tap((event) => {\n const state = untracked(() => getState(store));\n const result = caseReducer.reducer(event, state);\n const updaters = Array.isArray(result) ? result : [result];\n\n patchState(store, ...updaters);\n })\n )\n )\n )\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
import { assertInInjectionContext, inject, Injector, DestroyRef, effect, untracked } from '@angular/core';
|
|
2
2
|
import { Subject, noop, isObservable } from 'rxjs';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
*
|
|
7
|
+
* Creates a reactive method for managing side effects by utilizing RxJS APIs.
|
|
8
|
+
* The method accepts an observable, a signal, a computation function, or
|
|
9
|
+
* a static value.
|
|
10
|
+
*
|
|
11
|
+
* @usageNotes
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { Component, inject, signal } from '@angular/core';
|
|
15
|
+
* import { switchMap } from 'rxjs';
|
|
16
|
+
* import { rxMethod } from '@ngrx/signals/rxjs-interop';
|
|
17
|
+
* import { tapResponse } from '@ngrx/operators';
|
|
18
|
+
*
|
|
19
|
+
* \@Component(...)
|
|
20
|
+
* export class TodoList {
|
|
21
|
+
* readonly #todosService = inject(TodosService);
|
|
22
|
+
* readonly userId = signal(1);
|
|
23
|
+
* readonly todos = signal<Todo[]>([]);
|
|
24
|
+
*
|
|
25
|
+
* readonly loadTodos = rxMethod<number>(
|
|
26
|
+
* switchMap((id) =>
|
|
27
|
+
* this.#todosService.getByUserId(id).pipe(
|
|
28
|
+
* tapResponse({
|
|
29
|
+
* next: (todos) => this.todos.set(todos),
|
|
30
|
+
* error: console.error,
|
|
31
|
+
* })
|
|
32
|
+
* )
|
|
33
|
+
* )
|
|
34
|
+
* );
|
|
35
|
+
*
|
|
36
|
+
* constructor() {
|
|
37
|
+
* // 👇 Load todos on `userId` changes.
|
|
38
|
+
* this.loadTodos(this.userId);
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
4
43
|
function rxMethod(generator, config) {
|
|
5
44
|
if (typeof ngDevMode !== 'undefined' && ngDevMode && !config?.injector) {
|
|
6
45
|
assertInInjectionContext(rxMethod);
|
|
@@ -19,7 +58,7 @@ function rxMethod(generator, config) {
|
|
|
19
58
|
ngDevMode &&
|
|
20
59
|
config?.injector === undefined &&
|
|
21
60
|
callerInjector === undefined) {
|
|
22
|
-
console.warn('@ngrx/signals/rxjs-interop:
|
|
61
|
+
console.warn('@ngrx/signals/rxjs-interop: Calling a reactive method outside of', 'an injection context with a signal or observable is deprecated.', 'In a future version, this will throw an error.', 'Either call it within an injection context', '(e.g. in a constructor or field initializer) or pass an injector', 'explicitly via the config parameter.\n\nFor more information, see:', 'https://ngrx.io/guide/signals/rxjs-integration#reactive-methods-and-injector-hierarchies');
|
|
23
62
|
}
|
|
24
63
|
const instanceInjector = config?.injector ?? callerInjector ?? sourceInjector;
|
|
25
64
|
if (typeof input === 'function') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngrx-signals-rxjs-interop.mjs","sources":["../../../../modules/signals/rxjs-interop/src/rx-method.ts","../../../../modules/signals/rxjs-interop/ngrx-signals-rxjs-interop.ts"],"sourcesContent":["import {\n assertInInjectionContext,\n DestroyRef,\n effect,\n inject,\n Injector,\n untracked,\n} from '@angular/core';\nimport { isObservable, noop, Observable, Subject } from 'rxjs';\n\ntype RxMethodRef = {\n destroy: () => void;\n};\n\nexport type RxMethod<Input> = ((\n input: Input | (() => Input) | Observable<Input>,\n config?: { injector?: Injector }\n) => RxMethodRef) &\n RxMethodRef;\n\nexport function rxMethod<Input>(\n generator: (source$: Observable<Input>) => Observable<unknown>,\n config?: { injector?: Injector }\n): RxMethod<Input> {\n if (typeof ngDevMode !== 'undefined' && ngDevMode && !config?.injector) {\n assertInInjectionContext(rxMethod);\n }\n\n const sourceInjector = config?.injector ?? inject(Injector);\n const source$ = new Subject<Input>();\n const sourceSub = generator(source$).subscribe();\n sourceInjector.get(DestroyRef).onDestroy(() => sourceSub.unsubscribe());\n\n const rxMethodFn = (\n input: Input | (() => Input) | Observable<Input>,\n config?: { injector?: Injector }\n ): RxMethodRef => {\n if (isStatic(input)) {\n source$.next(input);\n return { destroy: noop };\n }\n\n const callerInjector = getCallerInjector();\n if (\n typeof ngDevMode !== 'undefined' &&\n ngDevMode &&\n config?.injector === undefined &&\n callerInjector === undefined\n ) {\n console.warn(\n '@ngrx/signals/rxjs-interop:
|
|
1
|
+
{"version":3,"file":"ngrx-signals-rxjs-interop.mjs","sources":["../../../../modules/signals/rxjs-interop/src/rx-method.ts","../../../../modules/signals/rxjs-interop/ngrx-signals-rxjs-interop.ts"],"sourcesContent":["import {\n assertInInjectionContext,\n DestroyRef,\n effect,\n inject,\n Injector,\n untracked,\n} from '@angular/core';\nimport { isObservable, noop, Observable, Subject } from 'rxjs';\n\ntype RxMethodRef = {\n destroy: () => void;\n};\n\nexport type RxMethod<Input> = ((\n input: Input | (() => Input) | Observable<Input>,\n config?: { injector?: Injector }\n) => RxMethodRef) &\n RxMethodRef;\n\n/**\n * @description\n *\n * Creates a reactive method for managing side effects by utilizing RxJS APIs.\n * The method accepts an observable, a signal, a computation function, or\n * a static value.\n *\n * @usageNotes\n *\n * ```ts\n * import { Component, inject, signal } from '@angular/core';\n * import { switchMap } from 'rxjs';\n * import { rxMethod } from '@ngrx/signals/rxjs-interop';\n * import { tapResponse } from '@ngrx/operators';\n *\n * \\@Component(...)\n * export class TodoList {\n * readonly #todosService = inject(TodosService);\n * readonly userId = signal(1);\n * readonly todos = signal<Todo[]>([]);\n *\n * readonly loadTodos = rxMethod<number>(\n * switchMap((id) =>\n * this.#todosService.getByUserId(id).pipe(\n * tapResponse({\n * next: (todos) => this.todos.set(todos),\n * error: console.error,\n * })\n * )\n * )\n * );\n *\n * constructor() {\n * // 👇 Load todos on `userId` changes.\n * this.loadTodos(this.userId);\n * }\n * }\n * ```\n */\nexport function rxMethod<Input>(\n generator: (source$: Observable<Input>) => Observable<unknown>,\n config?: { injector?: Injector }\n): RxMethod<Input> {\n if (typeof ngDevMode !== 'undefined' && ngDevMode && !config?.injector) {\n assertInInjectionContext(rxMethod);\n }\n\n const sourceInjector = config?.injector ?? inject(Injector);\n const source$ = new Subject<Input>();\n const sourceSub = generator(source$).subscribe();\n sourceInjector.get(DestroyRef).onDestroy(() => sourceSub.unsubscribe());\n\n const rxMethodFn = (\n input: Input | (() => Input) | Observable<Input>,\n config?: { injector?: Injector }\n ): RxMethodRef => {\n if (isStatic(input)) {\n source$.next(input);\n return { destroy: noop };\n }\n\n const callerInjector = getCallerInjector();\n\n if (\n typeof ngDevMode !== 'undefined' &&\n ngDevMode &&\n config?.injector === undefined &&\n callerInjector === undefined\n ) {\n console.warn(\n '@ngrx/signals/rxjs-interop: Calling a reactive method outside of',\n 'an injection context with a signal or observable is deprecated.',\n 'In a future version, this will throw an error.',\n 'Either call it within an injection context',\n '(e.g. in a constructor or field initializer) or pass an injector',\n 'explicitly via the config parameter.\\n\\nFor more information, see:',\n 'https://ngrx.io/guide/signals/rxjs-integration#reactive-methods-and-injector-hierarchies'\n );\n }\n\n const instanceInjector =\n config?.injector ?? callerInjector ?? sourceInjector;\n\n if (typeof input === 'function') {\n const watcher = effect(\n () => {\n const value = input();\n untracked(() => source$.next(value));\n },\n { injector: instanceInjector }\n );\n sourceSub.add({ unsubscribe: () => watcher.destroy() });\n\n return watcher;\n }\n\n const instanceSub = input.subscribe((value) => source$.next(value));\n sourceSub.add(instanceSub);\n\n if (instanceInjector !== sourceInjector) {\n instanceInjector\n .get(DestroyRef)\n .onDestroy(() => instanceSub.unsubscribe());\n }\n\n return { destroy: () => instanceSub.unsubscribe() };\n };\n rxMethodFn.destroy = sourceSub.unsubscribe.bind(sourceSub);\n\n return rxMethodFn;\n}\n\nfunction isStatic<T>(value: T | (() => T) | Observable<T>): value is T {\n return typeof value !== 'function' && !isObservable(value);\n}\n\nfunction getCallerInjector(): Injector | undefined {\n try {\n return inject(Injector);\n } catch {\n return undefined;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
import { isWritableStateSource } from '@ngrx/signals';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
*
|
|
6
|
+
* Allows updating the protected state of a SignalStore for testing purposes.
|
|
7
|
+
*
|
|
8
|
+
* @usageNotes
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { TestBed } from '@angular/core/testing';
|
|
12
|
+
* import {
|
|
13
|
+
* patchState,
|
|
14
|
+
* signalStore,
|
|
15
|
+
* withState,
|
|
16
|
+
* withComputed,
|
|
17
|
+
* } from '@ngrx/signals';
|
|
18
|
+
* import { unprotected } from '@ngrx/signals/testing';
|
|
19
|
+
*
|
|
20
|
+
* const UserStore = signalStore(
|
|
21
|
+
* { providedIn: 'root' },
|
|
22
|
+
* withState({ firstName: 'Eric', lastName: 'Clapton' }),
|
|
23
|
+
* withComputed(({ firstName, lastName }) => ({
|
|
24
|
+
* fullName: () => `${firstName()} ${lastName()}`,
|
|
25
|
+
* }))
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* describe('UserStore', () => {
|
|
29
|
+
* it('recomputes fullName on firstName changes', () => {
|
|
30
|
+
* const userStore = TestBed.inject(UserStore);
|
|
31
|
+
*
|
|
32
|
+
* patchState(unprotected(userStore), { firstName: 'Patrick' });
|
|
33
|
+
* expect(userStore.fullName()).toBe('Patrick Clapton');
|
|
34
|
+
* });
|
|
35
|
+
* });
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
3
38
|
function unprotected(source) {
|
|
4
39
|
if (isWritableStateSource(source)) {
|
|
5
40
|
return source;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngrx-signals-testing.mjs","sources":["../../../../modules/signals/testing/src/unprotected.ts","../../../../modules/signals/testing/ngrx-signals-testing.ts"],"sourcesContent":["import {\n isWritableStateSource,\n Prettify,\n StateSource,\n WritableStateSource,\n} from '@ngrx/signals';\n\ntype UnprotectedSource<Source extends StateSource<object>> =\n Source extends StateSource<infer State>\n ? Prettify<\n Omit<Source, keyof StateSource<State>> & WritableStateSource<State>\n >\n : never;\n\nexport function unprotected<Source extends StateSource<object>>(\n source: Source\n): UnprotectedSource<Source> {\n if (isWritableStateSource(source)) {\n return source as UnprotectedSource<Source>;\n }\n\n throw new Error('@ngrx/signals: The provided source is not writable.');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"ngrx-signals-testing.mjs","sources":["../../../../modules/signals/testing/src/unprotected.ts","../../../../modules/signals/testing/ngrx-signals-testing.ts"],"sourcesContent":["import {\n isWritableStateSource,\n Prettify,\n StateSource,\n WritableStateSource,\n} from '@ngrx/signals';\n\ntype UnprotectedSource<Source extends StateSource<object>> =\n Source extends StateSource<infer State>\n ? Prettify<\n Omit<Source, keyof StateSource<State>> & WritableStateSource<State>\n >\n : never;\n\n/**\n * @description\n *\n * Allows updating the protected state of a SignalStore for testing purposes.\n *\n * @usageNotes\n *\n * ```ts\n * import { TestBed } from '@angular/core/testing';\n * import {\n * patchState,\n * signalStore,\n * withState,\n * withComputed,\n * } from '@ngrx/signals';\n * import { unprotected } from '@ngrx/signals/testing';\n *\n * const UserStore = signalStore(\n * { providedIn: 'root' },\n * withState({ firstName: 'Eric', lastName: 'Clapton' }),\n * withComputed(({ firstName, lastName }) => ({\n * fullName: () => `${firstName()} ${lastName()}`,\n * }))\n * );\n *\n * describe('UserStore', () => {\n * it('recomputes fullName on firstName changes', () => {\n * const userStore = TestBed.inject(UserStore);\n *\n * patchState(unprotected(userStore), { firstName: 'Patrick' });\n * expect(userStore.fullName()).toBe('Patrick Clapton');\n * });\n * });\n * ```\n */\nexport function unprotected<Source extends StateSource<object>>(\n source: Source\n): UnprotectedSource<Source> {\n if (isWritableStateSource(source)) {\n return source as UnprotectedSource<Source>;\n }\n\n throw new Error('@ngrx/signals: The provided source is not writable.');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;AAcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCG;AACG,SAAU,WAAW,CACzB,MAAc,EAAA;AAEd,IAAA,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE;AACjC,QAAA,OAAO,MAAmC;IAC5C;AAEA,IAAA,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC;AACxE;;ACzDA;;AAEG;;;;"}
|