@networkpro/web 1.7.4 → 1.7.6
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/budget.json +34 -0
- package/cspell.json +2 -0
- package/package.json +1 -1
- package/src/lib/registerServiceWorker.js +10 -0
- package/src/service-worker.js +90 -10
package/budget.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"path": "/*",
|
|
4
|
+
"resourceSizes": [
|
|
5
|
+
{ "resourceType": "script", "budget": 300 },
|
|
6
|
+
{ "resourceType": "stylesheet", "budget": 100 },
|
|
7
|
+
{ "resourceType": "image", "budget": 350 },
|
|
8
|
+
{ "resourceType": "font", "budget": 200 },
|
|
9
|
+
{ "resourceType": "other", "budget": 150 },
|
|
10
|
+
{ "resourceType": "document", "budget": 50 },
|
|
11
|
+
{ "resourceType": "total", "budget": 1000 }
|
|
12
|
+
],
|
|
13
|
+
"resourceCounts": [
|
|
14
|
+
{ "resourceType": "third-party", "budget": 15 },
|
|
15
|
+
{ "resourceType": "script", "budget": 15 },
|
|
16
|
+
{ "resourceType": "stylesheet", "budget": 5 },
|
|
17
|
+
{ "resourceType": "image", "budget": 15 },
|
|
18
|
+
{ "resourceType": "font", "budget": 10 },
|
|
19
|
+
{ "resourceType": "other", "budget": 10 },
|
|
20
|
+
{ "resourceType": "total", "budget": 60 }
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "/foss-spotlight",
|
|
25
|
+
"resourceSizes": [
|
|
26
|
+
{ "resourceType": "image", "budget": 500 },
|
|
27
|
+
{ "resourceType": "total", "budget": 1200 }
|
|
28
|
+
],
|
|
29
|
+
"resourceCounts": [
|
|
30
|
+
{ "resourceType": "image", "budget": 25 },
|
|
31
|
+
{ "resourceType": "total", "budget": 75 }
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
]
|
package/cspell.json
CHANGED
package/package.json
CHANGED
|
@@ -48,6 +48,16 @@ export function registerServiceWorker() {
|
|
|
48
48
|
.then((registration) => {
|
|
49
49
|
console.log("✅ Service Worker registered with scope:", registration.scope);
|
|
50
50
|
|
|
51
|
+
// 🧼 Manual cleanup of unexpected caches
|
|
52
|
+
caches.keys().then((keys) => {
|
|
53
|
+
keys.forEach((key) => {
|
|
54
|
+
if (!key.startsWith("cache-")) {
|
|
55
|
+
console.log("🧹 Deleting unexpected cache:", key);
|
|
56
|
+
caches.delete(key);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
51
61
|
registration.addEventListener("updatefound", () => {
|
|
52
62
|
const newWorker = registration.installing;
|
|
53
63
|
console.log("[SW-CLIENT] New service worker installing...");
|
package/src/service-worker.js
CHANGED
|
@@ -33,7 +33,6 @@ const IGNORE_PATHS = new Set([
|
|
|
33
33
|
"/docs/extensions.md",
|
|
34
34
|
"/docs/Home.md",
|
|
35
35
|
"/img/banner-1280x640.png",
|
|
36
|
-
"/img/banner-og-1200x630.png",
|
|
37
36
|
"/img/logo-transparent.png",
|
|
38
37
|
"/img/logo.png",
|
|
39
38
|
"/img/svelte.png",
|
|
@@ -55,6 +54,7 @@ const ASSETS = [
|
|
|
55
54
|
|
|
56
55
|
const shouldExclude =
|
|
57
56
|
path.startsWith("http") ||
|
|
57
|
+
path.startsWith("/assets/") ||
|
|
58
58
|
disallowedHosts.some(
|
|
59
59
|
(host) => hostname === host || hostname.endsWith(`.${host}`),
|
|
60
60
|
) ||
|
|
@@ -74,25 +74,105 @@ const ASSETS = [
|
|
|
74
74
|
|
|
75
75
|
const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
|
|
76
76
|
|
|
77
|
+
/** @type {string[]} */
|
|
78
|
+
const REQUIRED_ASSETS = [
|
|
79
|
+
"/disableSw.js",
|
|
80
|
+
"/favicon.ico",
|
|
81
|
+
"/icon-192x192.png",
|
|
82
|
+
"/icon-512x512-maskable.png",
|
|
83
|
+
"/icon-512x512.png",
|
|
84
|
+
"/icon-contact.png",
|
|
85
|
+
"/icon-services.png",
|
|
86
|
+
"/icon-splash.png",
|
|
87
|
+
"/img/banner-og-1200x630.png",
|
|
88
|
+
"/img/qr/pgp-contact.png",
|
|
89
|
+
"/img/qr/pgp-github.png",
|
|
90
|
+
"/img/qr/pgp-support.png",
|
|
91
|
+
"/img/qr/vcard.png",
|
|
92
|
+
"/manifest.json",
|
|
93
|
+
"/offline.html",
|
|
94
|
+
"/offline.min.css",
|
|
95
|
+
"/screenshots/desktop-about.png",
|
|
96
|
+
"/screenshots/desktop-home.png",
|
|
97
|
+
"/screenshots/mobile-foss.png",
|
|
98
|
+
"/screenshots/mobile-home.png",
|
|
99
|
+
"/styles/brands.min.css",
|
|
100
|
+
"/styles/fontawesome.min.css",
|
|
101
|
+
"/styles/global.min.css",
|
|
102
|
+
"/styles/solid.min.css",
|
|
103
|
+
"/webfonts/fa-brands-400.woff2",
|
|
104
|
+
"/webfonts/fa-solid-900.woff2",
|
|
105
|
+
"/.well-known/dnt-policy-1.0.txt",
|
|
106
|
+
];
|
|
107
|
+
|
|
77
108
|
if (isDev) {
|
|
78
109
|
console.log("[SW] Assets to precache:", ASSETS);
|
|
79
110
|
console.log("[SW] Excluded assets:", uniqueExcludedAssets);
|
|
80
111
|
}
|
|
81
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Safely cache a list of assets, logging or throwing if required assets fail.
|
|
115
|
+
*
|
|
116
|
+
* @param {Cache} cache
|
|
117
|
+
* @param {string[]} assets
|
|
118
|
+
* @param {string[]} required
|
|
119
|
+
* @returns {Promise<string[]>} Cached asset paths
|
|
120
|
+
*/
|
|
121
|
+
async function cacheAssetsSafely(cache, assets, required = []) {
|
|
122
|
+
/** @type {string[]} */
|
|
123
|
+
const cachedPaths = [];
|
|
124
|
+
|
|
125
|
+
await Promise.all(
|
|
126
|
+
assets.map(async (asset) => {
|
|
127
|
+
try {
|
|
128
|
+
await cache.add(asset);
|
|
129
|
+
cachedPaths.push(asset);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
const msg =
|
|
132
|
+
err instanceof Error
|
|
133
|
+
? `[SW] Failed to cache ${asset}: ${err.message}`
|
|
134
|
+
: `[SW] Failed to cache ${asset}: Unknown error`;
|
|
135
|
+
|
|
136
|
+
if (isDev) {
|
|
137
|
+
throw new Error(msg);
|
|
138
|
+
} else {
|
|
139
|
+
console.warn(msg);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}),
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const missing = required.filter((req) => !cachedPaths.includes(req));
|
|
146
|
+
if (missing.length > 0) {
|
|
147
|
+
const errorMsg = `[SW] ⚠️ Missing required assets: ${missing.join(", ")}`;
|
|
148
|
+
if (isDev) throw new Error(errorMsg);
|
|
149
|
+
console.error(errorMsg);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return cachedPaths;
|
|
153
|
+
}
|
|
154
|
+
|
|
82
155
|
// 🔹 Install event
|
|
83
156
|
sw.addEventListener("install", (event) => {
|
|
84
157
|
if (isDev) console.log("[SW] Install event");
|
|
158
|
+
|
|
85
159
|
event.waitUntil(
|
|
86
160
|
(async () => {
|
|
87
161
|
const cache = await caches.open(CACHE);
|
|
162
|
+
let cachedPaths = [];
|
|
163
|
+
|
|
88
164
|
try {
|
|
89
|
-
await cache
|
|
90
|
-
if (isDev)
|
|
91
|
-
|
|
92
|
-
|
|
165
|
+
cachedPaths = await cacheAssetsSafely(cache, ASSETS, REQUIRED_ASSETS);
|
|
166
|
+
if (isDev) {
|
|
167
|
+
console.log("[SW] Cached assets:", cachedPaths);
|
|
168
|
+
}
|
|
93
169
|
} catch (err) {
|
|
94
|
-
if (isDev)
|
|
170
|
+
if (isDev) throw err;
|
|
171
|
+
console.warn("[SW] Error while precaching (non-fatal in prod):", err);
|
|
95
172
|
}
|
|
173
|
+
|
|
174
|
+
await sw.skipWaiting();
|
|
175
|
+
if (isDev) console.log("[SW] skipWaiting() called");
|
|
96
176
|
})(),
|
|
97
177
|
);
|
|
98
178
|
});
|
|
@@ -112,12 +192,12 @@ sw.addEventListener("activate", (event) => {
|
|
|
112
192
|
tasks.push(
|
|
113
193
|
caches.keys().then((keys) =>
|
|
114
194
|
Promise.all(
|
|
115
|
-
keys
|
|
116
|
-
|
|
195
|
+
keys
|
|
196
|
+
.filter((key) => key !== CACHE)
|
|
197
|
+
.map((key) => {
|
|
117
198
|
if (isDev) console.log("[SW] Deleting old cache:", key);
|
|
118
199
|
return caches.delete(key);
|
|
119
|
-
}
|
|
120
|
-
}),
|
|
200
|
+
}),
|
|
121
201
|
),
|
|
122
202
|
),
|
|
123
203
|
);
|