@brust/runtime-dom 2.0.0-alpha.30 → 2.0.0-alpha.32
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/package.json +1 -1
- package/src/nav/nav.ts +12 -3
package/package.json
CHANGED
package/src/nav/nav.ts
CHANGED
|
@@ -52,14 +52,21 @@ export function boot(load: Load = (u) => import(/* @vite-ignore */ u)): () => vo
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// ---- the page cache (§10.1): an LRU of 32 documents by URL without its hash, filled by prefetches and navigations,
|
|
55
|
-
// fresh for 5 minutes (`data-brust-cache` seconds), any age for back/forward; a fetch in flight (at: Infinity) is shared
|
|
55
|
+
// fresh for 5 minutes (`data-brust-cache` seconds), any age for back/forward; a fetch in flight (at: Infinity) is shared.
|
|
56
|
+
// `seen` (F479): when each URL was last fetched, kept or not (32 of them, oldest out): a prefetch of one fetched less than
|
|
57
|
+
// `data-brust-prefetch-gap` seconds ago (10; 0 = no gap) does nothing. It gates prefetches only; a navigation never waits.
|
|
56
58
|
const cache = new Map<string, [Promise<Got>, number]>()
|
|
59
|
+
const seen = new Map<string, number>()
|
|
60
|
+
const gap = () => { const s = html.getAttribute('data-brust-prefetch-gap'); return s == null || isNaN(+s) ? 1e4 : +s * 1e3 }
|
|
57
61
|
const ttl = () => { const s = html.getAttribute('data-brust-cache'); return s == null || isNaN(+s) ? 3e5 : +s * 1e3 }
|
|
58
62
|
const get = (u: string, any?: boolean, init?: RequestInit): Promise<Got> => {
|
|
59
63
|
const k = noHash(u)
|
|
60
64
|
let e = cache.get(k)
|
|
61
65
|
cache.delete(k)
|
|
62
66
|
if (!e || !(any || Date.now() - e[1] < ttl())) {
|
|
67
|
+
seen.delete(k)
|
|
68
|
+
seen.set(k, Date.now())
|
|
69
|
+
if (seen.size > 32) seen.delete(seen.keys().next().value!)
|
|
63
70
|
const p = fetch(k, init).then(async (r) => ({ status: r.status, url: r.url, type: r.headers.get('content-type') ?? '', text: await r.text(), no: r.status >= 400 || /no-store/i.test(r.headers.get('cache-control') ?? '') }))
|
|
64
71
|
const f = (e = [p, Infinity])
|
|
65
72
|
const drop = () => cache.get(k) === f && cache.delete(k)
|
|
@@ -117,7 +124,9 @@ export function boot(load: Load = (u) => import(/* @vite-ignore */ u)): () => vo
|
|
|
117
124
|
const prefetch = (t: EventTarget | null) => {
|
|
118
125
|
const l = target(t)
|
|
119
126
|
const c = (navigator as { connection?: { saveData?: boolean; effectiveType?: string } }).connection
|
|
120
|
-
if (!l || l[0].closest('[data-brust-prefetch="false"]') || c?.saveData || /2g/.test(c?.effectiveType ?? '')) return
|
|
127
|
+
if (!l || l[0].closest('[data-brust-prefetch="false"]') || c?.saveData || /2g/.test(c?.effectiveType ?? '') || sameDoc(l[1], location.href)) return
|
|
128
|
+
const at = seen.get(noHash(l[1]))
|
|
129
|
+
if (at != null && Date.now() - at < gap()) return
|
|
121
130
|
get(l[1], false, { priority: 'low' } as RequestInit).catch(() => {})
|
|
122
131
|
}
|
|
123
132
|
|
|
@@ -249,7 +258,7 @@ export function boot(load: Load = (u) => import(/* @vite-ignore */ u)): () => vo
|
|
|
249
258
|
location[o?.replace ? 'replace' : 'assign'](url)
|
|
250
259
|
return Promise.resolve()
|
|
251
260
|
}
|
|
252
|
-
g[KEY] = { navigate, clearCache: () => cache.clear() }
|
|
261
|
+
g[KEY] = { navigate, clearCache: () => (cache.clear(), seen.clear()) }
|
|
253
262
|
|
|
254
263
|
on(document, 'click', (e: MouseEvent) => {
|
|
255
264
|
if (e.defaultPrevented || e.button || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return
|