@jasonshimmy/custom-elements-runtime 0.3.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,138 @@
1
+ import type { VNode } from "./runtime/types";
2
+ /**
3
+ * Conditional rendering with negated condition (opposite of when)
4
+ * @param cond - Boolean condition to negate
5
+ * @param children - Content to render when condition is false
6
+ */
7
+ export declare function unless(cond: boolean, children: VNode | VNode[]): VNode;
8
+ /**
9
+ * Render content only if array/collection is empty
10
+ * @param collection - Array or collection to check
11
+ * @param children - Content to render when empty
12
+ */
13
+ export declare function whenEmpty(collection: any[] | null | undefined, children: VNode | VNode[]): VNode;
14
+ /**
15
+ * Render content only if array/collection has items
16
+ * @param collection - Array or collection to check
17
+ * @param children - Content to render when not empty
18
+ */
19
+ export declare function whenNotEmpty(collection: any[] | null | undefined, children: VNode | VNode[]): VNode;
20
+ /**
21
+ * Enhanced each with filtering capability
22
+ * @param list - Array to iterate over
23
+ * @param predicate - Filter function (optional)
24
+ * @param render - Render function for each item
25
+ */
26
+ export declare function eachWhere<T>(list: T[], predicate: (item: T, index: number) => boolean, render: (item: T, index: number, filteredIndex: number) => VNode | VNode[]): VNode[];
27
+ /**
28
+ * Render different content based on array length
29
+ * @param list - Array to check
30
+ * @param cases - Object with length-based cases
31
+ */
32
+ export declare function switchOnLength<T>(list: T[], cases: {
33
+ empty?: VNode | VNode[];
34
+ one?: (item: T) => VNode | VNode[];
35
+ many?: (items: T[]) => VNode | VNode[];
36
+ exactly?: {
37
+ [count: number]: (items: T[]) => VNode | VNode[];
38
+ };
39
+ }): VNode;
40
+ /**
41
+ * Group array items and render each group
42
+ * @param list - Array to group
43
+ * @param groupBy - Function to determine group key
44
+ * @param renderGroup - Function to render each group
45
+ */
46
+ export declare function eachGroup<T, K extends string | number>(list: T[], groupBy: (item: T) => K, renderGroup: (groupKey: K, items: T[], groupIndex: number) => VNode | VNode[]): VNode[];
47
+ /**
48
+ * Render with pagination/chunking
49
+ * @param list - Array to chunk
50
+ * @param pageSize - Items per page/chunk
51
+ * @param currentPage - Current page (0-based)
52
+ * @param render - Render function for visible items
53
+ */
54
+ export declare function eachPage<T>(list: T[], pageSize: number, currentPage: number, render: (item: T, index: number, pageIndex: number) => VNode | VNode[]): VNode[];
55
+ /**
56
+ * Render content based on Promise state
57
+ * @param promiseState - Object with loading, data, error states
58
+ * @param cases - Render functions for each state
59
+ */
60
+ export declare function switchOnPromise<T, E = Error>(promiseState: {
61
+ loading?: boolean;
62
+ data?: T;
63
+ error?: E;
64
+ }, cases: {
65
+ loading?: VNode | VNode[];
66
+ success?: (data: T) => VNode | VNode[];
67
+ error?: (error: E) => VNode | VNode[];
68
+ idle?: VNode | VNode[];
69
+ }): VNode;
70
+ /**
71
+ * Render content based on screen size/media query
72
+ * @param mediaQuery - CSS media query string
73
+ * @param children - Content to render when media query matches
74
+ */
75
+ export declare function whenMedia(mediaQuery: string, children: VNode | VNode[]): VNode;
76
+ /**
77
+ * Media variants matching those in style.ts
78
+ */
79
+ export declare const mediaVariants: {
80
+ readonly sm: "(min-width:640px)";
81
+ readonly md: "(min-width:768px)";
82
+ readonly lg: "(min-width:1024px)";
83
+ readonly xl: "(min-width:1280px)";
84
+ readonly "2xl": "(min-width:1536px)";
85
+ readonly dark: "(prefers-color-scheme: dark)";
86
+ };
87
+ /**
88
+ * Responsive order matching style.ts
89
+ */
90
+ export declare const responsiveOrder: readonly ["sm", "md", "lg", "xl", "2xl"];
91
+ /**
92
+ * Individual responsive directives matching the style.ts breakpoint system
93
+ */
94
+ export declare const responsive: {
95
+ readonly sm: (children: VNode | VNode[]) => VNode;
96
+ readonly md: (children: VNode | VNode[]) => VNode;
97
+ readonly lg: (children: VNode | VNode[]) => VNode;
98
+ readonly xl: (children: VNode | VNode[]) => VNode;
99
+ readonly "2xl": (children: VNode | VNode[]) => VNode;
100
+ readonly dark: (children: VNode | VNode[]) => VNode;
101
+ readonly light: (children: VNode | VNode[]) => VNode;
102
+ readonly touch: (children: VNode | VNode[]) => VNode;
103
+ readonly mouse: (children: VNode | VNode[]) => VNode;
104
+ readonly reducedMotion: (children: VNode | VNode[]) => VNode;
105
+ readonly highContrast: (children: VNode | VNode[]) => VNode;
106
+ readonly portrait: (children: VNode | VNode[]) => VNode;
107
+ readonly landscape: (children: VNode | VNode[]) => VNode;
108
+ };
109
+ /**
110
+ * Advanced responsive directive that matches the style.ts multi-variant processing
111
+ * Allows chaining responsive and dark mode conditions like in CSS classes
112
+ * @param variants - Array of variant keys (e.g., ['dark', 'lg'])
113
+ * @param children - Content to render when all variants match
114
+ */
115
+ export declare function whenVariants(variants: Array<keyof typeof mediaVariants | 'light'>, children: VNode | VNode[]): VNode;
116
+ /**
117
+ * Responsive switch directive - render different content for different breakpoints
118
+ * Mirrors the responsive behavior from the style system
119
+ * @param content - Object with breakpoint keys and corresponding content
120
+ */
121
+ export declare function responsiveSwitch(content: {
122
+ base?: VNode | VNode[];
123
+ sm?: VNode | VNode[];
124
+ md?: VNode | VNode[];
125
+ lg?: VNode | VNode[];
126
+ xl?: VNode | VNode[];
127
+ "2xl"?: VNode | VNode[];
128
+ }): VNode[];
129
+ /**
130
+ * Enhanced match directive with more fluent API
131
+ * @param value - Value to match against
132
+ */
133
+ export declare function switchOn<T>(value: T): {
134
+ case(matcher: T | ((val: T) => boolean), content: VNode | VNode[]): /*elided*/ any;
135
+ when(predicate: (val: T) => boolean, content: VNode | VNode[]): /*elided*/ any;
136
+ otherwise(content: VNode | VNode[]): /*elided*/ any;
137
+ done(): VNode;
138
+ };
@@ -9,3 +9,8 @@ export declare function match(): {
9
9
  otherwise(content: VNode | VNode[]): /*elided*/ any;
10
10
  done(): VNode[];
11
11
  };
12
+ /**
13
+ * Create a stable anchor block with consistent boundaries.
14
+ * Always has start/end boundaries.
15
+ */
16
+ export declare function anchorBlock(children: VNode | VNode[] | null | undefined, anchorKey: string): VNode;
package/dist/index.d.ts CHANGED
@@ -1,15 +1,18 @@
1
1
  /**
2
2
  * Custom Elements Runtime
3
3
  * Lightweight, strongly typed, functional custom element runtime for two-way binding, event, and prop support.
4
- * Supports: state, computed, props, style, render, lifecycle hooks, :model and @event attributes.
4
+ * Supports: reactive props, computed, events, style, render, lifecycle hooks, :model and @event attributes.
5
5
  * No external dependencies. Mobile-first, secure, and developer friendly.
6
6
  */
7
- export * from "./runtime/types";
7
+ export { component } from "./runtime/component";
8
+ export { useEmit, useOnConnected, useOnDisconnected, useOnAttributeChanged, useOnError, useStyle } from "./runtime/hooks";
9
+ export { ref, computed, watch } from "./runtime/reactive";
10
+ export { html } from "./runtime/template-compiler";
11
+ export { css } from "./runtime/style";
12
+ export { renderToString } from "./runtime/vdom";
13
+ export type { VNode } from "./runtime/types";
8
14
  export * from "./directives";
15
+ export * from "./directive-enhancements";
9
16
  export * from "./event-bus";
10
17
  export * from "./store";
11
18
  export * from "./router";
12
- export { renderToString } from "./runtime/vdom";
13
- export { component } from "./runtime/component";
14
- export { css } from "./runtime/style";
15
- export { html } from "./runtime/template-compiler";
@@ -1,4 +1,4 @@
1
- import type { ComponentConfig, ComponentContext } from "./types";
1
+ import type { ComponentConfig, VNode } from "./types";
2
2
  /**
3
3
  * @internal
4
4
  * Runtime registry of component configs.
@@ -7,7 +7,44 @@ import type { ComponentConfig, ComponentContext } from "./types";
7
7
  * internal tests only. Consumers should use the public `component` API.
8
8
  */
9
9
  export declare const registry: Map<string, ComponentConfig<any, any, any>>;
10
- export declare function component<S extends object = {}, C extends object = {}, P extends object = {}, T extends object = any>(tag: string, renderOrConfig: ((context: ComponentContext<S, C, P, T>) => any) | ComponentConfig<S, C, P, T>, config?: Partial<ComponentConfig<S, C, P, T>>): void;
11
10
  export declare function createElementClass<S extends object, C extends object, P extends object, T extends object = any>(tag: string, config: ComponentConfig<S, C, P, T>): CustomElementConstructor | {
12
11
  new (): object;
13
12
  };
13
+ /**
14
+ * Streamlined functional component API with automatic reactive props and lifecycle hooks.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * // Simple component with no parameters
19
+ * component('simple-header', () => {
20
+ * return html`<h1>Hello World</h1>`;
21
+ * });
22
+ *
23
+ * // With props only
24
+ * component('with-props', ({ message = 'Hello' }) => {
25
+ * return html`<div>${message}</div>`;
26
+ * });
27
+ *
28
+ * // With props and hooks
29
+ * component('my-switch', ({
30
+ * modelValue = false,
31
+ * label = ''
32
+ * }, { emit, onConnected, onDisconnected }) => {
33
+ * onConnected(() => console.log('Switch connected!'));
34
+ * onDisconnected(() => console.log('Switch disconnected!'));
35
+ *
36
+ * return html`
37
+ * <label>
38
+ * ${label}
39
+ * <input
40
+ * type="checkbox"
41
+ * :checked="${modelValue}"
42
+ * @change="${(e) => emit('update:modelValue', e.target.checked)}"
43
+ * />
44
+ * </label>
45
+ * `;
46
+ * });
47
+ * ```
48
+ */
49
+ export declare function component(tag: string, renderFn: () => VNode | VNode[] | Promise<VNode | VNode[]>): void;
50
+ export declare function component<TProps extends Record<string, any> = {}>(tag: string, renderFn: (props: TProps) => VNode | VNode[] | Promise<VNode | VNode[]>): void;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Event Manager for tracking and cleaning up event listeners
3
+ * Prevents memory leaks by maintaining cleanup functions
4
+ */
5
+ /**
6
+ * Manages event listeners and their cleanup for elements
7
+ */
8
+ declare class EventManager {
9
+ private static cleanupFunctions;
10
+ /**
11
+ * Add an event listener with automatic cleanup tracking
12
+ */
13
+ static addListener(element: HTMLElement, event: string, handler: EventListener, options?: AddEventListenerOptions): void;
14
+ /**
15
+ * Remove a specific event listener
16
+ */
17
+ static removeListener(element: HTMLElement, event: string, handler: EventListener, options?: EventListenerOptions): void;
18
+ /**
19
+ * Clean up all event listeners for an element
20
+ */
21
+ static cleanup(element: HTMLElement): void;
22
+ /**
23
+ * Clean up all tracked event listeners (useful for testing)
24
+ */
25
+ static cleanupAll(): void;
26
+ /**
27
+ * Check if an element has any tracked event listeners
28
+ */
29
+ static hasListeners(element: HTMLElement): boolean;
30
+ /**
31
+ * Get the number of tracked event listeners for an element
32
+ */
33
+ static getListenerCount(element: HTMLElement): number;
34
+ }
35
+ /**
36
+ * Enhanced event listener tracker that stores more metadata
37
+ * for better debugging and cleanup
38
+ */
39
+ interface EventListenerMetadata {
40
+ event: string;
41
+ handler: EventListener;
42
+ options?: AddEventListenerOptions;
43
+ cleanup: () => void;
44
+ addedAt: number;
45
+ }
46
+ declare class DetailedEventManager {
47
+ private static listeners;
48
+ static addListener(element: HTMLElement, event: string, handler: EventListener, options?: AddEventListenerOptions): void;
49
+ static removeListener(element: HTMLElement, event: string, handler: EventListener, options?: EventListenerOptions): boolean;
50
+ static cleanup(element: HTMLElement): void;
51
+ static getListenerInfo(element: HTMLElement): EventListenerMetadata[];
52
+ static findStaleListeners(_maxAge?: number): Array<{
53
+ element: HTMLElement;
54
+ listeners: EventListenerMetadata[];
55
+ }>;
56
+ }
57
+ export { EventManager, DetailedEventManager };
58
+ export type { EventListenerMetadata };
@@ -1,4 +1,23 @@
1
+ /**
2
+ * Convert camelCase to kebab-case with caching
3
+ */
1
4
  export declare function toKebab(str: string): string;
5
+ /**
6
+ * Convert kebab-case to camelCase with caching
7
+ */
8
+ export declare function toCamel(str: string): string;
9
+ /**
10
+ * Clear string transformation caches (useful for testing)
11
+ */
12
+ export declare function clearStringCaches(): void;
13
+ /**
14
+ * Get cache statistics for debugging
15
+ */
16
+ export declare function getStringCacheStats(): {
17
+ kebabCacheSize: number;
18
+ camelCacheSize: number;
19
+ htmlEscapeCacheSize: number;
20
+ };
2
21
  export declare function escapeHTML(str: string | number | boolean): string | number | boolean;
3
22
  /**
4
23
  * Get nested property value from object using dot notation
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Context-based hooks for functional components
3
+ * Provides React-like hooks with perfect TypeScript inference
4
+ */
5
+ /**
6
+ * Set the current component context (called internally during render)
7
+ * @internal
8
+ */
9
+ export declare function setCurrentComponentContext(context: any): void;
10
+ /**
11
+ * Clear the current component context (called internally after render)
12
+ * @internal
13
+ */
14
+ export declare function clearCurrentComponentContext(): void;
15
+ /**
16
+ * Get the emit function for the current component
17
+ * Must be called during component render
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * component('my-button', ({ label = 'Click me' }) => {
22
+ * const emit = useEmit();
23
+ *
24
+ * return html`
25
+ * <button @click="${() => emit('button-click', { label })}">
26
+ * ${label}
27
+ * </button>
28
+ * `;
29
+ * });
30
+ * ```
31
+ */
32
+ export declare function useEmit(): (eventName: string, detail?: any) => boolean;
33
+ /**
34
+ * Register a callback to be called when component is connected to DOM
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * component('my-component', () => {
39
+ * useOnConnected(() => {
40
+ * console.log('Component mounted!');
41
+ * });
42
+ *
43
+ * return html`<div>Hello World</div>`;
44
+ * });
45
+ * ```
46
+ */
47
+ export declare function useOnConnected(callback: () => void): void;
48
+ /**
49
+ * Register a callback to be called when component is disconnected from DOM
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * component('my-component', () => {
54
+ * useOnDisconnected(() => {
55
+ * console.log('Component unmounted!');
56
+ * });
57
+ *
58
+ * return html`<div>Goodbye World</div>`;
59
+ * });
60
+ * ```
61
+ */
62
+ export declare function useOnDisconnected(callback: () => void): void;
63
+ /**
64
+ * Register a callback to be called when an attribute changes
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * component('my-component', () => {
69
+ * useOnAttributeChanged((name, oldValue, newValue) => {
70
+ * console.log(`Attribute ${name} changed from ${oldValue} to ${newValue}`);
71
+ * });
72
+ *
73
+ * return html`<div>Attribute watcher</div>`;
74
+ * });
75
+ * ```
76
+ */
77
+ export declare function useOnAttributeChanged(callback: (name: string, oldValue: string | null, newValue: string | null) => void): void;
78
+ /**
79
+ * Register a callback to be called when an error occurs
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * component('my-component', () => {
84
+ * useOnError((error) => {
85
+ * console.error('Component error:', error);
86
+ * });
87
+ *
88
+ * return html`<div>Error handler</div>`;
89
+ * });
90
+ * ```
91
+ */
92
+ export declare function useOnError(callback: (error: Error) => void): void;
93
+ /**
94
+ * Register a style function that will be called during each render
95
+ * to provide reactive styles for the component
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * import { css } from '@lib/style';
100
+ *
101
+ * component('my-component', ({ theme = 'light' }) => {
102
+ * useStyle(() => css`
103
+ * :host {
104
+ * background: ${theme === 'light' ? 'white' : 'black'};
105
+ * color: ${theme === 'light' ? 'black' : 'white'};
106
+ * }
107
+ * `);
108
+ *
109
+ * return html`<div>Styled component</div>`;
110
+ * });
111
+ * ```
112
+ */
113
+ export declare function useStyle(callback: () => string): void;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Development-only logging utilities
3
+ * These are stripped out in production builds via bundler configuration
4
+ */
5
+ /**
6
+ * Log error only in development mode
7
+ */
8
+ export declare function devError(message: string, ...args: any[]): void;
9
+ /**
10
+ * Log warning only in development mode
11
+ */
12
+ export declare function devWarn(message: string, ...args: any[]): void;
13
+ /**
14
+ * Log info only in development mode
15
+ */
16
+ export declare function devLog(message: string, ...args: any[]): void;
@@ -1,6 +1,18 @@
1
1
  import type { ComponentConfig, ComponentContext } from "./types";
2
+ export type PropDefinition = {
3
+ type: StringConstructor | NumberConstructor | BooleanConstructor | FunctionConstructor;
4
+ default?: string | number | boolean;
5
+ };
2
6
  /**
3
- * Applies props to the component context.
7
+ * Applies props to the component context using a direct prop definitions object.
8
+ * @param element - The custom element instance.
9
+ * @param propDefinitions - Object mapping prop names to their definitions.
10
+ * @param context - The component context.
11
+ */
12
+ export declare function applyPropsFromDefinitions(element: HTMLElement, propDefinitions: Record<string, PropDefinition>, context: any): void;
13
+ /**
14
+ * Legacy function for ComponentConfig compatibility.
15
+ * Applies props to the component context using a ComponentConfig.
4
16
  * @param element - The custom element instance.
5
17
  * @param cfg - The component config.
6
18
  * @param context - The component context.
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Reactive proxy cache to optimize proxy creation and reuse
3
+ * Uses WeakMap for automatic garbage collection when objects are no longer referenced
4
+ */
5
+ declare class ReactiveProxyCache {
6
+ private static cache;
7
+ private static arrayHandlerCache;
8
+ private static objectHandlerCache;
9
+ /**
10
+ * Get or create a reactive proxy for an object
11
+ */
12
+ static getOrCreateProxy<T extends object>(obj: T, reactiveState: any, isArray?: boolean): T;
13
+ /**
14
+ * Get or create a cached array handler
15
+ */
16
+ private static getOrCreateArrayHandler;
17
+ /**
18
+ * Get or create a cached object handler
19
+ */
20
+ private static getOrCreateObjectHandler;
21
+ /**
22
+ * Check if an object already has a cached proxy
23
+ */
24
+ static hasProxy(obj: object): boolean;
25
+ /**
26
+ * Clear all cached proxies (useful for testing)
27
+ */
28
+ static clear(): void;
29
+ /**
30
+ * Get cache statistics (for debugging)
31
+ * Note: WeakMap doesn't provide size, so this is limited
32
+ */
33
+ static getStats(): {
34
+ hasCachedProxies: boolean;
35
+ };
36
+ }
37
+ /**
38
+ * Optimized proxy creation utilities
39
+ */
40
+ declare class ProxyOptimizer {
41
+ private static contextCache;
42
+ /**
43
+ * Create an optimized reactive proxy with minimal overhead
44
+ */
45
+ static createReactiveProxy<T extends object>(obj: T, onUpdate: () => void, makeReactive: (value: any) => any): T;
46
+ /**
47
+ * Mark an object as a proxy (for optimization)
48
+ */
49
+ static markAsProxy(obj: any): void;
50
+ }
51
+ export { ReactiveProxyCache, ProxyOptimizer };
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Global reactive system for tracking dependencies and triggering updates
3
+ */
4
+ declare class ReactiveSystem {
5
+ private currentComponent;
6
+ private componentDependencies;
7
+ private componentRenderFunctions;
8
+ private stateStorage;
9
+ private stateIndexCounter;
10
+ private trackingDisabled;
11
+ private lastWarningTime;
12
+ /**
13
+ * Set the current component being rendered for dependency tracking
14
+ */
15
+ setCurrentComponent(componentId: string, renderFn: () => void): void;
16
+ /**
17
+ * Clear the current component after rendering
18
+ */
19
+ clearCurrentComponent(): void;
20
+ /**
21
+ * Temporarily disable dependency tracking
22
+ */
23
+ disableTracking(): void;
24
+ /**
25
+ * Re-enable dependency tracking
26
+ */
27
+ enableTracking(): void;
28
+ /**
29
+ * Check if a component is currently rendering
30
+ */
31
+ isRenderingComponent(): boolean;
32
+ /**
33
+ * Return whether we should emit a render-time warning for the current component.
34
+ * This throttles warnings to avoid spamming the console for legitimate rapid updates.
35
+ */
36
+ shouldEmitRenderWarning(): boolean;
37
+ /**
38
+ * Execute a function with tracking disabled
39
+ */
40
+ withoutTracking<T>(fn: () => T): T;
41
+ /**
42
+ * Get or create a state instance for the current component
43
+ */
44
+ getOrCreateState<T>(initialValue: T): ReactiveState<T>;
45
+ /**
46
+ * Track a dependency for the current component
47
+ */
48
+ trackDependency(state: ReactiveState<any>): void;
49
+ /**
50
+ * Trigger updates for all components that depend on a state
51
+ */
52
+ triggerUpdate(state: ReactiveState<any>): void;
53
+ /**
54
+ * Clean up component dependencies when component is destroyed
55
+ */
56
+ cleanup(componentId: string): void;
57
+ }
58
+ declare const reactiveSystem: ReactiveSystem;
59
+ export { reactiveSystem };
60
+ /**
61
+ * Internal reactive state class
62
+ */
63
+ export declare class ReactiveState<T> {
64
+ private _value;
65
+ private dependents;
66
+ constructor(initialValue: T);
67
+ get value(): T;
68
+ set value(newValue: T);
69
+ addDependent(componentId: string): void;
70
+ removeDependent(componentId: string): void;
71
+ getDependents(): Set<string>;
72
+ private makeReactive;
73
+ }
74
+ /**
75
+ * Create reactive state that automatically triggers component re-renders
76
+ * when accessed during render and modified afterwards.
77
+ * Defaults to null if no initial value is provided (Vue-style ref).
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const counter = ref(0);
82
+ * const user = ref({ name: 'John', age: 30 });
83
+ * const emptyRef = ref(); // defaults to null
84
+ *
85
+ * // Usage in component
86
+ * counter.value++; // triggers re-render
87
+ * user.value.name = 'Jane'; // triggers re-render
88
+ * console.log(emptyRef.value); // null
89
+ * ```
90
+ */
91
+ export declare function ref<T = null>(initialValue?: T): ReactiveState<T extends undefined ? null : T>;
92
+ /**
93
+ * Create computed state that derives from other reactive state
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * const firstName = ref('John');
98
+ * const lastName = ref('Doe');
99
+ * const fullName = computed(() => `${firstName.value} ${lastName.value}`);
100
+ * ```
101
+ */
102
+ export declare function computed<T>(fn: () => T): {
103
+ readonly value: T;
104
+ };
105
+ /**
106
+ * Create a watcher that runs when dependencies change
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * const count = ref(0);
111
+ * watch(() => count.value, (newVal, oldVal) => {
112
+ * console.log(`Count changed from ${oldVal} to ${newVal}`);
113
+ * });
114
+ * ```
115
+ */
116
+ export declare function watch<T>(source: () => T, callback: (newValue: T, oldValue: T) => void, options?: {
117
+ immediate?: boolean;
118
+ }): () => void;
@@ -9,10 +9,10 @@ export declare function renderComponent<S extends object, C extends object, P ex
9
9
  */
10
10
  export declare function renderOutput<S extends object, C extends object, P extends object, T extends object>(shadowRoot: ShadowRoot | null, output: VNode | VNode[], context: ComponentContext<S, C, P, T>, refs: Refs["refs"], setHtmlString: (html: string) => void): void;
11
11
  /**
12
- * Debounced render request.
12
+ * Debounced render request with infinite loop protection.
13
13
  */
14
14
  export declare function requestRender(renderFn: () => void, lastRenderTime: number, renderCount: number, setLastRenderTime: (t: number) => void, setRenderCount: (c: number) => void, renderTimeoutId: ReturnType<typeof setTimeout> | null, setRenderTimeoutId: (id: ReturnType<typeof setTimeout> | null) => void): void;
15
15
  /**
16
16
  * Applies styles to the shadowRoot.
17
17
  */
18
- export declare function applyStyle<S extends object, C extends object, P extends object, T extends object>(shadowRoot: ShadowRoot | null, cfg: ComponentConfig<S, C, P, T>, context: ComponentContext<S, C, P, T>, htmlString: string, styleSheet: CSSStyleSheet | null, setStyleSheet: (sheet: CSSStyleSheet | null) => void): void;
18
+ export declare function applyStyle<S extends object, C extends object, P extends object, T extends object>(shadowRoot: ShadowRoot | null, context: ComponentContext<S, C, P, T>, htmlString: string, styleSheet: CSSStyleSheet | null, setStyleSheet: (sheet: CSSStyleSheet | null) => void): void;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Update Scheduler for batching DOM updates
3
+ * Prevents excessive re-renders and improves performance
4
+ */
5
+ declare class UpdateScheduler {
6
+ private pendingUpdates;
7
+ private isFlushScheduled;
8
+ /**
9
+ * Schedule an update to be executed in the next microtask
10
+ * Uses component identity to deduplicate multiple render requests for the same component
11
+ */
12
+ schedule(update: () => void, componentId?: string): void;
13
+ /**
14
+ * Execute all pending updates
15
+ */
16
+ private flush;
17
+ /**
18
+ * Get the number of pending updates
19
+ */
20
+ get pendingCount(): number;
21
+ }
22
+ export declare const updateScheduler: UpdateScheduler;
23
+ /**
24
+ * Schedule a DOM update to be batched with optional component identity
25
+ */
26
+ export declare function scheduleDOMUpdate(update: () => void, componentId?: string): void;
27
+ export {};