import * as i0 from '@angular/core'; import { InjectionToken, Provider, Signal } from '@angular/core'; import { AccumulationFn, PickSlice, KeyCompareMap } from '@rx-angular/state/selections'; import * as rxjs from 'rxjs'; import { SchedulerLike, Subscribable, Observable, OperatorFunction, Unsubscribable } from 'rxjs'; type RX_STATE_CONFIGS = 'Accumulator' | 'Scheduler'; interface RxStateConfigFn { kind: RX_STATE_CONFIGS; providers: Provider[]; } /** * Injection token for the default accumulator function. * * @example * providers: [ * { * provide: RX_ACCUMULATOR_FN, * useValue: (state, slice) => ({ ...state, ...slice }) * } * ] */ declare const RX_ACCUMULATOR_FN: InjectionToken; /** * Provider function to specify a custom `AccumulationFn` for `RxState` to use. * @param fn */ declare function withAccumulatorFn(fn: AccumulationFn): RxStateConfigFn; /** * Injection token for the default state scheduler * * @example * providers: [ * { * provide: RX_STATE_SCHEDULER, * useValue: asapScheduler * } * ] */ declare const RX_STATE_SCHEDULER: InjectionToken; /** * Provider function to specify a scheduler for `RxState` to perform state updates & emit new values. * @param scheduler */ declare function withScheduler(scheduler: SchedulerLike | 'sync'): RxStateConfigFn; /** * Provider function to specify synchronous (no) scheduling for `RxState`. The state computations * will be fully synchronous instead of using the default `queueScheduler` */ declare function withSyncScheduler(): RxStateConfigFn; /** * This function is used to provide the configuration for the rxState function. * * You can provide multiple configurations at once. * * You can use these functions to provide the configuration: * - withAccumulatorFn - to provide a custom accumulator function * - withScheduler - to provide a custom scheduler * */ declare function provideRxStateConfig(...configs: RxStateConfigFn[]): Provider[]; type SignalStateProxy = { [K in keyof State]: Signal; }; type ProjectStateFn = (oldState: Type) => Partial; type ProjectValueFn = (oldState: Type) => Type[Key]; type ProjectStateReducer = (oldState: Type, value: Value) => Partial; type ProjectValueReducer = (oldState: Type, value: Value) => Type[Key]; type ReadOnly = 'get' | 'select' | 'computed' | 'signal'; /** * @description * RxState is a light-weight reactive state management service for managing local state in angular. * * @example * Component({ * selector: 'app-stateful', * template: `
{{ state$ | async | json }}
`, * providers: [RxState] * }) * export class StatefulComponent { * readonly state$ = this.state.select(); * * constructor(private state: RxState<{ foo: string }>) {} * } * * @docsCategory RxState * @docsPage RxState */ declare class RxState$1 implements Subscribable { private subscription; protected scheduler: rxjs.SchedulerLike | "sync" | null; private accumulator; private effectObservable; private readonly injector; private signalStoreProxy; /** * @description * The unmodified state exposed as `Observable`. It is not shared, distinct or gets replayed. * Use the `$` property if you want to read the state without having applied {@link stateful} to it. */ readonly $: Observable; /** * @internal */ constructor(); /** * @description * * Return RxState in ReadOnly mode exposing only methods for reading state * get(), select(), computed() and signal() methods. * This can be helpful when you don't want others to write in your state. * * @example * ```typescript * const readOnlyState = state.asReadOnly(); * const getNum = state.get('num'); * const selectNum$ = state.select('num'); * ``` * * @return Pick, ReadOnly> */ asReadOnly(): Pick, ReadOnly>; /** * @description * * Allows to customize state accumulation function. * This can be helpful to implement deep updates and tackle other immutability problems in a custom way. * @example * * ```typescript * const myAccumulator = (state: MyState, slice: Partial) => deepCopy(state, slice); * * this.state.setAccumulator(myAccumulator); * ``` * * @param {AccumulationFn} accumulatorFn * @return void * * @deprecated * Use `provideRxStateConfig` and provide the accumulator with the `withAccumulator` provider function. * Will be removed in future versions. */ setAccumulator(accumulatorFn: AccumulationFn): void; /** * @description * Read from the state in imperative manner. Returns the state object in its current state. * * @example * const { disabled } = state.get(); * if (!disabled) { * doStuff(); * } * * @return State */ get(): State; /** * @description * Read from the state in imperative manner by providing keys as parameters. * Returns the part of state object. * * @example * // Access a single property * const bar = state.get('bar'); * * // Access a nested property * const foo = state.get('bar', 'foo'); * * @param {KeyA} keyA * @return State[KeyA] */ get(keyA: KeyA): State[KeyA]; /** @internal **/ get(keyA: KeyA, keyB: KeyB): State[KeyA][KeyB]; /** @internal **/ get(keyA: KeyA, keyB: KeyB, keyC: KeyC): State[KeyA][KeyB][KeyC]; /** @internal **/ get(keyA: KeyA, keyB: KeyB, keyC: KeyC, keyD: KeyD): State[KeyA][KeyB][KeyC][KeyD]; /** @internal **/ get(keyA: KeyA, keyB: KeyB, keyC: KeyC, keyD: KeyD, keyE: KeyE): State[KeyA][KeyB][KeyC][KeyD][KeyE]; /** @internal **/ get(keyA: KeyA, keyB: KeyB, keyC: KeyC, keyD: KeyD, keyE: KeyE, keyF: KeyF): State[KeyA][KeyB][KeyC][KeyD][KeyE][KeyF]; /** * @description * Manipulate one or many properties of the state by providing * a `Partial`state or a `ProjectionFunction`. * * @example * // Update one or many properties of the state by providing a `Partial` * * const partialState = { * foo: 'bar', * bar: 5 * }; * state.set(partialState); * * // Update one or many properties of the state by providing a `ProjectionFunction` * * const reduceFn = oldState => ({ * bar: oldState.bar + 5 * }); * state.set(reduceFn); * * @param {Partial|ProjectStateFn} stateOrProjectState * @return void */ set(stateOrProjectState: Partial | ProjectStateFn): void; /** * @description * Manipulate a single property of the state by the property name and a `ProjectionFunction`. * * @example * const reduceFn = oldState => oldState.bar + 5; * state.set('bar', reduceFn); * * @param {Key} key * @param {ProjectValueFn} projectSlice * @return void */ set(key: Key, projectSlice: ProjectValueFn): void; /** * @description * Connect an `Observable>` to the state `State`. * Any change emitted by the source will get merged into the state. * Subscription handling is done automatically. * * @example * const sliceToAdd$ = interval(250).pipe(mapTo({ * bar: 5, * foo: 'foo' * }); * state.connect(sliceToAdd$); * // every 250ms the properties bar and foo get updated due to the emission of sliceToAdd$ * * // Additionally you can provide a `projectionFunction` to access the current state object and do custom mappings. * * const sliceToAdd$ = interval(250).pipe(mapTo({ * bar: 5, * foo: 'foo' * }); * state.connect(sliceToAdd$, (state, slice) => state.bar += slice.bar); * // every 250ms the properties bar and foo get updated due to the emission of sliceToAdd$. Bar will increase by * // 5 due to the projectionFunction * * @param {Observable>} inputOrSlice$ * @return void */ connect(inputOrSlice$: Observable>): void; /** * @description * Connect a `Signal>` to the state `State`. * Any change emitted by the source will get merged into the state. * * @example * const partialState = signal({ foo: 'foo', bar: 5 }); * state.connect(partialState); * * @param {Signal>} signal * @return void */ connect(signal: Signal>): void; /** * @description * Connect an `Observable` to the state `State`. * Any change emitted by the source will get forwarded to project function and merged into the state. * Subscription handling is done automatically. * * You have to provide a `projectionFunction` to access the current state object and do custom mappings. * * @example * const sliceToAdd$ = interval(250); * state.connect(sliceToAdd$, (type, value) => ({bar: value})); * // every 250ms the property bar get updated due to the emission of sliceToAdd$ * * @param {Observable} inputOrSlice$ * @param {ProjectStateReducer} projectFn * @return void */ connect(inputOrSlice$: Observable, projectFn: ProjectStateReducer): void; /** * @description * Connect a `Signal` to the state `State`. * Any change emitted by the source will get forwarded to the project function and merged into the state. * * You have to provide a `projectionFunction` to access the current state object and do custom mappings. * * @example * const signalSlice = signal(5); * state.connect(signalSlice, (type, value) => ({bar: value})); * * @param {Signal} signal * @param {ProjectStateReducer} projectFn * @return void */ connect(signal: Signal, projectFn: ProjectStateReducer): void; /** * * @description * Connect an `Observable` source to a specific property `Key` in the state `State`. * Any emitted change will update this specific property in the state. * Subscription handling is done automatically. * * @example * const myTimer$ = interval(250); * state.connect('timer', myTimer$); * // every 250ms the property timer will get updated * @param {Key} key * @param {Observable} slice$ * * @return void */ connect(key: Key, slice$: Observable): void; /** * * @description * Connect a `Signal` source to a specific property `Key` in the state `State`. * Any emitted change will update this specific property in the state. * * @example * const currentTime = signal(Date.now()) * state.connect('currentTime', currentTime); * * @param {Key} key * @param {Signal} signal * * @return void */ connect(key: Key, signal: Signal): void; /** * @description * Connect an `Observable` source to a specific property in the state. Additionally, you can provide a * `projectionFunction` to access the current state object on every emission of your connected `Observable`. * Any change emitted by the source will get merged into the state. * Subscription handling is done automatically. * * @example * const myTimer$ = interval(250); * state.connect('timer', myTimer$, (state, timerChange) => state.timer += timerChange); * // every 250ms the property timer will get updated * * @param {Key} key * @param {Observable} input$ * @param {ProjectValueReducer} projectSliceFn * * @return void */ connect(key: Key, input$: Observable, projectSliceFn: ProjectValueReducer): void; /** * * @description * Connect a `Signal` source to a specific property in the state. Additionally, you can provide a * `projectionFunction` to access the current state object on every emission of your connected `Observable`. * Any change emitted by the source will get merged into the state. * Subscription handling is done automatically. * * @example * const currentTime = signal(Date.now()) * state.connect('currentTime', currentTime, (state, currentTime) => state.currentTime = currentTime); * * @param {Key} key * @param {Signal} signal * @param {ProjectValueReducer} projectSliceFn * * @return void */ connect(key: Key, signal: Signal, projectSliceFn: ProjectValueReducer): void; /** * @description * Returns the state as cached and distinct `Observable`. * This way you don't have to think about * **late subscribers**, **multiple subscribers** or **multiple emissions** of the same value * * @example * const state$ = state.select(); * state$.subscribe(state => doStuff(state)); * * @returns Observable */ select(): Observable; /** * @description * Returns the state as cached and distinct `Observable`. Accepts arbitrary * [rxjs operators](https://rxjs-dev.firebaseapp.com/guide/operators) * to enrich the selection with reactive composition. * * @example * const profilePicture$ = state.select( * map((state) => state.profilePicture), * switchMap(profilePicture => mapImageAsync(profilePicture)) * ); * @param op { OperatorFunction } * @returns Observable */ select(op: OperatorFunction): Observable; /** * @internal */ select(op1: OperatorFunction, op2: OperatorFunction): Observable; /** * @internal */ select(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable; /** * @internal */ select(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction, op4: OperatorFunction): Observable; /** * @internal */ select(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction, op4: OperatorFunction, op5: OperatorFunction): Observable; /** * @description * Transform a slice of the state by providing keys and map function. * Returns result of applying function to state slice as cached and distinct `Observable`. * * @example * // Project state slice * const text$ = state.select( * ['query', 'results'], * ({ query, results }) => `${results.length} results found for "${query}"` * ); * * @param {Key[]} keys * @param {(slice: PickSlice) => Value} fn * @param {KeyCompareMap>} keyCompareMap * * @return Observable */ select(keys: Key[], fn?: (slice: PickSlice) => Value, keyCompareMap?: KeyCompareMap>): Observable; /** * @description * Transform a single property of the state by providing a key and map function. * Returns result of applying function to state property as cached and distinct `Observable`. * * @example * // Project state based on single property * const foo$ = state.select('bar', bar => `bar equals ${bar}`); * * @param {Key} key * @param {(val: Type[Key]) => Value} fn * * @return Observable */ select(key: Key, fn: (val: State[Key]) => Value): Observable; /** * @description * Access a single property of the state by providing keys. * Returns a single property of the state as cached and distinct `Observable`. * * @example * // Access a single property * * const bar$ = state.select('bar'); * * // Access a nested property * * const foo$ = state.select('bar', 'foo'); * * @return Observable */ select(keyA: KeyA): Observable; /** * @internal */ select(keyA: KeyA, keyB: KeyB): Observable; /** * @internal */ select(keyA: KeyA, keyB: KeyB, keyC: KeyC): Observable; /** * @internal */ select(keyA: KeyA, keyB: KeyB, keyC: KeyC, keyD: KeyD): Observable; /** * @internal */ select(keyA: KeyA, keyB: KeyB, keyC: KeyC, keyD: KeyD, keyE: KeyE): Observable; /** * @internal */ select(keyA: KeyA, keyB: KeyB, keyC: KeyC, keyD: KeyD, keyE: KeyE, keyF: KeyF): Observable; /** * @description * Returns a signal of the given key. It's first value is determined by the * current keys value in RxState. Whenever the key gets updated, the signal * will also be updated accordingly. * * @example * const fooSignal = state.signal('foo'); * * @param {Key} key * * @return Signal */ signal(key: Key): Signal; /** * @description * Lets you create a computed signal based off multiple keys stored in RxState. * * @example * const computedSignal = state.computed((s) => s.foo + s.bar); * * @param {(slice: SignalStateProxy) => ComputedType} fn * @return Signal */ computed(fn: (slice: SignalStateProxy) => ComputedType): Signal; /** * @description * Lets you create a computed signal derived from state and rxjs operators. * * @throws If the initial value is not provided and the signal is not sync. * Use startWith() to provide an initial value. * * @example * const computedSignal = state.computedFrom( * map(state => state.foo), * filter(foo => foo > 5) * ); * * @param op1 { OperatorFunction } * @returns Signal */ computedFrom(op1: OperatorFunction): Signal; /** @internal */ computedFrom(op1: OperatorFunction, op2: OperatorFunction): Signal; /** @internal */ computedFrom(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Signal; /** @internal */ computedFrom(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction, op4: OperatorFunction): Signal; /** @internal */ computedFrom(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction, op4: OperatorFunction, op5: OperatorFunction): Signal; /** * @description * Manages side-effects of your state. Provide an `Observable` * **side-effect** and an optional `sideEffectFunction`. * Subscription handling is done automatically. * * @example * // Directly pass an observable side-effect * const localStorageEffect$ = changes$.pipe( * tap(changes => storeChanges(changes)) * ); * state.hold(localStorageEffect$); * * // Pass an additional `sideEffectFunction` * * const localStorageEffectFn = changes => storeChanges(changes); * state.hold(changes$, localStorageEffectFn); * * @param {Observable} obsOrObsWithSideEffect * @param {function} [sideEffectFn] * * @return void */ hold(obsOrObsWithSideEffect: Observable, sideEffectFn?: (arg: SideEffect) => void): void; /** * @internal */ subscribe(): Unsubscribable; static ɵfac: i0.ɵɵFactoryDeclaration, never>; static ɵprov: i0.ɵɵInjectableDeclaration>; } type RxState = Pick, 'get' | 'select' | 'connect' | 'set' | '$' | 'setAccumulator' | 'signal' | 'computed' | 'computedFrom' | 'asReadOnly'>; type RxStateSetupFn = (rxState: Pick, 'connect' | 'set' | 'get' | 'select' | 'setAccumulator'>) => void; /** * @description * Functional way to setup state management with RxState. It's a wrapper around RxState that automatically get * destroyed. * * @example * ```ts * import { rxState } from '@rx-angular/state'; * * Component({}) * export class FooComponent { * readonly state = rxState<{ count: number }>(({ set }) => set({ count: 0 })); * } * ``` * * @param setupFn * @returns RxState instance * * * * @docsCategory RxState * @docsPage RxState * */ declare function rxState(setupFn?: RxStateSetupFn): RxState; export { RX_ACCUMULATOR_FN, RX_STATE_SCHEDULER, RxState$1 as RxState, provideRxStateConfig, rxState, withAccumulatorFn, withScheduler, withSyncScheduler }; export type { ProjectStateFn, ProjectStateReducer, ProjectValueFn, ProjectValueReducer, RxStateSetupFn }; //# sourceMappingURL=index.d.ts.map