@budarin/pluggable-serviceworker 1.2.1 → 1.5.0

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.
Files changed (96) hide show
  1. package/README.md +339 -159
  2. package/dist/index.d.ts +16 -23
  3. package/dist/index.js +61 -17
  4. package/dist/plugins/cacheFirst.d.ts +5 -3
  5. package/dist/plugins/cacheFirst.js +22 -19
  6. package/dist/plugins/claim.d.ts +2 -3
  7. package/dist/plugins/claim.js +6 -7
  8. package/dist/plugins/claimAndReloadClients.d.ts +2 -0
  9. package/dist/plugins/claimAndReloadClients.js +10 -0
  10. package/dist/plugins/index.d.ts +9 -5
  11. package/dist/plugins/index.js +9 -5
  12. package/dist/plugins/networkFirst.d.ts +5 -3
  13. package/dist/plugins/networkFirst.js +18 -16
  14. package/dist/plugins/precache.d.ts +6 -3
  15. package/dist/plugins/precache.js +10 -8
  16. package/dist/plugins/precacheAndNotify.d.ts +6 -0
  17. package/dist/plugins/precacheAndNotify.js +13 -0
  18. package/dist/plugins/precacheMissing.d.ts +6 -0
  19. package/dist/plugins/precacheMissing.js +16 -0
  20. package/dist/plugins/pruneStaleCache.d.ts +6 -0
  21. package/dist/plugins/pruneStaleCache.js +17 -0
  22. package/dist/plugins/reloadClients.d.ts +2 -0
  23. package/dist/plugins/reloadClients.js +9 -0
  24. package/dist/plugins/restoreAssetToCache.d.ts +6 -3
  25. package/dist/plugins/restoreAssetToCache.js +22 -37
  26. package/dist/plugins/serveFromCache.d.ts +5 -3
  27. package/dist/plugins/serveFromCache.js +10 -11
  28. package/dist/plugins/skipWaiting.d.ts +2 -3
  29. package/dist/plugins/skipWaiting.js +8 -7
  30. package/dist/plugins/skipWaitingOnMessage.d.ts +5 -0
  31. package/dist/plugins/skipWaitingOnMessage.js +12 -0
  32. package/dist/plugins/staleWhileRevalidate.d.ts +5 -3
  33. package/dist/plugins/staleWhileRevalidate.js +20 -18
  34. package/dist/presets/index.d.ts +1 -2
  35. package/dist/presets/index.js +0 -1
  36. package/dist/presets/offlineFirst.d.ts +6 -3
  37. package/dist/presets/offlineFirst.js +3 -5
  38. package/dist/sw/activateImmediately.d.ts +5 -3
  39. package/dist/sw/activateImmediately.js +3 -4
  40. package/dist/sw/activateOnNextVisit.d.ts +5 -3
  41. package/dist/sw/activateOnNextVisit.js +3 -4
  42. package/dist/sw/activateOnSignal.d.ts +6 -3
  43. package/dist/sw/activateOnSignal.js +11 -5
  44. package/dist/sw/index.d.ts +0 -1
  45. package/dist/sw/index.js +0 -1
  46. package/dist/utils/index.d.ts +2 -0
  47. package/dist/utils/index.js +2 -0
  48. package/dist/utils/isAssetRequest.d.ts +1 -0
  49. package/dist/utils/isAssetRequest.js +10 -0
  50. package/dist/utils/isRequestUrlInAssets.d.ts +1 -0
  51. package/dist/utils/isRequestUrlInAssets.js +10 -0
  52. package/dist/utils/normalizeUrl.d.ts +1 -0
  53. package/dist/utils/normalizeUrl.js +3 -0
  54. package/dist/utils/notifyClients.d.ts +1 -0
  55. package/dist/utils/notifyClients.js +4 -0
  56. package/package.json +11 -8
  57. package/dist/index.d.ts.map +0 -1
  58. package/dist/index.js.map +0 -1
  59. package/dist/plugins/cacheFirst.d.ts.map +0 -1
  60. package/dist/plugins/cacheFirst.js.map +0 -1
  61. package/dist/plugins/claim.d.ts.map +0 -1
  62. package/dist/plugins/claim.js.map +0 -1
  63. package/dist/plugins/claimOnMessage.d.ts +0 -3
  64. package/dist/plugins/claimOnMessage.d.ts.map +0 -1
  65. package/dist/plugins/claimOnMessage.js +0 -11
  66. package/dist/plugins/claimOnMessage.js.map +0 -1
  67. package/dist/plugins/index.d.ts.map +0 -1
  68. package/dist/plugins/index.js.map +0 -1
  69. package/dist/plugins/networkFirst.d.ts.map +0 -1
  70. package/dist/plugins/networkFirst.js.map +0 -1
  71. package/dist/plugins/networkOnly.d.ts +0 -3
  72. package/dist/plugins/networkOnly.d.ts.map +0 -1
  73. package/dist/plugins/networkOnly.js +0 -5
  74. package/dist/plugins/networkOnly.js.map +0 -1
  75. package/dist/plugins/precache.d.ts.map +0 -1
  76. package/dist/plugins/precache.js.map +0 -1
  77. package/dist/plugins/restoreAssetToCache.d.ts.map +0 -1
  78. package/dist/plugins/restoreAssetToCache.js.map +0 -1
  79. package/dist/plugins/serveFromCache.d.ts.map +0 -1
  80. package/dist/plugins/serveFromCache.js.map +0 -1
  81. package/dist/plugins/skipWaiting.d.ts.map +0 -1
  82. package/dist/plugins/skipWaiting.js.map +0 -1
  83. package/dist/plugins/staleWhileRevalidate.d.ts.map +0 -1
  84. package/dist/plugins/staleWhileRevalidate.js.map +0 -1
  85. package/dist/presets/index.d.ts.map +0 -1
  86. package/dist/presets/index.js.map +0 -1
  87. package/dist/presets/offlineFirst.d.ts.map +0 -1
  88. package/dist/presets/offlineFirst.js.map +0 -1
  89. package/dist/sw/activateImmediately.d.ts.map +0 -1
  90. package/dist/sw/activateImmediately.js.map +0 -1
  91. package/dist/sw/activateOnNextVisit.d.ts.map +0 -1
  92. package/dist/sw/activateOnNextVisit.js.map +0 -1
  93. package/dist/sw/activateOnSignal.d.ts.map +0 -1
  94. package/dist/sw/activateOnSignal.js.map +0 -1
  95. package/dist/sw/index.d.ts.map +0 -1
  96. package/dist/sw/index.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -30,42 +30,36 @@ export interface Logger {
30
30
  warn: (...data: unknown[]) => void;
31
31
  error: (...data: unknown[]) => void;
32
32
  }
33
- export interface SwContext {
33
+ export interface PluginContext {
34
34
  logger?: Logger;
35
35
  }
36
- export interface ServiceWorkerInitOptions extends SwContext {
36
+ export interface ServiceWorkerInitOptions extends PluginContext {
37
37
  onError?: (error: Error | unknown, event: Event, errorType?: ServiceWorkerErrorType) => void;
38
38
  }
39
39
  export type PushNotificationPayload = {
40
40
  title: string;
41
41
  } & NotificationOptions;
42
- export interface OfflineFirstContext extends SwContext {
43
- assets: string[];
44
- cacheName: string;
45
- claimMessageType?: string;
46
- cacheMatchIgnoreSearch?: boolean;
47
- }
48
42
  export declare function __resetServiceWorkerState(): void;
49
- export type ContextOfPlugin<P> = P extends ServiceWorkerPlugin<infer C> ? C : SwContext;
43
+ export type ContextOfPlugin<P> = P extends ServiceWorkerPlugin<infer C> ? C : PluginContext;
50
44
  export type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
51
- export type AnyServiceWorkerPlugin = ServiceWorkerPlugin<SwContext> | ServiceWorkerPlugin<OfflineFirstContext>;
52
- export type RequiredOptions<P extends readonly AnyServiceWorkerPlugin[]> = UnionToIntersection<ContextOfPlugin<P[number]>>;
53
- interface ServiceWorkerEventHandlers<C extends SwContext = SwContext> {
54
- install?: (event: ExtendableEvent, context: C) => void | Promise<void>;
55
- activate?: (event: ExtendableEvent, context: C) => void | Promise<void>;
56
- fetch?: (event: FetchEvent, context: C) => Promise<Response | undefined>;
57
- message?: (event: SwMessageEvent, context: C) => void;
58
- sync?: (event: SyncEvent, context: C) => Promise<void>;
59
- periodicsync?: (event: PeriodicSyncEvent, context: C) => Promise<void>;
60
- push?: (event: PushEvent, context: C) => void | PushNotificationPayload | Promise<void | PushNotificationPayload>;
45
+ export type RequiredOptions<P extends readonly unknown[]> = UnionToIntersection<ContextOfPlugin<P[number]>>;
46
+ interface ServiceWorkerEventHandlers {
47
+ install?: (event: ExtendableEvent, logger: Logger) => void | Promise<void>;
48
+ activate?: (event: ExtendableEvent, logger: Logger) => void | Promise<void>;
49
+ fetch?: (event: FetchEvent, logger: Logger) => Promise<Response | undefined>;
50
+ message?: (event: SwMessageEvent, logger: Logger) => void;
51
+ sync?: (event: SyncEvent, logger: Logger) => Promise<void>;
52
+ periodicsync?: (event: PeriodicSyncEvent, logger: Logger) => Promise<void>;
53
+ push?: (event: PushEvent, logger: Logger) => void | PushNotificationPayload | false | Promise<void | PushNotificationPayload | false>;
61
54
  }
62
- export interface ServiceWorkerPlugin<C extends SwContext = SwContext> extends ServiceWorkerEventHandlers<C> {
55
+ export interface ServiceWorkerPlugin<_C extends PluginContext = PluginContext> extends ServiceWorkerEventHandlers {
63
56
  name: string;
64
57
  order?: number;
65
58
  }
59
+ export type Plugin = ServiceWorkerPlugin<PluginContext>;
66
60
  export type ServiceWorkerConfig = ServiceWorkerInitOptions;
67
61
  export type FetchResponse = Promise<Response | undefined>;
68
- export declare function createEventHandlers<C extends SwContext>(plugins: readonly ServiceWorkerPlugin<C>[], options: C & ServiceWorkerInitOptions): {
62
+ export declare function createEventHandlers<_C extends PluginContext = PluginContext>(plugins: readonly ServiceWorkerPlugin<_C>[], options: _C & ServiceWorkerInitOptions): {
69
63
  install: (event: ExtendableEvent) => void;
70
64
  activate: (event: ExtendableEvent) => void;
71
65
  fetch: (event: FetchEvent) => void;
@@ -78,6 +72,5 @@ export declare function createEventHandlers<C extends SwContext>(plugins: readon
78
72
  unhandledrejection: (event: PromiseRejectionEvent) => void;
79
73
  rejectionhandled: (event: PromiseRejectionEvent) => void;
80
74
  };
81
- export declare function initServiceWorker<P extends readonly AnyServiceWorkerPlugin[]>(plugins: P, options: RequiredOptions<P> & ServiceWorkerInitOptions): void;
75
+ export declare function initServiceWorker<P extends readonly unknown[]>(plugins: P, options: RequiredOptions<P> & ServiceWorkerInitOptions): void;
82
76
  export {};
83
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { SW_EVENT_PUSH, SW_EVENT_SYNC, SW_EVENT_ERROR, SW_EVENT_FETCH, SW_EVENT_INSTALL, SW_EVENT_MESSAGE, SW_EVENT_ACTIVATE, SW_EVENT_PERIODICSYNC, SW_EVENT_MESSAGEERROR, SW_EVENT_REJECTIONHANDLED, SW_EVENT_UNHANDLEDREJECTION, } from '@budarin/http-constants';
1
+ import { SW_EVENT_PUSH, SW_EVENT_SYNC, SW_EVENT_ERROR, SW_EVENT_FETCH, SW_EVENT_INSTALL, SW_EVENT_MESSAGE, SW_EVENT_ACTIVATE, SW_EVENT_PERIODICSYNC, SW_EVENT_MESSAGEERROR, SW_EVENT_REJECTIONHANDLED, SW_EVENT_UNHANDLEDREJECTION, } from '@budarin/http-constants/service-worker';
2
2
  export var ServiceWorkerErrorType;
3
3
  (function (ServiceWorkerErrorType) {
4
4
  ServiceWorkerErrorType["ERROR"] = "error";
@@ -47,19 +47,19 @@ export function createEventHandlers(plugins, options) {
47
47
  return {
48
48
  install: (event) => {
49
49
  event.waitUntil(Promise.all(handlers.install.map((handler) => Promise.resolve()
50
- .then(() => handler(event, options))
50
+ .then(() => handler(event, logger))
51
51
  .catch((error) => options.onError?.(error, event, ServiceWorkerErrorType.PLUGIN_ERROR)))));
52
52
  },
53
53
  activate: (event) => {
54
54
  event.waitUntil(Promise.all(handlers.activate.map((handler) => Promise.resolve()
55
- .then(() => handler(event, options))
55
+ .then(() => handler(event, logger))
56
56
  .catch((error) => options.onError?.(error, event, ServiceWorkerErrorType.PLUGIN_ERROR)))));
57
57
  },
58
58
  fetch: (event) => {
59
59
  event.respondWith((async () => {
60
60
  for (const handler of handlers.fetch) {
61
61
  try {
62
- const result = await handler(event, options);
62
+ const result = await handler(event, logger);
63
63
  if (result !== undefined) {
64
64
  return result;
65
65
  }
@@ -83,7 +83,7 @@ export function createEventHandlers(plugins, options) {
83
83
  message: (event) => {
84
84
  handlers.message.forEach((handler) => {
85
85
  try {
86
- handler(event, options);
86
+ handler(event, logger);
87
87
  }
88
88
  catch (error) {
89
89
  options.onError?.(error, event, ServiceWorkerErrorType.PLUGIN_ERROR);
@@ -92,31 +92,76 @@ export function createEventHandlers(plugins, options) {
92
92
  },
93
93
  sync: (event) => {
94
94
  event.waitUntil(Promise.all(handlers.sync.map((handler) => Promise.resolve()
95
- .then(() => handler(event, options))
95
+ .then(() => handler(event, logger))
96
96
  .catch((error) => options.onError?.(error, event, ServiceWorkerErrorType.PLUGIN_ERROR)))));
97
97
  },
98
98
  periodicsync: (event) => {
99
99
  event.waitUntil(Promise.all(handlers.periodicsync.map((handler) => Promise.resolve()
100
- .then(() => handler(event, options))
100
+ .then(() => handler(event, logger))
101
101
  .catch((error) => options.onError?.(error, event, ServiceWorkerErrorType.PLUGIN_ERROR)))));
102
102
  },
103
103
  push: (event) => {
104
104
  event.waitUntil((async () => {
105
+ const returns = [];
105
106
  for (const handler of handlers.push) {
106
107
  try {
107
- const result = await Promise.resolve(handler(event, options));
108
- if (result != null &&
109
- typeof result === 'object' &&
110
- 'title' in result &&
111
- typeof result.title === 'string') {
112
- const { title, ...opts } = result;
113
- await self.registration.showNotification(title, opts);
114
- return;
115
- }
108
+ const result = await Promise.resolve(handler(event, logger));
109
+ returns.push(result);
116
110
  }
117
111
  catch (error) {
118
112
  options.onError?.(error, event, ServiceWorkerErrorType.PLUGIN_ERROR);
113
+ returns.push(undefined);
114
+ }
115
+ }
116
+ const payloads = returns.filter((r) => r != null &&
117
+ typeof r === 'object' &&
118
+ !Array.isArray(r) &&
119
+ 'title' in r &&
120
+ typeof r.title === 'string');
121
+ if (returns.length === handlers.push.length &&
122
+ returns.every((r) => r === false)) {
123
+ return;
124
+ }
125
+ for (const payload of payloads) {
126
+ const { title, ...opts } = payload;
127
+ await self.registration.showNotification(title, opts);
128
+ }
129
+ if (payloads.length > 0) {
130
+ return;
131
+ }
132
+ if (!returns.every((r) => r === undefined))
133
+ return;
134
+ try {
135
+ const data = event.data;
136
+ if (!data) {
137
+ return;
119
138
  }
139
+ let payload;
140
+ try {
141
+ payload = await data.json();
142
+ }
143
+ catch {
144
+ const text = data.text();
145
+ payload = text.length > 0 ? { title: text } : null;
146
+ }
147
+ if (payload == null) {
148
+ return;
149
+ }
150
+ const withTitle = typeof payload === 'object' &&
151
+ payload !== null &&
152
+ 'title' in payload &&
153
+ typeof payload.title ===
154
+ 'string'
155
+ ? payload
156
+ : null;
157
+ if (withTitle == null) {
158
+ return;
159
+ }
160
+ const { title, ...opts } = withTitle;
161
+ await self.registration.showNotification(title, opts);
162
+ }
163
+ catch (error) {
164
+ options.onError?.(error, event, ServiceWorkerErrorType.PLUGIN_ERROR);
120
165
  }
121
166
  })());
122
167
  },
@@ -180,4 +225,3 @@ export function initServiceWorker(plugins, options) {
180
225
  self.addEventListener(SW_EVENT_PERIODICSYNC, handlers.periodicsync);
181
226
  self.addEventListener(SW_EVENT_PUSH, handlers.push);
182
227
  }
183
- //# sourceMappingURL=index.js.map
@@ -1,3 +1,5 @@
1
- import type { ServiceWorkerPlugin, OfflineFirstContext } from '../index.js';
2
- export declare const cacheFirst: ServiceWorkerPlugin<OfflineFirstContext>;
3
- //# sourceMappingURL=cacheFirst.d.ts.map
1
+ import type { Plugin } from '../index.js';
2
+ export interface CacheFirstConfig {
3
+ cacheName: string;
4
+ }
5
+ export declare function cacheFirst(config: CacheFirstConfig): Plugin;
@@ -1,20 +1,23 @@
1
- export const cacheFirst = {
2
- name: 'cacheFirst',
3
- fetch: async (event, context) => {
4
- const cache = await caches.open(context.cacheName);
5
- const cached = await cache.match(event.request);
6
- if (cached)
7
- return cached;
8
- try {
9
- const response = await fetch(event.request);
10
- if (response.ok) {
11
- await cache.put(event.request, response.clone());
1
+ export function cacheFirst(config) {
2
+ const { cacheName } = config;
3
+ return {
4
+ name: 'cacheFirst',
5
+ fetch: async (event) => {
6
+ const cache = await caches.open(cacheName);
7
+ const cached = await cache.match(event.request);
8
+ if (cached) {
9
+ return cached;
12
10
  }
13
- return response;
14
- }
15
- catch {
16
- return undefined;
17
- }
18
- },
19
- };
20
- //# sourceMappingURL=cacheFirst.js.map
11
+ try {
12
+ const response = await fetch(event.request);
13
+ if (response.ok) {
14
+ await cache.put(event.request, response.clone());
15
+ }
16
+ return response;
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ },
22
+ };
23
+ }
@@ -1,3 +1,2 @@
1
- import type { ServiceWorkerPlugin } from '../index.js';
2
- export declare const claim: ServiceWorkerPlugin;
3
- //# sourceMappingURL=claim.d.ts.map
1
+ import type { Plugin } from '../index.js';
2
+ export declare function claim(): Plugin;
@@ -1,7 +1,6 @@
1
- export const claim = {
2
- name: 'claim',
3
- activate: (event, _context) => {
4
- event.waitUntil(Promise.resolve().then(() => self.clients.claim()));
5
- },
6
- };
7
- //# sourceMappingURL=claim.js.map
1
+ export function claim() {
2
+ return {
3
+ name: 'claim',
4
+ activate: () => self.clients.claim(),
5
+ };
6
+ }
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from '../index.js';
2
+ export declare function claimAndReloadClients(): Plugin;
@@ -0,0 +1,10 @@
1
+ export function claimAndReloadClients() {
2
+ return {
3
+ name: 'claimAndReloadClients',
4
+ activate: () => self.clients
5
+ .claim()
6
+ .then(() => self.clients
7
+ .matchAll({ type: 'window' })
8
+ .then((list) => Promise.all(list.map((client) => client.navigate(client.url))))),
9
+ };
10
+ }
@@ -1,10 +1,14 @@
1
+ export { claim } from './claim.js';
1
2
  export { precache } from './precache.js';
3
+ export { cacheFirst } from './cacheFirst.js';
2
4
  export { skipWaiting } from './skipWaiting.js';
3
- export { claim } from './claim.js';
4
- export { claimOnMessage } from './claimOnMessage.js';
5
+ export { networkFirst } from './networkFirst.js';
6
+ export { reloadClients } from './reloadClients.js';
5
7
  export { serveFromCache } from './serveFromCache.js';
8
+ export { precacheMissing } from './precacheMissing.js';
9
+ export { pruneStaleCache } from './pruneStaleCache.js';
10
+ export { precacheAndNotify } from './precacheAndNotify.js';
6
11
  export { restoreAssetToCache } from './restoreAssetToCache.js';
7
- export { cacheFirst } from './cacheFirst.js';
8
- export { networkFirst } from './networkFirst.js';
12
+ export { skipWaitingOnMessage } from './skipWaitingOnMessage.js';
9
13
  export { staleWhileRevalidate } from './staleWhileRevalidate.js';
10
- //# sourceMappingURL=index.d.ts.map
14
+ export { claimAndReloadClients } from './claimAndReloadClients.js';
@@ -1,10 +1,14 @@
1
+ export { claim } from './claim.js';
1
2
  export { precache } from './precache.js';
3
+ export { cacheFirst } from './cacheFirst.js';
2
4
  export { skipWaiting } from './skipWaiting.js';
3
- export { claim } from './claim.js';
4
- export { claimOnMessage } from './claimOnMessage.js';
5
+ export { networkFirst } from './networkFirst.js';
6
+ export { reloadClients } from './reloadClients.js';
5
7
  export { serveFromCache } from './serveFromCache.js';
8
+ export { precacheMissing } from './precacheMissing.js';
9
+ export { pruneStaleCache } from './pruneStaleCache.js';
10
+ export { precacheAndNotify } from './precacheAndNotify.js';
6
11
  export { restoreAssetToCache } from './restoreAssetToCache.js';
7
- export { cacheFirst } from './cacheFirst.js';
8
- export { networkFirst } from './networkFirst.js';
12
+ export { skipWaitingOnMessage } from './skipWaitingOnMessage.js';
9
13
  export { staleWhileRevalidate } from './staleWhileRevalidate.js';
10
- //# sourceMappingURL=index.js.map
14
+ export { claimAndReloadClients } from './claimAndReloadClients.js';
@@ -1,3 +1,5 @@
1
- import type { ServiceWorkerPlugin, OfflineFirstContext } from '../index.js';
2
- export declare const networkFirst: ServiceWorkerPlugin<OfflineFirstContext>;
3
- //# sourceMappingURL=networkFirst.d.ts.map
1
+ import type { Plugin } from '../index.js';
2
+ export interface NetworkFirstConfig {
3
+ cacheName: string;
4
+ }
5
+ export declare function networkFirst(config: NetworkFirstConfig): Plugin;
@@ -1,17 +1,19 @@
1
- export const networkFirst = {
2
- name: 'networkFirst',
3
- fetch: async (event, context) => {
4
- const cache = await caches.open(context.cacheName);
5
- try {
6
- const response = await fetch(event.request);
7
- if (response.ok) {
8
- await cache.put(event.request, response.clone());
1
+ export function networkFirst(config) {
2
+ const { cacheName } = config;
3
+ return {
4
+ name: 'networkFirst',
5
+ fetch: async (event) => {
6
+ const cache = await caches.open(cacheName);
7
+ try {
8
+ const response = await fetch(event.request);
9
+ if (response.ok) {
10
+ await cache.put(event.request, response.clone());
11
+ }
12
+ return response;
9
13
  }
10
- return response;
11
- }
12
- catch {
13
- return (await cache.match(event.request)) ?? undefined;
14
- }
15
- },
16
- };
17
- //# sourceMappingURL=networkFirst.js.map
14
+ catch {
15
+ return (await cache.match(event.request)) ?? undefined;
16
+ }
17
+ },
18
+ };
19
+ }
@@ -1,3 +1,6 @@
1
- import type { ServiceWorkerPlugin, OfflineFirstContext } from '../index.js';
2
- export declare const precache: ServiceWorkerPlugin<OfflineFirstContext>;
3
- //# sourceMappingURL=precache.d.ts.map
1
+ import type { Plugin } from '../index.js';
2
+ export interface PrecacheConfig {
3
+ cacheName: string;
4
+ assets: string[];
5
+ }
6
+ export declare function precache(config: PrecacheConfig): Plugin;
@@ -1,8 +1,10 @@
1
- export const precache = {
2
- name: 'precache',
3
- install: async (_event, context) => {
4
- const cache = await caches.open(context.cacheName);
5
- await cache.addAll(context.assets);
6
- },
7
- };
8
- //# sourceMappingURL=precache.js.map
1
+ export function precache(config) {
2
+ const { cacheName, assets } = config;
3
+ return {
4
+ name: 'precache',
5
+ install: async () => {
6
+ const cache = await caches.open(cacheName);
7
+ await cache.addAll(assets);
8
+ },
9
+ };
10
+ }
@@ -0,0 +1,6 @@
1
+ import type { Plugin } from '../index.js';
2
+ import type { PrecacheConfig } from './precache.js';
3
+ export interface PrecacheAndNotifyConfig extends PrecacheConfig {
4
+ messageType?: string;
5
+ }
6
+ export declare function precacheAndNotify(config: PrecacheAndNotifyConfig): Plugin;
@@ -0,0 +1,13 @@
1
+ import { notifyClients } from '../utils/notifyClients.js';
2
+ import { SW_MSG_INSTALLED } from '@budarin/http-constants/service-worker';
3
+ export function precacheAndNotify(config) {
4
+ const { cacheName, assets, messageType = SW_MSG_INSTALLED } = config;
5
+ return {
6
+ name: 'precacheAndNotify',
7
+ install: async () => {
8
+ const cache = await caches.open(cacheName);
9
+ await cache.addAll(assets);
10
+ await notifyClients(messageType);
11
+ },
12
+ };
13
+ }
@@ -0,0 +1,6 @@
1
+ import type { Plugin } from '../index.js';
2
+ export interface PrecacheMissingConfig {
3
+ cacheName: string;
4
+ assets: string[];
5
+ }
6
+ export declare function precacheMissing(config: PrecacheMissingConfig): Plugin;
@@ -0,0 +1,16 @@
1
+ import { normalizeUrl } from '../utils/normalizeUrl.js';
2
+ export function precacheMissing(config) {
3
+ const { cacheName, assets } = config;
4
+ return {
5
+ name: 'precacheMissing',
6
+ install: async () => {
7
+ const cache = await caches.open(cacheName);
8
+ const keys = await cache.keys();
9
+ const cachedHrefs = new Set(keys.map((r) => normalizeUrl(r.url)));
10
+ const missing = assets.filter((url) => !cachedHrefs.has(normalizeUrl(url)));
11
+ if (missing.length > 0) {
12
+ await cache.addAll(missing);
13
+ }
14
+ },
15
+ };
16
+ }
@@ -0,0 +1,6 @@
1
+ import type { Plugin } from '../index.js';
2
+ export interface PruneStaleCacheConfig {
3
+ cacheName: string;
4
+ assets: string[];
5
+ }
6
+ export declare function pruneStaleCache(config: PruneStaleCacheConfig): Plugin;
@@ -0,0 +1,17 @@
1
+ import { normalizeUrl } from '../utils/normalizeUrl.js';
2
+ export function pruneStaleCache(config) {
3
+ const { cacheName, assets } = config;
4
+ const assetHrefs = new Set(assets.map((url) => normalizeUrl(url)));
5
+ return {
6
+ name: 'pruneStaleCache',
7
+ activate: async () => {
8
+ const cache = await caches.open(cacheName);
9
+ const keys = await cache.keys();
10
+ await Promise.all(keys.map(async (request) => {
11
+ if (!assetHrefs.has(normalizeUrl(request.url))) {
12
+ await cache.delete(request);
13
+ }
14
+ }));
15
+ },
16
+ };
17
+ }
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from '../index.js';
2
+ export declare function reloadClients(): Plugin;
@@ -0,0 +1,9 @@
1
+ export function reloadClients() {
2
+ return {
3
+ name: 'reloadClients',
4
+ activate: async () => {
5
+ const list = await self.clients.matchAll({ type: 'window' });
6
+ await Promise.all(list.map((client) => client.navigate(client.url)));
7
+ },
8
+ };
9
+ }
@@ -1,3 +1,6 @@
1
- import type { ServiceWorkerPlugin, OfflineFirstContext } from '../index.js';
2
- export declare const restoreAssetToCache: ServiceWorkerPlugin<OfflineFirstContext>;
3
- //# sourceMappingURL=restoreAssetToCache.d.ts.map
1
+ import type { Plugin } from '../index.js';
2
+ export interface RestoreAssetToCacheConfig {
3
+ cacheName: string;
4
+ assets: string[];
5
+ }
6
+ export declare function restoreAssetToCache(config: RestoreAssetToCacheConfig): Plugin;
@@ -1,42 +1,27 @@
1
- function isAssetRequest(requestUrl, assets) {
2
- try {
3
- const url = new URL(requestUrl);
4
- const pathname = url.pathname;
5
- return assets.some((asset) => {
1
+ import { isRequestUrlInAssets } from '../utils/isRequestUrlInAssets.js';
2
+ export function restoreAssetToCache(config) {
3
+ const { cacheName, assets } = config;
4
+ return {
5
+ name: 'restoreAssetToCache',
6
+ fetch: async (event) => {
7
+ if (!isRequestUrlInAssets(event.request.url, assets)) {
8
+ return undefined;
9
+ }
10
+ const cache = await caches.open(cacheName);
11
+ const cached = await cache.match(event.request);
12
+ if (cached) {
13
+ return cached;
14
+ }
6
15
  try {
7
- const assetUrl = new URL(asset, self.location.origin);
8
- return url.href === assetUrl.href;
16
+ const response = await fetch(event.request);
17
+ if (response.ok) {
18
+ await cache.put(event.request, response.clone());
19
+ }
20
+ return response;
9
21
  }
10
22
  catch {
11
- const norm = asset.startsWith('/') ? asset : `/${asset}`;
12
- return pathname === norm;
23
+ return undefined;
13
24
  }
14
- });
15
- }
16
- catch {
17
- return false;
18
- }
25
+ },
26
+ };
19
27
  }
20
- export const restoreAssetToCache = {
21
- name: 'restoreAssetToCache',
22
- fetch: async (event, context) => {
23
- if (!isAssetRequest(event.request.url, context.assets))
24
- return undefined;
25
- const cache = await caches.open(context.cacheName);
26
- const cached = await cache.match(event.request);
27
- if (cached) {
28
- return cached;
29
- }
30
- try {
31
- const response = await fetch(event.request);
32
- if (response.ok) {
33
- await cache.put(event.request, response.clone());
34
- }
35
- return response;
36
- }
37
- catch {
38
- return undefined;
39
- }
40
- },
41
- };
42
- //# sourceMappingURL=restoreAssetToCache.js.map
@@ -1,3 +1,5 @@
1
- import type { ServiceWorkerPlugin, OfflineFirstContext } from '../index.js';
2
- export declare const serveFromCache: ServiceWorkerPlugin<OfflineFirstContext>;
3
- //# sourceMappingURL=serveFromCache.d.ts.map
1
+ import type { Plugin } from '../index.js';
2
+ export interface ServeFromCacheConfig {
3
+ cacheName: string;
4
+ }
5
+ export declare function serveFromCache(config: ServeFromCacheConfig): Plugin;
@@ -1,11 +1,10 @@
1
- export const serveFromCache = {
2
- name: 'serveFromCache',
3
- fetch: async (event, context) => {
4
- const cache = await caches.open(context.cacheName);
5
- const options = context.cacheMatchIgnoreSearch
6
- ? { ignoreSearch: true }
7
- : undefined;
8
- return cache.match(event.request, options) ?? undefined;
9
- },
10
- };
11
- //# sourceMappingURL=serveFromCache.js.map
1
+ export function serveFromCache(config) {
2
+ const { cacheName } = config;
3
+ return {
4
+ name: 'serveFromCache',
5
+ fetch: async (event) => {
6
+ const cache = await caches.open(cacheName);
7
+ return cache.match(event.request) ?? undefined;
8
+ },
9
+ };
10
+ }
@@ -1,3 +1,2 @@
1
- import type { ServiceWorkerPlugin } from '../index.js';
2
- export declare const skipWaiting: ServiceWorkerPlugin;
3
- //# sourceMappingURL=skipWaiting.d.ts.map
1
+ import type { Plugin } from '../index.js';
2
+ export declare function skipWaiting(): Plugin;
@@ -1,7 +1,8 @@
1
- export const skipWaiting = {
2
- name: 'skipWaiting',
3
- install: (_event, _context) => {
4
- self.skipWaiting();
5
- },
6
- };
7
- //# sourceMappingURL=skipWaiting.js.map
1
+ export function skipWaiting() {
2
+ return {
3
+ name: 'skipWaiting',
4
+ install: (_event, _logger) => {
5
+ self.skipWaiting();
6
+ },
7
+ };
8
+ }
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from '../index.js';
2
+ export interface SkipWaitingOnMessageConfig {
3
+ messageType?: string;
4
+ }
5
+ export declare function skipWaitingOnMessage(config?: SkipWaitingOnMessageConfig): Plugin;