@fluixi/core 1.0.0-alpha.92 → 1.0.0-alpha.93
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 -2
- package/dist/src/cdn/{chunk-MDJLC3PE.mjs → chunk-7XM7Q5VR.mjs} +271 -229
- package/dist/src/cdn/core.cjs +360 -253
- package/dist/src/cdn/core.mjs +92 -20
- package/dist/src/cdn/{router-JYFZP3EZ.mjs → router-VOY43YNM.mjs} +7 -3
- package/dist/src/index.cjs +547 -232
- package/dist/src/index.mjs +547 -223
- package/dist/src/lib/client/chunk-QT3RFKH6.mjs +53 -0
- package/dist/src/lib/client/index.cjs +310 -176
- package/dist/src/lib/client/index.d.ts.map +1 -1
- package/dist/src/lib/client/index.js +33 -18
- package/dist/src/lib/client/index.mjs +86 -15
- package/dist/src/lib/client/{router-PHLUYVQU.mjs → router-ADTS55OP.mjs} +244 -99
- package/dist/src/lib/context/context.cjs +35 -72
- package/dist/src/lib/context/context.d.ts +45 -291
- package/dist/src/lib/context/context.d.ts.map +1 -1
- package/dist/src/lib/context/context.js +65 -397
- package/dist/src/lib/context/context.mjs +38 -73
- package/dist/src/lib/context/index.cjs +35 -72
- package/dist/src/lib/context/index.d.ts +2 -2
- package/dist/src/lib/context/index.d.ts.map +1 -1
- package/dist/src/lib/context/index.js +1 -5
- package/dist/src/lib/context/index.mjs +38 -73
- package/dist/src/lib/core.cjs +546 -231
- package/dist/src/lib/core.d.ts +3 -1
- package/dist/src/lib/core.d.ts.map +1 -1
- package/dist/src/lib/core.js +5 -3
- package/dist/src/lib/core.mjs +546 -222
- package/dist/src/lib/env/index.cjs +1 -17
- package/dist/src/lib/env/index.d.ts +2 -14
- package/dist/src/lib/env/index.d.ts.map +1 -1
- package/dist/src/lib/env/index.js +2 -26
- package/dist/src/lib/env/index.mjs +1 -17
- package/dist/src/lib/i18n/index.cjs +17 -2
- package/dist/src/lib/i18n/index.d.ts +10 -0
- package/dist/src/lib/i18n/index.d.ts.map +1 -1
- package/dist/src/lib/i18n/index.js +17 -1
- package/dist/src/lib/i18n/index.mjs +17 -2
- package/dist/src/lib/index.cjs +64 -99
- package/dist/src/lib/index.mjs +43 -76
- package/dist/src/lib/isomorphic.cjs +9 -4
- package/dist/src/lib/isomorphic.d.ts +9 -2
- package/dist/src/lib/isomorphic.d.ts.map +1 -1
- package/dist/src/lib/isomorphic.js +11 -4
- package/dist/src/lib/isomorphic.mjs +9 -4
- package/dist/src/lib/jsx-runtime/index.cjs +1 -1
- package/dist/src/lib/jsx-runtime/index.mjs +1 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -1
- package/dist/src/lib/plugins/fluixi-routes-plugin.cjs +2 -2
- package/dist/src/lib/plugins/fluixi-routes-plugin.mjs +2 -2
- package/dist/src/lib/plugins/index.cjs +3 -3
- package/dist/src/lib/plugins/index.mjs +3 -3
- package/dist/src/lib/plugins/route-codegen.cjs +2 -2
- package/dist/src/lib/plugins/route-codegen.js +1 -1
- package/dist/src/lib/plugins/route-codegen.mjs +2 -2
- package/dist/src/lib/render/index.cjs +1 -1
- package/dist/src/lib/render/index.mjs +1 -1
- package/dist/src/lib/render/versions.cjs +1 -1
- package/dist/src/lib/render/versions.mjs +1 -1
- package/dist/src/lib/router/data.cjs +113 -115
- package/dist/src/lib/router/data.d.ts +63 -10
- package/dist/src/lib/router/data.d.ts.map +1 -1
- package/dist/src/lib/router/data.js +158 -68
- package/dist/src/lib/router/data.mjs +112 -112
- package/dist/src/lib/router/index.cjs +260 -163
- package/dist/src/lib/router/index.d.ts +22 -2
- package/dist/src/lib/router/index.d.ts.map +1 -1
- package/dist/src/lib/router/index.js +165 -22
- package/dist/src/lib/router/index.mjs +244 -143
- package/dist/src/lib/server/index.cjs +1 -1
- package/dist/src/lib/server/index.mjs +1 -1
- 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 +194 -37
- package/dist/src/lib/theme/index.d.ts +23 -11
- package/dist/src/lib/theme/index.d.ts.map +1 -1
- package/dist/src/lib/theme/index.js +73 -32
- package/dist/src/lib/theme/index.mjs +197 -35
- 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/routes.cjs +1 -1
- package/dist/src/routes.mjs +1 -1
- package/dist/src/utils.cjs +1 -1
- package/dist/src/utils.mjs +1 -1
- package/dist/src/version.generated.cjs +1 -1
- package/dist/src/version.generated.d.ts +1 -1
- package/dist/src/version.generated.js +1 -1
- package/dist/src/version.generated.mjs +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +18 -11
- package/dist/src/lib/client/chunk-VB567ABU.mjs +0 -133
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/core v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/core v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -21,85 +21,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
21
21
|
};
|
|
22
22
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
23
23
|
|
|
24
|
-
// src/lib/server/hydration.ts
|
|
25
|
-
function isHydrating() {
|
|
26
|
-
return hydrating;
|
|
27
|
-
}
|
|
28
|
-
function setHydrating(state) {
|
|
29
|
-
hydrating = state;
|
|
30
|
-
}
|
|
31
|
-
function setHydrationData(key, data) {
|
|
32
|
-
hydrationDataMap.set(key, data);
|
|
33
|
-
}
|
|
34
|
-
function getHydrationData(key) {
|
|
35
|
-
return hydrationDataMap.get(key);
|
|
36
|
-
}
|
|
37
|
-
function clearHydrationData() {
|
|
38
|
-
hydrationDataMap.clear();
|
|
39
|
-
}
|
|
40
|
-
function deserializeHydrationData() {
|
|
41
|
-
if (typeof window === "undefined") {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
const script = document.getElementById("__FLUIXI_HYDRATION__");
|
|
45
|
-
if (!script || script.getAttribute("type") !== "application/json") {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
const json = script.textContent || "{}";
|
|
50
|
-
const data = JSON.parse(json);
|
|
51
|
-
for (const [key, value] of Object.entries(data)) {
|
|
52
|
-
hydrationDataMap.set(key, value);
|
|
53
|
-
}
|
|
54
|
-
return true;
|
|
55
|
-
} catch (error) {
|
|
56
|
-
console.error("Failed to deserialize hydration data:", error);
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
function cleanupHydration() {
|
|
61
|
-
if (typeof window === "undefined") {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const script = document.getElementById("__FLUIXI_HYDRATION__");
|
|
65
|
-
if (script) {
|
|
66
|
-
script.remove();
|
|
67
|
-
}
|
|
68
|
-
const walker = document.createTreeWalker(
|
|
69
|
-
document.body,
|
|
70
|
-
NodeFilter.SHOW_COMMENT,
|
|
71
|
-
null
|
|
72
|
-
);
|
|
73
|
-
const comments = [];
|
|
74
|
-
let node;
|
|
75
|
-
while (node = walker.nextNode()) {
|
|
76
|
-
const comment = node;
|
|
77
|
-
const text = comment.nodeValue || "";
|
|
78
|
-
if (text.startsWith("#") || text.startsWith("/")) {
|
|
79
|
-
comments.push(comment);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
comments.forEach((comment) => comment.remove());
|
|
83
|
-
clearHydrationData();
|
|
84
|
-
}
|
|
85
|
-
function isServerEnvironment() {
|
|
86
|
-
return (0, import_dom3.isServer)();
|
|
87
|
-
}
|
|
88
|
-
var import_dom3, hydrating, hydrationDataMap;
|
|
89
|
-
var init_hydration = __esm({
|
|
90
|
-
"src/lib/server/hydration.ts"() {
|
|
91
|
-
"use strict";
|
|
92
|
-
import_dom3 = require("@fluixi/dom");
|
|
93
|
-
hydrating = false;
|
|
94
|
-
hydrationDataMap = /* @__PURE__ */ new Map();
|
|
95
|
-
if (typeof window !== "undefined") {
|
|
96
|
-
window.addEventListener("load", () => {
|
|
97
|
-
setTimeout(cleanupHydration, 100);
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
|
|
103
24
|
// src/lib/render/lazy.ts
|
|
104
25
|
function fromChunk(value) {
|
|
105
26
|
if (value != null && (typeof value === "object" || typeof value === "function")) {
|
|
@@ -206,107 +127,130 @@ var init_transition = __esm({
|
|
|
206
127
|
// src/lib/context/context.ts
|
|
207
128
|
function createContext3(defaultValue, name) {
|
|
208
129
|
const context = (0, import_signal7.createContext)(defaultValue, name);
|
|
209
|
-
const Provider = (props) =>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
130
|
+
const Provider = (props) => (
|
|
131
|
+
// Children stay a getter: the reactive Provider reads them after stamping the value on
|
|
132
|
+
// its owner. Reading `props.children` here would render them, and any <Outlet/> in them,
|
|
133
|
+
// before the context exists.
|
|
134
|
+
context.Provider({
|
|
213
135
|
value: props.value,
|
|
214
136
|
get children() {
|
|
215
137
|
return props.children;
|
|
216
138
|
},
|
|
217
139
|
debug: props.debug
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
if (typeof Symbol !== "undefined" && Symbol.for) {
|
|
221
|
-
Provider.$$typeof = /* @__PURE__ */ Symbol.for("react.provider");
|
|
222
|
-
}
|
|
223
|
-
Provider.$$typeof = /* @__PURE__ */ Symbol.for("react.provider");
|
|
140
|
+
})
|
|
141
|
+
);
|
|
224
142
|
return {
|
|
225
143
|
id: context.id,
|
|
226
144
|
Provider: (0, import_dom11.asProvider)(Provider),
|
|
227
145
|
defaultValue
|
|
228
146
|
};
|
|
229
147
|
}
|
|
230
|
-
var import_dom11, import_signal7
|
|
148
|
+
var import_dom11, import_signal7;
|
|
231
149
|
var init_context = __esm({
|
|
232
150
|
"src/lib/context/context.ts"() {
|
|
233
151
|
"use strict";
|
|
234
152
|
import_dom11 = require("@fluixi/dom");
|
|
235
153
|
import_signal7 = require("@fluixi/reactive/signal");
|
|
236
|
-
import_signal8 = require("@fluixi/reactive/signal");
|
|
237
154
|
}
|
|
238
155
|
});
|
|
239
156
|
|
|
240
157
|
// src/lib/router/data.ts
|
|
241
|
-
function
|
|
242
|
-
|
|
158
|
+
function onRevalidate(listener) {
|
|
159
|
+
revalidationListeners.add(listener);
|
|
160
|
+
return () => void revalidationListeners.delete(listener);
|
|
161
|
+
}
|
|
162
|
+
function cache(fn, name, options = {}) {
|
|
163
|
+
const { ttl = Infinity, staleWhileRevalidate = true } = options;
|
|
164
|
+
return (...args) => {
|
|
165
|
+
const store = options.cache ?? (0, import_signal9.currentResourceCache)();
|
|
243
166
|
const key = name + ":" + JSON.stringify(args);
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
if (
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const promise = Promise.resolve(fn(...args)).then(
|
|
257
|
-
(val) => {
|
|
258
|
-
globalCache.set(key, val);
|
|
259
|
-
inflightRequests.delete(key);
|
|
260
|
-
if (isServerEnvironment()) {
|
|
261
|
-
setHydrationData(key, val);
|
|
167
|
+
const fetchFresh = () => {
|
|
168
|
+
const running = store.inflight.get(key);
|
|
169
|
+
if (running) return running;
|
|
170
|
+
const promise = Promise.resolve(fn(...args)).then(
|
|
171
|
+
(value) => {
|
|
172
|
+
store.set(key, { value, timestamp: Date.now() });
|
|
173
|
+
store.inflight.delete(key);
|
|
174
|
+
return value;
|
|
175
|
+
},
|
|
176
|
+
(error) => {
|
|
177
|
+
store.inflight.delete(key);
|
|
178
|
+
throw error;
|
|
262
179
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
|
|
180
|
+
);
|
|
181
|
+
store.inflight.set(key, promise);
|
|
182
|
+
return promise;
|
|
183
|
+
};
|
|
184
|
+
const hit = store.get(key);
|
|
185
|
+
if (hit && (ttl === Infinity || Date.now() - hit.timestamp <= ttl)) return Promise.resolve(hit.value);
|
|
186
|
+
if (hit && staleWhileRevalidate) {
|
|
187
|
+
fetchFresh().then(reloadMounted, () => void 0);
|
|
188
|
+
return Promise.resolve(hit.value);
|
|
189
|
+
}
|
|
190
|
+
return fetchFresh();
|
|
272
191
|
};
|
|
273
192
|
}
|
|
274
|
-
function revalidate(key) {
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
193
|
+
function revalidate(key, store) {
|
|
194
|
+
const names = typeof key === "string" ? [key] : Array.isArray(key) ? key : null;
|
|
195
|
+
drop(names ?? key, store ?? (0, import_signal9.currentResourceCache)());
|
|
196
|
+
if (names && !store) tellOtherTabs(names);
|
|
197
|
+
}
|
|
198
|
+
function drop(what, store) {
|
|
199
|
+
const matches = Array.isArray(what) ? (k) => what.some((n) => k === n || k.startsWith(n + ":")) : what;
|
|
200
|
+
for (const k of [...store.keys()]) if (matches(k)) store.delete(k);
|
|
201
|
+
reloadMounted();
|
|
202
|
+
}
|
|
203
|
+
function tellOtherTabs(names) {
|
|
204
|
+
try {
|
|
205
|
+
localStorage.setItem(TABS_KEY, JSON.stringify({ names, at: Date.now() + Math.random() }));
|
|
206
|
+
} catch {
|
|
281
207
|
}
|
|
282
|
-
setRevalidationVersion((v) => v + 1);
|
|
283
208
|
}
|
|
284
209
|
function createAsync(fetcher, source) {
|
|
285
|
-
const [data] = (0,
|
|
210
|
+
const [data] = (0, import_signal8.createResource)(source || (() => true), fetcher);
|
|
286
211
|
return data;
|
|
287
212
|
}
|
|
288
213
|
function getSubmissionSignal(url) {
|
|
289
214
|
if (!submissionState.has(url)) {
|
|
290
215
|
submissionState.set(
|
|
291
216
|
url,
|
|
292
|
-
(0,
|
|
217
|
+
(0, import_signal8.createSignal)(void 0)
|
|
293
218
|
);
|
|
294
219
|
}
|
|
295
220
|
return submissionState.get(url);
|
|
296
221
|
}
|
|
297
|
-
function
|
|
222
|
+
function getSubmissionsSignal(url) {
|
|
223
|
+
if (!submissionsState.has(url)) submissionsState.set(url, (0, import_signal8.createSignal)([]));
|
|
224
|
+
return submissionsState.get(url);
|
|
225
|
+
}
|
|
226
|
+
function action(fn, name, options = {}) {
|
|
298
227
|
const actionUrl = name || fn.name || "action";
|
|
299
228
|
const submit = async (input) => {
|
|
300
229
|
const [, setSubmission] = getSubmissionSignal(actionUrl);
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
230
|
+
const [, setSubmissions] = getSubmissionsSignal(actionUrl);
|
|
231
|
+
let entry;
|
|
232
|
+
const drop2 = () => setSubmissions((list) => list.filter((s) => s !== entry));
|
|
233
|
+
const settle = (next) => {
|
|
234
|
+
setSubmissions((list) => list.map((s) => s === entry ? next : s));
|
|
235
|
+
entry = next;
|
|
236
|
+
};
|
|
237
|
+
const clear = () => {
|
|
238
|
+
setSubmission(void 0);
|
|
239
|
+
drop2();
|
|
240
|
+
};
|
|
241
|
+
const retry = () => {
|
|
242
|
+
drop2();
|
|
243
|
+
return submit(input);
|
|
244
|
+
};
|
|
245
|
+
entry = {
|
|
304
246
|
input,
|
|
305
247
|
// Approximate type for tracking
|
|
306
248
|
pending: true,
|
|
307
249
|
clear,
|
|
308
250
|
retry
|
|
309
|
-
}
|
|
251
|
+
};
|
|
252
|
+
setSubmission(entry);
|
|
253
|
+
setSubmissions((list) => [...list, entry]);
|
|
310
254
|
try {
|
|
311
255
|
const result = await fn(input);
|
|
312
256
|
setSubmission({
|
|
@@ -316,41 +260,63 @@ function action(fn, name) {
|
|
|
316
260
|
clear,
|
|
317
261
|
retry
|
|
318
262
|
});
|
|
263
|
+
drop2();
|
|
264
|
+
const stale = typeof options.invalidates === "function" ? options.invalidates(result) : options.invalidates;
|
|
265
|
+
for (const key of stale ?? []) revalidate(key);
|
|
319
266
|
return result;
|
|
320
267
|
} catch (error) {
|
|
321
|
-
|
|
268
|
+
const failed = {
|
|
322
269
|
input,
|
|
323
270
|
error,
|
|
324
271
|
pending: false,
|
|
325
272
|
clear,
|
|
326
273
|
retry
|
|
327
|
-
}
|
|
274
|
+
};
|
|
275
|
+
setSubmission(failed);
|
|
276
|
+
settle(failed);
|
|
328
277
|
throw error;
|
|
329
278
|
}
|
|
330
279
|
};
|
|
331
280
|
submit.url = actionUrl;
|
|
332
|
-
submit.with = (args) => action((...a) => fn(args, ...a), name);
|
|
281
|
+
submit.with = (args) => action((...a) => fn(args, ...a), name, options);
|
|
333
282
|
return submit;
|
|
334
283
|
}
|
|
335
284
|
function useSubmission(actionFn) {
|
|
336
285
|
const [submission] = getSubmissionSignal(actionFn.url);
|
|
337
286
|
return submission;
|
|
338
287
|
}
|
|
288
|
+
function useSubmissions(actionFn) {
|
|
289
|
+
const [submissions] = getSubmissionsSignal(actionFn.url);
|
|
290
|
+
return submissions;
|
|
291
|
+
}
|
|
339
292
|
function useAction(actionFn) {
|
|
340
293
|
return actionFn;
|
|
341
294
|
}
|
|
342
|
-
var
|
|
295
|
+
var import_signal8, import_signal9, revalidationListeners, reloadMounted, TABS_KEY, submissionState, submissionsState, RouteDataContext, RouteDataProvider;
|
|
343
296
|
var init_data = __esm({
|
|
344
297
|
"src/lib/router/data.ts"() {
|
|
345
298
|
"use strict";
|
|
299
|
+
import_signal8 = require("@fluixi/reactive/signal");
|
|
346
300
|
import_signal9 = require("@fluixi/reactive/signal");
|
|
347
|
-
init_hydration();
|
|
348
301
|
init_context();
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
302
|
+
revalidationListeners = /* @__PURE__ */ new Set();
|
|
303
|
+
reloadMounted = () => {
|
|
304
|
+
for (const listener of [...revalidationListeners]) listener();
|
|
305
|
+
};
|
|
306
|
+
TABS_KEY = "fluixi:revalidate";
|
|
307
|
+
if (typeof window !== "undefined") {
|
|
308
|
+
window.addEventListener("storage", (event) => {
|
|
309
|
+
if (event.key !== TABS_KEY || !event.newValue) return;
|
|
310
|
+
try {
|
|
311
|
+
const names = JSON.parse(event.newValue).names;
|
|
312
|
+
if (Array.isArray(names) && names.every((n) => typeof n === "string")) drop(names, (0, import_signal9.currentResourceCache)());
|
|
313
|
+
} catch {
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
globalThis[/* @__PURE__ */ Symbol.for("fluixi.revalidate")] = (names) => revalidate(names);
|
|
353
318
|
submissionState = /* @__PURE__ */ new Map();
|
|
319
|
+
submissionsState = /* @__PURE__ */ new Map();
|
|
354
320
|
RouteDataContext = createContext3(void 0, "route-data");
|
|
355
321
|
RouteDataProvider = RouteDataContext.Provider;
|
|
356
322
|
}
|
|
@@ -380,6 +346,7 @@ __export(router_exports, {
|
|
|
380
346
|
select: () => select,
|
|
381
347
|
supportsViewTransitions: () => supportsViewTransitions,
|
|
382
348
|
useAction: () => useAction,
|
|
349
|
+
useIsRouting: () => useIsRouting,
|
|
383
350
|
useLevelParams: () => useLevelParams,
|
|
384
351
|
useLinkNavigation: () => useLinkNavigation,
|
|
385
352
|
useLocation: () => useLocation,
|
|
@@ -391,7 +358,8 @@ __export(router_exports, {
|
|
|
391
358
|
useRouteData: () => useRouteData,
|
|
392
359
|
useRouter: () => useRouter,
|
|
393
360
|
useSearchParams: () => useSearchParams,
|
|
394
|
-
useSubmission: () => useSubmission
|
|
361
|
+
useSubmission: () => useSubmission,
|
|
362
|
+
useSubmissions: () => useSubmissions
|
|
395
363
|
});
|
|
396
364
|
function renderLayer(m, depth, base) {
|
|
397
365
|
let data;
|
|
@@ -402,10 +370,32 @@ function renderLayer(m, depth, base) {
|
|
|
402
370
|
cancelled = true;
|
|
403
371
|
});
|
|
404
372
|
const owner = (0, import_signal10.getOwner)();
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
)
|
|
408
|
-
|
|
373
|
+
const router = (0, import_signal11.useContext)(RouterContext);
|
|
374
|
+
let watching = false;
|
|
375
|
+
const trackDeps = (deps) => {
|
|
376
|
+
if (watching || cancelled) return;
|
|
377
|
+
watching = true;
|
|
378
|
+
(0, import_signal10.runWithOwner)(owner, () => {
|
|
379
|
+
let first = true;
|
|
380
|
+
(0, import_signal10.createEffect)(() => {
|
|
381
|
+
deps();
|
|
382
|
+
if (first) first = false;
|
|
383
|
+
else (0, import_signal10.untrack)(() => void refetch());
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
};
|
|
387
|
+
const [resource, { refetch }] = (0, import_signal10.createResource)(() => {
|
|
388
|
+
const result = loader({ params: base.params, location: base.location }, owner, () => cancelled, trackDeps);
|
|
389
|
+
return router ? router.trackLoad(result) : result;
|
|
390
|
+
});
|
|
391
|
+
(0, import_signal10.onCleanup)(onRevalidate(() => void refetch()));
|
|
392
|
+
data = () => {
|
|
393
|
+
const error = resource.error;
|
|
394
|
+
if (error !== void 0 && error !== null) throw error;
|
|
395
|
+
return resource();
|
|
396
|
+
};
|
|
397
|
+
Object.defineProperty(data, "loading", { get: () => resource.loading });
|
|
398
|
+
Object.defineProperty(data, "state", { get: () => resource.state });
|
|
409
399
|
}
|
|
410
400
|
const buildPage = () => RouteDataContext2.Provider({
|
|
411
401
|
value: data,
|
|
@@ -423,12 +413,15 @@ function renderLayer(m, depth, base) {
|
|
|
423
413
|
});
|
|
424
414
|
}
|
|
425
415
|
});
|
|
426
|
-
if (!data) return buildPage();
|
|
416
|
+
if (!data) return { view: buildPage(), ready: () => true };
|
|
427
417
|
const res = data;
|
|
428
|
-
const isLoading = () =>
|
|
418
|
+
const isLoading = () => {
|
|
419
|
+
const state = res.state;
|
|
420
|
+
return state === void 0 ? res.loading : state === "pending" || state === "unresolved";
|
|
421
|
+
};
|
|
429
422
|
const [ready, setReady] = (0, import_signal10.createSignal)((0, import_signal10.untrack)(() => !isLoading()));
|
|
430
423
|
(0, import_signal10.createEffect)(() => setReady(!isLoading()));
|
|
431
|
-
return (0, import_signal10.createMemo)(() => ready() ? buildPage() : null);
|
|
424
|
+
return { view: (0, import_signal10.createMemo)(() => ready() ? buildPage() : null), ready };
|
|
432
425
|
}
|
|
433
426
|
function renderChild(ctx) {
|
|
434
427
|
const childIdx = ctx.depth + 1;
|
|
@@ -439,17 +432,43 @@ function renderChild(ctx) {
|
|
|
439
432
|
const c = ctx.matched()[childIdx]?.component;
|
|
440
433
|
if ((0, import_signal10.untrack)(childComp) !== c) setChildComp(() => c);
|
|
441
434
|
});
|
|
442
|
-
|
|
435
|
+
const owner = (0, import_signal10.getOwner)();
|
|
436
|
+
let shown = null;
|
|
437
|
+
let pending = null;
|
|
438
|
+
const drop2 = (layer) => layer?.dispose();
|
|
439
|
+
(0, import_signal10.onCleanup)(() => {
|
|
440
|
+
drop2(shown);
|
|
441
|
+
drop2(pending);
|
|
442
|
+
shown = pending = null;
|
|
443
|
+
});
|
|
444
|
+
const incoming = (0, import_signal10.createMemo)(() => {
|
|
443
445
|
const component = childComp();
|
|
444
|
-
if (!component)
|
|
446
|
+
if (!component) return null;
|
|
447
|
+
const m = (0, import_signal10.untrack)(() => ctx.matched())[childIdx];
|
|
448
|
+
return (0, import_signal10.runWithOwner)(
|
|
449
|
+
owner,
|
|
450
|
+
() => (0, import_signal10.createRoot)((dispose) => ({
|
|
451
|
+
...renderLayer(m, childIdx, { matched: ctx.matched, params: ctx.params, location: ctx.location }),
|
|
452
|
+
dispose
|
|
453
|
+
}))
|
|
454
|
+
);
|
|
455
|
+
});
|
|
456
|
+
return (0, import_signal10.createMemo)(() => {
|
|
457
|
+
const next = incoming();
|
|
458
|
+
if (!next) {
|
|
459
|
+
drop2(shown);
|
|
460
|
+
drop2(pending);
|
|
461
|
+
shown = pending = null;
|
|
445
462
|
return ctx.notFound ? ctx.notFound() : null;
|
|
446
463
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
464
|
+
if (next === shown) return shown.view;
|
|
465
|
+
if (pending && pending !== next) drop2(pending);
|
|
466
|
+
pending = next;
|
|
467
|
+
if (shown && !next.ready()) return shown.view;
|
|
468
|
+
drop2(shown);
|
|
469
|
+
shown = next;
|
|
470
|
+
pending = null;
|
|
471
|
+
return shown.view;
|
|
453
472
|
});
|
|
454
473
|
}
|
|
455
474
|
function renderNotFound(notFound) {
|
|
@@ -483,6 +502,8 @@ function Router(props) {
|
|
|
483
502
|
history
|
|
484
503
|
});
|
|
485
504
|
const [state, setState] = (0, import_signal10.createSignal)(router.state());
|
|
505
|
+
const [navigating, setNavigating] = (0, import_signal10.createSignal)(false);
|
|
506
|
+
const [loads, setLoads] = (0, import_signal10.createSignal)(0);
|
|
486
507
|
let navigationId = 0;
|
|
487
508
|
const takeMode = () => {
|
|
488
509
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
@@ -492,12 +513,15 @@ function Router(props) {
|
|
|
492
513
|
const unsub = router.subscribe((next) => {
|
|
493
514
|
const id = ++navigationId;
|
|
494
515
|
const mode = takeMode();
|
|
516
|
+
setNavigating(true);
|
|
495
517
|
const prepared = prepareComponents(
|
|
496
518
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
497
519
|
);
|
|
498
520
|
const commit = () => {
|
|
499
521
|
setState(next);
|
|
500
|
-
|
|
522
|
+
const flushed = (0, import_signal10.flush)();
|
|
523
|
+
if (id === navigationId) setNavigating(false);
|
|
524
|
+
return flushed;
|
|
501
525
|
};
|
|
502
526
|
if (!prepared) {
|
|
503
527
|
void runTransition(mode, commit);
|
|
@@ -519,7 +543,18 @@ function Router(props) {
|
|
|
519
543
|
const ctx = {
|
|
520
544
|
router,
|
|
521
545
|
location: (0, import_signal10.createMemo)(() => state().location),
|
|
522
|
-
params: (0, import_signal10.createMemo)(() => state().match?.params ?? {})
|
|
546
|
+
params: (0, import_signal10.createMemo)(() => state().match?.params ?? {}),
|
|
547
|
+
isRouting: () => navigating() || loads() > 0,
|
|
548
|
+
// Counted by the promise, not by an owner: a load a newer navigation superseded still
|
|
549
|
+
// settles and uncounts itself, and a resource seeded from the server never calls it.
|
|
550
|
+
trackLoad(result) {
|
|
551
|
+
if (result && typeof result.finally === "function") {
|
|
552
|
+
setLoads((n) => n + 1);
|
|
553
|
+
void result.finally(() => setLoads((n) => n - 1)).catch(() => {
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
return result;
|
|
557
|
+
}
|
|
523
558
|
};
|
|
524
559
|
const root = {
|
|
525
560
|
depth: -1,
|
|
@@ -542,6 +577,21 @@ function Outlet() {
|
|
|
542
577
|
if (!ctx) return null;
|
|
543
578
|
return renderChild(ctx);
|
|
544
579
|
}
|
|
580
|
+
function useIsRouting(options = {}) {
|
|
581
|
+
const routing = (0, import_signal11.useContext)(RouterContext)?.isRouting ?? (() => false);
|
|
582
|
+
const delay = options.delay ?? 0;
|
|
583
|
+
if (delay <= 0) return routing;
|
|
584
|
+
const [late, setLate] = (0, import_signal10.createSignal)(false);
|
|
585
|
+
(0, import_signal10.createEffect)(() => {
|
|
586
|
+
if (!routing()) {
|
|
587
|
+
setLate(false);
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
const timer = setTimeout(() => setLate(true), delay);
|
|
591
|
+
(0, import_signal10.onCleanup)(() => clearTimeout(timer));
|
|
592
|
+
});
|
|
593
|
+
return () => routing() && late();
|
|
594
|
+
}
|
|
545
595
|
function Redirect(props) {
|
|
546
596
|
const ctx = (0, import_signal11.useContext)(RouterContext);
|
|
547
597
|
if (ctx && typeof window !== "undefined") {
|
|
@@ -655,18 +705,31 @@ function useRouteData() {
|
|
|
655
705
|
}
|
|
656
706
|
function Link(props) {
|
|
657
707
|
const ctx = (0, import_signal11.useContext)(RouterContext);
|
|
658
|
-
const navigate = () => ctx
|
|
708
|
+
const navigate = () => ctx.router.navigate(read(props.href) ?? "", { replace: read(props.replace) });
|
|
659
709
|
const a = (0, import_dom12.createNativeElement)("a");
|
|
660
710
|
(0, import_dom12.setAttribute)(a, "href", read(props.href) ?? "");
|
|
661
711
|
if (props.slot) (0, import_dom12.setAttribute)(a, "slot", read(props.slot));
|
|
662
712
|
for (const k of Object.keys(props)) {
|
|
663
713
|
if (LINK_OWN_PROPS.has(k)) continue;
|
|
664
714
|
const v = props[k];
|
|
665
|
-
if (
|
|
715
|
+
if (typeof v === "function") {
|
|
716
|
+
if (/^on[A-Z]/.test(k)) continue;
|
|
717
|
+
const read2 = v;
|
|
718
|
+
const apply = () => {
|
|
719
|
+
const value = read2();
|
|
720
|
+
if (value == null || value === false) a.removeAttribute?.(k);
|
|
721
|
+
else (0, import_dom12.setAttribute)(a, k, String(value));
|
|
722
|
+
};
|
|
723
|
+
if (typeof a.addEventListener === "function") (0, import_signal10.createEffect)(apply);
|
|
724
|
+
else apply();
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
if (v != null) (0, import_dom12.setAttribute)(a, k, String(v));
|
|
666
728
|
}
|
|
667
729
|
if (typeof a.addEventListener === "function") {
|
|
668
730
|
a.addEventListener("click", (e) => {
|
|
669
731
|
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
732
|
+
if (!ctx) return;
|
|
670
733
|
e.preventDefault();
|
|
671
734
|
navigate();
|
|
672
735
|
});
|
|
@@ -737,6 +800,7 @@ var init_router = __esm({
|
|
|
737
800
|
import_object = require("@fluixi/utils/object");
|
|
738
801
|
import_compare = require("@fluixi/utils/compare");
|
|
739
802
|
import_router = require("@fluixi/router");
|
|
803
|
+
init_data();
|
|
740
804
|
import_router2 = require("@fluixi/router");
|
|
741
805
|
init_data();
|
|
742
806
|
init_lazy();
|
|
@@ -750,7 +814,9 @@ var init_router = __esm({
|
|
|
750
814
|
router: { navigate: () => {
|
|
751
815
|
} },
|
|
752
816
|
location: () => ({ pathname: "", search: "", hash: "", query: {} }),
|
|
753
|
-
params: () => ({})
|
|
817
|
+
params: () => ({}),
|
|
818
|
+
isRouting: () => false,
|
|
819
|
+
trackLoad: (result) => result
|
|
754
820
|
};
|
|
755
821
|
read = (v) => typeof v === "function" ? v() : v;
|
|
756
822
|
LINK_OWN_PROPS = /* @__PURE__ */ new Set([
|
|
@@ -781,14 +847,72 @@ var import_dom13 = require("@fluixi/dom");
|
|
|
781
847
|
var import_dom = require("@fluixi/dom");
|
|
782
848
|
|
|
783
849
|
// src/version.generated.ts
|
|
784
|
-
var VERSION = "1.0.0-alpha.
|
|
850
|
+
var VERSION = "1.0.0-alpha.93";
|
|
785
851
|
|
|
786
852
|
// src/lib/render/versions.ts
|
|
787
853
|
var import_dom2 = require("@fluixi/dom");
|
|
788
854
|
(0, import_dom.registerCoreVersion)(VERSION);
|
|
789
855
|
|
|
790
|
-
// src/lib/
|
|
791
|
-
|
|
856
|
+
// src/lib/server/hydration.ts
|
|
857
|
+
var import_dom3 = require("@fluixi/dom");
|
|
858
|
+
var hydrating = false;
|
|
859
|
+
var hydrationDataMap = /* @__PURE__ */ new Map();
|
|
860
|
+
function setHydrating(state) {
|
|
861
|
+
hydrating = state;
|
|
862
|
+
}
|
|
863
|
+
function clearHydrationData() {
|
|
864
|
+
hydrationDataMap.clear();
|
|
865
|
+
}
|
|
866
|
+
function deserializeHydrationData() {
|
|
867
|
+
if (typeof window === "undefined") {
|
|
868
|
+
return false;
|
|
869
|
+
}
|
|
870
|
+
const script = document.getElementById("__FLUIXI_HYDRATION__");
|
|
871
|
+
if (!script || script.getAttribute("type") !== "application/json") {
|
|
872
|
+
return false;
|
|
873
|
+
}
|
|
874
|
+
try {
|
|
875
|
+
const json = script.textContent || "{}";
|
|
876
|
+
const data = JSON.parse(json);
|
|
877
|
+
for (const [key, value] of Object.entries(data)) {
|
|
878
|
+
hydrationDataMap.set(key, value);
|
|
879
|
+
}
|
|
880
|
+
return true;
|
|
881
|
+
} catch (error) {
|
|
882
|
+
console.error("Failed to deserialize hydration data:", error);
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function cleanupHydration() {
|
|
887
|
+
if (typeof window === "undefined") {
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
const script = document.getElementById("__FLUIXI_HYDRATION__");
|
|
891
|
+
if (script) {
|
|
892
|
+
script.remove();
|
|
893
|
+
}
|
|
894
|
+
const walker = document.createTreeWalker(
|
|
895
|
+
document.body,
|
|
896
|
+
NodeFilter.SHOW_COMMENT,
|
|
897
|
+
null
|
|
898
|
+
);
|
|
899
|
+
const comments = [];
|
|
900
|
+
let node;
|
|
901
|
+
while (node = walker.nextNode()) {
|
|
902
|
+
const comment = node;
|
|
903
|
+
const text = comment.nodeValue || "";
|
|
904
|
+
if (text.startsWith("#") || text.startsWith("/")) {
|
|
905
|
+
comments.push(comment);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
comments.forEach((comment) => comment.remove());
|
|
909
|
+
clearHydrationData();
|
|
910
|
+
}
|
|
911
|
+
if (typeof window !== "undefined") {
|
|
912
|
+
window.addEventListener("load", () => {
|
|
913
|
+
setTimeout(cleanupHydration, 100);
|
|
914
|
+
});
|
|
915
|
+
}
|
|
792
916
|
|
|
793
917
|
// src/lib/render/index.ts
|
|
794
918
|
var import_dom9 = require("@fluixi/dom");
|
|
@@ -921,16 +1045,26 @@ async function startClient(App, options = {}) {
|
|
|
921
1045
|
(0, import_head.setActiveHead)(head);
|
|
922
1046
|
(0, import_head.stripHeadMarker)(container);
|
|
923
1047
|
if (shouldHydrate) {
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
1048
|
+
(0, import_dom13.beginAppHydration)();
|
|
1049
|
+
try {
|
|
1050
|
+
if (options.routes && options.routes.length) {
|
|
1051
|
+
const { preloadRoutes: preloadRoutes2 } = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
1052
|
+
await preloadRoutes2(options.routes, window.location.pathname);
|
|
1053
|
+
}
|
|
1054
|
+
deserializeHydrationData();
|
|
1055
|
+
setHydrating(true);
|
|
1056
|
+
(0, import_dom13.hydrate)(rootOf(App), container);
|
|
1057
|
+
replayEvents();
|
|
1058
|
+
} finally {
|
|
1059
|
+
(0, import_dom13.endAppHydration)();
|
|
927
1060
|
}
|
|
928
|
-
deserializeHydrationData();
|
|
929
|
-
setHydrating(true);
|
|
930
|
-
(0, import_dom13.hydrate)(rootOf(App), container);
|
|
931
|
-
replayEvents();
|
|
932
1061
|
setTimeout(() => {
|
|
933
1062
|
setHydrating(false);
|
|
1063
|
+
const removed = (0, import_dom13.removeUnclaimedKeyed)(container);
|
|
1064
|
+
if (removed && typeof process !== "undefined" && false) {
|
|
1065
|
+
console.warn(`[fluixi] hydration: removed ${removed} server element(s) the client did not render. Check for markup that depends on client-only state.`);
|
|
1066
|
+
}
|
|
1067
|
+
(0, import_dom13.clearHydrationKeys)();
|
|
934
1068
|
cleanupHydration();
|
|
935
1069
|
}, 100);
|
|
936
1070
|
} else {
|