ts-service-worker 1.0.31

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 ADDED
@@ -0,0 +1,229 @@
1
+
2
+
3
+ ## Why
4
+
5
+ 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 effectively use.
6
+
7
+ Unfortunately, the service worker API is so low-level it can be hard to use. It requires series of nested promise chains, and quickly grows complicated. In the documentation there are 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 their more complex lifecycle.
8
+
9
+ And since service workers run in the browser, they must be written in the browser's version Javascript. If this likely involves transpilation, which will requiring additional complexity in the build process to produce a separate artifact.
10
+
11
+ There are a [other libraries](#other-libraries) designed to help, which may be useful to you. **TS-Service-worker** aims to solve specific challenges. It:
12
+
13
+ - is written in Typescript and fully typed
14
+ - avoids nesting and promise chains
15
+ - has a declarative API to _describe_ your webapp caching
16
+ - supports easy integration of multiple caching strategies
17
+ - build a compatible service-worker.js that requires no additional transpilation
18
+ - can scan your disk for resources to cache
19
+ - provides built-in debug logging
20
+ - provides simple a simple cache clearing rule
21
+
22
+ ## Examples
23
+
24
+ The very simplest service worker might provide an offline backup of the whole site:
25
+ ```ts
26
+ import {requestHandler, Origin} from "ts-service-worker";
27
+
28
+ export const plan: Plan = [
29
+ {paths: Origin, strategy: "networkFirst"}
30
+ ]
31
+ app.get('/service-worker.js', requestHandler(plan))
32
+ ```
33
+ This plan says, "intercept all the requests from the origin and below (usually everything under `/`), and serve if from the network if available, otherwise, serve from the cache." This is just one of the example caching strategies, and demonstrates:
34
+
35
+ - declarative configuration
36
+ - conveniences like `Origin` that make doing simple things simple
37
+ - how a simple caching strategy is insufficent.
38
+
39
+ Some of the deficiences of this strategy:
40
+ - it only caches paths that have been visited
41
+ - provides no way to update cached files
42
+ - caches everything fetched, even unimportant resources
43
+
44
+ A real caching plan requires more nuance. Here's a slightly more realistic plan:
45
+ ```ts
46
+ export const plan: Plan =
47
+ [
48
+ {strategy: 'networkOnly', paths: ['/open-search.xml']},
49
+ {strategy: 'staleWhileRevalidate', ['/my-data.json']}
50
+ {strategy: 'staticOfflineBackup', [/.*\.html/], backup: '/networkDown.html'}
51
+ ]
52
+ ```
53
+ Here, we see multiple strategies in action. Each request is evaluated (sequentially) against the paths, and the first matching strategy is applied.
54
+ - The path `open-search.xml` will never be cached,
55
+ - `/my-data.json` will be served from the cache and re-fetched in the background, available for a later access.
56
+ - Finally, the file `/networkDown.html` will be cached, and served as a replacement for other HTML pages when the network is down.
57
+
58
+ Another common strategy is to pre-cache some resources on disk. These can be explicitly listed, or dynamically determined from glob matches of files on disk:
59
+ ```ts
60
+ {
61
+ strategy: 'cache-on-install',
62
+ files: { glob: '*.png', dir: 'src/assets/images', prefix: '/img'}
63
+ }
64
+ ```
65
+ 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.
66
+
67
+ ## Usage
68
+
69
+ There are a few ways to use this:
70
+
71
+ ### CLI
72
+
73
+ 1. Create a `service-worker.ts` file that exports a `plan` variable
74
+ 2. Run `> ts-sw service-worker.ts`
75
+ 3. Serve the resultant file as your service worker, editing the Typescript file and regenerating as needed.
76
+
77
+ ### Within Express
78
+ ```ts
79
+ import { requestHandler } from 'ts-service-worker'
80
+ app.get('/service-worker.js', requestHandler([
81
+ { strategy: 'networkFirst', paths: Origin }
82
+ ]))
83
+ })
84
+ ```
85
+ ### Other
86
+ 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!
87
+
88
+ Note that the output of this tool needs no post-processing, so it's best to avoid these tools for the service worker if possible. If the code output isn't compatible, let me know and I'll fix it right away.
89
+
90
+ ## Options
91
+
92
+ The following may be provided as options, and they effect the generation of the Javascript code:
93
+
94
+ * version – semantic version of the worker. Major version bump means to reset the cache.
95
+ * skipWaiting – executes the normal skip waiting logic, and allows your service worker to come into play without all the browser windows being closed.
96
+ * debug – outputs log messages as files are fetched. This is too noise for production, but may be useful to figure out what is going on with your service worker.
97
+
98
+ ## Paths
99
+
100
+ Paths can be:
101
+ - a string URL path. This is intepreted as the meaning the URL must END with this pattern
102
+ - a RegExp, matching the full URL
103
+ - an array of strings or RegExp
104
+ - the symbol `Symbol.for('origin')`, which matches everything under the service worker's domain.
105
+ - the symbol `Symbol.for('scope')`, which matches everything under the service worker's scope, which is the level that a service worker is installed at.
106
+
107
+ ## Strategies
108
+
109
+ **ts-service-worker**
110
+
111
+ ### cache-on-install
112
+
113
+ Tell it paths to cache when the service worker activates.
114
+
115
+ Also, it can scan directories from resources. This is optional, but for some use cases you will have a whole directory of files you want to pre-cache. Use normal glob patterns to identify these as shown below.
116
+ ```ts
117
+ plan: Plan = [
118
+ {
119
+ files: {
120
+ glob: '**/*.png',
121
+ dir: 'src/images',
122
+ prefix: '/assets'
123
+ },
124
+ strategy: 'cache on install'
125
+ }
126
+ ]
127
+ ```
128
+ The globs are evaluated with the `service-worker.js` file is created, so updating resources will require rebuilding the file.
129
+
130
+ ### cacheFirst
131
+
132
+ Ideal for: CSS, images, fonts, JS, templates… basically anything you'd consider static to that "version" of your site.
133
+ >> 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.
134
+
135
+ 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)](#Rebuild Cache).
136
+
137
+ See [https://web.dev/learn/pwa/serving/#cache-first].
138
+
139
+
140
+ ### networkFirst
141
+
142
+ This is most useful to provide the user with a backup in case the network isn't available.
143
+
144
+ > This strategy is the mirror of the Cache First strategy; it checks if the request can be fulfilled from the network and, if it can't, tries to retrieve it from the cache. If there is neither a network response nor a cache response, the request will error. Getting the response from the network is usually slower than getting it from the cache, this strategy prioritizes updated content instead of performance.
145
+
146
+ See [https://web.dev/learn/pwa/serving/#network-first].
147
+
148
+ ### staleWhileRevalidate
149
+
150
+ This is useful for resources that could be slow to fetch but where freshness is not critical.
151
+
152
+ > The stale while revalidate strategy returns a cached response immediately, then checks the network for an update, replacing the cached response if one is found. This strategy always makes a network request, because even if a cached resource is found, it will try to update what was in the cache with what was received from the network, to use the updated version in the next request. This strategy, therefore, provides a way for you to benefit from the quick serving of the cache first strategy and update the cache in the background.
153
+
154
+ > With this strategy, the assets are updated in the background. This means your users won't get the new version of the assets until the next time that path is requested. At that time the strategy will again check if a new version exists and the cycle repeats.
155
+
156
+ See https://web.dev/learn/pwa/serving/#stale-while-revalidate
157
+
158
+ ### networkOnly
159
+
160
+ > The network only strategy is similar to how browsers behave without a service worker or the Cache Storage API. Requests will only return a resource if it can be fetched from the network. This is often useful for resources like online-only API requests.
161
+ >
162
+ See https://web.dev/learn/pwa/serving/#network-only
163
+
164
+ ### staticOfflineBackup
165
+
166
+ Use this strategy to provide a backup for a resource only to be applied when a site is offline. This may be a "sorry" page, or could provide some reasonable alternative. This is commonly used for placeholder images or other content.
167
+
168
+ The backup resource is loaded on service worker installation and served as needed.
169
+
170
+ Note: this currently doesn't support inline SVGs that you see in some examples, but requires using a separate file.
171
+
172
+ Note: this does **not** serve the "backup" file from cache by default. If you want to do that, use another strategy in combination. This likely is `networkFirst`, but it's up to you.
173
+
174
+
175
+ ## Rebuild Cache
176
+
177
+ The browsers will manage the cache, removing items if it becomes too larger.
178
+
179
+ Most of the strategies will replace older assets with newer ones when found.
180
+
181
+ If you _need_ to reset the cache, simply increment the version number. A major version bump means the whole cache is replaced. See [#versioning] below.
182
+
183
+ ## Versioning
184
+
185
+ Service workers themselves have no concept of versioning. The browser manages downloading the service worker on page load, and if it's "out of date", it will notice. It will install the new service worker and then wait until the current one isn't in use, and replace it with the new one. This generally means a new service worker won't come into play until the user closes the windows, so it may be some time. To accelerate this, pass `skipWaiting` in the options, which will activate the service worker as soon as it is downloaded.
186
+
187
+ Service workers themselves don't have the concept of semantic versioning, but this library provides a simple one: you can provide a VERSION string. The first component of it (the major version number), will be used to name the cache. If this changes, the cache is deleting and a new one created. This is the only effective way of resetting the cache from the service worker. (To test locally, you will use the browser's developer tools.)
188
+
189
+
190
+
191
+ Strategies:
192
+ precache
193
+ cache
194
+ prefetching (on installation)
195
+ offline responses
196
+ network-first
197
+ cache-first
198
+ offline backup
199
+
200
+ ## TODO
201
+ 1. Fix backup to ONLY serve backup if network fails.
202
+ 2. Command line
203
+ https://web.dev/learn/pwa/serving/#cache-only
204
+ 3. filter/only to process only certain types, eg. only: /https?:.*/
205
+ 4. allowOnly: /
206
+ 5. https://web.dev/learn/pwa/workbox/#offline-fallback
207
+ 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
208
+ 6. https://github.com/veiss-com/sw-tools#limiting-the-cache-size
209
+ 7. expiring cache
210
+ 8. change name of service worker request handler. requesthandler?
211
+
212
+ REFERENCE
213
+ https://web.dev/learn/pwa/serving/
214
+ https://web.dev/offline-cookbook/#on-network-response
215
+
216
+ Interesting reference showing the complexities: https://adactio.com/serviceworker.js and https://adactio.medium.com/cache-limiting-in-service-workers-d6741361ca19
217
+
218
+
219
+ ## Other Libraries
220
+ - 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.
221
+ - https://vite-pwa-org.netlify.app/frameworks/sveltekit.html
222
+ - https://github.com/veiss-com/sw-tools#offline -- very specific features
223
+ - https://github.com/TalAter/UpUp/ -- single use case: provides a "backup" of your site if it's offline
224
+
225
+ ## License
226
+
227
+ Copyright (c) 2023 Andrew J. Peterson, dba NDP Software
228
+
229
+ Available for licensing at reasonable rate. Please contact NDP Software.