@serwist/window 9.5.7 → 9.5.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serwist/window",
3
- "version": "9.5.7",
3
+ "version": "9.5.9",
4
4
  "type": "module",
5
5
  "description": "Simplifies communications with Serwist packages running in the service worker",
6
6
  "files": [
@@ -24,34 +24,33 @@
24
24
  "repository": "https://github.com/serwist/serwist",
25
25
  "bugs": "https://github.com/serwist/serwist/issues",
26
26
  "homepage": "https://serwist.pages.dev",
27
- "main": "./dist/index.js",
28
- "types": "./dist/index.d.ts",
27
+ "main": "./dist/index.mjs",
28
+ "types": "./dist/index.d.mts",
29
29
  "typesVersions": {
30
30
  "*": {
31
31
  "internal": [
32
- "./dist/index.internal.d.ts"
32
+ "./dist/index.internal.d.mts"
33
33
  ]
34
34
  }
35
35
  },
36
36
  "exports": {
37
37
  ".": {
38
- "types": "./dist/index.d.ts",
39
- "default": "./dist/index.js"
38
+ "types": "./dist/index.d.mts",
39
+ "default": "./dist/index.mjs"
40
40
  },
41
41
  "./internal": {
42
- "types": "./dist/index.internal.d.ts",
43
- "default": "./dist/index.internal.js"
42
+ "types": "./dist/index.internal.d.mts",
43
+ "default": "./dist/index.internal.mjs"
44
44
  },
45
45
  "./package.json": "./package.json"
46
46
  },
47
47
  "dependencies": {
48
48
  "@types/trusted-types": "2.0.7",
49
- "serwist": "9.5.7"
49
+ "serwist": "9.5.9"
50
50
  },
51
51
  "devDependencies": {
52
- "rollup": "4.59.0",
53
- "typescript": "5.9.3",
54
- "@serwist/configs": "9.5.7"
52
+ "tsdown": "0.21.10",
53
+ "typescript": "6.0.3"
55
54
  },
56
55
  "peerDependencies": {
57
56
  "typescript": ">=5.0.0"
@@ -62,8 +61,8 @@
62
61
  }
63
62
  },
64
63
  "scripts": {
65
- "build": "rimraf dist && NODE_ENV=production rollup --config rollup.config.js",
66
- "dev": "rollup --config rollup.config.js --watch",
64
+ "build": "rimraf dist && NODE_ENV=production tsdown",
65
+ "dev": "tsdown --watch",
67
66
  "lint": "biome lint ./src",
68
67
  "typecheck": "tsc"
69
68
  }
package/dist/Serwist.d.ts DELETED
@@ -1,281 +0,0 @@
1
- import { SerwistEventTarget } from "./utils/SerwistEventTarget.js";
2
- /**
3
- * A class to aid in handling service worker registration, updates, and
4
- * reacting to service worker lifecycle events.
5
- *
6
- * @fires `@serwist/window.Serwist.message`
7
- * @fires `@serwist/window.Serwist.installed`
8
- * @fires `@serwist/window.Serwist.waiting`
9
- * @fires `@serwist/window.Serwist.controlling`
10
- * @fires `@serwist/window.Serwist.activated`
11
- * @fires `@serwist/window.Serwist.redundant`
12
- */
13
- export declare class Serwist extends SerwistEventTarget {
14
- private readonly _scriptURL;
15
- private readonly _registerOptions;
16
- private _updateFoundCount;
17
- private readonly _swDeferred;
18
- private readonly _activeDeferred;
19
- private readonly _controllingDeferred;
20
- private _registrationTime;
21
- private _isUpdate?;
22
- private _compatibleControllingSW?;
23
- private _registration?;
24
- private _sw?;
25
- private readonly _ownSWs;
26
- private _externalSW?;
27
- private _waitingTimeout?;
28
- /**
29
- * Creates a new Serwist instance with a script URL and service worker
30
- * options. The script URL and options are the same as those used when
31
- * calling [navigator.serviceWorker.register(scriptURL, options)](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register).
32
- *
33
- * @param scriptURL The service worker script associated with this instance. Using a
34
- * [`TrustedScriptURL`](https://developer.mozilla.org/en-US/docs/Web/API/TrustedScriptURL) is supported.
35
- * @param registerOptions The service worker options associated with this instance.
36
- */
37
- constructor(scriptURL: string | TrustedScriptURL, registerOptions?: RegistrationOptions);
38
- /**
39
- * Registers a service worker for this instances script URL and service
40
- * worker options. By default this method delays registration until after
41
- * the window has loaded.
42
- *
43
- * @param options
44
- */
45
- register({ immediate, }?: {
46
- /**
47
- * Setting this to true will register the service worker immediately,
48
- * even if the window has not loaded (not recommended).
49
- */
50
- immediate?: boolean;
51
- }): Promise<ServiceWorkerRegistration | undefined>;
52
- /**
53
- * Checks for updates of the registered service worker.
54
- */
55
- update(): Promise<void>;
56
- /**
57
- * Resolves to the service worker registered by this instance as soon as it
58
- * is active. If a service worker was already controlling at registration
59
- * time then it will resolve to that if the script URLs (and optionally
60
- * script versions) match, otherwise it will wait until an update is found
61
- * and activates.
62
- *
63
- * @returns
64
- */
65
- get active(): Promise<ServiceWorker>;
66
- /**
67
- * Resolves to the service worker registered by this instance as soon as it
68
- * is controlling the page. If a service worker was already controlling at
69
- * registration time then it will resolve to that if the script URLs (and
70
- * optionally script versions) match, otherwise it will wait until an update
71
- * is found and starts controlling the page.
72
- * Note: the first time a service worker is installed it will active but
73
- * not start controlling the page unless `clients.claim()` is called in the
74
- * service worker.
75
- *
76
- * @returns
77
- */
78
- get controlling(): Promise<ServiceWorker>;
79
- /**
80
- * Resolves with a reference to a service worker that matches the script URL
81
- * of this instance, as soon as it's available.
82
- *
83
- * If, at registration time, there's already an active or waiting service
84
- * worker with a matching script URL, it will be used (with the waiting
85
- * service worker taking precedence over the active service worker if both
86
- * match, since the waiting service worker would have been registered more
87
- * recently).
88
- * If there's no matching active or waiting service worker at registration
89
- * time then the promise will not resolve until an update is found and starts
90
- * installing, at which point the installing service worker is used.
91
- *
92
- * @returns
93
- */
94
- getSW(): Promise<ServiceWorker>;
95
- /**
96
- * Sends the passed data object to the service worker registered by this
97
- * instance (via `getSW`) and resolves with a response (if any).
98
- *
99
- * A response can be sent by calling `event.ports[0].postMessage(...)`, which will
100
- * resolve the promise returned by `messageSW()`. If no response is sent, the promise
101
- * will never resolve.
102
- *
103
- * @param data An object to send to the service worker
104
- * @returns
105
- */
106
- messageSW(data: any): Promise<any>;
107
- /**
108
- * Sends a `{ type: "SKIP_WAITING" }` message to the service worker that is
109
- * currently waiting and associated with the current registration.
110
- *
111
- * If there is no current registration, or no service worker is waiting,
112
- * calling this will have no effect.
113
- */
114
- messageSkipWaiting(): void;
115
- /**
116
- * Checks for a service worker already controlling the page and returns
117
- * it if its script URL matches.
118
- *
119
- * @private
120
- * @returns
121
- */
122
- private _getControllingSWIfCompatible;
123
- /**
124
- * Registers a service worker for this instances script URL and register
125
- * options and tracks the time registration was complete.
126
- *
127
- * @private
128
- */
129
- private _registerScript;
130
- /**
131
- * @private
132
- * @param originalEvent
133
- */
134
- private readonly _onUpdateFound;
135
- /**
136
- * @private
137
- * @param originalEvent
138
- */
139
- private readonly _onStateChange;
140
- /**
141
- * @private
142
- * @param originalEvent
143
- */
144
- private readonly _onControllerChange;
145
- /**
146
- * @private
147
- * @param originalEvent
148
- */
149
- private readonly _onMessage;
150
- }
151
- /**
152
- * The `message` event is dispatched any time a `postMessage` is received.
153
- *
154
- * @event workbox-window.Workbox#message
155
- * @type {SerwistEvent}
156
- * @property {*} data The `data` property from the original `message` event.
157
- * @property {Event} originalEvent The original [`message`]{@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent}
158
- * event.
159
- * @property {string} type `message`.
160
- * @property {MessagePort[]} ports The `ports` value from `originalEvent`.
161
- * @property {Workbox} target The `Workbox` instance.
162
- */
163
- /**
164
- * The `installed` event is dispatched if the state of a
165
- * {@link workbox-window.Workbox} instance's
166
- * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker}
167
- * changes to `installed`.
168
- *
169
- * Then can happen either the very first time a service worker is installed,
170
- * or after an update to the current service worker is found. In the case
171
- * of an update being found, the event's `isUpdate` property will be `true`.
172
- *
173
- * @event workbox-window.Workbox#installed
174
- * @type {SerwistEvent}
175
- * @property {ServiceWorker} sw The service worker instance.
176
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
177
- * event.
178
- * @property {boolean|undefined} isUpdate True if a service worker was already
179
- * controlling when this `Workbox` instance called `register()`.
180
- * @property {boolean|undefined} isExternal True if this event is associated
181
- * with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
182
- * @property {string} type `installed`.
183
- * @property {Workbox} target The `Workbox` instance.
184
- */
185
- /**
186
- * The `waiting` event is dispatched if the state of a
187
- * {@link workbox-window.Workbox} instance's
188
- * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
189
- * changes to `installed` and then doesn't immediately change to `activating`.
190
- * It may also be dispatched if a service worker with the same
191
- * [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
192
- * was already waiting when the {@link workbox-window.Workbox#register}
193
- * method was called.
194
- *
195
- * @event workbox-window.Workbox#waiting
196
- * @type {SerwistEvent}
197
- * @property {ServiceWorker} sw The service worker instance.
198
- * @property {Event|undefined} originalEvent The original
199
- * [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
200
- * event, or `undefined` in the case where the service worker was waiting
201
- * to before `.register()` was called.
202
- * @property {boolean|undefined} isUpdate True if a service worker was already
203
- * controlling when this `Workbox` instance called `register()`.
204
- * @property {boolean|undefined} isExternal True if this event is associated
205
- * with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
206
- * @property {boolean|undefined} wasWaitingBeforeRegister True if a service worker with
207
- * a matching `scriptURL` was already waiting when this `Workbox`
208
- * instance called `register()`.
209
- * @property {string} type `waiting`.
210
- * @property {Workbox} target The `Workbox` instance.
211
- */
212
- /**
213
- * The `controlling` event is dispatched if a
214
- * [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
215
- * fires on the service worker [container]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer}
216
- * and the [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
217
- * of the new [controller]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller}
218
- * matches the `scriptURL` of the `Workbox` instance's
219
- * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}.
220
- *
221
- * @event workbox-window.Workbox#controlling
222
- * @type {SerwistEvent}
223
- * @property {ServiceWorker} sw The service worker instance.
224
- * @property {Event} originalEvent The original [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
225
- * event.
226
- * @property {boolean|undefined} isUpdate True if a service worker was already
227
- * controlling when this service worker was registered.
228
- * @property {boolean|undefined} isExternal True if this event is associated
229
- * with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
230
- * @property {string} type `controlling`.
231
- * @property {Workbox} target The `Workbox` instance.
232
- */
233
- /**
234
- * The `activated` event is dispatched if the state of a
235
- * {@link workbox-window.Workbox} instance's
236
- * {@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw|registered service worker}
237
- * changes to `activated`.
238
- *
239
- * @event workbox-window.Workbox#activated
240
- * @type {SerwistEvent}
241
- * @property {ServiceWorker} sw The service worker instance.
242
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
243
- * event.
244
- * @property {boolean|undefined} isUpdate True if a service worker was already
245
- * controlling when this `Workbox` instance called `register()`.
246
- * @property {boolean|undefined} isExternal True if this event is associated
247
- * with an [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}.
248
- * @property {string} type `activated`.
249
- * @property {Workbox} target The `Workbox` instance.
250
- */
251
- /**
252
- * The `redundant` event is dispatched if the state of a
253
- * {@link workbox-window.Workbox} instance's
254
- * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
255
- * changes to `redundant`.
256
- *
257
- * @event workbox-window.Workbox#redundant
258
- * @type {SerwistEvent}
259
- * @property {ServiceWorker} sw The service worker instance.
260
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
261
- * event.
262
- * @property {boolean|undefined} isUpdate True if a service worker was already
263
- * controlling when this `Workbox` instance called `register()`.
264
- * @property {string} type `redundant`.
265
- * @property {Workbox} target The `Workbox` instance.
266
- */
267
- /**
268
- * The `installing` event is dispatched if the service worker
269
- * finds the new version and starts installing.
270
- *
271
- * @event workbox-window.Workbox#installing
272
- * @type {SerwistEvent}
273
- * @property {ServiceWorker} sw The installing service worker instance.
274
- * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
275
- * event.
276
- * @property {boolean|undefined} isUpdate True if a service worker was already
277
- * controlling when this `Workbox` instance called `register()`.
278
- * @property {string} type `installing`.
279
- * @property {Workbox} target The `Workbox` instance.
280
- */
281
- //# sourceMappingURL=Serwist.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Serwist.d.ts","sourceRoot":"","sources":["../src/Serwist.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAgBnE;;;;;;;;;;GAUG;AACH,qBAAa,OAAQ,SAAQ,kBAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA2B;IAC5D,OAAO,CAAC,iBAAiB,CAAK;IAG9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2C;IACvE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA2C;IAC3E,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA2C;IAEhF,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,SAAS,CAAC,CAAU;IAC5B,OAAO,CAAC,wBAAwB,CAAC,CAAgB;IACjD,OAAO,CAAC,aAAa,CAAC,CAA4B;IAClD,OAAO,CAAC,GAAG,CAAC,CAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,WAAW,CAAC,CAAgB;IACpC,OAAO,CAAC,eAAe,CAAC,CAAS;IAEjC;;;;;;;;OAQG;gBACS,SAAS,EAAE,MAAM,GAAG,gBAAgB,EAAE,eAAe,GAAE,mBAAwB;IAY3F;;;;;;OAMG;IACG,QAAQ,CAAC,EACb,SAAiB,GAClB,GAAE;QACD;;;WAGG;QACH,SAAS,CAAC,EAAE,OAAO,CAAC;KAChB,GAAG,OAAO,CAAC,yBAAyB,GAAG,SAAS,CAAC;IAyFvD;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7B;;;;;;;;OAQG;IACH,IAAI,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC,CAEnC;IAED;;;;;;;;;;;OAWG;IACH,IAAI,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC,CAExC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC;IAM/B;;;;;;;;;;OAUG;IAEG,SAAS,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAKxC;;;;;;OAMG;IACH,kBAAkB,IAAI,IAAI;IAM1B;;;;;;OAMG;IACH,OAAO,CAAC,6BAA6B;IAQrC;;;;;OAKG;YACW,eAAe;IAsB7B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAsE7B;IAEF;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAqF7B;IAEF;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAuBlC;IAEF;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,UAAU,CAuBzB;CACH;AAKD;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;;;;;;;;GAaG"}
package/dist/index.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import { messageSW } from "./messageSW.js";
2
- import { Serwist } from "./Serwist.js";
3
- export { messageSW, Serwist };
4
- export * from "./utils/SerwistEvent.js";
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAG9B,cAAc,yBAAyB,CAAC"}
@@ -1,3 +0,0 @@
1
- import { isCurrentPageOutOfScope } from "./utils/isCurrentPageOutOfScope.js";
2
- export { isCurrentPageOutOfScope };
3
- //# sourceMappingURL=index.internal.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.internal.d.ts","sourceRoot":"","sources":["../src/index.internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
@@ -1,7 +0,0 @@
1
- const isCurrentPageOutOfScope = (scope)=>{
2
- const scopeURL = new URL(scope, document.baseURI);
3
- const scopeURLBasePath = new URL("./", scopeURL.href).pathname;
4
- return !location.pathname.startsWith(scopeURLBasePath);
5
- };
6
-
7
- export { isCurrentPageOutOfScope };
package/dist/index.js DELETED
@@ -1,304 +0,0 @@
1
- import { Deferred, logger } from 'serwist/internal';
2
- import { isCurrentPageOutOfScope } from './index.internal.js';
3
-
4
- const messageSW = (sw, data)=>{
5
- return new Promise((resolve)=>{
6
- const messageChannel = new MessageChannel();
7
- messageChannel.port1.onmessage = (event)=>{
8
- resolve(event.data);
9
- };
10
- sw.postMessage(data, [
11
- messageChannel.port2
12
- ]);
13
- });
14
- };
15
-
16
- class SerwistEvent {
17
- type;
18
- target;
19
- sw;
20
- originalEvent;
21
- isExternal;
22
- constructor(type, props){
23
- this.type = type;
24
- Object.assign(this, props);
25
- }
26
- }
27
-
28
- class SerwistEventTarget {
29
- _eventListenerRegistry = new Map();
30
- addEventListener(type, listener) {
31
- const foo = this._getEventListenersByType(type);
32
- foo.add(listener);
33
- }
34
- removeEventListener(type, listener) {
35
- this._getEventListenersByType(type).delete(listener);
36
- }
37
- dispatchEvent(event) {
38
- event.target = this;
39
- const listeners = this._getEventListenersByType(event.type);
40
- for (const listener of listeners){
41
- listener(event);
42
- }
43
- }
44
- _getEventListenersByType(type) {
45
- if (!this._eventListenerRegistry.has(type)) {
46
- this._eventListenerRegistry.set(type, new Set());
47
- }
48
- return this._eventListenerRegistry.get(type);
49
- }
50
- }
51
-
52
- function urlsMatch(url1, url2) {
53
- const { href } = location;
54
- return new URL(url1, href).href === new URL(url2, href).href;
55
- }
56
-
57
- const WAITING_TIMEOUT_DURATION = 200;
58
- const REGISTRATION_TIMEOUT_DURATION = 60000;
59
- const SKIP_WAITING_MESSAGE = {
60
- type: "SKIP_WAITING"
61
- };
62
- class Serwist extends SerwistEventTarget {
63
- _scriptURL;
64
- _registerOptions = {};
65
- _updateFoundCount = 0;
66
- _swDeferred = new Deferred();
67
- _activeDeferred = new Deferred();
68
- _controllingDeferred = new Deferred();
69
- _registrationTime = 0;
70
- _isUpdate;
71
- _compatibleControllingSW;
72
- _registration;
73
- _sw;
74
- _ownSWs = new Set();
75
- _externalSW;
76
- _waitingTimeout;
77
- constructor(scriptURL, registerOptions = {}){
78
- super();
79
- this._scriptURL = scriptURL;
80
- this._registerOptions = registerOptions;
81
- navigator.serviceWorker.addEventListener("message", this._onMessage);
82
- }
83
- async register({ immediate = false } = {}) {
84
- if (process.env.NODE_ENV !== "production") {
85
- if (this._registrationTime) {
86
- logger.error("Cannot re-register a Serwist instance after it has been registered. Create a new instance instead.");
87
- return;
88
- }
89
- }
90
- if (!immediate && document.readyState !== "complete") {
91
- await new Promise((res)=>window.addEventListener("load", res));
92
- }
93
- this._isUpdate = Boolean(navigator.serviceWorker.controller);
94
- this._compatibleControllingSW = this._getControllingSWIfCompatible();
95
- this._registration = await this._registerScript();
96
- if (this._compatibleControllingSW) {
97
- this._sw = this._compatibleControllingSW;
98
- this._activeDeferred.resolve(this._compatibleControllingSW);
99
- this._controllingDeferred.resolve(this._compatibleControllingSW);
100
- this._compatibleControllingSW.addEventListener("statechange", this._onStateChange, {
101
- once: true
102
- });
103
- }
104
- const waitingSW = this._registration.waiting;
105
- if (waitingSW && urlsMatch(waitingSW.scriptURL, this._scriptURL.toString())) {
106
- this._sw = waitingSW;
107
- void Promise.resolve().then(()=>{
108
- this.dispatchEvent(new SerwistEvent("waiting", {
109
- sw: waitingSW,
110
- wasWaitingBeforeRegister: true
111
- }));
112
- if (process.env.NODE_ENV !== "production") {
113
- logger.warn("A service worker was already waiting to activate before this script was registered...");
114
- }
115
- });
116
- }
117
- if (this._sw) {
118
- this._swDeferred.resolve(this._sw);
119
- this._ownSWs.add(this._sw);
120
- }
121
- if (process.env.NODE_ENV !== "production") {
122
- logger.log("Successfully registered service worker.", this._scriptURL.toString());
123
- if (navigator.serviceWorker.controller) {
124
- if (this._compatibleControllingSW) {
125
- logger.debug("A service worker with the same script URL is already controlling this page.");
126
- } else {
127
- logger.debug("A service worker with a different script URL is currently controlling the page. The browser is now fetching the new script now...");
128
- }
129
- }
130
- if (isCurrentPageOutOfScope(this._registerOptions.scope || this._scriptURL.toString())) {
131
- logger.warn("The current page is not in scope for the registered service worker. Was this a mistake?");
132
- }
133
- }
134
- this._registration.addEventListener("updatefound", this._onUpdateFound);
135
- navigator.serviceWorker.addEventListener("controllerchange", this._onControllerChange);
136
- return this._registration;
137
- }
138
- async update() {
139
- if (!this._registration) {
140
- if (process.env.NODE_ENV !== "production") {
141
- logger.error("Cannot update a Serwist instance without being registered. Register the Serwist instance first.");
142
- }
143
- return;
144
- }
145
- await this._registration.update();
146
- }
147
- get active() {
148
- return this._activeDeferred.promise;
149
- }
150
- get controlling() {
151
- return this._controllingDeferred.promise;
152
- }
153
- getSW() {
154
- return this._sw !== undefined ? Promise.resolve(this._sw) : this._swDeferred.promise;
155
- }
156
- async messageSW(data) {
157
- const sw = await this.getSW();
158
- return messageSW(sw, data);
159
- }
160
- messageSkipWaiting() {
161
- if (this._registration?.waiting) {
162
- void messageSW(this._registration.waiting, SKIP_WAITING_MESSAGE);
163
- }
164
- }
165
- _getControllingSWIfCompatible() {
166
- const controller = navigator.serviceWorker.controller;
167
- if (controller && urlsMatch(controller.scriptURL, this._scriptURL.toString())) {
168
- return controller;
169
- }
170
- return undefined;
171
- }
172
- async _registerScript() {
173
- try {
174
- const reg = await navigator.serviceWorker.register(this._scriptURL, this._registerOptions);
175
- this._registrationTime = performance.now();
176
- return reg;
177
- } catch (error) {
178
- if (process.env.NODE_ENV !== "production") {
179
- logger.error(error);
180
- }
181
- throw error;
182
- }
183
- }
184
- _onUpdateFound = (originalEvent)=>{
185
- const registration = this._registration;
186
- const installingSW = registration.installing;
187
- const updateLikelyTriggeredExternally = this._updateFoundCount > 0 || !urlsMatch(installingSW.scriptURL, this._scriptURL.toString()) || performance.now() > this._registrationTime + REGISTRATION_TIMEOUT_DURATION;
188
- if (updateLikelyTriggeredExternally) {
189
- this._externalSW = installingSW;
190
- registration.removeEventListener("updatefound", this._onUpdateFound);
191
- } else {
192
- this._sw = installingSW;
193
- this._ownSWs.add(installingSW);
194
- this._swDeferred.resolve(installingSW);
195
- if (process.env.NODE_ENV !== "production") {
196
- if (this._isUpdate) {
197
- logger.log("Updated service worker found. Installing now...");
198
- } else {
199
- logger.log("Service worker is installing...");
200
- }
201
- }
202
- }
203
- this.dispatchEvent(new SerwistEvent("installing", {
204
- sw: installingSW,
205
- originalEvent,
206
- isExternal: updateLikelyTriggeredExternally,
207
- isUpdate: this._isUpdate
208
- }));
209
- ++this._updateFoundCount;
210
- installingSW.addEventListener("statechange", this._onStateChange);
211
- };
212
- _onStateChange = (originalEvent)=>{
213
- const registration = this._registration;
214
- const sw = originalEvent.target;
215
- const { state } = sw;
216
- const isExternal = sw === this._externalSW;
217
- const eventProps = {
218
- sw,
219
- isExternal,
220
- originalEvent
221
- };
222
- if (!isExternal && this._isUpdate) {
223
- eventProps.isUpdate = true;
224
- }
225
- this.dispatchEvent(new SerwistEvent(state, eventProps));
226
- if (state === "installed") {
227
- this._waitingTimeout = self.setTimeout(()=>{
228
- if (state === "installed" && registration.waiting === sw) {
229
- this.dispatchEvent(new SerwistEvent("waiting", eventProps));
230
- if (process.env.NODE_ENV !== "production") {
231
- if (isExternal) {
232
- logger.warn("An external service worker has installed but is " + "waiting for this client to close before activating...");
233
- } else {
234
- logger.warn("The service worker has installed but is waiting " + "for existing clients to close before activating...");
235
- }
236
- }
237
- }
238
- }, WAITING_TIMEOUT_DURATION);
239
- } else if (state === "activating") {
240
- clearTimeout(this._waitingTimeout);
241
- if (!isExternal) {
242
- this._activeDeferred.resolve(sw);
243
- }
244
- }
245
- if (process.env.NODE_ENV !== "production") {
246
- switch(state){
247
- case "installed":
248
- if (isExternal) {
249
- logger.warn("An external service worker has installed. " + "You may want to suggest users reload this page.");
250
- } else {
251
- logger.log("Registered service worker installed.");
252
- }
253
- break;
254
- case "activated":
255
- if (isExternal) {
256
- logger.warn("An external service worker has activated.");
257
- } else {
258
- logger.log("Registered service worker activated.");
259
- if (sw !== navigator.serviceWorker.controller) {
260
- logger.warn("The registered service worker is active but " + "not yet controlling the page. Reload or run " + "`clients.claim()` in the service worker.");
261
- }
262
- }
263
- break;
264
- case "redundant":
265
- if (sw === this._compatibleControllingSW) {
266
- logger.log("Previously controlling service worker now redundant!");
267
- } else if (!isExternal) {
268
- logger.log("Registered service worker now redundant!");
269
- }
270
- break;
271
- }
272
- }
273
- };
274
- _onControllerChange = (originalEvent)=>{
275
- const sw = this._sw;
276
- const isExternal = sw !== navigator.serviceWorker.controller;
277
- this.dispatchEvent(new SerwistEvent("controlling", {
278
- isExternal,
279
- originalEvent,
280
- sw,
281
- isUpdate: this._isUpdate
282
- }));
283
- if (!isExternal) {
284
- if (process.env.NODE_ENV !== "production") {
285
- logger.log("Registered service worker now controlling this page.");
286
- }
287
- this._controllingDeferred.resolve(sw);
288
- }
289
- };
290
- _onMessage = async (originalEvent)=>{
291
- const { data, ports, source } = originalEvent;
292
- await this.getSW();
293
- if (this._ownSWs.has(source)) {
294
- this.dispatchEvent(new SerwistEvent("message", {
295
- data,
296
- originalEvent,
297
- ports,
298
- sw: source
299
- }));
300
- }
301
- };
302
- }
303
-
304
- export { Serwist, SerwistEvent, messageSW };