1
- import { APP_RESOURCES , getCachedOrFetch } from './cache ' ;
1
+ import { version } from '$service-worker ' ;
2
2
3
- function isAssetRequest ( pathname : string ) : boolean {
4
- return / ^ \/ a p i \/ a s s e t s \/ [ a - f 0 - 9 - ] + \/ ( o r i g i n a l | t h u m b n a i l ) / . 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 } ;
5
74
}
6
75
7
- function isIgnoredFileType ( pathname : string ) : boolean {
8
- return / \. ( p n g | i c o | t x t | j s o n | t s | t t f | c s s | j s | s v e l t e ) $ / . 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
+ }
9
80
}
10
81
11
- function isIgnoredPath ( pathname : string ) : boolean {
12
- return / ^ \/ ( s r c | a p i ) ( \/ .* ) ? $ / . test ( pathname ) || / ^ \/ ( n o d e _ m o d u l e s | @ v i t e | @ i d ) ( \/ .* ) ? $ / . 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 / ^ \/ a p i \/ a s s e t s \/ [ a - f 0 - 9 - ] + \/ ( o r i g i n a l | t h u m b n a i l ) / . test ( pathname ) ;
13
100
}
14
101
15
102
export function handleFetchEvent ( event : FetchEvent ) : void {
@@ -18,21 +105,12 @@ export function handleFetchEvent(event: FetchEvent): void {
18
105
}
19
106
20
107
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 ) {
24
109
return ;
25
110
}
26
111
27
112
if ( isAssetRequest ( url . pathname ) ) {
28
113
event . respondWith ( getCachedOrFetch ( event . request , true ) ) ;
29
114
return ;
30
115
}
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 ) ) ;
38
116
}
0 commit comments