@fluixi/core 1.0.0-alpha.83 → 1.0.0-alpha.85
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/dist/cdn/core.global.js +2 -1
- package/dist/cli/generate.cjs +4117 -292
- package/dist/cli/generate.mjs +4122 -292
- package/dist/cli/index.cjs +4117 -292
- package/dist/cli/index.mjs +4122 -292
- package/dist/cli/run.cjs +63 -1
- package/dist/cli/run.mjs +39 -1
- package/dist/src/cdn/chunk-MDJLC3PE.mjs +830 -0
- package/dist/src/cdn/core.cjs +1365 -1
- package/dist/src/cdn/core.d.ts +3 -3
- package/dist/src/cdn/core.js +3 -3
- package/dist/src/cdn/core.mjs +642 -1
- package/dist/src/cdn/router-JYFZP3EZ.mjs +70 -0
- package/dist/src/index.cjs +1280 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -11
- package/dist/src/index.mjs +1393 -1
- package/dist/src/jsx-dev-runtime.cjs +26 -1
- package/dist/src/jsx-dev-runtime.mjs +24 -1
- package/dist/src/jsx-runtime.cjs +26 -1
- package/dist/src/jsx-runtime.js +0 -9
- package/dist/src/jsx-runtime.mjs +24 -1
- package/dist/src/lib/client/chunk-7IUN2FLI.mjs +133 -0
- package/dist/src/lib/client/index.cjs +956 -1
- package/dist/src/lib/client/index.d.ts +17 -6
- package/dist/src/lib/client/index.d.ts.map +1 -1
- package/dist/src/lib/client/index.js +26 -19
- package/dist/src/lib/client/index.mjs +222 -1
- package/dist/src/lib/client/router-NOFEMOEH.mjs +631 -0
- package/dist/src/lib/context/context.cjs +118 -1
- package/dist/src/lib/context/context.d.ts +19 -37
- package/dist/src/lib/context/context.d.ts.map +1 -1
- package/dist/src/lib/context/context.js +8 -45
- package/dist/src/lib/context/context.mjs +99 -1
- package/dist/src/lib/context/index.cjs +120 -1
- package/dist/src/lib/context/index.mjs +99 -1
- package/dist/src/lib/control-flow.cjs +35 -1
- package/dist/src/lib/control-flow.mjs +25 -1
- package/dist/src/lib/core.cjs +1279 -1
- package/dist/src/lib/core.d.ts +0 -2
- package/dist/src/lib/core.d.ts.map +1 -1
- package/dist/src/lib/core.js +14 -48
- package/dist/src/lib/core.mjs +1393 -1
- package/dist/src/lib/env/index.cjs +60 -1
- package/dist/src/lib/env/index.d.ts +5 -5
- package/dist/src/lib/env/index.js +5 -5
- package/dist/src/lib/env/index.mjs +39 -1
- package/dist/src/lib/i18n/index.cjs +108 -1
- package/dist/src/lib/i18n/index.d.ts +31 -10
- package/dist/src/lib/i18n/index.d.ts.map +1 -1
- package/dist/src/lib/i18n/index.js +31 -10
- package/dist/src/lib/i18n/index.mjs +88 -1
- package/dist/src/lib/index.cjs +633 -1
- package/dist/src/lib/index.d.ts +0 -2
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +5 -11
- package/dist/src/lib/index.mjs +721 -1
- package/dist/src/lib/isomorphic.cjs +85 -1
- package/dist/src/lib/isomorphic.d.ts +41 -8
- package/dist/src/lib/isomorphic.d.ts.map +1 -1
- package/dist/src/lib/isomorphic.js +38 -5
- package/dist/src/lib/isomorphic.mjs +64 -1
- package/dist/src/lib/jsx-runtime/index.cjs +21 -1
- package/dist/src/lib/jsx-runtime/index.d.ts +1 -1
- package/dist/src/lib/jsx-runtime/index.js +1 -11
- package/dist/src/lib/jsx-runtime/index.mjs +4 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +21 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +4 -1
- package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +302 -8
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts +15 -1
- package/dist/src/lib/plugins/fluixi-routes-plugin.d.ts.map +1 -1
- package/dist/src/lib/plugins/fluixi-routes-plugin.js +19 -5
- package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +271 -8
- package/dist/src/lib/plugins/index.cjs +311 -8
- package/dist/src/lib/plugins/index.mjs +279 -8
- package/dist/src/lib/plugins/route-codegen.cjs +73 -8
- package/dist/src/lib/plugins/route-codegen.d.ts +0 -1
- package/dist/src/lib/plugins/route-codegen.d.ts.map +1 -1
- package/dist/src/lib/plugins/route-codegen.js +4 -5
- package/dist/src/lib/plugins/route-codegen.mjs +52 -8
- package/dist/src/lib/plugins/route-scanner.cjs +189 -1
- package/dist/src/lib/plugins/route-scanner.d.ts +1 -2
- package/dist/src/lib/plugins/route-scanner.d.ts.map +1 -1
- package/dist/src/lib/plugins/route-scanner.js +7 -8
- package/dist/src/lib/plugins/route-scanner.mjs +158 -1
- package/dist/src/lib/plugins/vite.cjs +27 -1
- package/dist/src/lib/plugins/vite.mjs +6 -1
- package/dist/src/lib/render/await.cjs +38 -1
- package/dist/src/lib/render/await.d.ts +18 -0
- package/dist/src/lib/render/await.d.ts.map +1 -1
- package/dist/src/lib/render/await.js +20 -2
- package/dist/src/lib/render/await.mjs +17 -1
- package/dist/src/lib/render/component.cjs +221 -1
- package/dist/src/lib/render/component.d.ts +3 -44
- package/dist/src/lib/render/component.d.ts.map +1 -1
- package/dist/src/lib/render/component.js +23 -55
- package/dist/src/lib/render/component.mjs +214 -1
- package/dist/src/lib/render/deferred.cjs +175 -1
- package/dist/src/lib/render/deferred.js +5 -5
- package/dist/src/lib/render/deferred.mjs +158 -1
- package/dist/src/lib/render/index.cjs +573 -1
- package/dist/src/lib/render/index.d.ts +3 -17
- package/dist/src/lib/render/index.d.ts.map +1 -1
- package/dist/src/lib/render/index.js +8 -22
- package/dist/src/lib/render/index.mjs +590 -1
- package/dist/src/lib/render/lazy.cjs +67 -1
- package/dist/src/lib/render/lazy.d.ts +22 -1
- package/dist/src/lib/render/lazy.d.ts.map +1 -1
- package/dist/src/lib/render/lazy.js +26 -5
- package/dist/src/lib/render/lazy.mjs +50 -1
- package/dist/src/lib/render/suspense.cjs +141 -1
- package/dist/src/lib/render/suspense.d.ts +40 -0
- package/dist/src/lib/render/suspense.d.ts.map +1 -1
- package/dist/src/lib/render/suspense.js +46 -6
- package/dist/src/lib/render/suspense.mjs +136 -1
- package/dist/src/lib/render/versions.cjs +35 -1
- package/dist/src/lib/render/versions.js +6 -6
- package/dist/src/lib/render/versions.mjs +14 -1
- package/dist/src/lib/router/data.cjs +230 -1
- package/dist/src/lib/router/data.d.ts +1 -13
- package/dist/src/lib/router/data.d.ts.map +1 -1
- package/dist/src/lib/router/data.js +0 -12
- package/dist/src/lib/router/data.mjs +214 -1
- package/dist/src/lib/router/index.cjs +709 -1
- package/dist/src/lib/router/index.d.ts +78 -23
- package/dist/src/lib/router/index.d.ts.map +1 -1
- package/dist/src/lib/router/index.js +161 -37
- package/dist/src/lib/router/index.mjs +722 -1
- 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 -1
- package/dist/src/lib/server/hydration.d.ts +15 -55
- package/dist/src/lib/server/hydration.d.ts.map +1 -1
- package/dist/src/lib/server/hydration.js +23 -62
- package/dist/src/lib/server/hydration.mjs +148 -1
- package/dist/src/lib/server/index.cjs +401 -11
- package/dist/src/lib/server/index.d.ts +30 -6
- package/dist/src/lib/server/index.d.ts.map +1 -1
- package/dist/src/lib/server/index.js +34 -11
- package/dist/src/lib/server/index.mjs +379 -11
- package/dist/src/lib/server/reactive.cjs +197 -1
- package/dist/src/lib/server/reactive.d.ts +18 -77
- package/dist/src/lib/server/reactive.d.ts.map +1 -1
- package/dist/src/lib/server/reactive.js +19 -78
- package/dist/src/lib/server/reactive.mjs +176 -1
- package/dist/src/lib/theme/index.cjs +110 -1
- package/dist/src/lib/theme/index.d.ts +19 -4
- package/dist/src/lib/theme/index.d.ts.map +1 -1
- package/dist/src/lib/theme/index.js +17 -2
- package/dist/src/lib/theme/index.mjs +89 -1
- package/dist/src/lib/utils/index.cjs +209 -1
- package/dist/src/lib/utils/index.d.ts +0 -93
- package/dist/src/lib/utils/index.d.ts.map +1 -1
- package/dist/src/lib/utils/index.js +0 -93
- package/dist/src/lib/utils/index.mjs +188 -1
- package/dist/src/routes.cjs +37 -1
- package/dist/src/routes.d.ts +1 -1
- package/dist/src/routes.js +2 -2
- package/dist/src/routes.mjs +17 -1
- package/dist/src/server.cjs +400 -11
- package/dist/src/server.d.ts +0 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +0 -1
- package/dist/src/server.mjs +377 -11
- package/dist/src/utils.cjs +21 -1
- package/dist/src/utils.d.ts +1 -1
- package/dist/src/utils.js +1 -1
- package/dist/src/utils.mjs +4 -1
- package/dist/src/version.generated.cjs +26 -1
- package/dist/src/version.generated.d.ts +1 -1
- package/dist/src/version.generated.js +2 -2
- package/dist/src/version.generated.mjs +5 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +17 -16
- package/src/index.ts +2 -14
- package/dist/src/cdn/chunk-55BT3H6E.mjs +0 -1
- package/dist/src/cdn/router-5JJZBK4E.mjs +0 -1
- package/dist/src/lib/client/chunk-SM4WHBOP.mjs +0 -1
- package/dist/src/lib/client/router-IBD4WPQT.mjs +0 -1
|
@@ -1 +1,85 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/isomorphic.ts
|
|
21
|
+
var isomorphic_exports = {};
|
|
22
|
+
__export(isomorphic_exports, {
|
|
23
|
+
createIsomorphicState: () => createIsomorphicState,
|
|
24
|
+
createIsomorphicStore: () => createIsomorphicStore
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(isomorphic_exports);
|
|
27
|
+
var import_signal = require("@fluixi/reactive/signal");
|
|
28
|
+
var import_dom = require("@fluixi/dom");
|
|
29
|
+
var REGISTRY_KEY = "__fluixi_iso_states__";
|
|
30
|
+
var SEED_PREFIX = "__iso:";
|
|
31
|
+
function registry() {
|
|
32
|
+
return globalThis[REGISTRY_KEY] ??= /* @__PURE__ */ new Map();
|
|
33
|
+
}
|
|
34
|
+
function readSeed(key) {
|
|
35
|
+
if (typeof window === "undefined") return void 0;
|
|
36
|
+
const data = (0, import_dom.getServerData)();
|
|
37
|
+
return data ? data[SEED_PREFIX + key] : void 0;
|
|
38
|
+
}
|
|
39
|
+
function createIsomorphicState(key, options) {
|
|
40
|
+
const seed = readSeed(key);
|
|
41
|
+
const initial = seed !== void 0 ? seed : typeof window !== "undefined" && options.client ? options.client() : options.fallback;
|
|
42
|
+
const [value, set] = (0, import_signal.createSignal)(initial);
|
|
43
|
+
registry().set(key, { server: options.server, set });
|
|
44
|
+
return { value, set, key };
|
|
45
|
+
}
|
|
46
|
+
function createIsomorphicStore(key, options) {
|
|
47
|
+
const seeded = readSeed(key) !== void 0;
|
|
48
|
+
const base = createIsomorphicState(key, {
|
|
49
|
+
server: options.server,
|
|
50
|
+
fallback: options.fallback
|
|
51
|
+
});
|
|
52
|
+
const value = () => base.value() ?? options.fallback;
|
|
53
|
+
const persistWrite = (v) => {
|
|
54
|
+
if (!options.persist || typeof localStorage === "undefined") return;
|
|
55
|
+
try {
|
|
56
|
+
localStorage.setItem(options.persist, JSON.stringify(v));
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const set = (v) => {
|
|
61
|
+
base.set(v);
|
|
62
|
+
persistWrite(v);
|
|
63
|
+
};
|
|
64
|
+
const setField = (k, val) => {
|
|
65
|
+
set({ ...value(), [k]: val });
|
|
66
|
+
};
|
|
67
|
+
const fields = {};
|
|
68
|
+
for (const k of Object.keys(options.fallback)) {
|
|
69
|
+
fields[k] = (0, import_signal.createMemo)(() => value()[k]);
|
|
70
|
+
}
|
|
71
|
+
let initPromise = null;
|
|
72
|
+
const ensureInit = () => {
|
|
73
|
+
if (seeded || !options.client) return Promise.resolve();
|
|
74
|
+
if (!initPromise) {
|
|
75
|
+
initPromise = Promise.resolve(options.client()).then((v) => {
|
|
76
|
+
set(v);
|
|
77
|
+
}).catch((e) => {
|
|
78
|
+
initPromise = null;
|
|
79
|
+
throw e;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return initPromise;
|
|
83
|
+
};
|
|
84
|
+
return { value, fields, set, setField, ensureInit, key };
|
|
85
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Isomorphic request state
|
|
2
|
+
* Isomorphic request state, the generic form of "ensureInit + transfer".
|
|
3
3
|
*
|
|
4
4
|
* A value that is resolved ONCE on the server (per request, before the app renders),
|
|
5
5
|
* serialized into the page, and seeded SYNCHRONOUSLY on the client so the first client
|
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
* - Client: `createIsomorphicState` reads that seed at creation and starts there.
|
|
12
12
|
*
|
|
13
13
|
* This module is client-safe (no node imports) so app stores can call it on both sides.
|
|
14
|
-
* It talks to @fluixi/server only through a `globalThis` registry
|
|
14
|
+
* It talks to @fluixi/server only through a `globalThis` registry, no import edge.
|
|
15
15
|
*
|
|
16
16
|
* NOTE (prototype): the signal is module-scoped, so concurrent SSR requests share it.
|
|
17
17
|
* That is fine for a single default value; per-user, per-request isolation wants the
|
|
18
|
-
* request-scoped (AsyncLocalStorage) store
|
|
18
|
+
* request-scoped (AsyncLocalStorage) store, a follow-up.
|
|
19
19
|
*/
|
|
20
20
|
import { type Accessor } from '@fluixi/reactive/signal';
|
|
21
21
|
export interface IsomorphicState<T> {
|
|
22
|
-
/** Reactive accessor for the current value (a real signal
|
|
22
|
+
/** Reactive accessor for the current value (a real signal: safe in JSX/control flow). */
|
|
23
23
|
value: Accessor<T | undefined>;
|
|
24
24
|
/** Update the value (client-side preference changes, optimistic updates). */
|
|
25
25
|
set: (v: T | undefined) => void;
|
|
@@ -27,16 +27,33 @@ export interface IsomorphicState<T> {
|
|
|
27
27
|
key: string;
|
|
28
28
|
}
|
|
29
29
|
export interface IsomorphicOptions<T> {
|
|
30
|
-
/** Resolve the value on the server for
|
|
30
|
+
/** Resolve the value on the server for this request (receives the RequestEvent). */
|
|
31
31
|
server: (event: any) => T | Promise<T>;
|
|
32
32
|
/** Optional client-only initial value when there is no server seed (pure SPA load). */
|
|
33
33
|
client?: () => T | undefined;
|
|
34
34
|
/** Value before resolution. */
|
|
35
35
|
fallback?: T;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* A value resolved on the server, transferred to the client, and resolvable there too.
|
|
39
|
+
*
|
|
40
|
+
* The server resolver runs per request and its result is serialized into the page, so the
|
|
41
|
+
* client starts with the answer rather than fetching it again. On a cold client load with
|
|
42
|
+
* no seed, the client resolver runs once instead.
|
|
43
|
+
*
|
|
44
|
+
* `key` names the transfer slot and has to be stable across the two sides.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const user = createIsomorphicState('user', {
|
|
49
|
+
* server: (event) => event.locals.user,
|
|
50
|
+
* client: () => fetch('/api/me').then((r) => r.json()),
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
37
54
|
export declare function createIsomorphicState<T>(key: string, options: IsomorphicOptions<T>): IsomorphicState<T>;
|
|
38
55
|
export interface IsomorphicStore<T extends Record<string, any>> {
|
|
39
|
-
/** Reactive accessor for the whole record (always defined
|
|
56
|
+
/** Reactive accessor for the whole record (always defined: falls back to `fallback`). */
|
|
40
57
|
value: Accessor<T>;
|
|
41
58
|
/** Per-field reactive accessors, one for every key of `fallback`. */
|
|
42
59
|
fields: {
|
|
@@ -48,7 +65,7 @@ export interface IsomorphicStore<T extends Record<string, any>> {
|
|
|
48
65
|
setField: <K extends keyof T>(key: K, val: T[K]) => void;
|
|
49
66
|
/**
|
|
50
67
|
* Run the async `client` resolver exactly once (memoised; the promise is reset on
|
|
51
|
-
* failure so a later call can retry). A
|
|
68
|
+
* failure so a later call can retry). A no-op when the value was server-seeded, the
|
|
52
69
|
* server already resolved and transferred it, so there is nothing to fetch.
|
|
53
70
|
*/
|
|
54
71
|
ensureInit: () => Promise<void>;
|
|
@@ -56,7 +73,7 @@ export interface IsomorphicStore<T extends Record<string, any>> {
|
|
|
56
73
|
key: string;
|
|
57
74
|
}
|
|
58
75
|
export interface IsomorphicStoreOptions<T> {
|
|
59
|
-
/** Resolve the record on the server for
|
|
76
|
+
/** Resolve the record on the server for this request (receives the RequestEvent). */
|
|
60
77
|
server: (event: any) => T | Promise<T>;
|
|
61
78
|
/** Resolve the record on a pure-SPA cold load (no server seed). Run once by ensureInit(). */
|
|
62
79
|
client?: () => T | Promise<T>;
|
|
@@ -65,5 +82,21 @@ export interface IsomorphicStoreOptions<T> {
|
|
|
65
82
|
/** localStorage key to mirror the record into on every write (optional). */
|
|
66
83
|
persist?: string;
|
|
67
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* `createIsomorphicState` for a record, exposed as a store rather than a single value.
|
|
87
|
+
*
|
|
88
|
+
* Reads track per key, so a component using one field is untouched when another changes.
|
|
89
|
+
* Otherwise the transfer is the same: the server resolver runs per request, the result is
|
|
90
|
+
* serialized into the page, and a seeded client does not refetch.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const settings = createIsomorphicStore('settings', {
|
|
95
|
+
* server: (event) => loadSettings(event.locals.userId),
|
|
96
|
+
* client: () => fetch('/api/settings').then((r) => r.json()),
|
|
97
|
+
* });
|
|
98
|
+
* settings.state.theme; // tracks `theme` alone
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
68
101
|
export declare function createIsomorphicStore<T extends Record<string, any>>(key: string, options: IsomorphicStoreOptions<T>): IsomorphicStore<T>;
|
|
69
102
|
//# sourceMappingURL=isomorphic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isomorphic.d.ts","sourceRoot":"","sources":["../../../src/lib/isomorphic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAA4B,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAelF,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,
|
|
1
|
+
{"version":3,"file":"isomorphic.d.ts","sourceRoot":"","sources":["../../../src/lib/isomorphic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAA4B,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAelF,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,yFAAyF;IACzF,KAAK,EAAE,QAAQ,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC/B,6EAA6E;IAC7E,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;IAChC,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,oFAAoF;IACpF,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvC,uFAAuF;IACvF,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,CAAC,CAAC;CACd;AASD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC5B,eAAe,CAAC,CAAC,CAAC,CAapB;AAkBD,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC5D,yFAAyF;IACzF,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnB,qEAAqE;IACrE,MAAM,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAAE,CAAC;IAC3C,gCAAgC;IAChC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACzD;;;;OAIG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,gCAAgC;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,qFAAqF;IACrF,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvC,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9B,sFAAsF;IACtF,QAAQ,EAAE,CAAC,CAAC;IACZ,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjE,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,GACjC,eAAe,CAAC,CAAC,CAAC,CAmDpB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Isomorphic request state
|
|
2
|
+
* Isomorphic request state, the generic form of "ensureInit + transfer".
|
|
3
3
|
*
|
|
4
4
|
* A value that is resolved ONCE on the server (per request, before the app renders),
|
|
5
5
|
* serialized into the page, and seeded SYNCHRONOUSLY on the client so the first client
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
* - Client: `createIsomorphicState` reads that seed at creation and starts there.
|
|
12
12
|
*
|
|
13
13
|
* This module is client-safe (no node imports) so app stores can call it on both sides.
|
|
14
|
-
* It talks to @fluixi/server only through a `globalThis` registry
|
|
14
|
+
* It talks to @fluixi/server only through a `globalThis` registry, no import edge.
|
|
15
15
|
*
|
|
16
16
|
* NOTE (prototype): the signal is module-scoped, so concurrent SSR requests share it.
|
|
17
17
|
* That is fine for a single default value; per-user, per-request isolation wants the
|
|
18
|
-
* request-scoped (AsyncLocalStorage) store
|
|
18
|
+
* request-scoped (AsyncLocalStorage) store, a follow-up.
|
|
19
19
|
*/
|
|
20
20
|
import { createSignal, createMemo } from '@fluixi/reactive/signal';
|
|
21
21
|
import { getServerData } from '@fluixi/dom';
|
|
@@ -31,6 +31,23 @@ function readSeed(key) {
|
|
|
31
31
|
const data = getServerData();
|
|
32
32
|
return data ? data[SEED_PREFIX + key] : undefined;
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* A value resolved on the server, transferred to the client, and resolvable there too.
|
|
36
|
+
*
|
|
37
|
+
* The server resolver runs per request and its result is serialized into the page, so the
|
|
38
|
+
* client starts with the answer rather than fetching it again. On a cold client load with
|
|
39
|
+
* no seed, the client resolver runs once instead.
|
|
40
|
+
*
|
|
41
|
+
* `key` names the transfer slot and has to be stable across the two sides.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* const user = createIsomorphicState('user', {
|
|
46
|
+
* server: (event) => event.locals.user,
|
|
47
|
+
* client: () => fetch('/api/me').then((r) => r.json()),
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
34
51
|
export function createIsomorphicState(key, options) {
|
|
35
52
|
const seed = readSeed(key);
|
|
36
53
|
const initial = seed !== undefined
|
|
@@ -42,8 +59,24 @@ export function createIsomorphicState(key, options) {
|
|
|
42
59
|
registry().set(key, { server: options.server, set: set });
|
|
43
60
|
return { value, set: set, key };
|
|
44
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* `createIsomorphicState` for a record, exposed as a store rather than a single value.
|
|
64
|
+
*
|
|
65
|
+
* Reads track per key, so a component using one field is untouched when another changes.
|
|
66
|
+
* Otherwise the transfer is the same: the server resolver runs per request, the result is
|
|
67
|
+
* serialized into the page, and a seeded client does not refetch.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* const settings = createIsomorphicStore('settings', {
|
|
72
|
+
* server: (event) => loadSettings(event.locals.userId),
|
|
73
|
+
* client: () => fetch('/api/settings').then((r) => r.json()),
|
|
74
|
+
* });
|
|
75
|
+
* settings.state.theme; // tracks `theme` alone
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
45
78
|
export function createIsomorphicStore(key, options) {
|
|
46
|
-
// Whether the server transferred a value for this key (read
|
|
79
|
+
// Whether the server transferred a value for this key (read before the base state
|
|
47
80
|
// consumes the seed). When true, ensureInit() must not refetch on the client.
|
|
48
81
|
const seeded = readSeed(key) !== undefined;
|
|
49
82
|
const base = createIsomorphicState(key, {
|
|
@@ -58,7 +91,7 @@ export function createIsomorphicStore(key, options) {
|
|
|
58
91
|
localStorage.setItem(options.persist, JSON.stringify(v));
|
|
59
92
|
}
|
|
60
93
|
catch {
|
|
61
|
-
/* quota / private mode
|
|
94
|
+
/* quota / private mode: persistence is best-effort */
|
|
62
95
|
}
|
|
63
96
|
};
|
|
64
97
|
const set = (v) => {
|
|
@@ -1 +1,64 @@
|
|
|
1
|
-
|
|
1
|
+
// src/lib/isomorphic.ts
|
|
2
|
+
import { createSignal, createMemo } from "@fluixi/reactive/signal";
|
|
3
|
+
import { getServerData } from "@fluixi/dom";
|
|
4
|
+
var REGISTRY_KEY = "__fluixi_iso_states__";
|
|
5
|
+
var SEED_PREFIX = "__iso:";
|
|
6
|
+
function registry() {
|
|
7
|
+
return globalThis[REGISTRY_KEY] ??= /* @__PURE__ */ new Map();
|
|
8
|
+
}
|
|
9
|
+
function readSeed(key) {
|
|
10
|
+
if (typeof window === "undefined") return void 0;
|
|
11
|
+
const data = getServerData();
|
|
12
|
+
return data ? data[SEED_PREFIX + key] : void 0;
|
|
13
|
+
}
|
|
14
|
+
function createIsomorphicState(key, options) {
|
|
15
|
+
const seed = readSeed(key);
|
|
16
|
+
const initial = seed !== void 0 ? seed : typeof window !== "undefined" && options.client ? options.client() : options.fallback;
|
|
17
|
+
const [value, set] = createSignal(initial);
|
|
18
|
+
registry().set(key, { server: options.server, set });
|
|
19
|
+
return { value, set, key };
|
|
20
|
+
}
|
|
21
|
+
function createIsomorphicStore(key, options) {
|
|
22
|
+
const seeded = readSeed(key) !== void 0;
|
|
23
|
+
const base = createIsomorphicState(key, {
|
|
24
|
+
server: options.server,
|
|
25
|
+
fallback: options.fallback
|
|
26
|
+
});
|
|
27
|
+
const value = () => base.value() ?? options.fallback;
|
|
28
|
+
const persistWrite = (v) => {
|
|
29
|
+
if (!options.persist || typeof localStorage === "undefined") return;
|
|
30
|
+
try {
|
|
31
|
+
localStorage.setItem(options.persist, JSON.stringify(v));
|
|
32
|
+
} catch {
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const set = (v) => {
|
|
36
|
+
base.set(v);
|
|
37
|
+
persistWrite(v);
|
|
38
|
+
};
|
|
39
|
+
const setField = (k, val) => {
|
|
40
|
+
set({ ...value(), [k]: val });
|
|
41
|
+
};
|
|
42
|
+
const fields = {};
|
|
43
|
+
for (const k of Object.keys(options.fallback)) {
|
|
44
|
+
fields[k] = createMemo(() => value()[k]);
|
|
45
|
+
}
|
|
46
|
+
let initPromise = null;
|
|
47
|
+
const ensureInit = () => {
|
|
48
|
+
if (seeded || !options.client) return Promise.resolve();
|
|
49
|
+
if (!initPromise) {
|
|
50
|
+
initPromise = Promise.resolve(options.client()).then((v) => {
|
|
51
|
+
set(v);
|
|
52
|
+
}).catch((e) => {
|
|
53
|
+
initPromise = null;
|
|
54
|
+
throw e;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return initPromise;
|
|
58
|
+
};
|
|
59
|
+
return { value, fields, set, setField, ensureInit, key };
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
createIsomorphicState,
|
|
63
|
+
createIsomorphicStore
|
|
64
|
+
};
|
|
@@ -1 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
/*! @fluixi/core v1.0.0-alpha.85 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __copyProps = (to, from, except, desc) => {
|
|
8
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
9
|
+
for (let key of __getOwnPropNames(from))
|
|
10
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
11
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
12
|
+
}
|
|
13
|
+
return to;
|
|
14
|
+
};
|
|
15
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
16
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
17
|
+
|
|
18
|
+
// src/lib/jsx-runtime/index.ts
|
|
19
|
+
var index_exports = {};
|
|
20
|
+
module.exports = __toCommonJS(index_exports);
|
|
21
|
+
__reExport(index_exports, require("@fluixi/jsx/jsx-runtime"), module.exports);
|
|
@@ -8,6 +8,6 @@ export type { JSX } from '@fluixi/jsx';
|
|
|
8
8
|
* any file imports from fluixi, because TypeScript processes declare global
|
|
9
9
|
* from all transitively-loaded modules.
|
|
10
10
|
*
|
|
11
|
-
* Pattern: same as SolidJS
|
|
11
|
+
* Pattern: same as SolidJS, the framework's main entry carries the global augmentation.
|
|
12
12
|
*/
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -7,17 +7,7 @@ export * from '@fluixi/jsx/jsx-runtime';
|
|
|
7
7
|
* any file imports from fluixi, because TypeScript processes declare global
|
|
8
8
|
* from all transitively-loaded modules.
|
|
9
9
|
*
|
|
10
|
-
* Pattern: same as SolidJS
|
|
10
|
+
* Pattern: same as SolidJS, the framework's main entry carries the global augmentation.
|
|
11
11
|
*/
|
|
12
12
|
// declare global {
|
|
13
13
|
// namespace JSX {
|
|
14
|
-
// type Element = FluixiJSX.Element;
|
|
15
|
-
// interface IntrinsicElements extends FluixiJSX.IntrinsicElements {}
|
|
16
|
-
// interface ElementChildrenAttribute {
|
|
17
|
-
// children: {};
|
|
18
|
-
// }
|
|
19
|
-
// interface IntrinsicAttributes {
|
|
20
|
-
// key?: string | number;
|
|
21
|
-
// }
|
|
22
|
-
// }
|
|
23
|
-
// }
|
|
@@ -1 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
/*! @fluixi/core v1.0.0-alpha.85 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __copyProps = (to, from, except, desc) => {
|
|
8
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
9
|
+
for (let key of __getOwnPropNames(from))
|
|
10
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
11
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
12
|
+
}
|
|
13
|
+
return to;
|
|
14
|
+
};
|
|
15
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
16
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
17
|
+
|
|
18
|
+
// src/lib/jsx-runtime/jsx-dev-runtime.ts
|
|
19
|
+
var jsx_dev_runtime_exports = {};
|
|
20
|
+
module.exports = __toCommonJS(jsx_dev_runtime_exports);
|
|
21
|
+
__reExport(jsx_dev_runtime_exports, require("@fluixi/jsx/jsx-dev-runtime"), module.exports);
|