@serwist/strategies 9.0.0-preview.0 → 9.0.0-preview.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CacheFirst.d.ts +2 -3
- package/dist/CacheFirst.d.ts.map +1 -1
- package/dist/CacheOnly.d.ts +2 -3
- package/dist/CacheOnly.d.ts.map +1 -1
- package/dist/NetworkFirst.d.ts +12 -14
- package/dist/NetworkFirst.d.ts.map +1 -1
- package/dist/NetworkOnly.d.ts +9 -12
- package/dist/NetworkOnly.d.ts.map +1 -1
- package/dist/StaleWhileRevalidate.d.ts +18 -20
- package/dist/StaleWhileRevalidate.d.ts.map +1 -1
- package/dist/Strategy.d.ts +1 -2
- package/dist/Strategy.d.ts.map +1 -1
- package/dist/StrategyHandler.d.ts +1 -2
- package/dist/StrategyHandler.d.ts.map +1 -1
- package/dist/index.js +50 -392
- package/package.json +4 -4
- package/src/CacheFirst.ts +2 -4
- package/src/CacheOnly.ts +2 -4
- package/src/NetworkFirst.ts +12 -15
- package/src/NetworkOnly.ts +9 -13
- package/src/StaleWhileRevalidate.ts +18 -21
- package/src/Strategy.ts +1 -3
- package/src/StrategyHandler.ts +15 -16
package/dist/CacheFirst.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Strategy } from "./Strategy.js";
|
|
2
2
|
import type { StrategyHandler } from "./StrategyHandler.js";
|
|
3
3
|
/**
|
|
4
|
-
* An implementation of
|
|
4
|
+
* An implementation of the [cache first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#cache-first-falling-back-to-network)
|
|
5
5
|
* request strategy.
|
|
6
6
|
*
|
|
7
7
|
* A cache first strategy is useful for assets that have been revisioned,
|
|
@@ -11,7 +11,7 @@ import type { StrategyHandler } from "./StrategyHandler.js";
|
|
|
11
11
|
* If the network request fails, and there is no cache match, this will throw
|
|
12
12
|
* a `SerwistError` exception.
|
|
13
13
|
*/
|
|
14
|
-
declare class CacheFirst extends Strategy {
|
|
14
|
+
export declare class CacheFirst extends Strategy {
|
|
15
15
|
/**
|
|
16
16
|
* @private
|
|
17
17
|
* @param request A request to run this strategy for.
|
|
@@ -20,5 +20,4 @@ declare class CacheFirst extends Strategy {
|
|
|
20
20
|
*/
|
|
21
21
|
_handle(request: Request, handler: StrategyHandler): Promise<Response>;
|
|
22
22
|
}
|
|
23
|
-
export { CacheFirst };
|
|
24
23
|
//# sourceMappingURL=CacheFirst.d.ts.map
|
package/dist/CacheFirst.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CacheFirst.d.ts","sourceRoot":"","sources":["../src/CacheFirst.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D;;;;;;;;;;GAUG;AACH,
|
|
1
|
+
{"version":3,"file":"CacheFirst.d.ts","sourceRoot":"","sources":["../src/CacheFirst.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D;;;;;;;;;;GAUG;AACH,qBAAa,UAAW,SAAQ,QAAQ;IACtC;;;;;OAKG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;CAsD7E"}
|
package/dist/CacheOnly.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Strategy } from "./Strategy.js";
|
|
2
2
|
import type { StrategyHandler } from "./StrategyHandler.js";
|
|
3
3
|
/**
|
|
4
|
-
* An implementation of
|
|
4
|
+
* An implementation of the [cache only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#cache-only)
|
|
5
5
|
* request strategy.
|
|
6
6
|
*
|
|
7
7
|
* This class is useful if you want to take advantage of any Serwist plugin.
|
|
8
8
|
*
|
|
9
9
|
* If there is no cache match, this will throw a `SerwistError` exception.
|
|
10
10
|
*/
|
|
11
|
-
declare class CacheOnly extends Strategy {
|
|
11
|
+
export declare class CacheOnly extends Strategy {
|
|
12
12
|
/**
|
|
13
13
|
* @private
|
|
14
14
|
* @param request A request to run this strategy for.
|
|
@@ -17,5 +17,4 @@ declare class CacheOnly extends Strategy {
|
|
|
17
17
|
*/
|
|
18
18
|
_handle(request: Request, handler: StrategyHandler): Promise<Response>;
|
|
19
19
|
}
|
|
20
|
-
export { CacheOnly };
|
|
21
20
|
//# sourceMappingURL=CacheOnly.d.ts.map
|
package/dist/CacheOnly.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CacheOnly.d.ts","sourceRoot":"","sources":["../src/CacheOnly.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D;;;;;;;GAOG;AACH,
|
|
1
|
+
{"version":3,"file":"CacheOnly.d.ts","sourceRoot":"","sources":["../src/CacheOnly.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D;;;;;;;GAOG;AACH,qBAAa,SAAU,SAAQ,QAAQ;IACrC;;;;;OAKG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;CA4B7E"}
|
package/dist/NetworkFirst.d.ts
CHANGED
|
@@ -7,21 +7,20 @@ export interface NetworkFirstOptions extends StrategyOptions {
|
|
|
7
7
|
*/
|
|
8
8
|
networkTimeoutSeconds?: number;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
* An implementation of a [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache)
|
|
12
|
-
* request strategy.
|
|
13
|
-
*
|
|
14
|
-
* By default, this strategy will cache responses with a 200 status code as
|
|
15
|
-
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
16
|
-
* Opaque responses are are cross-origin requests where the response doesn't
|
|
17
|
-
* support [CORS](https://enable-cors.org/).
|
|
18
|
-
*
|
|
19
|
-
* If the network request fails, and there is no cache match, this will throw
|
|
20
|
-
* a `SerwistError` exception.
|
|
21
|
-
*/
|
|
22
|
-
declare class NetworkFirst extends Strategy {
|
|
10
|
+
export declare class NetworkFirst extends Strategy {
|
|
23
11
|
private readonly _networkTimeoutSeconds;
|
|
24
12
|
/**
|
|
13
|
+
* An implementation of the [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache)
|
|
14
|
+
* request strategy.
|
|
15
|
+
*
|
|
16
|
+
* By default, this strategy will cache responses with a 200 status code as
|
|
17
|
+
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
18
|
+
* Opaque responses are are cross-origin requests where the response doesn't
|
|
19
|
+
* support [CORS](https://enable-cors.org/).
|
|
20
|
+
*
|
|
21
|
+
* If the network request fails, and there is no cache match, this will throw
|
|
22
|
+
* a `SerwistError` exception.
|
|
23
|
+
*
|
|
25
24
|
* @param options
|
|
26
25
|
* This option can be used to combat
|
|
27
26
|
* "[lie-fi](https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi)"
|
|
@@ -58,5 +57,4 @@ declare class NetworkFirst extends Strategy {
|
|
|
58
57
|
handler: StrategyHandler;
|
|
59
58
|
}): Promise<Response | undefined>;
|
|
60
59
|
}
|
|
61
|
-
export { NetworkFirst };
|
|
62
60
|
//# sourceMappingURL=NetworkFirst.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkFirst.d.ts","sourceRoot":"","sources":["../src/NetworkFirst.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI5D,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED
|
|
1
|
+
{"version":3,"file":"NetworkFirst.d.ts","sourceRoot":"","sources":["../src/NetworkFirst.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI5D,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,qBAAa,YAAa,SAAQ,QAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IAEhD;;;;;;;;;;;;;;;;OAgBG;gBACS,OAAO,GAAE,mBAAwB;IAsB7C;;;;;OAKG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgE5E;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA8B1B;;;;;;;;;OASG;IACG,kBAAkB,CAAC,EACvB,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAO,GACR,EAAE;QACD,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE,GAAG,EAAE,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,eAAe,CAAC;KAC1B,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;CAqClC"}
|
package/dist/NetworkOnly.d.ts
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import type { StrategyOptions } from "./Strategy.js";
|
|
2
2
|
import { Strategy } from "./Strategy.js";
|
|
3
3
|
import type { StrategyHandler } from "./StrategyHandler.js";
|
|
4
|
-
interface NetworkOnlyOptions extends Omit<StrategyOptions, "cacheName" | "matchOptions"> {
|
|
4
|
+
export interface NetworkOnlyOptions extends Omit<StrategyOptions, "cacheName" | "matchOptions"> {
|
|
5
5
|
/**
|
|
6
6
|
* If set, any network requests that fail to respond within the timeout will result in a network error.
|
|
7
7
|
*/
|
|
8
8
|
networkTimeoutSeconds?: number;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
* An implementation of a [network only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-only)
|
|
12
|
-
* request strategy.
|
|
13
|
-
*
|
|
14
|
-
* This class is useful if you want to take advantage of any Serwist plugin.
|
|
15
|
-
*
|
|
16
|
-
* If the network request fails, this will throw a `SerwistError` exception.
|
|
17
|
-
*/
|
|
18
|
-
declare class NetworkOnly extends Strategy {
|
|
10
|
+
export declare class NetworkOnly extends Strategy {
|
|
19
11
|
private readonly _networkTimeoutSeconds;
|
|
20
12
|
/**
|
|
13
|
+
* An implementation of the [network only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-only)
|
|
14
|
+
* request strategy.
|
|
15
|
+
*
|
|
16
|
+
* This class is useful if you want to take advantage of any Serwist plugin.
|
|
17
|
+
*
|
|
18
|
+
* If the network request fails, this will throw a `SerwistError` exception.
|
|
19
|
+
*
|
|
21
20
|
* @param options
|
|
22
21
|
*/
|
|
23
22
|
constructor(options?: NetworkOnlyOptions);
|
|
@@ -29,6 +28,4 @@ declare class NetworkOnly extends Strategy {
|
|
|
29
28
|
*/
|
|
30
29
|
_handle(request: Request, handler: StrategyHandler): Promise<Response>;
|
|
31
30
|
}
|
|
32
|
-
export { NetworkOnly };
|
|
33
|
-
export type { NetworkOnlyOptions };
|
|
34
31
|
//# sourceMappingURL=NetworkOnly.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NetworkOnly.d.ts","sourceRoot":"","sources":["../src/NetworkOnly.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,
|
|
1
|
+
{"version":3,"file":"NetworkOnly.d.ts","sourceRoot":"","sources":["../src/NetworkOnly.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,cAAc,CAAC;IAC7F;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,qBAAa,WAAY,SAAQ,QAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IAEhD;;;;;;;;;OASG;gBACS,OAAO,GAAE,kBAAuB;IAM5C;;;;;OAKG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;CA+C7E"}
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import type { StrategyOptions } from "./Strategy.js";
|
|
2
2
|
import { Strategy } from "./Strategy.js";
|
|
3
3
|
import type { StrategyHandler } from "./StrategyHandler.js";
|
|
4
|
-
|
|
5
|
-
* An implementation of a
|
|
6
|
-
* [stale-while-revalidate](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#stale-while-revalidate)
|
|
7
|
-
* request strategy.
|
|
8
|
-
*
|
|
9
|
-
* Resources are requested from both the cache and the network in parallel.
|
|
10
|
-
* The strategy will respond with the cached version if available, otherwise
|
|
11
|
-
* wait for the network response. The cache is updated with the network response
|
|
12
|
-
* with each successful request.
|
|
13
|
-
*
|
|
14
|
-
* By default, this strategy will cache responses with a 200 status code as
|
|
15
|
-
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
16
|
-
* Opaque responses are cross-origin requests where the response doesn't
|
|
17
|
-
* support [CORS](https://enable-cors.org/).
|
|
18
|
-
*
|
|
19
|
-
* If the network request fails, and there is no cache match, this will throw
|
|
20
|
-
* a `SerwistError` exception.
|
|
21
|
-
*/
|
|
22
|
-
declare class StaleWhileRevalidate extends Strategy {
|
|
4
|
+
export declare class StaleWhileRevalidate extends Strategy {
|
|
23
5
|
/**
|
|
6
|
+
* An implementation of the
|
|
7
|
+
* [stale-while-revalidate](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#stale-while-revalidate)
|
|
8
|
+
* request strategy.
|
|
9
|
+
*
|
|
10
|
+
* Resources are requested from both the cache and the network in parallel.
|
|
11
|
+
* The strategy will respond with the cached version if available, otherwise
|
|
12
|
+
* wait for the network response. The cache is updated with the network response
|
|
13
|
+
* with each successful request.
|
|
14
|
+
*
|
|
15
|
+
* By default, this strategy will cache responses with a 200 status code as
|
|
16
|
+
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
17
|
+
* Opaque responses are cross-origin requests where the response doesn't
|
|
18
|
+
* support [CORS](https://enable-cors.org/).
|
|
19
|
+
*
|
|
20
|
+
* If the network request fails, and there is no cache match, this will throw
|
|
21
|
+
* a `SerwistError` exception.
|
|
22
|
+
*
|
|
24
23
|
* @param options
|
|
25
24
|
*/
|
|
26
25
|
constructor(options?: StrategyOptions);
|
|
@@ -32,5 +31,4 @@ declare class StaleWhileRevalidate extends Strategy {
|
|
|
32
31
|
*/
|
|
33
32
|
_handle(request: Request, handler: StrategyHandler): Promise<Response>;
|
|
34
33
|
}
|
|
35
|
-
export { StaleWhileRevalidate };
|
|
36
34
|
//# sourceMappingURL=StaleWhileRevalidate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StaleWhileRevalidate.d.ts","sourceRoot":"","sources":["../src/StaleWhileRevalidate.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI5D
|
|
1
|
+
{"version":3,"file":"StaleWhileRevalidate.d.ts","sourceRoot":"","sources":["../src/StaleWhileRevalidate.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI5D,qBAAa,oBAAqB,SAAQ,QAAQ;IAChD;;;;;;;;;;;;;;;;;;;OAmBG;gBACS,OAAO,GAAE,eAAoB;IAUzC;;;;;OAKG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;CAsD7E"}
|
package/dist/Strategy.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export interface StrategyOptions {
|
|
|
27
27
|
* fetching and cache logic, which will ensure all relevant cache, cache options,
|
|
28
28
|
* fetch options and plugins are used (per the current strategy instance).
|
|
29
29
|
*/
|
|
30
|
-
declare abstract class Strategy implements RouteHandlerObject {
|
|
30
|
+
export declare abstract class Strategy implements RouteHandlerObject {
|
|
31
31
|
cacheName: string;
|
|
32
32
|
plugins: SerwistPlugin[];
|
|
33
33
|
fetchOptions?: RequestInit;
|
|
@@ -80,5 +80,4 @@ declare abstract class Strategy implements RouteHandlerObject {
|
|
|
80
80
|
_getResponse(handler: StrategyHandler, request: Request, event: ExtendableEvent): Promise<Response>;
|
|
81
81
|
_awaitComplete(responseDone: Promise<Response>, handler: StrategyHandler, request: Request, event: ExtendableEvent): Promise<void>;
|
|
82
82
|
}
|
|
83
|
-
export { Strategy };
|
|
84
83
|
//# sourceMappingURL=Strategy.d.ts.map
|
package/dist/Strategy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Strategy.d.ts","sourceRoot":"","sources":["../src/Strategy.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG/F,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B;;;OAGG;IACH,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED;;;;;GAKG;AACH,
|
|
1
|
+
{"version":3,"file":"Strategy.d.ts","sourceRoot":"","sources":["../src/Strategy.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG/F,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B;;;OAGG;IACH,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED;;;;;GAKG;AACH,8BAAsB,QAAS,YAAW,kBAAkB;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAEjC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAErG;;;;;;;;;OASG;gBACS,OAAO,GAAE,eAAoB;IAOzC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,sBAAsB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAKvE;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,sBAAsB,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAsBrF,YAAY,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAyCnG,cAAc,CAAC,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAqCzI"}
|
|
@@ -6,7 +6,7 @@ import type { Strategy } from "./Strategy.js";
|
|
|
6
6
|
* and keeps track of when the strategy is "done" (i.e. all added `event.waitUntil()` promises
|
|
7
7
|
* have resolved).
|
|
8
8
|
*/
|
|
9
|
-
declare class StrategyHandler {
|
|
9
|
+
export declare class StrategyHandler {
|
|
10
10
|
/**
|
|
11
11
|
* The request the strategy is performing (passed to the strategy's
|
|
12
12
|
* `handle()` or `handleAll()` method).
|
|
@@ -184,5 +184,4 @@ declare class StrategyHandler {
|
|
|
184
184
|
*/
|
|
185
185
|
_ensureResponseSafeToCache(response: Response): Promise<Response | undefined>;
|
|
186
186
|
}
|
|
187
|
-
export { StrategyHandler };
|
|
188
187
|
//# sourceMappingURL=StrategyHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StrategyHandler.d.ts","sourceRoot":"","sources":["../src/StrategyHandler.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAiB,aAAa,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAYtH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C;;;;;GAKG;AACH,
|
|
1
|
+
{"version":3,"file":"StrategyHandler.d.ts","sourceRoot":"","sources":["../src/StrategyHandler.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAiB,aAAa,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAYtH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B;;;OAGG;IACI,OAAO,EAAG,OAAO,CAAC;IACzB;;;;;OAKG;IACI,GAAG,CAAC,EAAE,GAAG,CAAC;IACjB;;OAEG;IACI,KAAK,EAAE,eAAe,CAAC;IAC9B;;;;;;OAMG;IACI,MAAM,CAAC,EAAE,GAAG,CAAC;IAEpB,OAAO,CAAC,UAAU,CAA+B;IAEjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAiB;IACzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAgB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IAEpE;;;;;;;;;OASG;gBACS,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAsB;IA4B/D;;;;;;;;;;;;OAYG;IACG,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAyElD;;;;;;;;;OASG;IACG,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAS7D;;;;;;;;;;;OAWG;IACG,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IA+BjE;;;;;;;;;;;;;;OAcG;IACG,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IA8FtE;;;;;;;;;;OAUG;IACG,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB7E;;;;;;OAMG;IACH,WAAW,CAAC,CAAC,SAAS,MAAM,aAAa,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO;IAS5D;;;;;;;;;;;;OAYG;IACG,YAAY,CAAC,CAAC,SAAS,MAAM,WAAW,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ3I;;;;;;;;OAQG;IACF,gBAAgB,CAAC,CAAC,SAAS,MAAM,aAAa,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAgBnG;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAK7C;;;;;;;;OAQG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAOlC;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf;;;;;;;OAOG;IACG,0BAA0B,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;CAuCpF"}
|
package/dist/index.js
CHANGED
|
@@ -3,48 +3,18 @@ import { assert, Deferred, logger, getFriendlyURL, SerwistError, timeout, cacheM
|
|
|
3
3
|
function toRequest(input) {
|
|
4
4
|
return typeof input === "string" ? new Request(input) : input;
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*/ class StrategyHandler {
|
|
12
|
-
/**
|
|
13
|
-
* The request the strategy is performing (passed to the strategy's
|
|
14
|
-
* `handle()` or `handleAll()` method).
|
|
15
|
-
*/ request;
|
|
16
|
-
/**
|
|
17
|
-
* A `URL` instance of `request.url` (if passed to the strategy's
|
|
18
|
-
* `handle()` or `handleAll()` method).
|
|
19
|
-
* Note: the `url` param will be present if the strategy was invoked
|
|
20
|
-
* from a `@serwist/routing.Route` object.
|
|
21
|
-
*/ url;
|
|
22
|
-
/**
|
|
23
|
-
* The event associated with this request.
|
|
24
|
-
*/ event;
|
|
25
|
-
/**
|
|
26
|
-
* A `param` value (if passed to the strategy's
|
|
27
|
-
* `handle()` or `handleAll()` method).
|
|
28
|
-
* Note: the `param` param will be present if the strategy was invoked
|
|
29
|
-
* from a `@serwist/routing.Route` object and the `@serwist/strategies.matchCallback`
|
|
30
|
-
* returned a truthy value (it will be that value).
|
|
31
|
-
*/ params;
|
|
6
|
+
class StrategyHandler {
|
|
7
|
+
request;
|
|
8
|
+
url;
|
|
9
|
+
event;
|
|
10
|
+
params;
|
|
32
11
|
_cacheKeys = {};
|
|
33
12
|
_strategy;
|
|
34
13
|
_extendLifetimePromises;
|
|
35
14
|
_handlerDeferred;
|
|
36
15
|
_plugins;
|
|
37
16
|
_pluginStateMap;
|
|
38
|
-
|
|
39
|
-
* Creates a new instance associated with the passed strategy and event
|
|
40
|
-
* that's handling the request.
|
|
41
|
-
*
|
|
42
|
-
* The constructor also initializes the state that will be passed to each of
|
|
43
|
-
* the plugins handling this request.
|
|
44
|
-
*
|
|
45
|
-
* @param strategy
|
|
46
|
-
* @param options
|
|
47
|
-
*/ constructor(strategy, options){
|
|
17
|
+
constructor(strategy, options){
|
|
48
18
|
if (process.env.NODE_ENV !== "production") {
|
|
49
19
|
assert.isInstance(options.event, ExtendableEvent, {
|
|
50
20
|
moduleName: "@serwist/strategies",
|
|
@@ -58,8 +28,6 @@ function toRequest(input) {
|
|
|
58
28
|
this._strategy = strategy;
|
|
59
29
|
this._handlerDeferred = new Deferred();
|
|
60
30
|
this._extendLifetimePromises = [];
|
|
61
|
-
// Copy the plugins list (since it's mutable on the strategy),
|
|
62
|
-
// so any mutations don't affect this handler instance.
|
|
63
31
|
this._plugins = [
|
|
64
32
|
...strategy.plugins
|
|
65
33
|
];
|
|
@@ -69,19 +37,7 @@ function toRequest(input) {
|
|
|
69
37
|
}
|
|
70
38
|
this.event.waitUntil(this._handlerDeferred.promise);
|
|
71
39
|
}
|
|
72
|
-
|
|
73
|
-
* Fetches a given request (and invokes any applicable plugin callback
|
|
74
|
-
* methods) using the `fetchOptions` (for non-navigation requests) and
|
|
75
|
-
* `plugins` defined on the `Strategy` object.
|
|
76
|
-
*
|
|
77
|
-
* The following plugin lifecycle methods are invoked when using this method:
|
|
78
|
-
* - `requestWillFetch()`
|
|
79
|
-
* - `fetchDidSucceed()`
|
|
80
|
-
* - `fetchDidFail()`
|
|
81
|
-
*
|
|
82
|
-
* @param input The URL or request to fetch.
|
|
83
|
-
* @returns
|
|
84
|
-
*/ async fetch(input) {
|
|
40
|
+
async fetch(input) {
|
|
85
41
|
const { event } = this;
|
|
86
42
|
let request = toRequest(input);
|
|
87
43
|
if (request.mode === "navigate" && event instanceof FetchEvent && event.preloadResponse) {
|
|
@@ -93,9 +49,6 @@ function toRequest(input) {
|
|
|
93
49
|
return possiblePreloadResponse;
|
|
94
50
|
}
|
|
95
51
|
}
|
|
96
|
-
// If there is a fetchDidFail plugin, we need to save a clone of the
|
|
97
|
-
// original request before it's either modified by a requestWillFetch
|
|
98
|
-
// plugin or before the original request's body is consumed via fetch().
|
|
99
52
|
const originalRequest = this.hasCallback("fetchDidFail") ? request.clone() : null;
|
|
100
53
|
try {
|
|
101
54
|
for (const cb of this.iterateCallbacks("requestWillFetch")){
|
|
@@ -111,13 +64,9 @@ function toRequest(input) {
|
|
|
111
64
|
});
|
|
112
65
|
}
|
|
113
66
|
}
|
|
114
|
-
// The request can be altered by plugins with `requestWillFetch` making
|
|
115
|
-
// the original request (most likely from a `fetch` event) different
|
|
116
|
-
// from the Request we make. Pass both to `fetchDidFail` to aid debugging.
|
|
117
67
|
const pluginFilteredRequest = request.clone();
|
|
118
68
|
try {
|
|
119
69
|
let fetchResponse;
|
|
120
|
-
// See https://github.com/GoogleChrome/workbox/issues/1796
|
|
121
70
|
fetchResponse = await fetch(request, request.mode === "navigate" ? undefined : this._strategy.fetchOptions);
|
|
122
71
|
if (process.env.NODE_ENV !== "production") {
|
|
123
72
|
logger.debug(`Network request for '${getFriendlyURL(request.url)}' returned a response with status '${fetchResponse.status}'.`);
|
|
@@ -134,8 +83,6 @@ function toRequest(input) {
|
|
|
134
83
|
if (process.env.NODE_ENV !== "production") {
|
|
135
84
|
logger.log(`Network request for '${getFriendlyURL(request.url)}' threw an error.`, error);
|
|
136
85
|
}
|
|
137
|
-
// `originalRequest` will only exist if a `fetchDidFail` callback
|
|
138
|
-
// is being used (see above).
|
|
139
86
|
if (originalRequest) {
|
|
140
87
|
await this.runCallbacks("fetchDidFail", {
|
|
141
88
|
error: error,
|
|
@@ -147,33 +94,13 @@ function toRequest(input) {
|
|
|
147
94
|
throw error;
|
|
148
95
|
}
|
|
149
96
|
}
|
|
150
|
-
|
|
151
|
-
* Calls `this.fetch()` and (in the background) runs `this.cachePut()` on
|
|
152
|
-
* the response generated by `this.fetch()`.
|
|
153
|
-
*
|
|
154
|
-
* The call to `this.cachePut()` automatically invokes `this.waitUntil()`,
|
|
155
|
-
* so you do not have to manually call `waitUntil()` on the event.
|
|
156
|
-
*
|
|
157
|
-
* @param input The request or URL to fetch and cache.
|
|
158
|
-
* @returns
|
|
159
|
-
*/ async fetchAndCachePut(input) {
|
|
97
|
+
async fetchAndCachePut(input) {
|
|
160
98
|
const response = await this.fetch(input);
|
|
161
99
|
const responseClone = response.clone();
|
|
162
100
|
void this.waitUntil(this.cachePut(input, responseClone));
|
|
163
101
|
return response;
|
|
164
102
|
}
|
|
165
|
-
|
|
166
|
-
* Matches a request from the cache (and invokes any applicable plugin
|
|
167
|
-
* callback methods) using the `cacheName`, `matchOptions`, and `plugins`
|
|
168
|
-
* defined on the strategy object.
|
|
169
|
-
*
|
|
170
|
-
* The following plugin lifecycle methods are invoked when using this method:
|
|
171
|
-
* - cacheKeyWillByUsed()
|
|
172
|
-
* - cachedResponseWillByUsed()
|
|
173
|
-
*
|
|
174
|
-
* @param key The Request or URL to use as the cache key.
|
|
175
|
-
* @returns A matching response, if found.
|
|
176
|
-
*/ async cacheMatch(key) {
|
|
103
|
+
async cacheMatch(key) {
|
|
177
104
|
const request = toRequest(key);
|
|
178
105
|
let cachedResponse;
|
|
179
106
|
const { cacheName, matchOptions } = this._strategy;
|
|
@@ -203,24 +130,8 @@ function toRequest(input) {
|
|
|
203
130
|
}
|
|
204
131
|
return cachedResponse;
|
|
205
132
|
}
|
|
206
|
-
|
|
207
|
-
* Puts a request/response pair in the cache (and invokes any applicable
|
|
208
|
-
* plugin callback methods) using the `cacheName` and `plugins` defined on
|
|
209
|
-
* the strategy object.
|
|
210
|
-
*
|
|
211
|
-
* The following plugin lifecycle methods are invoked when using this method:
|
|
212
|
-
* - cacheKeyWillByUsed()
|
|
213
|
-
* - cacheWillUpdate()
|
|
214
|
-
* - cacheDidUpdate()
|
|
215
|
-
*
|
|
216
|
-
* @param key The request or URL to use as the cache key.
|
|
217
|
-
* @param response The response to cache.
|
|
218
|
-
* @returns `false` if a cacheWillUpdate caused the response
|
|
219
|
-
* not be cached, and `true` otherwise.
|
|
220
|
-
*/ async cachePut(key, response) {
|
|
133
|
+
async cachePut(key, response) {
|
|
221
134
|
const request = toRequest(key);
|
|
222
|
-
// Run in the next task to avoid blocking other cache reads.
|
|
223
|
-
// https://github.com/w3c/ServiceWorker/issues/1397
|
|
224
135
|
await timeout(0);
|
|
225
136
|
const effectiveRequest = await this.getCacheKey(request, "write");
|
|
226
137
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -230,11 +141,6 @@ function toRequest(input) {
|
|
|
230
141
|
method: effectiveRequest.method
|
|
231
142
|
});
|
|
232
143
|
}
|
|
233
|
-
// See https://github.com/GoogleChrome/workbox/issues/2818
|
|
234
|
-
const vary = response.headers.get("Vary");
|
|
235
|
-
if (vary) {
|
|
236
|
-
logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} has a 'Vary: ${vary}' header. Consider setting the {ignoreVary: true} option on your strategy to ensure cache matching and deletion works as expected.`);
|
|
237
|
-
}
|
|
238
144
|
}
|
|
239
145
|
if (!response) {
|
|
240
146
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -253,21 +159,23 @@ function toRequest(input) {
|
|
|
253
159
|
}
|
|
254
160
|
const { cacheName, matchOptions } = this._strategy;
|
|
255
161
|
const cache = await self.caches.open(cacheName);
|
|
162
|
+
if (process.env.NODE_ENV !== "production") {
|
|
163
|
+
const vary = response.headers.get("Vary");
|
|
164
|
+
if (vary && matchOptions?.ignoreVary !== true) {
|
|
165
|
+
logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} has a 'Vary: ${vary}' header. Consider setting the {ignoreVary: true} option on your strategy to ensure cache matching and deletion works as expected.`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
256
168
|
const hasCacheUpdateCallback = this.hasCallback("cacheDidUpdate");
|
|
257
|
-
const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams(
|
|
258
|
-
// feature. Consider into ways to only add this behavior if using
|
|
259
|
-
// precaching.
|
|
260
|
-
cache, effectiveRequest.clone(), [
|
|
169
|
+
const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams(cache, effectiveRequest.clone(), [
|
|
261
170
|
"__WB_REVISION__"
|
|
262
171
|
], matchOptions) : null;
|
|
263
172
|
if (process.env.NODE_ENV !== "production") {
|
|
264
|
-
logger.debug(`Updating the '${cacheName}' cache with a new Response
|
|
173
|
+
logger.debug(`Updating the '${cacheName}' cache with a new Response for ${getFriendlyURL(effectiveRequest.url)}.`);
|
|
265
174
|
}
|
|
266
175
|
try {
|
|
267
176
|
await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache);
|
|
268
177
|
} catch (error) {
|
|
269
178
|
if (error instanceof Error) {
|
|
270
|
-
// See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError
|
|
271
179
|
if (error.name === "QuotaExceededError") {
|
|
272
180
|
await executeQuotaErrorCallbacks();
|
|
273
181
|
}
|
|
@@ -285,17 +193,7 @@ function toRequest(input) {
|
|
|
285
193
|
}
|
|
286
194
|
return true;
|
|
287
195
|
}
|
|
288
|
-
|
|
289
|
-
* Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and
|
|
290
|
-
* executes any of those callbacks found in sequence. The final `Request`
|
|
291
|
-
* object returned by the last plugin is treated as the cache key for cache
|
|
292
|
-
* reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have
|
|
293
|
-
* been registered, the passed request is returned unmodified
|
|
294
|
-
*
|
|
295
|
-
* @param request
|
|
296
|
-
* @param mode
|
|
297
|
-
* @returns
|
|
298
|
-
*/ async getCacheKey(request, mode) {
|
|
196
|
+
async getCacheKey(request, mode) {
|
|
299
197
|
const key = `${request.url} | ${mode}`;
|
|
300
198
|
if (!this._cacheKeys[key]) {
|
|
301
199
|
let effectiveRequest = request;
|
|
@@ -304,7 +202,6 @@ function toRequest(input) {
|
|
|
304
202
|
mode,
|
|
305
203
|
request: effectiveRequest,
|
|
306
204
|
event: this.event,
|
|
307
|
-
// params has a type any can't change right now.
|
|
308
205
|
params: this.params
|
|
309
206
|
}));
|
|
310
207
|
}
|
|
@@ -312,13 +209,7 @@ function toRequest(input) {
|
|
|
312
209
|
}
|
|
313
210
|
return this._cacheKeys[key];
|
|
314
211
|
}
|
|
315
|
-
|
|
316
|
-
* Returns true if the strategy has at least one plugin with the given
|
|
317
|
-
* callback.
|
|
318
|
-
*
|
|
319
|
-
* @param name The name of the callback to check for.
|
|
320
|
-
* @returns
|
|
321
|
-
*/ hasCallback(name) {
|
|
212
|
+
hasCallback(name) {
|
|
322
213
|
for (const plugin of this._strategy.plugins){
|
|
323
214
|
if (name in plugin) {
|
|
324
215
|
return true;
|
|
@@ -326,34 +217,12 @@ function toRequest(input) {
|
|
|
326
217
|
}
|
|
327
218
|
return false;
|
|
328
219
|
}
|
|
329
|
-
|
|
330
|
-
* Runs all plugin callbacks matching the given name, in order, passing the
|
|
331
|
-
* given param object (merged ith the current plugin state) as the only
|
|
332
|
-
* argument.
|
|
333
|
-
*
|
|
334
|
-
* Note: since this method runs all plugins, it's not suitable for cases
|
|
335
|
-
* where the return value of a callback needs to be applied prior to calling
|
|
336
|
-
* the next callback. See `@serwist/strategies.iterateCallbacks` for how to handle that case.
|
|
337
|
-
*
|
|
338
|
-
* @param name The name of the callback to run within each plugin.
|
|
339
|
-
* @param param The object to pass as the first (and only) param when executing each callback. This object will be merged with the
|
|
340
|
-
* current plugin state prior to callback execution.
|
|
341
|
-
*/ async runCallbacks(name, param) {
|
|
220
|
+
async runCallbacks(name, param) {
|
|
342
221
|
for (const callback of this.iterateCallbacks(name)){
|
|
343
|
-
// TODO(philipwalton): not sure why `any` is needed. It seems like
|
|
344
|
-
// this should work with `as SerwistPluginCallbackParam[C]`.
|
|
345
222
|
await callback(param);
|
|
346
223
|
}
|
|
347
224
|
}
|
|
348
|
-
|
|
349
|
-
* Accepts a callback and returns an iterable of matching plugin callbacks,
|
|
350
|
-
* where each callback is wrapped with the current handler state (i.e. when
|
|
351
|
-
* you call each callback, whatever object parameter you pass it will
|
|
352
|
-
* be merged with the plugin's current state).
|
|
353
|
-
*
|
|
354
|
-
* @param name The name fo the callback to run
|
|
355
|
-
* @returns
|
|
356
|
-
*/ *iterateCallbacks(name) {
|
|
225
|
+
*iterateCallbacks(name) {
|
|
357
226
|
for (const plugin of this._strategy.plugins){
|
|
358
227
|
if (typeof plugin[name] === "function") {
|
|
359
228
|
const state = this._pluginStateMap.get(plugin);
|
|
@@ -362,57 +231,26 @@ function toRequest(input) {
|
|
|
362
231
|
...param,
|
|
363
232
|
state
|
|
364
233
|
};
|
|
365
|
-
// TODO(philipwalton): not sure why `any` is needed. It seems like
|
|
366
|
-
// this should work with `as WorkboxPluginCallbackParam[C]`.
|
|
367
234
|
return plugin[name](statefulParam);
|
|
368
235
|
};
|
|
369
236
|
yield statefulCallback;
|
|
370
237
|
}
|
|
371
238
|
}
|
|
372
239
|
}
|
|
373
|
-
|
|
374
|
-
* Adds a promise to the
|
|
375
|
-
* [extend lifetime promises](https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises)
|
|
376
|
-
* of the event event associated with the request being handled (usually a `FetchEvent`).
|
|
377
|
-
*
|
|
378
|
-
* Note: you can await
|
|
379
|
-
* `@serwist/strategies.StrategyHandler.doneWaiting`
|
|
380
|
-
* to know when all added promises have settled.
|
|
381
|
-
*
|
|
382
|
-
* @param promise A promise to add to the extend lifetime promises of
|
|
383
|
-
* the event that triggered the request.
|
|
384
|
-
*/ waitUntil(promise) {
|
|
240
|
+
waitUntil(promise) {
|
|
385
241
|
this._extendLifetimePromises.push(promise);
|
|
386
242
|
return promise;
|
|
387
243
|
}
|
|
388
|
-
|
|
389
|
-
* Returns a promise that resolves once all promises passed to
|
|
390
|
-
* `@serwist/strategies.StrategyHandler.waitUntil` have settled.
|
|
391
|
-
*
|
|
392
|
-
* Note: any work done after `doneWaiting()` settles should be manually
|
|
393
|
-
* passed to an event's `waitUntil()` method (not this handler's
|
|
394
|
-
* `waitUntil()` method), otherwise the service worker thread my be killed
|
|
395
|
-
* prior to your work completing.
|
|
396
|
-
*/ async doneWaiting() {
|
|
244
|
+
async doneWaiting() {
|
|
397
245
|
let promise = undefined;
|
|
398
246
|
while(promise = this._extendLifetimePromises.shift()){
|
|
399
247
|
await promise;
|
|
400
248
|
}
|
|
401
249
|
}
|
|
402
|
-
|
|
403
|
-
* Stops running the strategy and immediately resolves any pending
|
|
404
|
-
* `waitUntil()` promises.
|
|
405
|
-
*/ destroy() {
|
|
250
|
+
destroy() {
|
|
406
251
|
this._handlerDeferred.resolve(null);
|
|
407
252
|
}
|
|
408
|
-
|
|
409
|
-
* This method will call `cacheWillUpdate` on the available plugins (or use
|
|
410
|
-
* status === 200) to determine if the response is safe and valid to cache.
|
|
411
|
-
*
|
|
412
|
-
* @param response
|
|
413
|
-
* @returns
|
|
414
|
-
* @private
|
|
415
|
-
*/ async _ensureResponseSafeToCache(response) {
|
|
253
|
+
async _ensureResponseSafeToCache(response) {
|
|
416
254
|
let responseToCache = response;
|
|
417
255
|
let pluginsUsed = false;
|
|
418
256
|
for (const callback of this.iterateCallbacks("cacheWillUpdate")){
|
|
@@ -446,66 +284,22 @@ function toRequest(input) {
|
|
|
446
284
|
}
|
|
447
285
|
}
|
|
448
286
|
|
|
449
|
-
|
|
450
|
-
* Classes extending the `Strategy` based class should implement this method,
|
|
451
|
-
* and leverage `@serwist/strategies`'s `StrategyHandler` arg to perform all
|
|
452
|
-
* fetching and cache logic, which will ensure all relevant cache, cache options,
|
|
453
|
-
* fetch options and plugins are used (per the current strategy instance).
|
|
454
|
-
*/ class Strategy {
|
|
287
|
+
class Strategy {
|
|
455
288
|
cacheName;
|
|
456
289
|
plugins;
|
|
457
290
|
fetchOptions;
|
|
458
291
|
matchOptions;
|
|
459
|
-
|
|
460
|
-
* Creates a new instance of the strategy and sets all documented option
|
|
461
|
-
* properties as public instance properties.
|
|
462
|
-
*
|
|
463
|
-
* Note: if a custom strategy class extends the base Strategy class and does
|
|
464
|
-
* not need more than these properties, it does not need to define its own
|
|
465
|
-
* constructor.
|
|
466
|
-
*
|
|
467
|
-
* @param options
|
|
468
|
-
*/ constructor(options = {}){
|
|
292
|
+
constructor(options = {}){
|
|
469
293
|
this.cacheName = privateCacheNames.getRuntimeName(options.cacheName);
|
|
470
294
|
this.plugins = options.plugins || [];
|
|
471
295
|
this.fetchOptions = options.fetchOptions;
|
|
472
296
|
this.matchOptions = options.matchOptions;
|
|
473
297
|
}
|
|
474
|
-
|
|
475
|
-
* Perform a request strategy and returns a `Promise` that will resolve with
|
|
476
|
-
* a `Response`, invoking all relevant plugin callbacks.
|
|
477
|
-
*
|
|
478
|
-
* When a strategy instance is registered with a `@serwist/routing` Route, this method is automatically
|
|
479
|
-
* called when the route matches.
|
|
480
|
-
*
|
|
481
|
-
* Alternatively, this method can be used in a standalone `FetchEvent`
|
|
482
|
-
* listener by passing it to `event.respondWith()`.
|
|
483
|
-
*
|
|
484
|
-
* @param options A `FetchEvent` or an object with the properties listed below.
|
|
485
|
-
* @param options.request A request to run this strategy for.
|
|
486
|
-
* @param options.event The event associated with the request.
|
|
487
|
-
* @param options.url
|
|
488
|
-
* @param options.params
|
|
489
|
-
*/ handle(options) {
|
|
298
|
+
handle(options) {
|
|
490
299
|
const [responseDone] = this.handleAll(options);
|
|
491
300
|
return responseDone;
|
|
492
301
|
}
|
|
493
|
-
|
|
494
|
-
* Similar to `@serwist/strategies`'s `Strategy.handle`, but
|
|
495
|
-
* instead of just returning a `Promise` that resolves to a `Response` it
|
|
496
|
-
* it will return an tuple of `[response, done]` promises, where the former
|
|
497
|
-
* (`response`) is equivalent to what `handle()` returns, and the latter is a
|
|
498
|
-
* Promise that will resolve once any promises that were added to
|
|
499
|
-
* `event.waitUntil()` as part of performing the strategy have completed.
|
|
500
|
-
*
|
|
501
|
-
* You can await the `done` promise to ensure any extra work performed by
|
|
502
|
-
* the strategy (usually caching responses) completes successfully.
|
|
503
|
-
*
|
|
504
|
-
* @param options A `FetchEvent` or `HandlerCallbackOptions` object.
|
|
505
|
-
* @returns A tuple of [response, done] promises that can be used to determine when the response resolves as
|
|
506
|
-
* well as when the handler has completed all its work.
|
|
507
|
-
*/ handleAll(options) {
|
|
508
|
-
// Allow for flexible options to be passed.
|
|
302
|
+
handleAll(options) {
|
|
509
303
|
if (options instanceof FetchEvent) {
|
|
510
304
|
options = {
|
|
511
305
|
event: options,
|
|
@@ -522,7 +316,6 @@ function toRequest(input) {
|
|
|
522
316
|
});
|
|
523
317
|
const responseDone = this._getResponse(handler, request, event);
|
|
524
318
|
const handlerDone = this._awaitComplete(responseDone, handler, request, event);
|
|
525
|
-
// Return an array of promises, suitable for use with Promise.all().
|
|
526
319
|
return [
|
|
527
320
|
responseDone,
|
|
528
321
|
handlerDone
|
|
@@ -536,9 +329,6 @@ function toRequest(input) {
|
|
|
536
329
|
let response = undefined;
|
|
537
330
|
try {
|
|
538
331
|
response = await this._handle(request, handler);
|
|
539
|
-
// The "official" Strategy subclasses all throw this error automatically,
|
|
540
|
-
// but in case a third-party Strategy doesn't, ensure that we have a
|
|
541
|
-
// consistent failure when there's no response or an error response.
|
|
542
332
|
if (response === undefined || response.type === "error") {
|
|
543
333
|
throw new SerwistError("no-response", {
|
|
544
334
|
url: request.url
|
|
@@ -578,11 +368,7 @@ function toRequest(input) {
|
|
|
578
368
|
let error = undefined;
|
|
579
369
|
try {
|
|
580
370
|
response = await responseDone;
|
|
581
|
-
} catch (error) {
|
|
582
|
-
// Ignore errors, as response errors should be caught via the `response`
|
|
583
|
-
// promise above. The `done` promise will only throw for errors in
|
|
584
|
-
// promises passed to `handler.waitUntil()`.
|
|
585
|
-
}
|
|
371
|
+
} catch (error) {}
|
|
586
372
|
try {
|
|
587
373
|
await handler.runCallbacks("handlerDidRespond", {
|
|
588
374
|
event,
|
|
@@ -619,23 +405,8 @@ const messages = {
|
|
|
619
405
|
}
|
|
620
406
|
};
|
|
621
407
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
* request strategy.
|
|
625
|
-
*
|
|
626
|
-
* A cache first strategy is useful for assets that have been revisioned,
|
|
627
|
-
* such as URLs like `/styles/example.a8f5f1.css`, since they
|
|
628
|
-
* can be cached for long periods of time.
|
|
629
|
-
*
|
|
630
|
-
* If the network request fails, and there is no cache match, this will throw
|
|
631
|
-
* a `SerwistError` exception.
|
|
632
|
-
*/ class CacheFirst extends Strategy {
|
|
633
|
-
/**
|
|
634
|
-
* @private
|
|
635
|
-
* @param request A request to run this strategy for.
|
|
636
|
-
* @param handler The event that triggered the request.
|
|
637
|
-
* @returns
|
|
638
|
-
*/ async _handle(request, handler) {
|
|
408
|
+
class CacheFirst extends Strategy {
|
|
409
|
+
async _handle(request, handler) {
|
|
639
410
|
const logs = [];
|
|
640
411
|
if (process.env.NODE_ENV !== "production") {
|
|
641
412
|
assert.isInstance(request, Request, {
|
|
@@ -688,20 +459,8 @@ const messages = {
|
|
|
688
459
|
}
|
|
689
460
|
}
|
|
690
461
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
* request strategy.
|
|
694
|
-
*
|
|
695
|
-
* This class is useful if you want to take advantage of any Serwist plugin.
|
|
696
|
-
*
|
|
697
|
-
* If there is no cache match, this will throw a `SerwistError` exception.
|
|
698
|
-
*/ class CacheOnly extends Strategy {
|
|
699
|
-
/**
|
|
700
|
-
* @private
|
|
701
|
-
* @param request A request to run this strategy for.
|
|
702
|
-
* @param handler The event that triggered the request.
|
|
703
|
-
* @returns
|
|
704
|
-
*/ async _handle(request, handler) {
|
|
462
|
+
class CacheOnly extends Strategy {
|
|
463
|
+
async _handle(request, handler) {
|
|
705
464
|
if (process.env.NODE_ENV !== "production") {
|
|
706
465
|
assert.isInstance(request, Request, {
|
|
707
466
|
moduleName: "@serwist/strategies",
|
|
@@ -730,21 +489,8 @@ const messages = {
|
|
|
730
489
|
}
|
|
731
490
|
}
|
|
732
491
|
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
Use of this source code is governed by an MIT-style
|
|
737
|
-
license that can be found in the LICENSE file or at
|
|
738
|
-
https://opensource.org/licenses/MIT.
|
|
739
|
-
*/ const cacheOkAndOpaquePlugin = {
|
|
740
|
-
/**
|
|
741
|
-
* Returns a valid response (to allow caching) if the status is 200 (OK) or
|
|
742
|
-
* 0 (opaque).
|
|
743
|
-
*
|
|
744
|
-
* @param options
|
|
745
|
-
* @returns
|
|
746
|
-
* @private
|
|
747
|
-
*/ cacheWillUpdate: async ({ response })=>{
|
|
492
|
+
const cacheOkAndOpaquePlugin = {
|
|
493
|
+
cacheWillUpdate: async ({ response })=>{
|
|
748
494
|
if (response.status === 200 || response.status === 0) {
|
|
749
495
|
return response;
|
|
750
496
|
}
|
|
@@ -752,28 +498,10 @@ const messages = {
|
|
|
752
498
|
}
|
|
753
499
|
};
|
|
754
500
|
|
|
755
|
-
|
|
756
|
-
* An implementation of a [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache)
|
|
757
|
-
* request strategy.
|
|
758
|
-
*
|
|
759
|
-
* By default, this strategy will cache responses with a 200 status code as
|
|
760
|
-
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
761
|
-
* Opaque responses are are cross-origin requests where the response doesn't
|
|
762
|
-
* support [CORS](https://enable-cors.org/).
|
|
763
|
-
*
|
|
764
|
-
* If the network request fails, and there is no cache match, this will throw
|
|
765
|
-
* a `SerwistError` exception.
|
|
766
|
-
*/ class NetworkFirst extends Strategy {
|
|
501
|
+
class NetworkFirst extends Strategy {
|
|
767
502
|
_networkTimeoutSeconds;
|
|
768
|
-
|
|
769
|
-
* @param options
|
|
770
|
-
* This option can be used to combat
|
|
771
|
-
* "[lie-fi](https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi)"
|
|
772
|
-
* scenarios.
|
|
773
|
-
*/ constructor(options = {}){
|
|
503
|
+
constructor(options = {}){
|
|
774
504
|
super(options);
|
|
775
|
-
// If this instance contains no plugins with a 'cacheWillUpdate' callback,
|
|
776
|
-
// prepend the `cacheOkAndOpaquePlugin` plugin to the plugins list.
|
|
777
505
|
if (!this.plugins.some((p)=>"cacheWillUpdate" in p)) {
|
|
778
506
|
this.plugins.unshift(cacheOkAndOpaquePlugin);
|
|
779
507
|
}
|
|
@@ -789,12 +517,7 @@ const messages = {
|
|
|
789
517
|
}
|
|
790
518
|
}
|
|
791
519
|
}
|
|
792
|
-
|
|
793
|
-
* @private
|
|
794
|
-
* @param request A request to run this strategy for.
|
|
795
|
-
* @param handler The event that triggered the request.
|
|
796
|
-
* @returns
|
|
797
|
-
*/ async _handle(request, handler) {
|
|
520
|
+
async _handle(request, handler) {
|
|
798
521
|
const logs = [];
|
|
799
522
|
if (process.env.NODE_ENV !== "production") {
|
|
800
523
|
assert.isInstance(request, Request, {
|
|
@@ -823,13 +546,7 @@ const messages = {
|
|
|
823
546
|
});
|
|
824
547
|
promises.push(networkPromise);
|
|
825
548
|
const response = await handler.waitUntil((async ()=>{
|
|
826
|
-
|
|
827
|
-
return await handler.waitUntil(Promise.race(promises)) || // If Promise.race() resolved with null, it might be due to a network
|
|
828
|
-
// timeout + a cache miss. If that were to happen, we'd rather wait until
|
|
829
|
-
// the networkPromise resolves instead of returning null.
|
|
830
|
-
// Note that it's fine to await an already-resolved promise, so we don't
|
|
831
|
-
// have to check to see if it's still "in flight".
|
|
832
|
-
await networkPromise;
|
|
549
|
+
return await handler.waitUntil(Promise.race(promises)) || await networkPromise;
|
|
833
550
|
})());
|
|
834
551
|
if (process.env.NODE_ENV !== "production") {
|
|
835
552
|
logger.groupCollapsed(messages.strategyStart(this.constructor.name, request));
|
|
@@ -846,12 +563,7 @@ const messages = {
|
|
|
846
563
|
}
|
|
847
564
|
return response;
|
|
848
565
|
}
|
|
849
|
-
|
|
850
|
-
* @param options
|
|
851
|
-
* @returns
|
|
852
|
-
* @private
|
|
853
|
-
*/ _getTimeoutPromise({ request, logs, handler }) {
|
|
854
|
-
// biome-ignore lint/suspicious/noImplicitAnyLet: setTimeout is typed with Node.js's typings, so we can't use number | undefined here.
|
|
566
|
+
_getTimeoutPromise({ request, logs, handler }) {
|
|
855
567
|
let timeoutId;
|
|
856
568
|
const timeoutPromise = new Promise((resolve)=>{
|
|
857
569
|
const onNetworkTimeout = async ()=>{
|
|
@@ -867,16 +579,7 @@ const messages = {
|
|
|
867
579
|
id: timeoutId
|
|
868
580
|
};
|
|
869
581
|
}
|
|
870
|
-
|
|
871
|
-
* @param options
|
|
872
|
-
* @param options.timeoutId
|
|
873
|
-
* @param options.request
|
|
874
|
-
* @param options.logs A reference to the logs Array.
|
|
875
|
-
* @param options.event
|
|
876
|
-
* @returns
|
|
877
|
-
*
|
|
878
|
-
* @private
|
|
879
|
-
*/ async _getNetworkPromise({ timeoutId, request, logs, handler }) {
|
|
582
|
+
async _getNetworkPromise({ timeoutId, request, logs, handler }) {
|
|
880
583
|
let error = undefined;
|
|
881
584
|
let response = undefined;
|
|
882
585
|
try {
|
|
@@ -910,27 +613,13 @@ const messages = {
|
|
|
910
613
|
}
|
|
911
614
|
}
|
|
912
615
|
|
|
913
|
-
|
|
914
|
-
* An implementation of a [network only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-only)
|
|
915
|
-
* request strategy.
|
|
916
|
-
*
|
|
917
|
-
* This class is useful if you want to take advantage of any Serwist plugin.
|
|
918
|
-
*
|
|
919
|
-
* If the network request fails, this will throw a `SerwistError` exception.
|
|
920
|
-
*/ class NetworkOnly extends Strategy {
|
|
616
|
+
class NetworkOnly extends Strategy {
|
|
921
617
|
_networkTimeoutSeconds;
|
|
922
|
-
|
|
923
|
-
* @param options
|
|
924
|
-
*/ constructor(options = {}){
|
|
618
|
+
constructor(options = {}){
|
|
925
619
|
super(options);
|
|
926
620
|
this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0;
|
|
927
621
|
}
|
|
928
|
-
|
|
929
|
-
* @private
|
|
930
|
-
* @param request A request to run this strategy for.
|
|
931
|
-
* @param handler The event that triggered the request.
|
|
932
|
-
* @returns
|
|
933
|
-
*/ async _handle(request, handler) {
|
|
622
|
+
async _handle(request, handler) {
|
|
934
623
|
if (process.env.NODE_ENV !== "production") {
|
|
935
624
|
assert.isInstance(request, Request, {
|
|
936
625
|
moduleName: "@serwist/strategies",
|
|
@@ -978,40 +667,14 @@ const messages = {
|
|
|
978
667
|
}
|
|
979
668
|
}
|
|
980
669
|
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
* [stale-while-revalidate](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#stale-while-revalidate)
|
|
984
|
-
* request strategy.
|
|
985
|
-
*
|
|
986
|
-
* Resources are requested from both the cache and the network in parallel.
|
|
987
|
-
* The strategy will respond with the cached version if available, otherwise
|
|
988
|
-
* wait for the network response. The cache is updated with the network response
|
|
989
|
-
* with each successful request.
|
|
990
|
-
*
|
|
991
|
-
* By default, this strategy will cache responses with a 200 status code as
|
|
992
|
-
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
993
|
-
* Opaque responses are cross-origin requests where the response doesn't
|
|
994
|
-
* support [CORS](https://enable-cors.org/).
|
|
995
|
-
*
|
|
996
|
-
* If the network request fails, and there is no cache match, this will throw
|
|
997
|
-
* a `SerwistError` exception.
|
|
998
|
-
*/ class StaleWhileRevalidate extends Strategy {
|
|
999
|
-
/**
|
|
1000
|
-
* @param options
|
|
1001
|
-
*/ constructor(options = {}){
|
|
670
|
+
class StaleWhileRevalidate extends Strategy {
|
|
671
|
+
constructor(options = {}){
|
|
1002
672
|
super(options);
|
|
1003
|
-
// If this instance contains no plugins with a 'cacheWillUpdate' callback,
|
|
1004
|
-
// prepend the `cacheOkAndOpaquePlugin` plugin to the plugins list.
|
|
1005
673
|
if (!this.plugins.some((p)=>"cacheWillUpdate" in p)) {
|
|
1006
674
|
this.plugins.unshift(cacheOkAndOpaquePlugin);
|
|
1007
675
|
}
|
|
1008
676
|
}
|
|
1009
|
-
|
|
1010
|
-
* @private
|
|
1011
|
-
* @param request A request to run this strategy for.
|
|
1012
|
-
* @param handler The event that triggered the request.
|
|
1013
|
-
* @returns
|
|
1014
|
-
*/ async _handle(request, handler) {
|
|
677
|
+
async _handle(request, handler) {
|
|
1015
678
|
const logs = [];
|
|
1016
679
|
if (process.env.NODE_ENV !== "production") {
|
|
1017
680
|
assert.isInstance(request, Request, {
|
|
@@ -1021,10 +684,7 @@ const messages = {
|
|
|
1021
684
|
paramName: "request"
|
|
1022
685
|
});
|
|
1023
686
|
}
|
|
1024
|
-
const fetchAndCachePromise = handler.fetchAndCachePut(request).catch(()=>{
|
|
1025
|
-
// Swallow this error because a 'no-response' error will be thrown in
|
|
1026
|
-
// main handler return flow. This will be in the `waitUntil()` flow.
|
|
1027
|
-
});
|
|
687
|
+
const fetchAndCachePromise = handler.fetchAndCachePut(request).catch(()=>{});
|
|
1028
688
|
void handler.waitUntil(fetchAndCachePromise);
|
|
1029
689
|
let response = await handler.cacheMatch(request);
|
|
1030
690
|
let error = undefined;
|
|
@@ -1037,8 +697,6 @@ const messages = {
|
|
|
1037
697
|
logs.push(`No response found in the '${this.cacheName}' cache. Will wait for the network response.`);
|
|
1038
698
|
}
|
|
1039
699
|
try {
|
|
1040
|
-
// NOTE(philipwalton): Really annoying that we have to type cast here.
|
|
1041
|
-
// https://github.com/microsoft/TypeScript/issues/20006
|
|
1042
700
|
response = await fetchAndCachePromise;
|
|
1043
701
|
} catch (err) {
|
|
1044
702
|
if (err instanceof Error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serwist/strategies",
|
|
3
|
-
"version": "9.0.0-preview.
|
|
3
|
+
"version": "9.0.0-preview.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A service worker helper library implementing common caching strategies.",
|
|
6
6
|
"files": [
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"./package.json": "./package.json"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@serwist/core": "9.0.0-preview.
|
|
33
|
+
"@serwist/core": "9.0.0-preview.10"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"rollup": "4.9.6",
|
|
37
|
-
"typescript": "5.4.0-dev.
|
|
38
|
-
"@serwist/constants": "9.0.0-preview.
|
|
37
|
+
"typescript": "5.4.0-dev.20240206",
|
|
38
|
+
"@serwist/constants": "9.0.0-preview.10"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"typescript": ">=5.0.0"
|
package/src/CacheFirst.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type { StrategyHandler } from "./StrategyHandler.js";
|
|
|
13
13
|
import { messages } from "./utils/messages.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* An implementation of
|
|
16
|
+
* An implementation of the [cache first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#cache-first-falling-back-to-network)
|
|
17
17
|
* request strategy.
|
|
18
18
|
*
|
|
19
19
|
* A cache first strategy is useful for assets that have been revisioned,
|
|
@@ -23,7 +23,7 @@ import { messages } from "./utils/messages.js";
|
|
|
23
23
|
* If the network request fails, and there is no cache match, this will throw
|
|
24
24
|
* a `SerwistError` exception.
|
|
25
25
|
*/
|
|
26
|
-
class CacheFirst extends Strategy {
|
|
26
|
+
export class CacheFirst extends Strategy {
|
|
27
27
|
/**
|
|
28
28
|
* @private
|
|
29
29
|
* @param request A request to run this strategy for.
|
|
@@ -85,5 +85,3 @@ class CacheFirst extends Strategy {
|
|
|
85
85
|
return response;
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
export { CacheFirst };
|
package/src/CacheOnly.ts
CHANGED
|
@@ -13,14 +13,14 @@ import type { StrategyHandler } from "./StrategyHandler.js";
|
|
|
13
13
|
import { messages } from "./utils/messages.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* An implementation of
|
|
16
|
+
* An implementation of the [cache only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#cache-only)
|
|
17
17
|
* request strategy.
|
|
18
18
|
*
|
|
19
19
|
* This class is useful if you want to take advantage of any Serwist plugin.
|
|
20
20
|
*
|
|
21
21
|
* If there is no cache match, this will throw a `SerwistError` exception.
|
|
22
22
|
*/
|
|
23
|
-
class CacheOnly extends Strategy {
|
|
23
|
+
export class CacheOnly extends Strategy {
|
|
24
24
|
/**
|
|
25
25
|
* @private
|
|
26
26
|
* @param request A request to run this strategy for.
|
|
@@ -56,5 +56,3 @@ class CacheOnly extends Strategy {
|
|
|
56
56
|
return response;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
|
|
60
|
-
export { CacheOnly };
|
package/src/NetworkFirst.ts
CHANGED
|
@@ -21,22 +21,21 @@ export interface NetworkFirstOptions extends StrategyOptions {
|
|
|
21
21
|
networkTimeoutSeconds?: number;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
* An implementation of a [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache)
|
|
26
|
-
* request strategy.
|
|
27
|
-
*
|
|
28
|
-
* By default, this strategy will cache responses with a 200 status code as
|
|
29
|
-
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
30
|
-
* Opaque responses are are cross-origin requests where the response doesn't
|
|
31
|
-
* support [CORS](https://enable-cors.org/).
|
|
32
|
-
*
|
|
33
|
-
* If the network request fails, and there is no cache match, this will throw
|
|
34
|
-
* a `SerwistError` exception.
|
|
35
|
-
*/
|
|
36
|
-
class NetworkFirst extends Strategy {
|
|
24
|
+
export class NetworkFirst extends Strategy {
|
|
37
25
|
private readonly _networkTimeoutSeconds: number;
|
|
38
26
|
|
|
39
27
|
/**
|
|
28
|
+
* An implementation of the [network first](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-first-falling-back-to-cache)
|
|
29
|
+
* request strategy.
|
|
30
|
+
*
|
|
31
|
+
* By default, this strategy will cache responses with a 200 status code as
|
|
32
|
+
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
33
|
+
* Opaque responses are are cross-origin requests where the response doesn't
|
|
34
|
+
* support [CORS](https://enable-cors.org/).
|
|
35
|
+
*
|
|
36
|
+
* If the network request fails, and there is no cache match, this will throw
|
|
37
|
+
* a `SerwistError` exception.
|
|
38
|
+
*
|
|
40
39
|
* @param options
|
|
41
40
|
* This option can be used to combat
|
|
42
41
|
* "[lie-fi](https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi)"
|
|
@@ -227,5 +226,3 @@ class NetworkFirst extends Strategy {
|
|
|
227
226
|
return response;
|
|
228
227
|
}
|
|
229
228
|
}
|
|
230
|
-
|
|
231
|
-
export { NetworkFirst };
|
package/src/NetworkOnly.ts
CHANGED
|
@@ -13,25 +13,24 @@ import { Strategy } from "./Strategy.js";
|
|
|
13
13
|
import type { StrategyHandler } from "./StrategyHandler.js";
|
|
14
14
|
import { messages } from "./utils/messages.js";
|
|
15
15
|
|
|
16
|
-
interface NetworkOnlyOptions extends Omit<StrategyOptions, "cacheName" | "matchOptions"> {
|
|
16
|
+
export interface NetworkOnlyOptions extends Omit<StrategyOptions, "cacheName" | "matchOptions"> {
|
|
17
17
|
/**
|
|
18
18
|
* If set, any network requests that fail to respond within the timeout will result in a network error.
|
|
19
19
|
*/
|
|
20
20
|
networkTimeoutSeconds?: number;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
* An implementation of a [network only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-only)
|
|
25
|
-
* request strategy.
|
|
26
|
-
*
|
|
27
|
-
* This class is useful if you want to take advantage of any Serwist plugin.
|
|
28
|
-
*
|
|
29
|
-
* If the network request fails, this will throw a `SerwistError` exception.
|
|
30
|
-
*/
|
|
31
|
-
class NetworkOnly extends Strategy {
|
|
23
|
+
export class NetworkOnly extends Strategy {
|
|
32
24
|
private readonly _networkTimeoutSeconds: number;
|
|
33
25
|
|
|
34
26
|
/**
|
|
27
|
+
* An implementation of the [network only](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#network-only)
|
|
28
|
+
* request strategy.
|
|
29
|
+
*
|
|
30
|
+
* This class is useful if you want to take advantage of any Serwist plugin.
|
|
31
|
+
*
|
|
32
|
+
* If the network request fails, this will throw a `SerwistError` exception.
|
|
33
|
+
*
|
|
35
34
|
* @param options
|
|
36
35
|
*/
|
|
37
36
|
constructor(options: NetworkOnlyOptions = {}) {
|
|
@@ -94,6 +93,3 @@ class NetworkOnly extends Strategy {
|
|
|
94
93
|
return response;
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
|
-
|
|
98
|
-
export { NetworkOnly };
|
|
99
|
-
export type { NetworkOnlyOptions };
|
|
@@ -14,26 +14,25 @@ import type { StrategyHandler } from "./StrategyHandler.js";
|
|
|
14
14
|
import { cacheOkAndOpaquePlugin } from "./plugins/cacheOkAndOpaquePlugin.js";
|
|
15
15
|
import { messages } from "./utils/messages.js";
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
* An implementation of a
|
|
19
|
-
* [stale-while-revalidate](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#stale-while-revalidate)
|
|
20
|
-
* request strategy.
|
|
21
|
-
*
|
|
22
|
-
* Resources are requested from both the cache and the network in parallel.
|
|
23
|
-
* The strategy will respond with the cached version if available, otherwise
|
|
24
|
-
* wait for the network response. The cache is updated with the network response
|
|
25
|
-
* with each successful request.
|
|
26
|
-
*
|
|
27
|
-
* By default, this strategy will cache responses with a 200 status code as
|
|
28
|
-
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
29
|
-
* Opaque responses are cross-origin requests where the response doesn't
|
|
30
|
-
* support [CORS](https://enable-cors.org/).
|
|
31
|
-
*
|
|
32
|
-
* If the network request fails, and there is no cache match, this will throw
|
|
33
|
-
* a `SerwistError` exception.
|
|
34
|
-
*/
|
|
35
|
-
class StaleWhileRevalidate extends Strategy {
|
|
17
|
+
export class StaleWhileRevalidate extends Strategy {
|
|
36
18
|
/**
|
|
19
|
+
* An implementation of the
|
|
20
|
+
* [stale-while-revalidate](https://developer.chrome.com/docs/workbox/caching-strategies-overview/#stale-while-revalidate)
|
|
21
|
+
* request strategy.
|
|
22
|
+
*
|
|
23
|
+
* Resources are requested from both the cache and the network in parallel.
|
|
24
|
+
* The strategy will respond with the cached version if available, otherwise
|
|
25
|
+
* wait for the network response. The cache is updated with the network response
|
|
26
|
+
* with each successful request.
|
|
27
|
+
*
|
|
28
|
+
* By default, this strategy will cache responses with a 200 status code as
|
|
29
|
+
* well as [opaque responses](https://developer.chrome.com/docs/workbox/caching-resources-during-runtime/#opaque-responses).
|
|
30
|
+
* Opaque responses are cross-origin requests where the response doesn't
|
|
31
|
+
* support [CORS](https://enable-cors.org/).
|
|
32
|
+
*
|
|
33
|
+
* If the network request fails, and there is no cache match, this will throw
|
|
34
|
+
* a `SerwistError` exception.
|
|
35
|
+
*
|
|
37
36
|
* @param options
|
|
38
37
|
*/
|
|
39
38
|
constructor(options: StrategyOptions = {}) {
|
|
@@ -107,5 +106,3 @@ class StaleWhileRevalidate extends Strategy {
|
|
|
107
106
|
return response;
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
|
-
|
|
111
|
-
export { StaleWhileRevalidate };
|
package/src/Strategy.ts
CHANGED
|
@@ -39,7 +39,7 @@ export interface StrategyOptions {
|
|
|
39
39
|
* fetching and cache logic, which will ensure all relevant cache, cache options,
|
|
40
40
|
* fetch options and plugins are used (per the current strategy instance).
|
|
41
41
|
*/
|
|
42
|
-
abstract class Strategy implements RouteHandlerObject {
|
|
42
|
+
export abstract class Strategy implements RouteHandlerObject {
|
|
43
43
|
cacheName: string;
|
|
44
44
|
plugins: SerwistPlugin[];
|
|
45
45
|
fetchOptions?: RequestInit;
|
|
@@ -201,5 +201,3 @@ abstract class Strategy implements RouteHandlerObject {
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
-
|
|
205
|
-
export { Strategy };
|
package/src/StrategyHandler.ts
CHANGED
|
@@ -30,7 +30,7 @@ function toRequest(input: RequestInfo) {
|
|
|
30
30
|
* and keeps track of when the strategy is "done" (i.e. all added `event.waitUntil()` promises
|
|
31
31
|
* have resolved).
|
|
32
32
|
*/
|
|
33
|
-
class StrategyHandler {
|
|
33
|
+
export class StrategyHandler {
|
|
34
34
|
/**
|
|
35
35
|
* The request the strategy is performing (passed to the strategy's
|
|
36
36
|
* `handle()` or `handleAll()` method).
|
|
@@ -281,16 +281,6 @@ class StrategyHandler {
|
|
|
281
281
|
method: effectiveRequest.method,
|
|
282
282
|
});
|
|
283
283
|
}
|
|
284
|
-
|
|
285
|
-
// See https://github.com/GoogleChrome/workbox/issues/2818
|
|
286
|
-
const vary = response.headers.get("Vary");
|
|
287
|
-
if (vary) {
|
|
288
|
-
logger.debug(
|
|
289
|
-
`The response for ${getFriendlyURL(
|
|
290
|
-
effectiveRequest.url,
|
|
291
|
-
)} has a 'Vary: ${vary}' header. Consider setting the {ignoreVary: true} option on your strategy to ensure cache matching and deletion works as expected.`,
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
284
|
}
|
|
295
285
|
|
|
296
286
|
if (!response) {
|
|
@@ -315,6 +305,18 @@ class StrategyHandler {
|
|
|
315
305
|
const { cacheName, matchOptions } = this._strategy;
|
|
316
306
|
const cache = await self.caches.open(cacheName);
|
|
317
307
|
|
|
308
|
+
if (process.env.NODE_ENV !== "production") {
|
|
309
|
+
// See https://github.com/GoogleChrome/workbox/issues/2818
|
|
310
|
+
const vary = response.headers.get("Vary");
|
|
311
|
+
if (vary && matchOptions?.ignoreVary !== true) {
|
|
312
|
+
logger.debug(
|
|
313
|
+
`The response for ${getFriendlyURL(
|
|
314
|
+
effectiveRequest.url,
|
|
315
|
+
)} has a 'Vary: ${vary}' header. Consider setting the {ignoreVary: true} option on your strategy to ensure cache matching and deletion works as expected.`,
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
318
320
|
const hasCacheUpdateCallback = this.hasCallback("cacheDidUpdate");
|
|
319
321
|
const oldResponse = hasCacheUpdateCallback
|
|
320
322
|
? await cacheMatchIgnoreParams(
|
|
@@ -329,7 +331,7 @@ class StrategyHandler {
|
|
|
329
331
|
: null;
|
|
330
332
|
|
|
331
333
|
if (process.env.NODE_ENV !== "production") {
|
|
332
|
-
logger.debug(`Updating the '${cacheName}' cache with a new Response
|
|
334
|
+
logger.debug(`Updating the '${cacheName}' cache with a new Response for ${getFriendlyURL(effectiveRequest.url)}.`);
|
|
333
335
|
}
|
|
334
336
|
|
|
335
337
|
try {
|
|
@@ -379,8 +381,7 @@ class StrategyHandler {
|
|
|
379
381
|
mode,
|
|
380
382
|
request: effectiveRequest,
|
|
381
383
|
event: this.event,
|
|
382
|
-
|
|
383
|
-
params: this.params, // eslint-disable-line
|
|
384
|
+
params: this.params,
|
|
384
385
|
}),
|
|
385
386
|
);
|
|
386
387
|
}
|
|
@@ -541,5 +542,3 @@ class StrategyHandler {
|
|
|
541
542
|
return responseToCache;
|
|
542
543
|
}
|
|
543
544
|
}
|
|
544
|
-
|
|
545
|
-
export { StrategyHandler };
|