@fluixi/core 1.0.0-alpha.92 → 1.0.0-alpha.94
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 +548 -232
- package/dist/src/index.mjs +549 -224
- package/dist/src/lib/client/chunk-TSXM2PNY.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-BDVPLLYX.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 +547 -231
- package/dist/src/lib/core.d.ts +5 -3
- package/dist/src/lib/core.d.ts.map +1 -1
- package/dist/src/lib/core.js +6 -4
- package/dist/src/lib/core.mjs +548 -223
- 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
|
@@ -18,8 +18,10 @@ import {
|
|
|
18
18
|
createMemo as createMemo2,
|
|
19
19
|
createResource as createResource3,
|
|
20
20
|
createEffect,
|
|
21
|
-
|
|
21
|
+
createRoot,
|
|
22
|
+
getOwner as getOwner2,
|
|
22
23
|
onCleanup,
|
|
24
|
+
runWithOwner,
|
|
23
25
|
untrack as untrack2,
|
|
24
26
|
flush
|
|
25
27
|
} from "@fluixi/reactive/signal";
|
|
@@ -88,172 +90,35 @@ import {
|
|
|
88
90
|
matchRoutes,
|
|
89
91
|
matchPath
|
|
90
92
|
} from "@fluixi/router";
|
|
91
|
-
import {
|
|
92
|
-
createMemoryHistory,
|
|
93
|
-
createBrowserHistory as createBrowserHistory2,
|
|
94
|
-
matchRoutes as matchRoutes2,
|
|
95
|
-
matchPath as matchPath2
|
|
96
|
-
} from "@fluixi/router";
|
|
97
93
|
|
|
98
94
|
// src/lib/router/data.ts
|
|
99
95
|
import {
|
|
100
96
|
createResource,
|
|
101
97
|
createSignal
|
|
102
98
|
} from "@fluixi/reactive/signal";
|
|
103
|
-
|
|
104
|
-
// src/lib/server/hydration.ts
|
|
105
|
-
import { isServer as domIsServer } from "@fluixi/dom";
|
|
106
|
-
var hydrating = false;
|
|
107
|
-
var hydrationDataMap = /* @__PURE__ */ new Map();
|
|
108
|
-
function isHydrating() {
|
|
109
|
-
return hydrating;
|
|
110
|
-
}
|
|
111
|
-
function setHydrating(state) {
|
|
112
|
-
hydrating = state;
|
|
113
|
-
}
|
|
114
|
-
function setHydrationData(key, data) {
|
|
115
|
-
hydrationDataMap.set(key, data);
|
|
116
|
-
}
|
|
117
|
-
function getHydrationData(key) {
|
|
118
|
-
return hydrationDataMap.get(key);
|
|
119
|
-
}
|
|
120
|
-
function clearHydrationData() {
|
|
121
|
-
hydrationDataMap.clear();
|
|
122
|
-
}
|
|
123
|
-
function deserializeHydrationData() {
|
|
124
|
-
if (typeof window === "undefined") {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
const script = document.getElementById("__FLUIXI_HYDRATION__");
|
|
128
|
-
if (!script || script.getAttribute("type") !== "application/json") {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
try {
|
|
132
|
-
const json = script.textContent || "{}";
|
|
133
|
-
const data = JSON.parse(json);
|
|
134
|
-
for (const [key, value] of Object.entries(data)) {
|
|
135
|
-
hydrationDataMap.set(key, value);
|
|
136
|
-
}
|
|
137
|
-
return true;
|
|
138
|
-
} catch (error) {
|
|
139
|
-
console.error("Failed to deserialize hydration data:", error);
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
function cleanupHydration() {
|
|
144
|
-
if (typeof window === "undefined") {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
const script = document.getElementById("__FLUIXI_HYDRATION__");
|
|
148
|
-
if (script) {
|
|
149
|
-
script.remove();
|
|
150
|
-
}
|
|
151
|
-
const walker = document.createTreeWalker(
|
|
152
|
-
document.body,
|
|
153
|
-
NodeFilter.SHOW_COMMENT,
|
|
154
|
-
null
|
|
155
|
-
);
|
|
156
|
-
const comments = [];
|
|
157
|
-
let node;
|
|
158
|
-
while (node = walker.nextNode()) {
|
|
159
|
-
const comment = node;
|
|
160
|
-
const text = comment.nodeValue || "";
|
|
161
|
-
if (text.startsWith("#") || text.startsWith("/")) {
|
|
162
|
-
comments.push(comment);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
comments.forEach((comment) => comment.remove());
|
|
166
|
-
clearHydrationData();
|
|
167
|
-
}
|
|
168
|
-
if (typeof window !== "undefined") {
|
|
169
|
-
window.addEventListener("load", () => {
|
|
170
|
-
setTimeout(cleanupHydration, 100);
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
function isServerEnvironment() {
|
|
174
|
-
return domIsServer();
|
|
175
|
-
}
|
|
99
|
+
import { currentResourceCache } from "@fluixi/reactive/signal";
|
|
176
100
|
|
|
177
101
|
// src/lib/context/context.ts
|
|
178
102
|
import { asProvider } from "@fluixi/dom";
|
|
179
|
-
import { createContext as createReactiveContext, useContext as useReactiveContext } from "@fluixi/reactive/signal";
|
|
180
103
|
import {
|
|
181
|
-
|
|
104
|
+
createContext as createReactiveContext,
|
|
105
|
+
getOwner,
|
|
106
|
+
useContext as useReactiveContext
|
|
182
107
|
} from "@fluixi/reactive/signal";
|
|
183
|
-
var _warnedEagerProvider = false;
|
|
184
|
-
function warnEagerProvider() {
|
|
185
|
-
if (_warnedEagerProvider) return;
|
|
186
|
-
_warnedEagerProvider = true;
|
|
187
|
-
if (typeof process !== "undefined" && true) return;
|
|
188
|
-
console.warn(
|
|
189
|
-
"[fluixi] createProvider({ context, value, children }) reads `children` eagerly: the object literal materialises `children` BEFORE the context is stamped, so a routed <Outlet/> that has siblings inside the provider renders detached and its descendants see no context under SSR. Use the lazy form instead:\n createProvider(Context, value, props) // children stays a getter\n // or JSX: <Context.Provider value={...}>{props.children}</Context.Provider>"
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
function createProvider(a, value, childProps) {
|
|
193
|
-
const isLazyForm = !!a?.Provider;
|
|
194
|
-
const context = isLazyForm ? a : a.context;
|
|
195
|
-
const rawValue = isLazyForm ? value : a.value;
|
|
196
|
-
const debug = isLazyForm ? false : a.debug ?? false;
|
|
197
|
-
if (!isLazyForm) warnEagerProvider();
|
|
198
|
-
const resolvedValue = typeof rawValue === "function" ? rawValue() : rawValue;
|
|
199
|
-
const sourceProps = isLazyForm ? childProps : a;
|
|
200
|
-
return context.Provider({
|
|
201
|
-
value: resolvedValue,
|
|
202
|
-
get children() {
|
|
203
|
-
return sourceProps?.children;
|
|
204
|
-
},
|
|
205
|
-
debug
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
function createContextWithProvider(defaultValue) {
|
|
209
|
-
const context = createContext(defaultValue);
|
|
210
|
-
const provider = (props) => {
|
|
211
|
-
return createProvider(context, props.value, props);
|
|
212
|
-
};
|
|
213
|
-
return [context, provider];
|
|
214
|
-
}
|
|
215
|
-
function composeProviders(contexts, children) {
|
|
216
|
-
if (contexts.length === 0) {
|
|
217
|
-
return readChildren(() => children);
|
|
218
|
-
}
|
|
219
|
-
const [context, value] = contexts[0];
|
|
220
|
-
const remaining = contexts.slice(1);
|
|
221
|
-
return createProvider(context, value, {
|
|
222
|
-
get children() {
|
|
223
|
-
return composeProviders(remaining, children);
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
function createConsumer(context) {
|
|
228
|
-
return (props) => {
|
|
229
|
-
const value = useContext(context);
|
|
230
|
-
return props.children(value);
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function useProvide(context, factory) {
|
|
234
|
-
const existing = useContext(context);
|
|
235
|
-
if (existing === context.defaultValue) {
|
|
236
|
-
return factory();
|
|
237
|
-
}
|
|
238
|
-
return existing;
|
|
239
|
-
}
|
|
240
108
|
function createContext(defaultValue, name) {
|
|
241
109
|
const context = createReactiveContext(defaultValue, name);
|
|
242
|
-
const Provider = (props) =>
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
110
|
+
const Provider = (props) => (
|
|
111
|
+
// Children stay a getter: the reactive Provider reads them after stamping the value on
|
|
112
|
+
// its owner. Reading `props.children` here would render them, and any <Outlet/> in them,
|
|
113
|
+
// before the context exists.
|
|
114
|
+
context.Provider({
|
|
246
115
|
value: props.value,
|
|
247
116
|
get children() {
|
|
248
117
|
return props.children;
|
|
249
118
|
},
|
|
250
119
|
debug: props.debug
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
if (typeof Symbol !== "undefined" && Symbol.for) {
|
|
254
|
-
Provider.$$typeof = /* @__PURE__ */ Symbol.for("react.provider");
|
|
255
|
-
}
|
|
256
|
-
Provider.$$typeof = /* @__PURE__ */ Symbol.for("react.provider");
|
|
120
|
+
})
|
|
121
|
+
);
|
|
257
122
|
return {
|
|
258
123
|
id: context.id,
|
|
259
124
|
Provider: asProvider(Provider),
|
|
@@ -264,55 +129,101 @@ function useContext(context) {
|
|
|
264
129
|
const value = useReactiveContext(context);
|
|
265
130
|
return value !== void 0 ? value : context.defaultValue;
|
|
266
131
|
}
|
|
132
|
+
function createProvider(context, value, props) {
|
|
133
|
+
const resolved = typeof value === "function" ? value() : value;
|
|
134
|
+
return context.Provider({
|
|
135
|
+
value: resolved,
|
|
136
|
+
get children() {
|
|
137
|
+
return props.children;
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function composeProviders(providers, props) {
|
|
142
|
+
const outermost = providers.reduceRight(
|
|
143
|
+
(inner, [context, value]) => ({
|
|
144
|
+
get children() {
|
|
145
|
+
return createProvider(context, value, inner);
|
|
146
|
+
}
|
|
147
|
+
}),
|
|
148
|
+
props
|
|
149
|
+
);
|
|
150
|
+
return outermost.children;
|
|
151
|
+
}
|
|
152
|
+
function requireContext(context, message) {
|
|
153
|
+
for (let owner = getOwner(); owner; owner = owner.parent) {
|
|
154
|
+
if (owner.contexts?.has(context.id)) return useContext(context);
|
|
155
|
+
}
|
|
156
|
+
throw new Error(message ?? `[fluixi] No Provider for ${context.id.description ?? "this context"} above this component.`);
|
|
157
|
+
}
|
|
267
158
|
|
|
268
159
|
// src/lib/router/data.ts
|
|
269
|
-
var
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
return
|
|
160
|
+
var revalidationListeners = /* @__PURE__ */ new Set();
|
|
161
|
+
function onRevalidate(listener) {
|
|
162
|
+
revalidationListeners.add(listener);
|
|
163
|
+
return () => void revalidationListeners.delete(listener);
|
|
164
|
+
}
|
|
165
|
+
var reloadMounted = () => {
|
|
166
|
+
for (const listener of [...revalidationListeners]) listener();
|
|
167
|
+
};
|
|
168
|
+
function cache(fn, name, options = {}) {
|
|
169
|
+
const { ttl = Infinity, staleWhileRevalidate = true } = options;
|
|
170
|
+
return (...args) => {
|
|
171
|
+
const store = options.cache ?? currentResourceCache();
|
|
273
172
|
const key = name + ":" + JSON.stringify(args);
|
|
274
|
-
|
|
275
|
-
const
|
|
276
|
-
if (
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const promise = Promise.resolve(fn(...args)).then(
|
|
287
|
-
(val) => {
|
|
288
|
-
globalCache.set(key, val);
|
|
289
|
-
inflightRequests.delete(key);
|
|
290
|
-
if (isServerEnvironment()) {
|
|
291
|
-
setHydrationData(key, val);
|
|
173
|
+
const fetchFresh = () => {
|
|
174
|
+
const running = store.inflight.get(key);
|
|
175
|
+
if (running) return running;
|
|
176
|
+
const promise = Promise.resolve(fn(...args)).then(
|
|
177
|
+
(value) => {
|
|
178
|
+
store.set(key, { value, timestamp: Date.now() });
|
|
179
|
+
store.inflight.delete(key);
|
|
180
|
+
return value;
|
|
181
|
+
},
|
|
182
|
+
(error) => {
|
|
183
|
+
store.inflight.delete(key);
|
|
184
|
+
throw error;
|
|
292
185
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
|
|
186
|
+
);
|
|
187
|
+
store.inflight.set(key, promise);
|
|
188
|
+
return promise;
|
|
189
|
+
};
|
|
190
|
+
const hit = store.get(key);
|
|
191
|
+
if (hit && (ttl === Infinity || Date.now() - hit.timestamp <= ttl)) return Promise.resolve(hit.value);
|
|
192
|
+
if (hit && staleWhileRevalidate) {
|
|
193
|
+
fetchFresh().then(reloadMounted, () => void 0);
|
|
194
|
+
return Promise.resolve(hit.value);
|
|
195
|
+
}
|
|
196
|
+
return fetchFresh();
|
|
302
197
|
};
|
|
303
198
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
199
|
+
function revalidate(key, store) {
|
|
200
|
+
const names = typeof key === "string" ? [key] : Array.isArray(key) ? key : null;
|
|
201
|
+
drop(names ?? key, store ?? currentResourceCache());
|
|
202
|
+
if (names && !store) tellOtherTabs(names);
|
|
203
|
+
}
|
|
204
|
+
function drop(what, store) {
|
|
205
|
+
const matches = Array.isArray(what) ? (k) => what.some((n) => k === n || k.startsWith(n + ":")) : what;
|
|
206
|
+
for (const k of [...store.keys()]) if (matches(k)) store.delete(k);
|
|
207
|
+
reloadMounted();
|
|
208
|
+
}
|
|
209
|
+
var TABS_KEY = "fluixi:revalidate";
|
|
210
|
+
function tellOtherTabs(names) {
|
|
211
|
+
try {
|
|
212
|
+
localStorage.setItem(TABS_KEY, JSON.stringify({ names, at: Date.now() + Math.random() }));
|
|
213
|
+
} catch {
|
|
313
214
|
}
|
|
314
|
-
setRevalidationVersion((v) => v + 1);
|
|
315
215
|
}
|
|
216
|
+
if (typeof window !== "undefined") {
|
|
217
|
+
window.addEventListener("storage", (event) => {
|
|
218
|
+
if (event.key !== TABS_KEY || !event.newValue) return;
|
|
219
|
+
try {
|
|
220
|
+
const names = JSON.parse(event.newValue).names;
|
|
221
|
+
if (Array.isArray(names) && names.every((n) => typeof n === "string")) drop(names, currentResourceCache());
|
|
222
|
+
} catch {
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
globalThis[/* @__PURE__ */ Symbol.for("fluixi.revalidate")] = (names) => revalidate(names);
|
|
316
227
|
function createAsync(fetcher, source) {
|
|
317
228
|
const [data] = createResource(source || (() => true), fetcher);
|
|
318
229
|
return data;
|
|
@@ -327,19 +238,39 @@ function getSubmissionSignal(url) {
|
|
|
327
238
|
}
|
|
328
239
|
return submissionState.get(url);
|
|
329
240
|
}
|
|
330
|
-
|
|
241
|
+
var submissionsState = /* @__PURE__ */ new Map();
|
|
242
|
+
function getSubmissionsSignal(url) {
|
|
243
|
+
if (!submissionsState.has(url)) submissionsState.set(url, createSignal([]));
|
|
244
|
+
return submissionsState.get(url);
|
|
245
|
+
}
|
|
246
|
+
function action(fn, name, options = {}) {
|
|
331
247
|
const actionUrl = name || fn.name || "action";
|
|
332
248
|
const submit = async (input) => {
|
|
333
249
|
const [, setSubmission] = getSubmissionSignal(actionUrl);
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
250
|
+
const [, setSubmissions] = getSubmissionsSignal(actionUrl);
|
|
251
|
+
let entry;
|
|
252
|
+
const drop2 = () => setSubmissions((list) => list.filter((s) => s !== entry));
|
|
253
|
+
const settle = (next) => {
|
|
254
|
+
setSubmissions((list) => list.map((s) => s === entry ? next : s));
|
|
255
|
+
entry = next;
|
|
256
|
+
};
|
|
257
|
+
const clear = () => {
|
|
258
|
+
setSubmission(void 0);
|
|
259
|
+
drop2();
|
|
260
|
+
};
|
|
261
|
+
const retry = () => {
|
|
262
|
+
drop2();
|
|
263
|
+
return submit(input);
|
|
264
|
+
};
|
|
265
|
+
entry = {
|
|
337
266
|
input,
|
|
338
267
|
// Approximate type for tracking
|
|
339
268
|
pending: true,
|
|
340
269
|
clear,
|
|
341
270
|
retry
|
|
342
|
-
}
|
|
271
|
+
};
|
|
272
|
+
setSubmission(entry);
|
|
273
|
+
setSubmissions((list) => [...list, entry]);
|
|
343
274
|
try {
|
|
344
275
|
const result = await fn(input);
|
|
345
276
|
setSubmission({
|
|
@@ -349,32 +280,49 @@ function action(fn, name) {
|
|
|
349
280
|
clear,
|
|
350
281
|
retry
|
|
351
282
|
});
|
|
283
|
+
drop2();
|
|
284
|
+
const stale = typeof options.invalidates === "function" ? options.invalidates(result) : options.invalidates;
|
|
285
|
+
for (const key of stale ?? []) revalidate(key);
|
|
352
286
|
return result;
|
|
353
287
|
} catch (error) {
|
|
354
|
-
|
|
288
|
+
const failed = {
|
|
355
289
|
input,
|
|
356
290
|
error,
|
|
357
291
|
pending: false,
|
|
358
292
|
clear,
|
|
359
293
|
retry
|
|
360
|
-
}
|
|
294
|
+
};
|
|
295
|
+
setSubmission(failed);
|
|
296
|
+
settle(failed);
|
|
361
297
|
throw error;
|
|
362
298
|
}
|
|
363
299
|
};
|
|
364
300
|
submit.url = actionUrl;
|
|
365
|
-
submit.with = (args) => action((...a) => fn(args, ...a), name);
|
|
301
|
+
submit.with = (args) => action((...a) => fn(args, ...a), name, options);
|
|
366
302
|
return submit;
|
|
367
303
|
}
|
|
368
304
|
function useSubmission(actionFn) {
|
|
369
305
|
const [submission] = getSubmissionSignal(actionFn.url);
|
|
370
306
|
return submission;
|
|
371
307
|
}
|
|
308
|
+
function useSubmissions(actionFn) {
|
|
309
|
+
const [submissions] = getSubmissionsSignal(actionFn.url);
|
|
310
|
+
return submissions;
|
|
311
|
+
}
|
|
372
312
|
function useAction(actionFn) {
|
|
373
313
|
return actionFn;
|
|
374
314
|
}
|
|
375
315
|
var RouteDataContext = createContext(void 0, "route-data");
|
|
376
316
|
var RouteDataProvider = RouteDataContext.Provider;
|
|
377
317
|
|
|
318
|
+
// src/lib/router/index.ts
|
|
319
|
+
import {
|
|
320
|
+
createMemoryHistory,
|
|
321
|
+
createBrowserHistory as createBrowserHistory2,
|
|
322
|
+
matchRoutes as matchRoutes2,
|
|
323
|
+
matchPath as matchPath2
|
|
324
|
+
} from "@fluixi/router";
|
|
325
|
+
|
|
378
326
|
// src/lib/render/lazy.ts
|
|
379
327
|
import { createComponent } from "@fluixi/dom";
|
|
380
328
|
import {
|
|
@@ -424,7 +372,7 @@ function lazy(loader, options) {
|
|
|
424
372
|
}
|
|
425
373
|
|
|
426
374
|
// src/lib/router/index.ts
|
|
427
|
-
import { runWithOwner } from "@fluixi/reactive/signal";
|
|
375
|
+
import { runWithOwner as runWithOwner2 } from "@fluixi/reactive/signal";
|
|
428
376
|
var RouterContext = createContext2(void 0, "router");
|
|
429
377
|
var OutletContext = createContext2(void 0, "outlet");
|
|
430
378
|
var LevelParamsContext = createContext2(void 0, "route-params");
|
|
@@ -437,11 +385,33 @@ function renderLayer(m, depth, base) {
|
|
|
437
385
|
onCleanup(() => {
|
|
438
386
|
cancelled = true;
|
|
439
387
|
});
|
|
440
|
-
const owner =
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
)
|
|
444
|
-
|
|
388
|
+
const owner = getOwner2();
|
|
389
|
+
const router = useContext2(RouterContext);
|
|
390
|
+
let watching = false;
|
|
391
|
+
const trackDeps = (deps) => {
|
|
392
|
+
if (watching || cancelled) return;
|
|
393
|
+
watching = true;
|
|
394
|
+
runWithOwner(owner, () => {
|
|
395
|
+
let first = true;
|
|
396
|
+
createEffect(() => {
|
|
397
|
+
deps();
|
|
398
|
+
if (first) first = false;
|
|
399
|
+
else untrack2(() => void refetch());
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
};
|
|
403
|
+
const [resource, { refetch }] = createResource3(() => {
|
|
404
|
+
const result = loader({ params: base.params, location: base.location }, owner, () => cancelled, trackDeps);
|
|
405
|
+
return router ? router.trackLoad(result) : result;
|
|
406
|
+
});
|
|
407
|
+
onCleanup(onRevalidate(() => void refetch()));
|
|
408
|
+
data = () => {
|
|
409
|
+
const error = resource.error;
|
|
410
|
+
if (error !== void 0 && error !== null) throw error;
|
|
411
|
+
return resource();
|
|
412
|
+
};
|
|
413
|
+
Object.defineProperty(data, "loading", { get: () => resource.loading });
|
|
414
|
+
Object.defineProperty(data, "state", { get: () => resource.state });
|
|
445
415
|
}
|
|
446
416
|
const buildPage = () => RouteDataContext2.Provider({
|
|
447
417
|
value: data,
|
|
@@ -459,12 +429,15 @@ function renderLayer(m, depth, base) {
|
|
|
459
429
|
});
|
|
460
430
|
}
|
|
461
431
|
});
|
|
462
|
-
if (!data) return buildPage();
|
|
432
|
+
if (!data) return { view: buildPage(), ready: () => true };
|
|
463
433
|
const res = data;
|
|
464
|
-
const isLoading = () =>
|
|
434
|
+
const isLoading = () => {
|
|
435
|
+
const state = res.state;
|
|
436
|
+
return state === void 0 ? res.loading : state === "pending" || state === "unresolved";
|
|
437
|
+
};
|
|
465
438
|
const [ready, setReady] = createSignal2(untrack2(() => !isLoading()));
|
|
466
439
|
createEffect(() => setReady(!isLoading()));
|
|
467
|
-
return createMemo2(() => ready() ? buildPage() : null);
|
|
440
|
+
return { view: createMemo2(() => ready() ? buildPage() : null), ready };
|
|
468
441
|
}
|
|
469
442
|
function renderChild(ctx) {
|
|
470
443
|
const childIdx = ctx.depth + 1;
|
|
@@ -475,17 +448,43 @@ function renderChild(ctx) {
|
|
|
475
448
|
const c = ctx.matched()[childIdx]?.component;
|
|
476
449
|
if (untrack2(childComp) !== c) setChildComp(() => c);
|
|
477
450
|
});
|
|
478
|
-
|
|
451
|
+
const owner = getOwner2();
|
|
452
|
+
let shown = null;
|
|
453
|
+
let pending = null;
|
|
454
|
+
const drop2 = (layer) => layer?.dispose();
|
|
455
|
+
onCleanup(() => {
|
|
456
|
+
drop2(shown);
|
|
457
|
+
drop2(pending);
|
|
458
|
+
shown = pending = null;
|
|
459
|
+
});
|
|
460
|
+
const incoming = createMemo2(() => {
|
|
479
461
|
const component = childComp();
|
|
480
|
-
if (!component)
|
|
462
|
+
if (!component) return null;
|
|
463
|
+
const m = untrack2(() => ctx.matched())[childIdx];
|
|
464
|
+
return runWithOwner(
|
|
465
|
+
owner,
|
|
466
|
+
() => createRoot((dispose) => ({
|
|
467
|
+
...renderLayer(m, childIdx, { matched: ctx.matched, params: ctx.params, location: ctx.location }),
|
|
468
|
+
dispose
|
|
469
|
+
}))
|
|
470
|
+
);
|
|
471
|
+
});
|
|
472
|
+
return createMemo2(() => {
|
|
473
|
+
const next = incoming();
|
|
474
|
+
if (!next) {
|
|
475
|
+
drop2(shown);
|
|
476
|
+
drop2(pending);
|
|
477
|
+
shown = pending = null;
|
|
481
478
|
return ctx.notFound ? ctx.notFound() : null;
|
|
482
479
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
480
|
+
if (next === shown) return shown.view;
|
|
481
|
+
if (pending && pending !== next) drop2(pending);
|
|
482
|
+
pending = next;
|
|
483
|
+
if (shown && !next.ready()) return shown.view;
|
|
484
|
+
drop2(shown);
|
|
485
|
+
shown = next;
|
|
486
|
+
pending = null;
|
|
487
|
+
return shown.view;
|
|
489
488
|
});
|
|
490
489
|
}
|
|
491
490
|
function renderNotFound(notFound) {
|
|
@@ -520,6 +519,8 @@ function Router(props) {
|
|
|
520
519
|
history
|
|
521
520
|
});
|
|
522
521
|
const [state, setState] = createSignal2(router.state());
|
|
522
|
+
const [navigating, setNavigating] = createSignal2(false);
|
|
523
|
+
const [loads, setLoads] = createSignal2(0);
|
|
523
524
|
let navigationId = 0;
|
|
524
525
|
const takeMode = () => {
|
|
525
526
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
@@ -529,12 +530,15 @@ function Router(props) {
|
|
|
529
530
|
const unsub = router.subscribe((next) => {
|
|
530
531
|
const id = ++navigationId;
|
|
531
532
|
const mode = takeMode();
|
|
533
|
+
setNavigating(true);
|
|
532
534
|
const prepared = prepareComponents(
|
|
533
535
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
534
536
|
);
|
|
535
537
|
const commit = () => {
|
|
536
538
|
setState(next);
|
|
537
|
-
|
|
539
|
+
const flushed = flush();
|
|
540
|
+
if (id === navigationId) setNavigating(false);
|
|
541
|
+
return flushed;
|
|
538
542
|
};
|
|
539
543
|
if (!prepared) {
|
|
540
544
|
void runTransition(mode, commit);
|
|
@@ -556,7 +560,18 @@ function Router(props) {
|
|
|
556
560
|
const ctx = {
|
|
557
561
|
router,
|
|
558
562
|
location: createMemo2(() => state().location),
|
|
559
|
-
params: createMemo2(() => state().match?.params ?? {})
|
|
563
|
+
params: createMemo2(() => state().match?.params ?? {}),
|
|
564
|
+
isRouting: () => navigating() || loads() > 0,
|
|
565
|
+
// Counted by the promise, not by an owner: a load a newer navigation superseded still
|
|
566
|
+
// settles and uncounts itself, and a resource seeded from the server never calls it.
|
|
567
|
+
trackLoad(result) {
|
|
568
|
+
if (result && typeof result.finally === "function") {
|
|
569
|
+
setLoads((n) => n + 1);
|
|
570
|
+
void result.finally(() => setLoads((n) => n - 1)).catch(() => {
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
return result;
|
|
574
|
+
}
|
|
560
575
|
};
|
|
561
576
|
const root = {
|
|
562
577
|
depth: -1,
|
|
@@ -579,6 +594,21 @@ function Outlet() {
|
|
|
579
594
|
if (!ctx) return null;
|
|
580
595
|
return renderChild(ctx);
|
|
581
596
|
}
|
|
597
|
+
function useIsRouting(options = {}) {
|
|
598
|
+
const routing = useContext2(RouterContext)?.isRouting ?? (() => false);
|
|
599
|
+
const delay = options.delay ?? 0;
|
|
600
|
+
if (delay <= 0) return routing;
|
|
601
|
+
const [late, setLate] = createSignal2(false);
|
|
602
|
+
createEffect(() => {
|
|
603
|
+
if (!routing()) {
|
|
604
|
+
setLate(false);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const timer = setTimeout(() => setLate(true), delay);
|
|
608
|
+
onCleanup(() => clearTimeout(timer));
|
|
609
|
+
});
|
|
610
|
+
return () => routing() && late();
|
|
611
|
+
}
|
|
582
612
|
function Redirect(props) {
|
|
583
613
|
const ctx = useContext2(RouterContext);
|
|
584
614
|
if (ctx && typeof window !== "undefined") {
|
|
@@ -594,7 +624,9 @@ var _ssrRouterStub = {
|
|
|
594
624
|
router: { navigate: () => {
|
|
595
625
|
} },
|
|
596
626
|
location: () => ({ pathname: "", search: "", hash: "", query: {} }),
|
|
597
|
-
params: () => ({})
|
|
627
|
+
params: () => ({}),
|
|
628
|
+
isRouting: () => false,
|
|
629
|
+
trackLoad: (result) => result
|
|
598
630
|
};
|
|
599
631
|
function useRouter() {
|
|
600
632
|
const ctx = useContext2(RouterContext);
|
|
@@ -709,18 +741,31 @@ var LINK_OWN_PROPS = /* @__PURE__ */ new Set([
|
|
|
709
741
|
]);
|
|
710
742
|
function Link(props) {
|
|
711
743
|
const ctx = useContext2(RouterContext);
|
|
712
|
-
const navigate = () => ctx
|
|
744
|
+
const navigate = () => ctx.router.navigate(read(props.href) ?? "", { replace: read(props.replace) });
|
|
713
745
|
const a = createNativeElement("a");
|
|
714
746
|
setAttribute(a, "href", read(props.href) ?? "");
|
|
715
747
|
if (props.slot) setAttribute(a, "slot", read(props.slot));
|
|
716
748
|
for (const k of Object.keys(props)) {
|
|
717
749
|
if (LINK_OWN_PROPS.has(k)) continue;
|
|
718
750
|
const v = props[k];
|
|
719
|
-
if (
|
|
751
|
+
if (typeof v === "function") {
|
|
752
|
+
if (/^on[A-Z]/.test(k)) continue;
|
|
753
|
+
const read2 = v;
|
|
754
|
+
const apply = () => {
|
|
755
|
+
const value = read2();
|
|
756
|
+
if (value == null || value === false) a.removeAttribute?.(k);
|
|
757
|
+
else setAttribute(a, k, String(value));
|
|
758
|
+
};
|
|
759
|
+
if (typeof a.addEventListener === "function") createEffect(apply);
|
|
760
|
+
else apply();
|
|
761
|
+
continue;
|
|
762
|
+
}
|
|
763
|
+
if (v != null) setAttribute(a, k, String(v));
|
|
720
764
|
}
|
|
721
765
|
if (typeof a.addEventListener === "function") {
|
|
722
766
|
a.addEventListener("click", (e) => {
|
|
723
767
|
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
768
|
+
if (!ctx) return;
|
|
724
769
|
e.preventDefault();
|
|
725
770
|
navigate();
|
|
726
771
|
});
|
|
@@ -785,16 +830,11 @@ async function preloadRoutes(routes, pathname) {
|
|
|
785
830
|
export {
|
|
786
831
|
__reExport,
|
|
787
832
|
lazy,
|
|
788
|
-
createProvider,
|
|
789
|
-
createContextWithProvider,
|
|
790
|
-
composeProviders,
|
|
791
|
-
createConsumer,
|
|
792
|
-
useProvide,
|
|
793
833
|
createContext,
|
|
794
834
|
useContext,
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
835
|
+
createProvider,
|
|
836
|
+
composeProviders,
|
|
837
|
+
requireContext,
|
|
798
838
|
supportsViewTransitions,
|
|
799
839
|
prefersReducedMotion,
|
|
800
840
|
cache,
|
|
@@ -802,9 +842,11 @@ export {
|
|
|
802
842
|
createAsync,
|
|
803
843
|
action,
|
|
804
844
|
useSubmission,
|
|
845
|
+
useSubmissions,
|
|
805
846
|
useAction,
|
|
806
847
|
Router,
|
|
807
848
|
Outlet,
|
|
849
|
+
useIsRouting,
|
|
808
850
|
Redirect,
|
|
809
851
|
useRouter,
|
|
810
852
|
useParams,
|
|
@@ -826,5 +868,5 @@ export {
|
|
|
826
868
|
createBrowserHistory2 as createBrowserHistory,
|
|
827
869
|
matchRoutes2 as matchRoutes,
|
|
828
870
|
matchPath2 as matchPath,
|
|
829
|
-
runWithOwner
|
|
871
|
+
runWithOwner2 as runWithOwner
|
|
830
872
|
};
|