import { Observable, PartialObserver, Subscription, BehaviorSubject, Subject } from 'rxjs'; import { MutableRefObject, RefObject } from 'react'; /** * Accepts a function that returns an Observable. * Optionally accepts an array of dependencies which * will be turned into Observable and be passed to the * `init` function. * * React functional components are called many times during their lifecycle. * Create or transform Observables in `init` function so that the operations * won't be repeatedly performed. * * ⚠ **Note:** `useObservable` will call `init` once and always return * the same Observable. It is not safe to access closure (except other Observables) * directly inside `init`. * You should use ref or pass them as dependencies through the second argument. * * ⚠ **Note:** Due to rules of hooks you can either offer or omit the * dependencies array but do not change to one another during Component's life cycle. * The length of the dependencies array must also be fixed. * * @template TOutput Output value in Observable * * @param init A pure function that, when applied to an Observable, * returns an Observable. */ declare function useObservable = Observable>(init: () => TObservable): TObservable; /** * @template TOutput Output value within Observable. * @template TInputs A readonly tuple of all dependencies. * * @param init A pure function that, when applied to an Observable, * returns an Observable. * @param inputs An dependency array with fixed length. When one of the dependencies * changes the Observable in `init` will emit an array of all the dependencies. */ declare function useObservable, TObservable extends Observable = Observable>(init: (inputs$: Observable<[...TInputs]>) => TObservable, inputs: [...TInputs]): TObservable; /** * Same as [[useObservable]] excepts using `useLayoutEffect`. * * Accepts a function that returns an Observable. * Optionally accepts an array of dependencies which * will be turned into Observable and be passed to the * `init` function. * * React functional components are called many times during their lifecycle. * Create or transform Observables in `init` function so that the operations * won't be repeatedly performed. * * ⚠ **Note:** `useLayoutObservable` will call `init` once and always return * the same Observable. It is not safe to access closure (except other Observables) * directly inside `init`. * You should use ref or pass them as dependencies through the second argument. * * ⚠ **Note:** Due to rules of hooks you can either offer or omit the * dependencies array but do not change to one another during Component's life cycle. * The length of the dependencies array must also be fixed. * * @template TOutput Output value in Observable * * @param init A pure function that, when applied to an Observable, * returns an Observable. */ declare function useLayoutObservable(init: () => Observable): Observable; /** * @template TOutput Output value within Observable. * @template TInputs A readonly tuple of all dependencies. * * @param init A pure function that, when applied to an Observable, * returns an Observable. * @param inputs An dependency array with fixed length. When one of the dependencies * changes the Observable in `init` will emit an array of all the dependencies. */ declare function useLayoutObservable>(init: (inputs$: Observable<[...TInputs]>) => Observable, inputs: [...TInputs]): Observable; /** * Returns a callback function and an events Observable. * * When the callback is called, the Observable will * emit the first argument of the callback. * * @template TEvent Output value of Observable. */ declare function useObservableCallback(): [ (event: TEvent) => void, Observable ]; /** * Returns a callback function and an events Observable. * * When the callback is called, the Observable will * emit the first argument of the callback. * * ⚠ **Note:** `useObservableCallback` will call `init` once and always return * the same Observable. It is not safe to access closure (except other Observables) * directly inside `init`. Use ref or [[useObservable]] with `withLatestFrom` instead. * * @template TOutput Output value within Observable. * @template TInput Selected values. * * @param init A pure function that, when applied to an Observable, * returns an Observable. */ declare function useObservableCallback(init: (events$: Observable) => Observable): [(event: TInput) => void, Observable]; /** * Returns a callback function and an events Observable. * * When the callback is called, the Observable will * emit the first argument of the callback. * * (From v2.1.0) Optionally accepts a selector function that transforms * a list of event arguments into a single value. * * ⚠ **Note:** `useObservableCallback` will call `init` once and always return * the same Observable. It is not safe to access closure (except other Observables) * directly inside `init`. Use ref or [[useObservable]] with `withLatestFrom` instead. * * @template TOutput Output value within Observable. * @template TInput Selected values. * @template TParams A tuple of event callback parameters. * * @param init A pure function that, when applied to an Observable, * returns an Observable. * @param selector A function that transforms an array of event arguments * into a single value. */ declare function useObservableCallback = [TInput]>(init: (events$: Observable) => Observable, selector: (args: TParams) => TInput): [(...args: TParams) => void, Observable]; /** * Accepts an Observable and optional `next`, `error`, `complete` functions. * These functions must be in correct order. * Use `undefined` or `null` for placeholder. * * Subscription will unsubscribe when unmount, you can also * unsubscribe manually. * * ⚠ **Note:** To make it concurrent mode compatible, the subscription happens * after the render is committed to the screen * which means even the Observable emits synchronous values * they will arrive after the first rendering. * * Note that changes of callbacks will not trigger * an emission. If you need that just create another * Observable of the callback with [[useObservable]]. * * (From v2.0) You can access closure directly inside callback like in `useEffect`. * `useSubscription` will ensure the latest callback is called. * * (From v2.3.4) when the Observable changes `useSubscription` will automatically * unsubscribe the old one and resubscribe to the new one. * * ⚠ **Note:** Due to the design of RxJS, once an error occurs in an observable, the observable * is killed. * You should prevent errors from reaching observables or `catchError` in sub-observables. * You can also make the observable as state and replace it on error. * `useSubscription` will automatically switch to the new one. * * @template TInput Input value within Observable. * * @param input$ Input Observable. * @param observer Observer */ declare function useSubscription(input$: Observable, observer?: PartialObserver): MutableRefObject; /** * @template TInput Input value within Observable. * * @param input$ Input Observable. * @param next Notify when a new value is emitted. * @param error Notify when a new error is thrown. * @param complete Notify when the Observable is complete. */ declare function useSubscription(input$: Observable, next?: ((value: TInput) => void) | null | undefined, error?: ((error: any) => void) | null | undefined, complete?: (() => void) | null | undefined): MutableRefObject; /** * Same as [[useSubscription]] except the subscription is established * under `useLayoutEffect`. * * Useful when values are needed before DOM paint. * * Use it scarcely as it runs synchronously before browser paint. * Too many synchronous emissions from the observable could * stretch the commit phase. * * @template TInput Input value within Observable. * * @param input$ Input Observable. * @param observer Observer */ declare function useLayoutSubscription(input$: Observable, observer?: PartialObserver): MutableRefObject; /** * @template TInput Input value within Observable. * * @param input$ Input Observable. * @param next Notify when a new value is emitted. * @param error Notify when a new error is thrown. * @param complete Notify when the Observable is complete. */ declare function useLayoutSubscription(input$: Observable, next?: ((value: TInput) => void) | null | undefined, error?: ((error: any) => void) | null | undefined, complete?: (() => void) | null | undefined): MutableRefObject; /** * Enhance an Observable by making errors catch-able to ErrorBoundary. * * It catches Observable error and re-throw it as React render error. * * @template TInput Input value within Observable. * * @param input$ Input Observable. * @returns Observable with the same input type */ declare function useRenderThrow(input$: Observable): Observable; /** * A sugar hook for getting values from an Observable. * * It can be used in two ways: * * 1. Offer an Observable and an optional initial state. * ```js * const output = useObservableState(input$, initialState) * ``` * 2. Offer an epic-like function and an optional initial state. * ```js * const [output, onInput] = useObservableState( * (input$, initialState) => input$.pipe(...), * initialState * ) * ``` * * The optional `initialState` is internally passed to `useState(initialState)`. * This means it can be either a state value or a function that returns the state * which is for expensive initialization. * * The `initialState`(or its returned result) is also passed to the `init` function. * This is useful if you want to implement reducer pattern which requires an initial state. * * ⚠ **Note:** These two ways use different hooks, choose either one each time * and do not change to the other one during Component's life cycle. * * ⚠ **Note:** `useObservableState` will call the epic-like `init` function only once * and always return the same Observable. * It is not safe to access closure directly inside `init`. * Use [[useObservable]] with `withLatestFrom` instead. * * ⚠ **Note:** To make it concurrent mode compatible, the subscription happens * after the render is committed to the screen which means even the Observable emits synchronous values * they will arrive after the first rendering. * * @template TState Output state. * * @param input$ A BehaviorSubject. */ declare function useObservableState(input$: BehaviorSubject): TState; /** * @template TState Output state. * * @param input$ An Observable. */ declare function useObservableState(input$: Observable): TState | undefined; /** * @template TState Output state. * * @param input$ An Observable. * @param initialState Optional initial state. * Can be the state value or a function that returns the state. */ declare function useObservableState(input$: Observable, initialState: TState | (() => TState)): TState; /** * @template TState Output state. * @template TInput Input values. * * @param init A epic-like function that, when applied to an Observable * and the initial state value, returns an Observable. */ declare function useObservableState(init: (input$: Observable) => Observable): [TState | undefined, (input: TInput) => void]; /** * Different input output types with initial state. * * @template TState Output state. * @template TInput Input values. * * @param init A epic-like function that, when applied to an Observable * and the initial state value, returns an Observable. * @param initialState Optional initial state. * Can be the state value or a function that returns the state. */ declare function useObservableState(init: (input$: Observable, initialState: TState) => Observable, initialState: TState | (() => TState)): [TState, (input: TInput) => void]; /** * Same as [[useObservableState]] except the subscription is established * under `useLayoutEffect`. * * A sugar hook for getting values from an Observable. * * It can be used in two ways: * * 1. Offer an Observable and an optional initial state. * ```js * const output = useLayoutObservableState(input$, initialState) * ``` * 2. Offer an epic-like function and an optional initial state. * ```js * const [output, onInput] = useLayoutObservableState( * (input$, initialState) => input$.pipe(...), * initialState * ) * ``` * * The optional `initialState` is internally passed to `useState(initialState)`. * This means it can be either a state value or a function that returns the state * which is for expensive initialization. * * The `initialState`(or its returned result) is also passed to the `init` function. * This is useful if you want to implement reduer pattern which requires an initial state. * * ⚠ **Note:** These two ways use different hooks, choose either one each time * and do not change to the other one during Component's life cycle. * * ⚠ **Note:** `useLayoutObservableState` will call the epic-like `init` function only once * and always return the same Observable. * It is not safe to access closure directly inside `init`. * Use [[useObservable]] with `withLatestFrom` instead. * * ⚠ **Note:** To make it concurrent mode compatible, the subscription happens * after the render is committed to the screen which means even the Observable emits synchronous values * they will arrive after the first rendering. * * @template TState Output state. * * @param input$ A BehaviorSubject. */ declare function useLayoutObservableState(input$: BehaviorSubject): TState; /** * @template TState Output state. * * @param input$ An Observable. */ declare function useLayoutObservableState(input$: Observable): TState | undefined; /** * @template TState Output state. * * @param input$ An Observable. * @param initialState Optional initial state. * Can be the state value or a function that returns the state. */ declare function useLayoutObservableState(input$: Observable, initialState: TState | (() => TState)): TState; /** * @template TState Output state. * @template TInput Input values. * * @param init A epic-like function that, when applied to an Observable * and the initial state value, returns an Observable. */ declare function useLayoutObservableState(init: (input$: Observable) => Observable): [TState | undefined, (input: TInput) => void]; /** * Different input output types with initial state. * * @template TState Output state. * @template TInput Input values. * * @param init A epic-like function that, when applied to an Observable * and the initial state value, returns an Observable. * @param initialState Optional initial state. * Can be the state value or a function that returns the state. */ declare function useLayoutObservableState(init: (input$: Observable, initialState: TState) => Observable, initialState: TState | (() => TState)): [TState, (input: TInput) => void]; /** * Optimized for safely getting synchronous values from hot or pure observables * without triggering extra initial re-rendering. * * ⚠ If the observable is cold and with side effects * they will be performed at least twice! * * By default this hook will subscribe to the observable at least twice. * The first time is for getting synchronous value to prevent extra initial re-rendering. * In concurrent mode this may happen more than one time. * * @template TState State. * * @param state$ An observable of state value. */ declare function useObservableEagerState(state$: Observable): TState; /** * Gets the value at path of state. Similar to lodash `get`. * Only changes of the resulted value will trigger a rerendering. * Errors are thrown on unreachable path. * * @param state$ Output state. */ declare function useObservableGetState(state$: Observable, initialState: TState | (() => TState)): TState; declare function useObservableGetState(state$: Observable, initialState: TInitial): TState | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A] | (() => TState[A]), pA: A): TState[A]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A): TState[A] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A][B] | (() => TState[A][B]), pA: A, pB: B): TState[A][B]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B): TState[A][B] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A][B][C] | (() => TState[A][B][C]), pA: A, pB: B, pC: C): TState[A][B][C]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B, pC: C): TState[A][B][C] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A][B][C][D] | (() => TState[A][B][C][D]), pA: A, pB: B, pC: C, pD: D): TState[A][B][C][D]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B, pC: C, pD: D): TState[A][B][C][D] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A][B][C][D][E] | (() => TState[A][B][C][D][E]), pA: A, pB: B, pC: C, pD: D, pE: E): TState[A][B][C][D][E]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B, pC: C, pD: D, pE: E): TState[A][B][C][D][E] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A][B][C][D][E][F] | (() => TState[A][B][C][D][E][F]), pA: A, pB: B, pC: C, pD: D, pE: E, pF: F): TState[A][B][C][D][E][F]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B, pC: C, pD: D, pE: E, pF: F): TState[A][B][C][D][E][F] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A][B][C][D][E][F][G] | (() => TState[A][B][C][D][E][F][G]), pA: A, pB: B, pC: C, pD: D, pE: E, pF: F, pG: G): TState[A][B][C][D][E][F][G]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B, pC: C, pD: D, pE: E, pF: F, pG: G): TState[A][B][C][D][E][F][G] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A][B][C][D][E][F][G][H] | (() => TState[A][B][C][D][E][F][G][H]), pA: A, pB: B, pC: C, pD: D, pE: E, pF: F, pG: G, pH: H): TState[A][B][C][D][E][F][G][H]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B, pC: C, pD: D, pE: E, pF: F, pG: G, pH: H): TState[A][B][C][D][E][F][G][H] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TState[A][B][C][D][E][F][G][H][I] | (() => TState[A][B][C][D][E][F][G][H][I]), pA: A, pB: B, pC: C, pD: D, pE: E, pF: F, pG: G, pH: H, pI: I): TState[A][B][C][D][E][F][G][H][I]; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B, pC: C, pD: D, pE: E, pF: F, pG: G, pH: H, pI: I): TState[A][B][C][D][E][F][G][H][I] | TInitial; declare function useObservableGetState(state$: Observable, initialState: TInitial, pA: A, pB: B, pC: C, pD: D, pE: E, pF: F, pG: G, pH: H, pI: I, pJ: J): TState[A][B][C][D][E][F][G][H][I][J] | TInitial; /** * Creates an object composed of the picked state properties. Similar to lodash `pick`. * Changes of any of these properties will trigger a rerendering. * Errors are thrown on unreachable path. * * @param state$ Output state. * @param keys keys of state */ declare function useObservablePickState(state$: Observable, initialState: TInitial, ...keys: TKeys[]): { [K in TKeys]: TState[K]; } | TInitial; declare function useObservablePickState(state$: Observable, initialState: { [K in TKeys]: TState[K]; } | (() => { [K in TKeys]: TState[K]; }), ...keys: TKeys[]): { [K in TKeys]: TState[K]; }; /** * Rewires Observable to Relay-like Suspense resource. */ declare class ObservableResource { /** * Unlike Promise, Observable is a multiple push mechanism. * Only force update when Suspense needs to restart. */ readonly shouldUpdate$$: Subject; get isDestroyed(): boolean; readonly valueRef$$: BehaviorSubject<{ current: TOutput; } | undefined>; input$: Observable; private _handler_; private _error_; private _subscription_; private _isDestroyed_; private readonly _observer_; /** * @param input$ An Observable. * @param isSuccess A function that determines if the value emitted from * `input$` is of success state. If false a Suspense is triggered. * Default all true. */ constructor(input$: Observable, isSuccess?: TInput extends TOutput ? (value: TInput) => boolean : (value: TInput) => value is TOutput); read(): TOutput; reload(newInput$?: Observable): void; destroy(): void; } /** * Consume the Observable resource. * * Unlike Promise, Observable is a multiple push mechanism. * This hook triggers extra re-rendering when Suspense should restart. * * @param resource Observable resource */ declare function useObservableSuspense(resource: ObservableResource): TOutput; /** * Returns a mutable ref object and a BehaviorSubject. * * Whenever ref.current is changed, the BehaviorSubject will emit the new value. * * @param initialValue The initial value of the BehaviorSubject. */ declare function useObservableRef(initialValue: TValue): [MutableRefObject, BehaviorSubject]; /** * Returns a ref object and a BehaviorSubject. * * Whenever ref.current is changed, the BehaviorSubject will emit the new value. * * @param initialValue The initial value of the BehaviorSubject. */ declare function useObservableRef(initialValue: TValue | null): [RefObject, BehaviorSubject]; /** * Returns a mutable ref object and a BehaviorSubject. * * Whenever ref.current is changed, the BehaviorSubject will emit the new value. * * @param initialValue A optional initial value of the BehaviorSubject. */ declare function useObservableRef(initialValue?: TValue): [MutableRefObject, BehaviorSubject]; /** * Useful utilities */ /** * Returns the first argument it receives. */ declare const identity: (value: T) => T; /** * Maps an Observable of Arraylike to an Observable * of the first item. * * Example: * * ```typescript * const text$ = useObservable(pluckFirst, [props.text]) * ``` * * @param inputs$ An Observable of array-like. * */ declare const pluckFirst: >(inputs$: Observable) => Observable; /** * Maps an Observable of DOM events to an Observable * of the currentTarget value. * * Example: * * ```typescript * const [onChange, textChange$] = useObservableCallback< * string, * React.FormEvent * >(pluckCurrentTargetValue) * ``` * */ declare const pluckCurrentTargetValue: (event$: Observable) => Observable; /** * Maps an Observable of DOM events to an Observable * of the currentTarget checked. * * Example: * * ```typescript * const [onChange, checked$] = useObservableCallback< * boolean, * React.FormEvent * >(pluckCurrentTargetChecked) * ``` * */ declare const pluckCurrentTargetChecked: (event$: Observable) => Observable; /** * One-time ref init. * @param init A function that returns a value. Will be called only once. * @returns A ref object with the returned value. */ declare const useRefFn: (init: () => T) => MutableRefObject; /** * Force re-renders Component. */ declare const useForceUpdate: () => (() => void); export { ObservableResource, identity, pluckCurrentTargetChecked, pluckCurrentTargetValue, pluckFirst, useForceUpdate, useLayoutObservable, useLayoutObservableState, useLayoutSubscription, useObservable, useObservableCallback, useObservableEagerState, useObservableGetState, useObservablePickState, useObservableRef, useObservableState, useObservableSuspense, useRefFn, useRenderThrow, useSubscription };