@networkpro/web 1.5.1 โ 1.5.2
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 +4 -4
- package/package.json +1 -1
- package/src/app.html +0 -10
- package/src/lib/registerServiceWorker.js +23 -14
- package/src/routes/+layout.js +0 -8
- package/src/routes/+layout.svelte +6 -0
- package/src/service-worker.js +50 -32
package/README.md
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
[](https://app.netlify.com/projects/networkpro-web/deploys) [](https://www.npmjs.com/package/@networkpro/web) [](https://github.com/netwk-pro/netwk-pro.github.io/actions/workflows/build-and-publish.yml)
|
|
9
|
+
[](https://github.com/prettier/prettier) [](https://stylelint.io/)
|
|
10
|
+
[](https://github.com/netwk-pro/netwk-pro.github.io/blob/master/CODE_OF_CONDUCT.md)
|
|
11
|
+
|
|
8
12
|
## ๐ Project Overview
|
|
9
13
|
|
|
10
14
|
This is the official web presence for **[Network Pro Strategies](https://netwk.pro/about)**, a privacy-forward consultancy specializing in network engineering, information security, and public advocacy focused on cybersecurity and digital privacy.
|
|
@@ -71,8 +75,6 @@ npm -v
|
|
|
71
75
|
|
|
72
76
|
---
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
|
|
76
78
|
## ๐ Available Scripts
|
|
77
79
|
|
|
78
80
|
The following CLI commands are available via `npm run <script>` or `pnpm run <script>`.
|
|
@@ -171,8 +173,6 @@ The following CLI commands are available via `npm run <script>` or `pnpm run <sc
|
|
|
171
173
|
|
|
172
174
|
---
|
|
173
175
|
|
|
174
|
-
|
|
175
|
-
|
|
176
176
|
## ๐งพ License
|
|
177
177
|
|
|
178
178
|
This project is licensed under:
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@networkpro/web",
|
|
3
3
|
"private": false,
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "1.5.
|
|
5
|
+
"version": "1.5.2",
|
|
6
6
|
"description": "Locking Down Networks, Unlocking Confidence | Security, Networking, Privacy โ Network Pro Strategies",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"advisory",
|
package/src/app.html
CHANGED
|
@@ -65,16 +65,6 @@
|
|
|
65
65
|
if (location.search.includes("nosw")) {
|
|
66
66
|
window.__DISABLE_SW__ = true;
|
|
67
67
|
console.warn("๐งช Service worker disabled via ?nosw flag in URL.");
|
|
68
|
-
|
|
69
|
-
if ("serviceWorker" in navigator) {
|
|
70
|
-
navigator.serviceWorker.getRegistrations().then((registrations) => {
|
|
71
|
-
for (const registration of registrations) {
|
|
72
|
-
registration.unregister().then((success) => {
|
|
73
|
-
console.log("๐งน SW unregistered:", success);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
68
|
}
|
|
79
69
|
</script>
|
|
80
70
|
|
|
@@ -10,50 +10,60 @@ This file is part of Network Pro.
|
|
|
10
10
|
* browser/environment compatibility checks. This supports offline usage and PWA behavior.
|
|
11
11
|
*/
|
|
12
12
|
export function registerServiceWorker() {
|
|
13
|
-
const disableSW =
|
|
13
|
+
const disableSW =
|
|
14
|
+
window?.__DISABLE_SW__ || location.search.includes("nosw");
|
|
14
15
|
|
|
15
16
|
if (disableSW) {
|
|
16
17
|
console.warn("โ ๏ธ Service Worker registration disabled via diagnostic mode.");
|
|
18
|
+
|
|
19
|
+
if ('serviceWorker' in navigator) {
|
|
20
|
+
navigator.serviceWorker.getRegistrations().then((registrations) => {
|
|
21
|
+
for (const registration of registrations) {
|
|
22
|
+
registration.unregister().then((success) => {
|
|
23
|
+
console.log("๐งน SW unregistered from registerServiceWorker.js:", success);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
return;
|
|
18
30
|
}
|
|
19
31
|
|
|
20
32
|
if ('serviceWorker' in navigator) {
|
|
21
|
-
//
|
|
33
|
+
// Optional: skip for Firefox in dev
|
|
22
34
|
const isFirefox = navigator.userAgent.includes('Firefox');
|
|
23
35
|
const isDevelopment =
|
|
24
|
-
|
|
25
|
-
window.location.hostname === '127.0.0.1';
|
|
36
|
+
location.hostname === 'localhost' || location.hostname === '127.0.0.1';
|
|
26
37
|
|
|
27
38
|
if (isFirefox && isDevelopment) {
|
|
28
|
-
console.log('
|
|
39
|
+
console.log('๐ SW registration skipped in Firefox development mode');
|
|
29
40
|
return;
|
|
30
41
|
}
|
|
31
42
|
|
|
32
|
-
// Wait until after full page load for performance optimization
|
|
33
43
|
window.addEventListener('load', () => {
|
|
34
44
|
navigator.serviceWorker
|
|
35
45
|
.register('service-worker.js')
|
|
36
46
|
.then((registration) => {
|
|
37
|
-
console.log('Service Worker registered with scope:', registration.scope);
|
|
47
|
+
console.log('โ
Service Worker registered with scope:', registration.scope);
|
|
38
48
|
|
|
39
|
-
// Track installation of a new service worker
|
|
40
49
|
registration.addEventListener('updatefound', () => {
|
|
41
50
|
const newWorker = registration.installing;
|
|
42
|
-
console.log('New service worker installing...');
|
|
51
|
+
console.log('[SW-CLIENT] New service worker installing...');
|
|
43
52
|
|
|
44
53
|
if (!newWorker) return;
|
|
45
54
|
|
|
46
55
|
let updatePrompted = false;
|
|
47
56
|
|
|
48
57
|
newWorker.addEventListener('statechange', () => {
|
|
58
|
+
console.log('[SW-CLIENT] New worker state:', newWorker.state);
|
|
59
|
+
|
|
49
60
|
if (
|
|
50
61
|
newWorker.state === 'installed' &&
|
|
51
62
|
navigator.serviceWorker.controller &&
|
|
52
63
|
!updatePrompted
|
|
53
64
|
) {
|
|
54
65
|
updatePrompted = true;
|
|
55
|
-
|
|
56
|
-
// Custom prompt: ask user to reload for latest content
|
|
66
|
+
console.log('[SW-CLIENT] New SW installed. Prompting user to reload.');
|
|
57
67
|
if (confirm('New content is available. Reload to update?')) {
|
|
58
68
|
window.location.reload();
|
|
59
69
|
}
|
|
@@ -62,19 +72,18 @@ export function registerServiceWorker() {
|
|
|
62
72
|
});
|
|
63
73
|
})
|
|
64
74
|
.catch((error) => {
|
|
65
|
-
console.error('Service Worker registration failed:', error);
|
|
75
|
+
console.error('โ Service Worker registration failed:', error);
|
|
66
76
|
});
|
|
67
77
|
|
|
68
|
-
// Ensure the page reloads automatically when the new service worker takes control
|
|
69
78
|
let refreshing = false;
|
|
70
79
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
80
|
+
console.log('[SW-CLIENT] Controller changed.');
|
|
71
81
|
if (!refreshing) {
|
|
72
82
|
refreshing = true;
|
|
73
83
|
window.location.reload();
|
|
74
84
|
}
|
|
75
85
|
});
|
|
76
86
|
|
|
77
|
-
// Optional PWA install prompt logic
|
|
78
87
|
window.addEventListener('beforeinstallprompt', (e) => {
|
|
79
88
|
e.preventDefault();
|
|
80
89
|
window.dispatchEvent(new CustomEvent('pwa-install-available', {
|
package/src/routes/+layout.js
CHANGED
|
@@ -21,9 +21,6 @@ const fallbackMeta = {
|
|
|
21
21
|
"Locking Down Networks, Unlocking Confidenceโข | Security, Networking, Privacy โ Network Proโข",
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
import { browser } from "$app/environment";
|
|
25
|
-
import { registerServiceWorker } from "$lib/registerServiceWorker.js";
|
|
26
|
-
|
|
27
24
|
export const prerender = "auto";
|
|
28
25
|
export const trailingSlash = "never";
|
|
29
26
|
|
|
@@ -34,11 +31,6 @@ export const trailingSlash = "never";
|
|
|
34
31
|
export function load({ url }) {
|
|
35
32
|
const normalizedPathname = url.pathname.replace(/\/+$/, "") || "/";
|
|
36
33
|
|
|
37
|
-
if (browser) {
|
|
38
|
-
// Move service worker registration here
|
|
39
|
-
registerServiceWorker();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
34
|
return {
|
|
43
35
|
pathname: normalizedPathname,
|
|
44
36
|
meta: fallbackMeta, // Required to ensure meta always exists for typing
|
|
@@ -13,6 +13,8 @@ This file is part of Network Pro.
|
|
|
13
13
|
import HeaderDefault from "$lib/components/layout/HeaderDefault.svelte";
|
|
14
14
|
import HeaderHome from "$lib/components/layout/HeaderHome.svelte";
|
|
15
15
|
import PWAInstallButton from "$lib/components/PWAInstallButton.svelte";
|
|
16
|
+
import { onMount } from "svelte";
|
|
17
|
+
import { registerServiceWorker } from "$lib/registerServiceWorker.js";
|
|
16
18
|
import { browser } from "$app/environment";
|
|
17
19
|
import "$lib/styles";
|
|
18
20
|
|
|
@@ -22,6 +24,10 @@ This file is part of Network Pro.
|
|
|
22
24
|
import faviconSvg from "$lib/img/favicon.svg";
|
|
23
25
|
import appleTouchIcon from "$lib/img/icon-180x180.png";
|
|
24
26
|
|
|
27
|
+
onMount(() => {
|
|
28
|
+
registerServiceWorker();
|
|
29
|
+
});
|
|
30
|
+
|
|
25
31
|
if (browser) {
|
|
26
32
|
// Preload logo images
|
|
27
33
|
[logoPng, logoWbp].forEach((src) => {
|
package/src/service-worker.js
CHANGED
|
@@ -18,28 +18,28 @@ const CACHE = `cache-${version}`;
|
|
|
18
18
|
/** @type {string[]} */
|
|
19
19
|
const excludedAssets = [];
|
|
20
20
|
|
|
21
|
+
const IGNORE_PATHS = new Set([
|
|
22
|
+
"/img/banner-1280x640.png",
|
|
23
|
+
"/img/banner-og-1200x630.png",
|
|
24
|
+
"/img/logo-transparent.png",
|
|
25
|
+
"/img/logo.png",
|
|
26
|
+
"/img/svelte.png",
|
|
27
|
+
"/webfonts/fa-brands-400.ttf",
|
|
28
|
+
"/webfonts/fa-solid-900.ttf",
|
|
29
|
+
"/robots.txt",
|
|
30
|
+
"/screenshots/desktop-foss.png",
|
|
31
|
+
"/sitemap.xml",
|
|
32
|
+
"/CNAME",
|
|
33
|
+
]);
|
|
34
|
+
|
|
21
35
|
/** @type {string[]} */
|
|
22
|
-
const ASSETS =
|
|
23
|
-
new Set(
|
|
36
|
+
const ASSETS = [
|
|
37
|
+
...new Set(
|
|
24
38
|
[...build, ...files, "/offline.html"].filter((path) => {
|
|
25
39
|
try {
|
|
26
40
|
const url = new URL(path, location.origin);
|
|
27
41
|
const hostname = url.hostname;
|
|
28
42
|
|
|
29
|
-
const IGNORE_PATHS = new Set([
|
|
30
|
-
"/img/banner-1280x640.png",
|
|
31
|
-
"/img/banner-og-1200x630.png",
|
|
32
|
-
"/img/logo-transparent.png",
|
|
33
|
-
"/img/logo.png",
|
|
34
|
-
"/img/svelte.png",
|
|
35
|
-
"/webfonts/fa-brands-400.ttf",
|
|
36
|
-
"/webfonts/fa-solid-900.ttf",
|
|
37
|
-
"/robots.txt",
|
|
38
|
-
"/screenshots/desktop-foss.png",
|
|
39
|
-
"/sitemap.xml",
|
|
40
|
-
"/CNAME",
|
|
41
|
-
]);
|
|
42
|
-
|
|
43
43
|
const shouldExclude =
|
|
44
44
|
path.startsWith("http") ||
|
|
45
45
|
disallowedHosts.some(
|
|
@@ -56,23 +56,24 @@ const ASSETS = Array.from(
|
|
|
56
56
|
}
|
|
57
57
|
}),
|
|
58
58
|
),
|
|
59
|
-
|
|
59
|
+
];
|
|
60
60
|
|
|
61
61
|
const uniqueExcludedAssets = [...new Set(excludedAssets)].sort();
|
|
62
62
|
|
|
63
63
|
console.log("[SW] Assets to precache:", ASSETS);
|
|
64
64
|
console.log("[SW] Excluded assets:", uniqueExcludedAssets);
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
* @param {ExtendableEvent} event
|
|
68
|
-
*/
|
|
66
|
+
// ๐น Install event
|
|
69
67
|
sw.addEventListener("install", (event) => {
|
|
68
|
+
console.log("[SW] Install event");
|
|
70
69
|
event.waitUntil(
|
|
71
70
|
(async () => {
|
|
72
71
|
const cache = await caches.open(CACHE);
|
|
73
72
|
try {
|
|
74
73
|
await cache.addAll(ASSETS);
|
|
74
|
+
console.log("[SW] Precaching complete");
|
|
75
75
|
sw.skipWaiting();
|
|
76
|
+
console.log("[SW] skipWaiting() called");
|
|
76
77
|
} catch (err) {
|
|
77
78
|
console.warn("[SW] Failed to precache some assets:", err);
|
|
78
79
|
}
|
|
@@ -80,23 +81,26 @@ sw.addEventListener("install", (event) => {
|
|
|
80
81
|
);
|
|
81
82
|
});
|
|
82
83
|
|
|
83
|
-
|
|
84
|
-
* @param {ExtendableEvent} event
|
|
85
|
-
*/
|
|
84
|
+
// ๐น Activate event
|
|
86
85
|
sw.addEventListener("activate", (event) => {
|
|
87
|
-
|
|
86
|
+
console.log("[SW] Activate event");
|
|
87
|
+
event.waitUntil(
|
|
88
88
|
(async () => {
|
|
89
89
|
const tasks = [];
|
|
90
90
|
|
|
91
91
|
if (sw.registration.navigationPreload) {
|
|
92
92
|
tasks.push(sw.registration.navigationPreload.enable());
|
|
93
|
+
console.log("[SW] Navigation preload enabled");
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
tasks.push(
|
|
96
97
|
caches.keys().then((keys) =>
|
|
97
98
|
Promise.all(
|
|
98
99
|
keys.map((key) => {
|
|
99
|
-
if (key !== CACHE)
|
|
100
|
+
if (key !== CACHE) {
|
|
101
|
+
console.log("[SW] Deleting old cache:", key);
|
|
102
|
+
return caches.delete(key);
|
|
103
|
+
}
|
|
100
104
|
}),
|
|
101
105
|
),
|
|
102
106
|
),
|
|
@@ -104,29 +108,43 @@ sw.addEventListener("activate", (event) => {
|
|
|
104
108
|
|
|
105
109
|
await Promise.all(tasks);
|
|
106
110
|
await sw.clients.claim();
|
|
111
|
+
console.log("[SW] clients.claim() called");
|
|
112
|
+
console.log("[SW] Scope:", sw.registration.scope);
|
|
107
113
|
})(),
|
|
108
114
|
);
|
|
109
115
|
});
|
|
110
116
|
|
|
111
|
-
|
|
112
|
-
* @param {FetchEvent} event
|
|
113
|
-
*/
|
|
117
|
+
// ๐น Fetch event
|
|
114
118
|
sw.addEventListener("fetch", (event) => {
|
|
115
|
-
|
|
119
|
+
console.log("[SW] Fetch intercepted:", event.request.url);
|
|
120
|
+
event.respondWith(
|
|
116
121
|
(async () => {
|
|
117
122
|
if (new URL(event.request.url).origin === location.origin) {
|
|
118
123
|
const cached = await caches.match(event.request);
|
|
119
|
-
if (cached)
|
|
124
|
+
if (cached) {
|
|
125
|
+
console.log("[SW] Serving from cache:", event.request.url);
|
|
126
|
+
return cached;
|
|
127
|
+
}
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
try {
|
|
123
131
|
if (event.request.mode === "navigate") {
|
|
124
132
|
const preloadResponse = await event.preloadResponse;
|
|
125
|
-
if (preloadResponse)
|
|
133
|
+
if (preloadResponse) {
|
|
134
|
+
console.log("[SW] Using preload response for:", event.request.url);
|
|
135
|
+
return preloadResponse;
|
|
136
|
+
}
|
|
126
137
|
}
|
|
127
138
|
|
|
139
|
+
console.log("[SW] Fetching from network:", event.request.url);
|
|
128
140
|
return await fetch(event.request);
|
|
129
|
-
} catch {
|
|
141
|
+
} catch (err) {
|
|
142
|
+
console.warn(
|
|
143
|
+
"[SW] Fetch failed; offline fallback used:",
|
|
144
|
+
event.request.url,
|
|
145
|
+
err,
|
|
146
|
+
);
|
|
147
|
+
|
|
130
148
|
if (event.request.mode === "navigate") {
|
|
131
149
|
const offline = await caches.match("/offline.html");
|
|
132
150
|
if (offline) return offline;
|