@expressive/react
Version:
Use classes to define state in React!
71 lines (65 loc) • 3 kB
TypeScript
import { Context } from '@expressive/mvc';
import React__default, { FunctionComponent } from 'react';
declare module '@expressive/mvc' {
namespace Model {
interface Component<T extends Model, P extends Model.Assign<T>> extends FunctionComponent<P & Component.Props<T>> {
displayName?: string;
Model: Model.Type<T>;
}
namespace Component {
type Props<T extends Model> = Partial<Pick<T, Exclude<keyof T, keyof Model>>> & {
is?: (instance: T) => void | (() => void);
};
}
function as<T extends Model, P extends Model.Assign<T>>(this: Model.Init<T>, render: (props: P, self: T) => React__default.ReactNode): Component<T, P>;
}
}
declare module '@expressive/mvc' {
namespace Model {
function use<T extends Model>(this: Model.Init<T>, apply?: Model.Assign<T>, repeat?: boolean): T;
function use<T extends Model>(this: Model.Init<T>, callback?: Model.Callback<T>, repeat?: boolean): T;
}
}
/** Type may not be undefined - instead will be null. */
type NoVoid<T> = T extends undefined | void ? null : T;
type ForceRefresh = {
/** Request a refresh for current component. */
(): void;
/**
* Request a refresh and again after promise either resolves or rejects.
*
* @param waitFor Promise to wait for.
* @returns Promise which resolves, after refresh, to same value as `waitFor`.
*/
<T = void>(waitFor: Promise<T>): Promise<T>;
/**
* Request refresh before and after async function.
* A refresh will occur both before and after the given function.
*
* **Note:** Any actions performed before first `await` will occur prior to refresh.
*
* @param invoke Async function to invoke.
* @returns Promise which resolves returned value after refresh.
*/
<T = void>(invoke: () => Promise<T>): Promise<T>;
};
declare module '@expressive/mvc' {
namespace Model {
type GetFactory<T extends Model, R> = (this: T, current: T, refresh: ForceRefresh) => R;
type GetEffect<T extends Model> = (this: T, current: T, refresh: ForceRefresh) => null;
/** Fetch instance of this class from context. */
function get<T extends Model>(this: Model.Type<T>): T;
/** Fetch instance of this class optionally. */
function get<T extends Model>(this: Model.Type<T>, required: false): T | undefined;
/** Fetch instance of this class from context. */
function get<T extends Model>(this: Model.Type<T>, requireValues: true): Required<T>;
function get<T extends Model, R>(this: Model.Type<T>, factory: GetFactory<T, Promise<R> | R>): NoVoid<R>;
function get<T extends Model>(this: Model.Type<T>, factory: GetEffect<T>): null;
}
}
declare const Pragma: {
useContext(): Context;
useFactory<T extends Function>(factory: (refresh: () => void) => T): T;
useLifecycle(callback: () => () => void): void;
};
export { Pragma };