Skip to content

Commit 91cbd56

Browse files
authored
revert: service worker changes (#19227)
1 parent 35280b9 commit 91cbd56

File tree

4 files changed

+97
-129
lines changed

4 files changed

+97
-129
lines changed

web/src/service-worker/broadcast-channel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { cancelLoad, getCachedOrFetch } from './cache';
1+
import { cancelLoad, getCachedOrFetch } from './fetch-event';
22

33
export const installBroadcastChannelListener = () => {
44
const broadcast = new BroadcastChannel('immich');

web/src/service-worker/cache.ts

Lines changed: 0 additions & 106 deletions
This file was deleted.

web/src/service-worker/fetch-event.ts

Lines changed: 95 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,102 @@
1-
import { APP_RESOURCES, getCachedOrFetch } from './cache';
1+
import { version } from '$service-worker';
22

3-
function isAssetRequest(pathname: string): boolean {
4-
return /^\/api\/assets\/[a-f0-9-]+\/(original|thumbnail)/.test(pathname);
3+
const useCache = true;
4+
const CACHE = `cache-${version}`;
5+
6+
export const isURL = (request: URL | RequestInfo): request is URL => (request as URL).href !== undefined;
7+
export const isRequest = (request: RequestInfo): request is Request => (request as Request).url !== undefined;
8+
9+
export async function deleteOldCaches() {
10+
for (const key of await caches.keys()) {
11+
if (key !== CACHE) {
12+
await caches.delete(key);
13+
}
14+
}
15+
}
16+
17+
const pendingLoads = new Map<string, AbortController>();
18+
19+
export async function cancelLoad(urlString: string) {
20+
const pending = pendingLoads.get(urlString);
21+
if (pending) {
22+
pending.abort();
23+
pendingLoads.delete(urlString);
24+
}
25+
}
26+
27+
export async function getCachedOrFetch(request: URL | Request | string, cancelable: boolean = false) {
28+
const cached = await checkCache(request);
29+
if (cached.response) {
30+
return cached.response;
31+
}
32+
33+
try {
34+
if (!cancelable) {
35+
const response = await fetch(request);
36+
checkResponse(response);
37+
return response;
38+
}
39+
40+
return await fetchWithCancellation(request, cached.cache);
41+
} catch {
42+
return new Response(undefined, {
43+
status: 499,
44+
statusText: 'Request canceled: Instructions unclear, accidentally interrupted myself',
45+
});
46+
}
47+
}
48+
49+
async function fetchWithCancellation(request: URL | Request | string, cache: Cache) {
50+
const cacheKey = getCacheKey(request);
51+
const cancelToken = new AbortController();
52+
53+
try {
54+
pendingLoads.set(cacheKey, cancelToken);
55+
const response = await fetch(request, {
56+
signal: cancelToken.signal,
57+
});
58+
59+
checkResponse(response);
60+
setCached(response, cache, cacheKey);
61+
return response;
62+
} finally {
63+
pendingLoads.delete(cacheKey);
64+
}
65+
}
66+
67+
async function checkCache(url: URL | Request | string) {
68+
if (!useCache) {
69+
return;
70+
}
71+
const cache = await caches.open(CACHE);
72+
const response = await cache.match(url);
73+
return { cache, response };
574
}
675

7-
function isIgnoredFileType(pathname: string): boolean {
8-
return /\.(png|ico|txt|json|ts|ttf|css|js|svelte)$/.test(pathname);
76+
async function setCached(response: Response, cache: Cache, cacheKey: URL | Request | string) {
77+
if (response.status === 200) {
78+
cache.put(cacheKey, response.clone());
79+
}
980
}
1081

11-
function isIgnoredPath(pathname: string): boolean {
12-
return /^\/(src|api)(\/.*)?$/.test(pathname) || /^\/(node_modules|@vite|@id)(\/.*)?$/.test(pathname);
82+
function checkResponse(response: Response) {
83+
if (!(response instanceof Response)) {
84+
throw new TypeError('invalid response from fetch');
85+
}
86+
}
87+
88+
function getCacheKey(request: URL | Request | string) {
89+
if (isURL(request)) {
90+
return request.toString();
91+
} else if (isRequest(request)) {
92+
return request.url;
93+
} else {
94+
return request;
95+
}
96+
}
97+
98+
function isAssetRequest(pathname: string): boolean {
99+
return /^\/api\/assets\/[a-f0-9-]+\/(original|thumbnail)/.test(pathname);
13100
}
14101

15102
export function handleFetchEvent(event: FetchEvent): void {
@@ -18,21 +105,12 @@ export function handleFetchEvent(event: FetchEvent): void {
18105
}
19106

20107
const url = new URL(event.request.url);
21-
22-
if (APP_RESOURCES.includes(url.pathname)) {
23-
event.respondWith(getCachedOrFetch(event.request));
108+
if (url.origin !== self.location.origin) {
24109
return;
25110
}
26111

27112
if (isAssetRequest(url.pathname)) {
28113
event.respondWith(getCachedOrFetch(event.request, true));
29114
return;
30115
}
31-
32-
if (isIgnoredFileType(url.pathname) || isIgnoredPath(url.pathname)) {
33-
return;
34-
}
35-
36-
const slash = new URL('/', url.origin);
37-
event.respondWith(getCachedOrFetch(slash));
38116
}

web/src/service-worker/index.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,17 @@
33
/// <reference lib="esnext" />
44
/// <reference lib="webworker" />
55
import { installBroadcastChannelListener } from './broadcast-channel';
6-
import { addFilesToCache, deleteOldCaches } from './cache';
7-
import { handleFetchEvent } from './fetch-event';
6+
import { deleteOldCaches, handleFetchEvent } from './fetch-event';
87

98
const sw = globalThis as unknown as ServiceWorkerGlobalScope;
109

1110
const handleActivate = (event: ExtendableEvent) => {
1211
event.waitUntil(sw.clients.claim());
13-
// Remove previous cached data from disk
1412
event.waitUntil(deleteOldCaches());
1513
};
1614

1715
const handleInstall = (event: ExtendableEvent) => {
1816
event.waitUntil(sw.skipWaiting());
19-
// Create a new cache and add all files to it
20-
event.waitUntil(addFilesToCache());
2117
};
2218

2319
sw.addEventListener('install', handleInstall, { passive: true });

0 commit comments

Comments
 (0)