@fluixi/core 1.0.0-alpha.53
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/LICENSE +21 -0
- package/README.md +611 -0
- package/dist/cdn/core.global.js +3 -0
- package/dist/cli/generate.cjs +1814 -0
- package/dist/cli/generate.d.ts +7 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +2580 -0
- package/dist/cli/generate.mjs +1814 -0
- package/dist/cli/index.cjs +1814 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +2580 -0
- package/dist/cli/index.mjs +1814 -0
- package/dist/cli/run.cjs +2 -0
- package/dist/cli/run.d.ts +3 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +62 -0
- package/dist/cli/run.mjs +2 -0
- package/dist/fluixi.d.ts +5 -0
- package/dist/src/cdn/chunk-PFM5O5UE.mjs +1 -0
- package/dist/src/cdn/core.cjs +1 -0
- package/dist/src/cdn/core.d.ts +16 -0
- package/dist/src/cdn/core.d.ts.map +1 -0
- package/dist/src/cdn/core.js +15 -0
- package/dist/src/cdn/core.mjs +1 -0
- package/dist/src/cdn/router-next-WNWCFVC2.mjs +1 -0
- package/dist/src/index.cjs +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +26 -0
- package/dist/src/index.mjs +1 -0
- package/dist/src/jsx-dev-runtime.cjs +1 -0
- package/dist/src/jsx-dev-runtime.d.ts +2 -0
- package/dist/src/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/src/jsx-dev-runtime.js +1 -0
- package/dist/src/jsx-dev-runtime.mjs +1 -0
- package/dist/src/jsx-runtime.cjs +1 -0
- package/dist/src/jsx-runtime.d.ts +7 -0
- package/dist/src/jsx-runtime.d.ts.map +1 -0
- package/dist/src/jsx-runtime.js +17 -0
- package/dist/src/jsx-runtime.mjs +1 -0
- package/dist/src/lib/client/chunk-D3VTWVNJ.mjs +1 -0
- package/dist/src/lib/client/index.cjs +1 -0
- package/dist/src/lib/client/index.d.ts +54 -0
- package/dist/src/lib/client/index.d.ts.map +1 -0
- package/dist/src/lib/client/index.js +142 -0
- package/dist/src/lib/client/index.mjs +1 -0
- package/dist/src/lib/client/router-next-UYIYMRJL.mjs +1 -0
- package/dist/src/lib/context/context.cjs +1 -0
- package/dist/src/lib/context/context.d.ts +337 -0
- package/dist/src/lib/context/context.d.ts.map +1 -0
- package/dist/src/lib/context/context.js +462 -0
- package/dist/src/lib/context/context.mjs +1 -0
- package/dist/src/lib/context/index.cjs +1 -0
- package/dist/src/lib/context/index.d.ts +3 -0
- package/dist/src/lib/context/index.d.ts.map +1 -0
- package/dist/src/lib/context/index.js +5 -0
- package/dist/src/lib/context/index.mjs +1 -0
- package/dist/src/lib/control-flow.cjs +1 -0
- package/dist/src/lib/control-flow.d.ts +4 -0
- package/dist/src/lib/control-flow.d.ts.map +1 -0
- package/dist/src/lib/control-flow.js +1 -0
- package/dist/src/lib/control-flow.mjs +1 -0
- package/dist/src/lib/core.cjs +1 -0
- package/dist/src/lib/core.d.ts +90 -0
- package/dist/src/lib/core.d.ts.map +1 -0
- package/dist/src/lib/core.js +181 -0
- package/dist/src/lib/core.mjs +1 -0
- package/dist/src/lib/directives/lit.cjs +1 -0
- package/dist/src/lib/directives/lit.d.ts +2 -0
- package/dist/src/lib/directives/lit.d.ts.map +1 -0
- package/dist/src/lib/directives/lit.js +31 -0
- package/dist/src/lib/directives/lit.mjs +0 -0
- package/dist/src/lib/env/index.cjs +1 -0
- package/dist/src/lib/env/index.d.ts +39 -0
- package/dist/src/lib/env/index.d.ts.map +1 -0
- package/dist/src/lib/env/index.js +50 -0
- package/dist/src/lib/env/index.mjs +1 -0
- package/dist/src/lib/i18n/index.cjs +1 -0
- package/dist/src/lib/i18n/index.d.ts +79 -0
- package/dist/src/lib/i18n/index.d.ts.map +1 -0
- package/dist/src/lib/i18n/index.js +127 -0
- package/dist/src/lib/i18n/index.mjs +1 -0
- package/dist/src/lib/index.cjs +1 -0
- package/dist/src/lib/index.d.ts +83 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +147 -0
- package/dist/src/lib/index.mjs +1 -0
- package/dist/src/lib/isomorphic.cjs +1 -0
- package/dist/src/lib/isomorphic.d.ts +69 -0
- package/dist/src/lib/isomorphic.d.ts.map +1 -0
- package/dist/src/lib/isomorphic.js +92 -0
- package/dist/src/lib/isomorphic.mjs +1 -0
- package/dist/src/lib/jsx-runtime/index.cjs +1 -0
- package/dist/src/lib/jsx-runtime/index.d.ts +13 -0
- package/dist/src/lib/jsx-runtime/index.d.ts.map +1 -0
- package/dist/src/lib/jsx-runtime/index.js +23 -0
- package/dist/src/lib/jsx-runtime/index.mjs +1 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts +2 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.js +1 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +13 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts +21 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts.map +1 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.js +102 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +13 -0
- package/dist/src/lib/plugins/index.cjs +13 -0
- package/dist/src/lib/plugins/index.d.ts +4 -0
- package/dist/src/lib/plugins/index.d.ts.map +1 -0
- package/dist/src/lib/plugins/index.js +3 -0
- package/dist/src/lib/plugins/index.mjs +13 -0
- package/dist/src/lib/plugins/route-codegen.cjs +8 -0
- package/dist/src/lib/plugins/route-codegen.d.ts +13 -0
- package/dist/src/lib/plugins/route-codegen.d.ts.map +1 -0
- package/dist/src/lib/plugins/route-codegen.js +81 -0
- package/dist/src/lib/plugins/route-codegen.mjs +8 -0
- package/dist/src/lib/plugins/route-scanner.cjs +1 -0
- package/dist/src/lib/plugins/route-scanner.d.ts +39 -0
- package/dist/src/lib/plugins/route-scanner.d.ts.map +1 -0
- package/dist/src/lib/plugins/route-scanner.js +216 -0
- package/dist/src/lib/plugins/route-scanner.mjs +1 -0
- package/dist/src/lib/plugins/vite.cjs +1 -0
- package/dist/src/lib/plugins/vite.d.ts +3 -0
- package/dist/src/lib/plugins/vite.d.ts.map +1 -0
- package/dist/src/lib/plugins/vite.js +1 -0
- package/dist/src/lib/plugins/vite.mjs +1 -0
- package/dist/src/lib/render/component.cjs +1 -0
- package/dist/src/lib/render/component.d.ts +328 -0
- package/dist/src/lib/render/component.d.ts.map +1 -0
- package/dist/src/lib/render/component.js +520 -0
- package/dist/src/lib/render/component.mjs +1 -0
- package/dist/src/lib/render/index.cjs +1 -0
- package/dist/src/lib/render/index.d.ts +113 -0
- package/dist/src/lib/render/index.d.ts.map +1 -0
- package/dist/src/lib/render/index.js +201 -0
- package/dist/src/lib/render/index.mjs +1 -0
- package/dist/src/lib/render/lazy.cjs +1 -0
- package/dist/src/lib/render/lazy.d.ts +28 -0
- package/dist/src/lib/render/lazy.d.ts.map +1 -0
- package/dist/src/lib/render/lazy.js +62 -0
- package/dist/src/lib/render/lazy.mjs +1 -0
- package/dist/src/lib/render/suspense.cjs +1 -0
- package/dist/src/lib/render/suspense.d.ts +25 -0
- package/dist/src/lib/render/suspense.d.ts.map +1 -0
- package/dist/src/lib/render/suspense.js +139 -0
- package/dist/src/lib/render/suspense.mjs +1 -0
- package/dist/src/lib/router-next/data.cjs +1 -0
- package/dist/src/lib/router-next/data.d.ts +101 -0
- package/dist/src/lib/router-next/data.d.ts.map +1 -0
- package/dist/src/lib/router-next/data.js +179 -0
- package/dist/src/lib/router-next/data.mjs +1 -0
- package/dist/src/lib/router-next/index.cjs +1 -0
- package/dist/src/lib/router-next/index.d.ts +156 -0
- package/dist/src/lib/router-next/index.d.ts.map +1 -0
- package/dist/src/lib/router-next/index.js +464 -0
- package/dist/src/lib/router-next/index.mjs +1 -0
- package/dist/src/lib/server/hydration.cjs +1 -0
- package/dist/src/lib/server/hydration.d.ts +238 -0
- package/dist/src/lib/server/hydration.d.ts.map +1 -0
- package/dist/src/lib/server/hydration.js +384 -0
- package/dist/src/lib/server/hydration.mjs +1 -0
- package/dist/src/lib/server/index.cjs +16 -0
- package/dist/src/lib/server/index.d.ts +91 -0
- package/dist/src/lib/server/index.d.ts.map +1 -0
- package/dist/src/lib/server/index.js +141 -0
- package/dist/src/lib/server/index.mjs +16 -0
- package/dist/src/lib/server/reactive.cjs +1 -0
- package/dist/src/lib/server/reactive.d.ts +298 -0
- package/dist/src/lib/server/reactive.d.ts.map +1 -0
- package/dist/src/lib/server/reactive.js +472 -0
- package/dist/src/lib/server/reactive.mjs +1 -0
- package/dist/src/lib/theme/index.cjs +1 -0
- package/dist/src/lib/theme/index.d.ts +51 -0
- package/dist/src/lib/theme/index.d.ts.map +1 -0
- package/dist/src/lib/theme/index.js +79 -0
- package/dist/src/lib/theme/index.mjs +1 -0
- package/dist/src/lib/utils/index.cjs +1 -0
- package/dist/src/lib/utils/index.d.ts +379 -0
- package/dist/src/lib/utils/index.d.ts.map +1 -0
- package/dist/src/lib/utils/index.js +527 -0
- package/dist/src/lib/utils/index.mjs +1 -0
- package/dist/src/rx.cjs +1 -0
- package/dist/src/rx.d.ts +2 -0
- package/dist/src/rx.d.ts.map +1 -0
- package/dist/src/rx.js +101 -0
- package/dist/src/rx.mjs +0 -0
- package/dist/src/server.cjs +16 -0
- package/dist/src/server.d.ts +64 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +63 -0
- package/dist/src/server.mjs +16 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +128 -0
- package/src/index.ts +31 -0
- package/types/fluixi.d.ts +5 -0
- package/types/vinxi.d.ts +50 -0
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component creation for Fluixi. Component-creation logic only — context lives in
|
|
3
|
+
* the reactive system, rendering in render/index.ts, and SSR in server/.
|
|
4
|
+
*/
|
|
5
|
+
import { registerCreateComponent, asComponent, } from '@fluixi/dom';
|
|
6
|
+
import { untrack, onCleanup, getOwner, createEffect, createMemo, createSignal, isSignal, batch, runWithOwner, } from '@fluixi/reactive/signal';
|
|
7
|
+
const sharedConfig = {
|
|
8
|
+
context: null,
|
|
9
|
+
owner: null,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Get shared reactive config
|
|
13
|
+
* Used for maintaining reactive context across components
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export function getSharedConfig() {
|
|
17
|
+
return sharedConfig;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Set current owner in shared config
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export function setOwner(owner) {
|
|
24
|
+
sharedConfig.owner = owner;
|
|
25
|
+
sharedConfig.context = owner;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get current owner from shared config
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export function getContextOwner() {
|
|
32
|
+
return sharedConfig.context || sharedConfig.owner;
|
|
33
|
+
}
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// GLOBAL STATE
|
|
36
|
+
// ============================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Development mode flag
|
|
39
|
+
*/
|
|
40
|
+
export const DEV = typeof process !== 'undefined' && process.env?.NODE_ENV === 'development';
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// OWNER-BASED LIFECYCLE COORDINATION
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Every component has a reactive Owner (from createRoot).
|
|
45
|
+
// onMount and useEffect attach callbacks to the Owner via a Symbol-keyed
|
|
46
|
+
// property. A single queueMicrotask per Owner flushes them in order:
|
|
47
|
+
// 1. All onMount callbacks run first
|
|
48
|
+
// 2. Then all useEffect callbacks are created as reactive effects
|
|
49
|
+
// This works regardless of whether the component goes through $component,
|
|
50
|
+
// the JSX runtime, or is called directly — as long as there's an Owner.
|
|
51
|
+
const _LIFECYCLE = Symbol.for('fluixi-lifecycle');
|
|
52
|
+
/**
|
|
53
|
+
* Get or create a lifecycle bucket on the current Owner.
|
|
54
|
+
* Returns null if there is no reactive Owner.
|
|
55
|
+
*/
|
|
56
|
+
function getOwnerLifecycle() {
|
|
57
|
+
const owner = getOwner();
|
|
58
|
+
if (!owner)
|
|
59
|
+
return null;
|
|
60
|
+
if (!owner[_LIFECYCLE]) {
|
|
61
|
+
const lc = { mounts: [], effects: [], scheduled: false };
|
|
62
|
+
owner[_LIFECYCLE] = lc;
|
|
63
|
+
}
|
|
64
|
+
return owner[_LIFECYCLE];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Schedule a microtask to flush the lifecycle for the current Owner.
|
|
68
|
+
* Only schedules once per Owner — subsequent calls are no-ops.
|
|
69
|
+
*/
|
|
70
|
+
function scheduleLifecycleFlush(lc) {
|
|
71
|
+
if (lc.scheduled)
|
|
72
|
+
return;
|
|
73
|
+
lc.scheduled = true;
|
|
74
|
+
// Capture the owner now; by microtask time it will have been restored.
|
|
75
|
+
const owner = getOwner();
|
|
76
|
+
queueMicrotask(() => {
|
|
77
|
+
runWithOwner(owner, () => {
|
|
78
|
+
// 1. Run ALL onMount callbacks first
|
|
79
|
+
for (const cb of lc.mounts) {
|
|
80
|
+
try {
|
|
81
|
+
const cleanup = cb();
|
|
82
|
+
if (typeof cleanup === 'function') {
|
|
83
|
+
onCleanup(cleanup);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (e) {
|
|
87
|
+
console.error('Error in onMount callback:', e);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// 2. THEN create effects for useEffect callbacks
|
|
91
|
+
for (const cb of lc.effects) {
|
|
92
|
+
let cleanup;
|
|
93
|
+
createEffect(() => {
|
|
94
|
+
if (cleanup)
|
|
95
|
+
cleanup();
|
|
96
|
+
cleanup = cb();
|
|
97
|
+
});
|
|
98
|
+
onCleanup(() => {
|
|
99
|
+
if (cleanup)
|
|
100
|
+
cleanup();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// Clear
|
|
104
|
+
lc.mounts = [];
|
|
105
|
+
lc.effects = [];
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// Give the dom runtime our createComponent. It gets everything else (effects,
|
|
110
|
+
// memos, …) from @fluixi/reactive directly.
|
|
111
|
+
export function ensureIntegration(from) {
|
|
112
|
+
registerCreateComponent(createComponent);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Create and execute a component once. Opens an Owner, runs the component untracked,
|
|
116
|
+
* captures its output, keeps children lazy, propagates context (via sharedConfig), and
|
|
117
|
+
* attaches cleanup. Components execute once and never re-execute.
|
|
118
|
+
*
|
|
119
|
+
* @template P - Props type
|
|
120
|
+
* @param {Component<P>} Comp - Component function
|
|
121
|
+
* @param {P} props - Component props
|
|
122
|
+
* @returns {any} Component output
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* const MyComponent = (props: { name: string }) => {
|
|
127
|
+
* return html`<div>Hello ${props.name}</div>`;
|
|
128
|
+
* };
|
|
129
|
+
*
|
|
130
|
+
* const result = createComponent(MyComponent, { name: 'World' });
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
// export function $component<T, U = any>(value: T, props?: U) {
|
|
134
|
+
// const component = () => (typeof value === 'function' && props) ?(value as any)(props) : value;
|
|
135
|
+
// Object.defineProperty(component, '__fluixi', {
|
|
136
|
+
// enumerable: true,
|
|
137
|
+
// configurable: true,
|
|
138
|
+
// value: true,
|
|
139
|
+
// });
|
|
140
|
+
// // (component as any).$COMPONENT = true;
|
|
141
|
+
// return asComponent(component) as C<T, U>;
|
|
142
|
+
// }
|
|
143
|
+
//
|
|
144
|
+
export function createComponent(Comp, props) {
|
|
145
|
+
return $component(Comp, props);
|
|
146
|
+
// const c = $component(Comp, props)
|
|
147
|
+
// // return c() as any
|
|
148
|
+
// return c as any
|
|
149
|
+
}
|
|
150
|
+
const cached = new WeakMap();
|
|
151
|
+
export function $component(value, props) {
|
|
152
|
+
// if(isComponent(value) || isRoutes(value) || isRouter(value)) {
|
|
153
|
+
// // if(!cached.has(value)){
|
|
154
|
+
// // cached.set(value, ()=>untrack(()=>value(props)))
|
|
155
|
+
// // }else{
|
|
156
|
+
// // console.log('skipp track', value)
|
|
157
|
+
// // }
|
|
158
|
+
// // return cached.get(value)()
|
|
159
|
+
// return untrack(() => value(props))
|
|
160
|
+
// }
|
|
161
|
+
const component = (typeof value === 'function')
|
|
162
|
+
? untrack(() => value(props))
|
|
163
|
+
: value;
|
|
164
|
+
// Only stamp $name and $COMPONENT on functions/objects — primitives (strings, numbers)
|
|
165
|
+
// cannot have properties added in strict mode and would throw TypeError.
|
|
166
|
+
// Also skip stamping reactive values (signals/memos) with $COMPONENT so the DOM
|
|
167
|
+
// runtime doesn't misidentify them as static component thunks and cache them.
|
|
168
|
+
if (component != null && (typeof component === 'function' || typeof component === 'object') && !isSignal(component)) {
|
|
169
|
+
try {
|
|
170
|
+
component['$name'] = value.name;
|
|
171
|
+
}
|
|
172
|
+
catch { }
|
|
173
|
+
// Always mark with asComponent so isComponent() works reliably in both dev and
|
|
174
|
+
// production browser environments.
|
|
175
|
+
return asComponent(component);
|
|
176
|
+
}
|
|
177
|
+
return component;
|
|
178
|
+
}
|
|
179
|
+
// ============================================================================
|
|
180
|
+
// LIFECYCLE HOOKS
|
|
181
|
+
// ============================================================================
|
|
182
|
+
/**
|
|
183
|
+
* Register a callback to run when component mounts
|
|
184
|
+
*
|
|
185
|
+
* SolidJS-aligned: uses createEffect to schedule the callback.
|
|
186
|
+
* The effect runs once after the reactive graph is established,
|
|
187
|
+
* tied to the current Owner for automatic cleanup.
|
|
188
|
+
*
|
|
189
|
+
* @param {LifecycleCallback} fn - Mount callback
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const MyComponent = () => {
|
|
194
|
+
* onMount(() => {
|
|
195
|
+
* console.log('Component mounted');
|
|
196
|
+
* return () => console.log('Cleanup');
|
|
197
|
+
* });
|
|
198
|
+
*
|
|
199
|
+
* return html`<div>Content</div>`;
|
|
200
|
+
* };
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
export function onMount(fn, reactive = true) {
|
|
204
|
+
const lc = getOwnerLifecycle();
|
|
205
|
+
if (lc) {
|
|
206
|
+
if (!reactive) {
|
|
207
|
+
if (!lc.scheduled) {
|
|
208
|
+
fn();
|
|
209
|
+
}
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
// Attach to Owner — will run BEFORE useEffect callbacks in the flush.
|
|
213
|
+
lc.mounts.push(fn);
|
|
214
|
+
scheduleLifecycleFlush(lc);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
if (!reactive) {
|
|
218
|
+
fn();
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
// No Owner (rare). Fall back to SolidJS pattern.
|
|
222
|
+
createEffect(() => {
|
|
223
|
+
const cleanup = untrack(fn);
|
|
224
|
+
if (typeof cleanup === 'function') {
|
|
225
|
+
onCleanup(cleanup);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Register a callback to run when component unmounts
|
|
232
|
+
*
|
|
233
|
+
* SolidJS-aligned: directly delegates to onCleanup which registers
|
|
234
|
+
* with the current reactive Owner for automatic disposal.
|
|
235
|
+
*
|
|
236
|
+
* @param {() => void} fn - Unmount callback
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* const MyComponent = () => {
|
|
241
|
+
* onUnmount(() => {
|
|
242
|
+
* console.log('Component is unmounting');
|
|
243
|
+
* });
|
|
244
|
+
*
|
|
245
|
+
* return html`<div>Content</div>`;
|
|
246
|
+
* };
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
export function onUnmount(fn) {
|
|
250
|
+
onCleanup(fn);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Register a cleanup function
|
|
254
|
+
*
|
|
255
|
+
* Section 1: Component constructs reactive graph including cleanup
|
|
256
|
+
*
|
|
257
|
+
* @param {() => void} fn - Cleanup function
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* const MyComponent = () => {
|
|
262
|
+
* const timer = setInterval(() => console.log('tick'), 1000);
|
|
263
|
+
*
|
|
264
|
+
* onCleanup(() => clearInterval(timer));
|
|
265
|
+
*
|
|
266
|
+
* return html`<div>Timer running</div>`;
|
|
267
|
+
* };
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
export { onCleanup };
|
|
271
|
+
// ============================================================================
|
|
272
|
+
// HOOKS
|
|
273
|
+
// ============================================================================
|
|
274
|
+
/**
|
|
275
|
+
* Create a reactive effect
|
|
276
|
+
*
|
|
277
|
+
* Effects run when their dependencies change
|
|
278
|
+
* On server, effects run once
|
|
279
|
+
*
|
|
280
|
+
* @param {(v?: any) => any} fn - Effect function
|
|
281
|
+
*
|
|
282
|
+
* @example
|
|
283
|
+
* ```typescript
|
|
284
|
+
* const MyComponent = () => {
|
|
285
|
+
* const [count, setCount] = createSignal(0);
|
|
286
|
+
*
|
|
287
|
+
* useEffect(() => {
|
|
288
|
+
* console.log('Count changed:', count());
|
|
289
|
+
* });
|
|
290
|
+
*
|
|
291
|
+
* return html`<button @click=${() => setCount(count() + 1)}>Click</button>`;
|
|
292
|
+
* };
|
|
293
|
+
* ```
|
|
294
|
+
*/
|
|
295
|
+
export function useEffect(callback) {
|
|
296
|
+
const lc = getOwnerLifecycle();
|
|
297
|
+
if (lc) {
|
|
298
|
+
// Attach to the Owner — created as an effect after all onMount callbacks.
|
|
299
|
+
lc.effects.push(callback);
|
|
300
|
+
scheduleLifecycleFlush(lc);
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
// No Owner (rare). Create the effect immediately.
|
|
304
|
+
let cleanup;
|
|
305
|
+
createEffect(() => {
|
|
306
|
+
if (cleanup)
|
|
307
|
+
cleanup();
|
|
308
|
+
cleanup = callback();
|
|
309
|
+
});
|
|
310
|
+
onCleanup(() => {
|
|
311
|
+
if (cleanup)
|
|
312
|
+
cleanup();
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Create a memoized computed value
|
|
318
|
+
*
|
|
319
|
+
* @template T
|
|
320
|
+
* @param {() => T} fn - Computation function
|
|
321
|
+
* @returns {() => T} Memoized accessor
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```typescript
|
|
325
|
+
* const MyComponent = () => {
|
|
326
|
+
* const [count, setCount] = createSignal(0);
|
|
327
|
+
* const doubled = useMemo(() => count() * 2);
|
|
328
|
+
*
|
|
329
|
+
* return html`<div>Doubled: ${doubled()}</div>`;
|
|
330
|
+
* };
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
export function useMemo(fn) {
|
|
334
|
+
// createMemo is natively reactive and disposed automatically
|
|
335
|
+
// when its Owner is cleaned up. No lifecycle stack needed.
|
|
336
|
+
return createMemo(fn);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Create a ref object
|
|
340
|
+
*
|
|
341
|
+
* Refs persist across component re-renders (though components only run once)
|
|
342
|
+
* Useful for storing DOM references and mutable values
|
|
343
|
+
*
|
|
344
|
+
* @template T
|
|
345
|
+
* @param {T} initialValue - Initial value
|
|
346
|
+
* @returns {RefObject<T>} Ref object
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* const MyComponent = () => {
|
|
351
|
+
* const inputRef = useRef<HTMLInputElement>(null);
|
|
352
|
+
*
|
|
353
|
+
* onMount(() => {
|
|
354
|
+
* inputRef.current?.focus();
|
|
355
|
+
* });
|
|
356
|
+
*
|
|
357
|
+
* return html`<input ref=${inputRef} />`;
|
|
358
|
+
* };
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
export function useRef(initialValue) {
|
|
362
|
+
const ref = { current: initialValue };
|
|
363
|
+
// Register cleanup to clear ref
|
|
364
|
+
onCleanup(() => {
|
|
365
|
+
ref.current = null;
|
|
366
|
+
});
|
|
367
|
+
return ref;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Create a reducer for state management
|
|
371
|
+
*
|
|
372
|
+
* @template S - State type
|
|
373
|
+
* @template A - Action type
|
|
374
|
+
* @param {(state: S, action: A) => S} reducer - Reducer function
|
|
375
|
+
* @param {S} initialState - Initial state
|
|
376
|
+
* @returns {[() => S, (action: A) => void]} State accessor and dispatch function
|
|
377
|
+
*
|
|
378
|
+
* @example
|
|
379
|
+
* ```typescript
|
|
380
|
+
* type Action = { type: 'increment' } | { type: 'decrement' };
|
|
381
|
+
*
|
|
382
|
+
* const MyComponent = () => {
|
|
383
|
+
* const [state, dispatch] = useReducer(
|
|
384
|
+
* (state: number, action: Action) => {
|
|
385
|
+
* switch (action.type) {
|
|
386
|
+
* case 'increment': return state + 1;
|
|
387
|
+
* case 'decrement': return state - 1;
|
|
388
|
+
* }
|
|
389
|
+
* },
|
|
390
|
+
* 0
|
|
391
|
+
* );
|
|
392
|
+
*
|
|
393
|
+
* return html`
|
|
394
|
+
* <button @click=${() => dispatch({ type: 'increment' })}>
|
|
395
|
+
* Count: ${state()}
|
|
396
|
+
* </button>
|
|
397
|
+
* `;
|
|
398
|
+
* };
|
|
399
|
+
* ```
|
|
400
|
+
*/
|
|
401
|
+
export function useReducer(reducer, initialState) {
|
|
402
|
+
const [state, setState] = createSignal(initialState);
|
|
403
|
+
const dispatch = (action) => {
|
|
404
|
+
setState(reducer(state(), action));
|
|
405
|
+
};
|
|
406
|
+
return [state, dispatch];
|
|
407
|
+
}
|
|
408
|
+
export function useEventListener(target, event, handler, options) {
|
|
409
|
+
useEffect(() => {
|
|
410
|
+
// Resolve target from ref or direct value
|
|
411
|
+
const element = target && 'current' in target
|
|
412
|
+
? target.current
|
|
413
|
+
: target;
|
|
414
|
+
if (!element)
|
|
415
|
+
return;
|
|
416
|
+
// Attach event listener
|
|
417
|
+
element.addEventListener(event, handler, options);
|
|
418
|
+
// Return cleanup function
|
|
419
|
+
return () => {
|
|
420
|
+
element.removeEventListener(event, handler, options);
|
|
421
|
+
};
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Create a callback function (memoization optimization)
|
|
426
|
+
*
|
|
427
|
+
* In Fluixi, components only run once, so this is mostly for
|
|
428
|
+
* API compatibility and explicit intent
|
|
429
|
+
*
|
|
430
|
+
* @template T
|
|
431
|
+
* @param {T} callback - Callback function
|
|
432
|
+
* @returns {T} Callback function
|
|
433
|
+
*
|
|
434
|
+
* @example
|
|
435
|
+
* ```typescript
|
|
436
|
+
* const MyComponent = () => {
|
|
437
|
+
* const handleClick = useCallback(() => {
|
|
438
|
+
* console.log('Clicked');
|
|
439
|
+
* });
|
|
440
|
+
*
|
|
441
|
+
* return html`<button @click=${handleClick}>Click</button>`;
|
|
442
|
+
* };
|
|
443
|
+
* ```
|
|
444
|
+
*/
|
|
445
|
+
export function useCallback(callback) {
|
|
446
|
+
// Components execute once, so callback is already stable
|
|
447
|
+
// This is mainly for API compatibility with React-like patterns
|
|
448
|
+
return callback;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Batch update helper
|
|
452
|
+
* Re-exported for convenience
|
|
453
|
+
*/
|
|
454
|
+
export { batch };
|
|
455
|
+
/**
|
|
456
|
+
* Create a memo
|
|
457
|
+
* Re-exported for convenience
|
|
458
|
+
*/
|
|
459
|
+
export { createMemo };
|
|
460
|
+
/**
|
|
461
|
+
* Create an effect
|
|
462
|
+
* Re-exported for convenience
|
|
463
|
+
*/
|
|
464
|
+
export { createEffect };
|
|
465
|
+
/**
|
|
466
|
+
* Get current reactive owner
|
|
467
|
+
* Re-exported for convenience
|
|
468
|
+
*/
|
|
469
|
+
export { getOwner };
|
|
470
|
+
/**
|
|
471
|
+
* Run with specific owner
|
|
472
|
+
* Re-exported for convenience
|
|
473
|
+
*/
|
|
474
|
+
export { runWithOwner };
|
|
475
|
+
// ============================================================================
|
|
476
|
+
// HELPER FUNCTIONS (INTERNAL)
|
|
477
|
+
// ============================================================================
|
|
478
|
+
/**
|
|
479
|
+
* Helper to check if we're in a component context
|
|
480
|
+
* @internal
|
|
481
|
+
*/
|
|
482
|
+
export function hasLifecycleContext() {
|
|
483
|
+
return getOwner() !== null;
|
|
484
|
+
}
|
|
485
|
+
// ============================================================================
|
|
486
|
+
// DEV MODE UTILITIES
|
|
487
|
+
// ============================================================================
|
|
488
|
+
/**
|
|
489
|
+
* Check if in development mode
|
|
490
|
+
*
|
|
491
|
+
* @returns {boolean} True if in development mode
|
|
492
|
+
*
|
|
493
|
+
* @example
|
|
494
|
+
* ```typescript
|
|
495
|
+
* if (isDev()) {
|
|
496
|
+
* console.log('Running in development mode');
|
|
497
|
+
* }
|
|
498
|
+
* ```
|
|
499
|
+
*/
|
|
500
|
+
export function isDev() {
|
|
501
|
+
// return false
|
|
502
|
+
return DEV;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Development-only code execution
|
|
506
|
+
*
|
|
507
|
+
* @param {() => void} fn - Function to run in dev mode
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```typescript
|
|
511
|
+
* devOnly(() => {
|
|
512
|
+
* console.log('This only runs in development');
|
|
513
|
+
* });
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
516
|
+
export function devOnly(fn) {
|
|
517
|
+
if (DEV) {
|
|
518
|
+
fn();
|
|
519
|
+
}
|
|
520
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{registerCreateComponent as y,asComponent as x}from"@fluixi/dom";import{untrack as a,onCleanup as r,getOwner as f,createEffect as s,createMemo as m,createSignal as C,isSignal as T,batch as R,runWithOwner as E}from"@fluixi/reactive/signal";var c={context:null,owner:null};function W(){return c}function K(e){c.owner=e,c.context=e}function V(){return c.context||c.owner}var p=typeof process<"u"&&!1,u=Symbol.for("fluixi-lifecycle");function l(){let e=f();if(!e)return null;if(!e[u]){let t={mounts:[],effects:[],scheduled:!1};e[u]=t}return e[u]}function d(e){if(e.scheduled)return;e.scheduled=!0;let t=f();queueMicrotask(()=>{E(t,()=>{for(let n of e.mounts)try{let o=n();typeof o=="function"&&r(o)}catch(o){console.error("Error in onMount callback:",o)}for(let n of e.effects){let o;s(()=>{o&&o(),o=n()}),r(()=>{o&&o()})}e.mounts=[],e.effects=[]})})}function F(e){y(O)}function O(e,t){return w(e,t)}function w(e,t){let n=typeof e=="function"?a(()=>e(t)):e;if(n!=null&&(typeof n=="function"||typeof n=="object")&&!T(n)){try{n.$name=e.name}catch{}return x(n)}return n}function I(e,t=!0){let n=l();if(n){if(!t){n.scheduled||e();return}n.mounts.push(e),d(n)}else{if(!t){e();return}s(()=>{let o=a(e);typeof o=="function"&&r(o)})}}function N(e){r(e)}function h(e){let t=l();if(t)t.effects.push(e),d(t);else{let n;s(()=>{n&&n(),n=e()}),r(()=>{n&&n()})}}function $(e){return m(e)}function q(e){let t={current:e};return r(()=>{t.current=null}),t}function P(e,t){let[n,o]=C(t);return[n,v=>{o(e(n(),v))}]}function Y(e,t,n,o){h(()=>{let i=e&&"current"in e?e.current:e;if(i)return i.addEventListener(t,n,o),()=>{i.removeEventListener(t,n,o)}})}function z(e){return e}function B(){return f()!==null}function G(){return p}function H(e){p&&e()}export{w as $component,p as DEV,R as batch,O as createComponent,s as createEffect,m as createMemo,H as devOnly,F as ensureIntegration,V as getContextOwner,f as getOwner,W as getSharedConfig,B as hasLifecycleContext,G as isDev,r as onCleanup,I as onMount,N as onUnmount,E as runWithOwner,K as setOwner,z as useCallback,h as useEffect,Y as useEventListener,$ as useMemo,P as useReducer,q as useRef};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var X=Object.create;var b=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var Q=Object.getPrototypeOf,Z=Object.prototype.hasOwnProperty;var ee=(e,n)=>{for(var t in n)b(e,t,{get:n[t],enumerable:!0})},O=(e,n,t,o)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of G(n))!Z.call(e,s)&&s!==t&&b(e,s,{get:()=>n[s],enumerable:!(o=Y(n,s))||o.enumerable});return e};var ne=(e,n,t)=>(t=e!=null?X(Q(e)):{},O(n||!e||!e.__esModule?b(t,"default",{value:e,enumerable:!0}):t,e)),te=e=>O(b({},"__esModule",{value:!0}),e);var pe={};ee(pe,{$component:()=>L,DEV:()=>x,Suspense:()=>C,SuspenseList:()=>H,batch:()=>r.batch,cleanupDelegation:()=>fe,createComponent:()=>v,createEffect:()=>r.createEffect,createMemo:()=>r.createMemo,devOnly:()=>N,getOwner:()=>r.getOwner,getSharedConfig:()=>k,initDelegation:()=>ue,isDev:()=>U,isJSXElement:()=>V,isLitResult:()=>I,isNode:()=>W,isPromise:()=>E,isRenderable:()=>ae,lazy:()=>K,onCleanup:()=>r.onCleanup,onMount:()=>j,onUnmount:()=>F,portal:()=>ce,render:()=>J,runWithOwner:()=>r.runWithOwner,useCallback:()=>z,useEffect:()=>g,useEventListener:()=>_,useMemo:()=>M,useReducer:()=>$,useRef:()=>D});module.exports=te(pe);var q=require("@fluixi/reactive/signal"),d=require("@fluixi/dom");var h=require("@fluixi/dom"),r=require("@fluixi/reactive/signal"),oe={context:null,owner:null};function k(){return oe}var x=typeof process<"u"&&!1,w=Symbol.for("fluixi-lifecycle");function R(){let e=(0,r.getOwner)();if(!e)return null;if(!e[w]){let n={mounts:[],effects:[],scheduled:!1};e[w]=n}return e[w]}function P(e){if(e.scheduled)return;e.scheduled=!0;let n=(0,r.getOwner)();queueMicrotask(()=>{(0,r.runWithOwner)(n,()=>{for(let t of e.mounts)try{let o=t();typeof o=="function"&&(0,r.onCleanup)(o)}catch(o){console.error("Error in onMount callback:",o)}for(let t of e.effects){let o;(0,r.createEffect)(()=>{o&&o(),o=t()}),(0,r.onCleanup)(()=>{o&&o()})}e.mounts=[],e.effects=[]})})}function A(e){(0,h.registerCreateComponent)(v)}function v(e,n){return L(e,n)}function L(e,n){let t=typeof e=="function"?(0,r.untrack)(()=>e(n)):e;if(t!=null&&(typeof t=="function"||typeof t=="object")&&!(0,r.isSignal)(t)){try{t.$name=e.name}catch{}return(0,h.asComponent)(t)}return t}function j(e,n=!0){let t=R();if(t){if(!n){t.scheduled||e();return}t.mounts.push(e),P(t)}else{if(!n){e();return}(0,r.createEffect)(()=>{let o=(0,r.untrack)(e);typeof o=="function"&&(0,r.onCleanup)(o)})}}function F(e){(0,r.onCleanup)(e)}function g(e){let n=R();if(n)n.effects.push(e),P(n);else{let t;(0,r.createEffect)(()=>{t&&t(),t=e()}),(0,r.onCleanup)(()=>{t&&t()})}}function M(e){return(0,r.createMemo)(e)}function D(e){let n={current:e};return(0,r.onCleanup)(()=>{n.current=null}),n}function $(e,n){let[t,o]=(0,r.createSignal)(n);return[t,p=>{o(e(t(),p))}]}function _(e,n,t,o){g(()=>{let s=e&&"current"in e?e.current:e;if(s)return s.addEventListener(n,t,o),()=>{s.removeEventListener(n,t,o)}})}function z(e){return e}function U(){return x}function N(e){x&&e()}var i=require("@fluixi/reactive/signal"),l=require("@fluixi/dom");function W(e){return typeof window>"u"?!1:typeof Node=="function"&&e instanceof Node?!0:!!(e&&typeof e=="object"&&typeof e.nodeType=="number")}function I(e){return!e||typeof e!="object"?!1:!!(typeof e._$litType$<"u"||typeof e._$litDirective$<"u"||Array.isArray(e.strings)&&Array.isArray(e.values))}function E(e){return!!(e&&typeof e=="object"&&typeof e.then=="function"||e instanceof Promise)}function V(e){return!!(e&&typeof e=="object"&&"type"in e&&"props"in e)}var B=(0,i.createContext)();function C(e){return(0,l.createComponent)(re,e)}function re(e){let n=(0,i.createSuspenseBoundary)(),t=(0,i.useContext)(B),o=t?t.register(n.inFallback):void 0;function s(a){return a==null||typeof a=="boolean"?null:typeof a=="function"&&(0,l.isComponent)(a)&&!(0,i.isSignal)(a)?a():a}let p=(0,l.runWithoutHydration)(()=>s(e.fallback??null)),u=(0,i.provideSuspense)(n,()=>e.children);(0,i.provideSuspense)(n,()=>{(0,i.createRenderEffect)(()=>{let a=u;if(Array.isArray(a))for(let S of a)typeof S=="function"&&(0,i.isSignal)(S)&&S();else typeof a=="function"&&(0,i.isSignal)(a)&&a()})});let[f,c]=(0,i.createSignal)(void 0),m=E(u);return m&&(n.increment(),u.then(a=>{c(()=>a),n.decrement()},()=>n.decrement())),(0,i.createMemo)(()=>(o?o.showFallback():n.inFallback())?p:m?f():u)}function H(e){return(0,l.createComponent)(ie,e)}function ie(e){let{revealOrder:n="together",tail:t}=e,o=[];function s(){if(n==="together"){let u=o.every(f=>!f.inFallback());o.forEach(f=>{f.setShowContent(u),f.setShowFallback(!u)})}else{let u=n==="backwards"?[...o].reverse():o,f=!1;for(let c of u)f||c.inFallback()?(f=!0,c.setShowContent(!1),c.setShowFallback(t!=="hidden")):(c.setShowContent(!0),c.setShowFallback(!1))}}let p={register:u=>{let[f,c]=(0,i.createSignal)(!0),[m,a]=(0,i.createSignal)(!1);return o.push({inFallback:u,setShowContent:c,setShowFallback:a}),(0,i.createEffect)(()=>{u(),s()}),{showContent:f,showFallback:m}}};return B.Provider({value:p,children:e.children})}(0,l.asSuspense)(C);Object.defineProperty(C,"__suspense",{value:!0,enumerable:!0});var y=require("@fluixi/reactive/signal");function K(e,n){let t,o,s;function p(){return o||(o=e().then(f=>t=f.default)),o}n?.preload&&p();let u=(f=>{if(t){let c=t;return(0,y.untrack)(()=>c(f))}if(!s){let[c]=(0,y.createResource)(()=>p());if(s=c,c.error)throw c.error}return(0,y.createMemo)(()=>{let c=s();return c?(0,y.untrack)(()=>c(f)):void 0},void 0,{name:"lazy"})});return u.preload=()=>p().then(()=>{}),u.$lazy=!0,u.loader=e,u}typeof window<"u"&&import("lit").then(e=>(0,d.registerLitRender)(e.render));var T=typeof window>"u";function J(e,n,t={}){if(A("render"),(0,d.delegateEvents)(["click","input","change","submit"]),T)throw new Error("render() is for client-side only. Use renderToString() on server.");if(!n)throw new Error("Container element is required");let o;return(0,q.createRoot)(s=>{o=s;let p=typeof e=="function"?e():e;n.textContent="",n.setAttribute("fluixi-js","v1"),(0,d.insert)(n,()=>p)}),()=>{o&&(o(),o=void 0)}}function se(e){return e&&typeof e=="object"&&(e._$litType$!==void 0||e._$litDirective$!==void 0)}function ce(e,n,t={}){let o=document.createElement("div");o.setAttribute("data-portal","true"),n.appendChild(o);let s=J(e,o,t);return()=>{s(),n.contains(o)&&n.removeChild(o)}}function ae(e){return!!(e==null||typeof e=="function"||(0,d.isDOMNode)(e)||se(e)||Array.isArray(e)||typeof e=="string"||typeof e=="number"||typeof e=="boolean")}function ue(){T||(0,d.delegateEvents)(["click","input","change","submit"])}function fe(){}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Client-Side Rendering for Fluixi
|
|
3
|
+
* @module @fluixi/core/render
|
|
4
|
+
*
|
|
5
|
+
* Client-side rendering:
|
|
6
|
+
* - Real DOM
|
|
7
|
+
* - Fine-grained mutation
|
|
8
|
+
*
|
|
9
|
+
* Following SolidJS structure: render logic separated from component creation
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Render options
|
|
13
|
+
*/
|
|
14
|
+
export interface RenderOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Whether to hydrate existing content
|
|
17
|
+
*/
|
|
18
|
+
hydrate?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Marker for hydration boundaries
|
|
21
|
+
*/
|
|
22
|
+
marker?: Node;
|
|
23
|
+
/**
|
|
24
|
+
* Callback when disposed
|
|
25
|
+
*/
|
|
26
|
+
onDispose?: () => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Render a component into a DOM element
|
|
30
|
+
*
|
|
31
|
+
* Section 7 — CLIENT:
|
|
32
|
+
* - Real DOM (no Virtual DOM)
|
|
33
|
+
* - Fine-grained mutation (no reconciliation)
|
|
34
|
+
*
|
|
35
|
+
* Section 1: Component executes once during render
|
|
36
|
+
* Section 5: Creates reactive owner (root)
|
|
37
|
+
*
|
|
38
|
+
* @param {() => any} code - Component or function to render
|
|
39
|
+
* @param {HTMLElement} container - Target DOM element
|
|
40
|
+
* @param {RenderOptions} options - Render options
|
|
41
|
+
* @returns {() => void} Dispose function
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import { render } from '@fluixi/core';
|
|
46
|
+
* import { createSignal } from '@fluixi/reactive';
|
|
47
|
+
* import { html } from 'lit';
|
|
48
|
+
*
|
|
49
|
+
* const App = () => {
|
|
50
|
+
* const [count, setCount] = createSignal(0);
|
|
51
|
+
* return html`
|
|
52
|
+
* <button @click=${() => setCount(count() + 1)}>
|
|
53
|
+
* Count: ${count()}
|
|
54
|
+
* </button>
|
|
55
|
+
* `;
|
|
56
|
+
* };
|
|
57
|
+
*
|
|
58
|
+
* const dispose = render(App, document.getElementById('app'));
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function render(code: () => any, container: HTMLElement, options?: RenderOptions): () => void;
|
|
62
|
+
/**
|
|
63
|
+
* Render into a different part of the DOM tree
|
|
64
|
+
*
|
|
65
|
+
* @param {() => any} code - Component to render
|
|
66
|
+
* @param {HTMLElement} target - Target element (outside current tree)
|
|
67
|
+
* @param {RenderOptions} options - Render options
|
|
68
|
+
* @returns {() => void} Dispose function
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* import { portal } from '@fluixi/core';
|
|
73
|
+
*
|
|
74
|
+
* const Modal = () => {
|
|
75
|
+
* return portal(
|
|
76
|
+
* () => html`<div class="modal">Content</div>`,
|
|
77
|
+
* document.body
|
|
78
|
+
* );
|
|
79
|
+
* };
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function portal(code: () => any, target: HTMLElement, options?: RenderOptions): () => void;
|
|
83
|
+
/**
|
|
84
|
+
* Check if a value can be rendered
|
|
85
|
+
*
|
|
86
|
+
* @param {any} value - Value to check
|
|
87
|
+
* @returns {boolean} True if renderable
|
|
88
|
+
*/
|
|
89
|
+
export declare function isRenderable(value: any): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Initialize event delegation
|
|
92
|
+
* Should be called once when app starts
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* import { initDelegation } from '@fluixi/core';
|
|
97
|
+
*
|
|
98
|
+
* initDelegation();
|
|
99
|
+
* render(App, document.getElementById('app'));
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export declare function initDelegation(): void;
|
|
103
|
+
/**
|
|
104
|
+
* Cleanup event delegation
|
|
105
|
+
* Should be called when app unmounts
|
|
106
|
+
*/
|
|
107
|
+
export declare function cleanupDelegation(): void;
|
|
108
|
+
export { createComponent, onMount, onUnmount, useEffect, useRef, useReducer, useMemo, useEventListener, useCallback, onCleanup, batch, createMemo, createEffect, getOwner, runWithOwner, isDev, devOnly, DEV, getSharedConfig, $component, } from './component.js';
|
|
109
|
+
export { Suspense, SuspenseList, type SuspenseProps, type SuspenseListProps, isNode, isLitResult, isPromise, isJSXElement, } from './suspense.js';
|
|
110
|
+
export { lazy } from "./lazy.js";
|
|
111
|
+
export type { LazyOptions, LazyComponent } from "./lazy.js";
|
|
112
|
+
export type { Component, ComponentProps, LifecycleCallback, RefObject, } from './component.js';
|
|
113
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/render/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0BH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC;IAEd;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,GAAG,EACf,SAAS,EAAE,WAAW,EACtB,OAAO,GAAE,aAAkB,GAC1B,MAAM,IAAI,CA4CZ;AAmBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,GAAG,EACf,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,aAAkB,GAC1B,MAAM,IAAI,CAaZ;AAMD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAchD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAGrC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAOD,OAAO,EACL,eAAe,EACf,OAAO,EACP,SAAS,EACT,SAAS,EACT,MAAM,EACN,UAAU,EACV,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,KAAK,EACL,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,OAAO,EACP,GAAG,EACH,eAAe,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,QAAQ,EACR,YAAY,EAEZ,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEtB,MAAM,EACN,WAAW,EACX,SAAS,EACT,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,YAAY,EAAC,WAAW,EAAE,aAAa,EAAC,MAAM,WAAW,CAAA;AAEzD,YAAY,EACV,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,SAAS,GACV,MAAM,gBAAgB,CAAC"}
|