@adpt/core
Version:
AdaptJS core library
449 lines • 21.2 kB
TypeScript
import { OptionalPropertiesT, RequiredPropertiesT } from "type-ops";
import { Constructor, ExcludeInterface, Message } from "@adpt/utils";
import { DependsOn, DependsOnMethod, DeployedWhenMethod, DeployHelpers, GoalStatus, WaitStatus } from "./deploy/deploy_types";
import { BuildData } from "./dom";
import { BuildId, Handle } from "./handle";
import { Defaultize } from "./jsx_namespace";
import { ObserverManagerDeployment } from "./observers/obs_manager_deployment";
import { DeployOpID } from "./server/deployment_data";
import { StateNamespace, StateStore, StateUpdater } from "./state";
import { ObserveForStatus, Status } from "./status";
import { Children, ChildType } from "./type_support";
export declare let ApplyStyle: ComponentType<any>;
export declare function isApplyStyle(el: AdaptElement): boolean;
/**
* An Adapt Element is an instance of an Adapt component.
*
* @remarks
* The Adapt DOM is composed of Elements.
*
* @public
*
* @privateRemarks
* NOTE(manishv):
* This is broken, why does JSX.ElementClass correspond to both the type
* a Component construtor has to return and what createElement has to return?
* I don't think React actually adheres to this constraint.
*/
export interface AdaptElement<P extends object = AnyProps> {
/** A copy of the props that the element was instantiated with */
readonly props: P & BuiltinProps;
/**
* The type of component that is associated with this element.
* @remarks
* For class components, this is the class (constructor) object.
* For function components, this is the function object.
*/
readonly componentType: ComponentType<P>;
/**
* The name of the class or function in {@link AdaptElement.componentType},
* as returned by `componentType.name` or, the string `"anonymous"` if
* no name is available.
*/
readonly componentName: string;
/**
* The name that a component author (optionally) associated with the
* component using the `displayName` static property. If not set on a
* component, defaults to {@link AdaptElement.componentName}.
*/
readonly displayName: string;
/**
* Adds a dependency for this Element. This Element will wait to deploy
* until all `dependencies` have completed deployment.
*/
addDependency(dependencies: Handle | Handle[]): void;
}
export declare function isElement<P extends object = AnyProps>(val: any): val is AdaptElement<P>;
export declare function isElementImpl<P extends object = AnyProps>(val: any): val is AdaptElementImpl<P>;
export declare type AdaptElementOrNull = AdaptElement<AnyProps> | null;
export interface GenericInstanceMethods {
dependsOn?: DependsOnMethod;
deployedWhen?: DeployedWhenMethod;
deployedWhenIsTrivial?: boolean;
}
export interface GenericInstance extends GenericInstanceMethods {
[key: string]: any;
}
export declare type ElementID = string;
/**
* Interface that represents an AdaptElement that has been mounted during
* the DOM build process.
* @public
*/
export interface AdaptMountedElement<P extends object = AnyProps> extends AdaptElement<P> {
readonly props: P & Required<BuiltinProps>;
readonly id: ElementID;
readonly path: string;
readonly keyPath: KeyPath;
readonly buildData: BuildData;
readonly instance: GenericInstance;
dependsOn: DependsOnMethod;
deployedWhen: DeployedWhenMethod;
/**
* True if the Element's `deployedWhen` is considered trivial.
* @remarks
* This flag is a hint for user interfaces, such as the Adapt CLI. It
* tells the user interface that this Element's `deployedWhen` function
* is "trivial" and therefore its status should not typically be shown in
* user interfaces unless the user has requested more detailed status
* information on all components, or if there's an active action for
* the component.
*
* This flag is `true` if the component does not have a custom
* `deployedWhen` method or if the trivial flag was specifically set via
* {@link useDeployedWhen} options (function component) or via
* {@link Component.deployedWhenIsTrivial} (class component).
*/
readonly deployedWhenIsTrivial: boolean;
status<T extends Status>(o?: ObserveForStatus): Promise<T>;
built(): boolean;
}
export declare function isMountedElement<P extends object = AnyProps>(val: any): val is AdaptMountedElement<P>;
export interface AdaptDeferredElement<P extends object = AnyProps> extends AdaptElement<P> {
readonly componentType: PrimitiveClassComponentTyp<P>;
}
export declare function isDeferredElement<P extends object = AnyProps>(val: AdaptElement<P>): val is AdaptDeferredElement<P>;
export declare function isDeferredElementImpl<P extends object = AnyProps>(val: AdaptElement<P>): val is AdaptDeferredElementImpl<P>;
export interface AdaptPrimitiveElement<P extends object = AnyProps> extends AdaptDeferredElement<P> {
}
export declare function isPrimitiveElement<P extends object>(elem: AdaptElement<P>): elem is AdaptPrimitiveElement<P>;
export interface AdaptMountedPrimitiveElement<P extends object = AnyProps> extends AdaptPrimitiveElement<P>, AdaptMountedElement<P> {
readonly props: P & Required<BuiltinProps>;
readonly componentType: PrimitiveClassComponentTyp<P>;
validate(): Message[];
}
export declare function isMountedPrimitiveElement<P extends object>(elem: AdaptElement<P>): elem is AdaptMountedPrimitiveElement<P>;
export interface AdaptComponentElement<P extends object = AnyProps> extends AdaptElement<P> {
readonly componentType: ClassComponentTyp<P, AnyState>;
}
export declare function isComponentElement<P extends object = AnyProps>(val: any): val is AdaptComponentElement<P>;
export interface AdaptSFCElement<P extends object = AnyProps> extends AdaptElement<P> {
readonly componentType: FunctionComponentTyp<P>;
}
export declare function isSFCElement<P extends object = AnyProps>(val: any): val is AdaptSFCElement<P>;
export declare type FinalDomElement<P extends object = AnyProps> = AdaptMountedPrimitiveElement<P>;
export declare type PartialFinalDomElement<P extends object = AnyProps> = AdaptMountedElement<P>;
export declare const isFinalDomElement: typeof isMountedPrimitiveElement;
export declare const isPartialFinalDomElement: typeof isMountedElement;
export declare function componentStateNow<C extends Component<P, S>, P extends object, S extends object>(c: C): S | undefined;
export interface DeployInfo {
deployID: string;
deployOpID: DeployOpID;
}
export interface BuildHelpers extends DeployInfo, BuildId {
elementStatus<T = Status>(handle: Handle): Promise<T | undefined>;
}
export declare abstract class Component<Props extends object = {}, State extends object = {}> implements GenericInstanceMethods {
readonly props: Props & Partial<BuiltinProps>;
deployInfo: DeployInfo;
dependsOn?: DependsOnMethod;
/**
* A derived component's custom `deployedWhen` method.
*
* @remarks
* Adding a custom `deployedWhen` method to a component allows the component to
* directly control when the component can be considered deployed.
*
* For more information on using `deployedWhen` methods, see
* {@link Adapt.DeployedWhenMethod}.
*
* For components that do not add a custom `deployedWhen` method, the
* default behavior is that a component becomes deployed when all of it's
* successors and children have been deployed. See {@link defaultDeployedWhen}
* for more information.
* @public
*/
deployedWhen?: DeployedWhenMethod;
/**
* A derived component can set this flag to `true` to indicate to user
* interfaces that this component's status should not typically be shown
* to the user, unless requested.
* @remarks
* This flag is a hint for user interfaces, such as the Adapt CLI. It
* tells the user interface that this Element's `deployedWhen` function
* is "trivial" and therefore its status should not typically be shown in
* user interfaces unless the user has requested more detailed status
* information on all components, or if there's an active action for
* this component.
*/
deployedWhenIsTrivial?: boolean;
cleanup?: (this: this) => void;
private stateUpdates;
private getState?;
state: Readonly<State>;
constructor(props: Props & Partial<BuiltinProps>);
setState(stateUpdate: Partial<State> | StateUpdater<Props, State>): void;
initialState?(): State;
abstract build(helpers: BuildHelpers): AdaptElementOrNull | Promise<AdaptElementOrNull>;
status(observeForStatus: ObserveForStatus, buildData: BuildData): Promise<unknown>;
}
export declare type PropsType<Comp extends Constructor<Component<any, any>>> = Comp extends Constructor<Component<infer CProps, any>> ? CProps : never;
export declare abstract class DeferredComponent<Props extends object = {}, State extends object = {}> extends Component<Props, State> {
}
export declare function isDeferred<P extends object, S extends object>(component: Component<P, S>): component is DeferredComponent<P, S>;
export declare abstract class PrimitiveComponent<Props extends object = {}, State extends object = {}> extends DeferredComponent<Props, State> {
build(): AdaptElementOrNull;
validate(): string | string[] | undefined;
}
export declare function isPrimitive<P extends object>(component: Component<P>): component is PrimitiveComponent<P>;
export interface SFC<Props extends object = AnyProps> {
(props: Props & Partial<BuiltinProps>): AdaptElementOrNull;
defaultProps?: Partial<Props>;
status?: (props: Props & BuiltinProps, observe: ObserveForStatus, buildData: BuildData) => Promise<unknown>;
}
/**
* Helper type for declaring the props argument of a function component.
* (The type that users of your component will see.)
*
* @remarks
* This helper type can be used to create the type for your function
* component's `props` argument. It correctly handles the standard
* set of {@link BuiltinProps} and your component's `defaultProps` so that
* users of your component can pass in props like `key` and `handle` and also
* not be required to pass in any props that are required, but have valid
* default values in `defaultProps`.
*
* This type should **only** be used to describe the first argument to your
* function component.
*
* It should typically be used along with {@link SFCBuildProps}.
*
* Type parameters:
*
* `Props` - The object type that describes the props your function
* component takes, not including any {@link BuiltinProps}. For props that
* your component requires, but has valid defaults set in `defaultProps`,
* those properties should be required (not optional) in `Props`.
*
* `Defaults` - The object type of your component's `defaultProps`.
*
* @example
* ```tsx
* interface MyProps {
* required: string; // User is required to always set this prop
* hasDefault: string; // User can optionally set this prop or get default
* optional?: string; // User can optionally set this prop, but no default
* }
* const defaultProps = {
* hasDefault: "thedefault"
* }
*
* // Types for the properties of the props argument below are:
* // props.required string [required]
* // props.hasDefault string [optional]
* // props.optional string [optional]
* // props.key string [optional]
* // props.handle Handle [optional]
* function MyComponent(props: SFCDeclProps<MyProps, typeof defaultProps) {
* // Types for the properties of the buildProps variable below are:
* // buildProps.required string
* // buildProps.hasDefault string
* // buildProps.optional string | undefined
* // buildProps.key string
* // buildProps.handle Handle
* const buildProps = props as SFCBuildProps<MyProps, typeof defaultProps>;
* ...
* }
* MyComponent.defaultProps = defaultProps;
* ```
* @public
*/
export declare type SFCDeclProps<Props, Defaults extends object = object> = Defaultize<Props, Defaults> & Partial<BuiltinProps>;
/**
* Helper type for declaring the props available to use **inside** the body
* of your function component.
*
* @remarks
* This helper type can be used to create the type of the "build props",
* which are the props available inside the body of your function component
* when your component is built by Adapt. The type of "build props" in a
* function component are different than the type that the user sees because
* Adapt deals with setting the values of some props automatically when
* a component gets built.
*
* This helper should **only** be used to describe the type of a function
* component's props **inside** the function body.
*
* It should typically be used along with {@link SFCDeclProps}. See the
* example usage of both helper types in {@link SFCDeclProps}.
*
* Type parameters:
*
* `Props` - The object type that describes the props your function
* component takes, not including any {@link BuiltinProps}. For props that
* your component requires, but has valid defaults set in `defaultProps`,
* those properties should be required (not optional) in `Props`.
*
* `Defaults` - (optional) The object type of your component's `defaultProps`.
*/
export declare type SFCBuildProps<Props, Defaults extends object = object> = {
[K in Extract<keyof Props, keyof Defaults>]: Props[K];
} & {
[K in Exclude<RequiredPropertiesT<Props>, keyof Defaults>]: Props[K];
} & {
[K in Exclude<OptionalPropertiesT<Props>, keyof Defaults>]?: Props[K];
} & Required<BuiltinProps>;
export declare function isComponent<P extends object, S extends object>(func: SFC | Component<P, S>): func is Component<P, S>;
export interface ComponentStatic<P> {
defaultProps?: Partial<P>;
displayName?: string;
noPlugin?: boolean;
}
export interface FunctionComponentTyp<P> extends ComponentStatic<P> {
(props: P & Partial<BuiltinProps>): AdaptElementOrNull;
status?: (props: P, observe: ObserveForStatus, buildData: BuildData) => Promise<unknown>;
}
export interface ClassComponentTyp<P extends object, S extends object> extends ComponentStatic<P> {
new (props: P & Partial<BuiltinProps>): Component<P, S>;
}
export interface DeferredClassComponentTyp<P extends object, S extends object> extends ComponentStatic<P> {
new (props: P & Partial<BuiltinProps>): DeferredComponent<P, S>;
}
export interface PrimitiveClassComponentTyp<P extends object> extends ComponentStatic<P> {
new (props: P & Partial<BuiltinProps>): PrimitiveComponent<P>;
}
export declare type ComponentType<P extends object> = FunctionComponentTyp<P> | ClassComponentTyp<P, AnyState> | DeferredClassComponentTyp<P, AnyState> | PrimitiveClassComponentTyp<P>;
export interface AnyProps {
[key: string]: any;
}
export interface BuiltinProps {
handle: Handle;
key?: string;
}
export interface AnyState {
[key: string]: any;
}
export interface WithChildren {
children?: any | any[];
}
export declare type GenericComponent = Component<AnyProps, AnyState>;
export declare type KeyPath = string[];
export declare type ElementPredicate = (el: AdaptElement) => boolean;
/**
* @internal
*/
export declare class AdaptElementImpl<Props extends object> implements AdaptElement<Props> {
readonly componentType: ComponentType<Props>;
readonly props: Props & BuiltinProps & WithChildren;
stateNamespace: StateNamespace;
mounted: boolean;
component: GenericComponent | null;
instanceMethods: GenericInstance;
path?: string;
keyPath?: KeyPath;
buildData: Partial<BuildData>;
buildState: BuildState;
reanimated: boolean;
stateUpdates: StateUpdater[];
private addlDependencies?;
constructor(componentType: ComponentType<Props>, props: Props & Partial<BuiltinProps>, children: any[]);
mount(parentNamespace: StateNamespace, path: string, keyPath: KeyPath, deployID: string, deployOpID: DeployOpID): void;
setBuilt: () => BuildState;
shouldBuild: () => boolean;
built: () => boolean;
setState: (stateUpdate: StateUpdater<Props, AnyState>) => void;
postBuild(stateStore: StateStore): Promise<{
stateChanged: boolean;
}>;
getStatusMethod: () => (o: ObserveForStatus<unknown>, b: BuildData) => Promise<any>;
statusCommon: (observeForStatus: ObserveForStatus<unknown>) => Promise<any>;
statusWithMgr: (mgr: ObserverManagerDeployment) => Promise<any>;
status: (o?: ObserveForStatus<unknown> | undefined) => Promise<any>;
/**
* Add one or more deploy dependencies to this Element.
* @remarks
* Intended to be called during the DOM build process.
*/
addDependency(dependencies: Handle | Handle[]): void;
/**
* Return all the dependencies of an Element.
* @remarks
* Intended to be called during the deployment phase from the execution
* plan code only.
* @internal
*/
dependsOn(goalStatus: GoalStatus, helpers: DeployHelpers): DependsOn | undefined;
/**
* Returns whether this Element (and ONLY this element) has completed
* deployment.
* @remarks
* Intended to be called during the deployment phase from the execution
* plan code only.
* @internal
*/
deployedWhen(goalStatus: GoalStatus, helpers: DeployHelpers): WaitStatus | Promise<WaitStatus>;
/**
* True if the Element's `deployedWhen` is considered trivial.
* @remarks
* This flag is a hint for user interfaces, such as the Adapt CLI. It
* tells the user interface that this Element's `deployedWhen` function
* is "trivial" and therefore its status should not typically be shown in
* user interfaces unless the user has requested more detailed status
* information on all components, or if there's an active action for
* this component.
*
* This flag is `true` if the component does not have a custom
* `deployedWhen` method or if the trivial flag was specifically set via
* {@link useDeployedWhen} options (function component) or via
* {@link Component.deployedWhenIsTrivial} (class component).
*/
readonly deployedWhenIsTrivial: boolean;
readonly componentName: string;
readonly displayName: string;
readonly id: string;
readonly instance: GenericInstance;
}
/**
* Creates a function that implements the default `deployedWhen` behavior for
* an Element.
* @remarks
* When a component has not specified a custom `deployedWhen`
* method, it will use this function to generate the default `deployedWhen`
* method.
*
* The default `deployedWhen` behavior, implemented by this function, is to
* return `true` (meaning the Element has reached the `goalStatus` and is deployed)
* once the successor Element of `el` is deployed. If `el` has no successor,
* it will return `true` once all of its children have become deployed.
*
* @param el - The Element for which a default `deployedWhen` function should
* be created.
*
* @returns A `deployedWhen` function for Element `el` that implements the
* default behavior.
* @public
*/
export declare function defaultDeployedWhen(el: AdaptElement): DeployedWhenMethod;
declare enum BuildState {
initial = "initial",
deferred = "deferred",
built = "built"
}
export declare class AdaptDeferredElementImpl<Props extends object> extends AdaptElementImpl<Props> {
setDeferred: () => BuildState;
shouldBuild: () => boolean;
}
export declare class AdaptPrimitiveElementImpl<Props extends object> extends AdaptDeferredElementImpl<Props> {
readonly componentType: PrimitiveClassComponentTyp<Props>;
component: PrimitiveComponent<Props> | null;
constructor(componentType: PrimitiveClassComponentTyp<Props>, props: Props & Partial<BuiltinProps>, children: any[]);
validate(): Message[];
}
export declare function createElement<Props extends object>(ctor: string | FunctionComponentTyp<Props> | ClassComponentTyp<Props, AnyState>, props: ExcludeInterface<Props, Children<any>> & Partial<BuiltinProps>, ...children: ChildType<Props>[]): AdaptElement;
export declare function cloneElement(element: AdaptElement, props: AnyProps, ...children: any[]): AdaptElement;
export declare type PrimitiveChildType<T> = T extends (infer U | (infer U)[])[] ? U : T extends (infer V)[][] ? V : T extends (infer W)[] ? W : T;
export declare function childrenToArray<T>(propsChildren: T | undefined): PrimitiveChildType<T>[];
export declare function simplifyChildren(children: any | any[] | undefined): any | any[] | undefined;
export interface ComponentConstructorData {
deployInfo: DeployInfo;
getState: () => any;
setInitialState: <T extends object>(init: T) => void;
stateUpdates: StateUpdater[];
observerManager: ObserverManagerDeployment;
}
export declare function setComponentConstructorStack_(stack: ComponentConstructorData[]): ComponentConstructorData[];
export declare function pushComponentConstructorData(d: ComponentConstructorData): void;
export declare function popComponentConstructorData(): void;
export declare function getComponentConstructorData(): ComponentConstructorData;
export {};
//# sourceMappingURL=jsx.d.ts.map