web-manager 4.0.9 → 4.0.11
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/CHANGELOG.md +8 -1
- package/dist/index.js +22 -0
- package/dist/modules/sentry.js +29 -0
- package/dist/modules/service-worker.js +23 -156
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -16,9 +16,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
16
16
|
|
17
17
|
---
|
18
18
|
## [4.0.0] - 2025-09-11
|
19
|
-
### BREAKING
|
19
|
+
### ⚠️ BREAKING
|
20
20
|
- Updated to ITW 3.0 standard.
|
21
21
|
|
22
|
+
### Added
|
23
|
+
- Updated `@sentry/browser` to `10.11.0` to avoid breaking changes in `10.12.0` that affect Ultimate-Jekyll.
|
24
|
+
> When installing from NPM:
|
25
|
+
> lighthouse → @sentry/node@9.46.0 → @sentry/core@9.46.0
|
26
|
+
> web-manager → @sentry/browser@10.15.0 → expects
|
27
|
+
> @sentry/core@10.15.0
|
28
|
+
|
22
29
|
## [3.2.74] - 2025-07-17
|
23
30
|
### Added
|
24
31
|
- Now looks for `build.json` in the `/@output/build/` directory to ensure it works with Vite's output structure.
|
package/dist/index.js
CHANGED
@@ -99,6 +99,11 @@ class Manager {
|
|
99
99
|
// Set up auth event listeners (uses event delegation, no need to wait for DOM)
|
100
100
|
this._auth.setupEventListeners();
|
101
101
|
|
102
|
+
// Set up push notification auto-request if enabled
|
103
|
+
if (this.config.pushNotifications?.enabled && this.config.pushNotifications?.config?.autoRequest > 0) {
|
104
|
+
this._setupNotificationAutoRequest();
|
105
|
+
}
|
106
|
+
|
102
107
|
// Old IE force polyfill
|
103
108
|
// await this._loadPolyfillsIfNeeded();
|
104
109
|
|
@@ -421,6 +426,23 @@ class Manager {
|
|
421
426
|
}, this.config.refreshNewVersion.config.interval);
|
422
427
|
}
|
423
428
|
|
429
|
+
_setupNotificationAutoRequest() {
|
430
|
+
const handleClick = () => {
|
431
|
+
// Remove listener after first click
|
432
|
+
document.removeEventListener('click', handleClick);
|
433
|
+
|
434
|
+
// Set timeout to request notifications
|
435
|
+
setTimeout(() => {
|
436
|
+
console.log('Auto-requesting notification permissions...');
|
437
|
+
this._notifications.subscribe().catch(err => {
|
438
|
+
console.error('Notification subscription failed:', err.message);
|
439
|
+
});
|
440
|
+
}, this.config.pushNotifications.config.autoRequest);
|
441
|
+
};
|
442
|
+
|
443
|
+
// Wait for user click
|
444
|
+
document.addEventListener('click', handleClick);
|
445
|
+
}
|
424
446
|
|
425
447
|
// async _loadPolyfillsIfNeeded() {
|
426
448
|
// // Check if polyfills are needed by testing for ES6 features
|
package/dist/modules/sentry.js
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
// Helper functions
|
2
|
+
function isLighthouse() {
|
3
|
+
try {
|
4
|
+
return typeof navigator !== 'undefined' && navigator.userAgent?.includes('Lighthouse');
|
5
|
+
} catch (e) {
|
6
|
+
return false;
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
function isAutomatedBrowser() {
|
11
|
+
try {
|
12
|
+
return typeof navigator !== 'undefined' && navigator.webdriver === true;
|
13
|
+
} catch (e) {
|
14
|
+
return false;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
1
18
|
class SentryModule {
|
2
19
|
constructor(manager) {
|
3
20
|
this.manager = manager;
|
@@ -100,6 +117,18 @@ class SentryModule {
|
|
100
117
|
return null;
|
101
118
|
}
|
102
119
|
|
120
|
+
// Block sending if Lighthouse is running
|
121
|
+
if (isLighthouse()) {
|
122
|
+
console.log('[Sentry] Lighthouse detected - not sending to Sentry');
|
123
|
+
return null;
|
124
|
+
}
|
125
|
+
|
126
|
+
// Block sending if automated browser (Selenium, Puppeteer, etc.)
|
127
|
+
if (isAutomatedBrowser()) {
|
128
|
+
console.log('[Sentry] Automated browser detected - not sending to Sentry');
|
129
|
+
return null;
|
130
|
+
}
|
131
|
+
|
103
132
|
return event;
|
104
133
|
};
|
105
134
|
|
@@ -2,7 +2,6 @@ class ServiceWorker {
|
|
2
2
|
constructor(manager) {
|
3
3
|
this.manager = manager;
|
4
4
|
this._registration = null;
|
5
|
-
this._updateCallbacks = [];
|
6
5
|
this._messageHandlers = new Map();
|
7
6
|
}
|
8
7
|
|
@@ -46,39 +45,33 @@ class ServiceWorker {
|
|
46
45
|
firebase: this.manager.config.firebase?.app?.config || null
|
47
46
|
};
|
48
47
|
|
49
|
-
// Register
|
48
|
+
// Register service worker
|
50
49
|
const registration = await navigator.serviceWorker.register(swPath, {
|
51
50
|
scope,
|
52
|
-
updateViaCache: 'none'
|
51
|
+
updateViaCache: 'none'
|
53
52
|
});
|
54
53
|
|
54
|
+
// Store registration
|
55
55
|
this._registration = registration;
|
56
56
|
this.manager.state.serviceWorker = registration;
|
57
57
|
|
58
|
-
// Set up update handlers
|
59
|
-
this._setupUpdateHandlers(registration);
|
60
|
-
|
61
58
|
// Wait for service worker to be ready and send config
|
62
59
|
await navigator.serviceWorker.ready;
|
63
|
-
|
64
|
-
if (registration.active) {
|
65
|
-
try {
|
66
|
-
this.postMessage({
|
67
|
-
command: 'update-config',
|
68
|
-
payload: config
|
69
|
-
});
|
70
|
-
} catch (error) {
|
71
|
-
console.warn('Could not send config to service worker:', error);
|
72
|
-
}
|
73
|
-
|
74
|
-
this._setupMessageChannel();
|
75
|
-
}
|
76
|
-
|
77
|
-
// Check for updates (this will detect if service worker file changed)
|
78
|
-
if (options.checkForUpdate !== false) {
|
79
|
-
registration.update();
|
80
|
-
}
|
81
60
|
|
61
|
+
// Send config to active service worker
|
62
|
+
// Removed due to issues init'ing firebase asynchronously in SW (now config is fetched directly in SW)
|
63
|
+
// if (registration.active) {
|
64
|
+
// try {
|
65
|
+
// this.postMessage({
|
66
|
+
// command: 'update-config',
|
67
|
+
// payload: config
|
68
|
+
// });
|
69
|
+
// } catch (error) {
|
70
|
+
// console.warn('Could not send config to service worker:', error);
|
71
|
+
// }
|
72
|
+
// }
|
73
|
+
|
74
|
+
// Resolve with registration
|
82
75
|
return registration;
|
83
76
|
} catch (error) {
|
84
77
|
console.error('Service Worker registration failed:', error);
|
@@ -86,66 +79,32 @@ class ServiceWorker {
|
|
86
79
|
}
|
87
80
|
}
|
88
81
|
|
89
|
-
// Unregister service worker
|
90
|
-
async unregister() {
|
91
|
-
try {
|
92
|
-
if (!this._registration) {
|
93
|
-
const registrations = await navigator.serviceWorker.getRegistrations();
|
94
|
-
for (const registration of registrations) {
|
95
|
-
await registration.unregister();
|
96
|
-
}
|
97
|
-
} else {
|
98
|
-
await this._registration.unregister();
|
99
|
-
}
|
100
|
-
|
101
|
-
this._registration = null;
|
102
|
-
this.manager.state.serviceWorker = null;
|
103
|
-
|
104
|
-
return true;
|
105
|
-
} catch (error) {
|
106
|
-
console.error('Service Worker unregistration failed:', error);
|
107
|
-
return false;
|
108
|
-
}
|
109
|
-
}
|
110
|
-
|
111
82
|
// Get current registration
|
112
83
|
getRegistration() {
|
113
84
|
return this._registration;
|
114
85
|
}
|
115
86
|
|
116
|
-
// Check for updates
|
117
|
-
async update() {
|
118
|
-
try {
|
119
|
-
if (!this._registration) {
|
120
|
-
throw new Error('No service worker registered');
|
121
|
-
}
|
122
|
-
|
123
|
-
await this._registration.update();
|
124
|
-
return true;
|
125
|
-
} catch (error) {
|
126
|
-
console.error('Service Worker update failed:', error);
|
127
|
-
return false;
|
128
|
-
}
|
129
|
-
}
|
130
|
-
|
131
87
|
// Post message to service worker
|
132
88
|
postMessage(message, options = {}) {
|
133
89
|
return new Promise((resolve, reject) => {
|
90
|
+
// Check support
|
134
91
|
if (!this.isSupported()) {
|
135
92
|
return reject(new Error('Service Workers not supported'));
|
136
93
|
}
|
137
94
|
|
95
|
+
// Get active service worker
|
138
96
|
const controller = this._registration?.active || navigator.serviceWorker.controller;
|
139
97
|
|
140
98
|
if (!controller) {
|
141
99
|
return reject(new Error('No active service worker'));
|
142
100
|
}
|
143
101
|
|
102
|
+
// Create message channel for two-way communication
|
144
103
|
const messageChannel = new MessageChannel();
|
145
104
|
const timeout = options.timeout || 5000;
|
146
105
|
let timeoutId;
|
147
106
|
|
148
|
-
// Set up timeout
|
107
|
+
// Set up timeout to prevent hanging
|
149
108
|
if (timeout > 0) {
|
150
109
|
timeoutId = setTimeout(() => {
|
151
110
|
messageChannel.port1.close();
|
@@ -153,7 +112,7 @@ class ServiceWorker {
|
|
153
112
|
}, timeout);
|
154
113
|
}
|
155
114
|
|
156
|
-
// Listen for response
|
115
|
+
// Listen for response from service worker
|
157
116
|
messageChannel.port1.onmessage = (event) => {
|
158
117
|
clearTimeout(timeoutId);
|
159
118
|
|
@@ -164,7 +123,7 @@ class ServiceWorker {
|
|
164
123
|
}
|
165
124
|
};
|
166
125
|
|
167
|
-
// Send message
|
126
|
+
// Send message with port for reply
|
168
127
|
controller.postMessage(message, [messageChannel.port2]);
|
169
128
|
});
|
170
129
|
}
|
@@ -198,44 +157,6 @@ class ServiceWorker {
|
|
198
157
|
};
|
199
158
|
}
|
200
159
|
|
201
|
-
// Skip waiting and activate new service worker
|
202
|
-
async skipWaiting() {
|
203
|
-
try {
|
204
|
-
if (!this._registration?.waiting) {
|
205
|
-
throw new Error('No service worker waiting');
|
206
|
-
}
|
207
|
-
|
208
|
-
// Post message to skip waiting
|
209
|
-
await this.postMessage({ action: 'skipWaiting' });
|
210
|
-
|
211
|
-
// Reload page after activation
|
212
|
-
let refreshing = false;
|
213
|
-
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
214
|
-
if (!refreshing) {
|
215
|
-
refreshing = true;
|
216
|
-
window.location.reload();
|
217
|
-
}
|
218
|
-
});
|
219
|
-
|
220
|
-
return true;
|
221
|
-
} catch (error) {
|
222
|
-
console.error('Skip waiting failed:', error);
|
223
|
-
return false;
|
224
|
-
}
|
225
|
-
}
|
226
|
-
|
227
|
-
// Listen for update events
|
228
|
-
onUpdateFound(callback) {
|
229
|
-
this._updateCallbacks.push(callback);
|
230
|
-
|
231
|
-
return () => {
|
232
|
-
const index = this._updateCallbacks.indexOf(callback);
|
233
|
-
if (index > -1) {
|
234
|
-
this._updateCallbacks.splice(index, 1);
|
235
|
-
}
|
236
|
-
};
|
237
|
-
}
|
238
|
-
|
239
160
|
// Get service worker state
|
240
161
|
getState() {
|
241
162
|
if (!this._registration) {
|
@@ -253,52 +174,6 @@ class ServiceWorker {
|
|
253
174
|
return 'unknown';
|
254
175
|
}
|
255
176
|
|
256
|
-
// Private: Set up update handlers
|
257
|
-
_setupUpdateHandlers(registration) {
|
258
|
-
// Listen for updates
|
259
|
-
registration.addEventListener('updatefound', () => {
|
260
|
-
const newWorker = registration.installing;
|
261
|
-
|
262
|
-
if (!newWorker) return;
|
263
|
-
|
264
|
-
newWorker.addEventListener('statechange', () => {
|
265
|
-
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
266
|
-
// New service worker available
|
267
|
-
this._notifyUpdateCallbacks({
|
268
|
-
type: 'update-available',
|
269
|
-
worker: newWorker
|
270
|
-
});
|
271
|
-
|
272
|
-
// Automatically skip waiting and activate new worker
|
273
|
-
if (this.manager.config.serviceWorker?.autoUpdate !== false) {
|
274
|
-
this.skipWaiting();
|
275
|
-
}
|
276
|
-
}
|
277
|
-
});
|
278
|
-
});
|
279
|
-
|
280
|
-
// Listen for controller changes
|
281
|
-
let refreshing = false;
|
282
|
-
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
283
|
-
if (!refreshing) {
|
284
|
-
this._notifyUpdateCallbacks({
|
285
|
-
type: 'controller-change'
|
286
|
-
});
|
287
|
-
}
|
288
|
-
});
|
289
|
-
}
|
290
|
-
|
291
|
-
// Private: Notify update callbacks
|
292
|
-
_notifyUpdateCallbacks(event) {
|
293
|
-
this._updateCallbacks.forEach(callback => {
|
294
|
-
try {
|
295
|
-
callback(event);
|
296
|
-
} catch (error) {
|
297
|
-
console.error('Update callback error:', error);
|
298
|
-
}
|
299
|
-
});
|
300
|
-
}
|
301
|
-
|
302
177
|
// Private: Handle incoming messages
|
303
178
|
_handleMessage(event) {
|
304
179
|
const { type, ...data } = event.data || {};
|
@@ -316,14 +191,6 @@ class ServiceWorker {
|
|
316
191
|
});
|
317
192
|
}
|
318
193
|
}
|
319
|
-
|
320
|
-
// Private: Set up message channel
|
321
|
-
_setupMessageChannel() {
|
322
|
-
// This ensures we can communicate with the service worker
|
323
|
-
navigator.serviceWorker.ready.then(() => {
|
324
|
-
console.log('Service Worker ready for messaging');
|
325
|
-
});
|
326
|
-
}
|
327
194
|
}
|
328
195
|
|
329
196
|
export default ServiceWorker;
|
package/package.json
CHANGED