@serwist/sw 9.0.0-preview.19 → 9.0.0-preview.20
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/abstractions/Serwist.d.ts +5 -7
- package/dist/abstractions/Serwist.d.ts.map +1 -1
- package/dist/chunks/NavigationRoute.js +1 -1
- package/dist/chunks/PrecacheFallbackPlugin.js +9 -9
- package/dist/chunks/precacheAndRoute.js +6 -5
- package/dist/chunks/registerRoute.js +3 -404
- package/dist/chunks/{getOrCreatePrecacheController.js → singletonPrecacheController.js} +10 -6
- package/dist/chunks/singletonRouter.js +435 -0
- package/dist/index.js +8 -7
- package/dist/index.plugins.js +2 -2
- package/dist/index.precaching.d.ts +2 -1
- package/dist/index.precaching.d.ts.map +1 -1
- package/dist/index.precaching.js +7 -7
- package/dist/index.routing.d.ts +3 -1
- package/dist/index.routing.d.ts.map +1 -1
- package/dist/index.routing.js +7 -9
- package/dist/plugins/googleAnalytics/initialize.d.ts +9 -1
- package/dist/plugins/googleAnalytics/initialize.d.ts.map +1 -1
- package/dist/precaching/addRoute.d.ts.map +1 -1
- package/dist/precaching/matchPrecache.d.ts.map +1 -1
- package/dist/precaching/precache.d.ts.map +1 -1
- package/dist/precaching/singletonPrecacheController.d.ts +38 -0
- package/dist/precaching/singletonPrecacheController.d.ts.map +1 -0
- package/dist/precaching/utils/getCacheKeyForURL.d.ts.map +1 -1
- package/dist/routing/RegExpRoute.d.ts +3 -3
- package/dist/routing/Router.d.ts +49 -23
- package/dist/routing/Router.d.ts.map +1 -1
- package/dist/routing/parseRoute.d.ts +16 -0
- package/dist/routing/parseRoute.d.ts.map +1 -0
- package/dist/routing/registerRoute.d.ts +5 -5
- package/dist/routing/registerRoute.d.ts.map +1 -1
- package/dist/routing/setCatchHandler.d.ts +1 -1
- package/dist/routing/setCatchHandler.d.ts.map +1 -1
- package/dist/routing/setDefaultHandler.d.ts +1 -1
- package/dist/routing/setDefaultHandler.d.ts.map +1 -1
- package/dist/routing/singletonRouter.d.ts +47 -0
- package/dist/routing/singletonRouter.d.ts.map +1 -0
- package/dist/routing/unregisterRoute.d.ts +1 -1
- package/dist/routing/unregisterRoute.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/abstractions/Serwist.ts +10 -12
- package/src/abstractions/installSerwist.ts +4 -4
- package/src/index.precaching.ts +3 -0
- package/src/index.routing.ts +15 -1
- package/src/plugins/googleAnalytics/initialize.ts +19 -6
- package/src/plugins/precaching/PrecacheFallbackPlugin.ts +2 -2
- package/src/precaching/addPlugins.ts +2 -2
- package/src/precaching/addRoute.ts +2 -2
- package/src/precaching/createHandlerBoundToURL.ts +2 -2
- package/src/precaching/getCacheKeyForURL.ts +2 -2
- package/src/precaching/matchPrecache.ts +2 -3
- package/src/precaching/precache.ts +2 -2
- package/src/precaching/singletonPrecacheController.ts +57 -0
- package/src/precaching/utils/getCacheKeyForURL.ts +2 -2
- package/src/routing/RegExpRoute.ts +3 -3
- package/src/routing/Router.ts +101 -52
- package/src/routing/{utils/parseRoute.ts → parseRoute.ts} +14 -3
- package/src/routing/registerRoute.ts +7 -13
- package/src/routing/setCatchHandler.ts +3 -4
- package/src/routing/setDefaultHandler.ts +3 -4
- package/src/routing/singletonRouter.ts +76 -0
- package/src/routing/unregisterRoute.ts +3 -4
- package/dist/precaching/utils/getOrCreatePrecacheController.d.ts +0 -7
- package/dist/precaching/utils/getOrCreatePrecacheController.d.ts.map +0 -1
- package/dist/routing/utils/getOrCreateDefaultRouter.d.ts +0 -10
- package/dist/routing/utils/getOrCreateDefaultRouter.d.ts.map +0 -1
- package/dist/routing/utils/parseRoute.d.ts +0 -5
- package/dist/routing/utils/parseRoute.d.ts.map +0 -1
- package/src/precaching/utils/getOrCreatePrecacheController.ts +0 -22
- package/src/routing/utils/getOrCreateDefaultRouter.ts +0 -29
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import type { RouteHandlerCallback } from "@serwist/core";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { getSingletonPrecacheController } from "./singletonPrecacheController.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Helper function that calls `PrecacheController#createHandlerBoundToURL`
|
|
@@ -25,6 +25,6 @@ import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheContro
|
|
|
25
25
|
* @return
|
|
26
26
|
*/
|
|
27
27
|
export const createHandlerBoundToURL = (url: string): RouteHandlerCallback => {
|
|
28
|
-
const precacheController =
|
|
28
|
+
const precacheController = getSingletonPrecacheController();
|
|
29
29
|
return precacheController.createHandlerBoundToURL(url);
|
|
30
30
|
};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
https://opensource.org/licenses/MIT.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { getSingletonPrecacheController } from "./singletonPrecacheController.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Takes in a URL, and returns the corresponding URL that could be used to
|
|
@@ -26,7 +26,7 @@ import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheContro
|
|
|
26
26
|
* @returns The cache key that corresponds to that URL.
|
|
27
27
|
*/
|
|
28
28
|
function getCacheKeyForURL(url: string): string | undefined {
|
|
29
|
-
const precacheController =
|
|
29
|
+
const precacheController = getSingletonPrecacheController();
|
|
30
30
|
return precacheController.getCacheKeyForURL(url);
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
https://opensource.org/licenses/MIT.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { getSingletonPrecacheController } from "./singletonPrecacheController.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Helper function that calls `PrecacheController#matchPrecache`
|
|
@@ -21,6 +21,5 @@ import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheContro
|
|
|
21
21
|
* @returns
|
|
22
22
|
*/
|
|
23
23
|
export const matchPrecache = (request: string | Request): Promise<Response | undefined> => {
|
|
24
|
-
|
|
25
|
-
return precacheController.matchPrecache(request);
|
|
24
|
+
return getSingletonPrecacheController().matchPrecache(request);
|
|
26
25
|
};
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
https://opensource.org/licenses/MIT.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { getSingletonPrecacheController } from "./singletonPrecacheController.js";
|
|
9
10
|
import type { PrecacheEntry } from "./types.js";
|
|
10
|
-
import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheController.js";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Adds items to the precache list, removing any duplicates and
|
|
@@ -26,6 +26,6 @@ import { getOrCreatePrecacheController } from "./utils/getOrCreatePrecacheContro
|
|
|
26
26
|
* @param entries Array of entries to precache.
|
|
27
27
|
*/
|
|
28
28
|
export const precache = (entries: (PrecacheEntry | string)[]): void => {
|
|
29
|
-
const precacheController =
|
|
29
|
+
const precacheController = getSingletonPrecacheController();
|
|
30
30
|
precacheController.precache(entries);
|
|
31
31
|
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2019 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { PrecacheController } from "./PrecacheController.js";
|
|
10
|
+
|
|
11
|
+
let defaultPrecacheController: PrecacheController | undefined = undefined;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new, singleton `PrecacheController` if one does not exist. If one does
|
|
15
|
+
* already exist, that instance is returned. This instance is used by Serwist's
|
|
16
|
+
* `PrecacheController`-dependent functions and classes unless you provide a different
|
|
17
|
+
* `Router` to them.
|
|
18
|
+
*
|
|
19
|
+
* @returns The singleton `PrecacheController`.
|
|
20
|
+
*/
|
|
21
|
+
export const getSingletonPrecacheController = (): PrecacheController => {
|
|
22
|
+
if (!defaultPrecacheController) {
|
|
23
|
+
defaultPrecacheController = new PrecacheController();
|
|
24
|
+
}
|
|
25
|
+
return defaultPrecacheController;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Changes the singleton `PrecacheController` to a different instance. This is meant for when you do not
|
|
30
|
+
* want to pass your own `PrecacheController` to every one of Serwist's `PrecacheController`-dependent
|
|
31
|
+
* functions and classes.
|
|
32
|
+
*
|
|
33
|
+
* It is highly recommended that you call this before anything else, if you plan on doing so.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```js
|
|
37
|
+
* import { PrecacheController, setSingletonPrecacheController } from "@serwist/sw/precaching";
|
|
38
|
+
*
|
|
39
|
+
* const controller = new PrecacheController();
|
|
40
|
+
*
|
|
41
|
+
* setSingletonPrecacheController(controller);
|
|
42
|
+
*
|
|
43
|
+
* // Do something with your controller...
|
|
44
|
+
*
|
|
45
|
+
* // This class now automatically picks up your `PrecacheController`! Without `setSingletonPrecacheController`,
|
|
46
|
+
* // you'd need to write this instead: `new Serwist({ controller })`
|
|
47
|
+
* const serwist = new Serwist();
|
|
48
|
+
*
|
|
49
|
+
* serwist.install();
|
|
50
|
+
* ```
|
|
51
|
+
* @param router
|
|
52
|
+
* @returns The new singleton `PrecacheController`.
|
|
53
|
+
*/
|
|
54
|
+
export const setSingletonPrecacheController = (precacheController: PrecacheController): PrecacheController => {
|
|
55
|
+
defaultPrecacheController = precacheController;
|
|
56
|
+
return defaultPrecacheController;
|
|
57
|
+
};
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
https://opensource.org/licenses/MIT.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { getSingletonPrecacheController } from "../singletonPrecacheController.js";
|
|
9
10
|
import type { PrecacheRouteOptions } from "../types.js";
|
|
10
11
|
import { generateURLVariations } from "./generateURLVariations.js";
|
|
11
|
-
import { getOrCreatePrecacheController } from "./getOrCreatePrecacheController.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* This function will take the request URL and manipulate it based on the
|
|
@@ -22,7 +22,7 @@ import { getOrCreatePrecacheController } from "./getOrCreatePrecacheController.j
|
|
|
22
22
|
* @private
|
|
23
23
|
*/
|
|
24
24
|
export const getCacheKeyForURL = (url: string, options: PrecacheRouteOptions): string | undefined => {
|
|
25
|
-
const precacheController =
|
|
25
|
+
const precacheController = getSingletonPrecacheController();
|
|
26
26
|
|
|
27
27
|
const urlsToCacheKeys = precacheController.getURLsToCacheKeys();
|
|
28
28
|
for (const possibleURL of generateURLVariations(url, options)) {
|
|
@@ -13,10 +13,10 @@ import { Route } from "./Route.js";
|
|
|
13
13
|
import type { HTTPMethod } from "./utils/constants.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* RegExpRoute makes it easy to create a regular expression based on a `@serwist/routing` Route.
|
|
16
|
+
* `RegExpRoute` makes it easy to create a regular expression based on a `@serwist/routing` Route.
|
|
17
17
|
*
|
|
18
|
-
* For same-origin requests the RegExp only needs to match part of the URL. For
|
|
19
|
-
* requests against third-party servers, you must define a RegExp that matches
|
|
18
|
+
* For same-origin requests the `RegExp` only needs to match part of the URL. For
|
|
19
|
+
* requests against third-party servers, you must define a `RegExp` that matches
|
|
20
20
|
* the start of the URL.
|
|
21
21
|
*/
|
|
22
22
|
export class RegExpRoute extends Route {
|
package/src/routing/Router.ts
CHANGED
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
https://opensource.org/licenses/MIT.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { RouteHandler, RouteHandlerCallbackOptions, RouteHandlerObject, RouteMatchCallbackOptions } from "@serwist/core";
|
|
9
|
+
import type { RouteHandler, RouteHandlerCallbackOptions, RouteHandlerObject, RouteMatchCallback, RouteMatchCallbackOptions } from "@serwist/core";
|
|
10
10
|
import { assert, SerwistError, getFriendlyURL, logger } from "@serwist/core/internal";
|
|
11
11
|
|
|
12
12
|
import type { Route } from "./Route.js";
|
|
13
|
+
import { parseRoute } from "./parseRoute.js";
|
|
13
14
|
import type { HTTPMethod } from "./utils/constants.js";
|
|
14
15
|
import { defaultMethod } from "./utils/constants.js";
|
|
15
16
|
import { normalizeHandler } from "./utils/normalizeHandler.js";
|
|
@@ -26,20 +27,21 @@ interface CacheURLsMessageData {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
30
|
+
* `Router` can be used to process a `FetchEvent` using one or more `Route`(s), responding with a `Response`
|
|
31
|
+
* if a matching route exists.
|
|
31
32
|
*
|
|
32
|
-
* If no
|
|
33
|
+
* If no `Route` matches given a `Request`, the `Router` will use the default handler if one is defined.
|
|
33
34
|
*
|
|
34
|
-
* Should the matching Route throw an error, the Router will use
|
|
35
|
-
* gracefully deal with issues and respond with a Request
|
|
35
|
+
* Should the matching Route throw an error, the Router will use the catch handler if one is defined to
|
|
36
|
+
* gracefully deal with issues and respond with a `Request`.
|
|
36
37
|
*
|
|
37
|
-
* If a
|
|
38
|
-
* be used to respond to the request.
|
|
38
|
+
* If a `Request` matches multiple routes, the earliest registered route will be used to respond to the `Request`.
|
|
39
39
|
*/
|
|
40
40
|
export class Router {
|
|
41
41
|
private readonly _routes: Map<HTTPMethod, Route[]>;
|
|
42
42
|
private readonly _defaultHandlerMap: Map<HTTPMethod, RouteHandlerObject>;
|
|
43
|
+
private _fetchListenerHandler: ((ev: FetchEvent) => void) | null = null;
|
|
44
|
+
private _cacheListenerHandler: ((ev: ExtendableMessageEvent) => void) | null = null;
|
|
43
45
|
private _catchHandler?: RouteHandlerObject;
|
|
44
46
|
|
|
45
47
|
/**
|
|
@@ -51,7 +53,7 @@ export class Router {
|
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
|
-
* @returns routes A `Map` of HTTP method name ('GET'
|
|
56
|
+
* @returns routes A `Map` of HTTP method name (`'GET'`, etc.) to an array of all the corresponding `Route`
|
|
55
57
|
* instances that are registered.
|
|
56
58
|
*/
|
|
57
59
|
get routes(): Map<HTTPMethod, Route[]> {
|
|
@@ -59,23 +61,40 @@ export class Router {
|
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
/**
|
|
62
|
-
* Adds a fetch event listener to respond to events when a
|
|
63
|
-
* the event's request.
|
|
64
|
+
* Adds a `fetch` event listener to respond to events when a `Route` matches
|
|
65
|
+
* the event's request. Effectively no-op if `addFEtchListener` has been
|
|
66
|
+
* called, but `removeFetchListener` has not.
|
|
64
67
|
*/
|
|
65
68
|
addFetchListener(): void {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
if (!this._fetchListenerHandler) {
|
|
70
|
+
this._fetchListenerHandler = (event) => {
|
|
71
|
+
const { request } = event;
|
|
72
|
+
const responsePromise = this.handleRequest({ request, event });
|
|
73
|
+
if (responsePromise) {
|
|
74
|
+
event.respondWith(responsePromise);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
self.addEventListener("fetch", this._fetchListenerHandler);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Removes `fetch` event listener added by `addFetchListener`.
|
|
83
|
+
* Effectively no-op if either `addFetchListener` has not been called or,
|
|
84
|
+
* if it has, so has `removeFetchListener`.
|
|
85
|
+
*/
|
|
86
|
+
removeFetchListener(): void {
|
|
87
|
+
if (this._fetchListenerHandler) {
|
|
88
|
+
self.removeEventListener("fetch", this._fetchListenerHandler);
|
|
89
|
+
this._fetchListenerHandler = null;
|
|
90
|
+
}
|
|
73
91
|
}
|
|
74
92
|
|
|
75
93
|
/**
|
|
76
|
-
* Adds a message event listener for URLs to cache from the window.
|
|
94
|
+
* Adds a `message` event listener for URLs to cache from the window.
|
|
77
95
|
* This is useful to cache resources loaded on the page prior to when the
|
|
78
|
-
* service worker started controlling it.
|
|
96
|
+
* service worker started controlling it. Effectively no-op if `addCacheListener`
|
|
97
|
+
* has been called, but `removeCacheListener` hasn't.
|
|
79
98
|
*
|
|
80
99
|
* The format of the message data sent from the window should be as follows.
|
|
81
100
|
* Where the `urlsToCache` array may consist of URL strings or an array of
|
|
@@ -95,38 +114,52 @@ export class Router {
|
|
|
95
114
|
* ```
|
|
96
115
|
*/
|
|
97
116
|
addCacheListener(): void {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
if (!this._cacheListenerHandler) {
|
|
118
|
+
this._cacheListenerHandler = (event) => {
|
|
119
|
+
if (event.data && event.data.type === "CACHE_URLS") {
|
|
120
|
+
const { payload }: CacheURLsMessageData = event.data;
|
|
101
121
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
122
|
+
if (process.env.NODE_ENV !== "production") {
|
|
123
|
+
logger.debug("Caching URLs from the window", payload.urlsToCache);
|
|
124
|
+
}
|
|
105
125
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
126
|
+
const requestPromises = Promise.all(
|
|
127
|
+
payload.urlsToCache.map((entry: string | [string, RequestInit?]) => {
|
|
128
|
+
if (typeof entry === "string") {
|
|
129
|
+
entry = [entry];
|
|
130
|
+
}
|
|
111
131
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
132
|
+
const request = new Request(...entry);
|
|
133
|
+
return this.handleRequest({ request, event });
|
|
134
|
+
}),
|
|
135
|
+
);
|
|
116
136
|
|
|
117
|
-
|
|
137
|
+
event.waitUntil(requestPromises);
|
|
118
138
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
139
|
+
// If a MessageChannel was used, reply to the message on success.
|
|
140
|
+
if (event.ports?.[0]) {
|
|
141
|
+
void requestPromises.then(() => event.ports[0].postMessage(true));
|
|
142
|
+
}
|
|
122
143
|
}
|
|
123
|
-
}
|
|
124
|
-
|
|
144
|
+
};
|
|
145
|
+
self.addEventListener("message", this._cacheListenerHandler);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Removes the `message` event listener added by `addCacheListener`.
|
|
151
|
+
* Effectively no-op if either `addCacheListener` has not been called or,
|
|
152
|
+
* if it has, so has `removeCacheListener`.
|
|
153
|
+
*/
|
|
154
|
+
removeCacheListener(): void {
|
|
155
|
+
if (this._cacheListenerHandler) {
|
|
156
|
+
self.removeEventListener("message", this._cacheListenerHandler);
|
|
157
|
+
}
|
|
125
158
|
}
|
|
126
159
|
|
|
127
160
|
/**
|
|
128
|
-
* Apply the routing rules to a FetchEvent object to get a Response from an
|
|
129
|
-
* appropriate Route's handler.
|
|
161
|
+
* Apply the routing rules to a `FetchEvent` object to get a `Response` from an
|
|
162
|
+
* appropriate `Route`'s handler.
|
|
130
163
|
*
|
|
131
164
|
* @param options
|
|
132
165
|
* @returns A promise is returned if a registered route can handle the request.
|
|
@@ -158,7 +191,7 @@ export class Router {
|
|
|
158
191
|
const url = new URL(request.url, location.href);
|
|
159
192
|
if (!url.protocol.startsWith("http")) {
|
|
160
193
|
if (process.env.NODE_ENV !== "production") {
|
|
161
|
-
logger.debug("
|
|
194
|
+
logger.debug("Router only supports URLs that start with 'http'.");
|
|
162
195
|
}
|
|
163
196
|
return;
|
|
164
197
|
}
|
|
@@ -334,21 +367,21 @@ export class Router {
|
|
|
334
367
|
* Define a default `handler` that's called when no routes explicitly
|
|
335
368
|
* match the incoming request.
|
|
336
369
|
*
|
|
337
|
-
* Each HTTP method ('GET'
|
|
370
|
+
* Each HTTP method (`'GET'`, `'POST'`, etc.) gets its own default handler.
|
|
338
371
|
*
|
|
339
372
|
* Without a default handler, unmatched requests will go against the
|
|
340
373
|
* network as if there were no service worker present.
|
|
341
374
|
*
|
|
342
|
-
* @param handler A callback function that returns a Promise resulting in a Response
|
|
375
|
+
* @param handler A callback function that returns a `Promise` resulting in a `Response`.
|
|
343
376
|
* @param method The HTTP method to associate with this default handler. Each method
|
|
344
|
-
* has its own default. Defaults to GET
|
|
377
|
+
* has its own default. Defaults to `'GET'`.
|
|
345
378
|
*/
|
|
346
379
|
setDefaultHandler(handler: RouteHandler, method: HTTPMethod = defaultMethod): void {
|
|
347
380
|
this._defaultHandlerMap.set(method, normalizeHandler(handler));
|
|
348
381
|
}
|
|
349
382
|
|
|
350
383
|
/**
|
|
351
|
-
* If a Route throws an error while handling a request, this `handler`
|
|
384
|
+
* If a `Route` throws an error while handling a request, this `handler`
|
|
352
385
|
* will be called and given a chance to provide a response.
|
|
353
386
|
*
|
|
354
387
|
* @param handler A callback function that returns a Promise resulting
|
|
@@ -359,9 +392,25 @@ export class Router {
|
|
|
359
392
|
}
|
|
360
393
|
|
|
361
394
|
/**
|
|
362
|
-
* Registers a
|
|
395
|
+
* Registers a `RegExp`, string, or function with a caching
|
|
396
|
+
* strategy to the `Router`.
|
|
397
|
+
*
|
|
398
|
+
* @param capture If the capture param is a `Route`, all other arguments will be ignored.
|
|
399
|
+
* @param handler A callback function that returns a `Promise` resulting in a `Response`.
|
|
400
|
+
* This parameter is required if `capture` is not a `Route` object.
|
|
401
|
+
* @param method The HTTP method to match the Route against. Defaults to `'GET'`.
|
|
402
|
+
* @returns The generated `Route`.
|
|
403
|
+
*/
|
|
404
|
+
registerCapture(capture: RegExp | string | RouteMatchCallback | Route, handler?: RouteHandler, method?: HTTPMethod): Route {
|
|
405
|
+
const route = parseRoute(capture, handler, method);
|
|
406
|
+
this.registerRoute(route);
|
|
407
|
+
return route;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Registers a `Route` with the router.
|
|
363
412
|
*
|
|
364
|
-
* @param route The
|
|
413
|
+
* @param route The `Route` to register.
|
|
365
414
|
*/
|
|
366
415
|
registerRoute(route: Route): void {
|
|
367
416
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -411,9 +460,9 @@ export class Router {
|
|
|
411
460
|
}
|
|
412
461
|
|
|
413
462
|
/**
|
|
414
|
-
* Unregisters a
|
|
463
|
+
* Unregisters a `Route` with the `Router`.
|
|
415
464
|
*
|
|
416
|
-
* @param route The
|
|
465
|
+
* @param route The `Route` to unregister.
|
|
417
466
|
*/
|
|
418
467
|
unregisterRoute(route: Route): void {
|
|
419
468
|
if (!this._routes.has(route.method)) {
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import type { RouteHandler, RouteMatchCallback } from "@serwist/core";
|
|
2
2
|
import { SerwistError, logger } from "@serwist/core/internal";
|
|
3
3
|
|
|
4
|
-
import { RegExpRoute } from "
|
|
5
|
-
import { Route } from "
|
|
6
|
-
import type { HTTPMethod } from "./constants.js";
|
|
4
|
+
import { RegExpRoute } from "./RegExpRoute.js";
|
|
5
|
+
import { Route } from "./Route.js";
|
|
6
|
+
import type { HTTPMethod } from "./utils/constants.js";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Parses a `RegExp`, string, or function with a caching strategy into a `Route`. This is for
|
|
10
|
+
* when you want to create a `Route`, but you don't want to register it just yet: sometimes
|
|
11
|
+
* you want to call `setCatchHandler` first, for example.
|
|
12
|
+
*
|
|
13
|
+
* @param capture If the capture param is a `Route`, all other arguments will be ignored.
|
|
14
|
+
* @param handler A callback function that returns a `Promise` resulting in a `Response`.
|
|
15
|
+
* This parameter is required if `capture` is not a `Route` object.
|
|
16
|
+
* @param method The HTTP method to match the `Route` against. Defaults to `'GET'`.
|
|
17
|
+
* @returns The generated `Route`.
|
|
18
|
+
*/
|
|
8
19
|
export const parseRoute = (capture: RegExp | string | RouteMatchCallback | Route, handler?: RouteHandler, method?: HTTPMethod): Route => {
|
|
9
20
|
let route: Route;
|
|
10
21
|
|
|
@@ -9,25 +9,19 @@
|
|
|
9
9
|
import type { RouteHandler, RouteMatchCallback } from "@serwist/core";
|
|
10
10
|
|
|
11
11
|
import { Route } from "./Route.js";
|
|
12
|
+
import { getSingletonRouter } from "./singletonRouter.js";
|
|
12
13
|
import type { HTTPMethod } from "./utils/constants.js";
|
|
13
|
-
import { getOrCreateDefaultRouter } from "./utils/getOrCreateDefaultRouter.js";
|
|
14
|
-
import { parseRoute } from "./utils/parseRoute.js";
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
|
-
* Registers a RegExp
|
|
18
|
-
* strategy to a singleton Router instance.
|
|
16
|
+
* Registers a `RegExp`, string, or function with a caching
|
|
17
|
+
* strategy to a singleton `Router` instance.
|
|
19
18
|
*
|
|
20
19
|
* @param capture If the capture param is a `Route`, all other arguments will be ignored.
|
|
21
|
-
* @param handler A callback function that returns a Promise resulting in a Response
|
|
20
|
+
* @param handler A callback function that returns a `Promise` resulting in a `Response`.
|
|
22
21
|
* This parameter is required if `capture` is not a `Route` object.
|
|
23
|
-
* @param method The HTTP method to match the Route against. Defaults to GET
|
|
24
|
-
* @returns The generated `Route
|
|
22
|
+
* @param method The HTTP method to match the `Route` against. Defaults to `'GET'`.
|
|
23
|
+
* @returns The generated `Route`, which can then be provided to `unregisterRoute` if needed.
|
|
25
24
|
*/
|
|
26
25
|
export const registerRoute = (capture: RegExp | string | RouteMatchCallback | Route, handler?: RouteHandler, method?: HTTPMethod): Route => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const defaultRouter = getOrCreateDefaultRouter();
|
|
30
|
-
defaultRouter.registerRoute(route);
|
|
31
|
-
|
|
32
|
-
return route;
|
|
26
|
+
return getSingletonRouter().registerCapture(capture, handler, method);
|
|
33
27
|
};
|
|
@@ -8,15 +8,14 @@
|
|
|
8
8
|
|
|
9
9
|
import type { RouteHandler } from "@serwist/core";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { getSingletonRouter } from "./singletonRouter.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* If a Route throws an error while handling a request, this `handler`
|
|
14
|
+
* If a `Route` throws an error while handling a request, this `handler`
|
|
15
15
|
* will be called and given a chance to provide a response.
|
|
16
16
|
*
|
|
17
17
|
* @param handler A callback function that returns a Promise resulting in a Response.
|
|
18
18
|
*/
|
|
19
19
|
export const setCatchHandler = (handler: RouteHandler): void => {
|
|
20
|
-
|
|
21
|
-
defaultRouter.setCatchHandler(handler);
|
|
20
|
+
getSingletonRouter().setCatchHandler(handler);
|
|
22
21
|
};
|
|
@@ -8,18 +8,17 @@
|
|
|
8
8
|
|
|
9
9
|
import type { RouteHandler } from "@serwist/core";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { getSingletonRouter } from "./singletonRouter.js";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Defines a default `handler` that's called when no routes explicitly
|
|
15
15
|
* match the incoming request.
|
|
16
16
|
*
|
|
17
|
-
* Without a default handler
|
|
17
|
+
* Without a default `handler`, unmatched requests will go against the
|
|
18
18
|
* network as if there were no service worker present.
|
|
19
19
|
*
|
|
20
20
|
* @param handler A callback function that returns a Promise resulting in a Response.
|
|
21
21
|
*/
|
|
22
22
|
export const setDefaultHandler = (handler: RouteHandler): void => {
|
|
23
|
-
|
|
24
|
-
defaultRouter.setDefaultHandler(handler);
|
|
23
|
+
getSingletonRouter().setDefaultHandler(handler);
|
|
25
24
|
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2019 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Router } from "./Router.js";
|
|
10
|
+
|
|
11
|
+
let defaultRouter: Router | undefined = undefined;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new, singleton `Router` if one does not exist. If one does
|
|
15
|
+
* already exist, that instance is returned. This instance is used by
|
|
16
|
+
* Serwist's `Router`-dependent functions and classes unless you provide
|
|
17
|
+
* a different `Router` to them.
|
|
18
|
+
*
|
|
19
|
+
* @returns The singleton `Router`.
|
|
20
|
+
*/
|
|
21
|
+
export const getSingletonRouter = (): Router => {
|
|
22
|
+
if (!defaultRouter) {
|
|
23
|
+
defaultRouter = new Router();
|
|
24
|
+
|
|
25
|
+
// The helpers that use the default Router assume these listeners exist.
|
|
26
|
+
defaultRouter.addFetchListener();
|
|
27
|
+
defaultRouter.addCacheListener();
|
|
28
|
+
}
|
|
29
|
+
return defaultRouter;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Changes the singleton `Router` to a different instance. This is meant for when you do not
|
|
34
|
+
* want to pass your own `Router` to every one of Serwist's `Router`-dependent functions and classes.
|
|
35
|
+
* If this or `getSingletonRouter` has been called before, it removes the listeners of the
|
|
36
|
+
* previous singleton `Router`. It also adds those of the new one, so you need not do that yourself.
|
|
37
|
+
*
|
|
38
|
+
* It is highly recommended that you call this before anything else, if you plan on doing so.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```js
|
|
42
|
+
* import { Router, setSingletonRouter } from "@serwist/sw/routing";
|
|
43
|
+
*
|
|
44
|
+
* const router = new Router();
|
|
45
|
+
*
|
|
46
|
+
* setSingletonRouter(router);
|
|
47
|
+
*
|
|
48
|
+
* router.registerRoute(
|
|
49
|
+
* new Route(
|
|
50
|
+
* /\/api\/.*\/*.json/,
|
|
51
|
+
* new NetworkOnly({
|
|
52
|
+
* plugins: [backgroundSync],
|
|
53
|
+
* }),
|
|
54
|
+
* "POST",
|
|
55
|
+
* ),
|
|
56
|
+
* );
|
|
57
|
+
*
|
|
58
|
+
* // This class now automatically picks up your `Router`! Without `setSingletonRouter`, you'd need to
|
|
59
|
+
* // write this instead: `new Serwist({ router })`
|
|
60
|
+
* const serwist = new Serwist();
|
|
61
|
+
*
|
|
62
|
+
* serwist.install();
|
|
63
|
+
* ```
|
|
64
|
+
* @param router
|
|
65
|
+
* @returns The new singleton `Router`.
|
|
66
|
+
*/
|
|
67
|
+
export const setSingletonRouter = (router: Router): Router => {
|
|
68
|
+
if (defaultRouter) {
|
|
69
|
+
defaultRouter.removeFetchListener();
|
|
70
|
+
defaultRouter.removeCacheListener();
|
|
71
|
+
}
|
|
72
|
+
defaultRouter = router;
|
|
73
|
+
defaultRouter.addFetchListener();
|
|
74
|
+
defaultRouter.addCacheListener();
|
|
75
|
+
return defaultRouter;
|
|
76
|
+
};
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { Route } from "./Route.js";
|
|
2
|
-
import {
|
|
2
|
+
import { getSingletonRouter } from "./singletonRouter.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Unregisters a route from the singleton Router instance.
|
|
5
|
+
* Unregisters a route from the singleton `Router` instance.
|
|
6
6
|
*
|
|
7
7
|
* @param route The route to unregister.
|
|
8
8
|
*/
|
|
9
9
|
export const unregisterRoute = (route: Route): void => {
|
|
10
|
-
|
|
11
|
-
defaultRouter.unregisterRoute(route);
|
|
10
|
+
getSingletonRouter().unregisterRoute(route);
|
|
12
11
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getOrCreatePrecacheController.d.ts","sourceRoot":"","sources":["../../../src/precaching/utils/getOrCreatePrecacheController.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAI9D;;;GAGG;AACH,eAAO,MAAM,6BAA6B,QAAO,kBAKhD,CAAC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Router } from "../Router.js";
|
|
2
|
-
/**
|
|
3
|
-
* Creates a new, singleton Router instance if one does not exist. If one
|
|
4
|
-
* does already exist, that instance is returned.
|
|
5
|
-
*
|
|
6
|
-
* @private
|
|
7
|
-
* @returns
|
|
8
|
-
*/
|
|
9
|
-
export declare const getOrCreateDefaultRouter: () => Router;
|
|
10
|
-
//# sourceMappingURL=getOrCreateDefaultRouter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getOrCreateDefaultRouter.d.ts","sourceRoot":"","sources":["../../../src/routing/utils/getOrCreateDefaultRouter.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAItC;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,QAAO,MAS3C,CAAC"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { RouteHandler, RouteMatchCallback } from "@serwist/core";
|
|
2
|
-
import { Route } from "../Route.js";
|
|
3
|
-
import type { HTTPMethod } from "./constants.js";
|
|
4
|
-
export declare const parseRoute: (capture: RegExp | string | RouteMatchCallback | Route, handler?: RouteHandler, method?: HTTPMethod) => Route;
|
|
5
|
-
//# sourceMappingURL=parseRoute.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parseRoute.d.ts","sourceRoot":"","sources":["../../../src/routing/utils/parseRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAItE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,eAAO,MAAM,UAAU,YAAa,MAAM,GAAG,MAAM,GAAG,kBAAkB,GAAG,KAAK,YAAY,YAAY,WAAW,UAAU,KAAG,KA2D/H,CAAC"}
|