@budarin/pluggable-serviceworker 1.5.0 → 1.5.1
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 +31 -23
- package/dist/plugins/claimAndReloadClients.js +5 -5
- package/dist/plugins/skipWaitingOnMessage.js +2 -1
- package/dist/sw/activateImmediately.d.ts +1 -1
- package/dist/sw/activateImmediately.js +2 -2
- package/dist/sw/activateOnNextVisit.d.ts +1 -1
- package/dist/sw/activateOnNextVisit.js +1 -1
- package/dist/utils/openCacheAndMatch.d.ts +4 -0
- package/dist/utils/openCacheAndMatch.js +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -440,6 +440,7 @@ function authPlugin(config: {
|
|
|
440
440
|
if (protectedPaths.some((p) => path.startsWith(p))) {
|
|
441
441
|
if (needsAuth(event.request)) {
|
|
442
442
|
logger.warn('auth: unauthorized', event.request.url);
|
|
443
|
+
|
|
443
444
|
return new Response('Unauthorized', { status: 401 }); // Прерывает цепочку
|
|
444
445
|
}
|
|
445
446
|
}
|
|
@@ -454,7 +455,7 @@ function authPlugin(config: {
|
|
|
454
455
|
**Почему последовательно:**
|
|
455
456
|
|
|
456
457
|
- **fetch**: Нужен только один ответ на текущий запрос браузера, первый успешный прерывает цепочку. Если никто не вернул ответ — выполняется `fetch(event.request)`
|
|
457
|
-
- **push**: Плагин может вернуть `PushNotificationPayload`, `false` (не показывать) или `undefined` (решение отдаётся библиотеке). Библиотека вызывает `showNotification` для каждого payload. Не показываем, если все вернули `false` или смесь без payload. Библиотека показывает
|
|
458
|
+
- **push**: Плагин может вернуть `PushNotificationPayload`, `false` (не показывать) или `undefined` (решение отдаётся библиотеке). Библиотека вызывает `showNotification` для каждого payload. Не показываем, если все вернули `false` или смесь без payload. Библиотека показывает нотификацию и в случае когда **все** плагины вернули `undefined`.
|
|
458
459
|
|
|
459
460
|
### 📋 Сводная таблица
|
|
460
461
|
|
|
@@ -479,19 +480,19 @@ function authPlugin(config: {
|
|
|
479
480
|
| Название | Событие | Описание |
|
|
480
481
|
| ------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
481
482
|
| `precache*(config)` | `install` | Кеширует список ресурсов из `config.assets` в кеш `config.cacheName`. |
|
|
482
|
-
| `precacheAndNotify(config)` | install
|
|
483
|
+
| `precacheAndNotify(config)` | `install` | Как **precache**, затем отправляет активным клиентам сообщение `{ type: config.messageType }` (по умолчанию `SW_INSTALLED`). |
|
|
483
484
|
| `precacheMissing(config)` | `install` | Добавляет в кеш только те ресурсы из `config.assets`, которых ещё нет в кеше. |
|
|
484
485
|
| `pruneStaleCache(config)` | `activate` | Удаляет из кеша записи, чей URL не входит в `config.assets`. |
|
|
485
|
-
| `skipWaiting
|
|
486
|
+
| `skipWaiting` | `install` | Вызывает `skipWaiting()`. |
|
|
486
487
|
| `claim` | `activate` | Вызывает `clients.claim()`. |
|
|
487
488
|
| `reloadClients` | `activate` | Перезагружает все окна-клиенты через `client.navigate(client.url)`. |
|
|
488
489
|
| `claimAndReloadClients` | `activate` | Композиция **claim** + **reloadClients**: сначала claim, затем перезагрузка (порядок гарантирован — один плагин). |
|
|
489
490
|
| `skipWaitingOnMessage(config?)` | `message` | При сообщении с `event.data.type === 'SW_MSG_SKIP_WAITING'` вызывает `skipWaiting()`. |
|
|
490
491
|
| `serveFromCache(config)` | `fetch` | Отдаёт ресурс из кеша `config.cacheName`; при отсутствии его в кэше — undefined. |
|
|
491
492
|
| `restoreAssetToCache(config)` | `fetch` | Для URL из `config.assets`: отдам ресурс из кеша или запрашиваем по сети, затем в кладем кго в кеш. Иначе — undefined. |
|
|
492
|
-
| cacheFirst(config)`
|
|
493
|
+
| `cacheFirst(config)` | `fetch` | Отдаем ресурс из кэша `config.cacheName`: при отсутствии его в кэше — делаем запрос на сервер и затем кладем ответ в кэш. |
|
|
493
494
|
| `networkFirst(config)` | `fetch` | Делаем запрос на сервер, при успехе — кладем его в кэш. При ошибке — отдаем из кэша. Иначе - `undefined`. |
|
|
494
|
-
| `staleWhileRevalidate(config)` | fetch
|
|
495
|
+
| `staleWhileRevalidate(config)` | `fetch` | Отдаёт из кэша, в фоне обновляет кэш. |
|
|
495
496
|
|
|
496
497
|
#### Композиция примитивов
|
|
497
498
|
|
|
@@ -499,32 +500,29 @@ function authPlugin(config: {
|
|
|
499
500
|
|
|
500
501
|
**Пример: claimAndReloadClients как композиция двух примитивов**
|
|
501
502
|
|
|
502
|
-
Плагин **claimAndReloadClients**
|
|
503
|
+
Плагин **claimAndReloadClients** вызывает существующие примитивы **claim** и **reloadClients** по очереди:
|
|
503
504
|
|
|
504
505
|
```typescript
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
self.clients.claim().then(() =>
|
|
508
|
-
self.clients
|
|
509
|
-
.matchAll({ type: 'window' })
|
|
510
|
-
.then((list) =>
|
|
511
|
-
Promise.all(list.map((client) => client.navigate(client.url)))
|
|
512
|
-
)
|
|
513
|
-
),
|
|
514
|
-
```
|
|
506
|
+
import { claim } from '@budarin/pluggable-serviceworker/plugins';
|
|
507
|
+
import { reloadClients } from '@budarin/pluggable-serviceworker/plugins';
|
|
515
508
|
|
|
516
|
-
|
|
509
|
+
const claimPlugin = claim();
|
|
510
|
+
const reloadPlugin = reloadClients();
|
|
517
511
|
|
|
518
|
-
|
|
519
|
-
|
|
512
|
+
activate: (event, logger) =>
|
|
513
|
+
Promise.resolve(claimPlugin.activate(event, logger)).then(() =>
|
|
514
|
+
reloadPlugin.activate(event, logger)
|
|
515
|
+
),
|
|
520
516
|
```
|
|
521
517
|
|
|
522
518
|
**Пример: кастомный кэш и логика по URL**
|
|
523
519
|
|
|
524
|
-
Фабрика `postsSwrPlugin(config)` возвращает плагин, который применяет stale-while-revalidate только к запросам, подходящим под `pathPattern`.
|
|
520
|
+
Фабрика `postsSwrPlugin(config)` возвращает плагин, который применяет `stale-while-revalidate`(SWR) только к запросам, подходящим под `pathPattern`.
|
|
525
521
|
|
|
526
522
|
```typescript
|
|
523
|
+
// postsSwrPlugin.ts
|
|
527
524
|
import type { Plugin } from '@budarin/pluggable-serviceworker';
|
|
525
|
+
|
|
528
526
|
import {
|
|
529
527
|
precache,
|
|
530
528
|
serveFromCache,
|
|
@@ -536,28 +534,39 @@ function postsSwrPlugin(config: {
|
|
|
536
534
|
pathPattern?: RegExp;
|
|
537
535
|
}): Plugin {
|
|
538
536
|
const { cacheName, pathPattern = /\/api\/posts(\/|$)/ } = config;
|
|
537
|
+
|
|
539
538
|
return {
|
|
540
539
|
name: 'postsSwr',
|
|
541
540
|
order: 0,
|
|
541
|
+
|
|
542
542
|
fetch: async (event) => {
|
|
543
|
-
if (!pathPattern.test(new URL(event.request.url).pathname))
|
|
543
|
+
if (!pathPattern.test(new URL(event.request.url).pathname)) {
|
|
544
544
|
return undefined;
|
|
545
|
+
}
|
|
546
|
+
|
|
545
547
|
const cache = await caches.open(cacheName);
|
|
546
548
|
const cached = await cache.match(event.request);
|
|
547
549
|
const revalidate = fetch(event.request).then(async (response) => {
|
|
548
|
-
if (response.ok)
|
|
550
|
+
if (response.ok) {
|
|
549
551
|
await cache.put(event.request, response.clone());
|
|
552
|
+
}
|
|
553
|
+
|
|
550
554
|
return response;
|
|
551
555
|
});
|
|
556
|
+
|
|
552
557
|
if (cached) {
|
|
553
558
|
void revalidate;
|
|
554
559
|
return cached;
|
|
555
560
|
}
|
|
561
|
+
|
|
556
562
|
return revalidate;
|
|
557
563
|
},
|
|
558
564
|
};
|
|
559
565
|
}
|
|
566
|
+
```
|
|
560
567
|
|
|
568
|
+
```typescript
|
|
569
|
+
// sw.ts
|
|
561
570
|
const staticCache = 'static-v1';
|
|
562
571
|
const assets = ['/', '/main.js'];
|
|
563
572
|
|
|
@@ -580,7 +589,6 @@ initServiceWorker(
|
|
|
580
589
|
| `offlineFirst(config)` | `precache(config) + serveFromCache(config)` | Статика из кеша, при отсутствии ресурса в кэше — делаем запрос к серверу. |
|
|
581
590
|
|
|
582
591
|
Конфиг пресета: `OfflineFirstConfig` (cacheName, assets). Импорт из `@budarin/pluggable-serviceworker/presets`.
|
|
583
|
-
|
|
584
592
|
Стратегии **networkFirst**, **staleWhileRevalidate** и др. доступны как примитивы — собирайте свой кастомный сервис-воркер из примитивов и пресетов.
|
|
585
593
|
|
|
586
594
|
### Типовые сервис-воркеры (из коробки)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { claim } from './claim.js';
|
|
2
|
+
import { reloadClients } from './reloadClients.js';
|
|
1
3
|
export function claimAndReloadClients() {
|
|
4
|
+
const claimPlugin = claim();
|
|
5
|
+
const reloadPlugin = reloadClients();
|
|
2
6
|
return {
|
|
3
7
|
name: 'claimAndReloadClients',
|
|
4
|
-
activate: () =>
|
|
5
|
-
.claim()
|
|
6
|
-
.then(() => self.clients
|
|
7
|
-
.matchAll({ type: 'window' })
|
|
8
|
-
.then((list) => Promise.all(list.map((client) => client.navigate(client.url))))),
|
|
8
|
+
activate: (event, logger) => Promise.resolve(claimPlugin.activate(event, logger)).then(() => reloadPlugin.activate(event, logger)),
|
|
9
9
|
};
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ServiceWorkerInitOptions } from '../index.js';
|
|
2
|
-
import {
|
|
2
|
+
import type { OfflineFirstConfig } from '../presets/offlineFirst.js';
|
|
3
3
|
export interface ActivateImmediatelyOptions extends ServiceWorkerInitOptions, OfflineFirstConfig {
|
|
4
4
|
}
|
|
5
5
|
export declare function activateImmediatelyServiceWorker(options: ActivateImmediatelyOptions): void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { claim } from '../plugins/claim.js';
|
|
1
2
|
import { initServiceWorker } from '../index.js';
|
|
2
|
-
import { offlineFirst, } from '../presets/offlineFirst.js';
|
|
3
3
|
import { skipWaiting } from '../plugins/skipWaiting.js';
|
|
4
|
-
import {
|
|
4
|
+
import { offlineFirst } from '../presets/offlineFirst.js';
|
|
5
5
|
export function activateImmediatelyServiceWorker(options) {
|
|
6
6
|
initServiceWorker([...offlineFirst(options), skipWaiting, claim], options);
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ServiceWorkerInitOptions } from '../index.js';
|
|
2
|
-
import {
|
|
2
|
+
import type { OfflineFirstConfig } from '../presets/offlineFirst.js';
|
|
3
3
|
export interface ActivateOnNextVisitOptions extends ServiceWorkerInitOptions, OfflineFirstConfig {
|
|
4
4
|
}
|
|
5
5
|
export declare function activateOnNextVisitServiceWorker(options: ActivateOnNextVisitOptions): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { initServiceWorker } from '../index.js';
|
|
2
|
-
import { offlineFirst
|
|
2
|
+
import { offlineFirst } from '../presets/offlineFirst.js';
|
|
3
3
|
export function activateOnNextVisitServiceWorker(options) {
|
|
4
4
|
initServiceWorker(offlineFirst(options), options);
|
|
5
5
|
}
|