ivi
Version:
Lightweight Embeddable Web UI Library.
372 lines • 11.5 kB
TypeScript
import { type TemplateData, ChildOpCode, PropOpCode, StateOpCode } from "./template.js";
export declare const EMPTY_ARRAY: any[];
declare global {
interface Element {
moveBefore<T extends Element | CharacterData>(node: T, child: Node | null): void;
}
}
/**
* Render Context.
*/
export interface RenderContext {
/** Parent DOM Element */
p: Element;
/** Next DOM Node. */
n: Node | null;
/** Template state index. */
si: number;
/** DOM Side Effects */
e: Array<() => void>;
}
/**
* Global Render Context.
*/
export declare const RENDER_CONTEXT: RenderContext;
/**
* Flags.
*/
export declare const enum Flags {
Template = 1,
Component = 2,
List = 4,
Array = 8,
Text = 16,
Root = 32,
Context = 64,
TypeMask = 127,
Dirty = 128,
DirtySubtree = 256,
ForceUpdate = 512,
DisplaceNode = 1024
}
/**
* Stateful Node.
*/
export type SAny = null | SRoot | SText | STemplate | SList | SComponent | SContext;
/**
* Stateful Node.
*/
export type SNode<V = VAny> = SNode1<V> | SNode2<V>;
/**
* Stateful Node with 1 state slot.
*
* @typeparam S1 State slot #1.
*/
export interface SNode1<V = VAny, S1 = any> {
/** Stateless Node. */
v: V;
/** See {@link Flags} for details. */
f: Flags;
/** Children Stateful Nodes. */
c: SNode | (SNode | null)[] | null;
/** Parent Stateful Node. */
p: SNode | null;
/** State slot #1. */
s1: S1;
}
/**
* Stateful Node with 2 state slots.
*
* @typeparam S1 State slot #1.
* @typeparam S2 State slot #2.
*/
export interface SNode2<V = VAny, S1 = any, S2 = any> extends SNode1<V, S1> {
/** State slot #2. */
s2: S2;
}
/** Stateful Root Node. */
export type SRoot<S = any> = SNode1<VRoot, S>;
/** Stateful Root Node. */
export type Root<S = any> = SRoot<S>;
/** Stateful Text Node. */
export type SText = SNode1<string | number, Text>;
/** Stateful Template Node. */
export type STemplate = SNode1<VTemplate, Node[]>;
/** Stateful List Node. */
export type SList = SNode1<VList, null>;
/** Stateful Component Node. */
export type SComponent<P = any> = SNode2<VComponent,
/** Render function. */
null | ComponentRenderFn<P>,
/** Unmount hooks. */
null | (() => void) | (() => void)[]>;
/** Stateful Component Node. */
export type Component<P = any> = SComponent<P>;
export type ComponentRenderFn<P = any> = (props: P) => VAny;
export type SContext = SNode1<VContext, null>;
/**
* Creates a Stateful Node instance.
*
* @param v VNode.
* @returns {@link SNode} instance.
*/
export declare const createSNode: <V extends VAny, S>(f: Flags, v: V, c: SNode | Array<SNode1 | null> | null, p: SNode | null, s1: S) => SNode1<V, S>;
/**
* Stateless Tree Node.
*/
export type VAny = null | undefined | false | string | number | VRoot | VTemplate | VComponent | VContext | VList | VAny[];
/**
* Stateless Node Descriptor.
*/
export interface VDescriptor<P1 = any, P2 = any> {
/** See {@link Flags} for details. */
readonly f: Flags;
/** First property. */
readonly p1: P1;
/** Second property. */
readonly p2: P2;
}
/** Root Invalidate Hook. */
export type OnRootInvalidated<S> = (root: SRoot<S>, state: S) => void;
/** Root Descriptor. */
export type RootDescriptor<S = any> = VDescriptor<OnRootInvalidated<S>, null>;
/** Template Descriptor */
export type TemplateDescriptor = VDescriptor<TemplateData, () => Element>;
/** Component Descriptor */
export type ComponentDescriptor<P = any> = VDescriptor<ComponentFactoryFn<P>, undefined | ((prev: P, next: P) => boolean)>;
export type ComponentFactoryFn<P = any> = (component: Component) => (props: P) => VAny;
/** Context Descriptor */
export type ContextDescriptor = VDescriptor<null, null>;
/** List Descriptor */
export type ListDescriptor = VDescriptor<null, null>;
/**
* Stateless Node.
*
* @typeparam D Descriptor.
* @typeparam P Property.
*/
export interface VNode<D extends VDescriptor<any, any> = VDescriptor<any, any>, P = any> {
/** Descriptor. */
readonly d: D;
/** Property. */
readonly p: P;
}
/** Stateless Root Node. */
export type VRoot = VNode<RootDescriptor, RootProps>;
/** Stateless Template Node. */
export type VTemplate<P = any> = VNode<TemplateDescriptor, P>;
/** Stateless Component Node. */
export type VComponent<P = any> = VNode<ComponentDescriptor, P>;
/** Stateless Context Node. */
export type VContext<T = any> = VNode<ContextDescriptor, ContextProps<T>>;
/** Stateless List Node. */
export type VList<K = any> = VNode<ListDescriptor, ListProps<K>>;
/**
* Stateless Root Node Props.
*
* Contains a DOM position where root children should mounted.
*/
export interface RootProps {
/** Parent Element */
p: Element;
/** Next Node */
n: Node | null;
}
/**
* Stateless Context Node Props.
*/
export interface ContextProps<T = any> {
/** Context Value. */
v: T;
/** Stateless Child Node. */
c: VAny;
}
/**
* Stateless List Node Props.
*
* Contains unique keys for stateless nodes and stateless nodes.
*/
export interface ListProps<K = any> {
/** Unique Keys. */
k: K[];
/** Stateless Nodes. */
v: VAny[];
}
/**
* Element Directive.
*/
export type ElementDirective = <E extends Element>(element: E) => void;
export declare const _flushDOMEffects: () => void;
/**
* Creates a HTML Template cloning factory.
*
* @__NO_SIDE_EFFECTS__
*/
export declare const _hN: (t: string | Node) => () => Element;
/**
* Creates a HTML Element factory.
*
* @__NO_SIDE_EFFECTS__
*/
export declare const _hE: (t: string) => () => Element;
/**
* Creates a SVG Template cloning factory.
*/
export declare const _sN: (t: string | Node) => () => Element;
/**
* Creates a SVG Element factory.
*
* @__NO_SIDE_EFFECTS__
*/
export declare const _sE: (t: string) => () => Element;
/**
* Creates a template descriptor with globally shared data.
*
* @__NO_SIDE_EFFECTS__
*/
export declare const _T: (p2: () => Element, f: number, p: PropOpCode[], c: ChildOpCode[], s: StateOpCode[], d?: string[]) => TemplateDescriptor;
/**
* @__NO_SIDE_EFFECTS__
*/
export declare const _t: (d: TemplateDescriptor, p: any[]) => VTemplate;
export type ComponentFactory = {
(factory: (c: Component) => () => VAny, areEqual?: (a?: any, b?: any) => boolean): () => VComponent<undefined>;
<P>(factory: (c: Component<P>) => (props: P) => VAny, areEqual?: (prev: P, next: P) => boolean): (props: P) => VComponent<P>;
};
/**
* Creates a factory that produces component nodes.
*
* @typeparam P Property type.
* @param factory Function that produces stateful render functions.
* @param areEqyal Function that checks `props` for equality.
* @returns Factory that produces component nodes.
* @__NO_SIDE_EFFECTS__
*/
export declare const component: ComponentFactory;
/**
* Gets current component props.
*
* @typeparam P Property type.
* @param component Component node.
* @returns Current component props.
*/
export declare const getProps: <P>(component: Component<P>) => P;
/**
* Adds an unmount hook.
*
* @example
*
* const Example = component((c) => {
* useUnmount(c, () => { console.log("unmounted"); });
*
* return () => null;
* });
*
* @param component Component instance.
* @param hook Unmount hook.
*/
export declare const useUnmount: (component: Component, hook: () => void) => void;
export type Effect = {
(component: Component, effect: () => (() => void) | void, areEqual?: (prev?: any, next?: any) => boolean): () => void;
<P>(component: Component, effect: (props: P) => (() => void) | void, areEqual?: (prev: P, next: P) => boolean): (props: P) => void;
};
/**
* Creates a side effect hook.
*
* @example
*
* const Example = component((c) => {
* const [count, setCount] = useState(c, 0);
* const timer = useEffect(c, ({ interval }) => {
* const tid = setInterval(() => { setCount(count() + 1); }, interval);
* return () => { clearInterval(tid); };
* }, shallowEq);
*
* return (interval) => (
* timer({ interval }),
*
* html`<span>${count()}</span>`
* );
* });
*
* @typeparam T Hook props type.
* @param component Component instance.
* @param hook Side effect function.
* @param areEqual Function that checks if input value hasn't changed.
* @returns Side effect hook.
*/
export declare const useEffect: Effect;
export declare const createEffectHandler: (scheduleFlushTask: () => Array<() => void>) => <P>(component: Component, hook: (props?: P) => (() => void) | void, areEqual?: (prev: P, next: P) => boolean) => (props?: P) => void;
export declare const useAnimationFrameEffect: <P>(component: Component, hook: (props?: P) => (() => void) | void, areEqual?: (prev: P, next: P) => boolean) => (props?: P) => void;
export declare const useIdleEffect: <P>(component: Component, hook: (props?: P) => (() => void) | void, areEqual?: (prev: P, next: P) => boolean) => (props?: P) => void;
/**
* Invalidates a component.
*
* @param c Component instance.
*/
export declare const invalidate: (c: Component) => void;
/**
* VDescriptor for List nodes.
*/
export declare const LIST_DESCRIPTOR: ListDescriptor;
/**
* Creates a dynamic list.
*
* @typeparam E Entry type.
* @typeparam K Key type.
* @param entries Entries.
* @param getKey Get key from entry function.
* @param render Render entry function.
* @returns Dynamic list.
* @__NO_SIDE_EFFECTS__
*/
export declare const List: <E, K>(entries: E[], getKey: (entry: E, index: number) => K, render: (entry: E, index: number) => VAny) => VList;
/**
* Performs dirty checking in a root subtree.
*
* When `forceUpdate` option is enabled, all components in a root subtree will
* be updated.
*
* @param root Root Node.
* @param forceUpdate Force update components.
*/
export declare const dirtyCheck: (root: Root, forceUpdate?: boolean) => void;
/**
* Unmounts a root subtree.
*
* When `detach` option is enabled, root DOM nodes will be detached from the
* DOM.
*
* @param root Root Node.
* @param detach Detach root DOM nodes from the DOM.
*/
export declare const unmount: (root: Root, detach: boolean) => void;
export type RootFactory = {
(onInvalidate: (root: Root<undefined>) => void): (parentElement: Element, nextNode?: Node | null) => Root<undefined>;
<S>(onInvalidate: (root: Root<S>, state: S) => void): (parentElement: Element, nextNode: Node | null, state: S) => Root<S>;
};
/**
* Defines a root node with a custom invalidation hook.
*
* @param onInvalidate Invalidated Hook.
* @returns Root Node factory.
* @__NO_SIDE_EFFECTS__
*/
export declare const defineRoot: RootFactory;
/**
* Creates a root node that uses microtask queue for scheduling updates.
*
* @param parentElement Parent DOM Element.
* @param nextNode Next DOM Node.
* @returns Root Node.
*/
export declare const createRoot: (parentElement: Element, nextNode?: Node | null) => Root<undefined>;
/**
* Updates a root subtree.
*
* When `forceUpdate` option is enabled, all components in a root subtree will
* be updated.
*
* @param root Root Node.
* @param v Stateless View Node.
* @param forceUpdate Force update components.
*/
export declare const update: (root: Root, v: VAny, forceUpdate?: boolean) => void;
/**
* Context.
*
* @returns Context getter and context provider.
* @__NO_SIDE_EFFECTS__
*/
export declare const context: <T>() => [get: (component: Component) => T | undefined, provider: (value: T, child: VAny) => VContext<T>];
//# sourceMappingURL=core.d.ts.map