gemi 0.52.0 → 0.53.0

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.
Files changed (68) hide show
  1. package/dist/{chunk-a0sy9f9x.js → chunk-07jtzbf0.js} +1 -1
  2. package/dist/{chunk-jdfe4dmh.js → chunk-1pqfmw5h.js} +2 -2
  3. package/dist/{chunk-jdfe4dmh.js.map → chunk-1pqfmw5h.js.map} +1 -1
  4. package/dist/chunk-3d3nmr5g.js +4 -0
  5. package/dist/{chunk-qj4mmner.js.map → chunk-3d3nmr5g.js.map} +2 -2
  6. package/dist/{chunk-et0j6jx8.js → chunk-7s1g3v1y.js} +3 -3
  7. package/dist/{chunk-et0j6jx8.js.map → chunk-7s1g3v1y.js.map} +1 -1
  8. package/dist/chunk-92793zh4.js +5 -0
  9. package/dist/{chunk-0tbwn6er.js.map → chunk-92793zh4.js.map} +3 -4
  10. package/dist/chunk-9279y4af.js +5 -0
  11. package/dist/{chunk-f29vd5mc.js.map → chunk-9279y4af.js.map} +2 -2
  12. package/dist/chunk-bq4w14a6.js +5 -0
  13. package/dist/chunk-bq4w14a6.js.map +10 -0
  14. package/dist/{chunk-4t6a82fh.js → chunk-cg53h5ht.js} +2 -2
  15. package/dist/{chunk-4t6a82fh.js.map → chunk-cg53h5ht.js.map} +1 -1
  16. package/dist/{chunk-km6x37ws.js → chunk-ear03axe.js} +24 -24
  17. package/dist/{chunk-km6x37ws.js.map → chunk-ear03axe.js.map} +3 -5
  18. package/dist/{chunk-38ma6gg3.js → chunk-fbp5vapa.js} +2 -2
  19. package/dist/{chunk-38ma6gg3.js.map → chunk-fbp5vapa.js.map} +2 -2
  20. package/dist/chunk-ffre1z8s.js +6 -0
  21. package/dist/{chunk-hbycemy5.js.map → chunk-ffre1z8s.js.map} +2 -2
  22. package/dist/{chunk-53e48ce8.js → chunk-qjnv2rkh.js} +2 -2
  23. package/dist/{chunk-53e48ce8.js.map → chunk-qjnv2rkh.js.map} +1 -1
  24. package/dist/{chunk-1ce7veh9.js → chunk-tkv6cw94.js} +3 -3
  25. package/dist/{chunk-1ce7veh9.js.map → chunk-tkv6cw94.js.map} +1 -1
  26. package/dist/chunk-y4djde42.js +5 -0
  27. package/dist/chunk-y4djde42.js.map +11 -0
  28. package/dist/chunks/ThemeProvider-CTX9LOFC.js +2718 -0
  29. package/dist/chunks/ThemeProvider-CTX9LOFC.js.map +1 -0
  30. package/dist/client/Mutation.d.ts +1 -1
  31. package/dist/client/Mutation.d.ts.map +1 -1
  32. package/dist/client/ThemeProvider.d.ts +7 -0
  33. package/dist/client/ThemeProvider.d.ts.map +1 -1
  34. package/dist/client/index.js +107 -2673
  35. package/dist/client/index.js.map +1 -1
  36. package/dist/client/useIsNavigationPending.d.ts.map +1 -1
  37. package/dist/client/useMutate.d.ts.map +1 -1
  38. package/dist/database/index.js +2 -2
  39. package/dist/database/index.js.map +1 -1
  40. package/dist/facades/index.js +2 -2
  41. package/dist/facades/index.js.map +1 -1
  42. package/dist/http/index.js +2 -2
  43. package/dist/http/index.js.map +1 -1
  44. package/dist/i18n/Dictionary.d.ts.map +1 -1
  45. package/dist/i18n/index.js +2 -2
  46. package/dist/i18n/index.js.map +3 -3
  47. package/dist/kernel/index.js +2 -2
  48. package/dist/kernel/index.js.map +2 -2
  49. package/dist/orm/index.js +2 -2
  50. package/dist/orm/index.js.map +2 -2
  51. package/dist/server/index.js +1 -1
  52. package/dist/services/index.js +2 -2
  53. package/dist/services/index.js.map +2 -2
  54. package/dist/testing/Page.d.ts +166 -0
  55. package/dist/testing/Page.d.ts.map +1 -0
  56. package/dist/testing/index.d.ts +3 -0
  57. package/dist/testing/index.d.ts.map +1 -0
  58. package/dist/testing/index.js +352 -0
  59. package/dist/testing/index.js.map +1 -0
  60. package/dist/utils/Subject.d.ts.map +1 -1
  61. package/dist/utils/variantKey.d.ts +19 -0
  62. package/dist/utils/variantKey.d.ts.map +1 -0
  63. package/package.json +2 -1
  64. package/dist/chunk-0tbwn6er.js +0 -5
  65. package/dist/chunk-f29vd5mc.js +0 -5
  66. package/dist/chunk-hbycemy5.js +0 -6
  67. package/dist/chunk-qj4mmner.js +0 -4
  68. /package/dist/{chunk-a0sy9f9x.js.map → chunk-07jtzbf0.js.map} +0 -0
@@ -1,380 +1,7 @@
1
- import { Component, Fragment, StrictMode, Suspense, createContext, createElement, isValidElement, lazy, memo, useCallback, useContext, useDeferredValue, useEffect, useMemo, useRef, useState, useSyncExternalStore, useTransition } from "react";
1
+ import { A as toVariantKey, C as useLocation, D as useParams, F as DEFAULT_STALE_TIME, I as QueryError, L as Subject, M as QueryConfigContext, N as QueryManagerContext, O as RouteStateContext, P as QueryManagerProvider, S as ServerDataProvider, T as Action, _ as useSearchParams, a as m, b as I18nProvider, c as ClientRouterContext, d as ComponentsProvider, f as loadViewModule, g as useRoute, h as routeDataUrl, i as WebSocketContextProvider, j as applyParams$1, k as RouteStateProvider, l as ClientRouterProvider, m as readRoutePayload, n as useTheme, o as RouteTransitionProvider, p as subscribeViewModules, r as WebSocketContext, s as useRouteTransition, t as ThemeProvider, u as ComponentsContext, v as useNavigate, x as ServerDataContext, y as I18nContext } from "../chunks/ThemeProvider-CTX9LOFC.js";
2
+ import { Fragment, StrictMode, Suspense, createContext, createElement, isValidElement, memo, useCallback, useContext, useDeferredValue, useEffect, useMemo, useRef, useState, useSyncExternalStore, useTransition } from "react";
2
3
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
3
- import { createPortal } from "react-dom";
4
4
  import { createRoot as createRoot$1, hydrateRoot } from "react-dom/client";
5
- //#region utils/Subject.ts
6
- var Subject = class {
7
- subscribers = /* @__PURE__ */ new Set();
8
- value;
9
- constructor(initialValue) {
10
- this.value = initialValue;
11
- }
12
- subscribe(subscriber) {
13
- this.subscribers.add(subscriber);
14
- return () => {
15
- this.subscribers.delete(subscriber);
16
- };
17
- }
18
- next(value) {
19
- this.value = value;
20
- this.subscribers.forEach((subscriber) => subscriber(value));
21
- }
22
- getValue() {
23
- return this.value;
24
- }
25
- };
26
- //#endregion
27
- //#region client/QueryError.ts
28
- /**
29
- * An HTTP failure from a query endpoint, in a shape an error boundary can
30
- * work with. `resolveVariant` used to store the parsed response body as the
31
- * error; boundaries expect an `Error`, so the body moves to a field.
32
- */
33
- var QueryError = class extends Error {
34
- path;
35
- variantKey;
36
- status;
37
- body;
38
- constructor(path, variantKey, status, body) {
39
- super(typeof body?.message === "string" ? body.message : `Request to /api${path} failed with status ${status}`);
40
- this.path = path;
41
- this.variantKey = variantKey;
42
- this.status = status;
43
- this.body = body;
44
- this.name = "QueryError";
45
- }
46
- };
47
- //#endregion
48
- //#region client/QueryResource.ts
49
- var DEFAULT_STALE_TIME = 5e3;
50
- var QueryResource = class {
51
- store;
52
- staleVariants = /* @__PURE__ */ new Set();
53
- lastFetchRecord = /* @__PURE__ */ new Map();
54
- key;
55
- /**
56
- * Variants with a request on the wire. React discards and retries a
57
- * suspended render, so `read` runs many times for one commit — this is what
58
- * collapses those attempts onto a single fetch. The `loading` flag can't do
59
- * it: render-initiated fetches are silent and never write to the store.
60
- */
61
- inflight = /* @__PURE__ */ new Set();
62
- /**
63
- * One promise per suspended variant, handed to `use()`. Settled by whatever
64
- * write lands first — the variant's own fetch or a `hydrate` from a route
65
- * payload — so a prefetch that arrives mid-suspension wakes the reader
66
- * without waiting on the wire.
67
- */
68
- pending = /* @__PURE__ */ new Map();
69
- constructor(key, initialState) {
70
- this.key = key;
71
- this.store = new Subject(/* @__PURE__ */ new Map());
72
- this.hydrate(initialState);
73
- }
74
- /**
75
- * Adopt server-prefetched data into the cache.
76
- *
77
- * Called once from the constructor for the SSR payload, and again on every
78
- * client-side navigation with the `prefetchedData` the server just produced —
79
- * otherwise the resource cache (which is keyed by path for the lifetime of
80
- * the app) would keep serving the first payload and revalidate it over `/api`.
81
- */
82
- hydrate(initialState) {
83
- const store = this.store.getValue();
84
- const now = Date.now();
85
- let changed = false;
86
- for (const [variantKey, data] of Object.entries(initialState ?? {})) {
87
- if (data === void 0) continue;
88
- const current = store.get(variantKey);
89
- if (current?.loading) continue;
90
- if (current?.hasData && current.data === data) continue;
91
- store.set(variantKey, {
92
- loading: false,
93
- data,
94
- hasData: true,
95
- error: null,
96
- version: now
97
- });
98
- this.staleVariants.delete(variantKey);
99
- this.lastFetchRecord.set(variantKey, now);
100
- this.settle(variantKey);
101
- changed = true;
102
- }
103
- if (changed) this.store.next(store);
104
- }
105
- pendingFor(variantKey) {
106
- let deferred = this.pending.get(variantKey);
107
- if (!deferred) {
108
- let resolve;
109
- deferred = {
110
- promise: new Promise((r) => {
111
- resolve = r;
112
- }),
113
- resolve
114
- };
115
- this.pending.set(variantKey, deferred);
116
- }
117
- return deferred;
118
- }
119
- settle(variantKey) {
120
- const deferred = this.pending.get(variantKey);
121
- if (deferred) {
122
- this.pending.delete(variantKey);
123
- deferred.resolve();
124
- }
125
- }
126
- isStale(variantKey, staleTime) {
127
- if (this.staleVariants.has(variantKey)) return true;
128
- const now = Date.now();
129
- return now - (this.lastFetchRecord.get(variantKey) ?? now) >= staleTime;
130
- }
131
- /**
132
- * The cached state for a variant, or `undefined` — a plain read that never
133
- * fetches and never revalidates.
134
- *
135
- * `getVariant` is the read that keeps the cache honest, and it starts a
136
- * request when it has to. That makes it the wrong thing to call while
137
- * rendering: React throws away a render whose subtree suspends and retries
138
- * it, so every discarded attempt would leak a request. Renders read with
139
- * this; effects, which only run for a render that committed, use
140
- * `getVariant`.
141
- */
142
- peek(variantKey) {
143
- return this.store.getValue().get(variantKey);
144
- }
145
- /**
146
- * The read a render performs. Never suspends when data is in hand (stale
147
- * data revalidates in the background instead), dedupes across the render
148
- * attempts React throws away, and hands back a promise that resolves off
149
- * any write to the variant — its own fetch or a `hydrate`.
150
- *
151
- * Safe during render: it never writes to the store synchronously, so the
152
- * snapshot `useSyncExternalStore` read stays valid for the whole attempt.
153
- */
154
- read(variantKey, staleTime = DEFAULT_STALE_TIME) {
155
- const state = this.peek(variantKey);
156
- if (state?.hasData) {
157
- if (!this.inflight.has(variantKey) && this.isStale(variantKey, staleTime)) {
158
- this.lastFetchRecord.set(variantKey, Date.now());
159
- this.resolveVariant(variantKey, true);
160
- }
161
- return { state };
162
- }
163
- if (state?.error) return { state };
164
- if (typeof window === "undefined") return { state };
165
- const deferred = this.pendingFor(variantKey);
166
- if (!this.inflight.has(variantKey)) this.resolveVariant(variantKey, true);
167
- return {
168
- state,
169
- promise: deferred.promise
170
- };
171
- }
172
- getVariant(variantKey, staleTime = DEFAULT_STALE_TIME) {
173
- const store = this.store.getValue();
174
- if (!store.has(variantKey)) {
175
- if (!this.inflight.has(variantKey)) this.resolveVariant(variantKey);
176
- } else {
177
- const variant = store.get(variantKey);
178
- if (!variant.loading && !this.inflight.has(variantKey)) {
179
- if (!variant.hasData) {
180
- this.resolveVariant(variantKey);
181
- return store.get(variantKey);
182
- }
183
- if (this.isStale(variantKey, staleTime)) {
184
- this.lastFetchRecord.set(variantKey, Date.now());
185
- this.resolveVariant(variantKey, true);
186
- return store.get(variantKey);
187
- }
188
- }
189
- }
190
- return store.get(variantKey);
191
- }
192
- /**
193
- * Drop the error for one variant (or every variant when omitted), so an
194
- * error boundary reset re-renders into a clean read instead of instantly
195
- * re-throwing the stored failure.
196
- */
197
- clearError(variantKey) {
198
- const store = this.store.getValue();
199
- let changed = false;
200
- for (const [key, state] of store) {
201
- if (variantKey !== void 0 && key !== variantKey) continue;
202
- if (state.error) {
203
- store.set(key, {
204
- ...state,
205
- error: null
206
- });
207
- changed = true;
208
- }
209
- }
210
- if (changed) this.store.next(store);
211
- }
212
- mutate(variantKey, fn = (data) => data) {
213
- const cacheKey = [
214
- typeof window !== "undefined" && window.location?.origin ? window.location.origin : "",
215
- this.key,
216
- variantKey
217
- ].filter((s) => s.length > 0).join("?");
218
- try {
219
- if (caches) caches?.delete(cacheKey);
220
- } catch (err) {}
221
- const store = this.store.getValue();
222
- const state = store.get(variantKey);
223
- if (!state || !state.hasData) {
224
- this.resolveVariant(variantKey, false, false);
225
- return;
226
- }
227
- const data = fn(state.data);
228
- this.staleVariants.add(variantKey);
229
- this.store.next(store.set(variantKey, {
230
- loading: false,
231
- data,
232
- hasData: true,
233
- error: null,
234
- version: state.version
235
- }));
236
- this.resolveVariant(variantKey, false, false);
237
- }
238
- refetch(variantKey) {
239
- this.resolveVariant(variantKey, false, false);
240
- }
241
- async resolveVariant(variantKey, silent = false, cache = true) {
242
- if (typeof window === "undefined") return;
243
- this.inflight.add(variantKey);
244
- try {
245
- const store = this.store.getValue();
246
- const previousState = store.get(variantKey);
247
- if (!silent) store.set(variantKey, {
248
- loading: true,
249
- data: previousState?.data,
250
- hasData: previousState?.hasData ?? false,
251
- error: previousState?.error,
252
- version: previousState?.version
253
- });
254
- let data = null;
255
- let response = null;
256
- const fullUrl = [this.key, variantKey].filter((s) => s.length).join("?");
257
- try {
258
- response = await fetch(`/api${fullUrl}`, { cache: cache ? "default" : "reload" });
259
- data = await response.json();
260
- } catch (error) {
261
- console.error(`Error fetching url /api${fullUrl}`, error);
262
- this.store.next(store.set(variantKey, {
263
- loading: false,
264
- data: previousState?.data,
265
- hasData: previousState?.hasData ?? false,
266
- error,
267
- version: previousState?.version
268
- }));
269
- return;
270
- }
271
- if (response.ok) {
272
- this.store.next(store.set(variantKey, {
273
- loading: false,
274
- data,
275
- hasData: true,
276
- error: null,
277
- version: Date.now()
278
- }));
279
- this.staleVariants.delete(variantKey);
280
- this.lastFetchRecord.set(variantKey, Date.now());
281
- } else this.store.next(store.set(variantKey, {
282
- loading: false,
283
- data: previousState?.data,
284
- hasData: previousState?.hasData ?? false,
285
- error: new QueryError(this.key, variantKey, response.status, data),
286
- version: previousState?.version
287
- }));
288
- } finally {
289
- this.inflight.delete(variantKey);
290
- this.settle(variantKey);
291
- }
292
- }
293
- };
294
- //#endregion
295
- //#region client/QueryManagerContext.tsx
296
- var QueryConfigContext = createContext(null);
297
- /**
298
- * The runtime mirror of the `QueryConfig` type: TS excess-property checking
299
- * only fires on fresh object literals, so a dynamically built (or plain-JS)
300
- * config could smuggle call-site-only keys (`lazy`, `fallbackData`,
301
- * `refetchUntil`) into every query. The provider picks these keys — and only
302
- * these — before the value enters the context. Keys whose value is
303
- * `undefined` are dropped too, so an absent value (e.g. an unset env-derived
304
- * `staleTime`) falls through to the framework default instead of shadowing it.
305
- */
306
- var APP_WIDE_QUERY_CONFIG_KEYS = [
307
- "suspense",
308
- "staleTime",
309
- "keepPreviousData",
310
- "retryIntervalOnError",
311
- "refreshInterval"
312
- ];
313
- function pickAppWideQueryConfig(queryConfig) {
314
- if (!queryConfig) return null;
315
- const picked = {};
316
- for (const key of APP_WIDE_QUERY_CONFIG_KEYS) if (queryConfig[key] !== void 0) picked[key] = queryConfig[key];
317
- return picked;
318
- }
319
- var QueryManagerContext = createContext({
320
- getResource: (key, initialState = {}) => {
321
- return new QueryResource(key, initialState);
322
- },
323
- hydrate: () => {},
324
- clearErrors: () => {}
325
- });
326
- var QueryManagerProvider = ({ children, queryConfig = null }) => {
327
- const resourcesRef = useRef(/* @__PURE__ */ new Map());
328
- const appQueryConfig = useMemo(() => pickAppWideQueryConfig(queryConfig), [queryConfig]);
329
- const getResource = useCallback((key, initialState) => {
330
- let resource = resourcesRef.current.get(key);
331
- if (!resource) {
332
- resource = new QueryResource(key, initialState ?? {});
333
- resourcesRef.current.set(key, resource);
334
- }
335
- return resource;
336
- }, []);
337
- const hydrate = useCallback((prefetchedData) => {
338
- if (!prefetchedData) return;
339
- for (const [key, initialState] of Object.entries(prefetchedData)) {
340
- if (!initialState || typeof initialState !== "object") continue;
341
- const resource = resourcesRef.current.get(key);
342
- if (resource) resource.hydrate(initialState);
343
- else resourcesRef.current.set(key, new QueryResource(key, initialState));
344
- }
345
- }, []);
346
- const clearErrors = useCallback(() => {
347
- for (const resource of resourcesRef.current.values()) resource.clearError();
348
- }, []);
349
- const drainedStreamRef = useRef(false);
350
- if (typeof window !== "undefined" && !drainedStreamRef.current) {
351
- drainedStreamRef.current = true;
352
- const w = window;
353
- const adopt = ([path, variantKey, data]) => {
354
- hydrate({ [path]: { [variantKey]: data } });
355
- };
356
- const buffered = Array.isArray(w.__GEMI_STREAM__) ? w.__GEMI_STREAM__ : [];
357
- w.__GEMI_STREAM__ = { push: adopt };
358
- for (const payload of buffered) adopt(payload);
359
- }
360
- const value = useMemo(() => ({
361
- getResource,
362
- hydrate,
363
- clearErrors
364
- }), [
365
- getResource,
366
- hydrate,
367
- clearErrors
368
- ]);
369
- return /* @__PURE__ */ jsx(QueryManagerContext.Provider, {
370
- value,
371
- children: /* @__PURE__ */ jsx(QueryConfigContext.Provider, {
372
- value: appQueryConfig,
373
- children
374
- })
375
- });
376
- };
377
- //#endregion
378
5
  //#region client/ServerQueryContext.tsx
379
6
  /**
380
7
  * Populated only during a streaming server render (`createRoot` threads the
@@ -383,42 +10,6 @@ var QueryManagerProvider = ({ children, queryConfig = null }) => {
383
10
  */
384
11
  var ServerQueryContext = createContext(null);
385
12
  //#endregion
386
- //#region utils/applyParams.ts
387
- function applyParams$1(url, params) {
388
- return url.replace(/:([^/]+[*?]?)/g, (_, key) => {
389
- const hasSuffix = key.endsWith("?") || key.endsWith("*");
390
- const paramName = hasSuffix ? key.slice(0, -1) : key;
391
- const value = params[paramName];
392
- if (value === void 0) {
393
- if (hasSuffix) return "";
394
- console.error(`Missing parameter: ${paramName} in URL: ${url}`);
395
- }
396
- return String(value);
397
- }).replace(/\/\//g, "/").replace(/\/$/, "");
398
- }
399
- //#endregion
400
- //#region utils/omitNullishValues.ts
401
- function omitNullishValues(input) {
402
- return Object.fromEntries(Object.entries(input).filter(([, value]) => {
403
- return value !== null && value !== void 0;
404
- }));
405
- }
406
- //#endregion
407
- //#region client/RouteStateContext.tsx
408
- var RouteStateContext = createContext({});
409
- var RouteStateProvider = (props) => {
410
- return /* @__PURE__ */ jsx(RouteStateContext.Provider, {
411
- value: props.state,
412
- children: props.children
413
- });
414
- };
415
- //#endregion
416
- //#region client/useParams.ts
417
- function useParams() {
418
- const { params = {} } = useContext(RouteStateContext);
419
- return params;
420
- }
421
- //#endregion
422
13
  //#region client/useRouteData.ts
423
14
  function useRouteData() {
424
15
  const { data, i18n, prefetchedData, breadcrumbs } = useContext(RouteStateContext);
@@ -485,9 +76,7 @@ function useFrameworkQuery(url, ...args) {
485
76
  const { getResource } = useContext(QueryManagerContext);
486
77
  const serverQueries = useContext(ServerQueryContext);
487
78
  const currentPath = applyParams$1(url, params);
488
- const searchParams = new URLSearchParams(omitNullishValues(search));
489
- searchParams.sort();
490
- const currentVariantKey = searchParams.toString();
79
+ const currentVariantKey = toVariantKey(search);
491
80
  const deferredPath = useDeferredValue(currentPath);
492
81
  const deferredVariantKey = useDeferredValue(currentVariantKey);
493
82
  const deferVariant = suspense && config.keepPreviousData;
@@ -538,2094 +127,128 @@ function useFrameworkQuery(url, ...args) {
538
127
  }
539
128
  } else readPromise = resource.read(variantKey, config.staleTime).promise;
540
129
  if (suspense && typeof window === "undefined" && !serverQueries && !state?.hasData && process.env.NODE_ENV !== "production") {
541
- const searchHint = variantKey ? `, { search: ${JSON.stringify(Object.fromEntries(searchParams))} }` : "";
130
+ const searchHint = variantKey ? `, { search: ${JSON.stringify(Object.fromEntries(new URLSearchParams(variantKey)))} }` : "";
542
131
  console.warn(`[gemi] useQuery("${url}") rendered on the server without data. The server never fetches, so this page ships without it and the client suspends after hydration. Add \`Query.prefetch("${url}"${searchHint})\` to the route's view handler.`);
543
132
  }
544
133
  const retry = useCallback((vk) => {
545
134
  if (!retryingMap.current.get(vk)) {
546
135
  if (configRef.current.debug) console.log("retrying", vk);
547
136
  retryingMap.current.set(vk, true);
548
- retryIntervalRef.current = setTimeout(() => {
549
- resource.getVariant(vk, configRef.current.staleTime);
550
- retryingMap.current.set(vk, false);
551
- }, configRef.current.retryIntervalOnError);
552
- }
553
- }, [resource]);
554
- useEffect(() => {
555
- if (fetchedRef.current) resource.getVariant(variantKey, configRef.current.staleTime);
556
- return () => {
557
- clearTimeout(retryIntervalRef.current);
558
- };
559
- }, [variantKey, resource]);
560
- useEffect(() => {
561
- if (!suspense && snapshot?.error) retry(variantKey);
562
- }, [
563
- snapshot,
564
- suspense,
565
- retry,
566
- variantKey
567
- ]);
568
- useEffect(() => {
569
- const cfg = configRef.current;
570
- if (!cfg.refetchUntil) return;
571
- if (snapshot && !snapshot.loading && snapshot.hasData && !snapshot.error) {
572
- const nextDuration = cfg.refetchUntil(snapshot.data, refetchUntilDurationRef.current);
573
- if (nextDuration > 0) {
574
- refetchUntilDurationRef.current = nextDuration;
575
- refetchUntilTimerRef.current = setTimeout(() => {
576
- resource.refetch(variantKey);
577
- }, nextDuration);
578
- } else refetchUntilDurationRef.current = 0;
579
- }
580
- return () => {
581
- if (refetchUntilTimerRef.current) clearTimeout(refetchUntilTimerRef.current);
582
- };
583
- }, [
584
- snapshot,
585
- resource,
586
- variantKey
587
- ]);
588
- const handleReload = useCallback(() => {
589
- if (configRef.current.debug) console.log("Reloading query for", variantKey);
590
- const data = resource.getVariant(variantKey, configRef.current.staleTime).data;
591
- resource.mutate(variantKey, () => data);
592
- }, [variantKey, resource]);
593
- useEffect(() => {
594
- if (!fetchedRef.current) return;
595
- refreshIntervalRef.current = setInterval(() => {
596
- handleReload();
597
- }, config.refreshInterval);
598
- return () => {
599
- if (refreshIntervalRef.current) clearInterval(refreshIntervalRef.current);
600
- };
601
- }, [config.refreshInterval, handleReload]);
602
- useEffect(() => {
603
- if (typeof import.meta.hot?.on === "function") import.meta.hot.on("http-reload", handleReload);
604
- return () => {
605
- if (typeof import.meta.hot?.off === "function") import.meta.hot.off("http-reload", handleReload);
606
- };
607
- }, [handleReload]);
608
- const trigger = useCallback(() => {
609
- fetchedRef.current = true;
610
- const variant = resource.store.getValue().get(variantKey);
611
- if (!variant || !variant.loading && !variant.hasData) resource.refetch(variantKey);
612
- }, [resource, variantKey]);
613
- const prefetch = useCallback(() => {
614
- if (prefetchedRef.current) return;
615
- prefetchedRef.current = true;
616
- fetchedRef.current = true;
617
- resource.read(variantKey, configRef.current.staleTime);
618
- }, [resource, variantKey]);
619
- const refetch = useCallback(() => {
620
- fetchedRef.current = true;
621
- resource.refetch(variantKey);
622
- }, [resource, variantKey]);
623
- function mutate(fn) {
624
- if (!fn) {
625
- fetchedRef.current = true;
626
- resource.refetch(variantKey);
627
- return;
628
- }
629
- return resource.mutate(variantKey, (data) => {
630
- if (data === void 0) {
631
- console.warn("Mutate function called before the query.");
632
- return data;
633
- }
634
- const updatedData = typeof fn === "function" ? fn(data) : fn;
635
- if (isPlainObject(data)) {
636
- if (isPlainObject(updatedData)) return updatedData;
637
- throw new Error("Mutate function must return an object when the current data is an object.");
638
- }
639
- if (Array.isArray(data)) {
640
- if (Array.isArray(updatedData)) return updatedData;
641
- throw new Error("Mutate function must return an array when the current data is an array.");
642
- }
643
- if (typeof data !== typeof updatedData) throw new Error("Mutate function must return the same type as the current data.");
644
- return updatedData;
645
- });
646
- }
647
- if (suspense) {
648
- if (serverError) throw serverError;
649
- if (state?.error && !state?.hasData) throw state.error;
650
- if (!state?.hasData && readPromise) throw readPromise;
651
- }
652
- return {
653
- data: state?.data,
654
- loading: isDeferred || (state?.loading ?? !lazy),
655
- error: state?.error,
656
- mutate,
657
- trigger,
658
- prefetch,
659
- refetch,
660
- version: state?.version
661
- };
662
- }
663
- //#endregion
664
- //#region ../../node_modules/.bun/@babel+runtime@7.29.2/node_modules/@babel/runtime/helpers/esm/extends.js
665
- function _extends() {
666
- return _extends = Object.assign ? Object.assign.bind() : function(n) {
667
- for (var e = 1; e < arguments.length; e++) {
668
- var t = arguments[e];
669
- for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
670
- }
671
- return n;
672
- }, _extends.apply(null, arguments);
673
- }
674
- //#endregion
675
- //#region ../../node_modules/.bun/history@5.3.0/node_modules/history/index.js
676
- /**
677
- * Actions represent the type of change to a location value.
678
- *
679
- * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#action
680
- */
681
- var Action;
682
- (function(Action) {
683
- /**
684
- * A POP indicates a change to an arbitrary index in the history stack, such
685
- * as a back or forward navigation. It does not describe the direction of the
686
- * navigation, only that the current index changed.
687
- *
688
- * Note: This is the default action for newly created history objects.
689
- */
690
- Action["Pop"] = "POP";
691
- /**
692
- * A PUSH indicates a new entry being added to the history stack, such as when
693
- * a link is clicked and a new page loads. When this happens, all subsequent
694
- * entries in the stack are lost.
695
- */
696
- Action["Push"] = "PUSH";
697
- /**
698
- * A REPLACE indicates the entry at the current index in the history stack
699
- * being replaced by a new one.
700
- */
701
- Action["Replace"] = "REPLACE";
702
- })(Action || (Action = {}));
703
- var readOnly = process.env.NODE_ENV !== "production" ? function(obj) {
704
- return Object.freeze(obj);
705
- } : function(obj) {
706
- return obj;
707
- };
708
- function warning(cond, message) {
709
- if (!cond) {
710
- if (typeof console !== "undefined") console.warn(message);
711
- try {
712
- throw new Error(message);
713
- } catch (e) {}
714
- }
715
- }
716
- var BeforeUnloadEventType = "beforeunload";
717
- var PopStateEventType = "popstate";
718
- /**
719
- * Browser history stores the location in regular URLs. This is the standard for
720
- * most web apps, but it requires some configuration on the server to ensure you
721
- * serve the same app at multiple URLs.
722
- *
723
- * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory
724
- */
725
- function createBrowserHistory(options) {
726
- if (options === void 0) options = {};
727
- var _options$window = options.window, window = _options$window === void 0 ? document.defaultView : _options$window;
728
- var globalHistory = window.history;
729
- function getIndexAndLocation() {
730
- var _window$location = window.location, pathname = _window$location.pathname, search = _window$location.search, hash = _window$location.hash;
731
- var state = globalHistory.state || {};
732
- return [state.idx, readOnly({
733
- pathname,
734
- search,
735
- hash,
736
- state: state.usr || null,
737
- key: state.key || "default"
738
- })];
739
- }
740
- var blockedPopTx = null;
741
- function handlePop() {
742
- if (blockedPopTx) {
743
- blockers.call(blockedPopTx);
744
- blockedPopTx = null;
745
- } else {
746
- var nextAction = Action.Pop;
747
- var _getIndexAndLocation = getIndexAndLocation(), nextIndex = _getIndexAndLocation[0], nextLocation = _getIndexAndLocation[1];
748
- if (blockers.length) if (nextIndex != null) {
749
- var delta = index - nextIndex;
750
- if (delta) {
751
- blockedPopTx = {
752
- action: nextAction,
753
- location: nextLocation,
754
- retry: function retry() {
755
- go(delta * -1);
756
- }
757
- };
758
- go(delta);
759
- }
760
- } else process.env.NODE_ENV !== "production" && warning(false, "You are trying to block a POP navigation to a location that was not created by the history library. The block will fail silently in production, but in general you should do all navigation with the history library (instead of using window.history.pushState directly) to avoid this situation.");
761
- else applyTx(nextAction);
762
- }
763
- }
764
- window.addEventListener(PopStateEventType, handlePop);
765
- var action = Action.Pop;
766
- var _getIndexAndLocation2 = getIndexAndLocation(), index = _getIndexAndLocation2[0], location = _getIndexAndLocation2[1];
767
- var listeners = createEvents();
768
- var blockers = createEvents();
769
- if (index == null) {
770
- index = 0;
771
- globalHistory.replaceState(_extends({}, globalHistory.state, { idx: index }), "");
772
- }
773
- function createHref(to) {
774
- return typeof to === "string" ? to : createPath(to);
775
- }
776
- function getNextLocation(to, state) {
777
- if (state === void 0) state = null;
778
- return readOnly(_extends({
779
- pathname: location.pathname,
780
- hash: "",
781
- search: ""
782
- }, typeof to === "string" ? parsePath(to) : to, {
783
- state,
784
- key: createKey()
785
- }));
786
- }
787
- function getHistoryStateAndUrl(nextLocation, index) {
788
- return [{
789
- usr: nextLocation.state,
790
- key: nextLocation.key,
791
- idx: index
792
- }, createHref(nextLocation)];
793
- }
794
- function allowTx(action, location, retry) {
795
- return !blockers.length || (blockers.call({
796
- action,
797
- location,
798
- retry
799
- }), false);
800
- }
801
- function applyTx(nextAction) {
802
- action = nextAction;
803
- var _getIndexAndLocation3 = getIndexAndLocation();
804
- index = _getIndexAndLocation3[0];
805
- location = _getIndexAndLocation3[1];
806
- listeners.call({
807
- action,
808
- location
809
- });
810
- }
811
- function push(to, state) {
812
- var nextAction = Action.Push;
813
- var nextLocation = getNextLocation(to, state);
814
- function retry() {
815
- push(to, state);
816
- }
817
- if (allowTx(nextAction, nextLocation, retry)) {
818
- var _getHistoryStateAndUr = getHistoryStateAndUrl(nextLocation, index + 1), historyState = _getHistoryStateAndUr[0], url = _getHistoryStateAndUr[1];
819
- try {
820
- globalHistory.pushState(historyState, "", url);
821
- } catch (error) {
822
- window.location.assign(url);
823
- }
824
- applyTx(nextAction);
825
- }
826
- }
827
- function replace(to, state) {
828
- var nextAction = Action.Replace;
829
- var nextLocation = getNextLocation(to, state);
830
- function retry() {
831
- replace(to, state);
832
- }
833
- if (allowTx(nextAction, nextLocation, retry)) {
834
- var _getHistoryStateAndUr2 = getHistoryStateAndUrl(nextLocation, index), historyState = _getHistoryStateAndUr2[0], url = _getHistoryStateAndUr2[1];
835
- globalHistory.replaceState(historyState, "", url);
836
- applyTx(nextAction);
837
- }
838
- }
839
- function go(delta) {
840
- globalHistory.go(delta);
841
- }
842
- return {
843
- get action() {
844
- return action;
845
- },
846
- get location() {
847
- return location;
848
- },
849
- createHref,
850
- push,
851
- replace,
852
- go,
853
- back: function back() {
854
- go(-1);
855
- },
856
- forward: function forward() {
857
- go(1);
858
- },
859
- listen: function listen(listener) {
860
- return listeners.push(listener);
861
- },
862
- block: function block(blocker) {
863
- var unblock = blockers.push(blocker);
864
- if (blockers.length === 1) window.addEventListener(BeforeUnloadEventType, promptBeforeUnload);
865
- return function() {
866
- unblock();
867
- if (!blockers.length) window.removeEventListener(BeforeUnloadEventType, promptBeforeUnload);
868
- };
869
- }
870
- };
871
- }
872
- function promptBeforeUnload(event) {
873
- event.preventDefault();
874
- event.returnValue = "";
875
- }
876
- function createEvents() {
877
- var handlers = [];
878
- return {
879
- get length() {
880
- return handlers.length;
881
- },
882
- push: function push(fn) {
883
- handlers.push(fn);
884
- return function() {
885
- handlers = handlers.filter(function(handler) {
886
- return handler !== fn;
887
- });
888
- };
889
- },
890
- call: function call(arg) {
891
- handlers.forEach(function(fn) {
892
- return fn && fn(arg);
893
- });
894
- }
895
- };
896
- }
897
- function createKey() {
898
- return Math.random().toString(36).substr(2, 8);
899
- }
900
- /**
901
- * Creates a string URL path from the given pathname, search, and hash components.
902
- *
903
- * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createpath
904
- */
905
- function createPath(_ref) {
906
- var _ref$pathname = _ref.pathname, pathname = _ref$pathname === void 0 ? "/" : _ref$pathname, _ref$search = _ref.search, search = _ref$search === void 0 ? "" : _ref$search, _ref$hash = _ref.hash, hash = _ref$hash === void 0 ? "" : _ref$hash;
907
- if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search;
908
- if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
909
- return pathname;
910
- }
911
- /**
912
- * Parses a string URL path into its separate pathname, search, and hash components.
913
- *
914
- * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#parsepath
915
- */
916
- function parsePath(path) {
917
- var parsedPath = {};
918
- if (path) {
919
- var hashIndex = path.indexOf("#");
920
- if (hashIndex >= 0) {
921
- parsedPath.hash = path.substr(hashIndex);
922
- path = path.substr(0, hashIndex);
923
- }
924
- var searchIndex = path.indexOf("?");
925
- if (searchIndex >= 0) {
926
- parsedPath.search = path.substr(searchIndex);
927
- path = path.substr(0, searchIndex);
928
- }
929
- if (path) parsedPath.pathname = path;
930
- }
931
- return parsedPath;
932
- }
933
- //#endregion
934
- //#region ../../node_modules/.bun/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/dist/urlpattern.js
935
- var Pe = Object.defineProperty;
936
- var a = (e, t) => Pe(e, "name", {
937
- value: t,
938
- configurable: !0
939
- });
940
- var P = class {
941
- type = 3;
942
- name = "";
943
- prefix = "";
944
- value = "";
945
- suffix = "";
946
- modifier = 3;
947
- constructor(t, r, n, c, l, f) {
948
- this.type = t, this.name = r, this.prefix = n, this.value = c, this.suffix = l, this.modifier = f;
949
- }
950
- hasCustomName() {
951
- return this.name !== "" && typeof this.name != "number";
952
- }
953
- };
954
- a(P, "Part");
955
- var Re = /[$_\p{ID_Start}]/u;
956
- var Ee = /[$_\u200C\u200D\p{ID_Continue}]/u;
957
- var v = ".*";
958
- function Oe(e, t) {
959
- return (t ? /^[\x00-\xFF]*$/ : /^[\x00-\x7F]*$/).test(e);
960
- }
961
- a(Oe, "isASCII");
962
- function D(e, t = !1) {
963
- let r = [], n = 0;
964
- for (; n < e.length;) {
965
- let c = e[n], l = a(function(f) {
966
- if (!t) throw new TypeError(f);
967
- r.push({
968
- type: "INVALID_CHAR",
969
- index: n,
970
- value: e[n++]
971
- });
972
- }, "ErrorOrInvalid");
973
- if (c === "*") {
974
- r.push({
975
- type: "ASTERISK",
976
- index: n,
977
- value: e[n++]
978
- });
979
- continue;
980
- }
981
- if (c === "+" || c === "?") {
982
- r.push({
983
- type: "OTHER_MODIFIER",
984
- index: n,
985
- value: e[n++]
986
- });
987
- continue;
988
- }
989
- if (c === "\\") {
990
- r.push({
991
- type: "ESCAPED_CHAR",
992
- index: n++,
993
- value: e[n++]
994
- });
995
- continue;
996
- }
997
- if (c === "{") {
998
- r.push({
999
- type: "OPEN",
1000
- index: n,
1001
- value: e[n++]
1002
- });
1003
- continue;
1004
- }
1005
- if (c === "}") {
1006
- r.push({
1007
- type: "CLOSE",
1008
- index: n,
1009
- value: e[n++]
1010
- });
1011
- continue;
1012
- }
1013
- if (c === ":") {
1014
- let f = "", s = n + 1;
1015
- for (; s < e.length;) {
1016
- let i = e.substr(s, 1);
1017
- if (s === n + 1 && Re.test(i) || s !== n + 1 && Ee.test(i)) {
1018
- f += e[s++];
1019
- continue;
1020
- }
1021
- break;
1022
- }
1023
- if (!f) {
1024
- l(`Missing parameter name at ${n}`);
1025
- continue;
1026
- }
1027
- r.push({
1028
- type: "NAME",
1029
- index: n,
1030
- value: f
1031
- }), n = s;
1032
- continue;
1033
- }
1034
- if (c === "(") {
1035
- let f = 1, s = "", i = n + 1, o = !1;
1036
- if (e[i] === "?") {
1037
- l(`Pattern cannot start with "?" at ${i}`);
1038
- continue;
1039
- }
1040
- for (; i < e.length;) {
1041
- if (!Oe(e[i], !1)) {
1042
- l(`Invalid character '${e[i]}' at ${i}.`), o = !0;
1043
- break;
1044
- }
1045
- if (e[i] === "\\") {
1046
- s += e[i++] + e[i++];
1047
- continue;
1048
- }
1049
- if (e[i] === ")") {
1050
- if (f--, f === 0) {
1051
- i++;
1052
- break;
1053
- }
1054
- } else if (e[i] === "(" && (f++, e[i + 1] !== "?")) {
1055
- l(`Capturing groups are not allowed at ${i}`), o = !0;
1056
- break;
1057
- }
1058
- s += e[i++];
1059
- }
1060
- if (o) continue;
1061
- if (f) {
1062
- l(`Unbalanced pattern at ${n}`);
1063
- continue;
1064
- }
1065
- if (!s) {
1066
- l(`Missing pattern at ${n}`);
1067
- continue;
1068
- }
1069
- r.push({
1070
- type: "REGEX",
1071
- index: n,
1072
- value: s
1073
- }), n = i;
1074
- continue;
1075
- }
1076
- r.push({
1077
- type: "CHAR",
1078
- index: n,
1079
- value: e[n++]
1080
- });
1081
- }
1082
- return r.push({
1083
- type: "END",
1084
- index: n,
1085
- value: ""
1086
- }), r;
1087
- }
1088
- a(D, "lexer");
1089
- function F(e, t = {}) {
1090
- let r = D(e);
1091
- t.delimiter ??= "/#?", t.prefixes ??= "./";
1092
- let n = `[^${x(t.delimiter)}]+?`, c = [], l = 0, f = 0, i = /* @__PURE__ */ new Set(), o = a((u) => {
1093
- if (f < r.length && r[f].type === u) return r[f++].value;
1094
- }, "tryConsume"), h = a(() => o("OTHER_MODIFIER") ?? o("ASTERISK"), "tryConsumeModifier"), p = a((u) => {
1095
- let d = o(u);
1096
- if (d !== void 0) return d;
1097
- let { type: g, index: y } = r[f];
1098
- throw new TypeError(`Unexpected ${g} at ${y}, expected ${u}`);
1099
- }, "mustConsume"), A = a(() => {
1100
- let u = "", d;
1101
- for (; d = o("CHAR") ?? o("ESCAPED_CHAR");) u += d;
1102
- return u;
1103
- }, "consumeText"), xe = a((u) => u, "DefaultEncodePart"), N = t.encodePart || xe, H = "", $ = a((u) => {
1104
- H += u;
1105
- }, "appendToPendingFixedValue"), M = a(() => {
1106
- H.length && (c.push(new P(3, "", "", N(H), "", 3)), H = "");
1107
- }, "maybeAddPartFromPendingFixedValue"), X = a((u, d, g, y, Z) => {
1108
- let m = 3;
1109
- switch (Z) {
1110
- case "?":
1111
- m = 1;
1112
- break;
1113
- case "*":
1114
- m = 0;
1115
- break;
1116
- case "+":
1117
- m = 2;
1118
- break;
1119
- }
1120
- if (!d && !g && m === 3) {
1121
- $(u);
1122
- return;
1123
- }
1124
- if (M(), !d && !g) {
1125
- if (!u) return;
1126
- c.push(new P(3, "", "", N(u), "", m));
1127
- return;
1128
- }
1129
- let S;
1130
- g ? g === "*" ? S = v : S = g : S = n;
1131
- let k = 2;
1132
- S === n ? (k = 1, S = "") : S === v && (k = 0, S = "");
1133
- let E;
1134
- if (d ? E = d : g && (E = l++), i.has(E)) throw new TypeError(`Duplicate name '${E}'.`);
1135
- i.add(E), c.push(new P(k, E, N(u), S, N(y), m));
1136
- }, "addPart");
1137
- for (; f < r.length;) {
1138
- let u = o("CHAR"), d = o("NAME"), g = o("REGEX");
1139
- if (!d && !g && (g = o("ASTERISK")), d || g) {
1140
- let m = u ?? "";
1141
- t.prefixes.indexOf(m) === -1 && ($(m), m = ""), M();
1142
- let S = h();
1143
- X(m, d, g, "", S);
1144
- continue;
1145
- }
1146
- let y = u ?? o("ESCAPED_CHAR");
1147
- if (y) {
1148
- $(y);
1149
- continue;
1150
- }
1151
- if (o("OPEN")) {
1152
- let m = A(), S = o("NAME"), k = o("REGEX");
1153
- !S && !k && (k = o("ASTERISK"));
1154
- let E = A();
1155
- p("CLOSE");
1156
- let be = h();
1157
- X(m, S, k, E, be);
1158
- continue;
1159
- }
1160
- M(), p("END");
1161
- }
1162
- return c;
1163
- }
1164
- a(F, "parse");
1165
- function x(e) {
1166
- return e.replace(/([.+*?^${}()[\]|/\\])/g, "\\$1");
1167
- }
1168
- a(x, "escapeString");
1169
- function B(e) {
1170
- return e && e.ignoreCase ? "ui" : "u";
1171
- }
1172
- a(B, "flags");
1173
- function q(e, t, r) {
1174
- return W(F(e, r), t, r);
1175
- }
1176
- a(q, "stringToRegexp");
1177
- function T(e) {
1178
- switch (e) {
1179
- case 0: return "*";
1180
- case 1: return "?";
1181
- case 2: return "+";
1182
- case 3: return "";
1183
- }
1184
- }
1185
- a(T, "modifierToString");
1186
- function W(e, t, r = {}) {
1187
- r.delimiter ??= "/#?", r.prefixes ??= "./", r.sensitive ??= !1, r.strict ??= !1, r.end ??= !0, r.start ??= !0, r.endsWith = "";
1188
- let n = r.start ? "^" : "";
1189
- for (let s of e) {
1190
- if (s.type === 3) {
1191
- s.modifier === 3 ? n += x(s.value) : n += `(?:${x(s.value)})${T(s.modifier)}`;
1192
- continue;
1193
- }
1194
- t && t.push(s.name);
1195
- let i = `[^${x(r.delimiter)}]+?`, o = s.value;
1196
- if (s.type === 1 ? o = i : s.type === 0 && (o = v), !s.prefix.length && !s.suffix.length) {
1197
- s.modifier === 3 || s.modifier === 1 ? n += `(${o})${T(s.modifier)}` : n += `((?:${o})${T(s.modifier)})`;
1198
- continue;
1199
- }
1200
- if (s.modifier === 3 || s.modifier === 1) {
1201
- n += `(?:${x(s.prefix)}(${o})${x(s.suffix)})`, n += T(s.modifier);
1202
- continue;
1203
- }
1204
- n += `(?:${x(s.prefix)}`, n += `((?:${o})(?:`, n += x(s.suffix), n += x(s.prefix), n += `(?:${o}))*)${x(s.suffix)})`, s.modifier === 0 && (n += "?");
1205
- }
1206
- let c = `[${x(r.endsWith)}]|$`, l = `[${x(r.delimiter)}]`;
1207
- if (r.end) return r.strict || (n += `${l}?`), r.endsWith.length ? n += `(?=${c})` : n += "$", new RegExp(n, B(r));
1208
- r.strict || (n += `(?:${l}(?=${c}))?`);
1209
- let f = !1;
1210
- if (e.length) {
1211
- let s = e[e.length - 1];
1212
- s.type === 3 && s.modifier === 3 && (f = r.delimiter.indexOf(s) > -1);
1213
- }
1214
- return f || (n += `(?=${l}|${c})`), new RegExp(n, B(r));
1215
- }
1216
- a(W, "partsToRegexp");
1217
- var b = {
1218
- delimiter: "",
1219
- prefixes: "",
1220
- sensitive: !0,
1221
- strict: !0
1222
- };
1223
- var J = {
1224
- delimiter: ".",
1225
- prefixes: "",
1226
- sensitive: !0,
1227
- strict: !0
1228
- };
1229
- var Q = {
1230
- delimiter: "/",
1231
- prefixes: "/",
1232
- sensitive: !0,
1233
- strict: !0
1234
- };
1235
- function ee(e, t) {
1236
- return e.length ? e[0] === "/" ? !0 : !t || e.length < 2 ? !1 : (e[0] == "\\" || e[0] == "{") && e[1] == "/" : !1;
1237
- }
1238
- a(ee, "isAbsolutePathname");
1239
- function te(e, t) {
1240
- return e.startsWith(t) ? e.substring(t.length, e.length) : e;
1241
- }
1242
- a(te, "maybeStripPrefix");
1243
- function ke(e, t) {
1244
- return e.endsWith(t) ? e.substr(0, e.length - t.length) : e;
1245
- }
1246
- a(ke, "maybeStripSuffix");
1247
- function _(e) {
1248
- return !e || e.length < 2 ? !1 : e[0] === "[" || (e[0] === "\\" || e[0] === "{") && e[1] === "[";
1249
- }
1250
- a(_, "treatAsIPv6Hostname");
1251
- var re = [
1252
- "ftp",
1253
- "file",
1254
- "http",
1255
- "https",
1256
- "ws",
1257
- "wss"
1258
- ];
1259
- function U(e) {
1260
- if (!e) return !0;
1261
- for (let t of re) if (e.test(t)) return !0;
1262
- return !1;
1263
- }
1264
- a(U, "isSpecialScheme");
1265
- function ne(e, t) {
1266
- if (e = te(e, "#"), t || e === "") return e;
1267
- let r = new URL("https://example.com");
1268
- return r.hash = e, r.hash ? r.hash.substring(1, r.hash.length) : "";
1269
- }
1270
- a(ne, "canonicalizeHash");
1271
- function se(e, t) {
1272
- if (e = te(e, "?"), t || e === "") return e;
1273
- let r = new URL("https://example.com");
1274
- return r.search = e, r.search ? r.search.substring(1, r.search.length) : "";
1275
- }
1276
- a(se, "canonicalizeSearch");
1277
- function ie(e, t) {
1278
- return t || e === "" ? e : _(e) ? K(e) : j(e);
1279
- }
1280
- a(ie, "canonicalizeHostname");
1281
- function ae(e, t) {
1282
- if (t || e === "") return e;
1283
- let r = new URL("https://example.com");
1284
- return r.password = e, r.password;
1285
- }
1286
- a(ae, "canonicalizePassword");
1287
- function oe(e, t) {
1288
- if (t || e === "") return e;
1289
- let r = new URL("https://example.com");
1290
- return r.username = e, r.username;
1291
- }
1292
- a(oe, "canonicalizeUsername");
1293
- function ce(e, t, r) {
1294
- if (r || e === "") return e;
1295
- if (t && !re.includes(t)) return new URL(`${t}:${e}`).pathname;
1296
- let n = e[0] == "/";
1297
- return e = new URL(n ? e : "/-" + e, "https://example.com").pathname, n || (e = e.substring(2, e.length)), e;
1298
- }
1299
- a(ce, "canonicalizePathname");
1300
- function le(e, t, r) {
1301
- return z(t) === e && (e = ""), r || e === "" ? e : G(e);
1302
- }
1303
- a(le, "canonicalizePort");
1304
- function fe(e, t) {
1305
- return e = ke(e, ":"), t || e === "" ? e : w(e);
1306
- }
1307
- a(fe, "canonicalizeProtocol");
1308
- function z(e) {
1309
- switch (e) {
1310
- case "ws":
1311
- case "http": return "80";
1312
- case "wws":
1313
- case "https": return "443";
1314
- case "ftp": return "21";
1315
- default: return "";
1316
- }
1317
- }
1318
- a(z, "defaultPortForProtocol");
1319
- function w(e) {
1320
- if (e === "") return e;
1321
- if (/^[-+.A-Za-z0-9]*$/.test(e)) return e.toLowerCase();
1322
- throw new TypeError(`Invalid protocol '${e}'.`);
1323
- }
1324
- a(w, "protocolEncodeCallback");
1325
- function he(e) {
1326
- if (e === "") return e;
1327
- let t = new URL("https://example.com");
1328
- return t.username = e, t.username;
1329
- }
1330
- a(he, "usernameEncodeCallback");
1331
- function ue(e) {
1332
- if (e === "") return e;
1333
- let t = new URL("https://example.com");
1334
- return t.password = e, t.password;
1335
- }
1336
- a(ue, "passwordEncodeCallback");
1337
- function j(e) {
1338
- if (e === "") return e;
1339
- if (/[\t\n\r #%/:<>?@[\]^\\|]/g.test(e)) throw new TypeError(`Invalid hostname '${e}'`);
1340
- let t = new URL("https://example.com");
1341
- return t.hostname = e, t.hostname;
1342
- }
1343
- a(j, "hostnameEncodeCallback");
1344
- function K(e) {
1345
- if (e === "") return e;
1346
- if (/[^0-9a-fA-F[\]:]/g.test(e)) throw new TypeError(`Invalid IPv6 hostname '${e}'`);
1347
- return e.toLowerCase();
1348
- }
1349
- a(K, "ipv6HostnameEncodeCallback");
1350
- function G(e) {
1351
- if (e === "" || /^[0-9]*$/.test(e) && parseInt(e) <= 65535) return e;
1352
- throw new TypeError(`Invalid port '${e}'.`);
1353
- }
1354
- a(G, "portEncodeCallback");
1355
- function de(e) {
1356
- if (e === "") return e;
1357
- let t = new URL("https://example.com");
1358
- return t.pathname = e[0] !== "/" ? "/-" + e : e, e[0] !== "/" ? t.pathname.substring(2, t.pathname.length) : t.pathname;
1359
- }
1360
- a(de, "standardURLPathnameEncodeCallback");
1361
- function pe(e) {
1362
- return e === "" ? e : new URL(`data:${e}`).pathname;
1363
- }
1364
- a(pe, "pathURLPathnameEncodeCallback");
1365
- function ge(e) {
1366
- if (e === "") return e;
1367
- let t = new URL("https://example.com");
1368
- return t.search = e, t.search.substring(1, t.search.length);
1369
- }
1370
- a(ge, "searchEncodeCallback");
1371
- function me(e) {
1372
- if (e === "") return e;
1373
- let t = new URL("https://example.com");
1374
- return t.hash = e, t.hash.substring(1, t.hash.length);
1375
- }
1376
- a(me, "hashEncodeCallback");
1377
- var C$1 = class {
1378
- #i;
1379
- #n = [];
1380
- #t = {};
1381
- #e = 0;
1382
- #s = 1;
1383
- #l = 0;
1384
- #o = 0;
1385
- #d = 0;
1386
- #p = 0;
1387
- #g = !1;
1388
- constructor(t) {
1389
- this.#i = t;
1390
- }
1391
- get result() {
1392
- return this.#t;
1393
- }
1394
- parse() {
1395
- for (this.#n = D(this.#i, !0); this.#e < this.#n.length; this.#e += this.#s) {
1396
- if (this.#s = 1, this.#n[this.#e].type === "END") {
1397
- if (this.#o === 0) {
1398
- this.#b(), this.#f() ? this.#r(9, 1) : this.#h() ? this.#r(8, 1) : this.#r(7, 0);
1399
- continue;
1400
- } else if (this.#o === 2) {
1401
- this.#u(5);
1402
- continue;
1403
- }
1404
- this.#r(10, 0);
1405
- break;
1406
- }
1407
- if (this.#d > 0) if (this.#A()) this.#d -= 1;
1408
- else continue;
1409
- if (this.#T()) {
1410
- this.#d += 1;
1411
- continue;
1412
- }
1413
- switch (this.#o) {
1414
- case 0:
1415
- this.#P() && this.#u(1);
1416
- break;
1417
- case 1:
1418
- if (this.#P()) {
1419
- this.#C();
1420
- let t = 7, r = 1;
1421
- this.#E() ? (t = 2, r = 3) : this.#g && (t = 2), this.#r(t, r);
1422
- }
1423
- break;
1424
- case 2:
1425
- this.#S() ? this.#u(3) : (this.#x() || this.#h() || this.#f()) && this.#u(5);
1426
- break;
1427
- case 3:
1428
- this.#O() ? this.#r(4, 1) : this.#S() && this.#r(5, 1);
1429
- break;
1430
- case 4:
1431
- this.#S() && this.#r(5, 1);
1432
- break;
1433
- case 5:
1434
- this.#y() ? this.#p += 1 : this.#w() && (this.#p -= 1), this.#k() && !this.#p ? this.#r(6, 1) : this.#x() ? this.#r(7, 0) : this.#h() ? this.#r(8, 1) : this.#f() && this.#r(9, 1);
1435
- break;
1436
- case 6:
1437
- this.#x() ? this.#r(7, 0) : this.#h() ? this.#r(8, 1) : this.#f() && this.#r(9, 1);
1438
- break;
1439
- case 7:
1440
- this.#h() ? this.#r(8, 1) : this.#f() && this.#r(9, 1);
1441
- break;
1442
- case 8:
1443
- this.#f() && this.#r(9, 1);
1444
- break;
1445
- case 9: break;
1446
- case 10: break;
1447
- }
1448
- }
1449
- this.#t.hostname !== void 0 && this.#t.port === void 0 && (this.#t.port = "");
1450
- }
1451
- #r(t, r) {
1452
- switch (this.#o) {
1453
- case 0: break;
1454
- case 1:
1455
- this.#t.protocol = this.#c();
1456
- break;
1457
- case 2: break;
1458
- case 3:
1459
- this.#t.username = this.#c();
1460
- break;
1461
- case 4:
1462
- this.#t.password = this.#c();
1463
- break;
1464
- case 5:
1465
- this.#t.hostname = this.#c();
1466
- break;
1467
- case 6:
1468
- this.#t.port = this.#c();
1469
- break;
1470
- case 7:
1471
- this.#t.pathname = this.#c();
1472
- break;
1473
- case 8:
1474
- this.#t.search = this.#c();
1475
- break;
1476
- case 9:
1477
- this.#t.hash = this.#c();
1478
- break;
1479
- case 10: break;
1480
- }
1481
- this.#o !== 0 && t !== 10 && ([
1482
- 1,
1483
- 2,
1484
- 3,
1485
- 4
1486
- ].includes(this.#o) && [
1487
- 6,
1488
- 7,
1489
- 8,
1490
- 9
1491
- ].includes(t) && (this.#t.hostname ??= ""), [
1492
- 1,
1493
- 2,
1494
- 3,
1495
- 4,
1496
- 5,
1497
- 6
1498
- ].includes(this.#o) && [8, 9].includes(t) && (this.#t.pathname ??= this.#g ? "/" : ""), [
1499
- 1,
1500
- 2,
1501
- 3,
1502
- 4,
1503
- 5,
1504
- 6,
1505
- 7
1506
- ].includes(this.#o) && t === 9 && (this.#t.search ??= "")), this.#R(t, r);
1507
- }
1508
- #R(t, r) {
1509
- this.#o = t, this.#l = this.#e + r, this.#e += r, this.#s = 0;
1510
- }
1511
- #b() {
1512
- this.#e = this.#l, this.#s = 0;
1513
- }
1514
- #u(t) {
1515
- this.#b(), this.#o = t;
1516
- }
1517
- #m(t) {
1518
- return t < 0 && (t = this.#n.length - t), t < this.#n.length ? this.#n[t] : this.#n[this.#n.length - 1];
1519
- }
1520
- #a(t, r) {
1521
- let n = this.#m(t);
1522
- return n.value === r && (n.type === "CHAR" || n.type === "ESCAPED_CHAR" || n.type === "INVALID_CHAR");
1523
- }
1524
- #P() {
1525
- return this.#a(this.#e, ":");
1526
- }
1527
- #E() {
1528
- return this.#a(this.#e + 1, "/") && this.#a(this.#e + 2, "/");
1529
- }
1530
- #S() {
1531
- return this.#a(this.#e, "@");
1532
- }
1533
- #O() {
1534
- return this.#a(this.#e, ":");
1535
- }
1536
- #k() {
1537
- return this.#a(this.#e, ":");
1538
- }
1539
- #x() {
1540
- return this.#a(this.#e, "/");
1541
- }
1542
- #h() {
1543
- if (this.#a(this.#e, "?")) return !0;
1544
- if (this.#n[this.#e].value !== "?") return !1;
1545
- let t = this.#m(this.#e - 1);
1546
- return t.type !== "NAME" && t.type !== "REGEX" && t.type !== "CLOSE" && t.type !== "ASTERISK";
1547
- }
1548
- #f() {
1549
- return this.#a(this.#e, "#");
1550
- }
1551
- #T() {
1552
- return this.#n[this.#e].type == "OPEN";
1553
- }
1554
- #A() {
1555
- return this.#n[this.#e].type == "CLOSE";
1556
- }
1557
- #y() {
1558
- return this.#a(this.#e, "[");
1559
- }
1560
- #w() {
1561
- return this.#a(this.#e, "]");
1562
- }
1563
- #c() {
1564
- let t = this.#n[this.#e], r = this.#m(this.#l).index;
1565
- return this.#i.substring(r, t.index);
1566
- }
1567
- #C() {
1568
- let t = {};
1569
- Object.assign(t, b), t.encodePart = w;
1570
- let r = q(this.#c(), void 0, t);
1571
- this.#g = U(r);
1572
- }
1573
- };
1574
- a(C$1, "Parser");
1575
- var V = [
1576
- "protocol",
1577
- "username",
1578
- "password",
1579
- "hostname",
1580
- "port",
1581
- "pathname",
1582
- "search",
1583
- "hash"
1584
- ];
1585
- var O = "*";
1586
- function Se(e, t) {
1587
- if (typeof e != "string") throw new TypeError("parameter 1 is not of type 'string'.");
1588
- let r = new URL(e, t);
1589
- return {
1590
- protocol: r.protocol.substring(0, r.protocol.length - 1),
1591
- username: r.username,
1592
- password: r.password,
1593
- hostname: r.hostname,
1594
- port: r.port,
1595
- pathname: r.pathname,
1596
- search: r.search !== "" ? r.search.substring(1, r.search.length) : void 0,
1597
- hash: r.hash !== "" ? r.hash.substring(1, r.hash.length) : void 0
1598
- };
1599
- }
1600
- a(Se, "extractValues");
1601
- function R(e, t) {
1602
- return t ? I(e) : e;
1603
- }
1604
- a(R, "processBaseURLString");
1605
- function L(e, t, r) {
1606
- let n;
1607
- if (typeof t.baseURL == "string") try {
1608
- n = new URL(t.baseURL), t.protocol === void 0 && (e.protocol = R(n.protocol.substring(0, n.protocol.length - 1), r)), !r && t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.username === void 0 && (e.username = R(n.username, r)), !r && t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.username === void 0 && t.password === void 0 && (e.password = R(n.password, r)), t.protocol === void 0 && t.hostname === void 0 && (e.hostname = R(n.hostname, r)), t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && (e.port = R(n.port, r)), t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.pathname === void 0 && (e.pathname = R(n.pathname, r)), t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.pathname === void 0 && t.search === void 0 && (e.search = R(n.search.substring(1, n.search.length), r)), t.protocol === void 0 && t.hostname === void 0 && t.port === void 0 && t.pathname === void 0 && t.search === void 0 && t.hash === void 0 && (e.hash = R(n.hash.substring(1, n.hash.length), r));
1609
- } catch {
1610
- throw new TypeError(`invalid baseURL '${t.baseURL}'.`);
1611
- }
1612
- if (typeof t.protocol == "string" && (e.protocol = fe(t.protocol, r)), typeof t.username == "string" && (e.username = oe(t.username, r)), typeof t.password == "string" && (e.password = ae(t.password, r)), typeof t.hostname == "string" && (e.hostname = ie(t.hostname, r)), typeof t.port == "string" && (e.port = le(t.port, e.protocol, r)), typeof t.pathname == "string") {
1613
- if (e.pathname = t.pathname, n && !ee(e.pathname, r)) {
1614
- let c = n.pathname.lastIndexOf("/");
1615
- c >= 0 && (e.pathname = R(n.pathname.substring(0, c + 1), r) + e.pathname);
1616
- }
1617
- e.pathname = ce(e.pathname, e.protocol, r);
1618
- }
1619
- return typeof t.search == "string" && (e.search = se(t.search, r)), typeof t.hash == "string" && (e.hash = ne(t.hash, r)), e;
1620
- }
1621
- a(L, "applyInit");
1622
- function I(e) {
1623
- return e.replace(/([+*?:{}()\\])/g, "\\$1");
1624
- }
1625
- a(I, "escapePatternString");
1626
- function Te(e) {
1627
- return e.replace(/([.+*?^${}()[\]|/\\])/g, "\\$1");
1628
- }
1629
- a(Te, "escapeRegexpString");
1630
- function Ae(e, t) {
1631
- t.delimiter ??= "/#?", t.prefixes ??= "./", t.sensitive ??= !1, t.strict ??= !1, t.end ??= !0, t.start ??= !0, t.endsWith = "";
1632
- let r = ".*", n = `[^${Te(t.delimiter)}]+?`, c = /[$_\u200C\u200D\p{ID_Continue}]/u, l = "";
1633
- for (let f = 0; f < e.length; ++f) {
1634
- let s = e[f];
1635
- if (s.type === 3) {
1636
- if (s.modifier === 3) {
1637
- l += I(s.value);
1638
- continue;
1639
- }
1640
- l += `{${I(s.value)}}${T(s.modifier)}`;
1641
- continue;
1642
- }
1643
- let i = s.hasCustomName(), o = !!s.suffix.length || !!s.prefix.length && (s.prefix.length !== 1 || !t.prefixes.includes(s.prefix)), h = f > 0 ? e[f - 1] : null, p = f < e.length - 1 ? e[f + 1] : null;
1644
- if (!o && i && s.type === 1 && s.modifier === 3 && p && !p.prefix.length && !p.suffix.length) if (p.type === 3) {
1645
- let A = p.value.length > 0 ? p.value[0] : "";
1646
- o = c.test(A);
1647
- } else o = !p.hasCustomName();
1648
- if (!o && !s.prefix.length && h && h.type === 3) {
1649
- let A = h.value[h.value.length - 1];
1650
- o = t.prefixes.includes(A);
1651
- }
1652
- o && (l += "{"), l += I(s.prefix), i && (l += `:${s.name}`), s.type === 2 ? l += `(${s.value})` : s.type === 1 ? i || (l += `(${n})`) : s.type === 0 && (!i && (!h || h.type === 3 || h.modifier !== 3 || o || s.prefix !== "") ? l += "*" : l += `(${r})`), s.type === 1 && i && s.suffix.length && c.test(s.suffix[0]) && (l += "\\"), l += I(s.suffix), o && (l += "}"), s.modifier !== 3 && (l += T(s.modifier));
1653
- }
1654
- return l;
1655
- }
1656
- a(Ae, "partsToPattern");
1657
- var Y = class {
1658
- #i;
1659
- #n = {};
1660
- #t = {};
1661
- #e = {};
1662
- #s = {};
1663
- #l = !1;
1664
- constructor(t = {}, r, n) {
1665
- try {
1666
- let c;
1667
- if (typeof r == "string" ? c = r : n = r, typeof t == "string") {
1668
- let i = new C$1(t);
1669
- if (i.parse(), t = i.result, c === void 0 && typeof t.protocol != "string") throw new TypeError("A base URL must be provided for a relative constructor string.");
1670
- t.baseURL = c;
1671
- } else {
1672
- if (!t || typeof t != "object") throw new TypeError("parameter 1 is not of type 'string' and cannot convert to dictionary.");
1673
- if (c) throw new TypeError("parameter 1 is not of type 'string'.");
1674
- }
1675
- typeof n > "u" && (n = { ignoreCase: !1 });
1676
- let l = { ignoreCase: n.ignoreCase === !0 }, f = {
1677
- pathname: O,
1678
- protocol: O,
1679
- username: O,
1680
- password: O,
1681
- hostname: O,
1682
- port: O,
1683
- search: O,
1684
- hash: O
1685
- };
1686
- this.#i = L(f, t, !0), z(this.#i.protocol) === this.#i.port && (this.#i.port = "");
1687
- let s;
1688
- for (s of V) {
1689
- if (!(s in this.#i)) continue;
1690
- let i = {}, o = this.#i[s];
1691
- switch (this.#t[s] = [], s) {
1692
- case "protocol":
1693
- Object.assign(i, b), i.encodePart = w;
1694
- break;
1695
- case "username":
1696
- Object.assign(i, b), i.encodePart = he;
1697
- break;
1698
- case "password":
1699
- Object.assign(i, b), i.encodePart = ue;
1700
- break;
1701
- case "hostname":
1702
- Object.assign(i, J), _(o) ? i.encodePart = K : i.encodePart = j;
1703
- break;
1704
- case "port":
1705
- Object.assign(i, b), i.encodePart = G;
1706
- break;
1707
- case "pathname":
1708
- U(this.#n.protocol) ? (Object.assign(i, Q, l), i.encodePart = de) : (Object.assign(i, b, l), i.encodePart = pe);
1709
- break;
1710
- case "search":
1711
- Object.assign(i, b, l), i.encodePart = ge;
1712
- break;
1713
- case "hash":
1714
- Object.assign(i, b, l), i.encodePart = me;
1715
- break;
1716
- }
1717
- try {
1718
- this.#s[s] = F(o, i), this.#n[s] = W(this.#s[s], this.#t[s], i), this.#e[s] = Ae(this.#s[s], i), this.#l = this.#l || this.#s[s].some((h) => h.type === 2);
1719
- } catch {
1720
- throw new TypeError(`invalid ${s} pattern '${this.#i[s]}'.`);
1721
- }
1722
- }
1723
- } catch (c) {
1724
- throw new TypeError(`Failed to construct 'URLPattern': ${c.message}`);
1725
- }
1726
- }
1727
- get [Symbol.toStringTag]() {
1728
- return "URLPattern";
1729
- }
1730
- test(t = {}, r) {
1731
- let n = {
1732
- pathname: "",
1733
- protocol: "",
1734
- username: "",
1735
- password: "",
1736
- hostname: "",
1737
- port: "",
1738
- search: "",
1739
- hash: ""
1740
- };
1741
- if (typeof t != "string" && r) throw new TypeError("parameter 1 is not of type 'string'.");
1742
- if (typeof t > "u") return !1;
1743
- try {
1744
- typeof t == "object" ? n = L(n, t, !1) : n = L(n, Se(t, r), !1);
1745
- } catch {
1746
- return !1;
1747
- }
1748
- let c;
1749
- for (c of V) if (!this.#n[c].exec(n[c])) return !1;
1750
- return !0;
1751
- }
1752
- exec(t = {}, r) {
1753
- let n = {
1754
- pathname: "",
1755
- protocol: "",
1756
- username: "",
1757
- password: "",
1758
- hostname: "",
1759
- port: "",
1760
- search: "",
1761
- hash: ""
1762
- };
1763
- if (typeof t != "string" && r) throw new TypeError("parameter 1 is not of type 'string'.");
1764
- if (typeof t > "u") return;
1765
- try {
1766
- typeof t == "object" ? n = L(n, t, !1) : n = L(n, Se(t, r), !1);
1767
- } catch {
1768
- return null;
1769
- }
1770
- let c = {};
1771
- r ? c.inputs = [t, r] : c.inputs = [t];
1772
- let l;
1773
- for (l of V) {
1774
- let f = this.#n[l].exec(n[l]);
1775
- if (!f) return null;
1776
- let s = {};
1777
- for (let [i, o] of this.#t[l].entries()) if (typeof o == "string" || typeof o == "number") s[o] = f[i + 1];
1778
- c[l] = {
1779
- input: n[l] ?? "",
1780
- groups: s
1781
- };
1782
- }
1783
- return c;
1784
- }
1785
- static compareComponent(t, r, n) {
1786
- let c = a((i, o) => {
1787
- for (let h of [
1788
- "type",
1789
- "modifier",
1790
- "prefix",
1791
- "value",
1792
- "suffix"
1793
- ]) {
1794
- if (i[h] < o[h]) return -1;
1795
- if (i[h] === o[h]) continue;
1796
- return 1;
1797
- }
1798
- return 0;
1799
- }, "comparePart"), l = new P(3, "", "", "", "", 3), f = new P(0, "", "", "", "", 3), s = a((i, o) => {
1800
- let h = 0;
1801
- for (; h < Math.min(i.length, o.length); ++h) {
1802
- let p = c(i[h], o[h]);
1803
- if (p) return p;
1804
- }
1805
- return i.length === o.length ? 0 : c(i[h] ?? l, o[h] ?? l);
1806
- }, "comparePartList");
1807
- return !r.#e[t] && !n.#e[t] ? 0 : r.#e[t] && !n.#e[t] ? s(r.#s[t], [f]) : !r.#e[t] && n.#e[t] ? s([f], n.#s[t]) : s(r.#s[t], n.#s[t]);
1808
- }
1809
- get protocol() {
1810
- return this.#e.protocol;
1811
- }
1812
- get username() {
1813
- return this.#e.username;
1814
- }
1815
- get password() {
1816
- return this.#e.password;
1817
- }
1818
- get hostname() {
1819
- return this.#e.hostname;
1820
- }
1821
- get port() {
1822
- return this.#e.port;
1823
- }
1824
- get pathname() {
1825
- return this.#e.pathname;
1826
- }
1827
- get search() {
1828
- return this.#e.search;
1829
- }
1830
- get hash() {
1831
- return this.#e.hash;
1832
- }
1833
- get hasRegExpGroups() {
1834
- return this.#l;
1835
- }
1836
- };
1837
- a(Y, "URLPattern");
1838
- //#endregion
1839
- //#region ../../node_modules/.bun/urlpattern-polyfill@10.1.0/node_modules/urlpattern-polyfill/index.js
1840
- if (!globalThis.URLPattern) globalThis.URLPattern = Y;
1841
- //#endregion
1842
- //#region utils/sleep.ts
1843
- function sleep(time) {
1844
- return new Promise((resolve) => setTimeout(resolve, time));
1845
- }
1846
- //#endregion
1847
- //#region client/ProgressManager.ts
1848
- var ProgressManager = class {
1849
- state = new Subject(100);
1850
- unsubscribe;
1851
- timer;
1852
- tick = 0;
1853
- isTicking = false;
1854
- constructor(subject) {
1855
- this.unsubscribe = subject.subscribe((state) => {
1856
- if (state) this.start();
1857
- else this.end();
1858
- });
1859
- }
1860
- getNextIncrement() {
1861
- const current = this.state.getValue();
1862
- if (current === 100) return Math.ceil(Math.random() * 10);
1863
- if (current <= 20) {
1864
- if (Math.ceil(Math.random() * 100) > 80) return current;
1865
- return current + Math.ceil(Math.random() * 5) + 1;
1866
- }
1867
- if (current <= 50) {
1868
- if (Math.ceil(Math.random() * 100) > 50) return current;
1869
- return Math.min(current + Math.ceil(Math.random() * 10), 70);
1870
- }
1871
- if (current <= 70) {
1872
- if (Math.ceil(Math.random() * 100) > 60) return current;
1873
- return Math.min(current + Math.ceil(Math.random() * 3), 80);
1874
- }
1875
- if (current <= 80) return Math.min(current + Math.ceil(Math.random() * 1), 90);
1876
- if (current <= 90) {
1877
- const x = Math.ceil(Math.random() * 100) > 50 ? 0 : 1;
1878
- return Math.min(current + x, 94);
1879
- }
1880
- if (current <= 94) {
1881
- const x = Math.ceil(Math.random() * 100) > 20 ? 0 : 1;
1882
- return Math.min(current + x, 99);
1883
- }
1884
- }
1885
- getNextInterval() {
1886
- if (this.tick === 0) {
1887
- this.tick = 1;
1888
- return 200;
1889
- }
1890
- const current = this.state.getValue();
1891
- if (current >= 88) return 400;
1892
- if (current >= 94) return 1e3;
1893
- if (current >= 98) return 2e3;
1894
- return 100;
1895
- }
1896
- async nextTick() {
1897
- if (!this.isTicking) return;
1898
- await sleep(this.getNextInterval());
1899
- if (!this.isTicking) return;
1900
- const increment = this.getNextIncrement();
1901
- this.state.next(Math.min(increment, 96));
1902
- await this.nextTick();
1903
- }
1904
- start() {
1905
- this.isTicking = true;
1906
- this.nextTick();
1907
- }
1908
- end() {
1909
- this.state.next(99);
1910
- this.isTicking = false;
1911
- this.tick = 0;
1912
- setTimeout(() => {
1913
- this.state.next(100);
1914
- }, 200);
1915
- }
1916
- destroy() {
1917
- this.end();
1918
- this.unsubscribe();
1919
- }
1920
- };
1921
- //#endregion
1922
- //#region client/useLocation.ts
1923
- function useLocation() {
1924
- const ctx = useContext(RouteStateContext);
1925
- if (!ctx) throw new Error("Router context not found");
1926
- const { hash, pathname, search, state, locale } = ctx;
1927
- return {
1928
- hash,
1929
- key: pathname,
1930
- pathname,
1931
- search,
1932
- state,
1933
- locale
1934
- };
1935
- }
1936
- //#endregion
1937
- //#region client/ServerDataProvider.tsx
1938
- var ServerDataContext = createContext({});
1939
- var ServerDataProvider = (props) => {
1940
- let _value = props.value;
1941
- if (props.value) _value = props.value;
1942
- else _value = window.__GEMI_DATA__;
1943
- return /* @__PURE__ */ jsx(ServerDataContext.Provider, {
1944
- value: _value,
1945
- children: props.children
1946
- });
1947
- };
1948
- //#endregion
1949
- //#region client/I18nContext.tsx
1950
- var I18nContext = createContext({});
1951
- var I18nProvider = (props) => {
1952
- const { i18n } = useContext(ServerDataContext);
1953
- const [currentLocale, setCurrentLocale] = useState(i18n.currentLocale);
1954
- const dictionary = useRef((() => {
1955
- const dictionary = /* @__PURE__ */ new Map();
1956
- for (const [locale, value] of Object.entries(i18n?.dictionary ?? {})) {
1957
- const components = /* @__PURE__ */ new Map();
1958
- for (const [component, translations] of Object.entries(value)) components.set(component, translations);
1959
- dictionary.set(locale, components);
1960
- }
1961
- return dictionary;
1962
- })());
1963
- function updateDictionary(translations = {}, locale) {
1964
- for (const [locale, value] of Object.entries(translations)) {
1965
- if (!dictionary.current.has(locale)) dictionary.current.set(locale, /* @__PURE__ */ new Map());
1966
- const scopes = dictionary.current.get(locale);
1967
- for (const [scope, translations] of Object.entries(value)) {
1968
- if (!scopes.has(scope)) scopes.set(scope, {});
1969
- scopes.set(scope, translations);
1970
- }
1971
- }
1972
- changeLocale(locale);
1973
- }
1974
- const changeLocale = (locale) => {
1975
- if (dictionary.current.has(locale)) setCurrentLocale(locale);
1976
- };
1977
- const getTranslations = (locale) => {
1978
- return (component) => {
1979
- return dictionary.current.get(locale).get(component);
1980
- };
1981
- };
1982
- const fetchTranslations = async (pathname, locale, signal) => {
1983
- if (Object.keys(i18n).length === 0) return;
1984
- updateDictionary(await (await fetch(`/api/__gemi__/services/i18n/translations/${locale || currentLocale}${pathname === "/" ? "" : pathname}`, { signal })).json());
1985
- };
1986
- return /* @__PURE__ */ jsx(I18nContext.Provider, {
1987
- value: {
1988
- getComponentTranslations: getTranslations(currentLocale),
1989
- locale: currentLocale,
1990
- changeLocale,
1991
- updateDictionary,
1992
- fetchTranslations,
1993
- supportedLocales: i18n.supportedLocales,
1994
- defaultLocale: i18n.defaultLocale
1995
- },
1996
- children: props.children
1997
- });
1998
- };
1999
- //#endregion
2000
- //#region client/useNavigate.ts
2001
- function useNavigate() {
2002
- const { history, setNavigationAbortController } = useContext(ClientRouterContext);
2003
- const { defaultLocale } = useContext(I18nContext);
2004
- const location = useLocation();
2005
- function action(pushOrReplace) {
2006
- return async (path, ...args) => {
2007
- const navigationAbortController = new AbortController();
2008
- if (setNavigationAbortController) setNavigationAbortController(navigationAbortController);
2009
- const [options = {}] = args;
2010
- const { search = {}, params = {}, shallow, locale, hash } = {
2011
- params: {},
2012
- shallow: false,
2013
- locale: null,
2014
- hash: "",
2015
- ...options
2016
- };
2017
- const urlSearchParams = new URLSearchParams(search);
2018
- let localeSegment = location.locale;
2019
- if (locale) localeSegment = locale;
2020
- if (localeSegment === defaultLocale) localeSegment = "";
2021
- const routePath = applyParams$1(path, params);
2022
- const finalPath = [[`${localeSegment ? `/${localeSegment}` : ""}${routePath === "/" ? "" : routePath}`, urlSearchParams.toString()].filter((s) => s.length > 0).join("?"), hash].filter(Boolean).join("");
2023
- if (shallow) {
2024
- history?.[pushOrReplace](finalPath, { shallow });
2025
- return;
2026
- }
2027
- history?.[pushOrReplace](finalPath === "" ? "/" : finalPath);
2028
- };
2029
- }
2030
- return {
2031
- push: action("push"),
2032
- replace: action("replace")
2033
- };
2034
- }
2035
- //#endregion
2036
- //#region client/useSearchParams.ts
2037
- var SearchParams = class {
2038
- searchParams;
2039
- callback;
2040
- constructor(searchParams, callback) {
2041
- this.searchParams = searchParams;
2042
- this.callback = callback;
2043
- }
2044
- get(key) {
2045
- return this.searchParams.get(key);
2046
- }
2047
- set(key, value) {
2048
- let entries = {};
2049
- if (typeof key === "string") {
2050
- let _value = value;
2051
- if (typeof value === "function") _value = value(this.get(key) ?? "");
2052
- entries[key] = _value;
2053
- } else entries = key ?? {};
2054
- for (const [key, value] of Object.entries(entries)) {
2055
- let _value = value;
2056
- if (typeof value === "function") _value = value(this.get(key) ?? "");
2057
- this.searchParams.set(key, _value);
2058
- }
2059
- return this;
2060
- }
2061
- append(key, value) {
2062
- this.searchParams.append(key, value);
2063
- return this;
2064
- }
2065
- sort() {
2066
- this.searchParams.sort();
2067
- return this;
2068
- }
2069
- clear() {
2070
- this.searchParams = new URLSearchParams();
2071
- return this;
2072
- }
2073
- delete(key) {
2074
- const keys = Array.isArray(key) ? key : [key];
2075
- for (const key of keys) this.searchParams.delete(key);
2076
- return this;
2077
- }
2078
- toJSON() {
2079
- const map = /* @__PURE__ */ new Map();
2080
- for (const [key, value] of this.searchParams) if (map.has(key)) {
2081
- const currentValue = map.get(key);
2082
- if (Array.isArray(currentValue)) {
2083
- currentValue.push(value);
2084
- map.set(key, currentValue);
2085
- } else map.set(key, [currentValue, value]);
2086
- } else map.set(key, value);
2087
- return Object.fromEntries(map.entries());
2088
- }
2089
- toString() {
2090
- return this.searchParams.toString();
2091
- }
2092
- push(mode = "soft") {
2093
- this.callback(this.toJSON(), mode === "soft");
2094
- }
2095
- };
2096
- function useSearchParams() {
2097
- const { push } = useNavigate();
2098
- const { search, pathname } = useContext(RouteStateContext);
2099
- const params = useParams();
2100
- const callback = (search, shallow) => {
2101
- push(pathname, {
2102
- params,
2103
- search,
2104
- shallow
2105
- });
2106
- };
2107
- return new SearchParams(new URLSearchParams(search), callback);
2108
- }
2109
- //#endregion
2110
- //#region client/useRoute.ts
2111
- function useRoute() {
2112
- const { pathname: _pathname } = useContext(RouteStateContext);
2113
- return {
2114
- pathname: _pathname,
2115
- startsWith: (pathname) => {
2116
- return _pathname.startsWith(pathname);
137
+ retryIntervalRef.current = setTimeout(() => {
138
+ resource.getVariant(vk, configRef.current.staleTime);
139
+ retryingMap.current.set(vk, false);
140
+ }, configRef.current.retryIntervalOnError);
2117
141
  }
2118
- };
2119
- }
2120
- //#endregion
2121
- //#region client/HttpReload.tsx
2122
- var HttpReload = () => {
2123
- const { replace } = useNavigate();
2124
- useSearchParams();
2125
- const { pathname } = useRoute();
2126
- useParams();
2127
- const [reloading, setReloading] = useState(false);
2128
- const handleReload = () => {
2129
- if (typeof document !== "undefined") document.querySelectorAll("vite-error-overlay").forEach((el) => {
2130
- if (typeof el.close === "function") el.close();
2131
- else el.remove();
2132
- });
2133
- setReloading(true);
2134
- };
142
+ }, [resource]);
2135
143
  useEffect(() => {
2136
- if (import.meta.hot) import.meta.hot.on("http-reload", handleReload);
144
+ if (fetchedRef.current) resource.getVariant(variantKey, configRef.current.staleTime);
2137
145
  return () => {
2138
- if (import.meta.hot) import.meta.hot.off("http-reload", handleReload);
146
+ clearTimeout(retryIntervalRef.current);
2139
147
  };
2140
- }, [handleReload]);
2141
- if (!reloading || typeof document === "undefined") return null;
2142
- return createPortal(/* @__PURE__ */ jsx("div", {
2143
- className: "fixed z-[1000] bottom-0 right-0 p-2",
2144
- children: /* @__PURE__ */ jsx("div", {
2145
- className: "p-2 bg-white text-black rounded-md shadow-md",
2146
- children: "..."
2147
- })
2148
- }), document.body);
2149
- };
2150
- //#endregion
2151
- //#region client/PrefetchCache.ts
2152
- /**
2153
- * How long a prefetched payload stays usable. Long enough to cover the gap
2154
- * between hovering a link and clicking it, short enough that a navigation is
2155
- * not served a snapshot the visitor would notice as out of date.
2156
- *
2157
- * A payload cached here is committed wholesale on navigation — including into
2158
- * the query cache via `hydrate` — so anything that invalidates page data has to
2159
- * `clear()` this too. `useMutation` does exactly that on every successful
2160
- * write; locale needs no such call, since the locale segment is part of the key.
2161
- */
2162
- var PREFETCH_TTL = 1e4;
2163
- /**
2164
- * Payloads fetched ahead of a navigation, keyed by the `.json` URL that
2165
- * navigation would request. Entries are handed over once — a navigation that
2166
- * consumes one becomes the live route data, so keeping a copy around would only
2167
- * let a later visit render from a stale snapshot.
2168
- */
2169
- var PrefetchCache = class {
2170
- entries = /* @__PURE__ */ new Map();
2171
- isFresh(entry) {
2172
- return Date.now() - entry.createdAt < PREFETCH_TTL;
2173
- }
2174
- /** Drops what has expired, then the oldest of whatever is still over budget. */
2175
- evict() {
2176
- for (const [url, entry] of this.entries) if (!this.isFresh(entry)) this.entries.delete(url);
2177
- while (this.entries.size >= 12) {
2178
- const oldest = this.entries.keys().next().value;
2179
- if (oldest === void 0) return;
2180
- this.entries.delete(oldest);
148
+ }, [variantKey, resource]);
149
+ useEffect(() => {
150
+ if (!suspense && snapshot?.error) retry(variantKey);
151
+ }, [
152
+ snapshot,
153
+ suspense,
154
+ retry,
155
+ variantKey
156
+ ]);
157
+ useEffect(() => {
158
+ const cfg = configRef.current;
159
+ if (!cfg.refetchUntil) return;
160
+ if (snapshot && !snapshot.loading && snapshot.hasData && !snapshot.error) {
161
+ const nextDuration = cfg.refetchUntil(snapshot.data, refetchUntilDurationRef.current);
162
+ if (nextDuration > 0) {
163
+ refetchUntilDurationRef.current = nextDuration;
164
+ refetchUntilTimerRef.current = setTimeout(() => {
165
+ resource.refetch(variantKey);
166
+ }, nextDuration);
167
+ } else refetchUntilDurationRef.current = 0;
2181
168
  }
2182
- }
2183
- /**
2184
- * Runs `load` unless the same URL is already in flight or freshly cached, so
2185
- * a link hovered repeatedly — or a screenful of eagerly prefetched links
2186
- * pointing at one route — costs a single request.
2187
- */
2188
- prime(url, load) {
2189
- const existing = this.entries.get(url);
2190
- if (existing && this.isFresh(existing)) return existing.promise;
2191
- this.evict();
2192
- const entry = {
2193
- createdAt: Date.now(),
2194
- promise: null
169
+ return () => {
170
+ if (refetchUntilTimerRef.current) clearTimeout(refetchUntilTimerRef.current);
2195
171
  };
2196
- entry.promise = load().catch(() => null).then((payload) => {
2197
- if (payload == null && this.entries.get(url) === entry) this.entries.delete(url);
2198
- return payload;
2199
- });
2200
- this.entries.set(url, entry);
2201
- return entry.promise;
2202
- }
2203
- /**
2204
- * Hands the payload for `url` to a navigation, if one was prefetched and is
2205
- * still fresh. Resolves to `null` when the prefetch failed, which callers
2206
- * must treat as a miss.
2207
- */
2208
- take(url) {
2209
- const entry = this.entries.get(url);
2210
- if (!entry) return null;
2211
- this.entries.delete(url);
2212
- return this.isFresh(entry) ? entry.promise : null;
2213
- }
2214
- /**
2215
- * Drops everything, for when the data behind these payloads may have moved
2216
- * on. In-flight loads still settle; their entries are simply gone by then.
2217
- */
2218
- clear() {
2219
- this.entries.clear();
2220
- }
2221
- /** Retained entries, fresh or not. Exposed for tests. */
2222
- get size() {
2223
- return this.entries.size;
2224
- }
2225
- };
2226
- //#endregion
2227
- //#region client/helpers/routeDataUrl.ts
2228
- /**
2229
- * The `.json` URL a route's page data is served from.
2230
- *
2231
- * Prefetching and navigation have to agree on this string exactly — the
2232
- * prefetch cache is keyed by it, and any disagreement silently turns every
2233
- * prefetch into a wasted request plus a full fetch on click.
2234
- */
2235
- function routeDataUrl(options) {
2236
- const { pathname, search = "", localeSegment = "" } = options;
2237
- return `${localeSegment}${localeSegment.length > 0 && pathname === "/" ? "" : pathname}.json${search}`;
2238
- }
2239
- //#endregion
2240
- //#region client/helpers/readRoutePayload.ts
2241
- /**
2242
- * Reads a navigation payload response (#290).
2243
- *
2244
- * The body is NDJSON: the first line is the envelope (route data, meta,
2245
- * partial info, already-resolved `prefetchedData`), later lines are
2246
- * `[path, variantKey, data]` query results streamed as they settle
2247
- * server-side. The returned promise resolves with the envelope as soon as
2248
- * its line arrives — the caller commits the navigation immediately — while
2249
- * the remaining lines keep draining in the background into `onQueryPayload`,
2250
- * whose `hydrate()` settles any segment that suspended on that variant.
2251
- *
2252
- * Tolerates two other body shapes so every producer keeps working: a plain
2253
- * single-JSON body with no trailing newline (error-path responses, buffering
2254
- * proxies) parses as the envelope at end-of-stream, and a `Response` without
2255
- * a readable `body` (test doubles) falls back to `.json()`.
2256
- */
2257
- async function readRoutePayload(response, onQueryPayload) {
2258
- const reader = response.body?.getReader?.();
2259
- if (!reader) try {
2260
- return await response.json();
2261
- } catch {
2262
- return null;
2263
- }
2264
- const decoder = new TextDecoder();
2265
- let buffer = "";
2266
- return await new Promise((resolve) => {
2267
- let envelopeResolved = false;
2268
- const emitEnvelope = (value) => {
2269
- if (envelopeResolved) return;
2270
- envelopeResolved = true;
2271
- resolve(value);
172
+ }, [
173
+ snapshot,
174
+ resource,
175
+ variantKey
176
+ ]);
177
+ const handleReload = useCallback(() => {
178
+ if (configRef.current.debug) console.log("Reloading query for", variantKey);
179
+ const data = resource.getVariant(variantKey, configRef.current.staleTime).data;
180
+ resource.mutate(variantKey, () => data);
181
+ }, [variantKey, resource]);
182
+ useEffect(() => {
183
+ if (!fetchedRef.current) return;
184
+ refreshIntervalRef.current = setInterval(() => {
185
+ handleReload();
186
+ }, config.refreshInterval);
187
+ return () => {
188
+ if (refreshIntervalRef.current) clearInterval(refreshIntervalRef.current);
2272
189
  };
2273
- const handleLine = (line) => {
2274
- if (line.trim().length === 0) return;
2275
- let value;
2276
- try {
2277
- value = JSON.parse(line);
2278
- } catch (error) {
2279
- console.error("[gemi] Unparseable route payload line", error);
2280
- emitEnvelope(null);
2281
- return;
190
+ }, [config.refreshInterval, handleReload]);
191
+ useEffect(() => {
192
+ if (typeof import.meta.hot?.on === "function") import.meta.hot.on("http-reload", handleReload);
193
+ return () => {
194
+ if (typeof import.meta.hot?.off === "function") import.meta.hot.off("http-reload", handleReload);
195
+ };
196
+ }, [handleReload]);
197
+ const trigger = useCallback(() => {
198
+ fetchedRef.current = true;
199
+ const variant = resource.store.getValue().get(variantKey);
200
+ if (!variant || !variant.loading && !variant.hasData) resource.refetch(variantKey);
201
+ }, [resource, variantKey]);
202
+ const prefetch = useCallback(() => {
203
+ if (prefetchedRef.current) return;
204
+ prefetchedRef.current = true;
205
+ fetchedRef.current = true;
206
+ resource.read(variantKey, configRef.current.staleTime);
207
+ }, [resource, variantKey]);
208
+ const refetch = useCallback(() => {
209
+ fetchedRef.current = true;
210
+ resource.refetch(variantKey);
211
+ }, [resource, variantKey]);
212
+ function mutate(fn) {
213
+ if (!fn) {
214
+ fetchedRef.current = true;
215
+ resource.refetch(variantKey);
216
+ return;
217
+ }
218
+ return resource.mutate(variantKey, (data) => {
219
+ if (data === void 0) {
220
+ console.warn("Mutate function called before the query.");
221
+ return data;
2282
222
  }
2283
- if (!envelopeResolved) {
2284
- emitEnvelope(value);
2285
- return;
223
+ const updatedData = typeof fn === "function" ? fn(data) : fn;
224
+ if (isPlainObject(data)) {
225
+ if (isPlainObject(updatedData)) return updatedData;
226
+ throw new Error("Mutate function must return an object when the current data is an object.");
2286
227
  }
2287
- if (Array.isArray(value) && value.length === 3) onQueryPayload?.(value);
2288
- };
2289
- (async () => {
2290
- try {
2291
- while (true) {
2292
- const { done, value } = await reader.read();
2293
- if (done) break;
2294
- buffer += decoder.decode(value, { stream: true });
2295
- let newline = buffer.indexOf("\n");
2296
- while (newline !== -1) {
2297
- const line = buffer.slice(0, newline);
2298
- buffer = buffer.slice(newline + 1);
2299
- handleLine(line);
2300
- newline = buffer.indexOf("\n");
2301
- }
2302
- }
2303
- buffer += decoder.decode();
2304
- handleLine(buffer);
2305
- emitEnvelope(null);
2306
- } catch (error) {
2307
- console.error("[gemi] Route payload stream failed", error);
2308
- emitEnvelope(null);
228
+ if (Array.isArray(data)) {
229
+ if (Array.isArray(updatedData)) return updatedData;
230
+ throw new Error("Mutate function must return an array when the current data is an array.");
2309
231
  }
2310
- })();
2311
- });
2312
- }
2313
- /**
2314
- * Reads the response to the very end and returns the envelope with every
2315
- * streamed query result merged into its `prefetchedData` — the settled
2316
- * aggregate a `<Link prefetch>` warms ahead of a click, equivalent to what
2317
- * the old blocking payload contained. Buffering is the point here: a hover
2318
- * prefetch has time, and the cache stores one complete payload.
2319
- */
2320
- async function readSettledRoutePayload(response) {
2321
- if (typeof response.text !== "function") try {
2322
- return await response.json();
2323
- } catch {
2324
- return null;
2325
- }
2326
- let text;
2327
- try {
2328
- text = await response.text();
2329
- } catch {
2330
- return null;
2331
- }
2332
- const lines = text.split("\n").filter((line) => line.trim().length > 0);
2333
- if (lines.length === 0) return null;
2334
- let envelope;
2335
- try {
2336
- envelope = JSON.parse(lines[0]);
2337
- } catch {
2338
- return null;
232
+ if (typeof data !== typeof updatedData) throw new Error("Mutate function must return the same type as the current data.");
233
+ return updatedData;
234
+ });
2339
235
  }
2340
- for (const line of lines.slice(1)) {
2341
- let value;
2342
- try {
2343
- value = JSON.parse(line);
2344
- } catch {
2345
- continue;
2346
- }
2347
- if (Array.isArray(value) && value.length === 3) {
2348
- const [path, variantKey, data] = value;
2349
- envelope.prefetchedData ??= {};
2350
- envelope.prefetchedData[path] ??= {};
2351
- envelope.prefetchedData[path][variantKey] = data;
2352
- }
236
+ if (suspense) {
237
+ if (serverError) throw serverError;
238
+ if (state?.error && !state?.hasData) throw state.error;
239
+ if (!state?.hasData && readPromise) throw readPromise;
2353
240
  }
2354
- return envelope;
2355
- }
2356
- //#endregion
2357
- //#region client/helpers/flattenComponentTree.ts
2358
- function flattenComponentTree(componentTree) {
2359
- let out = [];
2360
- for (const [root, branches] of componentTree) out.push(root, ...flattenComponentTree(branches).flat());
2361
- return Array.from(new Set(out));
2362
- }
2363
- //#endregion
2364
- //#region client/ComponentContext.tsx
2365
- /**
2366
- * Resolved view modules, not just their default exports. A route segment's
2367
- * `Suspense` fallback and error UI come from optional named exports
2368
- * (`Loading`, `Error`), and those have to be readable synchronously
2369
- * while rendering — so every path that loads a view chunk records the module
2370
- * here. Browsers dedupe the underlying dynamic import, so calling
2371
- * `loadViewModule` repeatedly is free.
2372
- */
2373
- var viewModules = /* @__PURE__ */ new Map();
2374
- var viewModuleListeners = /* @__PURE__ */ new Set();
2375
- function loadViewModule(name) {
2376
- const loader = typeof window !== "undefined" ? window.loaders?.[name] : void 0;
2377
- if (!loader) return Promise.resolve(null);
2378
- return Promise.resolve(loader()).then((mod) => {
2379
- const isNew = !viewModules.has(name);
2380
- viewModules.set(name, mod);
2381
- if (isNew) for (const listener of viewModuleListeners) listener();
2382
- return mod;
2383
- });
2384
- }
2385
- function subscribeViewModules(listener) {
2386
- viewModuleListeners.add(listener);
2387
- return () => {
2388
- viewModuleListeners.delete(listener);
241
+ return {
242
+ data: state?.data,
243
+ loading: isDeferred || (state?.loading ?? !lazy),
244
+ error: state?.error,
245
+ mutate,
246
+ trigger,
247
+ prefetch,
248
+ refetch,
249
+ version: state?.version
2389
250
  };
2390
251
  }
2391
- function getViewModule(name) {
2392
- return viewModules.get(name);
2393
- }
2394
- var viewImportMap = null;
2395
- if (typeof window !== "undefined" && process.env.NODE_ENV !== "test") {
2396
- viewImportMap = {};
2397
- const { componentTree = [] } = window.__GEMI_DATA__ ?? {};
2398
- for (const viewName of flattenComponentTree(componentTree)) viewImportMap[viewName] = lazy(() => loadViewModule(viewName));
2399
- }
2400
- var ComponentsContext = createContext({
2401
- viewImportMap,
2402
- getViewModule
2403
- });
2404
- var ComponentsProvider = (props) => {
2405
- const { modules } = props;
2406
- const value = useMemo(() => ({
2407
- viewImportMap: props.viewImportMap ?? viewImportMap,
2408
- getViewModule: modules ? (name) => modules[name] ?? getViewModule(name) : getViewModule
2409
- }), [props.viewImportMap, modules]);
2410
- return /* @__PURE__ */ jsx(ComponentsContext.Provider, {
2411
- value,
2412
- children: props.children
2413
- });
2414
- };
2415
- //#endregion
2416
- //#region client/ClientRouterContext.tsx
2417
- var ClientRouterContext = createContext({});
2418
- var ClientRouterProvider = (props) => {
2419
- const { children, pathname, currentPath, is404, is500, routeManifest, cssManifest, modulePreloadManifest, pageData, params, searchParams, breadcrumbs, urlLocaleSegment } = props;
2420
- const navigationAbortControllerRef = useRef(new AbortController());
2421
- const [isNavigatingSubject] = useState(() => {
2422
- return new Subject(false);
2423
- });
2424
- const { supportedLocales = [], locale } = useContext(I18nContext);
2425
- const [progressManager] = useState(new ProgressManager(isNavigatingSubject));
2426
- const [prefetchCache] = useState(() => new PrefetchCache());
2427
- const pageDataRef = useRef(structuredClone(pageData));
2428
- const scrollHistoryRef = useRef(/* @__PURE__ */ new Map());
2429
- /** Hrefs already announced; `null` until seeded from the shell's own hints. */
2430
- const preloadedModulesRef = useRef(null);
2431
- const breadcrumbsCache = useRef(new Map(Object.entries(breadcrumbs)));
2432
- const initalViewEntries = is404 ? ["404"] : is500 ? ["500"] : routeManifest[pathname] ?? ["404"];
2433
- const viewEntriesSubject = useRef(new Subject(initalViewEntries));
2434
- const [routerSubject] = useState(() => {
2435
- return new Subject({
2436
- views: initalViewEntries,
2437
- params,
2438
- search: searchParams,
2439
- state: {},
2440
- pathname,
2441
- hash: "",
2442
- action: null,
2443
- routePath: currentPath,
2444
- locale
2445
- });
2446
- });
2447
- const [history] = useState(() => {
2448
- let history = null;
2449
- if (typeof window !== "undefined") history = createBrowserHistory();
2450
- return history;
2451
- });
2452
- const findMatchingRouteFromParams = useMemo(() => (pathname) => {
2453
- let routePath = pathname.replace("/en-US", "").replace("/tr-TR", "");
2454
- routePath = routePath === "" ? "/" : routePath;
2455
- const candidates = [];
2456
- for (const route of Object.keys(routeManifest)) if (new Y({ pathname: route }).test({ pathname: routePath })) candidates.push(route);
2457
- return (candidates.sort((a, b) => {
2458
- return a.split("/").length + a.split(":").length - (b.split("/").length + b.split(":").length);
2459
- }) ?? [])[0];
2460
- }, [routeManifest]);
2461
- const getViewPathsFromPathname = useMemo(() => (pathname) => {
2462
- const route = findMatchingRouteFromParams(pathname);
2463
- return routeManifest[route] ?? [];
2464
- }, [findMatchingRouteFromParams, routeManifest]);
2465
- const getRoutePathnameFromHref = useMemo(() => (href) => {
2466
- return findMatchingRouteFromParams(href);
2467
- }, [findMatchingRouteFromParams]);
2468
- const getParams = useMemo(() => (pathname) => {
2469
- return new Y({ pathname: findMatchingRouteFromParams(pathname) }).exec({ pathname })?.pathname.groups ?? {};
2470
- }, [findMatchingRouteFromParams]);
2471
- useEffect(() => {
2472
- history?.listen(({ location, action }) => {
2473
- if (!window.scrollHistory) window.scrollHistory = /* @__PURE__ */ new Map();
2474
- const { hash, pathname, search } = routerSubject.getValue();
2475
- const key = [
2476
- pathname,
2477
- search,
2478
- hash
2479
- ].join("");
2480
- window.scrollHistory.set(key, window.scrollY);
2481
- let _pathname = location.pathname;
2482
- let _locale = null;
2483
- for (const locale of supportedLocales) if (_pathname.startsWith(`/${locale}`)) {
2484
- _locale = locale;
2485
- _pathname = _pathname.replace(`/${locale}`, "");
2486
- break;
2487
- }
2488
- _pathname = _pathname === "" ? "/" : _pathname;
2489
- const routePath = getRoutePathnameFromHref(_pathname);
2490
- routerSubject.next({
2491
- views: getViewPathsFromPathname(_pathname),
2492
- params: getParams(_pathname),
2493
- search: location.search,
2494
- state: location.state,
2495
- pathname: _pathname,
2496
- action,
2497
- routePath,
2498
- hash: location.hash,
2499
- locale: _locale
2500
- });
2501
- });
2502
- }, [
2503
- supportedLocales,
2504
- history,
2505
- routerSubject,
2506
- getParams,
2507
- getRoutePathnameFromHref,
2508
- getViewPathsFromPathname
2509
- ]);
2510
- const updatePageData = (newPageData, breadcrumbs) => {
2511
- const [key, value] = Object.entries(newPageData)[0];
2512
- if (!pageDataRef.current?.[key]) pageDataRef.current[key] = {};
2513
- for (const b in breadcrumbs) breadcrumbsCache.current.set(b, breadcrumbs[b]);
2514
- pageDataRef.current[key] = value;
2515
- };
2516
- const getPageData = (key, pathname) => {
2517
- return pageDataRef.current[pathname]?.[key];
2518
- };
2519
- const setNavigationAbortController = (controller) => {
2520
- navigationAbortControllerRef.current.abort();
2521
- navigationAbortControllerRef.current = controller;
2522
- };
2523
- const fetchRouteCSS = async (routePath) => {
2524
- const views = routeManifest[routePath];
2525
- if (!views) return;
2526
- const cssFiles = views.flatMap((view) => {
2527
- return cssManifest?.[view];
2528
- }).filter(Boolean).filter((file) => !document.getElementById(file));
2529
- if (cssFiles.length === 0) return;
2530
- async function fetchCSS(path) {
2531
- return {
2532
- content: (await fetch(`/${path}`)).text(),
2533
- id: path
2534
- };
2535
- }
2536
- const result = await Promise.all(cssFiles?.map((file) => fetchCSS(file)));
2537
- for (const { content, id } of result) {
2538
- const style = document.createElement("style");
2539
- style.id = id;
2540
- style.textContent = await content;
2541
- document.head.appendChild(style);
2542
- }
2543
- };
2544
- /**
2545
- * Announces every chunk a navigation to `routePath` will import.
2546
- *
2547
- * `loadViewModule` starts each view's own chunk, but a chunk's static
2548
- * imports are discoverable only once it has arrived and parsed — so a
2549
- * `layout -> view -> components` route still costs a round trip per level on
2550
- * every navigation, holding the transition open for exactly the interval the
2551
- * shell's head hints remove from the first load (#352). These are the same
2552
- * per-view lists the shell renders, shipped in the document payload.
2553
- *
2554
- * `modulepreload` rather than `import()`: it fills the HTTP cache without
2555
- * evaluating anything, so warming a link that is never clicked costs a
2556
- * download and no side effects.
2557
- */
2558
- const preloadRouteModules = (routePath) => {
2559
- if (typeof document === "undefined") return;
2560
- if (!preloadedModulesRef.current) preloadedModulesRef.current = new Set(Array.from(document.querySelectorAll("link[rel=\"modulepreload\"]"), (link) => link.getAttribute("href") ?? ""));
2561
- const preloaded = preloadedModulesRef.current;
2562
- for (const view of routeManifest[routePath] ?? []) for (const href of modulePreloadManifest?.[view] ?? []) {
2563
- if (preloaded.has(href)) continue;
2564
- preloaded.add(href);
2565
- const link = document.createElement("link");
2566
- link.rel = "modulepreload";
2567
- link.href = href;
2568
- document.head.appendChild(link);
2569
- }
2570
- };
2571
- /**
2572
- * Warms everything a navigation to `target` would need: the route's page
2573
- * data, its stylesheets and its component chunks.
2574
- *
2575
- * The payload is requested *without* the partial-render header, because the
2576
- * route on screen when the link is prefetched is not necessarily the one it
2577
- * will be clicked from — a partial response computed against the wrong base
2578
- * has nothing sound to merge onto. A full payload is always safe to commit.
2579
- *
2580
- * It carries `Purpose: prefetch` so applications can tell speculative traffic
2581
- * from a real visit — a route's handlers run either way, and a `viewport`
2582
- * page multiplies that by the number of links on it.
2583
- */
2584
- const prefetchRoute = async (target) => {
2585
- if (typeof window === "undefined") return;
2586
- const { pathname, search = "", localeSegment = "" } = target;
2587
- const routePath = getRoutePathnameFromHref(pathname);
2588
- if (!routePath) return;
2589
- const url = routeDataUrl({
2590
- pathname,
2591
- search,
2592
- localeSegment
2593
- });
2594
- fetchRouteCSS(routePath).catch(() => {});
2595
- preloadRouteModules(routePath);
2596
- for (const view of routeManifest[routePath] ?? []) loadViewModule(view);
2597
- await prefetchCache.prime(url, async () => {
2598
- const response = await fetch(url, { headers: { Purpose: "prefetch" } });
2599
- if (!response.ok) return null;
2600
- return await readSettledRoutePayload(response);
2601
- });
2602
- };
2603
- return /* @__PURE__ */ jsxs(ClientRouterContext.Provider, {
2604
- value: {
2605
- isNavigatingSubject,
2606
- prefetchRoute,
2607
- takePrefetched: (url) => prefetchCache.take(url),
2608
- clearPrefetchCache: () => prefetchCache.clear(),
2609
- getViewPathsFromPathname,
2610
- history,
2611
- getScrollPosition: (path) => {
2612
- return scrollHistoryRef.current.get(path) || 0;
2613
- },
2614
- viewEntriesSubject: viewEntriesSubject.current,
2615
- updatePageData,
2616
- getPageData,
2617
- getRoutePathnameFromHref,
2618
- setNavigationAbortController,
2619
- progressManager,
2620
- fetchRouteCSS,
2621
- preloadRouteModules,
2622
- breadcrumbsCache: breadcrumbsCache.current,
2623
- routerSubject,
2624
- urlLocaleSegment
2625
- },
2626
- children: [children, import.meta.hot && /* @__PURE__ */ jsx(HttpReload, {})]
2627
- });
2628
- };
2629
252
  //#endregion
2630
253
  //#region client/useMutation.ts
2631
254
  function applyParams(url, params = {}) {
@@ -2833,9 +456,7 @@ function useMutate() {
2833
456
  const { path, params = {}, search = {} } = options ?? {};
2834
457
  const normalPath = applyParams$1(path, params);
2835
458
  const resource = getResource(normalPath);
2836
- const searchParams = new URLSearchParams(omitNullishValues(search));
2837
- searchParams.sort();
2838
- const variantKey = searchParams.toString();
459
+ const variantKey = toVariantKey(search);
2839
460
  return resource.mutate.call(resource, variantKey, (data) => {
2840
461
  if (data === void 0 || data === null) {
2841
462
  console.warn("Mutate function called before the query.");
@@ -2957,7 +578,7 @@ function useFormStatus() {
2957
578
  }
2958
579
  function useFormData() {
2959
580
  const { formDataSubject } = useContext(MutationContext);
2960
- return useSyncExternalStore(formDataSubject.current.subscribe.bind(formDataSubject.current), formDataSubject.current.getValue.bind(formDataSubject.current), formDataSubject.current.getValue.bind(formDataSubject.current));
581
+ return useSyncExternalStore(formDataSubject.current.subscribe, formDataSubject.current.getValue, formDataSubject.current.getValue);
2961
582
  }
2962
583
  var ValidationErrors = (props) => {
2963
584
  const { render = (props) => /* @__PURE__ */ jsx("div", { ...props }), name } = props;
@@ -3076,29 +697,6 @@ function useBreadcrumbs() {
3076
697
  return breadcrumbs.filter((breadcrumb) => breadcrumb?.label.length > 0);
3077
698
  }
3078
699
  //#endregion
3079
- //#region client/RouteTransitionProvider.tsx
3080
- var RouteTransitionContext = createContext({
3081
- isTransitioning: false,
3082
- targetPath: "",
3083
- currentPath: ""
3084
- });
3085
- var RouteTransitionProvider = (props) => {
3086
- const { isPending, isFetching, transitionPath } = props;
3087
- return /* @__PURE__ */ jsx(RouteTransitionContext.Provider, {
3088
- value: {
3089
- isTransitioning: isPending || isFetching,
3090
- targetPath: transitionPath[1],
3091
- currentPath: transitionPath[0] || ""
3092
- },
3093
- children: props.children
3094
- });
3095
- };
3096
- function useRouteTransition() {
3097
- const context = useContext(RouteTransitionContext);
3098
- if (!context) throw new Error("useRouteTransition must be used within a RouteTransitionProvider");
3099
- return context;
3100
- }
3101
- //#endregion
3102
700
  //#region client/Link.tsx
3103
701
  /** How long the pointer has to rest on an `intent` link before it counts. */
3104
702
  var INTENT_DELAY = 100;
@@ -3249,126 +847,6 @@ var Redirect = (props) => {
3249
847
  return /* @__PURE__ */ jsx(Fragment$1, {});
3250
848
  };
3251
849
  //#endregion
3252
- //#region ../../node_modules/.bun/react-error-boundary@6.1.1+83d5fd7b249dbeef/node_modules/react-error-boundary/dist/react-error-boundary.js
3253
- var h = createContext(null);
3254
- var c = {
3255
- didCatch: !1,
3256
- error: null
3257
- };
3258
- var m = class extends Component {
3259
- constructor(e) {
3260
- super(e), this.resetErrorBoundary = this.resetErrorBoundary.bind(this), this.state = c;
3261
- }
3262
- static getDerivedStateFromError(e) {
3263
- return {
3264
- didCatch: !0,
3265
- error: e
3266
- };
3267
- }
3268
- resetErrorBoundary(...e) {
3269
- const { error: t } = this.state;
3270
- t !== null && (this.props.onReset?.({
3271
- args: e,
3272
- reason: "imperative-api"
3273
- }), this.setState(c));
3274
- }
3275
- componentDidCatch(e, t) {
3276
- this.props.onError?.(e, t);
3277
- }
3278
- componentDidUpdate(e, t) {
3279
- const { didCatch: o } = this.state, { resetKeys: s } = this.props;
3280
- o && t.error !== null && C(e.resetKeys, s) && (this.props.onReset?.({
3281
- next: s,
3282
- prev: e.resetKeys,
3283
- reason: "keys"
3284
- }), this.setState(c));
3285
- }
3286
- render() {
3287
- const { children: e, fallbackRender: t, FallbackComponent: o, fallback: s } = this.props, { didCatch: n, error: a } = this.state;
3288
- let i = e;
3289
- if (n) {
3290
- const u = {
3291
- error: a,
3292
- resetErrorBoundary: this.resetErrorBoundary
3293
- };
3294
- if (typeof t == "function") i = t(u);
3295
- else if (o) i = createElement(o, u);
3296
- else if (s !== void 0) i = s;
3297
- else throw a;
3298
- }
3299
- return createElement(h.Provider, { value: {
3300
- didCatch: n,
3301
- error: a,
3302
- resetErrorBoundary: this.resetErrorBoundary
3303
- } }, i);
3304
- }
3305
- };
3306
- function C(r = [], e = []) {
3307
- return r.length !== e.length || r.some((t, o) => !Object.is(t, e[o]));
3308
- }
3309
- //#endregion
3310
- //#region client/WebsocketContext.tsx
3311
- var WebSocketContext = createContext({});
3312
- var WebSocketContextProvider = (props) => {
3313
- const wsRef = useRef(null);
3314
- function getWS() {
3315
- return new Promise((resolve) => {
3316
- if (wsRef.current) resolve(wsRef.current);
3317
- else {
3318
- const ws = new WebSocket("ws://localhost:5173/");
3319
- ws.onopen = () => {
3320
- wsRef.current = ws;
3321
- console.log("ws opened");
3322
- ws.addEventListener("close", () => {
3323
- console.log("ws closed");
3324
- wsRef.current = null;
3325
- });
3326
- resolve(ws);
3327
- };
3328
- }
3329
- });
3330
- }
3331
- const subscribe = async (topic, handler) => {
3332
- const ws = await getWS();
3333
- ws.send(JSON.stringify({
3334
- type: "subscribe",
3335
- topic
3336
- }));
3337
- ws.addEventListener("message", handler);
3338
- };
3339
- const unsubscribe = async (topic, handler) => {
3340
- const ws = await getWS();
3341
- ws.send(JSON.stringify({
3342
- type: "unsubscribe",
3343
- topic
3344
- }));
3345
- ws.removeEventListener("message", handler);
3346
- };
3347
- const broadcast = async (topic, payload = {}) => {
3348
- (await getWS()).send(JSON.stringify({
3349
- type: "broadcast",
3350
- topic,
3351
- payload
3352
- }));
3353
- };
3354
- useEffect(() => {
3355
- return () => {
3356
- if (wsRef.current) {
3357
- wsRef.current.close();
3358
- wsRef.current = null;
3359
- }
3360
- };
3361
- }, []);
3362
- return /* @__PURE__ */ jsx(WebSocketContext.Provider, {
3363
- value: {
3364
- subscribe,
3365
- unsubscribe,
3366
- broadcast
3367
- },
3368
- children: props.children
3369
- });
3370
- };
3371
- //#endregion
3372
850
  //#region client/Head.tsx
3373
851
  function updateMeta(meta) {
3374
852
  if (!meta) return;
@@ -3463,50 +941,6 @@ var Head = ({ children = null, charSet = "utf-8" }) => {
3463
941
  ] });
3464
942
  };
3465
943
  //#endregion
3466
- //#region client/ThemeProvider.tsx
3467
- var ThemeContext = createContext({
3468
- theme: "light",
3469
- setTheme: (theme) => {}
3470
- });
3471
- function storeTheme(theme) {
3472
- try {
3473
- localStorage.setItem("theme", theme);
3474
- } catch (error) {
3475
- console.error("Failed to store theme in localStorage:", error);
3476
- }
3477
- }
3478
- var ThemeProvider = (props) => {
3479
- const [theme, setTheme] = useState(() => {
3480
- if (typeof window === "undefined") return "light";
3481
- return localStorage.getItem("theme") || "light";
3482
- });
3483
- useEffect(() => {
3484
- if (theme === "system") window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", ({ matches }) => {
3485
- document.documentElement.classList.remove("light", "dark");
3486
- document.documentElement.classList.add(matches ? "dark" : "light");
3487
- });
3488
- }, [theme]);
3489
- return /* @__PURE__ */ jsx(ThemeContext.Provider, {
3490
- value: {
3491
- theme,
3492
- setTheme: (newTheme) => {
3493
- setTheme(newTheme);
3494
- storeTheme(newTheme);
3495
- let documentTheme = newTheme;
3496
- if (newTheme === "system") documentTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
3497
- document.documentElement.classList.remove("light", "dark");
3498
- document.documentElement.classList.add(documentTheme);
3499
- }
3500
- },
3501
- children: props.children
3502
- });
3503
- };
3504
- function useTheme() {
3505
- const context = useContext(ThemeContext);
3506
- if (!context) throw new Error("useTheme must be used within a ThemeProvider");
3507
- return context;
3508
- }
3509
- //#endregion
3510
944
  //#region utils/partialRender.ts
3511
945
  /**
3512
946
  * Route the client is currently rendering, sent on `.json` navigations so the