flexium 0.8.15 → 0.9.1

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 (125) hide show
  1. package/dist/{DrawText-CeXBL8Ev.d.ts → DrawText-Bvzl40Vi.d.ts} +1 -1
  2. package/dist/{DrawText-JB58mpQT.d.cts → DrawText-CJikXQjL.d.cts} +1 -1
  3. package/dist/advanced.d.cts +3 -1
  4. package/dist/advanced.d.ts +3 -1
  5. package/dist/advanced.js +1 -1
  6. package/dist/advanced.mjs +1 -1
  7. package/dist/advanced.mjs.map +1 -1
  8. package/dist/canvas.d.cts +5 -3
  9. package/dist/canvas.d.ts +5 -3
  10. package/dist/canvas.js +1 -1
  11. package/dist/canvas.mjs +1 -1
  12. package/dist/chunk-2ZHUQBNI.mjs +2 -0
  13. package/dist/chunk-2ZHUQBNI.mjs.map +1 -0
  14. package/dist/{chunk-CNY6FPKJ.js → chunk-DFG62GKW.js} +2 -2
  15. package/dist/{chunk-CZYIK6FD.mjs.map → chunk-DFG62GKW.js.map} +1 -1
  16. package/dist/{chunk-ZNPYN2TZ.mjs → chunk-HDCPA76O.mjs} +2 -2
  17. package/dist/{chunk-ZNPYN2TZ.mjs.map → chunk-HDCPA76O.mjs.map} +1 -1
  18. package/dist/chunk-J4CK5NRW.mjs +3 -0
  19. package/dist/chunk-J4CK5NRW.mjs.map +1 -0
  20. package/dist/chunk-JEDCNAAI.mjs +3 -0
  21. package/dist/chunk-JEDCNAAI.mjs.map +1 -0
  22. package/dist/{chunk-DOGIWSDA.js → chunk-JHJHIMWD.js} +2 -2
  23. package/dist/{chunk-DOGIWSDA.js.map → chunk-JHJHIMWD.js.map} +1 -1
  24. package/dist/{chunk-GDBJ322I.js → chunk-L4C5UBOX.js} +2 -2
  25. package/dist/{chunk-GDBJ322I.js.map → chunk-L4C5UBOX.js.map} +1 -1
  26. package/dist/chunk-M4ANLZ6P.js +3 -0
  27. package/dist/chunk-M4ANLZ6P.js.map +1 -0
  28. package/dist/chunk-RDA77IE6.js +2 -0
  29. package/dist/chunk-RDA77IE6.js.map +1 -0
  30. package/dist/{chunk-CZYIK6FD.mjs → chunk-RUXAK74B.mjs} +2 -2
  31. package/dist/chunk-RUXAK74B.mjs.map +1 -0
  32. package/dist/chunk-TRIEKNVZ.mjs +2 -0
  33. package/dist/{chunk-MLZTCKTH.mjs.map → chunk-TRIEKNVZ.mjs.map} +1 -1
  34. package/dist/chunk-VIVO4FHN.js +3 -0
  35. package/dist/chunk-VIVO4FHN.js.map +1 -0
  36. package/dist/chunk-XLE6SMWX.mjs +3 -0
  37. package/dist/chunk-XLE6SMWX.mjs.map +1 -0
  38. package/dist/chunk-YGMMJWAA.js +3 -0
  39. package/dist/chunk-YGMMJWAA.js.map +1 -0
  40. package/dist/components-D4WeooPi.d.ts +126 -0
  41. package/dist/components-DZy2r6m5.d.cts +126 -0
  42. package/dist/core.d.cts +159 -15
  43. package/dist/core.d.ts +159 -15
  44. package/dist/core.js +1 -1
  45. package/dist/core.mjs +1 -1
  46. package/dist/dom.d.cts +2 -3
  47. package/dist/dom.d.ts +2 -3
  48. package/dist/dom.js +1 -1
  49. package/dist/dom.js.map +1 -1
  50. package/dist/dom.mjs +1 -1
  51. package/dist/dom.mjs.map +1 -1
  52. package/dist/effect-BlnnM1t5.d.cts +20 -0
  53. package/dist/effect-BlnnM1t5.d.ts +20 -0
  54. package/dist/index.d.cts +2 -2
  55. package/dist/index.d.ts +2 -2
  56. package/dist/index.js +1 -1
  57. package/dist/index.js.map +1 -1
  58. package/dist/index.mjs +1 -1
  59. package/dist/index.mjs.map +1 -1
  60. package/dist/interactive.d.cts +1 -1
  61. package/dist/interactive.d.ts +1 -1
  62. package/dist/interactive.js +1 -1
  63. package/dist/interactive.mjs +1 -1
  64. package/dist/interactive.mjs.map +1 -1
  65. package/dist/metafile-cjs.json +1 -1
  66. package/dist/metafile-esm.json +1 -1
  67. package/dist/owner-QS9tPwPr.d.cts +27 -0
  68. package/dist/owner-QS9tPwPr.d.ts +27 -0
  69. package/dist/{portal-DBwz7gD0.d.ts → portal-C3ESJhlv.d.ts} +1 -1
  70. package/dist/{portal-BpcIlK9y.d.cts → portal-CAEbiMUZ.d.cts} +1 -1
  71. package/dist/primitives/motion.js +1 -1
  72. package/dist/primitives/motion.mjs +1 -1
  73. package/dist/primitives/ui.d.cts +1 -1
  74. package/dist/primitives/ui.d.ts +1 -1
  75. package/dist/primitives/ui.js +1 -1
  76. package/dist/primitives/ui.mjs +1 -1
  77. package/dist/primitives/ui.mjs.map +1 -1
  78. package/dist/primitives.d.cts +6 -4
  79. package/dist/primitives.d.ts +6 -4
  80. package/dist/primitives.js +1 -1
  81. package/dist/primitives.mjs +1 -1
  82. package/dist/router.d.cts +11 -120
  83. package/dist/router.d.ts +11 -120
  84. package/dist/router.js +1 -1
  85. package/dist/router.mjs +1 -1
  86. package/dist/server.js +1 -1
  87. package/dist/server.mjs +1 -1
  88. package/dist/server.mjs.map +1 -1
  89. package/dist/signal-3YZHUCLL.js +2 -0
  90. package/dist/{signal-XZXQ4VYQ.js.map → signal-3YZHUCLL.js.map} +1 -1
  91. package/dist/signal-Dxh9PsKr.d.cts +69 -0
  92. package/dist/signal-Dxh9PsKr.d.ts +69 -0
  93. package/dist/signal-F2HEYB6F.mjs +2 -0
  94. package/dist/{signal-PWBIM6JV.mjs.map → signal-F2HEYB6F.mjs.map} +1 -1
  95. package/dist/sync-Z4QqUDjF.d.cts +25 -0
  96. package/dist/sync-Z4QqUDjF.d.ts +25 -0
  97. package/dist/test-exports.d.cts +29 -8
  98. package/dist/test-exports.d.ts +29 -8
  99. package/dist/test-exports.js +1 -1
  100. package/dist/test-exports.mjs +1 -1
  101. package/package.json +1 -1
  102. package/dist/chunk-2MVKTSFR.mjs +0 -3
  103. package/dist/chunk-2MVKTSFR.mjs.map +0 -1
  104. package/dist/chunk-2U4DW375.mjs +0 -2
  105. package/dist/chunk-2U4DW375.mjs.map +0 -1
  106. package/dist/chunk-5S3ZQ2LB.mjs +0 -3
  107. package/dist/chunk-5S3ZQ2LB.mjs.map +0 -1
  108. package/dist/chunk-CNY6FPKJ.js.map +0 -1
  109. package/dist/chunk-EX2GURH5.mjs +0 -3
  110. package/dist/chunk-EX2GURH5.mjs.map +0 -1
  111. package/dist/chunk-I7UCVARB.js +0 -2
  112. package/dist/chunk-I7UCVARB.js.map +0 -1
  113. package/dist/chunk-MLZTCKTH.mjs +0 -2
  114. package/dist/chunk-REETNY2Z.js +0 -3
  115. package/dist/chunk-REETNY2Z.js.map +0 -1
  116. package/dist/chunk-ROYFUJN5.js +0 -3
  117. package/dist/chunk-ROYFUJN5.js.map +0 -1
  118. package/dist/chunk-V4K6WOXN.js +0 -3
  119. package/dist/chunk-V4K6WOXN.js.map +0 -1
  120. package/dist/signal-PWBIM6JV.mjs +0 -2
  121. package/dist/signal-XZXQ4VYQ.js +0 -2
  122. package/dist/signal-mNtlF8-v.d.cts +0 -158
  123. package/dist/signal-mNtlF8-v.d.ts +0 -158
  124. package/dist/state-kK9sQh9s.d.cts +0 -73
  125. package/dist/state-kK9sQh9s.d.ts +0 -73
package/dist/core.d.cts CHANGED
@@ -1,24 +1,168 @@
1
- export { A as AsyncStatus, S as StateAction, b as StateKey, c as StateOptions, a as StateValue, _ as state } from './state-kK9sQh9s.cjs';
2
- export { d as batch, e as effect, o as onCleanup, b as onMount, r as root, u as untrack } from './signal-mNtlF8-v.cjs';
3
- import { a as FNodeChild } from './renderer-DSLb-FGg.cjs';
1
+ export { e as effect } from './effect-BlnnM1t5.cjs';
4
2
 
5
- interface Context<T> {
6
- id: symbol;
7
- Provider: (props: {
8
- value: T;
9
- children: FNodeChild;
10
- }) => FNodeChild;
11
- defaultValue: T;
3
+ /** Key type - string or array of serializable values */
4
+ type StateKey = string | readonly (string | number | boolean | null | undefined | object)[];
5
+ /** Action function type for state mutation */
6
+ type StateAction<T> = (newValue: T | ((prev: T) => T)) => void;
7
+ /**
8
+ * StateValue type - a value-like proxy that behaves like T.
9
+ * Can be used directly in expressions and JSX.
10
+ */
11
+ type StateValue<T> = T & (() => T) & {
12
+ peek(): T;
13
+ };
14
+ /**
15
+ * Check if a value is a StateValue (created by the state() API).
16
+ * Useful for type guards and runtime detection of reactive state.
17
+ * @internal
18
+ * @param value - The value to check
19
+ * @returns true if the value is a StateValue proxy, false otherwise
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * const count = state(0)
24
+ * isStateValue(count) // true
25
+ * isStateValue(5) // false
26
+ * ```
27
+ */
28
+ declare function isStateValue(value: unknown): boolean;
29
+ /**
30
+ * Compare a StateValue with a primitive value safely.
31
+ * Handles Proxy comparison automatically by extracting the underlying value.
32
+ *
33
+ * @param stateValue - The StateValue to compare
34
+ * @param value - The value to compare against
35
+ * @returns true if the StateValue's underlying value equals the comparison value
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const [count, setCount] = state(0)
40
+ *
41
+ * // ✅ Safe comparison using helper
42
+ * if (equals(count, 5)) {
43
+ * console.log('Count is 5')
44
+ * }
45
+ *
46
+ * // ❌ Direct comparison (always false)
47
+ * if (count === 5) { ... }
48
+ * ```
49
+ */
50
+ declare function equals<T>(stateValue: StateValue<T>, value: T): boolean;
51
+ /**
52
+ * Check if a StateValue is truthy.
53
+ * Useful for boolean checks without explicit conversion.
54
+ *
55
+ * @param stateValue - The StateValue to check
56
+ * @returns true if the underlying value is truthy
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * const [user, setUser] = state<User | null>(null)
61
+ *
62
+ * // ✅ Safe boolean check
63
+ * if (isTruthy(user)) {
64
+ * console.log('User exists:', user.name)
65
+ * }
66
+ *
67
+ * // ❌ Direct check (always true for Proxy)
68
+ * if (user) { ... }
69
+ * ```
70
+ */
71
+ declare function isTruthy<T>(stateValue: StateValue<T>): boolean;
72
+ /** Async state status */
73
+ type AsyncStatus = 'idle' | 'loading' | 'success' | 'error';
74
+ /** Options for state() */
75
+ interface StateOptions<P = unknown> {
76
+ /**
77
+ * Key for global state sharing. Can be a string or array.
78
+ * Array keys are useful for hierarchical namespacing.
79
+ * @example
80
+ * state('light', { key: 'theme' })
81
+ * state(null, { key: ['user', 'profile', userId] })
82
+ */
83
+ key?: StateKey;
84
+ /**
85
+ * Parameters to pass to the function (for computed/async state).
86
+ * Improves DX by making dependencies explicit.
87
+ * @example
88
+ * state(
89
+ * async ({ userId }) => fetch(`/api/users/${userId}`),
90
+ * { key: ['user', userId], params: { userId } }
91
+ * )
92
+ */
93
+ params?: P;
94
+ }
95
+ /**
96
+ * Unified State API
97
+ *
98
+ * One function for all reactive state needs - always returns an array for consistency:
99
+ * 1. Simple state: const [count, setCount] = state(0)
100
+ * 2. Derived state: const [doubled] = state(() => count * 2)
101
+ * 3. Async state: const [data, refetch, status, error] = state(async () => fetch(...))
102
+ * 4. Global state: const [theme, setTheme] = state('light', { key: 'theme' })
103
+ * 5. With params: const [user] = state(async (p) => fetch(`/api/${p.id}`), { params: { id } })
104
+ *
105
+ * @example
106
+ * ```tsx
107
+ * function Counter() {
108
+ * const [count, setCount] = state(0)
109
+ * const [doubled] = state(() => count * 2)
110
+ * return <Button onPress={() => setCount(count + 1)}>{doubled}</Button>
111
+ * }
112
+ * ```
113
+ */
114
+ interface StateFunction {
115
+ <T>(initialValue: T, options?: StateOptions): [StateValue<T>, StateAction<T>];
116
+ <T, P>(computeFn: (params: P) => T, options: StateOptions<P> & {
117
+ params: P;
118
+ }): [StateValue<T>];
119
+ <T>(computeFn: () => T, options?: StateOptions): [StateValue<T>];
120
+ <T, P>(fetcher: (params: P) => Promise<T>, options: StateOptions<P> & {
121
+ params: P;
122
+ }): [StateValue<T | undefined>, () => void, StateValue<AsyncStatus>, StateValue<unknown>];
123
+ <T>(fetcher: () => Promise<T>, options?: StateOptions): [StateValue<T | undefined>, () => void, StateValue<AsyncStatus>, StateValue<unknown>];
124
+ /** Delete a specific global state by key */
125
+ delete: (key: StateKey) => boolean;
126
+ /** Clear all global states */
127
+ clear: () => void;
128
+ /** Check if a global state exists */
129
+ has: (key: StateKey) => boolean;
130
+ /** Current number of global states */
131
+ readonly size: number;
132
+ }
133
+ declare const _state: StateFunction;
134
+
135
+ /**
136
+ * Ref object type for DOM element references
137
+ */
138
+ interface RefObject<T> {
139
+ current: T | null;
12
140
  }
13
- declare function createContext<T>(defaultValue: T): Context<T>;
14
141
  /**
15
- * Get the current value from a context.
142
+ * Create a ref object to hold a reference to a DOM element.
143
+ * Use with the `ref` prop on JSX elements.
144
+ *
145
+ * @param initialValue - Initial value (typically null)
146
+ * @returns A ref object with a `current` property
16
147
  *
17
148
  * @example
18
149
  * ```tsx
19
- * const theme = context(ThemeContext)
150
+ * function MyComponent() {
151
+ * const inputRef = ref<HTMLInputElement>(null)
152
+ *
153
+ * const focusInput = () => {
154
+ * inputRef.current?.focus()
155
+ * }
156
+ *
157
+ * return (
158
+ * <div>
159
+ * <input ref={inputRef} type="text" />
160
+ * <button onclick={focusInput}>Focus</button>
161
+ * </div>
162
+ * )
163
+ * }
20
164
  * ```
21
165
  */
22
- declare function context<T>(ctx: Context<T>): T;
166
+ declare function ref<T>(initialValue: T | null): RefObject<T>;
23
167
 
24
- export { type Context, context, createContext };
168
+ export { type AsyncStatus, type RefObject, type StateAction, type StateKey, type StateOptions, type StateValue, equals, isStateValue, isTruthy, ref, _state as state };
package/dist/core.d.ts CHANGED
@@ -1,24 +1,168 @@
1
- export { A as AsyncStatus, S as StateAction, b as StateKey, c as StateOptions, a as StateValue, _ as state } from './state-kK9sQh9s.js';
2
- export { d as batch, e as effect, o as onCleanup, b as onMount, r as root, u as untrack } from './signal-mNtlF8-v.js';
3
- import { a as FNodeChild } from './renderer-DSLb-FGg.js';
1
+ export { e as effect } from './effect-BlnnM1t5.js';
4
2
 
5
- interface Context<T> {
6
- id: symbol;
7
- Provider: (props: {
8
- value: T;
9
- children: FNodeChild;
10
- }) => FNodeChild;
11
- defaultValue: T;
3
+ /** Key type - string or array of serializable values */
4
+ type StateKey = string | readonly (string | number | boolean | null | undefined | object)[];
5
+ /** Action function type for state mutation */
6
+ type StateAction<T> = (newValue: T | ((prev: T) => T)) => void;
7
+ /**
8
+ * StateValue type - a value-like proxy that behaves like T.
9
+ * Can be used directly in expressions and JSX.
10
+ */
11
+ type StateValue<T> = T & (() => T) & {
12
+ peek(): T;
13
+ };
14
+ /**
15
+ * Check if a value is a StateValue (created by the state() API).
16
+ * Useful for type guards and runtime detection of reactive state.
17
+ * @internal
18
+ * @param value - The value to check
19
+ * @returns true if the value is a StateValue proxy, false otherwise
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * const count = state(0)
24
+ * isStateValue(count) // true
25
+ * isStateValue(5) // false
26
+ * ```
27
+ */
28
+ declare function isStateValue(value: unknown): boolean;
29
+ /**
30
+ * Compare a StateValue with a primitive value safely.
31
+ * Handles Proxy comparison automatically by extracting the underlying value.
32
+ *
33
+ * @param stateValue - The StateValue to compare
34
+ * @param value - The value to compare against
35
+ * @returns true if the StateValue's underlying value equals the comparison value
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const [count, setCount] = state(0)
40
+ *
41
+ * // ✅ Safe comparison using helper
42
+ * if (equals(count, 5)) {
43
+ * console.log('Count is 5')
44
+ * }
45
+ *
46
+ * // ❌ Direct comparison (always false)
47
+ * if (count === 5) { ... }
48
+ * ```
49
+ */
50
+ declare function equals<T>(stateValue: StateValue<T>, value: T): boolean;
51
+ /**
52
+ * Check if a StateValue is truthy.
53
+ * Useful for boolean checks without explicit conversion.
54
+ *
55
+ * @param stateValue - The StateValue to check
56
+ * @returns true if the underlying value is truthy
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * const [user, setUser] = state<User | null>(null)
61
+ *
62
+ * // ✅ Safe boolean check
63
+ * if (isTruthy(user)) {
64
+ * console.log('User exists:', user.name)
65
+ * }
66
+ *
67
+ * // ❌ Direct check (always true for Proxy)
68
+ * if (user) { ... }
69
+ * ```
70
+ */
71
+ declare function isTruthy<T>(stateValue: StateValue<T>): boolean;
72
+ /** Async state status */
73
+ type AsyncStatus = 'idle' | 'loading' | 'success' | 'error';
74
+ /** Options for state() */
75
+ interface StateOptions<P = unknown> {
76
+ /**
77
+ * Key for global state sharing. Can be a string or array.
78
+ * Array keys are useful for hierarchical namespacing.
79
+ * @example
80
+ * state('light', { key: 'theme' })
81
+ * state(null, { key: ['user', 'profile', userId] })
82
+ */
83
+ key?: StateKey;
84
+ /**
85
+ * Parameters to pass to the function (for computed/async state).
86
+ * Improves DX by making dependencies explicit.
87
+ * @example
88
+ * state(
89
+ * async ({ userId }) => fetch(`/api/users/${userId}`),
90
+ * { key: ['user', userId], params: { userId } }
91
+ * )
92
+ */
93
+ params?: P;
94
+ }
95
+ /**
96
+ * Unified State API
97
+ *
98
+ * One function for all reactive state needs - always returns an array for consistency:
99
+ * 1. Simple state: const [count, setCount] = state(0)
100
+ * 2. Derived state: const [doubled] = state(() => count * 2)
101
+ * 3. Async state: const [data, refetch, status, error] = state(async () => fetch(...))
102
+ * 4. Global state: const [theme, setTheme] = state('light', { key: 'theme' })
103
+ * 5. With params: const [user] = state(async (p) => fetch(`/api/${p.id}`), { params: { id } })
104
+ *
105
+ * @example
106
+ * ```tsx
107
+ * function Counter() {
108
+ * const [count, setCount] = state(0)
109
+ * const [doubled] = state(() => count * 2)
110
+ * return <Button onPress={() => setCount(count + 1)}>{doubled}</Button>
111
+ * }
112
+ * ```
113
+ */
114
+ interface StateFunction {
115
+ <T>(initialValue: T, options?: StateOptions): [StateValue<T>, StateAction<T>];
116
+ <T, P>(computeFn: (params: P) => T, options: StateOptions<P> & {
117
+ params: P;
118
+ }): [StateValue<T>];
119
+ <T>(computeFn: () => T, options?: StateOptions): [StateValue<T>];
120
+ <T, P>(fetcher: (params: P) => Promise<T>, options: StateOptions<P> & {
121
+ params: P;
122
+ }): [StateValue<T | undefined>, () => void, StateValue<AsyncStatus>, StateValue<unknown>];
123
+ <T>(fetcher: () => Promise<T>, options?: StateOptions): [StateValue<T | undefined>, () => void, StateValue<AsyncStatus>, StateValue<unknown>];
124
+ /** Delete a specific global state by key */
125
+ delete: (key: StateKey) => boolean;
126
+ /** Clear all global states */
127
+ clear: () => void;
128
+ /** Check if a global state exists */
129
+ has: (key: StateKey) => boolean;
130
+ /** Current number of global states */
131
+ readonly size: number;
132
+ }
133
+ declare const _state: StateFunction;
134
+
135
+ /**
136
+ * Ref object type for DOM element references
137
+ */
138
+ interface RefObject<T> {
139
+ current: T | null;
12
140
  }
13
- declare function createContext<T>(defaultValue: T): Context<T>;
14
141
  /**
15
- * Get the current value from a context.
142
+ * Create a ref object to hold a reference to a DOM element.
143
+ * Use with the `ref` prop on JSX elements.
144
+ *
145
+ * @param initialValue - Initial value (typically null)
146
+ * @returns A ref object with a `current` property
16
147
  *
17
148
  * @example
18
149
  * ```tsx
19
- * const theme = context(ThemeContext)
150
+ * function MyComponent() {
151
+ * const inputRef = ref<HTMLInputElement>(null)
152
+ *
153
+ * const focusInput = () => {
154
+ * inputRef.current?.focus()
155
+ * }
156
+ *
157
+ * return (
158
+ * <div>
159
+ * <input ref={inputRef} type="text" />
160
+ * <button onclick={focusInput}>Focus</button>
161
+ * </div>
162
+ * )
163
+ * }
20
164
  * ```
21
165
  */
22
- declare function context<T>(ctx: Context<T>): T;
166
+ declare function ref<T>(initialValue: T | null): RefObject<T>;
23
167
 
24
- export { type Context, context, createContext };
168
+ export { type AsyncStatus, type RefObject, type StateAction, type StateKey, type StateOptions, type StateValue, equals, isStateValue, isTruthy, ref, _state as state };
package/dist/core.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkCNY6FPKJ_js=require('./chunk-CNY6FPKJ.js'),chunkI7UCVARB_js=require('./chunk-I7UCVARB.js'),chunkROYFUJN5_js=require('./chunk-ROYFUJN5.js');Object.defineProperty(exports,"context",{enumerable:true,get:function(){return chunkCNY6FPKJ_js.b}});Object.defineProperty(exports,"createContext",{enumerable:true,get:function(){return chunkCNY6FPKJ_js.a}});Object.defineProperty(exports,"state",{enumerable:true,get:function(){return chunkI7UCVARB_js.f}});Object.defineProperty(exports,"batch",{enumerable:true,get:function(){return chunkROYFUJN5_js.l}});Object.defineProperty(exports,"effect",{enumerable:true,get:function(){return chunkROYFUJN5_js.j}});Object.defineProperty(exports,"onCleanup",{enumerable:true,get:function(){return chunkROYFUJN5_js.o}});Object.defineProperty(exports,"onMount",{enumerable:true,get:function(){return chunkROYFUJN5_js.g}});Object.defineProperty(exports,"root",{enumerable:true,get:function(){return chunkROYFUJN5_js.m}});Object.defineProperty(exports,"untrack",{enumerable:true,get:function(){return chunkROYFUJN5_js.k}});//# sourceMappingURL=core.js.map
1
+ 'use strict';var chunkRDA77IE6_js=require('./chunk-RDA77IE6.js'),chunkYGMMJWAA_js=require('./chunk-YGMMJWAA.js');Object.defineProperty(exports,"equals",{enumerable:true,get:function(){return chunkRDA77IE6_js.f}});Object.defineProperty(exports,"isStateValue",{enumerable:true,get:function(){return chunkRDA77IE6_js.d}});Object.defineProperty(exports,"isTruthy",{enumerable:true,get:function(){return chunkRDA77IE6_js.g}});Object.defineProperty(exports,"ref",{enumerable:true,get:function(){return chunkRDA77IE6_js.i}});Object.defineProperty(exports,"state",{enumerable:true,get:function(){return chunkRDA77IE6_js.h}});Object.defineProperty(exports,"effect",{enumerable:true,get:function(){return chunkYGMMJWAA_js.h}});//# sourceMappingURL=core.js.map
2
2
  //# sourceMappingURL=core.js.map
package/dist/core.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export{b as context,a as createContext}from'./chunk-CZYIK6FD.mjs';export{f as state}from'./chunk-2U4DW375.mjs';export{l as batch,j as effect,o as onCleanup,g as onMount,m as root,k as untrack}from'./chunk-5S3ZQ2LB.mjs';//# sourceMappingURL=core.mjs.map
1
+ export{f as equals,d as isStateValue,g as isTruthy,i as ref,h as state}from'./chunk-2ZHUQBNI.mjs';export{h as effect}from'./chunk-J4CK5NRW.mjs';//# sourceMappingURL=core.mjs.map
2
2
  //# sourceMappingURL=core.mjs.map
package/dist/dom.d.cts CHANGED
@@ -1,7 +1,6 @@
1
- export { e as effect, r as root } from './signal-mNtlF8-v.cjs';
2
- export { _ as state } from './state-kK9sQh9s.cjs';
3
- export { D as DOMRenderer, F as Fragment, P as Portal, a as createReactiveRoot, c as createRoot, d as domRenderer, f, m as mountReactive, r as render } from './portal-BpcIlK9y.cjs';
1
+ export { D as DOMRenderer, F as Fragment, P as Portal, a as createReactiveRoot, c as createRoot, d as domRenderer, f, m as mountReactive, r as render } from './portal-CAEbiMUZ.cjs';
4
2
  export { C as CommonProps, R as Renderer } from './renderer-DSLb-FGg.cjs';
3
+ import './signal-Dxh9PsKr.cjs';
5
4
 
6
5
  /**
7
6
  * Hydration options
package/dist/dom.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- export { e as effect, r as root } from './signal-mNtlF8-v.js';
2
- export { _ as state } from './state-kK9sQh9s.js';
3
- export { D as DOMRenderer, F as Fragment, P as Portal, a as createReactiveRoot, c as createRoot, d as domRenderer, f, m as mountReactive, r as render } from './portal-DBwz7gD0.js';
1
+ export { D as DOMRenderer, F as Fragment, P as Portal, a as createReactiveRoot, c as createRoot, d as domRenderer, f, m as mountReactive, r as render } from './portal-C3ESJhlv.js';
4
2
  export { C as CommonProps, R as Renderer } from './renderer-DSLb-FGg.js';
3
+ import './signal-Dxh9PsKr.js';
5
4
 
6
5
  /**
7
6
  * Hydration options
package/dist/dom.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkREETNY2Z_js=require('./chunk-REETNY2Z.js');require('./chunk-CNY6FPKJ.js');var chunkI7UCVARB_js=require('./chunk-I7UCVARB.js'),chunkQ7IWDVJ4_js=require('./chunk-Q7IWDVJ4.js');require('./chunk-WQFQO5LK.js');var chunkROYFUJN5_js=require('./chunk-ROYFUJN5.js');var b={viewBox:"viewBox",preserveAspectRatio:"preserveAspectRatio",strokeWidth:"stroke-width",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",fillOpacity:"fill-opacity",strokeOpacity:"stroke-opacity",stopColor:"stop-color",stopOpacity:"stop-opacity",clipPath:"clip-path",markerEnd:"marker-end",markerStart:"marker-start",markerMid:"marker-mid"};function T(t,e,a={}){let{onMismatch:r,recoverMismatch:n=false}=a,i=(s,l,p)=>{r?r(s,l,p):typeof __DEV__<"u"&&__DEV__&&console.warn(`[Flexium Hydration] ${s}`);};c(t,e.firstChild,{handleMismatch:i,recoverMismatch:n});}function c(t,e,a){if(t==null||t===false)return e;if(!e)return a.handleMismatch("No DOM node found for vnode",e,t),null;if(typeof t=="string"||typeof t=="number")if(e.nodeType===Node.TEXT_NODE){let r=String(t);return e.textContent!==r&&(a.handleMismatch(`Text mismatch: "${e.textContent}" vs "${r}"`,e,t),e.textContent=r),e.nextSibling}else return a.handleMismatch(`Expected text node, got ${e.nodeType}`,e,t),e.nextSibling;if(chunkROYFUJN5_js.n(t)&&e.nodeType===Node.TEXT_NODE)return chunkROYFUJN5_js.j(()=>{e.textContent=String(t.value);}),e.nextSibling;if(typeof t=="function")return chunkROYFUJN5_js.j(()=>{let r=t();e.nodeType===Node.TEXT_NODE&&(e.textContent=String(r));}),e.nextSibling;if(typeof t.type=="function"){let r=t.type({...t.props,children:t.children});return c(r,e,a)}if(t.type==="fragment"||t.type===null){let r=e,n=t.children||[];for(let i of n)r=c(i,r,a);return r}if(typeof t.type=="string"){if(e.nodeType!==Node.ELEMENT_NODE)return a.handleMismatch(`Expected element node, got ${e.nodeType}`,e,t),e.nextSibling;let r=e,n=r.tagName.toLowerCase();if(n!==t.type.toLowerCase())return a.handleMismatch(`Tag mismatch: "${n}" vs "${t.type}"`,e,t),e.nextSibling;t.props&&S(r,t.props,a);let i=r.firstChild;if(t.children){let s=Array.isArray(t.children)?t.children.flat():[t.children];for(let l of s)l==null||l===false||(i=c(l,i,a));}return r.nextSibling}return e?.nextSibling||null}function S(t,e,a){for(let r in e){let n=e[r];if(r==="children"||r==="key"||r==="ref"){r==="ref"&&typeof n=="function"&&n(t);continue}if(r.startsWith("on")){let i=r.slice(2).toLowerCase();t.addEventListener(i,n);continue}if(chunkROYFUJN5_js.n(n)){let i=r==="className"?"class":r;chunkROYFUJN5_js.j(()=>{if(i==="class")t.setAttribute("class",String(n.value));else if(i==="style"&&typeof n.value=="object")Object.assign(t.style,n.value);else {let s=b[i]||i;i in t&&!(t instanceof SVGElement)?t[i]=n.value:t.setAttribute(s,String(n.value));}});continue}if(typeof __DEV__<"u"&&__DEV__&&(r==="className"||r==="class")){let i=t.getAttribute("class")||"";i!==n&&a.handleMismatch(`Class mismatch on <${t.tagName.toLowerCase()}>: "${i}" vs "${n}"`,t,e);}}}Object.defineProperty(exports,"DOMRenderer",{enumerable:true,get:function(){return chunkREETNY2Z_js.a}});Object.defineProperty(exports,"Portal",{enumerable:true,get:function(){return chunkREETNY2Z_js.i}});Object.defineProperty(exports,"createReactiveRoot",{enumerable:true,get:function(){return chunkREETNY2Z_js.f}});Object.defineProperty(exports,"createRoot",{enumerable:true,get:function(){return chunkREETNY2Z_js.h}});Object.defineProperty(exports,"domRenderer",{enumerable:true,get:function(){return chunkREETNY2Z_js.b}});Object.defineProperty(exports,"mountReactive",{enumerable:true,get:function(){return chunkREETNY2Z_js.e}});Object.defineProperty(exports,"render",{enumerable:true,get:function(){return chunkREETNY2Z_js.g}});Object.defineProperty(exports,"state",{enumerable:true,get:function(){return chunkI7UCVARB_js.f}});Object.defineProperty(exports,"Fragment",{enumerable:true,get:function(){return chunkQ7IWDVJ4_js.b}});Object.defineProperty(exports,"f",{enumerable:true,get:function(){return chunkQ7IWDVJ4_js.a}});Object.defineProperty(exports,"effect",{enumerable:true,get:function(){return chunkROYFUJN5_js.j}});Object.defineProperty(exports,"root",{enumerable:true,get:function(){return chunkROYFUJN5_js.m}});exports.hydrate=T;//# sourceMappingURL=dom.js.map
1
+ 'use strict';var chunkVIVO4FHN_js=require('./chunk-VIVO4FHN.js');require('./chunk-DFG62GKW.js'),require('./chunk-RDA77IE6.js');var chunkQ7IWDVJ4_js=require('./chunk-Q7IWDVJ4.js');require('./chunk-WQFQO5LK.js');var chunkYGMMJWAA_js=require('./chunk-YGMMJWAA.js');var C={viewBox:"viewBox",preserveAspectRatio:"preserveAspectRatio",strokeWidth:"stroke-width",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",fillOpacity:"fill-opacity",strokeOpacity:"stroke-opacity",stopColor:"stop-color",stopOpacity:"stop-opacity",clipPath:"clip-path",markerEnd:"marker-end",markerStart:"marker-start",markerMid:"marker-mid"};function M(t,e,a={}){let{onMismatch:n,recoverMismatch:r=false}=a,i=(s,l,p)=>{n?n(s,l,p):typeof __DEV__<"u"&&__DEV__&&console.warn(`[Flexium Hydration] ${s}`);};c(t,e.firstChild,{handleMismatch:i,recoverMismatch:r});}function c(t,e,a){if(t==null||t===false)return e;if(!e)return a.handleMismatch("No DOM node found for vnode",e,t),null;if(typeof t=="string"||typeof t=="number")if(e.nodeType===Node.TEXT_NODE){let n=String(t);return e.textContent!==n&&(a.handleMismatch(`Text mismatch: "${e.textContent}" vs "${n}"`,e,t),e.textContent=n),e.nextSibling}else return a.handleMismatch(`Expected text node, got ${e.nodeType}`,e,t),e.nextSibling;if(chunkYGMMJWAA_js.l(t)&&e.nodeType===Node.TEXT_NODE)return chunkYGMMJWAA_js.h(()=>{e.textContent=String(t.value);}),e.nextSibling;if(typeof t=="function")return chunkYGMMJWAA_js.h(()=>{let n=t();e.nodeType===Node.TEXT_NODE&&(e.textContent=String(n));}),e.nextSibling;if(typeof t.type=="function"){let n=t.type({...t.props,children:t.children});return c(n,e,a)}if(t.type==="fragment"||t.type===null){let n=e,r=t.children||[];for(let i of r)n=c(i,n,a);return n}if(typeof t.type=="string"){if(e.nodeType!==Node.ELEMENT_NODE)return a.handleMismatch(`Expected element node, got ${e.nodeType}`,e,t),e.nextSibling;let n=e,r=n.tagName.toLowerCase();if(r!==t.type.toLowerCase())return a.handleMismatch(`Tag mismatch: "${r}" vs "${t.type}"`,e,t),e.nextSibling;t.props&&b(n,t.props,a);let i=n.firstChild;if(t.children){let s=Array.isArray(t.children)?t.children.flat():[t.children];for(let l of s)l==null||l===false||(i=c(l,i,a));}return n.nextSibling}return e?.nextSibling||null}function b(t,e,a){for(let n in e){let r=e[n];if(n==="children"||n==="key"||n==="ref"){n==="ref"&&typeof r=="function"&&r(t);continue}if(n.startsWith("on")){let i=n.slice(2).toLowerCase();t.addEventListener(i,r);continue}if(chunkYGMMJWAA_js.l(r)){let i=n==="className"?"class":n;chunkYGMMJWAA_js.h(()=>{if(i==="class")t.setAttribute("class",String(r.value));else if(i==="style"&&typeof r.value=="object")Object.assign(t.style,r.value);else {let s=C[i]||i;i in t&&!(t instanceof SVGElement)?t[i]=r.value:t.setAttribute(s,String(r.value));}});continue}if(typeof __DEV__<"u"&&__DEV__&&(n==="className"||n==="class")){let i=t.getAttribute("class")||"";i!==r&&a.handleMismatch(`Class mismatch on <${t.tagName.toLowerCase()}>: "${i}" vs "${r}"`,t,e);}}}Object.defineProperty(exports,"DOMRenderer",{enumerable:true,get:function(){return chunkVIVO4FHN_js.a}});Object.defineProperty(exports,"Portal",{enumerable:true,get:function(){return chunkVIVO4FHN_js.i}});Object.defineProperty(exports,"createReactiveRoot",{enumerable:true,get:function(){return chunkVIVO4FHN_js.f}});Object.defineProperty(exports,"createRoot",{enumerable:true,get:function(){return chunkVIVO4FHN_js.h}});Object.defineProperty(exports,"domRenderer",{enumerable:true,get:function(){return chunkVIVO4FHN_js.b}});Object.defineProperty(exports,"mountReactive",{enumerable:true,get:function(){return chunkVIVO4FHN_js.e}});Object.defineProperty(exports,"render",{enumerable:true,get:function(){return chunkVIVO4FHN_js.g}});Object.defineProperty(exports,"Fragment",{enumerable:true,get:function(){return chunkQ7IWDVJ4_js.b}});Object.defineProperty(exports,"f",{enumerable:true,get:function(){return chunkQ7IWDVJ4_js.a}});exports.hydrate=M;//# sourceMappingURL=dom.js.map
2
2
  //# sourceMappingURL=dom.js.map
package/dist/dom.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/renderers/dom/hydrate.ts"],"names":["SVG_ATTR_MAP","hydrate","vnode","container","options","onMismatch","recoverMismatch","handleMismatch","message","domNode","vn","hydrateNode","ctx","text","isSignal","effect","value","result","currentNode","children","child","el","tagName","hydrateProps","childDom","props","key","eventName","propName","attrName","domClass"],"mappings":"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","file":"dom.js","sourcesContent":["import { effect, isSignal } from '../../core/signal'\n\n/**\n * SVG Attribute Case Mapping\n * React-like camelCase to SVG case-sensitive attributes\n */\nconst SVG_ATTR_MAP: Record<string, string> = {\n viewBox: 'viewBox',\n preserveAspectRatio: 'preserveAspectRatio',\n strokeWidth: 'stroke-width',\n strokeLinecap: 'stroke-linecap',\n strokeLinejoin: 'stroke-linejoin',\n strokeDasharray: 'stroke-dasharray',\n strokeDashoffset: 'stroke-dashoffset',\n fillOpacity: 'fill-opacity',\n strokeOpacity: 'stroke-opacity',\n stopColor: 'stop-color',\n stopOpacity: 'stop-opacity',\n clipPath: 'clip-path',\n markerEnd: 'marker-end',\n markerStart: 'marker-start',\n markerMid: 'marker-mid',\n}\n\n/**\n * Hydration options\n */\nexport interface HydrateOptions {\n /** Called when hydration encounters a mismatch */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onMismatch?: (message: string, domNode: Node | null, vnode: any) => void\n /** Whether to recover from mismatches by re-rendering */\n recoverMismatch?: boolean\n}\n\n/**\n * Hydrate server-rendered HTML with client-side interactivity\n *\n * This function walks the existing DOM tree and attaches event handlers,\n * sets up signal bindings, and validates that the DOM matches the expected vnode structure.\n *\n * @param vnode - Virtual node to hydrate against\n * @param container - Container element with server-rendered HTML\n * @param options - Hydration options\n *\n * @example\n * ```tsx\n * // Server rendered HTML in #app\n * hydrate(<App />, document.getElementById('app'));\n * ```\n */\nexport function hydrate(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vnode: any,\n container: Element,\n options: HydrateOptions = {}\n) {\n const { onMismatch, recoverMismatch = false } = options\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handleMismatch = (message: string, domNode: Node | null, vn: any) => {\n if (onMismatch) {\n onMismatch(message, domNode, vn)\n } else if (typeof __DEV__ !== 'undefined' ? __DEV__ : false) {\n console.warn(`[Flexium Hydration] ${message}`)\n }\n }\n\n hydrateNode(vnode, container.firstChild as Node, {\n handleMismatch,\n recoverMismatch,\n })\n}\n\ninterface HydrateContext {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleMismatch: (message: string, domNode: Node | null, vnode: any) => void\n recoverMismatch: boolean\n}\n\nfunction hydrateNode(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vnode: any,\n domNode: Node | null,\n ctx: HydrateContext\n): Node | null {\n if (vnode === null || vnode === undefined || vnode === false) {\n return domNode\n }\n\n if (!domNode) {\n ctx.handleMismatch('No DOM node found for vnode', domNode, vnode)\n return null\n }\n\n // Handle text/number primitives\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n if (domNode.nodeType === Node.TEXT_NODE) {\n const text = String(vnode)\n if (domNode.textContent !== text) {\n ctx.handleMismatch(\n `Text mismatch: \"${domNode.textContent}\" vs \"${text}\"`,\n domNode,\n vnode\n )\n domNode.textContent = text\n }\n return domNode.nextSibling\n } else {\n ctx.handleMismatch(\n `Expected text node, got ${domNode.nodeType}`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n }\n\n // Handle signals - create reactive binding\n if (isSignal(vnode)) {\n if (domNode.nodeType === Node.TEXT_NODE) {\n effect(() => {\n domNode.textContent = String(vnode.value)\n })\n return domNode.nextSibling\n }\n }\n\n // Handle computed values\n if (typeof vnode === 'function') {\n // Create reactive binding for computed/derived values\n effect(() => {\n const value = vnode()\n if (domNode.nodeType === Node.TEXT_NODE) {\n domNode.textContent = String(value)\n }\n })\n return domNode.nextSibling\n }\n\n // Handle function components\n if (typeof vnode.type === 'function') {\n const result = vnode.type({ ...vnode.props, children: vnode.children })\n return hydrateNode(result, domNode, ctx)\n }\n\n // Handle fragments\n if (vnode.type === 'fragment' || vnode.type === null) {\n let currentNode: Node | null = domNode\n const children = vnode.children || []\n for (const child of children) {\n currentNode = hydrateNode(child, currentNode, ctx)\n }\n return currentNode\n }\n\n // Handle element vnodes\n if (typeof vnode.type === 'string') {\n if (domNode.nodeType !== Node.ELEMENT_NODE) {\n ctx.handleMismatch(\n `Expected element node, got ${domNode.nodeType}`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n\n const el = domNode as Element\n const tagName = el.tagName.toLowerCase()\n\n if (tagName !== vnode.type.toLowerCase()) {\n ctx.handleMismatch(\n `Tag mismatch: \"${tagName}\" vs \"${vnode.type}\"`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n\n // Hydrate props\n if (vnode.props) {\n hydrateProps(el, vnode.props, ctx)\n }\n\n // Hydrate children\n let childDom = el.firstChild\n if (vnode.children) {\n const children = Array.isArray(vnode.children)\n ? vnode.children.flat()\n : [vnode.children]\n for (const child of children) {\n if (child === null || child === undefined || child === false) continue\n childDom = hydrateNode(child, childDom, ctx) as ChildNode | null\n }\n }\n\n return el.nextSibling\n }\n\n return domNode?.nextSibling || null\n}\n\n/**\n * Hydrate element props - attach events, set up reactive bindings\n */\nfunction hydrateProps(\n el: Element,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n props: Record<string, any>,\n ctx: HydrateContext\n): void {\n for (const key in props) {\n const value = props[key]\n\n if (key === 'children' || key === 'key' || key === 'ref') {\n // Handle ref callback\n if (key === 'ref' && typeof value === 'function') {\n value(el)\n }\n continue\n }\n\n // Event handlers\n if (key.startsWith('on')) {\n const eventName = key.slice(2).toLowerCase()\n el.addEventListener(eventName, value)\n continue\n }\n\n // Reactive props (signals)\n if (isSignal(value)) {\n const propName = key === 'className' ? 'class' : key\n effect(() => {\n if (propName === 'class') {\n el.setAttribute('class', String(value.value))\n } else if (propName === 'style' && typeof value.value === 'object') {\n Object.assign((el as HTMLElement).style, value.value)\n } else {\n // Handle SVG attributes\n const attrName = SVG_ATTR_MAP[propName] || propName\n\n if (propName in el && !(el instanceof SVGElement)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ; (el as any)[propName] = value.value\n } else {\n el.setAttribute(attrName, String(value.value))\n }\n }\n })\n continue\n }\n\n // Validate static props match (in development)\n if (typeof __DEV__ !== 'undefined' ? __DEV__ : false) {\n if (key === 'className' || key === 'class') {\n const domClass = el.getAttribute('class') || ''\n if (domClass !== value) {\n ctx.handleMismatch(\n `Class mismatch on <${el.tagName.toLowerCase()}>: \"${domClass}\" vs \"${value}\"`,\n el,\n props\n )\n }\n }\n }\n }\n}\n\n// Declare global __DEV__ for development mode detection\ndeclare global {\n const __DEV__: boolean | undefined\n}\n"]}
1
+ {"version":3,"sources":["../src/renderers/dom/hydrate.ts"],"names":["SVG_ATTR_MAP","hydrate","vnode","container","options","onMismatch","recoverMismatch","handleMismatch","message","domNode","vn","hydrateNode","ctx","text","isSignal","effect","value","result","currentNode","children","child","el","tagName","hydrateProps","childDom","props","key","eventName","propName","attrName","domClass"],"mappings":"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","file":"dom.js","sourcesContent":["import { effect, isSignal } from '../../core/signal'\n\n/**\n * SVG Attribute Case Mapping\n * React-like camelCase to SVG case-sensitive attributes\n */\nconst SVG_ATTR_MAP: Record<string, string> = {\n viewBox: 'viewBox',\n preserveAspectRatio: 'preserveAspectRatio',\n strokeWidth: 'stroke-width',\n strokeLinecap: 'stroke-linecap',\n strokeLinejoin: 'stroke-linejoin',\n strokeDasharray: 'stroke-dasharray',\n strokeDashoffset: 'stroke-dashoffset',\n fillOpacity: 'fill-opacity',\n strokeOpacity: 'stroke-opacity',\n stopColor: 'stop-color',\n stopOpacity: 'stop-opacity',\n clipPath: 'clip-path',\n markerEnd: 'marker-end',\n markerStart: 'marker-start',\n markerMid: 'marker-mid',\n}\n\n/**\n * Hydration options\n */\nexport interface HydrateOptions {\n /** Called when hydration encounters a mismatch */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onMismatch?: (message: string, domNode: Node | null, vnode: any) => void\n /** Whether to recover from mismatches by re-rendering */\n recoverMismatch?: boolean\n}\n\n/**\n * Hydrate server-rendered HTML with client-side interactivity\n *\n * This function walks the existing DOM tree and attaches event handlers,\n * sets up signal bindings, and validates that the DOM matches the expected vnode structure.\n *\n * @param vnode - Virtual node to hydrate against\n * @param container - Container element with server-rendered HTML\n * @param options - Hydration options\n *\n * @example\n * ```tsx\n * // Server rendered HTML in #app\n * hydrate(<App />, document.getElementById('app'));\n * ```\n */\nexport function hydrate(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vnode: any,\n container: Element,\n options: HydrateOptions = {}\n) {\n const { onMismatch, recoverMismatch = false } = options\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handleMismatch = (message: string, domNode: Node | null, vn: any) => {\n if (onMismatch) {\n onMismatch(message, domNode, vn)\n } else if (typeof __DEV__ !== 'undefined' ? __DEV__ : false) {\n console.warn(`[Flexium Hydration] ${message}`)\n }\n }\n\n hydrateNode(vnode, container.firstChild as Node, {\n handleMismatch,\n recoverMismatch,\n })\n}\n\ninterface HydrateContext {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleMismatch: (message: string, domNode: Node | null, vnode: any) => void\n recoverMismatch: boolean\n}\n\nfunction hydrateNode(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vnode: any,\n domNode: Node | null,\n ctx: HydrateContext\n): Node | null {\n if (vnode === null || vnode === undefined || vnode === false) {\n return domNode\n }\n\n if (!domNode) {\n ctx.handleMismatch('No DOM node found for vnode', domNode, vnode)\n return null\n }\n\n // Handle text/number primitives\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n if (domNode.nodeType === Node.TEXT_NODE) {\n const text = String(vnode)\n if (domNode.textContent !== text) {\n ctx.handleMismatch(\n `Text mismatch: \"${domNode.textContent}\" vs \"${text}\"`,\n domNode,\n vnode\n )\n domNode.textContent = text\n }\n return domNode.nextSibling\n } else {\n ctx.handleMismatch(\n `Expected text node, got ${domNode.nodeType}`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n }\n\n // Handle signals - create reactive binding\n if (isSignal(vnode)) {\n if (domNode.nodeType === Node.TEXT_NODE) {\n effect(() => {\n domNode.textContent = String(vnode.value)\n })\n return domNode.nextSibling\n }\n }\n\n // Handle computed values\n if (typeof vnode === 'function') {\n // Create reactive binding for computed/derived values\n effect(() => {\n const value = vnode()\n if (domNode.nodeType === Node.TEXT_NODE) {\n domNode.textContent = String(value)\n }\n })\n return domNode.nextSibling\n }\n\n // Handle function components\n if (typeof vnode.type === 'function') {\n const result = vnode.type({ ...vnode.props, children: vnode.children })\n return hydrateNode(result, domNode, ctx)\n }\n\n // Handle fragments\n if (vnode.type === 'fragment' || vnode.type === null) {\n let currentNode: Node | null = domNode\n const children = vnode.children || []\n for (const child of children) {\n currentNode = hydrateNode(child, currentNode, ctx)\n }\n return currentNode\n }\n\n // Handle element vnodes\n if (typeof vnode.type === 'string') {\n if (domNode.nodeType !== Node.ELEMENT_NODE) {\n ctx.handleMismatch(\n `Expected element node, got ${domNode.nodeType}`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n\n const el = domNode as Element\n const tagName = el.tagName.toLowerCase()\n\n if (tagName !== vnode.type.toLowerCase()) {\n ctx.handleMismatch(\n `Tag mismatch: \"${tagName}\" vs \"${vnode.type}\"`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n\n // Hydrate props\n if (vnode.props) {\n hydrateProps(el, vnode.props, ctx)\n }\n\n // Hydrate children\n let childDom = el.firstChild\n if (vnode.children) {\n const children = Array.isArray(vnode.children)\n ? vnode.children.flat()\n : [vnode.children]\n for (const child of children) {\n if (child === null || child === undefined || child === false) continue\n childDom = hydrateNode(child, childDom, ctx) as ChildNode | null\n }\n }\n\n return el.nextSibling\n }\n\n return domNode?.nextSibling || null\n}\n\n/**\n * Hydrate element props - attach events, set up reactive bindings\n */\nfunction hydrateProps(\n el: Element,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n props: Record<string, any>,\n ctx: HydrateContext\n): void {\n for (const key in props) {\n const value = props[key]\n\n if (key === 'children' || key === 'key' || key === 'ref') {\n // Handle ref callback\n if (key === 'ref' && typeof value === 'function') {\n value(el)\n }\n continue\n }\n\n // Event handlers\n if (key.startsWith('on')) {\n const eventName = key.slice(2).toLowerCase()\n el.addEventListener(eventName, value)\n continue\n }\n\n // Reactive props (signals)\n if (isSignal(value)) {\n const propName = key === 'className' ? 'class' : key\n effect(() => {\n if (propName === 'class') {\n el.setAttribute('class', String(value.value))\n } else if (propName === 'style' && typeof value.value === 'object') {\n Object.assign((el as HTMLElement).style, value.value)\n } else {\n // Handle SVG attributes\n const attrName = SVG_ATTR_MAP[propName] || propName\n\n if (propName in el && !(el instanceof SVGElement)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ; (el as any)[propName] = value.value\n } else {\n el.setAttribute(attrName, String(value.value))\n }\n }\n })\n continue\n }\n\n // Validate static props match (in development)\n if (typeof __DEV__ !== 'undefined' ? __DEV__ : false) {\n if (key === 'className' || key === 'class') {\n const domClass = el.getAttribute('class') || ''\n if (domClass !== value) {\n ctx.handleMismatch(\n `Class mismatch on <${el.tagName.toLowerCase()}>: \"${domClass}\" vs \"${value}\"`,\n el,\n props\n )\n }\n }\n }\n }\n}\n\n// Declare global __DEV__ for development mode detection\ndeclare global {\n const __DEV__: boolean | undefined\n}\n"]}
package/dist/dom.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export{a as DOMRenderer,i as Portal,f as createReactiveRoot,h as createRoot,b as domRenderer,e as mountReactive,g as render}from'./chunk-EX2GURH5.mjs';import'./chunk-CZYIK6FD.mjs';export{f as state}from'./chunk-2U4DW375.mjs';export{b as Fragment,a as f}from'./chunk-WVEJT7HD.mjs';import'./chunk-KNF5ERPK.mjs';import {n,j}from'./chunk-5S3ZQ2LB.mjs';export{j as effect,m as root}from'./chunk-5S3ZQ2LB.mjs';var b={viewBox:"viewBox",preserveAspectRatio:"preserveAspectRatio",strokeWidth:"stroke-width",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",fillOpacity:"fill-opacity",strokeOpacity:"stroke-opacity",stopColor:"stop-color",stopOpacity:"stop-opacity",clipPath:"clip-path",markerEnd:"marker-end",markerStart:"marker-start",markerMid:"marker-mid"};function T(t,e,a={}){let{onMismatch:r,recoverMismatch:n=false}=a,i=(s,l,p)=>{r?r(s,l,p):typeof __DEV__<"u"&&__DEV__&&console.warn(`[Flexium Hydration] ${s}`);};c(t,e.firstChild,{handleMismatch:i,recoverMismatch:n});}function c(t,e,a){if(t==null||t===false)return e;if(!e)return a.handleMismatch("No DOM node found for vnode",e,t),null;if(typeof t=="string"||typeof t=="number")if(e.nodeType===Node.TEXT_NODE){let r=String(t);return e.textContent!==r&&(a.handleMismatch(`Text mismatch: "${e.textContent}" vs "${r}"`,e,t),e.textContent=r),e.nextSibling}else return a.handleMismatch(`Expected text node, got ${e.nodeType}`,e,t),e.nextSibling;if(n(t)&&e.nodeType===Node.TEXT_NODE)return j(()=>{e.textContent=String(t.value);}),e.nextSibling;if(typeof t=="function")return j(()=>{let r=t();e.nodeType===Node.TEXT_NODE&&(e.textContent=String(r));}),e.nextSibling;if(typeof t.type=="function"){let r=t.type({...t.props,children:t.children});return c(r,e,a)}if(t.type==="fragment"||t.type===null){let r=e,n=t.children||[];for(let i of n)r=c(i,r,a);return r}if(typeof t.type=="string"){if(e.nodeType!==Node.ELEMENT_NODE)return a.handleMismatch(`Expected element node, got ${e.nodeType}`,e,t),e.nextSibling;let r=e,n=r.tagName.toLowerCase();if(n!==t.type.toLowerCase())return a.handleMismatch(`Tag mismatch: "${n}" vs "${t.type}"`,e,t),e.nextSibling;t.props&&S(r,t.props,a);let i=r.firstChild;if(t.children){let s=Array.isArray(t.children)?t.children.flat():[t.children];for(let l of s)l==null||l===false||(i=c(l,i,a));}return r.nextSibling}return e?.nextSibling||null}function S(t,e,a){for(let r in e){let n$1=e[r];if(r==="children"||r==="key"||r==="ref"){r==="ref"&&typeof n$1=="function"&&n$1(t);continue}if(r.startsWith("on")){let i=r.slice(2).toLowerCase();t.addEventListener(i,n$1);continue}if(n(n$1)){let i=r==="className"?"class":r;j(()=>{if(i==="class")t.setAttribute("class",String(n$1.value));else if(i==="style"&&typeof n$1.value=="object")Object.assign(t.style,n$1.value);else {let s=b[i]||i;i in t&&!(t instanceof SVGElement)?t[i]=n$1.value:t.setAttribute(s,String(n$1.value));}});continue}if(typeof __DEV__<"u"&&__DEV__&&(r==="className"||r==="class")){let i=t.getAttribute("class")||"";i!==n$1&&a.handleMismatch(`Class mismatch on <${t.tagName.toLowerCase()}>: "${i}" vs "${n$1}"`,t,e);}}}export{T as hydrate};//# sourceMappingURL=dom.mjs.map
1
+ export{a as DOMRenderer,i as Portal,f as createReactiveRoot,h as createRoot,b as domRenderer,e as mountReactive,g as render}from'./chunk-JEDCNAAI.mjs';import'./chunk-RUXAK74B.mjs';import'./chunk-2ZHUQBNI.mjs';export{b as Fragment,a as f}from'./chunk-WVEJT7HD.mjs';import'./chunk-KNF5ERPK.mjs';import {l,h}from'./chunk-J4CK5NRW.mjs';var C={viewBox:"viewBox",preserveAspectRatio:"preserveAspectRatio",strokeWidth:"stroke-width",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",fillOpacity:"fill-opacity",strokeOpacity:"stroke-opacity",stopColor:"stop-color",stopOpacity:"stop-opacity",clipPath:"clip-path",markerEnd:"marker-end",markerStart:"marker-start",markerMid:"marker-mid"};function M(t,e,a={}){let{onMismatch:n,recoverMismatch:r=false}=a,i=(s,l,p)=>{n?n(s,l,p):typeof __DEV__<"u"&&__DEV__&&console.warn(`[Flexium Hydration] ${s}`);};c(t,e.firstChild,{handleMismatch:i,recoverMismatch:r});}function c(t,e,a){if(t==null||t===false)return e;if(!e)return a.handleMismatch("No DOM node found for vnode",e,t),null;if(typeof t=="string"||typeof t=="number")if(e.nodeType===Node.TEXT_NODE){let n=String(t);return e.textContent!==n&&(a.handleMismatch(`Text mismatch: "${e.textContent}" vs "${n}"`,e,t),e.textContent=n),e.nextSibling}else return a.handleMismatch(`Expected text node, got ${e.nodeType}`,e,t),e.nextSibling;if(l(t)&&e.nodeType===Node.TEXT_NODE)return h(()=>{e.textContent=String(t.value);}),e.nextSibling;if(typeof t=="function")return h(()=>{let n=t();e.nodeType===Node.TEXT_NODE&&(e.textContent=String(n));}),e.nextSibling;if(typeof t.type=="function"){let n=t.type({...t.props,children:t.children});return c(n,e,a)}if(t.type==="fragment"||t.type===null){let n=e,r=t.children||[];for(let i of r)n=c(i,n,a);return n}if(typeof t.type=="string"){if(e.nodeType!==Node.ELEMENT_NODE)return a.handleMismatch(`Expected element node, got ${e.nodeType}`,e,t),e.nextSibling;let n=e,r=n.tagName.toLowerCase();if(r!==t.type.toLowerCase())return a.handleMismatch(`Tag mismatch: "${r}" vs "${t.type}"`,e,t),e.nextSibling;t.props&&b(n,t.props,a);let i=n.firstChild;if(t.children){let s=Array.isArray(t.children)?t.children.flat():[t.children];for(let l of s)l==null||l===false||(i=c(l,i,a));}return n.nextSibling}return e?.nextSibling||null}function b(t,e,a){for(let n in e){let r=e[n];if(n==="children"||n==="key"||n==="ref"){n==="ref"&&typeof r=="function"&&r(t);continue}if(n.startsWith("on")){let i=n.slice(2).toLowerCase();t.addEventListener(i,r);continue}if(l(r)){let i=n==="className"?"class":n;h(()=>{if(i==="class")t.setAttribute("class",String(r.value));else if(i==="style"&&typeof r.value=="object")Object.assign(t.style,r.value);else {let s=C[i]||i;i in t&&!(t instanceof SVGElement)?t[i]=r.value:t.setAttribute(s,String(r.value));}});continue}if(typeof __DEV__<"u"&&__DEV__&&(n==="className"||n==="class")){let i=t.getAttribute("class")||"";i!==r&&a.handleMismatch(`Class mismatch on <${t.tagName.toLowerCase()}>: "${i}" vs "${r}"`,t,e);}}}export{M as hydrate};//# sourceMappingURL=dom.mjs.map
2
2
  //# sourceMappingURL=dom.mjs.map
package/dist/dom.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/renderers/dom/hydrate.ts"],"names":["SVG_ATTR_MAP","hydrate","vnode","container","options","onMismatch","recoverMismatch","handleMismatch","message","domNode","vn","hydrateNode","ctx","text","isSignal","effect","value","result","currentNode","children","child","el","tagName","hydrateProps","childDom","props","key","eventName","propName","attrName","domClass"],"mappings":"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","file":"dom.mjs","sourcesContent":["import { effect, isSignal } from '../../core/signal'\n\n/**\n * SVG Attribute Case Mapping\n * React-like camelCase to SVG case-sensitive attributes\n */\nconst SVG_ATTR_MAP: Record<string, string> = {\n viewBox: 'viewBox',\n preserveAspectRatio: 'preserveAspectRatio',\n strokeWidth: 'stroke-width',\n strokeLinecap: 'stroke-linecap',\n strokeLinejoin: 'stroke-linejoin',\n strokeDasharray: 'stroke-dasharray',\n strokeDashoffset: 'stroke-dashoffset',\n fillOpacity: 'fill-opacity',\n strokeOpacity: 'stroke-opacity',\n stopColor: 'stop-color',\n stopOpacity: 'stop-opacity',\n clipPath: 'clip-path',\n markerEnd: 'marker-end',\n markerStart: 'marker-start',\n markerMid: 'marker-mid',\n}\n\n/**\n * Hydration options\n */\nexport interface HydrateOptions {\n /** Called when hydration encounters a mismatch */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onMismatch?: (message: string, domNode: Node | null, vnode: any) => void\n /** Whether to recover from mismatches by re-rendering */\n recoverMismatch?: boolean\n}\n\n/**\n * Hydrate server-rendered HTML with client-side interactivity\n *\n * This function walks the existing DOM tree and attaches event handlers,\n * sets up signal bindings, and validates that the DOM matches the expected vnode structure.\n *\n * @param vnode - Virtual node to hydrate against\n * @param container - Container element with server-rendered HTML\n * @param options - Hydration options\n *\n * @example\n * ```tsx\n * // Server rendered HTML in #app\n * hydrate(<App />, document.getElementById('app'));\n * ```\n */\nexport function hydrate(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vnode: any,\n container: Element,\n options: HydrateOptions = {}\n) {\n const { onMismatch, recoverMismatch = false } = options\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handleMismatch = (message: string, domNode: Node | null, vn: any) => {\n if (onMismatch) {\n onMismatch(message, domNode, vn)\n } else if (typeof __DEV__ !== 'undefined' ? __DEV__ : false) {\n console.warn(`[Flexium Hydration] ${message}`)\n }\n }\n\n hydrateNode(vnode, container.firstChild as Node, {\n handleMismatch,\n recoverMismatch,\n })\n}\n\ninterface HydrateContext {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleMismatch: (message: string, domNode: Node | null, vnode: any) => void\n recoverMismatch: boolean\n}\n\nfunction hydrateNode(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vnode: any,\n domNode: Node | null,\n ctx: HydrateContext\n): Node | null {\n if (vnode === null || vnode === undefined || vnode === false) {\n return domNode\n }\n\n if (!domNode) {\n ctx.handleMismatch('No DOM node found for vnode', domNode, vnode)\n return null\n }\n\n // Handle text/number primitives\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n if (domNode.nodeType === Node.TEXT_NODE) {\n const text = String(vnode)\n if (domNode.textContent !== text) {\n ctx.handleMismatch(\n `Text mismatch: \"${domNode.textContent}\" vs \"${text}\"`,\n domNode,\n vnode\n )\n domNode.textContent = text\n }\n return domNode.nextSibling\n } else {\n ctx.handleMismatch(\n `Expected text node, got ${domNode.nodeType}`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n }\n\n // Handle signals - create reactive binding\n if (isSignal(vnode)) {\n if (domNode.nodeType === Node.TEXT_NODE) {\n effect(() => {\n domNode.textContent = String(vnode.value)\n })\n return domNode.nextSibling\n }\n }\n\n // Handle computed values\n if (typeof vnode === 'function') {\n // Create reactive binding for computed/derived values\n effect(() => {\n const value = vnode()\n if (domNode.nodeType === Node.TEXT_NODE) {\n domNode.textContent = String(value)\n }\n })\n return domNode.nextSibling\n }\n\n // Handle function components\n if (typeof vnode.type === 'function') {\n const result = vnode.type({ ...vnode.props, children: vnode.children })\n return hydrateNode(result, domNode, ctx)\n }\n\n // Handle fragments\n if (vnode.type === 'fragment' || vnode.type === null) {\n let currentNode: Node | null = domNode\n const children = vnode.children || []\n for (const child of children) {\n currentNode = hydrateNode(child, currentNode, ctx)\n }\n return currentNode\n }\n\n // Handle element vnodes\n if (typeof vnode.type === 'string') {\n if (domNode.nodeType !== Node.ELEMENT_NODE) {\n ctx.handleMismatch(\n `Expected element node, got ${domNode.nodeType}`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n\n const el = domNode as Element\n const tagName = el.tagName.toLowerCase()\n\n if (tagName !== vnode.type.toLowerCase()) {\n ctx.handleMismatch(\n `Tag mismatch: \"${tagName}\" vs \"${vnode.type}\"`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n\n // Hydrate props\n if (vnode.props) {\n hydrateProps(el, vnode.props, ctx)\n }\n\n // Hydrate children\n let childDom = el.firstChild\n if (vnode.children) {\n const children = Array.isArray(vnode.children)\n ? vnode.children.flat()\n : [vnode.children]\n for (const child of children) {\n if (child === null || child === undefined || child === false) continue\n childDom = hydrateNode(child, childDom, ctx) as ChildNode | null\n }\n }\n\n return el.nextSibling\n }\n\n return domNode?.nextSibling || null\n}\n\n/**\n * Hydrate element props - attach events, set up reactive bindings\n */\nfunction hydrateProps(\n el: Element,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n props: Record<string, any>,\n ctx: HydrateContext\n): void {\n for (const key in props) {\n const value = props[key]\n\n if (key === 'children' || key === 'key' || key === 'ref') {\n // Handle ref callback\n if (key === 'ref' && typeof value === 'function') {\n value(el)\n }\n continue\n }\n\n // Event handlers\n if (key.startsWith('on')) {\n const eventName = key.slice(2).toLowerCase()\n el.addEventListener(eventName, value)\n continue\n }\n\n // Reactive props (signals)\n if (isSignal(value)) {\n const propName = key === 'className' ? 'class' : key\n effect(() => {\n if (propName === 'class') {\n el.setAttribute('class', String(value.value))\n } else if (propName === 'style' && typeof value.value === 'object') {\n Object.assign((el as HTMLElement).style, value.value)\n } else {\n // Handle SVG attributes\n const attrName = SVG_ATTR_MAP[propName] || propName\n\n if (propName in el && !(el instanceof SVGElement)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ; (el as any)[propName] = value.value\n } else {\n el.setAttribute(attrName, String(value.value))\n }\n }\n })\n continue\n }\n\n // Validate static props match (in development)\n if (typeof __DEV__ !== 'undefined' ? __DEV__ : false) {\n if (key === 'className' || key === 'class') {\n const domClass = el.getAttribute('class') || ''\n if (domClass !== value) {\n ctx.handleMismatch(\n `Class mismatch on <${el.tagName.toLowerCase()}>: \"${domClass}\" vs \"${value}\"`,\n el,\n props\n )\n }\n }\n }\n }\n}\n\n// Declare global __DEV__ for development mode detection\ndeclare global {\n const __DEV__: boolean | undefined\n}\n"]}
1
+ {"version":3,"sources":["../src/renderers/dom/hydrate.ts"],"names":["SVG_ATTR_MAP","hydrate","vnode","container","options","onMismatch","recoverMismatch","handleMismatch","message","domNode","vn","hydrateNode","ctx","text","isSignal","effect","value","result","currentNode","children","child","el","tagName","hydrateProps","childDom","props","key","eventName","propName","attrName","domClass"],"mappings":"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","file":"dom.mjs","sourcesContent":["import { effect, isSignal } from '../../core/signal'\n\n/**\n * SVG Attribute Case Mapping\n * React-like camelCase to SVG case-sensitive attributes\n */\nconst SVG_ATTR_MAP: Record<string, string> = {\n viewBox: 'viewBox',\n preserveAspectRatio: 'preserveAspectRatio',\n strokeWidth: 'stroke-width',\n strokeLinecap: 'stroke-linecap',\n strokeLinejoin: 'stroke-linejoin',\n strokeDasharray: 'stroke-dasharray',\n strokeDashoffset: 'stroke-dashoffset',\n fillOpacity: 'fill-opacity',\n strokeOpacity: 'stroke-opacity',\n stopColor: 'stop-color',\n stopOpacity: 'stop-opacity',\n clipPath: 'clip-path',\n markerEnd: 'marker-end',\n markerStart: 'marker-start',\n markerMid: 'marker-mid',\n}\n\n/**\n * Hydration options\n */\nexport interface HydrateOptions {\n /** Called when hydration encounters a mismatch */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onMismatch?: (message: string, domNode: Node | null, vnode: any) => void\n /** Whether to recover from mismatches by re-rendering */\n recoverMismatch?: boolean\n}\n\n/**\n * Hydrate server-rendered HTML with client-side interactivity\n *\n * This function walks the existing DOM tree and attaches event handlers,\n * sets up signal bindings, and validates that the DOM matches the expected vnode structure.\n *\n * @param vnode - Virtual node to hydrate against\n * @param container - Container element with server-rendered HTML\n * @param options - Hydration options\n *\n * @example\n * ```tsx\n * // Server rendered HTML in #app\n * hydrate(<App />, document.getElementById('app'));\n * ```\n */\nexport function hydrate(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vnode: any,\n container: Element,\n options: HydrateOptions = {}\n) {\n const { onMismatch, recoverMismatch = false } = options\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handleMismatch = (message: string, domNode: Node | null, vn: any) => {\n if (onMismatch) {\n onMismatch(message, domNode, vn)\n } else if (typeof __DEV__ !== 'undefined' ? __DEV__ : false) {\n console.warn(`[Flexium Hydration] ${message}`)\n }\n }\n\n hydrateNode(vnode, container.firstChild as Node, {\n handleMismatch,\n recoverMismatch,\n })\n}\n\ninterface HydrateContext {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleMismatch: (message: string, domNode: Node | null, vnode: any) => void\n recoverMismatch: boolean\n}\n\nfunction hydrateNode(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vnode: any,\n domNode: Node | null,\n ctx: HydrateContext\n): Node | null {\n if (vnode === null || vnode === undefined || vnode === false) {\n return domNode\n }\n\n if (!domNode) {\n ctx.handleMismatch('No DOM node found for vnode', domNode, vnode)\n return null\n }\n\n // Handle text/number primitives\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n if (domNode.nodeType === Node.TEXT_NODE) {\n const text = String(vnode)\n if (domNode.textContent !== text) {\n ctx.handleMismatch(\n `Text mismatch: \"${domNode.textContent}\" vs \"${text}\"`,\n domNode,\n vnode\n )\n domNode.textContent = text\n }\n return domNode.nextSibling\n } else {\n ctx.handleMismatch(\n `Expected text node, got ${domNode.nodeType}`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n }\n\n // Handle signals - create reactive binding\n if (isSignal(vnode)) {\n if (domNode.nodeType === Node.TEXT_NODE) {\n effect(() => {\n domNode.textContent = String(vnode.value)\n })\n return domNode.nextSibling\n }\n }\n\n // Handle computed values\n if (typeof vnode === 'function') {\n // Create reactive binding for computed/derived values\n effect(() => {\n const value = vnode()\n if (domNode.nodeType === Node.TEXT_NODE) {\n domNode.textContent = String(value)\n }\n })\n return domNode.nextSibling\n }\n\n // Handle function components\n if (typeof vnode.type === 'function') {\n const result = vnode.type({ ...vnode.props, children: vnode.children })\n return hydrateNode(result, domNode, ctx)\n }\n\n // Handle fragments\n if (vnode.type === 'fragment' || vnode.type === null) {\n let currentNode: Node | null = domNode\n const children = vnode.children || []\n for (const child of children) {\n currentNode = hydrateNode(child, currentNode, ctx)\n }\n return currentNode\n }\n\n // Handle element vnodes\n if (typeof vnode.type === 'string') {\n if (domNode.nodeType !== Node.ELEMENT_NODE) {\n ctx.handleMismatch(\n `Expected element node, got ${domNode.nodeType}`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n\n const el = domNode as Element\n const tagName = el.tagName.toLowerCase()\n\n if (tagName !== vnode.type.toLowerCase()) {\n ctx.handleMismatch(\n `Tag mismatch: \"${tagName}\" vs \"${vnode.type}\"`,\n domNode,\n vnode\n )\n return domNode.nextSibling\n }\n\n // Hydrate props\n if (vnode.props) {\n hydrateProps(el, vnode.props, ctx)\n }\n\n // Hydrate children\n let childDom = el.firstChild\n if (vnode.children) {\n const children = Array.isArray(vnode.children)\n ? vnode.children.flat()\n : [vnode.children]\n for (const child of children) {\n if (child === null || child === undefined || child === false) continue\n childDom = hydrateNode(child, childDom, ctx) as ChildNode | null\n }\n }\n\n return el.nextSibling\n }\n\n return domNode?.nextSibling || null\n}\n\n/**\n * Hydrate element props - attach events, set up reactive bindings\n */\nfunction hydrateProps(\n el: Element,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n props: Record<string, any>,\n ctx: HydrateContext\n): void {\n for (const key in props) {\n const value = props[key]\n\n if (key === 'children' || key === 'key' || key === 'ref') {\n // Handle ref callback\n if (key === 'ref' && typeof value === 'function') {\n value(el)\n }\n continue\n }\n\n // Event handlers\n if (key.startsWith('on')) {\n const eventName = key.slice(2).toLowerCase()\n el.addEventListener(eventName, value)\n continue\n }\n\n // Reactive props (signals)\n if (isSignal(value)) {\n const propName = key === 'className' ? 'class' : key\n effect(() => {\n if (propName === 'class') {\n el.setAttribute('class', String(value.value))\n } else if (propName === 'style' && typeof value.value === 'object') {\n Object.assign((el as HTMLElement).style, value.value)\n } else {\n // Handle SVG attributes\n const attrName = SVG_ATTR_MAP[propName] || propName\n\n if (propName in el && !(el instanceof SVGElement)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ; (el as any)[propName] = value.value\n } else {\n el.setAttribute(attrName, String(value.value))\n }\n }\n })\n continue\n }\n\n // Validate static props match (in development)\n if (typeof __DEV__ !== 'undefined' ? __DEV__ : false) {\n if (key === 'className' || key === 'class') {\n const domClass = el.getAttribute('class') || ''\n if (domClass !== value) {\n ctx.handleMismatch(\n `Class mismatch on <${el.tagName.toLowerCase()}>: \"${domClass}\" vs \"${value}\"`,\n el,\n props\n )\n }\n }\n }\n }\n}\n\n// Declare global __DEV__ for development mode detection\ndeclare global {\n const __DEV__: boolean | undefined\n}\n"]}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Creates a side effect that runs when dependencies change
3
+ *
4
+ * @param fn - Effect function, can return a cleanup function
5
+ * @param options - Optional error handler
6
+ * @returns Dispose function to stop the effect
7
+ *
8
+ * @example
9
+ * const count = signal(0);
10
+ * const dispose = effect(() => {
11
+ * console.log('Count:', count.value);
12
+ * return () => console.log('Cleanup');
13
+ * });
14
+ */
15
+ declare function effect(fn: () => void | (() => void), options?: {
16
+ onError?: (error: Error) => void;
17
+ name?: string;
18
+ }): () => void;
19
+
20
+ export { effect as e };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Creates a side effect that runs when dependencies change
3
+ *
4
+ * @param fn - Effect function, can return a cleanup function
5
+ * @param options - Optional error handler
6
+ * @returns Dispose function to stop the effect
7
+ *
8
+ * @example
9
+ * const count = signal(0);
10
+ * const dispose = effect(() => {
11
+ * console.log('Count:', count.value);
12
+ * return () => console.log('Cleanup');
13
+ * });
14
+ */
15
+ declare function effect(fn: () => void | (() => void), options?: {
16
+ onError?: (error: Error) => void;
17
+ name?: string;
18
+ }): () => void;
19
+
20
+ export { effect as e };