/** * Core TypeScript Type Definitions * * This file defines the fundamental types used across AppRun: * 1. Component Types * - View: Function that renders state to VDOM * - Action: Function that updates state (sync/async/generator) * - Update: Collection of actions (array or object format) * - ActionDef: Tuple definition for action arrays * * 2. Virtual DOM Types * - VNode: Virtual DOM node structure with tag/props/children * - VDOM: Union of possible VDOM types (false, string, VNode, array) * - Element: DOM element references (HTMLElement or string selector) * - TemplateResult: Lit-html template support * * 3. Configuration Types * - EventOptions: Event handler options (once, delay, transition) * - ActionOptions: Action behavior options (render, history, global, callback) * - MountOptions: Component mounting options (global events, routing, transitions) * - AppStartOptions: Application startup configuration with lifecycle hooks * * Features: * - Strong typing for component lifecycle * - Flexible action definition formats * - Comprehensive event options * - Integration with external libraries (lit-html) * - Type-safe component mounting * - Lifecycle hook typing * * Type Safety Improvements (v3.35.1): * - Enhanced generic constraints for better type inference * - Improved union types for VDOM flexibility * - Better callback typing in options * - Stricter typing for lifecycle methods * - Added support for async generator and generator functions in Action types * * Usage: * ```ts * class MyComponent extends Component { * view: View; * update: Update; * } * * // Type-safe action definitions with async generators * const update: Update = { * 'event': (state: State, ...args) => newState, * 'stream-event': async function* (state: State, ...args) { * yield { ...state, loading: true }; * const data = await fetchData(); * yield { ...state, data, loading: false }; * } * }; * ``` */ import { TemplateResult } from 'lit-html'; export type Element = HTMLElement | string; export type State = T | Promise | (() => T) | (() => Promise); export type VNode = { tag: string | Function, props: {}, children: Array } export type VDOM = false | string | VNode | Array | TemplateResult; export type View = (state: T) => VDOM | void; export type Action = (state: T, ...p: any[]) => T | Promise | void | AsyncGenerator | Generator; export type ActionDef = (readonly [E, Action, {}?]); export type Update = ActionDef[] | { [name: string]: Action | {}[] } | (E | Action | {})[]; export type ActionOptions = { render?: boolean, history?, global?: boolean; callback?: (state: any) => void; }; export type EventOptions = { once?: boolean; transition?: boolean; delay?: number; } | any; export type MountOptions = { render?: boolean, history?, global_event?: boolean, route?: string; transition?: boolean; }; export type AppStartOptions = { render?: boolean; history?; transition?: boolean; route?: string; rendered?: (state: T) => void mounted?: (props: any, children: any, state: T) => T }; export type Router = (url: string, ...args: any[]) => any; export type CustomElementOptions = { render?: boolean; shadow?: boolean; history?: boolean; global_event?: boolean; observedAttributes?: string[]; }; export interface IApp { // Event system methods on(name: string, fn: (...args: any[]) => any, options?: EventOptions): void; off(name: string, fn: (...args: any[]) => any): void; run(name: string, ...args: any[]): number; runAsync(name: string, ...args: any[]): Promise; once(name: string, fn: (...args: any[]) => any, options?: EventOptions): void; find(name: string): any; /** @deprecated Use runAsync() instead */ query(name: string, ...args: any[]): Promise; start(element?: Element | string, model?: T, view?: View, update?: Update, options?: AppStartOptions): any; h(tag: string | Function, props?: any, ...children: any[]): VNode | VNode[]; createElement(tag: string | Function, props?: any, ...children: any[]): VNode | VNode[]; render(element: Element | ShadowRoot, node: VNode, component?: {}): void; Fragment(props: any, ...children: any[]): any[]; route: Router; webComponent(name: string, componentClass: any, options?: CustomElementOptions): void; safeHTML(html: string): any[]; use_render(render: any, mode?: 0 | 1): void; use_react(React: any, ReactDOM: any): void; version: string; basePath?: string; addComponents: (element: Element | string, components: ComponentRoute) => void; } // Define what constitutes a mountable component interface ComponentLike { mount(element?: Element | string, options?: any): any; } // Define component constructor type type ComponentConstructor = new ( state?: T, view?: any, update?: any, options?: any ) => ComponentLike; // Enhanced ComponentRoute type with clear distinctions export type ComponentRoute = { [route: string]: | ComponentLike // Component instance | ComponentConstructor // Component class constructor | (() => ComponentLike | ComponentConstructor | Promise) // Factory function | ((...args: any[]) => any) // Event handler function };