| 1118 | } |
| 1119 | |
| 1120 | async cleanupCaches(): Promise<void> { |
| 1121 | try { |
| 1122 | // Query for all currently active clients, and list the client IDs. This may skip some clients |
| 1123 | // in the browser back-forward cache, but not much can be done about that. |
| 1124 | const activeClients = new Set<ClientId>( |
| 1125 | (await this.scope.clients.matchAll()).map((client) => client.id), |
| 1126 | ); |
| 1127 | |
| 1128 | // A simple list of client IDs that the SW has kept track of. Subtracting `activeClients` from |
| 1129 | // this list will result in the set of client IDs which are being tracked but are no longer |
| 1130 | // used in the browser, and thus can be cleaned up. |
| 1131 | const knownClients: ClientId[] = Array.from(this.clientVersionMap.keys()); |
| 1132 | |
| 1133 | // Remove clients in the `clientVersionMap` that are no longer active. |
| 1134 | const obsoleteClients = knownClients.filter((id) => !activeClients.has(id)); |
| 1135 | obsoleteClients.forEach((id) => this.clientVersionMap.delete(id)); |
| 1136 | |
| 1137 | // Next, determine the set of versions which are still used. All others can be removed. |
| 1138 | const usedVersions = new Set(this.clientVersionMap.values()); |
| 1139 | |
| 1140 | // Collect all obsolete versions by filtering out used versions from the set of all versions. |
| 1141 | const obsoleteVersions = Array.from(this.versions.keys()).filter( |
| 1142 | (version) => !usedVersions.has(version) && version !== this.latestHash, |
| 1143 | ); |
| 1144 | |
| 1145 | // Remove all the versions which are no longer used. |
| 1146 | obsoleteVersions.forEach((version) => this.versions.delete(version)); |
| 1147 | |
| 1148 | // Commit all the changes to the saved state. |
| 1149 | await this.sync(); |
| 1150 | |
| 1151 | // Delete all caches that are no longer needed. |
| 1152 | const allCaches = await this.adapter.caches.keys(); |
| 1153 | const usedCaches = new Set(await this.getCacheNames()); |
| 1154 | const cachesToDelete = allCaches.filter((name) => !usedCaches.has(name)); |
| 1155 | await Promise.all(cachesToDelete.map((name) => this.adapter.caches.delete(name))); |
| 1156 | } catch (err) { |
| 1157 | // Oh well? Not much that can be done here. These caches will be removed on the next attempt |
| 1158 | // or when the SW revs its format version, which happens from time to time. |
| 1159 | this.debugger.log(err as Error, 'cleanupCaches'); |
| 1160 | } |
| 1161 | } |
| 1162 | |
| 1163 | /** |
| 1164 | * Determine if a specific version of the given resource is cached anywhere within the SW, |