@lithiumjs/angular
Version:
Reactive components made easy. Lithium provides utilities that enable seamless reactive state and event interactions for Angular components.
109 lines (108 loc) • 8.6 kB
TypeScript
import type { Constructable, IfEquals, IfReadonly, StringKey } from "./lang-utils";
import { AsyncSourceKey } from "./metadata";
import { EventEmitter, FactoryProvider, Injector, Type } from "@angular/core";
import { Observable, Subject, Subscription } from "rxjs";
import { CommonMetadata } from "./metadata";
declare const COMPONENT_STATE_IDENTITY: unique symbol;
export type ComponentState<ComponentT> = ComponentState.Of<ComponentT>;
type ComponentClassProvider<ComponentT> = Type<ComponentT> | Type<unknown>;
export type ManagedComponent = Constructable<any, any> & {
[CommonMetadata.MANAGED_ONDESTROY_KEY]: Observable<void>;
};
export declare class ComponentStateRef<ComponentT> extends Promise<ComponentState<ComponentT>> {
componentInstance: ComponentT & ManagedComponent;
/**
* @description Resolves the `ComponentState` instance for this reference.
* @returns An `Observable` that emits the `ComponentState` instance for this reference.
*/
state(): Observable<ComponentState<ComponentT>>;
/**
* @description Returns an `Observable` that represents the current value of the given state property and emits whenever the value of the given state
* property is changed.
* @param stateProp - The state property to observe.
* @returns An `Observable` that emits the value of the given state property and re-emits when the value is changed.
*/
get<K extends StringKey<ComponentT>>(stateProp: ComponentState.ReadableKey<ComponentT, K>): Observable<ComponentT[K]>;
/**
* @description Returns an array of `Observable`s that represents the current value for each given state property. Each `Observable` emits whenever a
* value of the corresponding given state property is changed.
* @param stateProps - The state properties to observe.
* @returns An array of `Observable`s that represents the current value for each given state property and re-emits when the corresponding value is
* changed.
*/
getAll<K extends Array<ComponentState.ReadableKey<ComponentT, StringKey<ComponentT>>>>(...stateProps: K): ComponentState.StateSelector<ComponentT, K>;
/**
* @description Returns an `EventEmitter` that emits whenever the value of the given state property is changed.
* @param stateProp - The state property to observe.
* @returns An `EventEmitter` instance that emits whenever the value of the given state property is changed.
*/
emitter<K extends StringKey<ComponentT>>(stateProp: ComponentState.ReadableKey<ComponentT, K>): EventEmitter<ComponentT[K]>;
/**
* @description Updates the value of the given state property with the given value. Equivalent to assigning to the component state property directly.
* @param stateProp - The state property to update. This property must not be readonly.
* @param value - The new value to update to.
* @returns An `Observable` that emits and completes when the value has been updated.
*/
set<K extends StringKey<ComponentT>, V extends ComponentT[K]>(stateProp: ComponentState.WritableKey<ComponentT, K>, value: V): Observable<void>;
/**
* @description Subscribes the given state property to the given source `Observable`. If `managed` is set to true, the lifetime of the subscription will
* be managed and cleaned up when the component is destroyed.
* @param stateProp - The state property to receive source updates. This property must not be readonly.
* @param source$ - The source `Observable` to subscribe to.
* @param managed - Whether or not the subscription lifetime should be managed. Defaults to `true`.
* @returns A `Subscription` representing the subscription to the source.
*/
subscribeTo<K extends StringKey<ComponentT>, V extends ComponentT[K]>(stateProp: ComponentState.WritableKey<ComponentT, K>, source$: Observable<V>, managed?: boolean): Subscription;
/**
* @description Synchronizes the values of the given state properties such that any changes from one state property will be propagated to the
* other state property. The initial value of the first given state property is used.
* @param statePropA - The first state property to synchronize. This property must not be readonly.
* @param statePropB - The second state property to synchronize. This property must not be readonly.
*/
sync<K1 extends StringKey<ComponentT>, K2 extends StringKey<ComponentT>, V extends IfEquals<ComponentT[K1], ComponentT[K2]> extends true ? ComponentT[K1] & ComponentT[K2] : never>(statePropA: V extends never ? never : ComponentState.WritableKey<ComponentT, K1>, statePropB: V extends never ? never : ComponentState.WritableKey<ComponentT, K2>): void;
/**
* @description Synchronizes the values of the given state property and source `Subject` such that any changes from the state property will be
* propagated to the source `Subject` and vice versa. The initial value of the source `Subject` is used.
* @param stateProp - The state property to synchronize. This property must not be readonly.
* @param source$ - The source `Subject` to synchronize with.
*/
syncWith<K extends StringKey<ComponentT>>(stateProp: ComponentState.WritableKey<ComponentT, K>, source$: Subject<ComponentT[K]>): void;
/**
* @description Synchronizes the state of `stateProp` and `sourceProp`, a property from another `ComponentStateRef`, such that any changes from
* `stateProp` will be propagated to `sourceProp` and vice versa. The initial state value of `sourceProp` is used.
* @param stateProp - The state property to synchronize. This property must not be readonly.
* @param sourceState - The source `ComponentStateRef` instance.
* @param sourceProp - The source state property from `sourceState` to synchronize with. This property must not be readonly.
*/
syncWith<ComponentT2, K1 extends StringKey<ComponentT>, K2 extends StringKey<ComponentT2>, V extends IfEquals<ComponentT[K1], ComponentT2[K2]> extends true ? ComponentT[K1] & ComponentT2[K2] : never>(stateProp: V extends never ? never : ComponentState.WritableKey<ComponentT, K1>, sourceState: ComponentStateRef<ComponentT2>, sourceProp: V extends never ? never : ComponentState.WritableKey<ComponentT2, K2>): void;
private get resolvedState();
}
export declare namespace ComponentState {
export interface CreateOptions {
lazy?: boolean;
}
export type ReactiveStateKey<ComponentT, K extends keyof ComponentT = keyof ComponentT> = K extends string ? AsyncSourceKey<ComponentT, K> : never;
type QualifiedStateKey<ComponentT, K extends keyof ComponentT = keyof ComponentT> = K extends `${infer _K}$` ? never : K;
export type StateKey<ComponentT> = keyof {
[K in keyof ComponentT as QualifiedStateKey<ComponentT, K>]: never;
};
export type Of<ComponentT> = {
readonly [K in keyof ComponentT as ReactiveStateKey<ComponentT, QualifiedStateKey<ComponentT, K>>]-?: IfReadonly<ComponentT, K> extends true ? Observable<ComponentT[K]> : Subject<ComponentT[K]>;
};
export type ReadableKey<ComponentT, K extends keyof ComponentT = keyof ComponentT> = K extends StateKey<ComponentT> ? K : never;
export type WritableKey<ComponentT, K extends keyof ComponentT = keyof ComponentT> = IfReadonly<ComponentT, K> extends true ? never : ReadableKey<ComponentT, K>;
export type StateSelector<ComponentT, K extends Array<ReadableKey<ComponentT>>> = {
[I in keyof K]: K[I] extends ReadableKey<ComponentT> ? Observable<ComponentT[K[I]]> : never;
};
export function create<ComponentT>($class: ComponentClassProvider<ComponentT>, options?: CreateOptions): FactoryProvider;
export function createFactory<ComponentT>($class: ComponentClassProvider<ComponentT>, options?: CreateOptions): (injector: Injector) => ComponentStateRef<ComponentT>;
export function tokenFor(provider: FactoryProvider): any;
export function stateKey<ComponentT, K extends StringKey<ComponentT> = StringKey<ComponentT>>(key: K): ReactiveStateKey<ComponentT, K> & keyof Of<ComponentT>;
export {};
}
export declare function createComponentState<ComponentT>($class: ComponentClassProvider<ComponentT>, options?: ComponentState.CreateOptions): FactoryProvider;
export declare function stateTokenFor(provider: FactoryProvider): any;
export declare function _requireComponentState<T extends {
[COMPONENT_STATE_IDENTITY]?: Partial<ComponentState<T>>;
} & Record<any, any>>(instance: T, initValue?: Partial<ComponentState<T>>): Partial<ComponentState<T>>;
export {};