UNPKG

@chrfalch/react-observable-context

Version:
57 lines (49 loc) 4.03 kB
import * as React from 'react'; import React__default from 'react'; type IsFunction<T> = T extends () => unknown ? true : T extends (...args: any[]) => unknown ? true : false; type FlattenedKeysOf<T extends object, TArrayLike extends boolean = false> = { [Key in keyof T & (string | number)]: IsFunction<T[Key]> extends true ? TArrayLike extends false ? `${Key}` : never : T[Key] extends object ? T[Key] extends Array<unknown> ? // Arrays should have both array and objects by indicies and length properties `${Key}` | `${Key}.${FlattenedKeysOf<T[Key], true>}` : `${Key}.${FlattenedKeysOf<T[Key], TArrayLike>}` : `${Key}`; }[keyof T & (string | number)]; type FlattenedObjectOf<T extends object, K extends FlattenedKeysOf<T> = FlattenedKeysOf<T>> = { [Key in K]: Key extends keyof T ? T[Key] : Key extends `${infer First}${'.'}${infer Rest}` ? First extends keyof T ? T[First] extends object ? FlattenedObjectOf<T[First]> extends object ? Rest extends keyof FlattenedObjectOf<T[First]> ? FlattenedObjectOf<T[First]>[Rest] : never : never : never : T extends Array<infer AT> ? Rest extends keyof AT ? AT[Rest] : never : never : T extends Array<infer AT> ? AT : never; }; type TObservableObject<TValue extends Record<string, unknown>> = TValue & { subscribe: <TProp extends FlattenedKeysOf<TValue>>(prop: TProp, listener: () => void) => () => void; }; /** * Creates a new React Context with the provided object as the initial value. * The context will support subscribing to changes and notifications when the value changes. * @param obj * @returns */ declare const createContext: <T>(obj: T) => React__default.Context<TObservableObject<NonNullable<T>> | undefined>; /** * Creates a new object that allows for subscribing to changes * @param initialValue Initial value of the object. * @returns The object that can be used as a object where we can read/write values. */ declare const makeObservable: <TInitialValue extends Record<string, unknown>>(initialValue: TInitialValue) => TObservableObject<TInitialValue>; /** * Creates a selector that subscribes to parts of the observable and returns the value of observed properties. * @param observable Observable to subscribe to * @param props Props to subscribe to (can be nested like a.b.c) * @returns An array of the values that will be updated if any of the properties change. */ declare const useObserver: <TValue extends Record<string, unknown>, TObservable extends TObservableObject<TValue>, TFlattened extends FlattenedObjectOf<TObservable>, TKeys extends Exclude<keyof TFlattened, "subscribe">>(observable: TObservable, ...props: TKeys[]) => Pick<Pick<FlattenedObjectOf<TObservable>, FlattenedKeysOf<TObservable, false>>, TKeys>; /** * Creates a new observable from the given value. The observable can be * used to subscribe to changes. The initial value is used as the initial * value of the observable, and subsequent changes to the initial value will * not result in the observable being updated. * @param initialValue Initial value to create the observable from * @returns A new observable */ declare const useObservable: <T extends Record<string, unknown>>(initialValue: T) => TObservableObject<T>; declare const Observable: { createContext: <T>(obj: T) => React.Context<TObservableObject<NonNullable<T>> | undefined>; makeObservable: <TInitialValue extends Record<string, unknown>>(initialValue: TInitialValue) => TObservableObject<TInitialValue>; useObserver: <TValue extends Record<string, unknown>, TObservable extends TObservableObject<TValue>, TFlattened extends FlattenedObjectOf<TObservable>, TKeys extends Exclude<keyof TFlattened, "subscribe">>(observable: TObservable, ...props: TKeys[]) => Pick<Pick<FlattenedObjectOf<TObservable>, FlattenedKeysOf<TObservable, false>>, TKeys>; useObservable: <T_1 extends Record<string, unknown>>(initialValue: T_1) => TObservableObject<T_1>; }; export { FlattenedKeysOf, Observable, createContext, Observable as default, makeObservable, useObservable, useObserver };