* Decide which version of the manifest to use for the event.
(event: FetchEvent)
| 796 | * Decide which version of the manifest to use for the event. |
| 797 | */ |
| 798 | private async assignVersion(event: FetchEvent): Promise<AppVersion | null> { |
| 799 | // First, check whether the event has a (non empty) client ID. If it does, the version may |
| 800 | // already be associated. |
| 801 | // |
| 802 | // NOTE: For navigation requests, we care about the `resultingClientId`. If it is undefined or |
| 803 | // the empty string (which is the case for sub-resource requests), we look at `clientId`. |
| 804 | // |
| 805 | // NOTE: If a request is a worker script, we should use the `clientId`, as worker is a part |
| 806 | // of requesting client. |
| 807 | const isWorkerScriptRequest = |
| 808 | event.request.destination === 'worker' && event.resultingClientId && event.clientId; |
| 809 | const clientId = isWorkerScriptRequest |
| 810 | ? event.clientId |
| 811 | : event.resultingClientId || event.clientId; |
| 812 | if (clientId) { |
| 813 | // Check if there is an assigned client id. |
| 814 | if (this.clientVersionMap.has(clientId)) { |
| 815 | // There is an assignment for this client already. |
| 816 | const hash = this.clientVersionMap.get(clientId)!; |
| 817 | let appVersion = this.lookupVersionByHash(hash, 'assignVersion'); |
| 818 | |
| 819 | // Ordinarily, this client would be served from its assigned version. But, if this |
| 820 | // request is a navigation request, this client can be updated to the latest |
| 821 | // version immediately. |
| 822 | if ( |
| 823 | this.state === DriverReadyState.NORMAL && |
| 824 | hash !== this.latestHash && |
| 825 | appVersion.isNavigationRequest(event.request) |
| 826 | ) { |
| 827 | // Update this client to the latest version immediately. |
| 828 | if (this.latestHash === null) { |
| 829 | throw new Error(`Invariant violated (assignVersion): latestHash was null`); |
| 830 | } |
| 831 | |
| 832 | const client = await this.scope.clients.get(clientId); |
| 833 | if (client) { |
| 834 | await this.updateClient(client); |
| 835 | } |
| 836 | |
| 837 | appVersion = this.lookupVersionByHash(this.latestHash, 'assignVersion'); |
| 838 | } |
| 839 | |
| 840 | if (isWorkerScriptRequest) { |
| 841 | if (!this.clientVersionMap.has(event.resultingClientId)) { |
| 842 | // New worker hasn't been seen before; set this client to requesting client version |
| 843 | this.clientVersionMap.set(event.resultingClientId, hash); |
| 844 | await this.sync(); |
| 845 | } else if (this.clientVersionMap.get(event.resultingClientId)! !== hash) { |
| 846 | throw new Error( |
| 847 | `Version mismatch between worker client ${event.resultingClientId} and requesting client ${clientId}`, |
| 848 | ); |
| 849 | } |
| 850 | } |
| 851 | |
| 852 | // TODO: make sure the version is valid. |
| 853 | return appVersion; |
| 854 | } else { |
| 855 | // This is the first time this client ID has been seen. Whether the SW is in a |
no test coverage detected