@furystack/shades
Version:
A lightweight UI framework for FuryStack with JSX support
103 lines • 4.32 kB
TypeScript
/**
* VNode-based reconciliation for Shades.
*
* Instead of creating real DOM elements during each render and then diffing them,
* the JSX factory produces lightweight VNode descriptors. A reconciler diffs the
* previous VNode tree against the new one and applies surgical DOM updates using
* tracked `_el` references.
*/
declare const VNODE_BRAND: "vnode";
declare const VTEXT_BRAND: "vtext";
/**
* Sentinel type used as VNode.type for JSX fragments (`<>...</>`).
*/
export declare const FRAGMENT: unique symbol;
/**
* Sentinel type for VNodes that wrap a pre-existing real DOM node.
* Used when shadeChildren (created outside render mode) flow into a VNode render.
*/
export declare const EXISTING_NODE: unique symbol;
/**
* A lightweight descriptor for a DOM element or Shade component.
*/
export type VNode = {
_brand: typeof VNODE_BRAND;
type: string | ((...args: unknown[]) => unknown) | typeof FRAGMENT | typeof EXISTING_NODE;
props: Record<string, unknown>;
children: VChild[];
_el?: Node;
};
/**
* A lightweight descriptor for a DOM text node.
*/
export type VTextNode = {
_brand: typeof VTEXT_BRAND;
text: string;
_el?: Text;
};
/**
* A single child in a VNode tree -- either an element/component or a text node.
*/
export type VChild = VNode | VTextNode;
export declare const isVNode: (v: unknown) => v is VNode;
export declare const isVTextNode: (v: unknown) => v is VTextNode;
/**
* Recursively flattens raw JSX children into a flat VChild array.
* - Strings and numbers become VTextNodes.
* - Fragment VNodes are inlined (their children are spliced in).
* - Nullish / boolean values are skipped.
*/
export declare const flattenVChildren: (raw: unknown[]) => VChild[];
/**
* Creates a VNode descriptor. Used as the JSX factory during renders.
*
* For intrinsic elements (string type), the returned VNode includes DOM-shim
* methods (`setAttribute`, `appendChild`, etc.) so that component code which
* creates intermediate JSX and calls DOM methods on it continues to work.
*
* @param type Tag name, Shade factory function, or null (fragment)
* @param props Element props / component props
* @param rawChildren Varargs children (strings, VNodes, arrays, etc.)
*/
export declare const createVNode: (type: string | ((...args: unknown[]) => unknown) | null, props: Record<string, unknown> | null, ...rawChildren: unknown[]) => VNode;
/**
* Shallow-compares two props objects. Returns true if all keys and values match.
*/
export declare const shallowEqual: (a: Record<string, unknown>, b: Record<string, unknown>) => boolean;
/**
* Converts a render result (VNode | HTMLElement | string | null) into a flat
* VChild array suitable for `patchChildren`.
*
* Real DOM elements can appear here when component state stores elements created
* outside renderMode (e.g. in async callbacks like NestedRouter's `updateUrl`).
*/
export declare const toVChildArray: (renderResult: unknown) => VChild[];
/**
* Diffs old and new props and applies minimal updates to a live DOM element.
*/
export declare const patchProps: (el: Element, oldProps: Record<string, unknown>, newProps: Record<string, unknown>) => void;
/**
* Creates real DOM nodes from a VChild and optionally appends to a parent.
* Sets `_el` on the VChild so subsequent patches can find the DOM node.
* @returns The created DOM node.
*/
export declare const mountChild: (child: VChild, parent: Node | null) => Node;
/**
* Removes the DOM node associated with a VChild from its parent.
*/
export declare const unmountChild: (child: VChild) => void;
/**
* Reconciles an array of old VChildren against new VChildren inside a parent
* DOM element. Patches matching pairs, removes excess old children, and
* mounts excess new children.
*
* **Note:** This uses positional (index-based) matching, not key-based
* reconciliation. Reordering list items will cause all children from the
* reorder point onward to be patched/replaced rather than moved. For
* dynamic lists where order changes frequently, wrap each item in its own
* Shade component so that the component boundary prevents unnecessary
* inner-DOM churn.
*/
export declare const patchChildren: (parentEl: Node, oldChildren: VChild[], newChildren: VChild[]) => void;
export {};
//# sourceMappingURL=vnode.d.ts.map