ts-service-worker 1.0.33 → 1.1.1
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/README.md +42 -31
- package/dist/cli.mjs +585 -249
- package/dist/index.js +589 -252
- package/dist/index.js.map +4 -4
- package/package.json +10 -8
- package/types/index.d.mts +1 -1
- package/types/requestHandler.d.mts +1 -0
- package/types/strategies.d.mts +3 -3
package/README.md
CHANGED
|
@@ -21,18 +21,14 @@ The idea is simple. You provide TS-Service-Worker with a **Plan** (and options),
|
|
|
21
21
|
|
|
22
22
|
The very simplest service worker might provide an offline backup of the whole site:
|
|
23
23
|
```ts
|
|
24
|
-
import {requestHandler
|
|
24
|
+
import {requestHandler} from "ts-service-worker";
|
|
25
25
|
|
|
26
26
|
export const plan: Plan = [
|
|
27
|
-
{paths:
|
|
27
|
+
{paths: /.*/, strategy: "networkFirst"} // don't do this!
|
|
28
28
|
]
|
|
29
29
|
app.get('/service-worker.js', requestHandler(plan))
|
|
30
30
|
```
|
|
31
|
-
This plan says, "intercept all the requests
|
|
32
|
-
|
|
33
|
-
- declarative configuration
|
|
34
|
-
- conveniences like `Origin` that make doing simple things simple
|
|
35
|
-
- how a simple caching strategy is insufficent. (shrug)
|
|
31
|
+
This plan says, "intercept all the requests, and serve them from the network if available; otherwise, serve from the cache." This is just one of the example caching strategies, and demonstrates the declarative configuration-- and how a simple caching strategy is insufficent. (shrug)
|
|
36
32
|
|
|
37
33
|
Some of the deficiences of this strategy:
|
|
38
34
|
- it only caches paths that have been visited
|
|
@@ -44,7 +40,7 @@ A real caching plan requires more nuance. Here is part of a slightly more realis
|
|
|
44
40
|
export const plan: Plan =
|
|
45
41
|
[
|
|
46
42
|
{strategy: 'networkOnly', paths: ['/open-search.xml']},
|
|
47
|
-
{strategy: 'staleWhileRevalidate', ['/my-data.json']}
|
|
43
|
+
{strategy: 'staleWhileRevalidate', ['/my-data.json']},
|
|
48
44
|
{strategy: 'staticOfflineBackup', [/.*\.html/], backup: '/networkDown.html'}
|
|
49
45
|
]
|
|
50
46
|
```
|
|
@@ -57,10 +53,13 @@ Another common strategy is to pre-cache some resources on disk. These can be exp
|
|
|
57
53
|
```ts
|
|
58
54
|
{
|
|
59
55
|
strategy: 'cache-on-install',
|
|
60
|
-
files: {
|
|
56
|
+
files: {
|
|
57
|
+
dir: 'src/assets/images', // Root of search
|
|
58
|
+
glob: '*.png', // match
|
|
59
|
+
prefix: '/img'} // pre-pending to matched relative path
|
|
61
60
|
}
|
|
62
61
|
```
|
|
63
|
-
These are just some examples. Each app is different and requires careful consideration and crafting. **TS-Service-Worker** makes developing a custom caching service worker easy and error-free.
|
|
62
|
+
These are just some examples of a caching plan. Each app is different and requires careful consideration and crafting. **TS-Service-Worker** makes developing a custom caching service worker easy and error-free.
|
|
64
63
|
|
|
65
64
|
## Usage
|
|
66
65
|
|
|
@@ -72,10 +71,11 @@ Using directly within Express (or equivalent) will be the most convenient and pr
|
|
|
72
71
|
|
|
73
72
|
```ts
|
|
74
73
|
import { requestHandler } from 'ts-service-worker'
|
|
74
|
+
// ...
|
|
75
75
|
app.get('/service-worker.js', requestHandler([
|
|
76
76
|
{ strategy: 'networkFirst', paths: Origin }
|
|
77
|
+
// ...
|
|
77
78
|
]))
|
|
78
|
-
})
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
### CLI
|
|
@@ -88,13 +88,13 @@ The CLI will generate the Javascript file from the specifications in a JSON file
|
|
|
88
88
|
4. Editing the JSON file and regenerate as needed.
|
|
89
89
|
|
|
90
90
|
### Other
|
|
91
|
-
There are other ways to incorporate this into your build cycle. The library exposes a method `generateServiceWorker` which accepts a plan and options and generates the necessary Javascript (text). Let me know how you do it!
|
|
91
|
+
There are other ways to incorporate this into your build cycle. The library exposes a method `generateServiceWorker()` which accepts a plan and options and generates the necessary Javascript (text). Let me know how you do it!
|
|
92
92
|
|
|
93
|
-
Note that the output of this tool needs _no_ post-processing, so
|
|
93
|
+
Note that the output of this tool needs _no_ post-processing, so don't use them. If the code output isn't compatible, let me know and I'll fix it right away.
|
|
94
94
|
|
|
95
95
|
### Options
|
|
96
96
|
|
|
97
|
-
The following may be provided as options for any usage
|
|
97
|
+
The following may be provided as options for any of the usage methods, and they affect the generation of the Javascript code:
|
|
98
98
|
|
|
99
99
|
* `version` – semantic version of the worker. Major version bump means to reset the cache.
|
|
100
100
|
* `skipWaiting` – executes the normal skip waiting logic, and allows your service worker to come into play without all the browser windows being closed.
|
|
@@ -102,21 +102,23 @@ The following may be provided as options for any usage method, and they effect t
|
|
|
102
102
|
|
|
103
103
|
## Paths
|
|
104
104
|
|
|
105
|
-
Paths expressions will match URLs requested from your website
|
|
106
|
-
- a string URL path. This is
|
|
105
|
+
Paths expressions, used for most strategies, will match URLs requested from your website. The path property can be:
|
|
106
|
+
- a string URL path. This is interpreted as the meaning the end of the URL. Therefore '.png' would match any png file.
|
|
107
107
|
- a RegExp, matching the full URL
|
|
108
|
-
- an array of strings or
|
|
109
|
-
- the symbol `
|
|
110
|
-
- the symbol `
|
|
108
|
+
- an array of strings or RegExps, following the rules above
|
|
109
|
+
- the symbol `OriginAndBelow`, which matches everything under the service worker's domain.
|
|
110
|
+
- the symbol `ScopeAndBelow`, which matches everything under the service worker's scope, which is the level that a service worker is installed at.
|
|
111
111
|
|
|
112
112
|
## Strategies
|
|
113
113
|
|
|
114
|
+
These are the currently implemented strategies.
|
|
115
|
+
|
|
114
116
|
### cacheFirst
|
|
115
117
|
|
|
116
118
|
This strategy is ideal for CSS, images, fonts, JS, templates… basically anything you'd consider static to that "version" of your site. Per [https://web.dev/learn/pwa/serving/#cache-first]:
|
|
117
119
|
>> Using this strategy, the service worker looks for the matching request in the cache and returns the corresponding Response if it's cached. Otherwise it retrieves the response from the network (~~optionally,~~ updating the cache for future calls). If there is neither a cache response nor a network response, the request will error. Since serving assets without going to the network tends to be faster, this strategy prioritizes performance over freshness.
|
|
118
120
|
|
|
119
|
-
There is no way to remove files from the cache. For this reason, use only for immutable resources (certain images and fingerprinted assets). If these do need to be updated, you will need to [rebuild the cache (see below)](#
|
|
121
|
+
There is no way to remove files from the cache. For this reason, use only for immutable resources (certain images and fingerprinted assets). If these do need to be updated, you will need to [rebuild the cache (see below)](#clearing-the-cache).
|
|
120
122
|
|
|
121
123
|
### networkFirst
|
|
122
124
|
This is most useful to provide the user with a backup in case the network isn't available. Per [https://web.dev/learn/pwa/serving/#network-first]:
|
|
@@ -145,11 +147,13 @@ The backup resource is loaded on service worker installation and served as neede
|
|
|
145
147
|
|
|
146
148
|
Note: this currently doesn't support inline SVGs that you see in some examples, but requires using a separate file.
|
|
147
149
|
|
|
148
|
-
Note: this does **not** serve the "backup"
|
|
150
|
+
Note: this does **not** serve the "backup" URL from cache by default. If it's a normal app in the URL and you want it cached, use another strategy like `networkFirst` in combination.
|
|
149
151
|
|
|
150
152
|
### cache-on-install
|
|
151
153
|
|
|
152
|
-
Cache specific paths when the service worker installs. Because it needs to know specific resources, path matching wildcards and regular expression will not work.
|
|
154
|
+
Cache specific paths when the service worker installs. Because it needs to know specific resources, path matching wildcards and regular expression will not work. For example, you can't pre-cache all files that end in `.png`-- there's no way for the service worker to know what they are! You must use FULL paths.
|
|
155
|
+
|
|
156
|
+
But this strategy has an extra feature that other strategies do not: it can scan directories for resources. In some cases this, when you have a whole directory of files to pre-cache, this will be the easiest to maintain. Use normal glob patterns to identify these as shown below. Here's one example:
|
|
153
157
|
|
|
154
158
|
```ts
|
|
155
159
|
plan: Plan = [
|
|
@@ -177,37 +181,44 @@ There are two components that relevant here:
|
|
|
177
181
|
|
|
178
182
|
When building your service worker, provide a `version` string in the options, follow semvar conventions. If you change this at all, the service worker will be re-installed (because it has changed). This, in itself, will _not_ affect the cached files. But, if the _major version_ changes, the cache (of responses) will be deleting and a new one created. _With this library, the way to reset the cache in users' browsers is to bump the major version number._ (To test locally, you can use the browser's developer tools.)
|
|
179
183
|
|
|
180
|
-
That being said, you're not in complete control. Browsers will manage the actual response cache, removing items if it becomes too large. These limits are quite high in modern browsers.
|
|
184
|
+
That being said, you're not in complete control. Browsers will manage the actual response cache, removing items if it becomes too large. These limits are quite high in modern browsers.
|
|
185
|
+
|
|
186
|
+
Some of the strategies will replace older assets with newer ones when found; some won't. This should be documented above or obvious.
|
|
181
187
|
|
|
182
188
|
#### Skip Waiting
|
|
183
189
|
|
|
184
|
-
Service workers themselves will re-install when they have changed-- based on the browsers' rules. This
|
|
190
|
+
Service workers themselves will re-install when they have changed-- based on the browsers' rules. This can be confusing at first, though, as new service workers will not normally be installed: the default behavior for service workers is to wait until all the windows associated with the service worker to close, and only then does it install the new service worker.
|
|
191
|
+
|
|
192
|
+
If this isn't what you want, you can accellerate this by passing `skipWaiting: true` in the options. This will install the service worker as soon as it is downloaded-- but still will not be available as the page first loads. Usually it will be ready on the next reload.
|
|
185
193
|
|
|
186
194
|
## Why TS-Service-Worker?
|
|
187
195
|
|
|
188
|
-
Service workers are a powerful tool for developers to improve the user experience, providing for fine-grained caching, offline usage and progressive web apps (PWAs). It replaced the coarse-grained _AppCache_, which proved quite hard to
|
|
196
|
+
Service workers are a powerful tool for developers to improve the user experience, providing for fine-grained caching, offline usage and progressive web apps (PWAs). It replaced the coarse-grained _AppCache_, which proved quite hard to use and was retired.
|
|
189
197
|
|
|
190
|
-
Unfortunately, the service worker API is also hard to use, as it is quite low-level. It requires a series of nested promise chains, and quickly grows complicated. In the documentation
|
|
198
|
+
Unfortunately, the service worker API is also hard to use as well, as it is quite low-level. It requires a series of nested promise chains, and quickly grows complicated. In the documentation contains good examples describing single specific strategies. While these are readable, they are minimally useful because real-world usage requires integrating several of these strategies at the same time. This can be error-prone and hard to follow. And as anyone who has developed service workers knows, they are tedious to test because of the complex lifecycle.
|
|
191
199
|
|
|
192
200
|
And since service workers run in the browser, they must be written in the browser's version Javascript. This likely involves transpilation, which will requiring additional complexity in the build process to produce a separate artifact. It can be quite challenging in a Typescript project.
|
|
193
201
|
|
|
194
202
|
There are [other libraries](#other-libraries) designed to help, which may be useful to you. **TS-Service-Worker** aims to solve specific challenges.
|
|
195
203
|
|
|
196
204
|
## TODO
|
|
205
|
+
1. Other matching mechanisms, like mime-type.
|
|
197
206
|
2. https://web.dev/learn/pwa/serving/#cache-only
|
|
198
|
-
3. filter/only to process only certain types, eg.
|
|
207
|
+
3. filter/only strategy: to process only certain types, eg. `{ strategy: 'filter', paths: ' /https?:.*/ }`. This is weird semantically, so I'm still thinking.
|
|
199
208
|
4. allowOnly: /
|
|
200
209
|
5. https://web.dev/learn/pwa/workbox/#offline-fallback
|
|
201
210
|
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#recovering_failed_requests ALSO offline SVG: https://github.com/veiss-com/sw-tools#offline
|
|
202
211
|
6. https://github.com/veiss-com/sw-tools#limiting-the-cache-size
|
|
203
|
-
7. expiring cache
|
|
212
|
+
7. expiring cache / expirations on cached items
|
|
204
213
|
|
|
205
214
|
## References
|
|
206
215
|
These are the basics of how service workers function:
|
|
207
216
|
- https://web.dev/learn/pwa/serving/
|
|
208
|
-
- https://web.dev/offline-cookbook
|
|
209
|
-
|
|
210
|
-
|
|
217
|
+
- https://web.dev/offline-cookbook/
|
|
218
|
+
- Interesting reference showing the complexities: https://adactio.com/serviceworker.js and https://adactio.medium.com/cache-limiting-in-service-workers-d6741361ca19
|
|
219
|
+
- The complexities of testing service workers: [https://medium.com/dev-channel/testing-service-workers-318d7b016b19]
|
|
220
|
+
- Service worker mocking library: [https://github.com/zackargyle/service-workers/tree/master/packages/service-worker-mock]
|
|
221
|
+
- See the service workers generated with this tool: [https://amp-what.com/service-worker.js]
|
|
211
222
|
|
|
212
223
|
## Other Libraries
|
|
213
224
|
- https://web.dev/learn/pwa/workbox/ -- popular and very cool tool. This will work for many projects, but I was looking for something where I had a little more control.
|