@jasonshimmy/custom-elements-runtime 2.5.1 → 2.5.5

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 (90) 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 -18
  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 +246 -3648
  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 +790 -464
  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 -3
  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 -147
  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 +56 -0
  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 +115 -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-CA4YRaBu.cjs +23 -0
  72. package/dist/template-compiler-CA4YRaBu.cjs.map +1 -0
  73. package/dist/template-compiler-CJFwjLCP.js +3981 -0
  74. package/dist/template-compiler-CJFwjLCP.js.map +1 -0
  75. package/dist/transitions-DPZiuXb9.cjs +330 -0
  76. package/dist/transitions-DPZiuXb9.cjs.map +1 -0
  77. package/dist/{transitions-CZ21fzhh.js → transitions-Di5wW9yc.js} +1059 -618
  78. package/dist/transitions-Di5wW9yc.js.map +1 -0
  79. package/dist/transitions.d.ts +1 -1
  80. package/package.json +20 -12
  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-BsKQl3aH.cjs +0 -5
  85. package/dist/namespace-helpers-BsKQl3aH.cjs.map +0 -1
  86. package/dist/namespace-helpers-Dw1mgQab.js +0 -692
  87. package/dist/namespace-helpers-Dw1mgQab.js.map +0 -1
  88. package/dist/transitions-CZ21fzhh.js.map +0 -1
  89. package/dist/transitions-RXe2brRm.cjs +0 -302
  90. package/dist/transitions-RXe2brRm.cjs.map +0 -1
@@ -1,23 +1,136 @@
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;
13
+ private isFlushing;
14
+ private readonly testEnv;
15
+ private lastCleanup;
16
+ private readonly CLEANUP_INTERVAL;
17
+ private readonly MAX_PENDING_SIZE;
18
+ private pendingIdleUpdates;
19
+ private idleCallbackHandle;
20
+ constructor();
4
21
  /**
5
22
  * Schedule an update to be executed in the next microtask
6
23
  * Uses component identity to deduplicate multiple render requests for the same component
7
24
  */
8
25
  schedule(update: () => void, componentId?: string): void;
9
26
  /**
10
- * Execute all pending updates
27
+ * Schedule the flush operation based on environment
28
+ */
29
+ private scheduleFlush;
30
+ /**
31
+ * Execute all pending updates with priority ordering
32
+ * Execute all pending updates with priority ordering
11
33
  */
12
34
  private flush;
35
+ /**
36
+ * Force flush any pending DOM updates immediately. This is useful in
37
+ * test environments or callers that require synchronous guarantees after
38
+ * state changes. Prefer relying on the scheduler's automatic flush when
39
+ * possible; use this only when a caller needs to synchronously observe
40
+ * rendered DOM changes.
41
+ */
42
+ flushImmediately(): void;
13
43
  /**
14
44
  * Get the number of pending updates
15
45
  */
16
46
  get pendingCount(): number;
47
+ /**
48
+ * Check if there are pending updates
49
+ */
50
+ get hasPendingUpdates(): boolean;
51
+ /**
52
+ * Check if currently flushing updates
53
+ */
54
+ get isFlushingUpdates(): boolean;
55
+ /**
56
+ * Schedule periodic cleanup to prevent memory leaks
57
+ */
58
+ private schedulePeriodicCleanup;
59
+ /**
60
+ * Perform periodic cleanup of stale entries
61
+ */
62
+ private performPeriodicCleanup;
63
+ /**
64
+ * Emergency cleanup when pending updates exceed safe limits
65
+ */
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;
17
94
  }
18
95
  export declare const updateScheduler: UpdateScheduler;
19
96
  /**
20
- * 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
21
99
  */
22
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;
115
+ /**
116
+ * Force flush any pending DOM updates immediately. This is useful in
117
+ * test environments or callers that require synchronous guarantees after
118
+ * state changes. Prefer relying on the scheduler's automatic flush when
119
+ * possible; use this only when a caller needs to synchronously observe
120
+ * rendered DOM changes.
121
+ */
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>;
23
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;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * vdom-patch.ts
3
+ *
4
+ * Core virtual DOM patching and rendering engine. Provides:
5
+ * - `cleanupRefs` — recursively remove event listeners and clear ref entries
6
+ * - `assignKeysDeep` — recursively assign stable keys to VNode trees
7
+ * - `patchProps` — diff and apply prop/attr/directive changes to a DOM element
8
+ * - `createElement` — create a new DOM element from a VNode descriptor
9
+ * - `patchChildren` — reconcile a list of child VNodes against real DOM children
10
+ * - `patch` — top-level diff/patch driver for a single VNode
11
+ * - `vdomRenderer` — entry-point renderer for a shadow root or container
12
+ */
13
+ import type { VNode, VDomRefs } from './types';
14
+ import { type VNodePropBag } from './vdom-helpers';
15
+ export declare function cleanupRefs(node: Node, refs?: VDomRefs): void;
16
+ /**
17
+ * Assign unique keys to VNodes for efficient rendering
18
+ * @param nodeOrNodes
19
+ * @param baseKey
20
+ * @returns
21
+ */
22
+ export declare function assignKeysDeep(nodeOrNodes: VNode | VNode[], baseKey: string): VNode | VNode[];
23
+ /**
24
+ * Patch props on an element.
25
+ * Only update changed props, remove old, add new.
26
+ * @param el
27
+ * @param oldProps
28
+ * @param newProps
29
+ * @param context
30
+ */
31
+ export declare function patchProps(el: HTMLElement, oldProps: VNodePropBag, newProps: VNodePropBag, context?: Record<string, unknown>): void;
32
+ /**
33
+ * Create a DOM element from a VNode.
34
+ * @param vnode
35
+ * @param context
36
+ * @param refs
37
+ * @returns
38
+ */
39
+ export declare function createElement(vnode: VNode | string, context?: Record<string, unknown>, refs?: VDomRefs, parentNamespace?: string | null): Node;
40
+ /**
41
+ * Patch children using keys for node matching.
42
+ * @param parent
43
+ * @param oldChildren
44
+ * @param newChildren
45
+ * @param context
46
+ * @param refs
47
+ * @returns
48
+ */
49
+ export declare function patchChildren(parent: HTMLElement, oldChildren: VNode[] | string | undefined, newChildren: VNode[] | string | undefined, context?: Record<string, unknown>, refs?: VDomRefs): void;
50
+ /**
51
+ * Patch a node using keys for node matching.
52
+ * @param dom
53
+ * @param oldVNode
54
+ * @param newVNode
55
+ * @param context
56
+ * @param refs
57
+ * @returns
58
+ */
59
+ export declare function patch(dom: Node, oldVNode: VNode | string | null, newVNode: VNode | string | null, context?: Record<string, unknown>, refs?: VDomRefs): Node;
60
+ /**
61
+ * Virtual DOM renderer.
62
+ * @param root The root element to render into.
63
+ * @param vnodeOrArray The virtual node or array of virtual nodes to render.
64
+ * @param context The context to use for rendering.
65
+ * @param refs The refs to use for rendering.
66
+ */
67
+ export declare function vdomRenderer(root: ShadowRoot, vnodeOrArray: VNode | VNode[], context?: Record<string, unknown>, refs?: VDomRefs): void;
@@ -1,142 +1,18 @@
1
1
  /**
2
2
  * vdom.ts
3
- * Lightweight, strongly typed, functional virtual DOM renderer for custom elements.
4
- * Features: keyed diffing, incremental patching, focus/caret preservation, event delegation, SSR-friendly, no dependencies.
5
- */
6
- import type { VNode, VDomRefs } from './types';
7
- type PropsMap = Record<string, unknown>;
8
- type DirectiveSpec = {
9
- value: unknown;
10
- modifiers: string[];
11
- arg?: string;
12
- };
13
- type VNodePropBag = {
14
- props?: PropsMap;
15
- attrs?: PropsMap;
16
- directives?: Record<string, DirectiveSpec>;
17
- isCustomElement?: boolean;
18
- [k: string]: unknown;
19
- };
20
- /**
21
- * Recursively clean up refs and event listeners for all descendants of a node
22
- * @param node The node to clean up.
23
- * @param refs The refs to clean up.
24
- * @returns
25
- */
26
- export declare function cleanupRefs(node: Node, refs?: VDomRefs): void;
27
- /**
28
- * Process :model directive for two-way data binding
29
- * @param value
30
- * @param modifiers
31
- * @param props
32
- * @param attrs
33
- * @param listeners
34
- * @param context
35
- * @param el
36
- * @returns
37
- */
38
- 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;
39
- /**
40
- * Process :bind directive for attribute/property binding
41
- * @param value
42
- * @param props
43
- * @param attrs
44
- * @param context
45
- * @returns
46
- */
47
- export declare function processBindDirective(value: unknown, props: PropsMap, attrs: PropsMap, context?: Record<string, unknown>, el?: Element): void;
48
- /**
49
- * Process :show directive for conditional display
50
- * @param value
51
- * @param attrs
52
- * @param context
53
- * @returns
54
- */
55
- export declare function processShowDirective(value: unknown, attrs: Record<string, unknown>, context?: Record<string, unknown>): void;
56
- export declare function processClassDirective(value: unknown, attrs: Record<string, unknown>, context?: Record<string, unknown>, originalVnodeAttrs?: Record<string, unknown>): void;
57
- /**
58
- * Process :style directive for dynamic inline styles
59
- * @param value
60
- * @param attrs
61
- * @param context
62
- * @returns
63
- */
64
- export declare function processStyleDirective(value: unknown, attrs: Record<string, unknown>, context?: Record<string, unknown>): void;
65
- /**
66
- * Process :ref directive for element references
67
- * @param value
68
- * @param props
69
- * @param context
70
- * @returns
71
- */
72
- export declare function processRefDirective(value: unknown, props: Record<string, unknown>, context?: Record<string, unknown>): void;
73
- /**
74
- * Process directives and return merged props, attrs, and event listeners
75
- * @param directives
76
- * @param context
77
- * @param el
78
- * @param vnodeAttrs
79
- * @returns
80
- */
81
- export declare function processDirectives(directives: Record<string, {
82
- value: unknown;
83
- modifiers: string[];
84
- arg?: string;
85
- }>, context?: Record<string, unknown>, el?: Element, vnodeAttrs?: PropsMap): {
86
- props: Record<string, unknown>;
87
- attrs: Record<string, unknown>;
88
- listeners: Record<string, EventListener>;
89
- };
90
- /**
91
- * Assign unique keys to VNodes for efficient rendering
92
- * @param nodeOrNodes
93
- * @param baseKey
94
- * @returns
95
- */
96
- export declare function assignKeysDeep(nodeOrNodes: VNode | VNode[], baseKey: string): VNode | VNode[];
97
- /**
98
- * Patch props on an element.
99
- * Only update changed props, remove old, add new.
100
- * @param el
101
- * @param oldProps
102
- * @param newProps
103
- * @param context
104
- */
105
- export declare function patchProps(el: HTMLElement, oldProps: VNodePropBag, newProps: VNodePropBag, context?: Record<string, unknown>): void;
106
- /**
107
- * Create a DOM element from a VNode.
108
- * @param vnode
109
- * @param context
110
- * @param refs
111
- * @returns
112
- */
113
- export declare function createElement(vnode: VNode | string, context?: Record<string, unknown>, refs?: VDomRefs, parentNamespace?: string | null): Node;
114
- /**
115
- * Patch children using keys for node matching.
116
- * @param parent
117
- * @param oldChildren
118
- * @param newChildren
119
- * @param context
120
- * @param refs
121
- * @returns
122
- */
123
- export declare function patchChildren(parent: HTMLElement, oldChildren: VNode[] | string | undefined, newChildren: VNode[] | string | undefined, context?: Record<string, unknown>, refs?: VDomRefs): void;
124
- /**
125
- * Patch a node using keys for node matching.
126
- * @param dom
127
- * @param oldVNode
128
- * @param newVNode
129
- * @param context
130
- * @param refs
131
- * @returns
132
- */
133
- export declare function patch(dom: Node, oldVNode: VNode | string | null, newVNode: VNode | string | null, context?: Record<string, unknown>, refs?: VDomRefs): Node;
134
- /**
135
- * Virtual DOM renderer.
136
- * @param root The root element to render into.
137
- * @param vnodeOrArray The virtual node or array of virtual nodes to render.
138
- * @param context The context to use for rendering.
139
- * @param refs The refs to use for rendering.
140
- */
141
- export declare function vdomRenderer(root: ShadowRoot, vnodeOrArray: VNode | VNode[], context?: Record<string, unknown>, refs?: VDomRefs): void;
142
- export {};
3
+ *
4
+ * Barrel re-export module for the virtual DOM implementation.
5
+ * The actual code lives in the focused sub-modules:
6
+ *
7
+ * | Module | Responsibilities |
8
+ * |----------------------|--------------------------------------------------------|
9
+ * | vdom-helpers.ts | Private utilities and shared internal types |
10
+ * | vdom-directives.ts | processModelDirective and all process*Directive funcs |
11
+ * | vdom-patch.ts | assignKeysDeep, patchProps, createElement, patch, etc. |
12
+ * | vdom-ssr.ts | renderToString (server-side rendering) |
13
+ *
14
+ * Import directly from these focused modules for tree-shaking.
15
+ * This file is kept for backwards compatibility.
16
+ */
17
+ export { processModelDirective, processBindDirective, processShowDirective, processClassDirective, processStyleDirective, processRefDirective, processDirectives, } from "./vdom-directives";
18
+ export { cleanupRefs, assignKeysDeep, patchProps, createElement, patchChildren, patch, vdomRenderer, } from "./vdom-patch";