- commit
- 7fa7dd4
- parent
- bb40c09
- author
- CheddarCrisp
- date
- 2020-03-14 02:35:35 +0100 CET
Create UI to prompt for reload when an update is available
7 files changed,
+466,
-37
+348,
-22
1@@ -339,6 +339,16 @@
2 "integrity": "sha1-SCIQFAWCo2uDw+NC4c/ryqkkCUg=",
3 "dev": true
4 },
5+ "aggregate-error": {
6+ "version": "3.0.1",
7+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
8+ "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
9+ "dev": true,
10+ "requires": {
11+ "clean-stack": "^2.0.0",
12+ "indent-string": "^4.0.0"
13+ }
14+ },
15 "ajv": {
16 "version": "6.10.0",
17 "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
18@@ -1027,6 +1037,12 @@
19 }
20 }
21 },
22+ "clean-stack": {
23+ "version": "2.2.0",
24+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
25+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
26+ "dev": true
27+ },
28 "clean-webpack-plugin": {
29 "version": "3.0.0",
30 "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz",
31@@ -2330,6 +2346,15 @@
32 "readable-stream": "^2.0.0"
33 }
34 },
35+ "fs-minipass": {
36+ "version": "2.1.0",
37+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
38+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
39+ "dev": true,
40+ "requires": {
41+ "minipass": "^3.0.0"
42+ }
43+ },
44 "fs-write-stream-atomic": {
45 "version": "1.0.10",
46 "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
47@@ -3403,6 +3428,12 @@
48 "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
49 "dev": true
50 },
51+ "indent-string": {
52+ "version": "4.0.0",
53+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
54+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
55+ "dev": true
56+ },
57 "indexes-of": {
58 "version": "1.0.1",
59 "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
60@@ -3703,6 +3734,33 @@
61 "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
62 "dev": true
63 },
64+ "jest-worker": {
65+ "version": "25.1.0",
66+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz",
67+ "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==",
68+ "dev": true,
69+ "requires": {
70+ "merge-stream": "^2.0.0",
71+ "supports-color": "^7.0.0"
72+ },
73+ "dependencies": {
74+ "has-flag": {
75+ "version": "4.0.0",
76+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
77+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
78+ "dev": true
79+ },
80+ "supports-color": {
81+ "version": "7.1.0",
82+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
83+ "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
84+ "dev": true,
85+ "requires": {
86+ "has-flag": "^4.0.0"
87+ }
88+ }
89+ }
90+ },
91 "json-parse-better-errors": {
92 "version": "1.0.2",
93 "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
94@@ -3889,6 +3947,12 @@
95 "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
96 "dev": true
97 },
98+ "merge-stream": {
99+ "version": "2.0.0",
100+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
101+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
102+ "dev": true
103+ },
104 "methods": {
105 "version": "1.1.2",
106 "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
107@@ -3980,6 +4044,50 @@
108 "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
109 "dev": true
110 },
111+ "minipass": {
112+ "version": "3.1.1",
113+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz",
114+ "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==",
115+ "dev": true,
116+ "requires": {
117+ "yallist": "^4.0.0"
118+ },
119+ "dependencies": {
120+ "yallist": {
121+ "version": "4.0.0",
122+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
123+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
124+ "dev": true
125+ }
126+ }
127+ },
128+ "minipass-collect": {
129+ "version": "1.0.2",
130+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
131+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
132+ "dev": true,
133+ "requires": {
134+ "minipass": "^3.0.0"
135+ }
136+ },
137+ "minipass-flush": {
138+ "version": "1.0.5",
139+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
140+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
141+ "dev": true,
142+ "requires": {
143+ "minipass": "^3.0.0"
144+ }
145+ },
146+ "minipass-pipeline": {
147+ "version": "1.2.2",
148+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz",
149+ "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==",
150+ "dev": true,
151+ "requires": {
152+ "minipass": "^3.0.0"
153+ }
154+ },
155 "mississippi": {
156 "version": "3.0.0",
157 "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
158@@ -5225,15 +5333,6 @@
159 "send": "0.17.1"
160 }
161 },
162- "serviceworker-webpack-plugin": {
163- "version": "1.0.1",
164- "resolved": "https://registry.npmjs.org/serviceworker-webpack-plugin/-/serviceworker-webpack-plugin-1.0.1.tgz",
165- "integrity": "sha512-VgDEkZ3pA0HajsRaWtl5w6bLxAXx0Y+4dm7YeTcIxVmvC9YXvstex38HOBDuYETeDS5fUlBy/47gC0QYBrG0nw==",
166- "dev": true,
167- "requires": {
168- "minimatch": "^3.0.4"
169- }
170- },
171 "set-blocking": {
172 "version": "2.0.0",
173 "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
174@@ -5853,9 +5952,9 @@
175 "dev": true
176 },
177 "terser": {
178- "version": "4.6.3",
179- "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz",
180- "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==",
181+ "version": "4.6.6",
182+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.6.tgz",
183+ "integrity": "sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g==",
184 "dev": true,
185 "requires": {
186 "commander": "^2.20.0",
187@@ -5872,28 +5971,200 @@
188 }
189 },
190 "terser-webpack-plugin": {
191- "version": "1.4.3",
192- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
193- "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
194+ "version": "2.3.5",
195+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz",
196+ "integrity": "sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w==",
197 "dev": true,
198 "requires": {
199- "cacache": "^12.0.2",
200- "find-cache-dir": "^2.1.0",
201- "is-wsl": "^1.1.0",
202- "schema-utils": "^1.0.0",
203+ "cacache": "^13.0.1",
204+ "find-cache-dir": "^3.2.0",
205+ "jest-worker": "^25.1.0",
206+ "p-limit": "^2.2.2",
207+ "schema-utils": "^2.6.4",
208 "serialize-javascript": "^2.1.2",
209 "source-map": "^0.6.1",
210- "terser": "^4.1.2",
211- "webpack-sources": "^1.4.0",
212- "worker-farm": "^1.7.0"
213+ "terser": "^4.4.3",
214+ "webpack-sources": "^1.4.3"
215 },
216 "dependencies": {
217+ "ajv": {
218+ "version": "6.12.0",
219+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
220+ "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
221+ "dev": true,
222+ "requires": {
223+ "fast-deep-equal": "^3.1.1",
224+ "fast-json-stable-stringify": "^2.0.0",
225+ "json-schema-traverse": "^0.4.1",
226+ "uri-js": "^4.2.2"
227+ }
228+ },
229+ "ajv-keywords": {
230+ "version": "3.4.1",
231+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
232+ "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==",
233+ "dev": true
234+ },
235+ "cacache": {
236+ "version": "13.0.1",
237+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
238+ "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==",
239+ "dev": true,
240+ "requires": {
241+ "chownr": "^1.1.2",
242+ "figgy-pudding": "^3.5.1",
243+ "fs-minipass": "^2.0.0",
244+ "glob": "^7.1.4",
245+ "graceful-fs": "^4.2.2",
246+ "infer-owner": "^1.0.4",
247+ "lru-cache": "^5.1.1",
248+ "minipass": "^3.0.0",
249+ "minipass-collect": "^1.0.2",
250+ "minipass-flush": "^1.0.5",
251+ "minipass-pipeline": "^1.2.2",
252+ "mkdirp": "^0.5.1",
253+ "move-concurrently": "^1.0.1",
254+ "p-map": "^3.0.0",
255+ "promise-inflight": "^1.0.1",
256+ "rimraf": "^2.7.1",
257+ "ssri": "^7.0.0",
258+ "unique-filename": "^1.1.1"
259+ }
260+ },
261+ "fast-deep-equal": {
262+ "version": "3.1.1",
263+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
264+ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
265+ "dev": true
266+ },
267+ "find-cache-dir": {
268+ "version": "3.3.1",
269+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
270+ "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
271+ "dev": true,
272+ "requires": {
273+ "commondir": "^1.0.1",
274+ "make-dir": "^3.0.2",
275+ "pkg-dir": "^4.1.0"
276+ }
277+ },
278+ "find-up": {
279+ "version": "4.1.0",
280+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
281+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
282+ "dev": true,
283+ "requires": {
284+ "locate-path": "^5.0.0",
285+ "path-exists": "^4.0.0"
286+ }
287+ },
288+ "graceful-fs": {
289+ "version": "4.2.3",
290+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
291+ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
292+ "dev": true
293+ },
294+ "locate-path": {
295+ "version": "5.0.0",
296+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
297+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
298+ "dev": true,
299+ "requires": {
300+ "p-locate": "^4.1.0"
301+ }
302+ },
303+ "make-dir": {
304+ "version": "3.0.2",
305+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz",
306+ "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==",
307+ "dev": true,
308+ "requires": {
309+ "semver": "^6.0.0"
310+ }
311+ },
312+ "p-limit": {
313+ "version": "2.2.2",
314+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
315+ "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
316+ "dev": true,
317+ "requires": {
318+ "p-try": "^2.0.0"
319+ }
320+ },
321+ "p-locate": {
322+ "version": "4.1.0",
323+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
324+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
325+ "dev": true,
326+ "requires": {
327+ "p-limit": "^2.2.0"
328+ }
329+ },
330+ "p-map": {
331+ "version": "3.0.0",
332+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
333+ "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
334+ "dev": true,
335+ "requires": {
336+ "aggregate-error": "^3.0.0"
337+ }
338+ },
339+ "path-exists": {
340+ "version": "4.0.0",
341+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
342+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
343+ "dev": true
344+ },
345+ "pkg-dir": {
346+ "version": "4.2.0",
347+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
348+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
349+ "dev": true,
350+ "requires": {
351+ "find-up": "^4.0.0"
352+ }
353+ },
354+ "rimraf": {
355+ "version": "2.7.1",
356+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
357+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
358+ "dev": true,
359+ "requires": {
360+ "glob": "^7.1.3"
361+ }
362+ },
363+ "schema-utils": {
364+ "version": "2.6.5",
365+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz",
366+ "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==",
367+ "dev": true,
368+ "requires": {
369+ "ajv": "^6.12.0",
370+ "ajv-keywords": "^3.4.1"
371+ }
372+ },
373+ "semver": {
374+ "version": "6.3.0",
375+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
376+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
377+ "dev": true
378+ },
379 "source-map": {
380 "version": "0.6.1",
381 "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
382 "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
383 "dev": true
384 },
385+ "ssri": {
386+ "version": "7.1.0",
387+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz",
388+ "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==",
389+ "dev": true,
390+ "requires": {
391+ "figgy-pudding": "^3.5.1",
392+ "minipass": "^3.1.1"
393+ }
394+ },
395 "webpack-sources": {
396 "version": "1.4.3",
397 "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
398@@ -6306,6 +6577,43 @@
399 "terser-webpack-plugin": "^1.1.0",
400 "watchpack": "^1.5.0",
401 "webpack-sources": "^1.3.0"
402+ },
403+ "dependencies": {
404+ "source-map": {
405+ "version": "0.6.1",
406+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
407+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
408+ "dev": true
409+ },
410+ "terser-webpack-plugin": {
411+ "version": "1.4.3",
412+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz",
413+ "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
414+ "dev": true,
415+ "requires": {
416+ "cacache": "^12.0.2",
417+ "find-cache-dir": "^2.1.0",
418+ "is-wsl": "^1.1.0",
419+ "schema-utils": "^1.0.0",
420+ "serialize-javascript": "^2.1.2",
421+ "source-map": "^0.6.1",
422+ "terser": "^4.1.2",
423+ "webpack-sources": "^1.4.0",
424+ "worker-farm": "^1.7.0"
425+ },
426+ "dependencies": {
427+ "webpack-sources": {
428+ "version": "1.4.3",
429+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
430+ "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
431+ "dev": true,
432+ "requires": {
433+ "source-list-map": "^2.0.0",
434+ "source-map": "~0.6.1"
435+ }
436+ }
437+ }
438+ }
439 }
440 },
441 "webpack-cli": {
442@@ -6514,6 +6822,15 @@
443 "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
444 "dev": true
445 },
446+ "workbox-broadcast-update": {
447+ "version": "5.0.0",
448+ "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-5.0.0.tgz",
449+ "integrity": "sha512-6iA/ubUoGLdyvQh6/RBCKbl/ghzl/bSjz6tVvzJKKYKQRHMQs4OeZCud81PTYynFq3AWaGaMp/KDZhhycjH39Q==",
450+ "dev": true,
451+ "requires": {
452+ "workbox-core": "^5.0.0"
453+ }
454+ },
455 "workbox-cacheable-response": {
456 "version": "5.0.0",
457 "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-5.0.0.tgz",
458@@ -6557,6 +6874,15 @@
459 "workbox-routing": "^5.0.0"
460 }
461 },
462+ "workbox-window": {
463+ "version": "5.0.0",
464+ "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-5.0.0.tgz",
465+ "integrity": "sha512-zowcWjR+fpjgAU9vu+0QZNEY2biecPxY7M5qn9Ki7UA3p1CCl7aIF0/itCN9H4AJ3CP/Ohbd6dxE7MnuDkPceA==",
466+ "dev": true,
467+ "requires": {
468+ "workbox-core": "^5.0.0"
469+ }
470+ },
471 "worker-farm": {
472 "version": "1.7.0",
473 "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+4,
-2
1@@ -22,20 +22,22 @@
2 "html-webpack-plugin": "^3.2.0",
3 "idb-keyval": "^3.2.0",
4 "reset-css": "^5.0.1",
5- "serviceworker-webpack-plugin": "^1.0.1",
6 "string-replace-loader": "^2.2.0",
7 "style-loader": "^1.1.3",
8 "svelte": "^3.4.1",
9 "svelte-loader": "^2.13.4",
10+ "terser-webpack-plugin": "^2.3.5",
11 "uuid": "^3.4.0",
12 "webpack": "^4.31.0",
13 "webpack-cli": "^3.3.2",
14 "webpack-dev-server": "^3.4.1",
15 "webpack-license-plugin": "^4.1.1",
16 "webpack-merge": "^4.2.2",
17+ "workbox-broadcast-update": "^5.0.0",
18 "workbox-cacheable-response": "^5.0.0",
19 "workbox-expiration": "^5.0.0",
20 "workbox-routing": "^5.0.0",
21- "workbox-strategies": "^5.0.0"
22+ "workbox-strategies": "^5.0.0",
23+ "workbox-window": "^5.0.0"
24 }
25 }
+12,
-4
1@@ -1,10 +1,18 @@
2 import App from './ncounter/App.svelte';
3-import runtime from 'serviceworker-webpack-plugin/lib/runtime';
4 import 'reset-css/reset.css';
5 import './ncounter/site.css';
6+import {Workbox} from 'workbox-window/Workbox.mjs';
7+
8+const app = new App({ target: document.body });
9
10 if ('serviceWorker' in navigator) {
11- const registration = runtime.register();
12-}
13+ const wb = new Workbox('sw.js');
14+
15+ wb.addEventListener('message', async (event) => {
16+ if (event.data.type === 'CACHE_UPDATED') {
17+ app.SetUpdateAvailable();
18+ }
19+ });
20
21-new App({ target: document.body });
22+ wb.register();
23+}
+80,
-1
1@@ -4,8 +4,16 @@
2 <Counter counterId={ counter.id }></Counter>
3 {/each}
4 </div>
5+ {#if showUpdateMessage}
6+ <div class="update-message">
7+ An update is available. <button class="reload" on:click="{ () => { window.location.reload(); } }">Load now</button><button class="later" on:click="{ () => { showUpdateMessage = false; } }">Later</button>
8+ </div>
9+ {/if}
10 <div class="tool-bar">
11 <button class="add" on:click="{ showAdd }"><i class="material-icons">add</i></button>
12+ {#if updateAvailable}<button class="update"
13+ class:animate="{!ignoreUpdate}"
14+ on:click={() => { ignoreUpdate = true; showUpdateMessage = !showUpdateMessage; }}><i class="material-icons">arrow_upward</i></button>{/if}
15 <button class="about" on:click="{ () => { showAbout = true; } }">?</button>
16 </div>
17 </div>
18@@ -36,6 +44,10 @@ let showAbout = false;
19 let newCounter = null;
20 let dialogForm = null;
21
22+let updateAvailable = false;
23+let ignoreUpdate = false;
24+let showUpdateMessage = false;
25+
26 function focus(node){
27 node.focus();
28 }
29@@ -68,6 +80,10 @@ function add(){
30
31 showAddDialog = false;
32 }
33+
34+export function SetUpdateAvailable(){
35+ updateAvailable = true;
36+}
37 </script>
38 <style lang="scss">
39 .app {
40@@ -117,8 +133,71 @@ function add(){
41 border: 2px solid var(--highlight-color);
42 }
43
44+ .add {
45+ margin-right: auto;
46+ }
47+
48+ @keyframes pulse {
49+ 0% {
50+ -webkit-text-stroke: 0 rgba(204, 204, 0, 0);
51+ }
52+
53+ 15% {
54+ -webkit-text-stroke: 3px rgba(204, 204, 0, 1);
55+ }
56+
57+ 30% {
58+ -webkit-text-stroke: 0 rgba(204, 204, 0, 0);
59+ }
60+ }
61+
62+ .update {
63+ margin-right: 10px;
64+ }
65+
66+ .update.animate {
67+ animation-name: pulse;
68+ animation-duration: 5s;
69+ animation-iteration-count: infinite;
70+ }
71+
72 .about {
73- margin-left: auto;
74 font-size: 20px;
75 }
76+
77+ .update-message {
78+ display: flex;
79+ align-items: center;
80+
81+ padding: 12px;
82+
83+ background-color: var(--background-primary);
84+ color: var(--text-primary);
85+
86+ box-shadow: 0 -1px 3px rgba(0,0,0,0.12), 0 -1px 2px rgba(0,0,0,0.24);
87+ }
88+
89+ .update-message > button {
90+ width: auto;
91+ height: 24px;
92+ font-size: 16px;
93+ }
94+
95+ @media(hover: hover){
96+ .update-message > button:hover {
97+ outline: 2px solid var(--button-color);
98+ }
99+ }
100+
101+ .update-message > button:focus {
102+ outline: 2px solid var(--button-color);
103+ }
104+
105+ .reload {
106+ margin-left: auto;
107+ }
108+
109+ .later {
110+ margin-left: 16px;
111+ }
112 </style>
+4,
-0
1@@ -2,6 +2,7 @@ import {registerRoute,setDefaultHandler} from 'workbox-routing';
2 import {CacheFirst, StaleWhileRevalidate, NetworkFirst} from 'workbox-strategies';
3 import {CacheableResponsePlugin} from 'workbox-cacheable-response';
4 import {ExpirationPlugin} from 'workbox-expiration';
5+import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';
6
7 // Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
8 registerRoute(
9@@ -32,6 +33,9 @@ registerRoute(
10 /\.(?:js|css|png)$/,
11 new StaleWhileRevalidate({
12 cacheName: 'static-resources',
13+ plugins: [
14+ new BroadcastUpdatePlugin(),
15+ ],
16 })
17 );
18
+6,
-8
1@@ -2,7 +2,6 @@ const path = require('path');
2 const HtmlWebpackPlugin = require('html-webpack-plugin');
3 const GoogleFontsPlugin = require('@beyonk/google-fonts-webpack-plugin');
4 const { CleanWebpackPlugin } = require('clean-webpack-plugin');
5-const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');
6 const LicensePlugin = require('webpack-license-plugin');
7 const CopyWebpackPlugin = require('copy-webpack-plugin');
8
9@@ -11,11 +10,14 @@ const year = now.getFullYear().toString();
10 const releaseDate = now.getFullYear() + "-" + (now.getMonth() + 1).toString().padStart(2, '0') + "-" + now.getDate().toString().padStart(2, '0');
11
12 module.exports = {
13- entry: './src/index.js',
14+ entry: {
15+ index: './src/index.js',
16+ sw: './src/sw.js'
17+ },
18 plugins: [
19 new CleanWebpackPlugin(),
20 new HtmlWebpackPlugin({
21- title: 'NCounter',
22+ excludeChunks: ['sw'],
23 template: 'src/index.html'
24 }),
25 new GoogleFontsPlugin({
26@@ -24,10 +26,6 @@ module.exports = {
27 ],
28 local: false
29 }),
30- new ServiceWorkerWebpackPlugin({
31- entry: path.join(__dirname, 'src/sw.js'),
32- publicPath: './'
33- }),
34 new LicensePlugin(),
35 new CopyWebpackPlugin([
36 {
37@@ -48,7 +46,7 @@ module.exports = {
38 ])
39 ],
40 output: {
41- filename: 'index.js',
42+ filename: '[name].js',
43 path: path.resolve(__dirname, 'dist')
44 },
45 module: {
+12,
-0
1@@ -1,6 +1,18 @@
2+const webpack = require('webpack');
3 const merge = require('webpack-merge');
4 const common = require('./webpack.common.js');
5+const Terser = require('terser-webpack-plugin');
6
7 module.exports = merge(common, {
8 mode: 'production',
9+ plugins: [
10+ new webpack.DefinePlugin({
11+ 'process.env.NODE_ENV': JSON.stringify('production'),
12+ }),
13+ ],
14+ optimization:{
15+ minimizer: [new Terser({
16+ test: /\.m?js$/,
17+ })]
18+ }
19 });