diff --git a/src/core/cache.js b/src/core/cache.js index 580c6ab1f..0750a938c 100644 --- a/src/core/cache.js +++ b/src/core/cache.js @@ -1,9 +1,8 @@ import { setMetaContent } from "../util" -import { SnapshotCache } from "./drive/snapshot_cache" export class Cache { clear() { - this.store.clear() + this.session.clearCache() } resetCacheControl() { @@ -18,18 +17,6 @@ export class Cache { this.#setCacheControl("no-preview") } - set store(store) { - if (typeof store === "string") { - SnapshotCache.setStore(store) - } else { - SnapshotCache.currentStore = store - } - } - - get store() { - return SnapshotCache.currentStore - } - #setCacheControl(value) { setMetaContent("turbo-cache-control", value) } diff --git a/src/core/drive/cache_stores/disk_store.js b/src/core/drive/cache_stores/disk_store.js deleted file mode 100644 index 285caa5d9..000000000 --- a/src/core/drive/cache_stores/disk_store.js +++ /dev/null @@ -1,64 +0,0 @@ -import { PageSnapshot } from "../page_snapshot" - -export class DiskStore { - _version = "v1" - - constructor() { - if (typeof caches === "undefined") { - throw new Error("windows.caches is undefined. CacheStore requires a secure context.") - } - - this.storage = this.openStorage() - } - - async has(location) { - const storage = await this.openStorage() - return (await storage.match(location)) !== undefined - } - - async get(location) { - const storage = await this.openStorage() - const response = await storage.match(location) - - if (response && response.ok) { - const html = await response.text() - return PageSnapshot.fromHTMLString(html) - } - } - - async put(location, snapshot) { - const storage = await this.openStorage() - - const response = new Response(snapshot.html, { - status: 200, - statusText: "OK", - headers: { - "Content-Type": "text/html" - } - }) - await storage.put(location, response) - return snapshot - } - - async clear() { - const storage = await this.openStorage() - const keys = await storage.keys() - await Promise.all(keys.map((key) => storage.delete(key))) - } - - openStorage() { - this.storage ||= caches.open(`turbo-${this.version}`) - return this.storage - } - - set version(value) { - if (value !== this._version) { - this._version = value - this.storage ||= caches.open(`turbo-${this.version}`) - } - } - - get version() { - return this._version - } -} diff --git a/src/core/drive/cache_stores/memory_store.js b/src/core/drive/cache_stores/memory_store.js deleted file mode 100644 index 3ec8ae0b1..000000000 --- a/src/core/drive/cache_stores/memory_store.js +++ /dev/null @@ -1,56 +0,0 @@ -import { toCacheKey } from "../../url" - -export class MemoryStore { - keys = [] - snapshots = {} - - constructor(size) { - this.size = size - } - - async has(location) { - return toCacheKey(location) in this.snapshots - } - - async get(location) { - if (await this.has(location)) { - const snapshot = this.read(location) - this.touch(location) - return snapshot - } - } - - async put(location, snapshot) { - this.write(location, snapshot) - this.touch(location) - return snapshot - } - - async clear() { - this.snapshots = {} - } - - // Private - - read(location) { - return this.snapshots[toCacheKey(location)] - } - - write(location, snapshot) { - this.snapshots[toCacheKey(location)] = snapshot - } - - touch(location) { - const key = toCacheKey(location) - const index = this.keys.indexOf(key) - if (index > -1) this.keys.splice(index, 1) - this.keys.unshift(key) - this.trim() - } - - trim() { - for (const key of this.keys.splice(this.size)) { - delete this.snapshots[key] - } - } -} diff --git a/src/core/drive/navigator.js b/src/core/drive/navigator.js index 999d97817..54b01e8ee 100644 --- a/src/core/drive/navigator.js +++ b/src/core/drive/navigator.js @@ -21,7 +21,7 @@ export class Navigator { referrer: this.location, ...options }) - return this.currentVisit.start() + this.currentVisit.start() } submitForm(form, submitter) { diff --git a/src/core/drive/page_snapshot.js b/src/core/drive/page_snapshot.js index 774a4af94..58a5a75a9 100644 --- a/src/core/drive/page_snapshot.js +++ b/src/core/drive/page_snapshot.js @@ -45,10 +45,6 @@ export class PageSnapshot extends Snapshot { return this.documentElement.getAttribute("lang") } - get html() { - return `${this.headElement.outerHTML}\n\n${this.element.outerHTML}` - } - get headElement() { return this.headSnapshot.element } diff --git a/src/core/drive/page_view.js b/src/core/drive/page_view.js index 249b73efc..0508d0960 100644 --- a/src/core/drive/page_view.js +++ b/src/core/drive/page_view.js @@ -7,7 +7,7 @@ import { PageSnapshot } from "./page_snapshot" import { SnapshotCache } from "./snapshot_cache" export class PageView extends View { - snapshotCache = new SnapshotCache() + snapshotCache = new SnapshotCache(10) lastRenderedLocation = new URL(location.href) forceReloaded = false @@ -36,10 +36,6 @@ export class PageView extends View { return this.render(renderer) } - setCacheStore(cacheName) { - SnapshotCache.setStore(cacheName) - } - clearSnapshotCache() { this.snapshotCache.clear() } diff --git a/src/core/drive/preloader.js b/src/core/drive/preloader.js index 62e0825f6..ff9d871d6 100644 --- a/src/core/drive/preloader.js +++ b/src/core/drive/preloader.js @@ -31,7 +31,9 @@ export class Preloader { async preloadURL(link) { const location = new URL(link.href) - if (await this.snapshotCache.has(location)) return + if (this.snapshotCache.has(location)) { + return + } try { const response = await fetch(location.toString(), { headers: { "Sec-Purpose": "prefetch", Accept: "text/html" } }) diff --git a/src/core/drive/snapshot_cache.js b/src/core/drive/snapshot_cache.js index 8e8c53c02..6ed37e8fd 100644 --- a/src/core/drive/snapshot_cache.js +++ b/src/core/drive/snapshot_cache.js @@ -1,35 +1,56 @@ -import { DiskStore } from "./cache_stores/disk_store" -import { MemoryStore } from "./cache_stores/memory_store" +import { toCacheKey } from "../url" export class SnapshotCache { - static currentStore = new MemoryStore(10) - - static setStore(storeName) { - switch (storeName) { - case "memory": - SnapshotCache.currentStore = new MemoryStore(10) - break - case "disk": - SnapshotCache.currentStore = new DiskStore() - break - default: - throw new Error(`Invalid store name: ${storeName}`) - } + keys = [] + snapshots = {} + + constructor(size) { + this.size = size } has(location) { - return SnapshotCache.currentStore.has(location) + return toCacheKey(location) in this.snapshots } get(location) { - return SnapshotCache.currentStore.get(location) + if (this.has(location)) { + const snapshot = this.read(location) + this.touch(location) + return snapshot + } } put(location, snapshot) { - return SnapshotCache.currentStore.put(location, snapshot) + this.write(location, snapshot) + this.touch(location) + return snapshot } clear() { - return SnapshotCache.currentStore.clear() + this.snapshots = {} + } + + // Private + + read(location) { + return this.snapshots[toCacheKey(location)] + } + + write(location, snapshot) { + this.snapshots[toCacheKey(location)] = snapshot + } + + touch(location) { + const key = toCacheKey(location) + const index = this.keys.indexOf(key) + if (index > -1) this.keys.splice(index, 1) + this.keys.unshift(key) + this.trim() + } + + trim() { + for (const key of this.keys.splice(this.size)) { + delete this.snapshots[key] + } } } diff --git a/src/core/drive/visit.js b/src/core/drive/visit.js index ce31fee7e..4e7796302 100644 --- a/src/core/drive/visit.js +++ b/src/core/drive/visit.js @@ -105,11 +105,10 @@ export class Visit { return this.isSamePage } - async start() { + start() { if (this.state == VisitState.initialized) { this.recordTimingMetric(TimingMetric.visitStart) this.state = VisitState.started - this.cachedSnapshot = await this.getCachedSnapshot() this.adapter.visitStarted(this) this.delegate.visitStarted(this) } @@ -155,10 +154,10 @@ export class Visit { } } - async issueRequest() { + issueRequest() { if (this.hasPreloadedResponse()) { this.simulateRequest() - } else if (!this.request && await this.shouldIssueRequest()) { + } else if (this.shouldIssueRequest() && !this.request) { this.request = new FetchRequest(this, FetchMethod.get, this.location) this.request.perform() } @@ -216,8 +215,8 @@ export class Visit { } } - async getCachedSnapshot() { - const snapshot = (await this.view.getCachedSnapshotForLocation(this.location)) || this.getPreloadedSnapshot() + getCachedSnapshot() { + const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot() if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) { if (this.action == "restore" || snapshot.isPreviewable) { @@ -233,12 +232,13 @@ export class Visit { } hasCachedSnapshot() { - return this.cachedSnapshot != null + return this.getCachedSnapshot() != null } - async loadCachedSnapshot() { - if (this.cachedSnapshot) { - const isPreview = await this.shouldIssueRequest() + loadCachedSnapshot() { + const snapshot = this.getCachedSnapshot() + if (snapshot) { + const isPreview = this.shouldIssueRequest() this.render(async () => { this.cacheSnapshot() if (this.isSamePage) { @@ -246,7 +246,7 @@ export class Visit { } else { if (this.view.renderPromise) await this.view.renderPromise - await this.renderPageSnapshot(this.cachedSnapshot, isPreview) + await this.renderPageSnapshot(snapshot, isPreview) this.adapter.visitRendered(this) if (!isPreview) { @@ -391,10 +391,10 @@ export class Visit { return typeof this.response == "object" } - async shouldIssueRequest() { + shouldIssueRequest() { if (this.isSamePage) { return false - } else if (this.action === "restore") { + } else if (this.action == "restore") { return !this.hasCachedSnapshot() } else { return this.willRender diff --git a/src/core/native/browser_adapter.js b/src/core/native/browser_adapter.js index 2351d10e4..15da5dd41 100644 --- a/src/core/native/browser_adapter.js +++ b/src/core/native/browser_adapter.js @@ -27,7 +27,11 @@ export class BrowserAdapter { visitRequestStarted(visit) { this.progressBar.setValue(0) - this.showVisitProgressBarAfterDelay() + if (visit.hasCachedSnapshot() || visit.action != "restore") { + this.showVisitProgressBarAfterDelay() + } else { + this.showProgressBar() + } } visitRequestCompleted(visit) { diff --git a/src/tests/fixtures/disk_cache.html b/src/tests/fixtures/disk_cache.html deleted file mode 100644 index f8ba78a64..000000000 --- a/src/tests/fixtures/disk_cache.html +++ /dev/null @@ -1,49 +0,0 @@ - - -
- - - -