Skip to content

Commit

Permalink
Ensure Storage is open before using it
Browse files Browse the repository at this point in the history
Always await the promise returned by `caches.open` before using the
resulting `Cache` object. This prevents race conditions where the
`Cache` object is used before it is ready.
  • Loading branch information
afcapel committed Jul 27, 2023
1 parent 2d0985c commit 4e91716
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
35 changes: 22 additions & 13 deletions src/core/drive/cache_stores/disk_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PageSnapshot } from "../page_snapshot"

export class DiskStore extends CacheStore {
_version = "v1"
storage!: Cache
storage!: Promise<Cache>

constructor() {
super()
Expand All @@ -12,45 +12,54 @@ export class DiskStore extends CacheStore {
throw new Error("windows.caches is undefined. CacheStore requires a secure context.")
}

this.initialize()
}

async initialize() {
this.storage = await caches.open(`turbo-${this.version}`)
this.storage = this.openStorage()
}

async has(location: URL) {
return (await this.storage.match(location)) !== undefined
const storage = await this.openStorage()
return (await storage.match(location)) !== undefined
}

async get(location: URL) {
const response = await this.storage.match(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: URL, snapshot: PageSnapshot) {
const storage = await this.openStorage()

const response = new Response(snapshot.html, {
status: 200,
statusText: "OK",
headers: {
"Content-Type": "text/html",
},
})
await this.storage.put(location, response)
await storage.put(location, response)
return snapshot
}

async clear() {
const keys = await this.storage.keys()
await Promise.all(keys.map((key) => this.storage.delete(key)))
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: string) {
this._version = value
this.initialize()
if (value !== this._version) {
this._version = value
this.storage ||= caches.open(`turbo-${this.version}`)
}
}

get version() {
Expand Down
2 changes: 1 addition & 1 deletion src/tests/functional/disk_cache_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ test.beforeEach(async ({ page }) => {
await page.goto(path)
})

test("test stores pages in the disk cache", async ({ page }) => {
test("stores pages in the disk cache", async ({ page }) => {
await assertCachedURLs(page, [])

page.click("#second-link")
Expand Down

0 comments on commit 4e91716

Please sign in to comment.