1'use strict' 2 3const { kConstruct } = require('./symbols') 4const { Cache } = require('./cache') 5const { webidl } = require('../fetch/webidl') 6const { kEnumerableProperty } = require('../core/util') 7 8class CacheStorage { 9 /** 10 * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map 11 * @type {Map<string, import('./cache').requestResponseList} 12 */ 13 #caches = new Map() 14 15 constructor () { 16 if (arguments[0] !== kConstruct) { 17 webidl.illegalConstructor() 18 } 19 } 20 21 async match (request, options = {}) { 22 webidl.brandCheck(this, CacheStorage) 23 webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.match' }) 24 25 request = webidl.converters.RequestInfo(request) 26 options = webidl.converters.MultiCacheQueryOptions(options) 27 28 // 1. 29 if (options.cacheName != null) { 30 // 1.1.1.1 31 if (this.#caches.has(options.cacheName)) { 32 // 1.1.1.1.1 33 const cacheList = this.#caches.get(options.cacheName) 34 const cache = new Cache(kConstruct, cacheList) 35 36 return await cache.match(request, options) 37 } 38 } else { // 2. 39 // 2.2 40 for (const cacheList of this.#caches.values()) { 41 const cache = new Cache(kConstruct, cacheList) 42 43 // 2.2.1.2 44 const response = await cache.match(request, options) 45 46 if (response !== undefined) { 47 return response 48 } 49 } 50 } 51 } 52 53 /** 54 * @see https://w3c.github.io/ServiceWorker/#cache-storage-has 55 * @param {string} cacheName 56 * @returns {Promise<boolean>} 57 */ 58 async has (cacheName) { 59 webidl.brandCheck(this, CacheStorage) 60 webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.has' }) 61 62 cacheName = webidl.converters.DOMString(cacheName) 63 64 // 2.1.1 65 // 2.2 66 return this.#caches.has(cacheName) 67 } 68 69 /** 70 * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open 71 * @param {string} cacheName 72 * @returns {Promise<Cache>} 73 */ 74 async open (cacheName) { 75 webidl.brandCheck(this, CacheStorage) 76 webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.open' }) 77 78 cacheName = webidl.converters.DOMString(cacheName) 79 80 // 2.1 81 if (this.#caches.has(cacheName)) { 82 // await caches.open('v1') !== await caches.open('v1') 83 84 // 2.1.1 85 const cache = this.#caches.get(cacheName) 86 87 // 2.1.1.1 88 return new Cache(kConstruct, cache) 89 } 90 91 // 2.2 92 const cache = [] 93 94 // 2.3 95 this.#caches.set(cacheName, cache) 96 97 // 2.4 98 return new Cache(kConstruct, cache) 99 } 100 101 /** 102 * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete 103 * @param {string} cacheName 104 * @returns {Promise<boolean>} 105 */ 106 async delete (cacheName) { 107 webidl.brandCheck(this, CacheStorage) 108 webidl.argumentLengthCheck(arguments, 1, { header: 'CacheStorage.delete' }) 109 110 cacheName = webidl.converters.DOMString(cacheName) 111 112 return this.#caches.delete(cacheName) 113 } 114 115 /** 116 * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys 117 * @returns {string[]} 118 */ 119 async keys () { 120 webidl.brandCheck(this, CacheStorage) 121 122 // 2.1 123 const keys = this.#caches.keys() 124 125 // 2.2 126 return [...keys] 127 } 128} 129 130Object.defineProperties(CacheStorage.prototype, { 131 [Symbol.toStringTag]: { 132 value: 'CacheStorage', 133 configurable: true 134 }, 135 match: kEnumerableProperty, 136 has: kEnumerableProperty, 137 open: kEnumerableProperty, 138 delete: kEnumerableProperty, 139 keys: kEnumerableProperty 140}) 141 142module.exports = { 143 CacheStorage 144} 145