@jasonshimmy/custom-elements-runtime 2.5.2 → 2.5.6

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.
Files changed (94) hide show
  1. package/README.md +115 -40
  2. package/dist/css/colors.d.ts +14 -0
  3. package/dist/custom-elements-runtime.cjs.js +6 -1
  4. package/dist/custom-elements-runtime.cjs.js.map +1 -1
  5. package/dist/custom-elements-runtime.colors.cjs.js +2 -0
  6. package/dist/custom-elements-runtime.colors.cjs.js.map +1 -0
  7. package/dist/custom-elements-runtime.colors.es.js +279 -0
  8. package/dist/custom-elements-runtime.colors.es.js.map +1 -0
  9. package/dist/custom-elements-runtime.directive-enhancements.es.js +1 -1
  10. package/dist/custom-elements-runtime.es.js +258 -166
  11. package/dist/custom-elements-runtime.es.js.map +1 -1
  12. package/dist/custom-elements-runtime.event-bus.cjs.js +1 -1
  13. package/dist/custom-elements-runtime.event-bus.cjs.js.map +1 -1
  14. package/dist/custom-elements-runtime.event-bus.es.js +28 -25
  15. package/dist/custom-elements-runtime.event-bus.es.js.map +1 -1
  16. package/dist/custom-elements-runtime.router.cjs.js +20 -20
  17. package/dist/custom-elements-runtime.router.cjs.js.map +1 -1
  18. package/dist/custom-elements-runtime.router.es.js +549 -531
  19. package/dist/custom-elements-runtime.router.es.js.map +1 -1
  20. package/dist/custom-elements-runtime.ssr.cjs.js +1 -1
  21. package/dist/custom-elements-runtime.ssr.es.js +12 -8
  22. package/dist/custom-elements-runtime.ssr.es.js.map +1 -1
  23. package/dist/custom-elements-runtime.store.cjs.js +1 -1
  24. package/dist/custom-elements-runtime.store.cjs.js.map +1 -1
  25. package/dist/custom-elements-runtime.store.es.js +5 -5
  26. package/dist/custom-elements-runtime.store.es.js.map +1 -1
  27. package/dist/custom-elements-runtime.transitions.cjs.js +1 -1
  28. package/dist/custom-elements-runtime.transitions.es.js +1 -1
  29. package/dist/event-bus.d.ts +17 -4
  30. package/dist/index.d.ts +13 -5
  31. package/dist/keep-alive.d.ts +50 -0
  32. package/dist/{logger-BuUYv7C_.js → logger-BvkEbVM4.js} +15 -11
  33. package/dist/logger-BvkEbVM4.js.map +1 -0
  34. package/dist/logger-CSALKaYm.cjs +2 -0
  35. package/dist/logger-CSALKaYm.cjs.map +1 -0
  36. package/dist/namespace-helpers-4qeKVqQw.cjs +5 -0
  37. package/dist/namespace-helpers-4qeKVqQw.cjs.map +1 -0
  38. package/dist/namespace-helpers-DcD_6_K1.js +989 -0
  39. package/dist/namespace-helpers-DcD_6_K1.js.map +1 -0
  40. package/dist/router/active-proxy.d.ts +5 -0
  41. package/dist/router/component-loader.d.ts +11 -0
  42. package/dist/router/instance.d.ts +11 -0
  43. package/dist/router/matcher.d.ts +14 -0
  44. package/dist/router/path-utils.d.ts +48 -0
  45. package/dist/router/types.d.ts +134 -0
  46. package/dist/router.d.ts +6 -208
  47. package/dist/runtime/builtin-components.d.ts +78 -0
  48. package/dist/runtime/component/element-class.d.ts +4 -0
  49. package/dist/runtime/component/factory.d.ts +39 -0
  50. package/dist/runtime/component/registry.d.ts +16 -0
  51. package/dist/runtime/component.d.ts +3 -50
  52. package/dist/runtime/discovery-state.d.ts +30 -0
  53. package/dist/runtime/hooks.d.ts +115 -0
  54. package/dist/runtime/logger.d.ts +19 -1
  55. package/dist/runtime/monitoring/health-monitor.d.ts +22 -65
  56. package/dist/runtime/reactive.d.ts +39 -7
  57. package/dist/runtime/render.d.ts +20 -4
  58. package/dist/runtime/scheduler.d.ts +69 -2
  59. package/dist/runtime/template-compiler/impl.d.ts +14 -0
  60. package/dist/runtime/template-compiler/lru-cache.d.ts +20 -0
  61. package/dist/runtime/template-compiler/props-parser.d.ts +15 -0
  62. package/dist/runtime/template-compiler/vnode-utils.d.ts +5 -0
  63. package/dist/runtime/template-compiler.d.ts +5 -28
  64. package/dist/runtime/types.d.ts +10 -0
  65. package/dist/runtime/vdom-directives.d.ts +71 -0
  66. package/dist/runtime/vdom-helpers.d.ts +126 -0
  67. package/dist/runtime/vdom-patch.d.ts +67 -0
  68. package/dist/runtime/vdom.d.ts +16 -140
  69. package/dist/ssr.d.ts +2 -1
  70. package/dist/teleport.d.ts +68 -0
  71. package/dist/template-compiler-BO8UEEDA.js +3984 -0
  72. package/dist/template-compiler-BO8UEEDA.js.map +1 -0
  73. package/dist/template-compiler-C4L8vT-6.cjs +23 -0
  74. package/dist/template-compiler-C4L8vT-6.cjs.map +1 -0
  75. package/dist/transitions-DPZiuXb9.cjs +330 -0
  76. package/dist/transitions-DPZiuXb9.cjs.map +1 -0
  77. package/dist/{transitions-Bx0Nc9zR.js → transitions-Di5wW9yc.js} +1072 -632
  78. package/dist/transitions-Di5wW9yc.js.map +1 -0
  79. package/dist/transitions.d.ts +1 -1
  80. package/package.json +18 -11
  81. package/dist/logger-BuUYv7C_.js.map +0 -1
  82. package/dist/logger-DiXdWaF-.cjs +0 -2
  83. package/dist/logger-DiXdWaF-.cjs.map +0 -1
  84. package/dist/namespace-helpers-BCVTzhAO.cjs +0 -5
  85. package/dist/namespace-helpers-BCVTzhAO.cjs.map +0 -1
  86. package/dist/namespace-helpers-CF28TyaG.js +0 -786
  87. package/dist/namespace-helpers-CF28TyaG.js.map +0 -1
  88. package/dist/template-compiler-CXHEnaBh.cjs +0 -17
  89. package/dist/template-compiler-CXHEnaBh.cjs.map +0 -1
  90. package/dist/template-compiler-DD_VZrte.js +0 -3729
  91. package/dist/template-compiler-DD_VZrte.js.map +0 -1
  92. package/dist/transitions-Bx0Nc9zR.js.map +0 -1
  93. package/dist/transitions-DfcqL-X4.cjs +0 -302
  94. package/dist/transitions-DfcqL-X4.cjs.map +0 -1
@@ -16,84 +16,41 @@ interface HealthReport {
16
16
  timestamp: number;
17
17
  recommendations: string[];
18
18
  }
19
- export declare class HealthMonitor {
20
- private metrics;
21
- private readonly maxHistorySize;
22
- private readonly checkInterval;
23
- private intervalId;
24
- private listeners;
25
- constructor();
26
- /**
27
- * Initialize default health metrics
28
- */
29
- private initializeMetrics;
30
- /**
31
- * Add a new health metric
32
- */
33
- private addMetric;
34
- /**
35
- * Update a specific health metric
36
- */
19
+ export type { HealthReport };
20
+ /**
21
+ * Public interface for a health monitor instance.
22
+ * All state is managed internally via closures — no class syntax.
23
+ */
24
+ export interface HealthMonitorInstance {
25
+ /** Update a specific health metric value */
37
26
  updateMetric(name: string, value: number): void;
38
- /**
39
- * Calculate health status based on value and threshold
40
- */
41
- private calculateStatus;
42
- /**
43
- * Get current health report
44
- */
27
+ /** Get the current health report */
45
28
  getHealthReport(): HealthReport;
46
- /**
47
- * Generate actionable recommendations based on metrics
48
- */
49
- private generateRecommendations;
50
- /**
51
- * Start periodic health monitoring
52
- */
53
- private startMonitoring;
54
- /**
55
- * Perform comprehensive health check
56
- */
57
- private performHealthCheck;
58
- /**
59
- * Update memory-related metrics
60
- */
61
- private updateMemoryMetrics;
62
- /**
63
- * Add health report listener
64
- */
29
+ /** Add a listener to be notified when a health check runs */
65
30
  addListener(listener: (report: HealthReport) => void): void;
66
- /**
67
- * Remove health report listener
68
- */
31
+ /** Remove a previously registered listener */
69
32
  removeListener(listener: (report: HealthReport) => void): void;
70
- /**
71
- * Notify all listeners of health report
72
- */
73
- private notifyListeners;
74
- /**
75
- * Stop health monitoring
76
- */
33
+ /** Stop the periodic health monitoring timer */
77
34
  stop(): void;
78
- /**
79
- * Get specific metric history for analysis
80
- */
35
+ /** Get historical values for a specific metric */
81
36
  getMetricHistory(name: string): number[];
82
- /**
83
- * Clear all metrics history
84
- */
37
+ /** Clear all metric history */
85
38
  clearHistory(): void;
86
39
  }
87
40
  /**
88
- * Get the global health monitor instance
41
+ * Create a new health monitor instance.
42
+ * All mutable state lives in closures — no `class` or `this`.
43
+ */
44
+ export declare function createHealthMonitor(): HealthMonitorInstance;
45
+ /**
46
+ * Get the global health monitor singleton instance.
89
47
  */
90
- export declare function getHealthMonitor(): HealthMonitor;
48
+ export declare function getHealthMonitor(): HealthMonitorInstance;
91
49
  /**
92
- * Update a health metric from anywhere in the framework
50
+ * Update a health metric from anywhere in the framework.
93
51
  */
94
52
  export declare function updateHealthMetric(name: string, value: number): void;
95
53
  /**
96
- * Get current health status
54
+ * Get the current health status report.
97
55
  */
98
56
  export declare function getHealthStatus(): HealthReport;
99
- export {};
@@ -1,3 +1,4 @@
1
+ import type { WatchOptions } from './types';
1
2
  /**
2
3
  * Global reactive system for tracking dependencies and triggering updates
3
4
  */
@@ -71,6 +72,22 @@ export declare class ReactiveState<T> {
71
72
  constructor(initialValue: T);
72
73
  get value(): T;
73
74
  set value(newValue: T);
75
+ /**
76
+ * Read the current value without registering a reactive dependency.
77
+ * Useful for internal infrastructure (e.g. stable hook slots) that must
78
+ * inspect the stored value without re-triggering the containing component.
79
+ * @internal
80
+ */
81
+ peek(): T;
82
+ /**
83
+ * Set the initial value without triggering any reactive updates or warnings.
84
+ * Only intended for internal/infrastructure use (e.g. storing a stable hook
85
+ * handle in a reactive slot without causing a spurious re-render).
86
+ * The value is stored as-is without reactive proxy wrapping so that opaque
87
+ * objects (e.g. TeleportHandle) are not accidentally instrumented.
88
+ * @internal
89
+ */
90
+ initSilent(value: T): void;
74
91
  addDependent(componentId: string): void;
75
92
  removeDependent(componentId: string): void;
76
93
  getDependents(): Set<string>;
@@ -101,18 +118,37 @@ export declare function ref<T>(initialValue: T): ReactiveState<T>;
101
118
  */
102
119
  export declare function isReactiveState(v: unknown): v is ReactiveState<unknown>;
103
120
  /**
104
- * Create computed state that derives from other reactive state
121
+ * Create computed state that derives from other reactive state.
122
+ * The result is cached and only recomputed when tracked reactive dependencies change.
105
123
  *
106
124
  * @example
107
125
  * ```ts
108
126
  * const firstName = ref('John');
109
127
  * const lastName = ref('Doe');
110
128
  * const fullName = computed(() => `${firstName.value} ${lastName.value}`);
129
+ * console.log(fullName.value); // 'John Doe' — cached until firstName or lastName changes
111
130
  * ```
112
131
  */
113
132
  export declare function computed<T>(fn: () => T): {
114
133
  readonly value: T;
115
134
  };
135
+ /**
136
+ * Run a side-effect function immediately and automatically re-run it whenever
137
+ * any reactive state accessed inside `fn` changes. Similar to Vue's `watchEffect`.
138
+ *
139
+ * @returns A cleanup function that stops the effect.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const count = ref(0);
144
+ * const stop = watchEffect(() => {
145
+ * document.title = `Count: ${count.value}`;
146
+ * });
147
+ * count.value++; // automatically re-runs the effect
148
+ * stop(); // cancel the effect
149
+ * ```
150
+ */
151
+ export declare function watchEffect(fn: () => void): () => void;
116
152
  /**
117
153
  * Create a watcher that runs when dependencies change
118
154
  *
@@ -124,9 +160,5 @@ export declare function computed<T>(fn: () => T): {
124
160
  * });
125
161
  * ```
126
162
  */
127
- export declare function watch<T>(source: ReactiveState<T>, callback: (newValue: T, oldValue?: T) => void, options?: {
128
- immediate?: boolean;
129
- }): () => void;
130
- export declare function watch<T>(source: () => T, callback: (newValue: T, oldValue?: T) => void, options?: {
131
- immediate?: boolean;
132
- }): () => void;
163
+ export declare function watch<T>(source: ReactiveState<T>, callback: (newValue: T, oldValue?: T) => void, options?: WatchOptions): () => void;
164
+ export declare function watch<T>(source: () => T, callback: (newValue: T, oldValue?: T) => void, options?: WatchOptions): () => void;
@@ -11,18 +11,34 @@ export declare function registerChildComponent(shadowRoot: ShadowRoot, childEl:
11
11
  */
12
12
  export declare function unregisterChildComponent(shadowRoot: ShadowRoot, childEl: HTMLElement): void;
13
13
  /**
14
- * Renders the component output.
14
+ * Renders the component output with optimized error handling and loading states.
15
15
  */
16
16
  export declare function renderComponent<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>, refs: Refs['refs'], setHtmlString: (html: string) => void, setLoading: (val: boolean) => void, setError: (err: Error | null) => void, applyStyle: (html: string) => void): void;
17
17
  /**
18
- * Renders VNode(s) to the shadowRoot.
18
+ * Renders VNode(s) to the shadowRoot with performance optimizations.
19
19
  */
20
20
  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;
21
21
  /**
22
- * Debounced render request with infinite loop protection.
22
+ * Advanced render request with intelligent throttling and loop detection.
23
23
  */
24
24
  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;
25
25
  /**
26
- * Applies styles to the shadowRoot with improved structure and maintainability.
26
+ * Optimized style application with intelligent caching and generation tracking.
27
27
  */
28
28
  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;
29
+ /**
30
+ * Clean up render-related caches for a shadow root
31
+ * @internal
32
+ */
33
+ export declare function cleanupRenderCaches(shadowRoot: ShadowRoot): void;
34
+ /**
35
+ * Get render performance metrics for debugging
36
+ * @internal
37
+ */
38
+ export declare function getRenderStats(shadowRoot: ShadowRoot): {
39
+ renderCount: number;
40
+ lastRenderTime: number;
41
+ isThrottled: boolean;
42
+ childComponentCount: number;
43
+ hasCachedHtml: boolean;
44
+ };
@@ -1,3 +1,12 @@
1
+ /**
2
+ * Scheduling priority for update tasks.
3
+ *
4
+ * - `'immediate'` — Run synchronously before returning (use sparingly).
5
+ * - `'normal'` — Batch via microtask (default).
6
+ * - `'idle'` — Defer to browser idle time via `requestIdleCallback`
7
+ * (time-sliced, non-blocking rendering for low-priority work).
8
+ */
9
+ export type UpdatePriority = 'immediate' | 'normal' | 'idle';
1
10
  declare class UpdateScheduler {
2
11
  private pendingUpdates;
3
12
  private isFlushScheduled;
@@ -6,6 +15,8 @@ declare class UpdateScheduler {
6
15
  private lastCleanup;
7
16
  private readonly CLEANUP_INTERVAL;
8
17
  private readonly MAX_PENDING_SIZE;
18
+ private pendingIdleUpdates;
19
+ private idleCallbackHandle;
9
20
  constructor();
10
21
  /**
11
22
  * Schedule an update to be executed in the next microtask
@@ -17,7 +28,8 @@ declare class UpdateScheduler {
17
28
  */
18
29
  private scheduleFlush;
19
30
  /**
20
- * Execute all pending updates
31
+ * Execute all pending updates with priority ordering
32
+ * Execute all pending updates with priority ordering
21
33
  */
22
34
  private flush;
23
35
  /**
@@ -52,12 +64,54 @@ declare class UpdateScheduler {
52
64
  * Emergency cleanup when pending updates exceed safe limits
53
65
  */
54
66
  private performEmergencyCleanup;
67
+ /**
68
+ * Schedule an update with an explicit priority level.
69
+ *
70
+ * - `'immediate'` — Runs synchronously before returning.
71
+ * - `'normal'` — Default microtask batching (same as `schedule()`).
72
+ * - `'idle'` — Deferred to browser idle time via `requestIdleCallback`
73
+ * with time-slicing to avoid blocking the main thread.
74
+ * Falls back to a 5 ms `setTimeout` when
75
+ * `requestIdleCallback` is unavailable (e.g. Safari < 16).
76
+ *
77
+ * @example Defer a low-priority analytics flush
78
+ * ```ts
79
+ * scheduleWithPriority(() => flushAnalytics(), 'idle');
80
+ * ```
81
+ */
82
+ scheduleWithPriority(update: () => void, priority?: UpdatePriority, componentId?: string): void;
83
+ /**
84
+ * Schedule a flush of idle-priority updates.
85
+ * Uses `requestIdleCallback` when available; falls back to a short `setTimeout`.
86
+ */
87
+ private scheduleIdleFlush;
88
+ /**
89
+ * Process pending idle-priority updates in a time-sliced manner.
90
+ * Yields back to the browser when the deadline's `timeRemaining()` reaches
91
+ * zero and reschedules any unprocessed work.
92
+ */
93
+ private flushIdleUpdates;
55
94
  }
56
95
  export declare const updateScheduler: UpdateScheduler;
57
96
  /**
58
- * Schedule a DOM update to be batched with optional component identity
97
+ * Schedule a DOM update to be batched with optional component identity and priority
98
+ * Schedule a DOM update to be batched with optional component identity and priority
59
99
  */
60
100
  export declare function scheduleDOMUpdate(update: () => void, componentId?: string): void;
101
+ /**
102
+ * Schedule an update with explicit priority.
103
+ * See `UpdateScheduler.scheduleWithPriority` for full documentation.
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * // Defer low-priority work to browser idle time (time-sliced, non-blocking)
108
+ * scheduleWithPriority(() => updateAnalyticsDashboard(), 'idle');
109
+ *
110
+ * // Run a critical update before any async code resumes
111
+ * scheduleWithPriority(() => updateCriticalUI(), 'immediate');
112
+ * ```
113
+ */
114
+ export declare function scheduleWithPriority(update: () => void, priority?: UpdatePriority, componentId?: string): void;
61
115
  /**
62
116
  * Force flush any pending DOM updates immediately. This is useful in
63
117
  * test environments or callers that require synchronous guarantees after
@@ -66,4 +120,17 @@ export declare function scheduleDOMUpdate(update: () => void, componentId?: stri
66
120
  * rendered DOM changes.
67
121
  */
68
122
  export declare function flushDOMUpdates(): void;
123
+ /**
124
+ * Returns a Promise that resolves after the next DOM update cycle completes.
125
+ * Equivalent to Vue's `nextTick()` — useful when you need to observe DOM
126
+ * state that reflects the latest reactive changes.
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * count.value++;
131
+ * await nextTick();
132
+ * console.log(element.shadowRoot.querySelector('span').textContent); // updated
133
+ * ```
134
+ */
135
+ export declare function nextTick(): Promise<void>;
69
136
  export {};
@@ -0,0 +1,14 @@
1
+ import type { VNode } from '../types';
2
+ /**
3
+ * Transform VNodes with :when directive into anchor blocks for conditional rendering
4
+ */
5
+ export declare function transformWhenDirective(vnode: VNode): VNode;
6
+ /**
7
+ * Internal implementation allowing an optional compile context for :model.
8
+ * Fixes:
9
+ * - Recognize interpolation markers embedded in text ("World{{1}}") and replace them.
10
+ * - Skip empty arrays from directives so markers don't leak as text.
11
+ * - Pass AnchorBlocks through (and deep-normalize their children's keys) so the renderer can mount/patch them surgically.
12
+ * - Do not rewrap interpolated VNodes (preserve their keys); only fill in missing keys.
13
+ */
14
+ export declare function htmlImpl(strings: TemplateStringsArray, values: unknown[], context?: Record<string, unknown>): VNode | VNode[];
@@ -0,0 +1,20 @@
1
+ import type { VNode } from '../types';
2
+ export declare class LRUCache<K, V> {
3
+ private map;
4
+ private maxSize;
5
+ private accessOrder;
6
+ private accessCounter;
7
+ constructor(maxSize: number);
8
+ get(key: K): V | undefined;
9
+ set(key: K, value: V): void;
10
+ private evictLRU;
11
+ has(key: K): boolean;
12
+ clear(): void;
13
+ get size(): number;
14
+ }
15
+ export declare const getCacheSize: () => number;
16
+ export declare const TEMPLATE_COMPILE_CACHE: LRUCache<string, VNode | VNode[]>;
17
+ /**
18
+ * Clear the template compile cache (useful for tests)
19
+ */
20
+ export declare function clearTemplateCompileCache(): void;
@@ -0,0 +1,15 @@
1
+ export interface ParsePropsResult {
2
+ props: Record<string, unknown>;
3
+ attrs: Record<string, unknown>;
4
+ directives: Record<string, {
5
+ value: unknown;
6
+ modifiers: string[];
7
+ arg?: string;
8
+ }>;
9
+ bound: string[];
10
+ }
11
+ /**
12
+ * Validates event handlers to prevent common mistakes that lead to infinite loops
13
+ */
14
+ export declare function validateEventHandler(value: unknown, eventName: string): void;
15
+ export declare function parseProps(str: string, values?: unknown[], context?: Record<string, unknown>): ParsePropsResult;
@@ -0,0 +1,5 @@
1
+ import type { VNode } from '../types';
2
+ export declare function h(tag: string, props?: Record<string, unknown>, children?: VNode[] | string, key?: string | number): VNode;
3
+ export declare function isAnchorBlock(v: unknown): boolean;
4
+ export declare function isElementVNode(v: unknown): v is VNode;
5
+ export declare function ensureKey(v: VNode, k?: string): VNode;
@@ -1,32 +1,9 @@
1
+ export type { ParsePropsResult } from './template-compiler/props-parser';
2
+ export { h, isAnchorBlock, isElementVNode, ensureKey } from './template-compiler/vnode-utils';
3
+ export { LRUCache, getCacheSize, TEMPLATE_COMPILE_CACHE, clearTemplateCompileCache } from './template-compiler/lru-cache';
4
+ export { parseProps, validateEventHandler } from './template-compiler/props-parser';
5
+ export { transformWhenDirective, htmlImpl } from './template-compiler/impl';
1
6
  import type { VNode } from './types';
2
- export declare function h(tag: string, props?: Record<string, unknown>, children?: VNode[] | string, key?: string | number): VNode;
3
- export declare function isAnchorBlock(v: unknown): boolean;
4
- export declare function isElementVNode(v: unknown): v is VNode;
5
- export declare function ensureKey(v: VNode, k?: string): VNode;
6
- export interface ParsePropsResult {
7
- props: Record<string, unknown>;
8
- attrs: Record<string, unknown>;
9
- directives: Record<string, {
10
- value: unknown;
11
- modifiers: string[];
12
- arg?: string;
13
- }>;
14
- bound: string[];
15
- }
16
- export declare function parseProps(str: string, values?: unknown[], context?: Record<string, unknown>): ParsePropsResult;
17
- /**
18
- * Internal implementation allowing an optional compile context for :model.
19
- * Fixes:
20
- * - Recognize interpolation markers embedded in text ("World{{1}}") and replace them.
21
- * - Skip empty arrays from directives so markers don't leak as text.
22
- * - Pass AnchorBlocks through (and deep-normalize their children's keys) so the renderer can mount/patch them surgically.
23
- * - Do not rewrap interpolated VNodes (preserve their keys); only fill in missing keys.
24
- */
25
- export declare function htmlImpl(strings: TemplateStringsArray, values: unknown[], context?: Record<string, unknown>): VNode | VNode[];
26
- /**
27
- * Clear the template compile cache (useful for tests)
28
- */
29
- export declare function clearTemplateCompileCache(): void;
30
7
  /**
31
8
  * Default export: plain html.
32
9
  */
@@ -44,6 +44,16 @@ export interface AnchorBlockVNode extends VNode {
44
44
  export type LifecycleKeys = 'onConnected' | 'onDisconnected' | 'onAttributeChanged' | 'onError';
45
45
  export interface WatchOptions {
46
46
  immediate?: boolean;
47
+ /**
48
+ * When `true`, the watcher tracks nested object/array property mutations.
49
+ * The callback receives deep-cloned snapshots of the new and old values so
50
+ * before/after state can be compared.
51
+ *
52
+ * Note: because deep watching bypasses reference equality, the callback fires
53
+ * on every nested mutation even if the resulting plain-object value is
54
+ * structurally identical. Use a shallow watcher (default) when you only need
55
+ * to detect `.value` reassignment.
56
+ */
47
57
  deep?: boolean;
48
58
  }
49
59
  export type WatchCallback<T = unknown, S = unknown> = (newValue: T, oldValue: T, context: S) => void;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * vdom-directives.ts
3
+ *
4
+ * Directive processors for the virtual DOM. Handles `:model`, `:bind`,
5
+ * `:show`, `:class`, `:style`, and `:ref` directives as well as the
6
+ * top-level `processDirectives` coordinator.
7
+ */
8
+ import { type PropsMap } from './vdom-helpers';
9
+ /**
10
+ * Process :model directive for two-way data binding
11
+ * @param value
12
+ * @param modifiers
13
+ * @param props
14
+ * @param attrs
15
+ * @param listeners
16
+ * @param context
17
+ * @param el
18
+ * @returns
19
+ */
20
+ export declare function processModelDirective(value: string | unknown, modifiers: string[], props: Record<string, unknown>, attrs: Record<string, unknown>, listeners: Record<string, EventListener>, context?: Record<string, unknown>, el?: Element, arg?: string): void;
21
+ /**
22
+ * Process :bind directive for attribute/property binding
23
+ * @param value
24
+ * @param props
25
+ * @param attrs
26
+ * @param context
27
+ * @returns
28
+ */
29
+ export declare function processBindDirective(value: unknown, props: PropsMap, attrs: PropsMap, context?: Record<string, unknown>, el?: Element): void;
30
+ /**
31
+ * Process :show directive for conditional display
32
+ * @param value
33
+ * @param attrs
34
+ * @param context
35
+ * @returns
36
+ */
37
+ export declare function processShowDirective(value: unknown, attrs: Record<string, unknown>, context?: Record<string, unknown>): void;
38
+ export declare function processClassDirective(value: unknown, attrs: Record<string, unknown>, context?: Record<string, unknown>, originalVnodeAttrs?: Record<string, unknown>): void;
39
+ /**
40
+ * Process :style directive for dynamic inline styles
41
+ * @param value
42
+ * @param attrs
43
+ * @param context
44
+ * @returns
45
+ */
46
+ export declare function processStyleDirective(value: unknown, attrs: Record<string, unknown>, context?: Record<string, unknown>): void;
47
+ /**
48
+ * Process :ref directive for element references
49
+ * @param value
50
+ * @param props
51
+ * @param context
52
+ * @returns
53
+ */
54
+ export declare function processRefDirective(value: unknown, props: Record<string, unknown>, context?: Record<string, unknown>): void;
55
+ /**
56
+ * Process directives and return merged props, attrs, and event listeners
57
+ * @param directives
58
+ * @param context
59
+ * @param el
60
+ * @param vnodeAttrs
61
+ * @returns
62
+ */
63
+ export declare function processDirectives(directives: Record<string, {
64
+ value: unknown;
65
+ modifiers: string[];
66
+ arg?: string;
67
+ }>, context?: Record<string, unknown>, el?: Element, vnodeAttrs?: PropsMap): {
68
+ props: Record<string, unknown>;
69
+ attrs: Record<string, unknown>;
70
+ listeners: Record<string, EventListener>;
71
+ };
@@ -0,0 +1,126 @@
1
+ /**
2
+ * vdom-helpers.ts
3
+ *
4
+ * Private utility functions and shared internal types for the virtual DOM.
5
+ * These are consumed by vdom-directives.ts and vdom-patch.ts.
6
+ * Keeping them here avoids circular imports and enables tree-shaking.
7
+ *
8
+ * Public API (for use by vdom-patch / vdom-directives only):
9
+ * hasValueProp — structural check: object has a `.value` property
10
+ * unwrapValue — unwrap reactive / wrapper objects to their inner value
11
+ * writebackAttr — mutate oldProps.attrs[key] to track applied values
12
+ * isNativeControl — true for input / select / textarea / button elements
13
+ * coerceBooleanForNative — coerce a value to boolean for native attributes
14
+ * eventNameFromKey — "onClick" → "click", "onUpdate:name" → "update:name"
15
+ * isBooleanishForProps — true when val is a clear boolean-ish primitive
16
+ */
17
+ /** A loose map of property names to arbitrary values used throughout the VDOM. */
18
+ export type PropsMap = Record<string, unknown>;
19
+ /**
20
+ * Directive specification as produced by the template compiler and consumed
21
+ * by `processDirectives`.
22
+ */
23
+ export interface DirectiveSpec {
24
+ value: unknown;
25
+ modifiers: string[];
26
+ arg?: string;
27
+ }
28
+ /**
29
+ * The `props` bag attached to a VNode. Used as the parameter / return type
30
+ * for patchProps, createElement, and VNode diffing helpers.
31
+ */
32
+ export interface VNodePropBag {
33
+ key?: string;
34
+ props?: Record<string, unknown>;
35
+ attrs?: Record<string, unknown>;
36
+ directives?: Record<string, DirectiveSpec>;
37
+ ref?: string;
38
+ reactiveRef?: {
39
+ value: unknown;
40
+ [key: string]: unknown;
41
+ };
42
+ /** Compiler-provided hint: whether this VNode represents a custom element. */
43
+ isCustomElement?: boolean;
44
+ /** Transition group metadata forwarded from `<Transition>`. */
45
+ _transitionGroup?: {
46
+ name?: string;
47
+ appear?: boolean;
48
+ mode?: 'out-in' | 'in-out' | 'default';
49
+ [key: string]: unknown;
50
+ };
51
+ [key: string]: unknown;
52
+ }
53
+ /**
54
+ * Extension of `globalThis` used exclusively for internal VDom test-env probes
55
+ * and debug diagnostics. Never rely on these properties in production code.
56
+ */
57
+ export interface VDomGlobal {
58
+ process?: {
59
+ env?: {
60
+ NODE_ENV?: string;
61
+ };
62
+ };
63
+ __vitest__?: unknown;
64
+ __VDOM_DISABLED_PROMOTIONS?: unknown[];
65
+ }
66
+ /**
67
+ * Returns `true` when `val` is an object that exposes a `.value` property.
68
+ * This is a structural (duck-type) check used in the VDOM prop-diffing loop
69
+ * to detect value-wrapper objects that are *not* identified as ReactiveState
70
+ * by `isReactiveState()` (e.g. plain `{ value: 42 }` bags).
71
+ *
72
+ * Note: ReactiveState instances also satisfy this check; callers should test
73
+ * `isReactiveState(val)` first and only fall through to `hasValueProp` for the
74
+ * non-reactive wrapper case.
75
+ */
76
+ export declare function hasValueProp(val: unknown): boolean;
77
+ /**
78
+ * Unwrap a reactive-state or value-wrapper object to its inner value.
79
+ * If `val` is an object with a `.value` property the inner value is returned;
80
+ * otherwise `val` is returned as-is (including primitives, null, undefined).
81
+ *
82
+ * @example
83
+ * unwrapValue(ref(42)) // → 42
84
+ * unwrapValue({ value: 'hello' }) // → 'hello'
85
+ * unwrapValue('plain') // → 'plain'
86
+ */
87
+ export declare function unwrapValue(val: unknown): unknown;
88
+ /**
89
+ * Write `val` back into `oldProps.attrs[key]` so that subsequent diff passes
90
+ * see the most recently applied attribute value without re-reading the DOM.
91
+ *
92
+ * When `val` is `undefined` the entry is *deleted* from `oldProps.attrs`
93
+ * (attribute was removed).
94
+ *
95
+ * Accepts `undefined` for `oldProps` to simplify call sites where the props
96
+ * bag may not have been initialised yet (e.g. `createElement` paths).
97
+ */
98
+ export declare function writebackAttr(oldProps: VNodePropBag | undefined, key: string, val: unknown): void;
99
+ /**
100
+ * Returns `true` when `el` is a native form control (input, select, textarea,
101
+ * or button). Used to gate attribute/property coercion logic that only applies
102
+ * to native control elements.
103
+ */
104
+ export declare function isNativeControl(el: Element): boolean;
105
+ /**
106
+ * Coerce `val` to a boolean for use with native element `.disabled` (and other
107
+ * boolean HTML attributes). Handles reactive/wrapper unwrapping, the string
108
+ * literals `'true'`/`'false'`, and falsy zero/empty-string values.
109
+ */
110
+ export declare function coerceBooleanForNative(val: unknown): boolean;
111
+ /**
112
+ * Convert an `onXxx` prop key to the corresponding DOM event name.
113
+ *
114
+ * @example
115
+ * eventNameFromKey('onClick') // → 'click'
116
+ * eventNameFromKey('onMouseOver') // → 'mouseOver' (EventManager normalises case)
117
+ * eventNameFromKey('onUpdate:name') // → 'update:name'
118
+ */
119
+ export declare function eventNameFromKey(key: string): string;
120
+ /**
121
+ * Returns `true` when `val` is a clear boolean-ish primitive — i.e. one of
122
+ * `true`, `false`, `'true'`, or `'false'`. Used to decide whether a `:bind`
123
+ * prop candidate should be treated as the authoritative source for a native
124
+ * `disabled` attribute rather than falling back to the merged attrs value.
125
+ */
126
+ export declare function isBooleanishForProps(val: unknown): boolean;