@fluixi/core 1.0.0-alpha.100
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 +334 -0
- package/dist/cdn/core.global.js +2 -0
- package/dist/cli/generate.cjs +5639 -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 +5644 -0
- package/dist/cli/index.cjs +5639 -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 +5644 -0
- package/dist/cli/run.cjs +64 -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 +40 -0
- package/dist/fluixi.d.ts +5 -0
- package/dist/src/cdn/chunk-RKBFEFZP.mjs +987 -0
- package/dist/src/cdn/core.cjs +1592 -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 +714 -0
- package/dist/src/cdn/router-V2THK27H.mjs +74 -0
- package/dist/src/index.cjs +1711 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +11 -0
- package/dist/src/index.mjs +1833 -0
- package/dist/src/jsx-dev-runtime.cjs +26 -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 +24 -0
- package/dist/src/jsx-runtime.cjs +26 -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 +8 -0
- package/dist/src/jsx-runtime.mjs +24 -0
- package/dist/src/lib/client/chunk-FDOPDB6Z.mjs +53 -0
- package/dist/src/lib/client/index.cjs +1210 -0
- package/dist/src/lib/client/index.d.ts +51 -0
- package/dist/src/lib/client/index.d.ts.map +1 -0
- package/dist/src/lib/client/index.js +174 -0
- package/dist/src/lib/client/index.mjs +293 -0
- package/dist/src/lib/client/router-4PTBPZLQ.mjs +891 -0
- package/dist/src/lib/context/context.cjs +81 -0
- package/dist/src/lib/context/context.d.ts +73 -0
- package/dist/src/lib/context/context.d.ts.map +1 -0
- package/dist/src/lib/context/context.js +93 -0
- package/dist/src/lib/context/context.mjs +64 -0
- package/dist/src/lib/context/index.cjs +83 -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 +1 -0
- package/dist/src/lib/context/index.mjs +64 -0
- package/dist/src/lib/control-flow.cjs +35 -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 +25 -0
- package/dist/src/lib/core.cjs +1710 -0
- package/dist/src/lib/core.d.ts +91 -0
- package/dist/src/lib/core.d.ts.map +1 -0
- package/dist/src/lib/core.js +158 -0
- package/dist/src/lib/core.mjs +1833 -0
- package/dist/src/lib/env/index.cjs +44 -0
- package/dist/src/lib/env/index.d.ts +26 -0
- package/dist/src/lib/env/index.d.ts.map +1 -0
- package/dist/src/lib/env/index.js +31 -0
- package/dist/src/lib/env/index.mjs +23 -0
- package/dist/src/lib/i18n/index.cjs +123 -0
- package/dist/src/lib/i18n/index.d.ts +110 -0
- package/dist/src/lib/i18n/index.d.ts.map +1 -0
- package/dist/src/lib/i18n/index.js +164 -0
- package/dist/src/lib/i18n/index.mjs +103 -0
- package/dist/src/lib/index.cjs +598 -0
- package/dist/src/lib/index.d.ts +81 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +130 -0
- package/dist/src/lib/index.mjs +688 -0
- package/dist/src/lib/isomorphic.cjs +90 -0
- package/dist/src/lib/isomorphic.d.ts +114 -0
- package/dist/src/lib/isomorphic.d.ts.map +1 -0
- package/dist/src/lib/isomorphic.js +132 -0
- package/dist/src/lib/isomorphic.mjs +69 -0
- package/dist/src/lib/jsx-runtime/index.cjs +21 -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 +13 -0
- package/dist/src/lib/jsx-runtime/index.mjs +4 -0
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +21 -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 +4 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +302 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts +35 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts.map +1 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.js +118 -0
- package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +271 -0
- package/dist/src/lib/plugins/index.cjs +311 -0
- package/dist/src/lib/plugins/index.d.ts +6 -0
- package/dist/src/lib/plugins/index.d.ts.map +1 -0
- package/dist/src/lib/plugins/index.js +7 -0
- package/dist/src/lib/plugins/index.mjs +279 -0
- package/dist/src/lib/plugins/route-codegen.cjs +73 -0
- package/dist/src/lib/plugins/route-codegen.d.ts +12 -0
- package/dist/src/lib/plugins/route-codegen.d.ts.map +1 -0
- package/dist/src/lib/plugins/route-codegen.js +80 -0
- package/dist/src/lib/plugins/route-codegen.mjs +52 -0
- package/dist/src/lib/plugins/route-scanner.cjs +189 -0
- package/dist/src/lib/plugins/route-scanner.d.ts +38 -0
- package/dist/src/lib/plugins/route-scanner.d.ts.map +1 -0
- package/dist/src/lib/plugins/route-scanner.js +215 -0
- package/dist/src/lib/plugins/route-scanner.mjs +158 -0
- package/dist/src/lib/plugins/vite.cjs +27 -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 +6 -0
- package/dist/src/lib/render/await.cjs +38 -0
- package/dist/src/lib/render/await.d.ts +26 -0
- package/dist/src/lib/render/await.d.ts.map +1 -0
- package/dist/src/lib/render/await.js +45 -0
- package/dist/src/lib/render/await.mjs +17 -0
- package/dist/src/lib/render/component.cjs +221 -0
- package/dist/src/lib/render/component.d.ts +296 -0
- package/dist/src/lib/render/component.d.ts.map +1 -0
- package/dist/src/lib/render/component.js +514 -0
- package/dist/src/lib/render/component.mjs +214 -0
- package/dist/src/lib/render/deferred.cjs +175 -0
- package/dist/src/lib/render/deferred.d.ts +36 -0
- package/dist/src/lib/render/deferred.d.ts.map +1 -0
- package/dist/src/lib/render/deferred.js +141 -0
- package/dist/src/lib/render/deferred.mjs +158 -0
- package/dist/src/lib/render/index.cjs +573 -0
- package/dist/src/lib/render/index.d.ts +98 -0
- package/dist/src/lib/render/index.d.ts.map +1 -0
- package/dist/src/lib/render/index.js +180 -0
- package/dist/src/lib/render/index.mjs +590 -0
- package/dist/src/lib/render/lazy.cjs +67 -0
- package/dist/src/lib/render/lazy.d.ts +49 -0
- package/dist/src/lib/render/lazy.d.ts.map +1 -0
- package/dist/src/lib/render/lazy.js +105 -0
- package/dist/src/lib/render/lazy.mjs +50 -0
- package/dist/src/lib/render/suspense.cjs +141 -0
- package/dist/src/lib/render/suspense.d.ts +65 -0
- package/dist/src/lib/render/suspense.d.ts.map +1 -0
- package/dist/src/lib/render/suspense.js +196 -0
- package/dist/src/lib/render/suspense.mjs +136 -0
- package/dist/src/lib/render/versions.cjs +35 -0
- package/dist/src/lib/render/versions.d.ts +2 -0
- package/dist/src/lib/render/versions.d.ts.map +1 -0
- package/dist/src/lib/render/versions.js +21 -0
- package/dist/src/lib/render/versions.mjs +14 -0
- package/dist/src/lib/router/data.cjs +228 -0
- package/dist/src/lib/router/data.d.ts +142 -0
- package/dist/src/lib/router/data.d.ts.map +1 -0
- package/dist/src/lib/router/data.js +258 -0
- package/dist/src/lib/router/data.mjs +214 -0
- package/dist/src/lib/router/index.cjs +921 -0
- package/dist/src/lib/router/index.d.ts +274 -0
- package/dist/src/lib/router/index.d.ts.map +1 -0
- package/dist/src/lib/router/index.js +904 -0
- package/dist/src/lib/router/index.mjs +938 -0
- package/dist/src/lib/router/scroll.cjs +79 -0
- package/dist/src/lib/router/scroll.d.ts +19 -0
- package/dist/src/lib/router/scroll.d.ts.map +1 -0
- package/dist/src/lib/router/scroll.js +68 -0
- package/dist/src/lib/router/scroll.mjs +58 -0
- package/dist/src/lib/router/transition.cjs +75 -0
- package/dist/src/lib/router/transition.d.ts +81 -0
- package/dist/src/lib/router/transition.d.ts.map +1 -0
- package/dist/src/lib/router/transition.js +136 -0
- package/dist/src/lib/router/transition.mjs +54 -0
- package/dist/src/lib/server/hydration.cjs +169 -0
- package/dist/src/lib/server/hydration.d.ts +198 -0
- package/dist/src/lib/server/hydration.d.ts.map +1 -0
- package/dist/src/lib/server/hydration.js +345 -0
- package/dist/src/lib/server/hydration.mjs +148 -0
- package/dist/src/lib/server/index.cjs +406 -0
- package/dist/src/lib/server/index.d.ts +115 -0
- package/dist/src/lib/server/index.d.ts.map +1 -0
- package/dist/src/lib/server/index.js +164 -0
- package/dist/src/lib/server/index.mjs +384 -0
- package/dist/src/lib/server/reactive.cjs +197 -0
- package/dist/src/lib/server/reactive.d.ts +239 -0
- package/dist/src/lib/server/reactive.d.ts.map +1 -0
- package/dist/src/lib/server/reactive.js +413 -0
- package/dist/src/lib/server/reactive.mjs +176 -0
- package/dist/src/lib/storage/cache.cjs +51 -0
- package/dist/src/lib/storage/cache.d.ts +18 -0
- package/dist/src/lib/storage/cache.d.ts.map +1 -0
- package/dist/src/lib/storage/cache.js +42 -0
- package/dist/src/lib/storage/cache.mjs +30 -0
- package/dist/src/lib/storage/index.cjs +246 -0
- package/dist/src/lib/storage/index.d.ts +83 -0
- package/dist/src/lib/storage/index.d.ts.map +1 -0
- package/dist/src/lib/storage/index.js +179 -0
- package/dist/src/lib/storage/index.mjs +231 -0
- package/dist/src/lib/storage/persisted.cjs +91 -0
- package/dist/src/lib/storage/persisted.d.ts +53 -0
- package/dist/src/lib/storage/persisted.d.ts.map +1 -0
- package/dist/src/lib/storage/persisted.js +75 -0
- package/dist/src/lib/storage/persisted.mjs +70 -0
- package/dist/src/lib/theme/color-scheme.cjs +281 -0
- package/dist/src/lib/theme/color-scheme.d.ts +61 -0
- package/dist/src/lib/theme/color-scheme.d.ts.map +1 -0
- package/dist/src/lib/theme/color-scheme.js +120 -0
- package/dist/src/lib/theme/color-scheme.mjs +265 -0
- package/dist/src/lib/theme/index.cjs +267 -0
- package/dist/src/lib/theme/index.d.ts +78 -0
- package/dist/src/lib/theme/index.d.ts.map +1 -0
- package/dist/src/lib/theme/index.js +135 -0
- package/dist/src/lib/theme/index.mjs +251 -0
- package/dist/src/lib/theme/provider.cjs +346 -0
- package/dist/src/lib/theme/provider.d.ts +34 -0
- package/dist/src/lib/theme/provider.d.ts.map +1 -0
- package/dist/src/lib/theme/provider.js +60 -0
- package/dist/src/lib/theme/provider.mjs +332 -0
- package/dist/src/lib/utils/index.cjs +209 -0
- package/dist/src/lib/utils/index.d.ts +286 -0
- package/dist/src/lib/utils/index.d.ts.map +1 -0
- package/dist/src/lib/utils/index.js +434 -0
- package/dist/src/lib/utils/index.mjs +188 -0
- package/dist/src/routes.cjs +37 -0
- package/dist/src/routes.d.ts +22 -0
- package/dist/src/routes.d.ts.map +1 -0
- package/dist/src/routes.js +20 -0
- package/dist/src/routes.mjs +17 -0
- package/dist/src/server.cjs +405 -0
- package/dist/src/server.d.ts +63 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +62 -0
- package/dist/src/server.mjs +382 -0
- package/dist/src/utils.cjs +21 -0
- package/dist/src/utils.d.ts +10 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +9 -0
- package/dist/src/utils.mjs +4 -0
- package/dist/src/version.generated.cjs +26 -0
- package/dist/src/version.generated.d.ts +3 -0
- package/dist/src/version.generated.d.ts.map +1 -0
- package/dist/src/version.generated.js +3 -0
- package/dist/src/version.generated.mjs +5 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +164 -0
- package/src/index.ts +19 -0
- package/types/fluixi.d.ts +5 -0
- package/types/vinxi.d.ts +50 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @fluixi/core/client
|
|
3
|
+
*
|
|
4
|
+
* Implements client-side mounting and hydration logic using @fluixi/dom runtime.
|
|
5
|
+
* Supports both JSX and Lit HTML.
|
|
6
|
+
*/
|
|
7
|
+
import '../render/versions.js';
|
|
8
|
+
/**
|
|
9
|
+
* Mount application to DOM (Client-side Rendering)
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { mount } from '@fluixi/core/client';
|
|
14
|
+
* import App from './App';
|
|
15
|
+
*
|
|
16
|
+
* mount(() => App(), document.getElementById('root'));
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function mount(App: () => any, container: HTMLElement | null): void;
|
|
20
|
+
export { hydrate } from '@fluixi/dom';
|
|
21
|
+
export interface StartClientOptions {
|
|
22
|
+
/** CSS selector or HTMLElement for the app root. Default: '#app' */
|
|
23
|
+
root?: string | HTMLElement;
|
|
24
|
+
/** Force hydration mode. Default: auto-detect from __FLUIXI_HYDRATION__ marker */
|
|
25
|
+
hydrate?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The app's route tree (the same array passed to <Router routes={...}/>). When provided,
|
|
28
|
+
* the lazy chunk(s) for the route matching the current URL are downloaded and awaited
|
|
29
|
+
* before hydration, so each lazy file-route resolves synchronously and adopts the server
|
|
30
|
+
* DOM in place (no fallback, no duplicate). Passing this also enables auto-hydration of a
|
|
31
|
+
* server-rendered (non-empty) root, giving flash-free hydration with zero extra config.
|
|
32
|
+
*/
|
|
33
|
+
routes?: any[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Mount or hydrate an app in the browser.
|
|
37
|
+
*
|
|
38
|
+
* Hydration is detected from the marker the server render leaves behind, so the same
|
|
39
|
+
* call works for a server-rendered page and a plain SPA. Pass `hydrate` to force it.
|
|
40
|
+
*
|
|
41
|
+
* Pass `routes` for a file-routed app. The chunks for the route matching the current URL
|
|
42
|
+
* are downloaded and awaited before hydrating, which is what lets each lazy route resolve
|
|
43
|
+
* synchronously and adopt the server's DOM rather than building a second copy beside it.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* await startClient(App, { root: '#app', routes });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function startClient(App: (props?: any) => any, options?: StartClientOptions): Promise<void>;
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,uBAAuB,CAAC;AAgB/B;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,SAAS,EAAE,WAAW,GAAG,IAAI,QAOlE;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;CAChB;AAoBD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,GAAG,EACzB,OAAO,GAAE,kBAAuB,iBAiFjC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @fluixi/core/client
|
|
3
|
+
*
|
|
4
|
+
* Implements client-side mounting and hydration logic using @fluixi/dom runtime.
|
|
5
|
+
* Supports both JSX and Lit HTML.
|
|
6
|
+
*/
|
|
7
|
+
import { render as domRender, hydrate as domHydrate, beginAppHydration, endAppHydration, removeUnclaimedKeyed, clearHydrationKeys, } from '@fluixi/dom';
|
|
8
|
+
// Registers core's version with the DOM runtime, which does the stamping. This entry is a
|
|
9
|
+
// separate subpath, so it does not otherwise load core's render, and without this the
|
|
10
|
+
// hydrate path stamped `fx-dom`/`fx-reactive` but never `fluixi`.
|
|
11
|
+
import '../render/versions.js';
|
|
12
|
+
import { deserializeHydrationData, setHydrating, cleanupHydration, } from '../server/hydration.js';
|
|
13
|
+
import { render } from '../render/index.js';
|
|
14
|
+
import { createComponent } from '../render/component.js';
|
|
15
|
+
import { createMemo } from '@fluixi/reactive/signal';
|
|
16
|
+
import { createHead, setActiveHead, mountHead, stripHeadMarker } from '@fluixi/head';
|
|
17
|
+
// Connect the reactive system (signals, effects, batch) to the DOM runtime.
|
|
18
|
+
// Without this, createRenderEffect in @fluixi/dom is a one-shot call that never
|
|
19
|
+
// re-runs when signals change: breaking all JSX reactive updates.
|
|
20
|
+
// ensureIntegration();
|
|
21
|
+
/**
|
|
22
|
+
* Mount application to DOM (Client-side Rendering)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* import { mount } from '@fluixi/core/client';
|
|
27
|
+
* import App from './App';
|
|
28
|
+
*
|
|
29
|
+
* mount(() => App(), document.getElementById('root'));
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function mount(App, container) {
|
|
33
|
+
if (!container) {
|
|
34
|
+
throw new Error('Container element not found for mount()');
|
|
35
|
+
}
|
|
36
|
+
// Use @fluixi/dom render which handles reactivity and supports Lit via registration
|
|
37
|
+
domRender(() => App(), container);
|
|
38
|
+
}
|
|
39
|
+
export { hydrate } from '@fluixi/dom';
|
|
40
|
+
/**
|
|
41
|
+
* Standard entry point for client-side rendering or hydration.
|
|
42
|
+
*
|
|
43
|
+
* Auto-detects whether to hydrate (if server-rendered HTML is present)
|
|
44
|
+
* or do a full client render.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* // entry-client.ts
|
|
49
|
+
* import { startClient } from '@fluixi/core/client';
|
|
50
|
+
* import App from './app';
|
|
51
|
+
*
|
|
52
|
+
* startClient(App);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
/** The root, entered the way the compiler enters every other component. */
|
|
56
|
+
const rootOf = (App) => createMemo(() => createComponent(App));
|
|
57
|
+
/**
|
|
58
|
+
* Mount or hydrate an app in the browser.
|
|
59
|
+
*
|
|
60
|
+
* Hydration is detected from the marker the server render leaves behind, so the same
|
|
61
|
+
* call works for a server-rendered page and a plain SPA. Pass `hydrate` to force it.
|
|
62
|
+
*
|
|
63
|
+
* Pass `routes` for a file-routed app. The chunks for the route matching the current URL
|
|
64
|
+
* are downloaded and awaited before hydrating, which is what lets each lazy route resolve
|
|
65
|
+
* synchronously and adopt the server's DOM rather than building a second copy beside it.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* await startClient(App, { root: '#app', routes });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export async function startClient(App, options = {}) {
|
|
73
|
+
const container = typeof options.root === 'string'
|
|
74
|
+
? document.querySelector(options.root)
|
|
75
|
+
: options.root ?? document.querySelector('#app');
|
|
76
|
+
if (!container) {
|
|
77
|
+
throw new Error(`[Fluixi] Mount container not found: ${options.root ?? '#app'}`);
|
|
78
|
+
}
|
|
79
|
+
// Hydrate when explicitly requested (`{ hydrate: true }`), when the server emits the
|
|
80
|
+
// `__FLUIXI_HYDRATION__` marker, or, with a route tree in hand, when the mount root already
|
|
81
|
+
// holds server-rendered content. A non-empty root means SSR/SSG ran, so reuse that DOM instead
|
|
82
|
+
// of clearing and re-rendering (which flashes). Auto-hydration is gated on `routes` because
|
|
83
|
+
// hydrating an app with async lazy file-routes is only safe once those chunks are preloaded
|
|
84
|
+
// (below): without the route tree we can't preload, so we fall back to the render() path. A
|
|
85
|
+
// client-only app mounts into an empty `<div id="root">` (firstElementChild null) -> client render.
|
|
86
|
+
const hasServerDom = !!document.getElementById('__FLUIXI_HYDRATION__') ||
|
|
87
|
+
(!!options.routes && container.firstElementChild != null);
|
|
88
|
+
const shouldHydrate = options.hydrate ?? hasServerDom;
|
|
89
|
+
// Active head registry for this document: seo()/useHead() during the app render register here;
|
|
90
|
+
// mountHead reconciles it into <head> after mount (reusing server tags by key) and keeps it live.
|
|
91
|
+
const head = createHead();
|
|
92
|
+
setActiveHead(head);
|
|
93
|
+
// Drop a stray `<!--fh:...-->` head-transport comment if the server left one in the mount root
|
|
94
|
+
// (streaming / custom servers that don't lift it into <head>). It would otherwise be the cursor's
|
|
95
|
+
// first node and strand hydration: rebuilding the whole tree as a duplicate. Harmless no-op when
|
|
96
|
+
// the server already extracted it (the supported adapter/prerender/dev paths do).
|
|
97
|
+
stripHeadMarker(container);
|
|
98
|
+
if (shouldHydrate) {
|
|
99
|
+
// Before the first await: custom elements the server rendered upgrade while the route
|
|
100
|
+
// chunks load, and wait for this hydration to hand them their owner.
|
|
101
|
+
beginAppHydration();
|
|
102
|
+
try {
|
|
103
|
+
// Preload the lazy chunk(s) for the current route so they resolve synchronously during the
|
|
104
|
+
// hydration render, the lazy boundary then adopts the server DOM in place instead of
|
|
105
|
+
// resolving a tick later and rebuilding a duplicate. Dynamic import keeps the router out of
|
|
106
|
+
// client-only bundles that never pass `routes`.
|
|
107
|
+
if (options.routes && options.routes.length) {
|
|
108
|
+
const { preloadRoutes } = await import('../router/index.js');
|
|
109
|
+
await preloadRoutes(options.routes, window.location.pathname);
|
|
110
|
+
}
|
|
111
|
+
deserializeHydrationData();
|
|
112
|
+
setHydrating(true);
|
|
113
|
+
// A memo around createComponent, which is what compiled JSX emits for every other
|
|
114
|
+
// component. Called directly, the root is the one component the runtime never hears
|
|
115
|
+
// about: nothing holds its return value, so no node is made and a graph of the
|
|
116
|
+
// application starts at whatever the root happened to render.
|
|
117
|
+
// Built inside hydrate, not as its argument: a memo runs when it is made, and made out
|
|
118
|
+
// here the root would render before hydration is on, without the key scope the server
|
|
119
|
+
// opened for it. Every key below would then be one level off and nothing adopted by key.
|
|
120
|
+
domHydrate(() => rootOf(App), container);
|
|
121
|
+
// Handlers are now wired (delegated $$listeners attach during the hydration
|
|
122
|
+
// render): replay any events the user fired before hydration.
|
|
123
|
+
replayEvents();
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
endAppHydration();
|
|
127
|
+
}
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
setHydrating(false);
|
|
130
|
+
// Late route chunks have had their chance to claim their markup: what nothing claimed
|
|
131
|
+
// is server output the client did not render, or rendered differently.
|
|
132
|
+
const removed = removeUnclaimedKeyed(container);
|
|
133
|
+
if (removed && typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production') {
|
|
134
|
+
console.warn(`[fluixi] hydration: removed ${removed} server element(s) the client did not render. Check for markup that depends on client-only state.`);
|
|
135
|
+
}
|
|
136
|
+
clearHydrationKeys();
|
|
137
|
+
cleanupHydration();
|
|
138
|
+
}, 100);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
render(rootOf(App), container);
|
|
142
|
+
}
|
|
143
|
+
mountHead(head);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Replay events captured before hydration by the server's eventCaptureScript
|
|
147
|
+
* (window.__FX_REPLAY__). Hydration REUSES the server DOM, so each recorded target
|
|
148
|
+
* is still live: re-dispatch a synthetic event on it so the app's delegated
|
|
149
|
+
* handlers fire. Discrete events only (click/input/change/submit/keydown). No-op
|
|
150
|
+
* when the capture script wasn't emitted (no queue).
|
|
151
|
+
*/
|
|
152
|
+
function replayEvents() {
|
|
153
|
+
if (typeof window === 'undefined')
|
|
154
|
+
return;
|
|
155
|
+
const w = window;
|
|
156
|
+
if (typeof w.__FX_REPLAY_STOP__ === 'function')
|
|
157
|
+
w.__FX_REPLAY_STOP__();
|
|
158
|
+
const queue = w.__FX_REPLAY__;
|
|
159
|
+
w.__FX_REPLAY__ = undefined;
|
|
160
|
+
w.__FX_REPLAY_STOP__ = undefined;
|
|
161
|
+
if (!Array.isArray(queue) || queue.length === 0)
|
|
162
|
+
return;
|
|
163
|
+
for (const rec of queue) {
|
|
164
|
+
const target = rec && rec.target;
|
|
165
|
+
// Skip targets dropped by a hydration mismatch (recreated, not reconnected).
|
|
166
|
+
if (!target || target.isConnected === false || typeof target.dispatchEvent !== 'function')
|
|
167
|
+
continue;
|
|
168
|
+
const type = rec.type;
|
|
169
|
+
const ev = type === 'click'
|
|
170
|
+
? new MouseEvent(type, { bubbles: true, cancelable: true })
|
|
171
|
+
: new Event(type, { bubbles: true, cancelable: true });
|
|
172
|
+
target.dispatchEvent(ev);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/*! @fluixi/core v1.0.0-alpha.100 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
|
+
import "./chunk-FDOPDB6Z.mjs";
|
|
3
|
+
|
|
4
|
+
// src/lib/client/index.ts
|
|
5
|
+
import {
|
|
6
|
+
render as domRender,
|
|
7
|
+
hydrate as domHydrate,
|
|
8
|
+
beginAppHydration,
|
|
9
|
+
endAppHydration,
|
|
10
|
+
removeUnclaimedKeyed,
|
|
11
|
+
clearHydrationKeys
|
|
12
|
+
} from "@fluixi/dom";
|
|
13
|
+
|
|
14
|
+
// src/lib/render/versions.ts
|
|
15
|
+
import { registerCoreVersion } from "@fluixi/dom";
|
|
16
|
+
|
|
17
|
+
// src/version.generated.ts
|
|
18
|
+
var VERSION = "1.0.0-alpha.100";
|
|
19
|
+
|
|
20
|
+
// src/lib/render/versions.ts
|
|
21
|
+
import { stampVersions, warnOnVersionSkew, versions } from "@fluixi/dom";
|
|
22
|
+
registerCoreVersion(VERSION);
|
|
23
|
+
|
|
24
|
+
// src/lib/server/hydration.ts
|
|
25
|
+
import { isServer as domIsServer } from "@fluixi/dom";
|
|
26
|
+
var hydrating = false;
|
|
27
|
+
var hydrationDataMap = /* @__PURE__ */ new Map();
|
|
28
|
+
function setHydrating(state) {
|
|
29
|
+
hydrating = state;
|
|
30
|
+
}
|
|
31
|
+
function clearHydrationData() {
|
|
32
|
+
hydrationDataMap.clear();
|
|
33
|
+
}
|
|
34
|
+
function deserializeHydrationData() {
|
|
35
|
+
if (typeof window === "undefined") {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const script = document.getElementById("__FLUIXI_HYDRATION__");
|
|
39
|
+
if (!script || script.getAttribute("type") !== "application/json") {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const json = script.textContent || "{}";
|
|
44
|
+
const data = JSON.parse(json);
|
|
45
|
+
for (const [key, value] of Object.entries(data)) {
|
|
46
|
+
hydrationDataMap.set(key, value);
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error("Failed to deserialize hydration data:", error);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function cleanupHydration() {
|
|
55
|
+
if (typeof window === "undefined") {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const script = document.getElementById("__FLUIXI_HYDRATION__");
|
|
59
|
+
if (script) {
|
|
60
|
+
script.remove();
|
|
61
|
+
}
|
|
62
|
+
const walker = document.createTreeWalker(
|
|
63
|
+
document.body,
|
|
64
|
+
NodeFilter.SHOW_COMMENT,
|
|
65
|
+
null
|
|
66
|
+
);
|
|
67
|
+
const comments = [];
|
|
68
|
+
let node;
|
|
69
|
+
while (node = walker.nextNode()) {
|
|
70
|
+
const comment = node;
|
|
71
|
+
const text = comment.nodeValue || "";
|
|
72
|
+
if (text.startsWith("#") || text.startsWith("/")) {
|
|
73
|
+
comments.push(comment);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
comments.forEach((comment) => comment.remove());
|
|
77
|
+
clearHydrationData();
|
|
78
|
+
}
|
|
79
|
+
if (typeof window !== "undefined") {
|
|
80
|
+
window.addEventListener("load", () => {
|
|
81
|
+
setTimeout(cleanupHydration, 100);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/lib/render/index.ts
|
|
86
|
+
import { isServer as isServer3 } from "@fluixi/dom";
|
|
87
|
+
import { createRoot as createRoot2 } from "@fluixi/reactive/signal";
|
|
88
|
+
import {
|
|
89
|
+
isDOMNode,
|
|
90
|
+
delegateEvents,
|
|
91
|
+
insert
|
|
92
|
+
} from "@fluixi/dom";
|
|
93
|
+
|
|
94
|
+
// src/lib/render/component.ts
|
|
95
|
+
import { isServer } from "@fluixi/dom";
|
|
96
|
+
import {
|
|
97
|
+
createComponent as domCreateComponent,
|
|
98
|
+
asComponent
|
|
99
|
+
} from "@fluixi/dom";
|
|
100
|
+
import {
|
|
101
|
+
untrack,
|
|
102
|
+
onCleanup,
|
|
103
|
+
getOwner,
|
|
104
|
+
createEffect,
|
|
105
|
+
createMemo,
|
|
106
|
+
createSignal,
|
|
107
|
+
isSignal,
|
|
108
|
+
batch,
|
|
109
|
+
runWithOwner,
|
|
110
|
+
isOwnerDisposed
|
|
111
|
+
} from "@fluixi/reactive/signal";
|
|
112
|
+
function createComponent(Comp, props) {
|
|
113
|
+
return domCreateComponent(Comp, props);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/lib/render/suspense.ts
|
|
117
|
+
import {
|
|
118
|
+
createSignal as createSignal2,
|
|
119
|
+
createMemo as createMemo2,
|
|
120
|
+
createEffect as createEffect2,
|
|
121
|
+
createRenderEffect as createRenderEffect2,
|
|
122
|
+
isSignal as isSignal2,
|
|
123
|
+
readChildren,
|
|
124
|
+
useContext as useContext2,
|
|
125
|
+
createContext as createContext2,
|
|
126
|
+
createSuspenseBoundary,
|
|
127
|
+
provideSuspense
|
|
128
|
+
} from "@fluixi/reactive/signal";
|
|
129
|
+
import {
|
|
130
|
+
asSuspense,
|
|
131
|
+
isComponent,
|
|
132
|
+
createComponent as createComponent2,
|
|
133
|
+
runWithoutHydration
|
|
134
|
+
} from "@fluixi/dom";
|
|
135
|
+
function isPromise(value) {
|
|
136
|
+
return !!(value && typeof value === "object" && typeof value.then === "function" || value instanceof Promise);
|
|
137
|
+
}
|
|
138
|
+
var SuspenseListContext = createContext2(void 0, "suspense-list");
|
|
139
|
+
function Suspense(props) {
|
|
140
|
+
return createComponent2(SuspenseImpl, props);
|
|
141
|
+
}
|
|
142
|
+
function SuspenseImpl(props) {
|
|
143
|
+
const boundary = createSuspenseBoundary();
|
|
144
|
+
const listCtx = useContext2(SuspenseListContext);
|
|
145
|
+
const listState = listCtx ? listCtx.register(boundary.inFallback) : void 0;
|
|
146
|
+
function instantiateOnce(val) {
|
|
147
|
+
if (val == null || typeof val === "boolean") return null;
|
|
148
|
+
if (typeof val === "function" && isComponent(val) && !isSignal2(val)) return val();
|
|
149
|
+
return val;
|
|
150
|
+
}
|
|
151
|
+
const fallback = runWithoutHydration(() => instantiateOnce(props.fallback ?? null));
|
|
152
|
+
const children = provideSuspense(boundary, () => readChildren(() => props.children));
|
|
153
|
+
const track = (value, depth) => {
|
|
154
|
+
if (depth > 8) return;
|
|
155
|
+
if (Array.isArray(value)) {
|
|
156
|
+
for (const x of value) track(x, depth + 1);
|
|
157
|
+
} else if (typeof value === "function" && isSignal2(value)) {
|
|
158
|
+
track(value(), depth + 1);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
provideSuspense(boundary, () => {
|
|
162
|
+
createRenderEffect2(() => track(children, 0));
|
|
163
|
+
});
|
|
164
|
+
const [resolved, setResolved] = createSignal2(void 0);
|
|
165
|
+
const childIsPromise = isPromise(children);
|
|
166
|
+
if (childIsPromise) {
|
|
167
|
+
boundary.increment();
|
|
168
|
+
children.then(
|
|
169
|
+
(v) => {
|
|
170
|
+
setResolved(() => v);
|
|
171
|
+
boundary.decrement();
|
|
172
|
+
},
|
|
173
|
+
() => boundary.decrement()
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
return createMemo2(() => {
|
|
177
|
+
const showFallback = listState ? listState.showFallback() : boundary.inFallback();
|
|
178
|
+
if (showFallback) return fallback;
|
|
179
|
+
if (childIsPromise) return resolved();
|
|
180
|
+
return children;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
asSuspense(Suspense);
|
|
184
|
+
Object.defineProperty(Suspense, "__suspense", { value: true, enumerable: true });
|
|
185
|
+
|
|
186
|
+
// src/lib/render/deferred.ts
|
|
187
|
+
import { isServer as isServer2 } from "@fluixi/dom";
|
|
188
|
+
import { createMemo as createMemo3, createSignal as createSignal3 } from "@fluixi/reactive/signal";
|
|
189
|
+
import { observeIntersection } from "@fluixi/dom/utils";
|
|
190
|
+
|
|
191
|
+
// src/lib/render/await.ts
|
|
192
|
+
import { createResource as createResource2 } from "@fluixi/reactive/signal";
|
|
193
|
+
|
|
194
|
+
// src/lib/render/index.ts
|
|
195
|
+
function render(code, container, options = {}) {
|
|
196
|
+
delegateEvents(["click", "input", "change", "submit"]);
|
|
197
|
+
if (isServer3()) {
|
|
198
|
+
throw new Error(
|
|
199
|
+
"render() is for client-side only. Use renderToString() on server."
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
if (!container) {
|
|
203
|
+
throw new Error("Container element is required");
|
|
204
|
+
}
|
|
205
|
+
let disposer;
|
|
206
|
+
createRoot2((dispose) => {
|
|
207
|
+
disposer = dispose;
|
|
208
|
+
const result = typeof code === "function" ? code() : code;
|
|
209
|
+
container.textContent = "";
|
|
210
|
+
stampVersions(container);
|
|
211
|
+
warnOnVersionSkew();
|
|
212
|
+
insert(container, () => result);
|
|
213
|
+
});
|
|
214
|
+
return () => {
|
|
215
|
+
if (disposer) {
|
|
216
|
+
disposer();
|
|
217
|
+
disposer = void 0;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/lib/client/index.ts
|
|
223
|
+
import { createMemo as createMemo4 } from "@fluixi/reactive/signal";
|
|
224
|
+
import { createHead, setActiveHead, mountHead, stripHeadMarker } from "@fluixi/head";
|
|
225
|
+
import { hydrate } from "@fluixi/dom";
|
|
226
|
+
function mount(App, container) {
|
|
227
|
+
if (!container) {
|
|
228
|
+
throw new Error("Container element not found for mount()");
|
|
229
|
+
}
|
|
230
|
+
domRender(() => App(), container);
|
|
231
|
+
}
|
|
232
|
+
var rootOf = (App) => createMemo4(() => createComponent(App));
|
|
233
|
+
async function startClient(App, options = {}) {
|
|
234
|
+
const container = typeof options.root === "string" ? document.querySelector(options.root) : options.root ?? document.querySelector("#app");
|
|
235
|
+
if (!container) {
|
|
236
|
+
throw new Error(
|
|
237
|
+
`[Fluixi] Mount container not found: ${options.root ?? "#app"}`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
const hasServerDom = !!document.getElementById("__FLUIXI_HYDRATION__") || !!options.routes && container.firstElementChild != null;
|
|
241
|
+
const shouldHydrate = options.hydrate ?? hasServerDom;
|
|
242
|
+
const head = createHead();
|
|
243
|
+
setActiveHead(head);
|
|
244
|
+
stripHeadMarker(container);
|
|
245
|
+
if (shouldHydrate) {
|
|
246
|
+
beginAppHydration();
|
|
247
|
+
try {
|
|
248
|
+
if (options.routes && options.routes.length) {
|
|
249
|
+
const { preloadRoutes } = await import("./router-4PTBPZLQ.mjs");
|
|
250
|
+
await preloadRoutes(options.routes, window.location.pathname);
|
|
251
|
+
}
|
|
252
|
+
deserializeHydrationData();
|
|
253
|
+
setHydrating(true);
|
|
254
|
+
domHydrate(() => rootOf(App), container);
|
|
255
|
+
replayEvents();
|
|
256
|
+
} finally {
|
|
257
|
+
endAppHydration();
|
|
258
|
+
}
|
|
259
|
+
setTimeout(() => {
|
|
260
|
+
setHydrating(false);
|
|
261
|
+
const removed = removeUnclaimedKeyed(container);
|
|
262
|
+
if (removed && typeof process !== "undefined" && false) {
|
|
263
|
+
console.warn(`[fluixi] hydration: removed ${removed} server element(s) the client did not render. Check for markup that depends on client-only state.`);
|
|
264
|
+
}
|
|
265
|
+
clearHydrationKeys();
|
|
266
|
+
cleanupHydration();
|
|
267
|
+
}, 100);
|
|
268
|
+
} else {
|
|
269
|
+
render(rootOf(App), container);
|
|
270
|
+
}
|
|
271
|
+
mountHead(head);
|
|
272
|
+
}
|
|
273
|
+
function replayEvents() {
|
|
274
|
+
if (typeof window === "undefined") return;
|
|
275
|
+
const w = window;
|
|
276
|
+
if (typeof w.__FX_REPLAY_STOP__ === "function") w.__FX_REPLAY_STOP__();
|
|
277
|
+
const queue = w.__FX_REPLAY__;
|
|
278
|
+
w.__FX_REPLAY__ = void 0;
|
|
279
|
+
w.__FX_REPLAY_STOP__ = void 0;
|
|
280
|
+
if (!Array.isArray(queue) || queue.length === 0) return;
|
|
281
|
+
for (const rec of queue) {
|
|
282
|
+
const target = rec && rec.target;
|
|
283
|
+
if (!target || target.isConnected === false || typeof target.dispatchEvent !== "function") continue;
|
|
284
|
+
const type = rec.type;
|
|
285
|
+
const ev = type === "click" ? new MouseEvent(type, { bubbles: true, cancelable: true }) : new Event(type, { bubbles: true, cancelable: true });
|
|
286
|
+
target.dispatchEvent(ev);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
export {
|
|
290
|
+
hydrate,
|
|
291
|
+
mount,
|
|
292
|
+
startClient
|
|
293
|
+
};
|