@budarin/pluggable-serviceworker 1.0.1 → 1.0.3
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 +161 -13
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +52 -11
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @budarin/pluggable-serviceworker
|
|
2
2
|
|
|
3
3
|
🔌 Расширяемый через плагины Service Worker
|
|
4
4
|
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
## 📦 Установка
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
npm install @
|
|
18
|
+
npm install @budarin/pluggable-serviceworker
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
или
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
pnpm add @
|
|
24
|
+
pnpm add @budarin/pluggable-serviceworker
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## 🚀 Быстрый старт
|
|
@@ -30,7 +30,7 @@ pnpm add @vadimbudarin/pluggable-serviceworker
|
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
32
|
// sw.js
|
|
33
|
-
import { initializeServiceWorker } from '@
|
|
33
|
+
import { initializeServiceWorker } from '@budarin/pluggable-serviceworker';
|
|
34
34
|
|
|
35
35
|
// Простой плагин для кеширования
|
|
36
36
|
const cachePlugin = {
|
|
@@ -54,7 +54,7 @@ initializeServiceWorker([cachePlugin]);
|
|
|
54
54
|
### Использование с приоритетами
|
|
55
55
|
|
|
56
56
|
```typescript
|
|
57
|
-
import { initializeServiceWorker } from '@
|
|
57
|
+
import { initializeServiceWorker } from '@budarin/pluggable-serviceworker';
|
|
58
58
|
|
|
59
59
|
const authPlugin = {
|
|
60
60
|
name: 'auth-plugin',
|
|
@@ -98,7 +98,7 @@ initializeServiceWorker([authPlugin, cachePlugin, loggingPlugin]);
|
|
|
98
98
|
### Обработка ошибок
|
|
99
99
|
|
|
100
100
|
```typescript
|
|
101
|
-
import { initializeServiceWorker } from '@
|
|
101
|
+
import { initializeServiceWorker } from '@budarin/pluggable-serviceworker';
|
|
102
102
|
|
|
103
103
|
const config = {
|
|
104
104
|
onError: (error, event) => {
|
|
@@ -142,8 +142,9 @@ interface ServiceWorkerPlugin {
|
|
|
142
142
|
activate?: (event: ExtendableEvent) => void | Promise<void>;
|
|
143
143
|
fetch?: (event: FetchEvent) => Promise<Response | null>;
|
|
144
144
|
message?: (event: MessageEvent) => void;
|
|
145
|
-
sync?: (event: SyncEvent) => void
|
|
146
|
-
|
|
145
|
+
sync?: (event: SyncEvent) => void | Promise<void>; // Фоновая синхронизация
|
|
146
|
+
periodicsync?: (event: PeriodicSyncEvent) => void | Promise<void>; // Периодическая синхронизация
|
|
147
|
+
push?: (event: PushEvent) => void | Promise<void>; // Может быть асинхронным
|
|
147
148
|
}
|
|
148
149
|
```
|
|
149
150
|
|
|
@@ -218,7 +219,7 @@ const cachePlugin = {
|
|
|
218
219
|
const notificationPlugin = {
|
|
219
220
|
name: 'notifications',
|
|
220
221
|
|
|
221
|
-
push: (event) => {
|
|
222
|
+
push: async (event) => {
|
|
222
223
|
const data = event.data?.json() || {};
|
|
223
224
|
|
|
224
225
|
const options = {
|
|
@@ -229,7 +230,7 @@ const notificationPlugin = {
|
|
|
229
230
|
data: data.url ? { url: data.url } : undefined,
|
|
230
231
|
};
|
|
231
232
|
|
|
232
|
-
self.registration.showNotification(
|
|
233
|
+
await self.registration.showNotification(
|
|
233
234
|
data.title || 'Уведомление',
|
|
234
235
|
options
|
|
235
236
|
);
|
|
@@ -250,9 +251,19 @@ const notificationPlugin = {
|
|
|
250
251
|
const backgroundSyncPlugin = {
|
|
251
252
|
name: 'background-sync',
|
|
252
253
|
|
|
253
|
-
sync: (event) => {
|
|
254
|
-
|
|
255
|
-
|
|
254
|
+
sync: async (event) => {
|
|
255
|
+
// Тег 'sync-data' регистрируется через:
|
|
256
|
+
// await self.registration.sync.register('sync-data');
|
|
257
|
+
if (event.tag === 'sync-data') {
|
|
258
|
+
await doBackgroundSync();
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
periodicsync: async (event) => {
|
|
263
|
+
// Тег 'content-sync' регистрируется через:
|
|
264
|
+
// await self.registration.periodicSync.register('content-sync', { minInterval: 24 * 60 * 60 * 1000 });
|
|
265
|
+
if (event.tag === 'content-sync') {
|
|
266
|
+
await doPeriodicSync();
|
|
256
267
|
}
|
|
257
268
|
},
|
|
258
269
|
};
|
|
@@ -275,6 +286,38 @@ async function doBackgroundSync() {
|
|
|
275
286
|
}
|
|
276
287
|
}
|
|
277
288
|
}
|
|
289
|
+
|
|
290
|
+
async function doPeriodicSync() {
|
|
291
|
+
// Периодическая синхронизация данных
|
|
292
|
+
try {
|
|
293
|
+
const response = await fetch('/api/sync');
|
|
294
|
+
const data = await response.json();
|
|
295
|
+
|
|
296
|
+
// Сохранение данных в кеш или IndexedDB
|
|
297
|
+
await updateLocalData(data);
|
|
298
|
+
|
|
299
|
+
console.log('Периодическая синхронизация завершена');
|
|
300
|
+
} catch (error) {
|
|
301
|
+
console.error('Ошибка периодической синхронизации:', error);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Регистрация синхронизации из основного потока (main thread):
|
|
306
|
+
//
|
|
307
|
+
// // Фоновая синхронизация (одноразовая)
|
|
308
|
+
// navigator.serviceWorker.ready.then(registration => {
|
|
309
|
+
// return registration.sync.register('sync-data');
|
|
310
|
+
// });
|
|
311
|
+
//
|
|
312
|
+
// // Периодическая синхронизация (требует разрешения)
|
|
313
|
+
// navigator.serviceWorker.ready.then(async registration => {
|
|
314
|
+
// const status = await navigator.permissions.query({ name: 'periodic-background-sync' });
|
|
315
|
+
// if (status.state === 'granted') {
|
|
316
|
+
// await registration.periodicSync.register('content-sync', {
|
|
317
|
+
// minInterval: 24 * 60 * 60 * 1000 // 24 часа
|
|
318
|
+
// });
|
|
319
|
+
// }
|
|
320
|
+
// });
|
|
278
321
|
```
|
|
279
322
|
|
|
280
323
|
## 🎯 Порядок выполнения
|
|
@@ -298,6 +341,111 @@ const plugins = [
|
|
|
298
341
|
// Порядок выполнения: first → second → third → fourth → fifth
|
|
299
342
|
```
|
|
300
343
|
|
|
344
|
+
## ⚡ Логика выполнения обработчиков
|
|
345
|
+
|
|
346
|
+
Разные типы событий Service Worker обрабатываются по-разному в зависимости от их специфики:
|
|
347
|
+
|
|
348
|
+
### 🔄 Параллельное выполнение
|
|
349
|
+
|
|
350
|
+
**События:** `install`, `activate`, `message`, `sync`, `periodicsync`
|
|
351
|
+
|
|
352
|
+
Все обработчики выполняются **одновременно** с помощью `Promise.all()`:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
// Все плагины инициализируются параллельно
|
|
356
|
+
const installPlugin1 = {
|
|
357
|
+
name: 'cache',
|
|
358
|
+
install: async () => {
|
|
359
|
+
/* кеширование */
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
const installPlugin2 = {
|
|
363
|
+
name: 'db',
|
|
364
|
+
install: async () => {
|
|
365
|
+
/* инициализация БД */
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
// Оба install обработчика выполнятся одновременно
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Почему параллельно:**
|
|
373
|
+
|
|
374
|
+
- **install/activate**: Все плагины должны инициализироваться независимо
|
|
375
|
+
- **message**: Все плагины должны получить сообщение одновременно
|
|
376
|
+
- **sync**: Разные задачи синхронизации независимы (синхронизация данных + кеша)
|
|
377
|
+
- **periodicsync**: Периодические задачи независимы друг от друга
|
|
378
|
+
|
|
379
|
+
### ➡️ Последовательное выполнение
|
|
380
|
+
|
|
381
|
+
**События:** `fetch`, `push`
|
|
382
|
+
|
|
383
|
+
Обработчики выполняются **по очереди** до первого успешного результата:
|
|
384
|
+
|
|
385
|
+
#### Fetch - с прерыванием цепочки
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
const authPlugin = {
|
|
389
|
+
name: 'auth',
|
|
390
|
+
priority: 1,
|
|
391
|
+
fetch: async (event) => {
|
|
392
|
+
if (needsAuth(event.request)) {
|
|
393
|
+
return new Response('Unauthorized', { status: 401 }); // Прерывает цепочку
|
|
394
|
+
}
|
|
395
|
+
return null; // Передает следующему плагину
|
|
396
|
+
},
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const cachePlugin = {
|
|
400
|
+
name: 'cache',
|
|
401
|
+
priority: 2,
|
|
402
|
+
fetch: async (event) => {
|
|
403
|
+
return await caches.match(event.request); // Может вернуть Response или null
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
// Выполнение: auth → cache → fetch(event.request) если все вернули null
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
#### Push - без прерывания
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
const notificationPlugin = {
|
|
414
|
+
name: 'notifications',
|
|
415
|
+
push: async (event) => {
|
|
416
|
+
await self.registration.showNotification('Уведомление');
|
|
417
|
+
// Не прерывает выполнение других плагинов
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const analyticsPlugin = {
|
|
422
|
+
name: 'analytics',
|
|
423
|
+
push: async (event) => {
|
|
424
|
+
await sendPushAnalytics(event.data);
|
|
425
|
+
// Выполнится после notifications
|
|
426
|
+
},
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
// Все push обработчики выполнятся последовательно
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Почему последовательно:**
|
|
433
|
+
|
|
434
|
+
- **fetch**: Нужен только один ответ, первый успешный прерывает цепочку
|
|
435
|
+
- **push**: Избегает конфликтов уведомлений, но все плагины должны обработать событие
|
|
436
|
+
|
|
437
|
+
### 📋 Сводная таблица
|
|
438
|
+
|
|
439
|
+
| Событие | Выполнение | Прерывание | Причина |
|
|
440
|
+
| -------------- | --------------- | ---------- | -------------------------------- |
|
|
441
|
+
| `install` | Параллельно | Нет | Независимая инициализация |
|
|
442
|
+
| `activate` | Параллельно | Нет | Независимая активация |
|
|
443
|
+
| `fetch` | Последовательно | Да | Нужен один ответ |
|
|
444
|
+
| `message` | Параллельно | Нет | Все получают сообщение |
|
|
445
|
+
| `sync` | Параллельно | Нет | Независимые задачи |
|
|
446
|
+
| `periodicsync` | Параллельно | Нет | Независимые периодические задачи |
|
|
447
|
+
| `push` | Последовательно | Нет | Избегание конфликтов |
|
|
448
|
+
|
|
301
449
|
## 🛡️ Обработка ошибок
|
|
302
450
|
|
|
303
451
|
- Ошибки в плагинах автоматически перехватываются
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,13 @@ interface SyncEvent extends ExtendableEvent {
|
|
|
2
2
|
readonly tag: string;
|
|
3
3
|
readonly lastChance: boolean;
|
|
4
4
|
}
|
|
5
|
+
interface PeriodicSyncEvent extends ExtendableEvent {
|
|
6
|
+
readonly tag: string;
|
|
7
|
+
}
|
|
5
8
|
declare global {
|
|
6
9
|
interface ServiceWorkerGlobalScopeEventMap {
|
|
7
10
|
sync: SyncEvent;
|
|
11
|
+
periodicsync: PeriodicSyncEvent;
|
|
8
12
|
}
|
|
9
13
|
}
|
|
10
14
|
interface ServiceWorkerEventHandlers {
|
|
@@ -12,8 +16,9 @@ interface ServiceWorkerEventHandlers {
|
|
|
12
16
|
activate?: (event: ExtendableEvent) => void | Promise<void>;
|
|
13
17
|
fetch?: (event: FetchEvent) => Promise<Response | null>;
|
|
14
18
|
message?: (event: MessageEvent) => void;
|
|
15
|
-
sync?: (event: SyncEvent) => void
|
|
16
|
-
|
|
19
|
+
sync?: (event: SyncEvent) => void | Promise<void>;
|
|
20
|
+
periodicsync?: (event: PeriodicSyncEvent) => void | Promise<void>;
|
|
21
|
+
push?: (event: PushEvent) => void | Promise<void>;
|
|
17
22
|
}
|
|
18
23
|
interface ServiceWorkerPlugin extends ServiceWorkerEventHandlers {
|
|
19
24
|
name: string;
|
|
@@ -29,6 +34,7 @@ export declare function createEventHandlers(plugins: ServiceWorkerPlugin[], conf
|
|
|
29
34
|
fetch: (event: FetchEvent) => void;
|
|
30
35
|
message: (event: MessageEvent) => void;
|
|
31
36
|
sync: (event: SyncEvent) => void;
|
|
37
|
+
periodicsync: (event: PeriodicSyncEvent) => void;
|
|
32
38
|
push: (event: PushEvent) => void;
|
|
33
39
|
};
|
|
34
40
|
export declare function initializeServiceWorker(plugins: ServiceWorkerPlugin[], config?: ServiceWorkerConfig): void;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,UAAU,SAAU,SAAQ,eAAe;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAChC;AAGD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,gCAAgC;QACtC,IAAI,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,UAAU,SAAU,SAAQ,eAAe;IACvC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAChC;AAED,UAAU,iBAAkB,SAAQ,eAAe;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACxB;AAGD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,gCAAgC;QACtC,IAAI,EAAE,SAAS,CAAC;QAChB,YAAY,EAAE,iBAAiB,CAAC;KACnC;CACJ;AAED,UAAU,0BAA0B;IAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACxD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,UAAU,mBAAoB,SAAQ,0BAA0B;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,mBAAmB;IACzB,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClD;AAID,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,mBAAmB,EAAE,EAC9B,MAAM,GAAE,mBAAwB,GACjC;IACC,OAAO,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC1C,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC3C,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACjC,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjD,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACpC,CAmIA;AAED,wBAAgB,uBAAuB,CACnC,OAAO,EAAE,mBAAmB,EAAE,EAC9B,MAAM,CAAC,EAAE,mBAAmB,GAC7B,IAAI,CAUN"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export function createEventHandlers(plugins, config = {}) {
|
|
|
5
5
|
fetch: [],
|
|
6
6
|
message: [],
|
|
7
7
|
sync: [],
|
|
8
|
+
periodicsync: [],
|
|
8
9
|
push: [],
|
|
9
10
|
};
|
|
10
11
|
const sortedPlugins = [
|
|
@@ -24,6 +25,8 @@ export function createEventHandlers(plugins, config = {}) {
|
|
|
24
25
|
handlers.message.push(plugin.message);
|
|
25
26
|
if (plugin.sync)
|
|
26
27
|
handlers.sync.push(plugin.sync);
|
|
28
|
+
if (plugin.periodicsync)
|
|
29
|
+
handlers.periodicsync.push(plugin.periodicsync);
|
|
27
30
|
if (plugin.push)
|
|
28
31
|
handlers.push.push(plugin.push);
|
|
29
32
|
});
|
|
@@ -61,14 +64,22 @@ export function createEventHandlers(plugins, config = {}) {
|
|
|
61
64
|
});
|
|
62
65
|
},
|
|
63
66
|
sync: (event) => {
|
|
64
|
-
handlers.sync.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
event.waitUntil(Promise.all(handlers.sync.map((handler) => Promise.resolve(handler(event)).catch((error) => config.onError?.(error, event)))));
|
|
68
|
+
},
|
|
69
|
+
periodicsync: (event) => {
|
|
70
|
+
event.waitUntil(Promise.all(handlers.periodicsync.map((handler) => Promise.resolve(handler(event)).catch((error) => config.onError?.(error, event)))));
|
|
67
71
|
},
|
|
68
72
|
push: (event) => {
|
|
69
|
-
|
|
70
|
-
handler
|
|
71
|
-
|
|
73
|
+
event.waitUntil((async () => {
|
|
74
|
+
for (const handler of handlers.push) {
|
|
75
|
+
try {
|
|
76
|
+
await Promise.resolve(handler(event));
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
config.onError?.(error, event);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
})());
|
|
72
83
|
},
|
|
73
84
|
};
|
|
74
85
|
}
|
|
@@ -79,6 +90,7 @@ export function initializeServiceWorker(plugins, config) {
|
|
|
79
90
|
self.addEventListener('fetch', handlers.fetch);
|
|
80
91
|
self.addEventListener('message', handlers.message);
|
|
81
92
|
self.addEventListener('sync', handlers.sync);
|
|
93
|
+
self.addEventListener('periodicsync', handlers.periodicsync);
|
|
82
94
|
self.addEventListener('push', handlers.push);
|
|
83
95
|
}
|
|
84
96
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -3,10 +3,15 @@ interface SyncEvent extends ExtendableEvent {
|
|
|
3
3
|
readonly lastChance: boolean;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
interface PeriodicSyncEvent extends ExtendableEvent {
|
|
7
|
+
readonly tag: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Extend ServiceWorkerGlobalScope to include sync events
|
|
7
11
|
declare global {
|
|
8
12
|
interface ServiceWorkerGlobalScopeEventMap {
|
|
9
13
|
sync: SyncEvent;
|
|
14
|
+
periodicsync: PeriodicSyncEvent;
|
|
10
15
|
}
|
|
11
16
|
}
|
|
12
17
|
|
|
@@ -15,8 +20,9 @@ interface ServiceWorkerEventHandlers {
|
|
|
15
20
|
activate?: (event: ExtendableEvent) => void | Promise<void>;
|
|
16
21
|
fetch?: (event: FetchEvent) => Promise<Response | null>;
|
|
17
22
|
message?: (event: MessageEvent) => void;
|
|
18
|
-
sync?: (event: SyncEvent) => void
|
|
19
|
-
|
|
23
|
+
sync?: (event: SyncEvent) => void | Promise<void>;
|
|
24
|
+
periodicsync?: (event: PeriodicSyncEvent) => void | Promise<void>;
|
|
25
|
+
push?: (event: PushEvent) => void | Promise<void>;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
interface ServiceWorkerPlugin extends ServiceWorkerEventHandlers {
|
|
@@ -40,6 +46,7 @@ export function createEventHandlers(
|
|
|
40
46
|
fetch: (event: FetchEvent) => void;
|
|
41
47
|
message: (event: MessageEvent) => void;
|
|
42
48
|
sync: (event: SyncEvent) => void;
|
|
49
|
+
periodicsync: (event: PeriodicSyncEvent) => void;
|
|
43
50
|
push: (event: PushEvent) => void;
|
|
44
51
|
} {
|
|
45
52
|
const handlers = {
|
|
@@ -47,8 +54,11 @@ export function createEventHandlers(
|
|
|
47
54
|
activate: [] as ((event: ExtendableEvent) => void | Promise<void>)[],
|
|
48
55
|
fetch: [] as ((event: FetchEvent) => FetchResponse)[],
|
|
49
56
|
message: [] as ((event: MessageEvent) => void)[],
|
|
50
|
-
sync: [] as ((event: SyncEvent) => void)[],
|
|
51
|
-
|
|
57
|
+
sync: [] as ((event: SyncEvent) => void | Promise<void>)[],
|
|
58
|
+
periodicsync: [] as ((
|
|
59
|
+
event: PeriodicSyncEvent
|
|
60
|
+
) => void | Promise<void>)[],
|
|
61
|
+
push: [] as ((event: PushEvent) => void | Promise<void>)[],
|
|
52
62
|
};
|
|
53
63
|
|
|
54
64
|
// Здесь происходит сортировка плагинов по их приоритету.
|
|
@@ -69,6 +79,8 @@ export function createEventHandlers(
|
|
|
69
79
|
if (plugin.fetch) handlers.fetch.push(plugin.fetch);
|
|
70
80
|
if (plugin.message) handlers.message.push(plugin.message);
|
|
71
81
|
if (plugin.sync) handlers.sync.push(plugin.sync);
|
|
82
|
+
if (plugin.periodicsync)
|
|
83
|
+
handlers.periodicsync.push(plugin.periodicsync);
|
|
72
84
|
if (plugin.push) handlers.push.push(plugin.push);
|
|
73
85
|
});
|
|
74
86
|
|
|
@@ -128,15 +140,43 @@ export function createEventHandlers(
|
|
|
128
140
|
},
|
|
129
141
|
|
|
130
142
|
sync: (event: SyncEvent): void => {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
143
|
+
event.waitUntil(
|
|
144
|
+
Promise.all(
|
|
145
|
+
handlers.sync.map((handler) =>
|
|
146
|
+
Promise.resolve(handler(event)).catch(
|
|
147
|
+
(error: unknown) =>
|
|
148
|
+
config.onError?.(error as Error, event)
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
);
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
periodicsync: (event: PeriodicSyncEvent): void => {
|
|
156
|
+
event.waitUntil(
|
|
157
|
+
Promise.all(
|
|
158
|
+
handlers.periodicsync.map((handler) =>
|
|
159
|
+
Promise.resolve(handler(event)).catch(
|
|
160
|
+
(error: unknown) =>
|
|
161
|
+
config.onError?.(error as Error, event)
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
);
|
|
134
166
|
},
|
|
135
167
|
|
|
136
168
|
push: (event: PushEvent): void => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
169
|
+
event.waitUntil(
|
|
170
|
+
(async (): Promise<void> => {
|
|
171
|
+
for (const handler of handlers.push) {
|
|
172
|
+
try {
|
|
173
|
+
await Promise.resolve(handler(event));
|
|
174
|
+
} catch (error) {
|
|
175
|
+
config.onError?.(error as Error, event);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
})()
|
|
179
|
+
);
|
|
140
180
|
},
|
|
141
181
|
};
|
|
142
182
|
}
|
|
@@ -152,5 +192,6 @@ export function initializeServiceWorker(
|
|
|
152
192
|
self.addEventListener('fetch', handlers.fetch);
|
|
153
193
|
self.addEventListener('message', handlers.message);
|
|
154
194
|
self.addEventListener('sync', handlers.sync);
|
|
195
|
+
self.addEventListener('periodicsync', handlers.periodicsync);
|
|
155
196
|
self.addEventListener('push', handlers.push);
|
|
156
197
|
}
|