flexium 0.9.1 → 0.10.4
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.
- package/README.md +14 -0
- package/dist/{DrawText-CJikXQjL.d.cts → DrawText-ccZrs3Xs.d.cts} +1 -1
- package/dist/{DrawText-Bvzl40Vi.d.ts → DrawText-ngwNNh8O.d.ts} +1 -1
- package/dist/advanced.d.cts +1 -1
- package/dist/advanced.d.ts +1 -1
- package/dist/advanced.js +1 -1
- package/dist/advanced.js.map +1 -1
- package/dist/advanced.mjs +1 -1
- package/dist/advanced.mjs.map +1 -1
- package/dist/canvas.d.cts +4 -4
- package/dist/canvas.d.ts +4 -4
- package/dist/canvas.js +1 -1
- package/dist/canvas.mjs +1 -1
- package/dist/chunk-3AWR7IKE.js +2 -0
- package/dist/chunk-3AWR7IKE.js.map +1 -0
- package/dist/chunk-3BQXIHYI.mjs +3 -0
- package/dist/chunk-3BQXIHYI.mjs.map +1 -0
- package/dist/chunk-5236IK5I.js +2 -0
- package/dist/chunk-5236IK5I.js.map +1 -0
- package/dist/{chunk-JHJHIMWD.js → chunk-63AW5ZOC.js} +2 -2
- package/dist/{chunk-JHJHIMWD.js.map → chunk-63AW5ZOC.js.map} +1 -1
- package/dist/chunk-6K44QCMT.mjs +3 -0
- package/dist/chunk-6K44QCMT.mjs.map +1 -0
- package/dist/chunk-7Q4UE442.mjs +2 -0
- package/dist/chunk-7Q4UE442.mjs.map +1 -0
- package/dist/chunk-AJT35P3Z.js +3 -0
- package/dist/chunk-AJT35P3Z.js.map +1 -0
- package/dist/chunk-AYQMU7XC.js +3 -0
- package/dist/chunk-AYQMU7XC.js.map +1 -0
- package/dist/chunk-B7VP6HBY.mjs +2 -0
- package/dist/chunk-B7VP6HBY.mjs.map +1 -0
- package/dist/{chunk-R5CS7UZG.mjs → chunk-BYHIHYRR.mjs} +2 -2
- package/dist/{chunk-R5CS7UZG.mjs.map → chunk-BYHIHYRR.mjs.map} +1 -1
- package/dist/chunk-HLPVL6EK.mjs +2 -0
- package/dist/{chunk-RUXAK74B.mjs.map → chunk-HLPVL6EK.mjs.map} +1 -1
- package/dist/{chunk-HDCPA76O.mjs → chunk-KJPIJNFH.mjs} +2 -2
- package/dist/chunk-KJPIJNFH.mjs.map +1 -0
- package/dist/chunk-PVPY55Z7.mjs +2 -0
- package/dist/{chunk-TRIEKNVZ.mjs.map → chunk-PVPY55Z7.mjs.map} +1 -1
- package/dist/chunk-Q7WT5IIF.mjs +3 -0
- package/dist/chunk-Q7WT5IIF.mjs.map +1 -0
- package/dist/chunk-S3EDPCYT.js +3 -0
- package/dist/chunk-S3EDPCYT.js.map +1 -0
- package/dist/{chunk-L4C5UBOX.js → chunk-WOHSSPKD.js} +2 -2
- package/dist/chunk-WOHSSPKD.js.map +1 -0
- package/dist/{chunk-DFG62GKW.js → chunk-WXEHDEIH.js} +2 -2
- package/dist/{chunk-DFG62GKW.js.map → chunk-WXEHDEIH.js.map} +1 -1
- package/dist/{chunk-3P6DMEGB.js → chunk-YDZ37ZZ4.js} +2 -2
- package/dist/{chunk-3P6DMEGB.js.map → chunk-YDZ37ZZ4.js.map} +1 -1
- package/dist/{components-D4WeooPi.d.ts → components-B7KQ8C-i.d.ts} +2 -2
- package/dist/{components-DZy2r6m5.d.cts → components-CxnAnbpI.d.cts} +2 -2
- package/dist/core.d.cts +48 -136
- package/dist/core.d.ts +48 -136
- package/dist/core.js +1 -1
- package/dist/core.mjs +1 -1
- package/dist/dom.d.cts +2 -2
- package/dist/dom.d.ts +2 -2
- package/dist/dom.js +1 -1
- package/dist/dom.js.map +1 -1
- package/dist/dom.mjs +1 -1
- package/dist/dom.mjs.map +1 -1
- package/dist/{effect-BlnnM1t5.d.cts → effect-14CxUU8r.d.cts} +8 -4
- package/dist/{effect-BlnnM1t5.d.ts → effect-14CxUU8r.d.ts} +8 -4
- package/dist/effect-3LUCHSAZ.mjs +2 -0
- package/dist/effect-3LUCHSAZ.mjs.map +1 -0
- package/dist/effect-K45UU3N4.js +2 -0
- package/dist/effect-K45UU3N4.js.map +1 -0
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/interactive.d.cts +15 -10
- package/dist/interactive.d.ts +15 -10
- package/dist/interactive.js +1 -1
- package/dist/interactive.js.map +1 -1
- package/dist/interactive.mjs +1 -1
- package/dist/interactive.mjs.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/{portal-C3ESJhlv.d.ts → portal-CVqrpmHd.d.ts} +2 -2
- package/dist/{portal-CAEbiMUZ.d.cts → portal-NLlE-fNZ.d.cts} +2 -2
- package/dist/primitives/layout.js +1 -1
- package/dist/primitives/layout.mjs +1 -1
- package/dist/primitives/motion.js +1 -1
- package/dist/primitives/motion.mjs +1 -1
- package/dist/primitives/ui.d.cts +3 -3
- package/dist/primitives/ui.d.ts +3 -3
- package/dist/primitives/ui.js +1 -1
- package/dist/primitives/ui.js.map +1 -1
- package/dist/primitives/ui.mjs +1 -1
- package/dist/primitives/ui.mjs.map +1 -1
- package/dist/primitives.d.cts +4 -4
- package/dist/primitives.d.ts +4 -4
- package/dist/primitives.js +1 -1
- package/dist/primitives.js.map +1 -1
- package/dist/primitives.mjs +1 -1
- package/dist/primitives.mjs.map +1 -1
- package/dist/router.d.cts +3 -3
- package/dist/router.d.ts +3 -3
- package/dist/router.js +1 -1
- package/dist/router.mjs +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +1 -1
- package/dist/server.mjs.map +1 -1
- package/dist/signal-2QUI7H7B.js +2 -0
- package/dist/{signal-3YZHUCLL.js.map → signal-2QUI7H7B.js.map} +1 -1
- package/dist/signal-C6936A3J.d.cts +175 -0
- package/dist/signal-C6936A3J.d.ts +175 -0
- package/dist/signal-L3ZWGOVT.mjs +2 -0
- package/dist/{signal-F2HEYB6F.mjs.map → signal-L3ZWGOVT.mjs.map} +1 -1
- package/dist/test-exports.d.cts +6 -6
- package/dist/test-exports.d.ts +6 -6
- package/dist/test-exports.js +1 -1
- package/dist/test-exports.mjs +1 -1
- package/package.json +2 -1
- package/dist/chunk-2ZHUQBNI.mjs +0 -2
- package/dist/chunk-2ZHUQBNI.mjs.map +0 -1
- package/dist/chunk-HDCPA76O.mjs.map +0 -1
- package/dist/chunk-J4CK5NRW.mjs +0 -3
- package/dist/chunk-J4CK5NRW.mjs.map +0 -1
- package/dist/chunk-JEDCNAAI.mjs +0 -3
- package/dist/chunk-JEDCNAAI.mjs.map +0 -1
- package/dist/chunk-L4C5UBOX.js.map +0 -1
- package/dist/chunk-M4ANLZ6P.js +0 -3
- package/dist/chunk-M4ANLZ6P.js.map +0 -1
- package/dist/chunk-RDA77IE6.js +0 -2
- package/dist/chunk-RDA77IE6.js.map +0 -1
- package/dist/chunk-RUXAK74B.mjs +0 -2
- package/dist/chunk-TRIEKNVZ.mjs +0 -2
- package/dist/chunk-VIVO4FHN.js +0 -3
- package/dist/chunk-VIVO4FHN.js.map +0 -1
- package/dist/chunk-XLE6SMWX.mjs +0 -3
- package/dist/chunk-XLE6SMWX.mjs.map +0 -1
- package/dist/chunk-YGMMJWAA.js +0 -3
- package/dist/chunk-YGMMJWAA.js.map +0 -1
- package/dist/signal-3YZHUCLL.js +0 -2
- package/dist/signal-Dxh9PsKr.d.cts +0 -69
- package/dist/signal-Dxh9PsKr.d.ts +0 -69
- package/dist/signal-F2HEYB6F.mjs +0 -2
package/dist/core.d.ts
CHANGED
|
@@ -1,116 +1,54 @@
|
|
|
1
|
-
export { e as effect } from './effect-
|
|
1
|
+
export { e as effect } from './effect-14CxUU8r.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
interface AutoCleanupConfig {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
maxIdleTime: number;
|
|
6
|
+
checkInterval: number;
|
|
7
|
+
minAccessCount: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* ------------------------------------------------------------------
|
|
11
|
+
* Helper Functions
|
|
12
|
+
* ------------------------------------------------------------------
|
|
13
|
+
*/
|
|
4
14
|
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
15
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
16
|
+
* ------------------------------------------------------------------
|
|
17
|
+
* Main State API
|
|
18
|
+
* ------------------------------------------------------------------
|
|
10
19
|
*/
|
|
20
|
+
type StateAction<T> = (newValue: T | ((prev: T) => T)) => void;
|
|
11
21
|
type StateValue<T> = T & (() => T) & {
|
|
12
22
|
peek(): T;
|
|
13
23
|
};
|
|
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
24
|
type AsyncStatus = 'idle' | 'loading' | 'success' | 'error';
|
|
74
|
-
/** Options for state() */
|
|
75
25
|
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
26
|
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
27
|
params?: P;
|
|
94
28
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
29
|
+
declare function isStateValue(value: unknown): boolean;
|
|
30
|
+
declare function equals<T>(stateValue: StateValue<T>, value: T): boolean;
|
|
31
|
+
declare function isTruthy<T>(stateValue: StateValue<T>): boolean;
|
|
32
|
+
interface StateStats {
|
|
33
|
+
total: number;
|
|
34
|
+
byNamespace: Record<string, number>;
|
|
35
|
+
topNamespaces: Array<{
|
|
36
|
+
namespace: string;
|
|
37
|
+
count: number;
|
|
38
|
+
}>;
|
|
39
|
+
averageAccessCount: number;
|
|
40
|
+
}
|
|
41
|
+
interface NamespaceStats {
|
|
42
|
+
namespace: string;
|
|
43
|
+
count: number;
|
|
44
|
+
totalAccessCount: number;
|
|
45
|
+
averageAccessCount: number;
|
|
46
|
+
states: Array<{
|
|
47
|
+
key: string;
|
|
48
|
+
accessCount: number;
|
|
49
|
+
createdAt: number;
|
|
50
|
+
}>;
|
|
51
|
+
}
|
|
114
52
|
interface StateFunction {
|
|
115
53
|
<T>(initialValue: T, options?: StateOptions): [StateValue<T>, StateAction<T>];
|
|
116
54
|
<T, P>(computeFn: (params: P) => T, options: StateOptions<P> & {
|
|
@@ -121,48 +59,22 @@ interface StateFunction {
|
|
|
121
59
|
params: P;
|
|
122
60
|
}): [StateValue<T | undefined>, () => void, StateValue<AsyncStatus>, StateValue<unknown>];
|
|
123
61
|
<T>(fetcher: () => Promise<T>, options?: StateOptions): [StateValue<T | undefined>, () => void, StateValue<AsyncStatus>, StateValue<unknown>];
|
|
124
|
-
/** Delete a specific global state by key */
|
|
125
62
|
delete: (key: StateKey) => boolean;
|
|
126
|
-
/** Clear all global states */
|
|
127
63
|
clear: () => void;
|
|
128
|
-
|
|
64
|
+
clearByPrefix: (prefix: StateKey) => number;
|
|
129
65
|
has: (key: StateKey) => boolean;
|
|
130
|
-
/** Current number of global states */
|
|
131
66
|
readonly size: number;
|
|
67
|
+
getStats: () => StateStats;
|
|
68
|
+
getNamespaceStats: (prefix: StateKey) => NamespaceStats;
|
|
69
|
+
enableAutoCleanup: (config?: Partial<AutoCleanupConfig>) => void;
|
|
70
|
+
disableAutoCleanup: () => void;
|
|
71
|
+
readonly isAutoCleanupEnabled: boolean;
|
|
132
72
|
}
|
|
133
|
-
declare const
|
|
73
|
+
declare const state: StateFunction;
|
|
134
74
|
|
|
135
|
-
/**
|
|
136
|
-
* Ref object type for DOM element references
|
|
137
|
-
*/
|
|
138
75
|
interface RefObject<T> {
|
|
139
76
|
current: T | null;
|
|
140
77
|
}
|
|
141
|
-
|
|
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
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* ```tsx
|
|
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
|
-
* }
|
|
164
|
-
* ```
|
|
165
|
-
*/
|
|
166
|
-
declare function ref<T>(initialValue: T | null): RefObject<T>;
|
|
78
|
+
declare function ref<T>(initial: T | null): RefObject<T>;
|
|
167
79
|
|
|
168
|
-
export { type AsyncStatus, type RefObject, type StateAction, type StateKey, type StateOptions, type StateValue, equals, isStateValue, isTruthy, ref,
|
|
80
|
+
export { type AsyncStatus, type RefObject, type StateAction, type StateKey, type StateOptions, type StateValue, equals, isStateValue, isTruthy, ref, state };
|
package/dist/core.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var chunk3AWR7IKE_js=require('./chunk-3AWR7IKE.js');require('./chunk-5236IK5I.js');var chunkAJT35P3Z_js=require('./chunk-AJT35P3Z.js');Object.defineProperty(exports,"equals",{enumerable:true,get:function(){return chunk3AWR7IKE_js.f}});Object.defineProperty(exports,"isStateValue",{enumerable:true,get:function(){return chunk3AWR7IKE_js.d}});Object.defineProperty(exports,"isTruthy",{enumerable:true,get:function(){return chunk3AWR7IKE_js.g}});Object.defineProperty(exports,"ref",{enumerable:true,get:function(){return chunk3AWR7IKE_js.i}});Object.defineProperty(exports,"state",{enumerable:true,get:function(){return chunk3AWR7IKE_js.h}});Object.defineProperty(exports,"effect",{enumerable:true,get:function(){return chunkAJT35P3Z_js.k}});//# sourceMappingURL=core.js.map
|
|
2
2
|
//# sourceMappingURL=core.js.map
|
package/dist/core.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{f as equals,d as isStateValue,g as isTruthy,i as ref,h as state}from'./chunk-
|
|
1
|
+
export{f as equals,d as isStateValue,g as isTruthy,i as ref,h as state}from'./chunk-7Q4UE442.mjs';import'./chunk-B7VP6HBY.mjs';export{k as effect}from'./chunk-Q7WT5IIF.mjs';//# sourceMappingURL=core.mjs.map
|
|
2
2
|
//# sourceMappingURL=core.mjs.map
|
package/dist/dom.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-
|
|
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-NLlE-fNZ.cjs';
|
|
2
2
|
export { C as CommonProps, R as Renderer } from './renderer-DSLb-FGg.cjs';
|
|
3
|
-
import './signal-
|
|
3
|
+
import './signal-C6936A3J.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Hydration options
|
package/dist/dom.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-
|
|
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-CVqrpmHd.js';
|
|
2
2
|
export { C as CommonProps, R as Renderer } from './renderer-DSLb-FGg.js';
|
|
3
|
-
import './signal-
|
|
3
|
+
import './signal-C6936A3J.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Hydration options
|
package/dist/dom.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var chunkS3EDPCYT_js=require('./chunk-S3EDPCYT.js');require('./chunk-WXEHDEIH.js'),require('./chunk-3AWR7IKE.js');var chunkQ7IWDVJ4_js=require('./chunk-Q7IWDVJ4.js');require('./chunk-WQFQO5LK.js');var chunk5236IK5I_js=require('./chunk-5236IK5I.js'),chunkAJT35P3Z_js=require('./chunk-AJT35P3Z.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: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(chunk5236IK5I_js.f(t)&&e.nodeType===Node.TEXT_NODE)return chunkAJT35P3Z_js.k(()=>{e.textContent=String(t.value);}),e.nextSibling;if(typeof t=="function")return chunkAJT35P3Z_js.k(()=>{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&&b(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 b(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(chunk5236IK5I_js.f(n)){let i=r==="className"?"class":r;chunkAJT35P3Z_js.k(()=>{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=C[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 chunkS3EDPCYT_js.a}});Object.defineProperty(exports,"Portal",{enumerable:true,get:function(){return chunkS3EDPCYT_js.i}});Object.defineProperty(exports,"createReactiveRoot",{enumerable:true,get:function(){return chunkS3EDPCYT_js.f}});Object.defineProperty(exports,"createRoot",{enumerable:true,get:function(){return chunkS3EDPCYT_js.h}});Object.defineProperty(exports,"domRenderer",{enumerable:true,get:function(){return chunkS3EDPCYT_js.b}});Object.defineProperty(exports,"mountReactive",{enumerable:true,get:function(){return chunkS3EDPCYT_js.e}});Object.defineProperty(exports,"render",{enumerable:true,get:function(){return chunkS3EDPCYT_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 { isSignal } from '../../core/signal'\nimport { effect } from '../../core/effect'\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-
|
|
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-6K44QCMT.mjs';import'./chunk-HLPVL6EK.mjs';import'./chunk-7Q4UE442.mjs';export{b as Fragment,a as f}from'./chunk-WVEJT7HD.mjs';import'./chunk-KNF5ERPK.mjs';import {f}from'./chunk-B7VP6HBY.mjs';import {k}from'./chunk-Q7WT5IIF.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: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(f(t)&&e.nodeType===Node.TEXT_NODE)return k(()=>{e.textContent=String(t.value);}),e.nextSibling;if(typeof t=="function")return k(()=>{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&&b(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 b(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(f(n)){let i=r==="className"?"class":r;k(()=>{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=C[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);}}}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 { isSignal } from '../../core/signal'\nimport { effect } from '../../core/effect'\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"]}
|
|
@@ -6,11 +6,15 @@
|
|
|
6
6
|
* @returns Dispose function to stop the effect
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
|
-
*
|
|
10
|
-
* const
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const [count, setCount] = state(0);
|
|
11
|
+
*
|
|
12
|
+
* effect(() => {
|
|
13
|
+
* console.log(count());
|
|
13
14
|
* });
|
|
15
|
+
*
|
|
16
|
+
* setCount(1); // logs: 1
|
|
17
|
+
* ```
|
|
14
18
|
*/
|
|
15
19
|
declare function effect(fn: () => void | (() => void), options?: {
|
|
16
20
|
onError?: (error: Error) => void;
|
|
@@ -6,11 +6,15 @@
|
|
|
6
6
|
* @returns Dispose function to stop the effect
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
|
-
*
|
|
10
|
-
* const
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const [count, setCount] = state(0);
|
|
11
|
+
*
|
|
12
|
+
* effect(() => {
|
|
13
|
+
* console.log(count());
|
|
13
14
|
* });
|
|
15
|
+
*
|
|
16
|
+
* setCount(1); // logs: 1
|
|
17
|
+
* ```
|
|
14
18
|
*/
|
|
15
19
|
declare function effect(fn: () => void | (() => void), options?: {
|
|
16
20
|
onError?: (error: Error) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"effect-3LUCHSAZ.mjs"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var chunkAJT35P3Z_js=require('./chunk-AJT35P3Z.js');Object.defineProperty(exports,"EffectNode",{enumerable:true,get:function(){return chunkAJT35P3Z_js.j}});Object.defineProperty(exports,"effect",{enumerable:true,get:function(){return chunkAJT35P3Z_js.k}});//# sourceMappingURL=effect-K45UU3N4.js.map
|
|
2
|
+
//# sourceMappingURL=effect-K45UU3N4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"effect-K45UU3N4.js"}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var o="0.
|
|
1
|
+
'use strict';var o="0.10.4";exports.VERSION=o;//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["VERSION"],"mappings":"aAwBO,IAAMA,CAAAA,CAAU","file":"index.js","sourcesContent":["/**\n * Flexium - Next-generation UI/UX library\n *\n * Please use explicit imports from submodules:\n *\n * @example\n * ```tsx\n * // Core reactivity\n * import { state, effect } from 'flexium/core'\n *\n * // DOM rendering\n * import { render, createRoot, Portal } from 'flexium/dom'\n *\n * // Canvas rendering\n * import { Canvas, Rect, Circle } from 'flexium/canvas'\n *\n * // Cross-platform primitives\n * import { Row, Column, Text } from 'flexium/primitives'\n *\n * // Router\n * import { Router, Route, Link } from 'flexium/router'\n * ```\n */\n\nexport const VERSION = '0.
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["VERSION"],"mappings":"aAwBO,IAAMA,CAAAA,CAAU","file":"index.js","sourcesContent":["/**\n * Flexium - Next-generation UI/UX library\n *\n * Please use explicit imports from submodules:\n *\n * @example\n * ```tsx\n * // Core reactivity\n * import { state, effect } from 'flexium/core'\n *\n * // DOM rendering\n * import { render, createRoot, Portal } from 'flexium/dom'\n *\n * // Canvas rendering\n * import { Canvas, Rect, Circle } from 'flexium/canvas'\n *\n * // Cross-platform primitives\n * import { Row, Column, Text } from 'flexium/primitives'\n *\n * // Router\n * import { Router, Route, Link } from 'flexium/router'\n * ```\n */\n\nexport const VERSION = '0.10.4'\n\n// Intentionally empty - use explicit submodule imports\n// flexium/core, flexium/dom, flexium/canvas, flexium/primitives, flexium/router\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var o="0.
|
|
1
|
+
var o="0.10.4";export{o as VERSION};//# sourceMappingURL=index.mjs.map
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":["VERSION"],"mappings":"AAwBO,IAAMA,CAAAA,CAAU","file":"index.mjs","sourcesContent":["/**\n * Flexium - Next-generation UI/UX library\n *\n * Please use explicit imports from submodules:\n *\n * @example\n * ```tsx\n * // Core reactivity\n * import { state, effect } from 'flexium/core'\n *\n * // DOM rendering\n * import { render, createRoot, Portal } from 'flexium/dom'\n *\n * // Canvas rendering\n * import { Canvas, Rect, Circle } from 'flexium/canvas'\n *\n * // Cross-platform primitives\n * import { Row, Column, Text } from 'flexium/primitives'\n *\n * // Router\n * import { Router, Route, Link } from 'flexium/router'\n * ```\n */\n\nexport const VERSION = '0.
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["VERSION"],"mappings":"AAwBO,IAAMA,CAAAA,CAAU","file":"index.mjs","sourcesContent":["/**\n * Flexium - Next-generation UI/UX library\n *\n * Please use explicit imports from submodules:\n *\n * @example\n * ```tsx\n * // Core reactivity\n * import { state, effect } from 'flexium/core'\n *\n * // DOM rendering\n * import { render, createRoot, Portal } from 'flexium/dom'\n *\n * // Canvas rendering\n * import { Canvas, Rect, Circle } from 'flexium/canvas'\n *\n * // Cross-platform primitives\n * import { Row, Column, Text } from 'flexium/primitives'\n *\n * // Router\n * import { Router, Route, Link } from 'flexium/router'\n * ```\n */\n\nexport const VERSION = '0.10.4'\n\n// Intentionally empty - use explicit submodule imports\n// flexium/core, flexium/dom, flexium/canvas, flexium/primitives, flexium/router\n"]}
|
package/dist/interactive.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as
|
|
1
|
+
import { S as SignalNode } from './signal-C6936A3J.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Loop - Core animation/game loop implementation with delta time and fixed timestep
|
|
@@ -38,17 +38,22 @@ declare function createLoop(options?: LoopOptions): Loop;
|
|
|
38
38
|
interface KeyboardState {
|
|
39
39
|
/** Check if a key is currently pressed */
|
|
40
40
|
isPressed(key: string): boolean;
|
|
41
|
-
/** Check if a key was
|
|
41
|
+
/** Check if a key was pressed in the current frame */
|
|
42
42
|
isJustPressed(key: string): boolean;
|
|
43
|
-
/** Check if a key was
|
|
43
|
+
/** Check if a key was released in the current frame */
|
|
44
44
|
isJustReleased(key: string): boolean;
|
|
45
45
|
/** Get all currently pressed keys */
|
|
46
|
+
getPressed(): string[];
|
|
47
|
+
/** Get all currently pressed keys (alias) */
|
|
46
48
|
getPressedKeys(): string[];
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Reactive set of all currently pressed keys
|
|
51
|
+
* @deprecated Use isPressed() or getPressed() instead for better performance
|
|
52
|
+
*/
|
|
53
|
+
keys: SignalNode<Set<string>>;
|
|
54
|
+
/** Clear all state at end of frame */
|
|
50
55
|
clearFrameState(): void;
|
|
51
|
-
/**
|
|
56
|
+
/** Remove event listeners */
|
|
52
57
|
dispose(): void;
|
|
53
58
|
}
|
|
54
59
|
/**
|
|
@@ -111,9 +116,9 @@ interface Vec2 {
|
|
|
111
116
|
}
|
|
112
117
|
interface MouseState {
|
|
113
118
|
/** Current mouse position relative to target */
|
|
114
|
-
readonly position:
|
|
119
|
+
readonly position: SignalNode<Vec2>;
|
|
115
120
|
/** Mouse position delta since last frame */
|
|
116
|
-
readonly delta:
|
|
121
|
+
readonly delta: SignalNode<Vec2>;
|
|
117
122
|
/** Check if a mouse button is pressed (0=left, 1=middle, 2=right) */
|
|
118
123
|
isPressed(button: number): boolean;
|
|
119
124
|
/** Check if left mouse button is pressed */
|
|
@@ -123,7 +128,7 @@ interface MouseState {
|
|
|
123
128
|
/** Check if middle mouse button is pressed */
|
|
124
129
|
isMiddlePressed(): boolean;
|
|
125
130
|
/** Wheel delta (positive = scroll down) */
|
|
126
|
-
readonly wheelDelta:
|
|
131
|
+
readonly wheelDelta: SignalNode<number>;
|
|
127
132
|
/** Clear frame state (call at end of frame) */
|
|
128
133
|
clearFrameState(): void;
|
|
129
134
|
/** Cleanup event listeners */
|