textbrowser 0.47.0 → 0.48.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/.eslintignore +2 -1
- package/.eslintrc.cjs +3 -1
- package/CHANGES.md +11 -0
- package/README.md +2 -6
- package/dist/WorkInfo-es.js +978 -345
- package/dist/activateCallback-es.js +6 -2
- package/dist/assets/index-_11XnUty.css +9 -0
- package/dist/assets/languages-1sAACTKG.json +67 -0
- package/dist/index-es.js +2738 -1134
- package/dist/index-es.min.js +4 -4
- package/dist/sw-helper.js +314 -0
- package/index.html +2 -0
- package/package.json +46 -45
- package/resources/activateCallback.js +6 -2
- package/resources/index.js +6 -14
- package/resources/resultsDisplay.js +49 -40
- package/resources/templates/languageSelect.js +3 -3
- package/resources/templates/resultsDisplayServerOrClient.js +76 -65
- package/resources/templates/workDisplay.js +123 -103
- package/resources/templates/workSelect.js +4 -4
- package/resources/utils/IntlURLSearchParams.js +4 -1
- package/resources/utils/Languages.js +6 -1
- package/resources/utils/Metadata.js +22 -21
- package/resources/utils/Plugin.js +4 -4
- package/resources/utils/ServiceWorker.js +21 -14
- package/resources/utils/WorkInfo.js +10 -5
- package/resources/utils/dialogs.js +2 -1
- package/resources/utils/getLocaleFallbackResults.js +6 -3
- package/resources/utils/sanitize.js +3 -3
- package/resources/workDisplay.js +13 -14
- package/resources/workSelect.js +3 -2
- package/server/main.js +6 -5
- package/sw-sample.js +5 -307
- package/dist/index-umd.js +0 -18864
- package/dist/index-umd.min.js +0 -19
|
@@ -3,7 +3,12 @@ import {i18n} from 'intl-dom';
|
|
|
3
3
|
import {getMetaProp, getMetadata, Metadata} from './Metadata.js';
|
|
4
4
|
import {PluginsForWork, escapePlugin} from './Plugin.js';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Imported by the `dist/sw-helper.js`
|
|
8
|
+
* @param {string} files The files.json file path
|
|
9
|
+
* @returns {PlainObject}
|
|
10
|
+
*/
|
|
11
|
+
export const getWorkFiles = async function getWorkFiles (files) {
|
|
7
12
|
const filesObj = await getJSON(files);
|
|
8
13
|
const dataFiles = [];
|
|
9
14
|
filesObj.groups.forEach((fileGroup) => {
|
|
@@ -62,9 +67,9 @@ export const getWorkData = async function ({
|
|
|
62
67
|
|
|
63
68
|
let fileData;
|
|
64
69
|
const fileGroup = filesObj.groups.find((fg) => {
|
|
65
|
-
fileData = fg.files.find((file) =>
|
|
66
|
-
work === workI18n(['workNames', fg.id, file.name])
|
|
67
|
-
);
|
|
70
|
+
fileData = fg.files.find((file) => {
|
|
71
|
+
return work === workI18n(['workNames', fg.id, file.name]);
|
|
72
|
+
});
|
|
68
73
|
return Boolean(fileData);
|
|
69
74
|
});
|
|
70
75
|
// This is not specific to the work, but we export it anyways
|
|
@@ -173,7 +178,7 @@ export const getWorkData = async function ({
|
|
|
173
178
|
console.log('pluginsForWork', pluginsForWork);
|
|
174
179
|
const {lang, namespace} = this; // array with first item as preferred
|
|
175
180
|
pluginsForWork.iterateMappings(({
|
|
176
|
-
plugin,
|
|
181
|
+
// plugin,
|
|
177
182
|
pluginName, pluginLang,
|
|
178
183
|
onByDefaultDefault,
|
|
179
184
|
placement, applicableFields, meta
|
|
@@ -63,6 +63,7 @@ class Dialog {
|
|
|
63
63
|
return dialog;
|
|
64
64
|
}
|
|
65
65
|
makeCancelDialog ({
|
|
66
|
+
// eslint-disable-next-line no-unused-vars -- Discarding
|
|
66
67
|
submit, // Don't pass this on to `args` if present
|
|
67
68
|
cancel,
|
|
68
69
|
cancelClass = 'cancel', submitClass = 'submit',
|
|
@@ -94,7 +95,7 @@ class Dialog {
|
|
|
94
95
|
message: msg,
|
|
95
96
|
submitClass = 'submit'
|
|
96
97
|
} = message;
|
|
97
|
-
return new Promise((resolve
|
|
98
|
+
return new Promise((resolve) => {
|
|
98
99
|
const dialog = /** @type {HTMLDialogElement} */ (jml('dialog', [
|
|
99
100
|
msg,
|
|
100
101
|
...(includeOk
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Note that this should be kept as a polyglot client-server file.
|
|
3
|
+
*/
|
|
1
4
|
import {i18n} from 'intl-dom';
|
|
2
5
|
|
|
3
6
|
export default async function getLocaleFallbackResults ({
|
|
@@ -14,9 +17,9 @@ export default async function getLocaleFallbackResults ({
|
|
|
14
17
|
// `$ref` (as with <https://github.com/whitlockjc/json-refs>) and
|
|
15
18
|
// replace `loadLocales` behavior with our own now resolved
|
|
16
19
|
// locales; see https://github.com/jdorn/json-editor/issues/132
|
|
17
|
-
return basePath + (langData.localeFileBasePath) + langs.find((l) =>
|
|
18
|
-
l.code === code
|
|
19
|
-
).locale.$ref;
|
|
20
|
+
return basePath + (langData.localeFileBasePath) + langs.find((l) => {
|
|
21
|
+
return l.code === code;
|
|
22
|
+
}).locale.$ref;
|
|
20
23
|
}
|
|
21
24
|
});
|
|
22
25
|
if (!$p.l10n) {
|
package/resources/workDisplay.js
CHANGED
|
@@ -31,15 +31,15 @@ export default async function workDisplay ({
|
|
|
31
31
|
);
|
|
32
32
|
|
|
33
33
|
async function _displayWork ({
|
|
34
|
-
workI18n, metadataObj, getFieldAliasOrName,
|
|
34
|
+
workI18n, metadataObj, getFieldAliasOrName, schemaItems, // schemaObj,
|
|
35
35
|
fieldInfo, metadata, pluginsForWork, groupsToWorks
|
|
36
36
|
}) {
|
|
37
37
|
const lParam = localizeParamNames
|
|
38
|
-
? key => l(['params', key])
|
|
39
|
-
: key => key;
|
|
38
|
+
? (key) => l(['params', key])
|
|
39
|
+
: (key) => key;
|
|
40
40
|
const lIndexedParam = localizeParamNames
|
|
41
|
-
? key => l(['params', 'indexed', key])
|
|
42
|
-
: key => key;
|
|
41
|
+
? (key) => l(['params', 'indexed', key])
|
|
42
|
+
: (key) => key;
|
|
43
43
|
|
|
44
44
|
// Returns element with localized option text (as Jamilih), with
|
|
45
45
|
// optional fallback direction
|
|
@@ -56,15 +56,14 @@ export default async function workDisplay ({
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
// Returns plain text node or element (as Jamilih) with fallback direction
|
|
59
|
-
const lDirectional = (key, substitutions) =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
);
|
|
59
|
+
const lDirectional = (key, substitutions) => l(
|
|
60
|
+
key,
|
|
61
|
+
substitutions
|
|
62
|
+
// formats
|
|
63
|
+
// Restore if `intl-dom` supports
|
|
64
|
+
// fallback: ({message}) =>
|
|
65
|
+
// Templates.workDisplay.bdo({fallbackDirection, message})
|
|
66
|
+
);
|
|
68
67
|
|
|
69
68
|
const fieldMatchesLocale = metadata.getFieldMatchesLocale({
|
|
70
69
|
namespace: this.namespace,
|
package/resources/workSelect.js
CHANGED
|
@@ -19,8 +19,9 @@ export default async function workSelect ({
|
|
|
19
19
|
const metadataObjs = await getJSON(works.groups.reduce((arr, fileGroup) => {
|
|
20
20
|
const metadataBaseDir = (works.metadataBaseDirectory || '') +
|
|
21
21
|
(fileGroup.metadataBaseDirectory || '') + '/';
|
|
22
|
-
return fileGroup.files.reduce((ar, fileData) =>
|
|
23
|
-
|
|
22
|
+
return fileGroup.files.reduce((ar, fileData) => [
|
|
23
|
+
...ar, metadataBaseDir + fileData.metadataFile
|
|
24
|
+
],
|
|
24
25
|
arr);
|
|
25
26
|
}, []));
|
|
26
27
|
|
package/server/main.js
CHANGED
|
@@ -7,7 +7,7 @@ import statik from '@brettz9/node-static';
|
|
|
7
7
|
import fetch from 'node-fetch';
|
|
8
8
|
import commandLineArgs from 'command-line-args';
|
|
9
9
|
import DOMParser from 'dom-parser';
|
|
10
|
-
import setGlobalVars from 'indexeddbshim/dist/indexeddbshim-UnicodeIdentifiers-node.
|
|
10
|
+
import setGlobalVars from 'indexeddbshim/dist/indexeddbshim-UnicodeIdentifiers-node.cjs';
|
|
11
11
|
import {getJSON} from 'simple-get-json';
|
|
12
12
|
import {setFetch} from 'intl-dom';
|
|
13
13
|
|
|
@@ -15,7 +15,6 @@ import IntlURLSearchParams from '../resources/utils/IntlURLSearchParams.js';
|
|
|
15
15
|
import {resultsDisplayServer} from '../resources/resultsDisplay.js';
|
|
16
16
|
import getLocaleFallbackResults from '../resources/utils/getLocaleFallbackResults.js';
|
|
17
17
|
import {setServiceWorkerDefaults} from '../resources/utils/ServiceWorker.js';
|
|
18
|
-
// import setGlobalVars from 'indexeddbshim/src/node-UnicodeIdentifiers.js';
|
|
19
18
|
import {Languages} from '../resources/utils/Languages.js';
|
|
20
19
|
import activateCallback from '../resources/activateCallback.js';
|
|
21
20
|
|
|
@@ -139,9 +138,11 @@ const srv = http.createServer(async (req, res) => {
|
|
|
139
138
|
res,
|
|
140
139
|
// For express, we'll first give a chance to other static servers
|
|
141
140
|
// they might supply
|
|
142
|
-
userParams.expressServer
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
userParams.expressServer
|
|
142
|
+
? () => {
|
|
143
|
+
// Empty
|
|
144
|
+
}
|
|
145
|
+
: next
|
|
145
146
|
);
|
|
146
147
|
};
|
|
147
148
|
if (userParams.expressServer) {
|
package/sw-sample.js
CHANGED
|
@@ -1,310 +1,8 @@
|
|
|
1
|
-
/* eslint-env
|
|
1
|
+
/* eslint-env serviceworker -- Service worker */
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import activateCallback from './node_modules/textbrowser/dist/activateCallback-es.js';
|
|
5
|
-
import {getWorkFiles} from './node_modules/textbrowser/dist/WorkInfo-es.js';
|
|
3
|
+
import swHelper from './node_modules/textbrowser/dist/sw-helper.js';
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
const minutes = 60 * 1000;
|
|
5
|
+
// IMPORTANT: Keep this comment and increment this number to trigger
|
|
6
|
+
// a worker change: 1
|
|
11
7
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
// Utilities
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {PlainObject} args
|
|
19
|
-
* @param {"log"|"error"|"beginInstall"|"finishedInstall"|"beginActivate"|"finishedActivate"} args.type
|
|
20
|
-
* @param {string} [args.message=type]
|
|
21
|
-
* @returns {Promise<void>}
|
|
22
|
-
*/
|
|
23
|
-
async function post ({type, message = type}) {
|
|
24
|
-
const clients = await self.clients.matchAll({
|
|
25
|
-
// Are there any uncontrolled within activate anyways?
|
|
26
|
-
includeUncontrolled: true,
|
|
27
|
-
type: 'window'
|
|
28
|
-
}) || [];
|
|
29
|
-
if (message.includes('Posting finished')) {
|
|
30
|
-
message += ` (count: ${clients.length})`;
|
|
31
|
-
}
|
|
32
|
-
clients.forEach((client) => {
|
|
33
|
-
// Although we only need one client to which to send
|
|
34
|
-
// arguments, we want to signal phase complete to all
|
|
35
|
-
// eslint-disable-next-line unicorn/require-post-message-target-origin -- In worker
|
|
36
|
-
client.postMessage({message, type});
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
* @param {string[]} messages
|
|
43
|
-
* @returns {Promise<void>}
|
|
44
|
-
*/
|
|
45
|
-
function log (...messages) {
|
|
46
|
-
const message = messages.join(' ');
|
|
47
|
-
console.log(message);
|
|
48
|
-
return post({message, type: 'log'});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
*
|
|
53
|
-
* @param {Error} error
|
|
54
|
-
* @param {string[]} messages
|
|
55
|
-
* @returns {Promise<void>}
|
|
56
|
-
*/
|
|
57
|
-
function logError (error, ...messages) {
|
|
58
|
-
const message = messages.join(' ');
|
|
59
|
-
console.error(error, message);
|
|
60
|
-
return post({message, errorType: error.type, name: error.name, type: 'error'});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @callback DelayCallback
|
|
65
|
-
* @param {Float} time
|
|
66
|
-
* @returns {void}
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
*
|
|
71
|
-
* @param {DelayCallback} cb
|
|
72
|
-
* @param {PositiveInteger} timeout
|
|
73
|
-
* @param {string} errMessage
|
|
74
|
-
* @param {PositiveInteger} [time=0]
|
|
75
|
-
* @returns {Promise<void>}
|
|
76
|
-
*/
|
|
77
|
-
async function tryAndRetry (cb, timeout, errMessage, time = 0) {
|
|
78
|
-
time++;
|
|
79
|
-
try {
|
|
80
|
-
// eslint-disable-next-line n/callback-return
|
|
81
|
-
await cb(time);
|
|
82
|
-
return undefined;
|
|
83
|
-
} catch (err) {
|
|
84
|
-
console.log('errrr', err);
|
|
85
|
-
logError(err, err.message || errMessage);
|
|
86
|
-
return new Promise((resolve, reject) => {
|
|
87
|
-
setTimeout(() => {
|
|
88
|
-
resolve(tryAndRetry(cb, timeout, errMessage, time));
|
|
89
|
-
}, timeout);
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* @typedef {PlainObject} ConfigObject
|
|
96
|
-
* @property {string} namespace
|
|
97
|
-
* @property {string} basePath
|
|
98
|
-
* @property {string} languages
|
|
99
|
-
* @property {string} files
|
|
100
|
-
* @property {string[]} userStaticFiles
|
|
101
|
-
*/
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
*
|
|
105
|
-
* @param {ConfigObject} args
|
|
106
|
-
* @returns {ConfigObject}
|
|
107
|
-
* @todo Since some of these reused, move to external file (or
|
|
108
|
-
* use `setServiceWorkerDefaults`?)
|
|
109
|
-
*/
|
|
110
|
-
function getConfigDefaults (args) {
|
|
111
|
-
return {
|
|
112
|
-
namespace: 'textbrowser',
|
|
113
|
-
basePath: '',
|
|
114
|
-
languages: new URL(
|
|
115
|
-
'../appdata/languages.json',
|
|
116
|
-
// Todo: Substitute with `import.meta.url` once implemented in
|
|
117
|
-
// service workers
|
|
118
|
-
new URL('node_modules/textbrowser/resources/index.js', location)
|
|
119
|
-
).href,
|
|
120
|
-
files: 'files.json',
|
|
121
|
-
userStaticFiles: defaultUserStaticFiles,
|
|
122
|
-
// Opportunity to override
|
|
123
|
-
...args
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const defaultUserStaticFiles = [
|
|
128
|
-
'/', // Needs a separate entry from `index.html` (at least in Chrome)
|
|
129
|
-
'index.html',
|
|
130
|
-
'files.json',
|
|
131
|
-
'site.json',
|
|
132
|
-
'resources/user.js'
|
|
133
|
-
// We do not put the user.json here as that is obtained live with this
|
|
134
|
-
// service worker via `pathToUserJSON`
|
|
135
|
-
];
|
|
136
|
-
// Todo: We could supply `new URL(fileName, moduleURL).href` to
|
|
137
|
-
// get these as reliable full paths without hard-coding or needing to
|
|
138
|
-
// actually be in `node_modules/textbrowser`; see `resources/index.js`
|
|
139
|
-
const textbrowserStaticResourceFiles = [
|
|
140
|
-
'node_modules/textbrowser/appdata/languages.json',
|
|
141
|
-
|
|
142
|
-
/*
|
|
143
|
-
// Only needed atm for browser validation
|
|
144
|
-
'node_modules/textbrowser/general-schemas/files.jsonschema',
|
|
145
|
-
'node_modules/textbrowser/general-schemas/languages.jsonschema',
|
|
146
|
-
'node_modules/textbrowser-data-schemas/schemas/locale.jsonschema',
|
|
147
|
-
'node_modules/textbrowser-data-schemas/schemas/metadata.jsonschema',
|
|
148
|
-
'node_modules/textbrowser-data-schemas/schemas/table.jsonschema', // Not currently using for validation or meta-data
|
|
149
|
-
*/
|
|
150
|
-
|
|
151
|
-
'node_modules/textbrowser/dist/index-es.js'
|
|
152
|
-
];
|
|
153
|
-
|
|
154
|
-
const params = new URL(location).searchParams;
|
|
155
|
-
const pathToUserJSON = params.get('pathToUserJSON');
|
|
156
|
-
const stylesheets = JSON.parse(params.get('stylesheets') || []);
|
|
157
|
-
|
|
158
|
-
console.log('sw info', pathToUserJSON);
|
|
159
|
-
console.log('sw stylesheets', stylesheets);
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
*
|
|
163
|
-
* @param {PositiveInteger} time
|
|
164
|
-
* @throws {Error} (This is actually caught internally.)
|
|
165
|
-
* @returns {Promise<void>}
|
|
166
|
-
*/
|
|
167
|
-
async function install (time) {
|
|
168
|
-
post({type: 'beginInstall'});
|
|
169
|
-
log(`Install: Trying, attempt ${time}`);
|
|
170
|
-
const now = Date.now();
|
|
171
|
-
const response = await fetch(pathToUserJSON);
|
|
172
|
-
const json = await response.json();
|
|
173
|
-
|
|
174
|
-
const {
|
|
175
|
-
namespace, languages, files, userStaticFiles
|
|
176
|
-
} = getConfigDefaults(json);
|
|
177
|
-
|
|
178
|
-
const {version} = await getJSON('./package.json');
|
|
179
|
-
|
|
180
|
-
console.log('opening cache', namespace + CURRENT_CACHES.prefetch + version);
|
|
181
|
-
const [
|
|
182
|
-
cache,
|
|
183
|
-
userDataFiles,
|
|
184
|
-
{languages: langs}
|
|
185
|
-
] = await Promise.all([
|
|
186
|
-
caches.open(namespace + CURRENT_CACHES.prefetch + version),
|
|
187
|
-
getWorkFiles(files),
|
|
188
|
-
getJSON(languages)
|
|
189
|
-
]);
|
|
190
|
-
log('Install: Retrieved dependency values');
|
|
191
|
-
|
|
192
|
-
const langPathParts = languages.split('/');
|
|
193
|
-
|
|
194
|
-
// Todo: Ought to make these locales only conditionally required and
|
|
195
|
-
// then only show those specified in languages menu or go directly
|
|
196
|
-
// to work selection
|
|
197
|
-
// Todo: We might give option to only download
|
|
198
|
-
// one locale and avoid language splash page
|
|
199
|
-
const localeFiles = langs.map(
|
|
200
|
-
({locale: {$ref}}) => {
|
|
201
|
-
return (langPathParts.length > 1
|
|
202
|
-
? langPathParts.slice(0, -1).join('/') + '/'
|
|
203
|
-
: ''
|
|
204
|
-
) + $ref;
|
|
205
|
-
}
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
const urlsToPrefetch = [
|
|
209
|
-
...textbrowserStaticResourceFiles,
|
|
210
|
-
...localeFiles,
|
|
211
|
-
...userStaticFiles,
|
|
212
|
-
...userDataFiles,
|
|
213
|
-
...stylesheets
|
|
214
|
-
];
|
|
215
|
-
// .map((url) => url === 'index.html' ? new Request(url, {cache: 'reload'}) : url)
|
|
216
|
-
try {
|
|
217
|
-
const cachePromises = urlsToPrefetch.map(async (urlToPrefetch) => {
|
|
218
|
-
// This constructs a new URL object using the service worker's script location as the base
|
|
219
|
-
// for relative URLs.
|
|
220
|
-
const url = new URL(urlToPrefetch, location.href);
|
|
221
|
-
url.search += (url.search ? '&' : '?') + 'cache-bust=' + now;
|
|
222
|
-
const request = new Request(url, {mode: 'no-cors'});
|
|
223
|
-
try {
|
|
224
|
-
const response = await fetch(request);
|
|
225
|
-
if (response.status >= 400) {
|
|
226
|
-
throw new Error('request for ' + urlToPrefetch +
|
|
227
|
-
' failed with status ' + response.statusText);
|
|
228
|
-
}
|
|
229
|
-
return cache.put(urlToPrefetch, response);
|
|
230
|
-
} catch (error) {
|
|
231
|
-
logError(error, 'Not caching ' + urlToPrefetch + ' due to ' + error);
|
|
232
|
-
throw error;
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
await Promise.all(cachePromises);
|
|
236
|
-
log('Install: Pre-fetching complete.');
|
|
237
|
-
} catch (error) {
|
|
238
|
-
logError(error, `Install: Pre-fetching failed: ${error}`);
|
|
239
|
-
// Failing gives chance for a new client to re-trigger install?
|
|
240
|
-
throw error;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// An install update event will not be reported until controlled,
|
|
244
|
-
// so we need to inform the clients
|
|
245
|
-
log(`Install: Posting finished message to clients`);
|
|
246
|
-
|
|
247
|
-
// Although we only need one client to which to send
|
|
248
|
-
// arguments, we want to signal phase complete to all
|
|
249
|
-
post({type: 'finishedInstall'});
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
*
|
|
254
|
-
* @param {PositiveInteger} time
|
|
255
|
-
* @returns {Promise<void>}
|
|
256
|
-
*/
|
|
257
|
-
async function activate (time) {
|
|
258
|
-
post({type: 'beginActivate'});
|
|
259
|
-
log(`Activate: Trying, attempt ${time}`);
|
|
260
|
-
const [json, cacheNames] = await Promise.all([
|
|
261
|
-
(await fetch(pathToUserJSON)).json(),
|
|
262
|
-
caches.keys()
|
|
263
|
-
]);
|
|
264
|
-
const {namespace, files, basePath} = getConfigDefaults(json);
|
|
265
|
-
const {version} = await getJSON('./package.json');
|
|
266
|
-
|
|
267
|
-
const expectedCacheNames = Object.values(CURRENT_CACHES).map((n) => namespace + n + version);
|
|
268
|
-
cacheNames.map(async (cacheName) => {
|
|
269
|
-
if (!expectedCacheNames.includes(cacheName)) {
|
|
270
|
-
log('Activate: Deleting out of date cache:', cacheName);
|
|
271
|
-
await caches.delete(cacheName);
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
await activateCallback({namespace, files, basePath, log});
|
|
276
|
-
log('Activate: Database changes completed');
|
|
277
|
-
|
|
278
|
-
log(`Activate: Posting finished message to clients`);
|
|
279
|
-
// Signal phase complete to all clients
|
|
280
|
-
post({type: 'finishedActivate'});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
self.addEventListener('install', (e) => {
|
|
284
|
-
e.waitUntil(tryAndRetry(install, 5 * minutes, 'Error installing'));
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
self.addEventListener('activate', (e) => {
|
|
288
|
-
// Erring is of no present use here:
|
|
289
|
-
// https://github.com/w3c/ServiceWorker/issues/659#issuecomment-384919053
|
|
290
|
-
e.waitUntil(tryAndRetry(activate, 5 * minutes, 'Error activating'));
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
// We cannot make this async as `e.respondWith` must be called synchronously
|
|
294
|
-
self.addEventListener('fetch', (e) => {
|
|
295
|
-
// DevTools opening will trigger these o-i-c requests
|
|
296
|
-
const {request} = e;
|
|
297
|
-
const {cache, mode, url} = request;
|
|
298
|
-
if (cache === 'only-if-cached' &&
|
|
299
|
-
mode !== 'same-origin') {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
console.log('fetching', url);
|
|
303
|
-
e.respondWith((async () => {
|
|
304
|
-
const cached = await caches.match(request);
|
|
305
|
-
if (!cached) {
|
|
306
|
-
console.log('no cached found', url);
|
|
307
|
-
}
|
|
308
|
-
return cached || fetch(request);
|
|
309
|
-
})());
|
|
310
|
-
});
|
|
8
|
+
swHelper(self);
|