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