@ohos-ports/layer0-prefetch 4.20.0-beta.0
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 +7 -0
- package/constants.d.ts +23 -0
- package/constants.js +25 -0
- package/index.js +24 -0
- package/package.json +50 -0
- package/sw/CustomCacheKeyPlugin.d.ts +10 -0
- package/sw/CustomCacheKeyPlugin.js +54 -0
- package/sw/CustomExpirationPlugin.d.ts +122 -0
- package/sw/CustomExpirationPlugin.js +280 -0
- package/sw/DeepFetchPlugin.d.ts +108 -0
- package/sw/DeepFetchPlugin.js +144 -0
- package/sw/DevtoolsPlugin.d.ts +64 -0
- package/sw/DevtoolsPlugin.js +131 -0
- package/sw/PrefetchPlugin.d.ts +32 -0
- package/sw/PrefetchPlugin.js +167 -0
- package/sw/Prefetcher.d.ts +209 -0
- package/sw/Prefetcher.js +367 -0
- package/sw/getServiceWorkerMaxAge.d.ts +22 -0
- package/sw/getServiceWorkerMaxAge.js +51 -0
- package/sw/index.d.ts +2 -0
- package/sw/index.js +6 -0
- package/sw/log.d.ts +1 -0
- package/sw/log.js +9 -0
- package/sw/messageBrowser.d.ts +7 -0
- package/sw/messageBrowser.js +18 -0
- package/sw/prefetch.d.ts +9 -0
- package/sw/prefetch.js +17 -0
- package/window/InstallOptions.d.ts +77 -0
- package/window/InstallOptions.js +2 -0
- package/window/PrefetchOptions.d.ts +19 -0
- package/window/PrefetchOptions.js +2 -0
- package/window/entry.d.ts +1 -0
- package/window/entry.js +8 -0
- package/window/getHostName.d.ts +1 -0
- package/window/getHostName.js +6 -0
- package/window/getUserAgent.d.ts +1 -0
- package/window/getUserAgent.js +6 -0
- package/window/index.d.ts +3 -0
- package/window/index.js +8 -0
- package/window/install.d.ts +13 -0
- package/window/install.js +72 -0
- package/window/isSafari.d.ts +6 -0
- package/window/isSafari.js +31 -0
- package/window/loadManifest.d.ts +3 -0
- package/window/loadManifest.js +20 -0
- package/window/prefetch.d.ts +71 -0
- package/window/prefetch.js +157 -0
- package/window/prefetchWhenVisible.d.ts +5 -0
- package/window/prefetchWhenVisible.js +20 -0
- package/window/registerServiceWorker.d.ts +2 -0
- package/window/registerServiceWorker.js +66 -0
- package/window/runWhenVisible.d.ts +6 -0
- package/window/runWhenVisible.js +28 -0
- package/window/waitForServiceWorker.d.ts +4 -0
- package/window/waitForServiceWorker.js +27 -0
- package/window/watchElements.d.ts +7 -0
- package/window/watchElements.js +63 -0
- package/window/watchLinks.d.ts +9 -0
- package/window/watchLinks.js +65 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/* istanbul ignore file */
|
|
4
|
+
const isSafari_1 = require("./isSafari");
|
|
5
|
+
function registerServiceWorker(serviceWorkerPath) {
|
|
6
|
+
if (isSafari_1.isSafariPrivateWindow()) {
|
|
7
|
+
// Private windows in safari have a known bug with sending cookies
|
|
8
|
+
// in POST requests. This often breaks cart and checkout, so we choose
|
|
9
|
+
// not to use service workers at all when in safari private windows.
|
|
10
|
+
// See the bug report here: https://bugs.webkit.org/show_bug.cgi?id=186617
|
|
11
|
+
console.log('skipping service worker in Safari private window');
|
|
12
|
+
unregisterServiceWorker();
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if ('serviceWorker' in navigator) {
|
|
16
|
+
if (document.readyState === 'complete') {
|
|
17
|
+
registerValidSW(serviceWorkerPath);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
window.addEventListener('load', () => {
|
|
21
|
+
registerValidSW(serviceWorkerPath);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.registerServiceWorker = registerServiceWorker;
|
|
27
|
+
function registerValidSW(swUrl) {
|
|
28
|
+
navigator.serviceWorker
|
|
29
|
+
.register(swUrl)
|
|
30
|
+
.then(registration => {
|
|
31
|
+
registration.onupdatefound = () => {
|
|
32
|
+
const installingWorker = registration.installing;
|
|
33
|
+
if (!installingWorker)
|
|
34
|
+
return;
|
|
35
|
+
installingWorker.onstatechange = () => {
|
|
36
|
+
console.log('[layer0 service worker] state:', installingWorker.state);
|
|
37
|
+
if (installingWorker.state === 'installed') {
|
|
38
|
+
if (navigator.serviceWorker.controller) {
|
|
39
|
+
// At this point, the old content will have been purged and
|
|
40
|
+
// the fresh content will have been added to the cache.
|
|
41
|
+
// It's the perfect time to display a "New content is
|
|
42
|
+
// available; please refresh." message in your web app.
|
|
43
|
+
document.dispatchEvent(new CustomEvent('sw-update-available'));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// At this point, everything has been precached.
|
|
47
|
+
// It's the perfect time to display a
|
|
48
|
+
// "Content is cached for offline use." message.
|
|
49
|
+
console.log('Content is cached for offline use.');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
})
|
|
55
|
+
.catch(error => {
|
|
56
|
+
console.error('Error during service worker registration:', error);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function unregisterServiceWorker() {
|
|
60
|
+
if ('serviceWorker' in navigator) {
|
|
61
|
+
navigator.serviceWorker.ready.then(registration => {
|
|
62
|
+
registration.unregister();
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.unregisterServiceWorker = unregisterServiceWorker;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs a callback function when an element it is visible in the viewport
|
|
3
|
+
* @param {HTMLElement} el The element
|
|
4
|
+
* @param {Function} callback The function to call once the element is visible
|
|
5
|
+
*/
|
|
6
|
+
export default function runWhenVisible(el: HTMLElement, callback: (param: HTMLElement) => void): void;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Runs a callback function when an element it is visible in the viewport
|
|
5
|
+
* @param {HTMLElement} el The element
|
|
6
|
+
* @param {Function} callback The function to call once the element is visible
|
|
7
|
+
*/
|
|
8
|
+
function runWhenVisible(el, callback) {
|
|
9
|
+
/* istanbul ignore next */
|
|
10
|
+
if (typeof IntersectionObserver === 'undefined')
|
|
11
|
+
return;
|
|
12
|
+
const observer = new IntersectionObserver(entries => {
|
|
13
|
+
// if intersectionRatio is 0, the element is out of view and we do not need to do anything.
|
|
14
|
+
if (entries[0].intersectionRatio > 0) {
|
|
15
|
+
observer.disconnect();
|
|
16
|
+
callback(el);
|
|
17
|
+
}
|
|
18
|
+
}, {
|
|
19
|
+
// setting this to > 0 to avoid a race condition where an element comes into the
|
|
20
|
+
// viewport at the same time as display/visibility becomes block/visible, and
|
|
21
|
+
// the IntersectionObserver is then only triggered with a ratio of 0
|
|
22
|
+
threshold: 0.01,
|
|
23
|
+
});
|
|
24
|
+
// Note: apparently we don't need to clean these up when the observed node is removed.
|
|
25
|
+
// See https://stackoverflow.com/questions/51106261/should-mutationobservers-be-removed-disconnected-when-the-attached-dom-node-is-r/51106262#51106262
|
|
26
|
+
observer.observe(el);
|
|
27
|
+
}
|
|
28
|
+
exports.default = runWhenVisible;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Resolves when the service worker has been installed.
|
|
5
|
+
*/
|
|
6
|
+
async function waitForServiceWorker() {
|
|
7
|
+
if (!navigator.serviceWorker || !navigator.serviceWorker.ready) {
|
|
8
|
+
throw new Error('service worker not supported');
|
|
9
|
+
}
|
|
10
|
+
await navigator.serviceWorker.ready;
|
|
11
|
+
if (navigator.serviceWorker.controller) {
|
|
12
|
+
return navigator.serviceWorker.controller;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
17
|
+
if (navigator.serviceWorker.controller) {
|
|
18
|
+
resolve(navigator.serviceWorker.controller);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
reject(new Error('service worker not supported'));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = waitForServiceWorker;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PrefetchWatcherConfig } from './InstallOptions';
|
|
2
|
+
/**
|
|
3
|
+
* Sets up observers to watch for elements matching the list of selectors, then
|
|
4
|
+
* perform the given callback when an element becomes visible
|
|
5
|
+
* @param {PrefetchWatcherConfig[]} configArr Contains the list of selector/callback pairs
|
|
6
|
+
*/
|
|
7
|
+
export default function watchElements(configArr: PrefetchWatcherConfig[] | undefined): void;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const runWhenVisible_1 = __importDefault(require("./runWhenVisible"));
|
|
7
|
+
let observer;
|
|
8
|
+
const watchConfigs = new Set();
|
|
9
|
+
/**
|
|
10
|
+
* Sets up observers to watch for elements matching the list of selectors, then
|
|
11
|
+
* perform the given callback when an element becomes visible
|
|
12
|
+
* @param {PrefetchWatcherConfig[]} configArr Contains the list of selector/callback pairs
|
|
13
|
+
*/
|
|
14
|
+
function watchElements(configArr) {
|
|
15
|
+
/* istanbul ignore next */
|
|
16
|
+
if (typeof MutationObserver === 'undefined')
|
|
17
|
+
return;
|
|
18
|
+
if (!configArr || !configArr.length)
|
|
19
|
+
return;
|
|
20
|
+
configArr.forEach(watch => watchConfigs.add(watch));
|
|
21
|
+
if (!observer) {
|
|
22
|
+
observer = new MutationObserver(mutationsList => {
|
|
23
|
+
for (let mutation of mutationsList) {
|
|
24
|
+
;
|
|
25
|
+
[...watchConfigs].forEach(watch => {
|
|
26
|
+
filterBySelector(mutation.addedNodes, watch.selector).forEach(match => runWhenVisible_1.default(match, watch.callback));
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
observer.observe(document.body, {
|
|
32
|
+
subtree: true,
|
|
33
|
+
childList: true,
|
|
34
|
+
});
|
|
35
|
+
configArr.forEach(watch => {
|
|
36
|
+
document.querySelectorAll(watch.selector).forEach(match => {
|
|
37
|
+
const el = match;
|
|
38
|
+
runWhenVisible_1.default(el, watch.callback);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
exports.default = watchElements;
|
|
43
|
+
/**
|
|
44
|
+
* Returns all nodes in the node list that match one of the given selectors
|
|
45
|
+
* @param {NodeList} nodes A node list to filter
|
|
46
|
+
* @param {String} selector Selector used to match elements
|
|
47
|
+
*/
|
|
48
|
+
function filterBySelector(nodes, selector) {
|
|
49
|
+
const results = new Set();
|
|
50
|
+
Array.from(nodes).forEach(n => {
|
|
51
|
+
if (n.nodeType === Node.ELEMENT_NODE) {
|
|
52
|
+
const el = n;
|
|
53
|
+
if (el.matches(selector)) {
|
|
54
|
+
results.add(el);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const matches = el.querySelectorAll(selector);
|
|
58
|
+
matches.forEach(match => results.add(match));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return results;
|
|
63
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import CacheManifest from '@layer0/core/router/CacheManifest';
|
|
2
|
+
import { ObserveOptionsConfig } from './InstallOptions';
|
|
3
|
+
/**
|
|
4
|
+
* Watches the DOM for all current and future links whose href matches one of the
|
|
5
|
+
* specified URL patterns
|
|
6
|
+
* @param {CacheManifest} cacheManifest Regular expressions that will be tested against link href attributes
|
|
7
|
+
* @param {ObserveOptionsConfig} observeOpts Configuration for how the DOM is observed for node changes
|
|
8
|
+
*/
|
|
9
|
+
export default function watchLinks(cacheManifest: CacheManifest, observerOpts?: ObserveOptionsConfig): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const prefetchWhenVisible_1 = __importDefault(require("./prefetchWhenVisible"));
|
|
7
|
+
const CacheManifest_1 = __importDefault(require("@layer0/core/router/CacheManifest"));
|
|
8
|
+
const observerDefaults = {
|
|
9
|
+
disabled: false,
|
|
10
|
+
attributes: false,
|
|
11
|
+
};
|
|
12
|
+
let observer;
|
|
13
|
+
const searchedEntries = new Set();
|
|
14
|
+
/**
|
|
15
|
+
* Watches the DOM for all current and future links whose href matches one of the
|
|
16
|
+
* specified URL patterns
|
|
17
|
+
* @param {CacheManifest} cacheManifest Regular expressions that will be tested against link href attributes
|
|
18
|
+
* @param {ObserveOptionsConfig} observeOpts Configuration for how the DOM is observed for node changes
|
|
19
|
+
*/
|
|
20
|
+
function watchLinks(cacheManifest, observerOpts) {
|
|
21
|
+
/* istanbul ignore next */
|
|
22
|
+
if (typeof MutationObserver === 'undefined')
|
|
23
|
+
return;
|
|
24
|
+
cacheManifest.entries.forEach(entry => searchedEntries.add(entry));
|
|
25
|
+
observerOpts = { ...observerDefaults, ...observerOpts };
|
|
26
|
+
if (!observer) {
|
|
27
|
+
observer = new MutationObserver(mutationsList => {
|
|
28
|
+
for (let mutation of mutationsList) {
|
|
29
|
+
filterByHref(mutation.addedNodes, CacheManifest_1.default.fromEntries([...searchedEntries.values()])).forEach(prefetchWhenVisible_1.default);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
if (!observerOpts.disabled) {
|
|
33
|
+
observer.observe(document.body, {
|
|
34
|
+
attributes: observerOpts.attributes,
|
|
35
|
+
childList: true,
|
|
36
|
+
subtree: true,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
filterByHref(document.querySelectorAll('a'), cacheManifest).forEach(prefetchWhenVisible_1.default);
|
|
41
|
+
}
|
|
42
|
+
exports.default = watchLinks;
|
|
43
|
+
/**
|
|
44
|
+
* Returns all nodes in the node list whose href matches at least one of the specified patterns.
|
|
45
|
+
* @param {NodeList} nodes A node list to filter
|
|
46
|
+
* @param {CacheManifest} cacheManifest Contains the list of route patterns to check
|
|
47
|
+
*/
|
|
48
|
+
function filterByHref(nodes, cacheManifest) {
|
|
49
|
+
const isMatchingLink = (el) => {
|
|
50
|
+
const href = el.getAttribute('href');
|
|
51
|
+
if (!href || el.tagName.toLowerCase() !== 'a') {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return cacheManifest.shouldPrefetch(new URL(href, window.location.href));
|
|
55
|
+
};
|
|
56
|
+
const results = new Set();
|
|
57
|
+
Array.from(nodes).forEach(n => {
|
|
58
|
+
if (n.nodeType === Node.ELEMENT_NODE) {
|
|
59
|
+
const el = n;
|
|
60
|
+
const links = [el, ...Array.from(el.querySelectorAll('a'))];
|
|
61
|
+
links.filter(isMatchingLink).forEach(link => results.add(link));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return results;
|
|
65
|
+
}
|