@hellotext/hellotext 2.5.7 → 2.5.8

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 (102) hide show
  1. package/README.md +0 -25
  2. package/dist/hellotext.js +1 -1
  3. package/index.d.ts +0 -6
  4. package/lib/api/acks.cjs +17 -31
  5. package/lib/api/acks.js +17 -42
  6. package/lib/api/businesses.cjs +14 -28
  7. package/lib/api/businesses.js +13 -36
  8. package/lib/api/events.cjs +26 -40
  9. package/lib/api/events.js +28 -52
  10. package/lib/api/forms.cjs +24 -40
  11. package/lib/api/forms.js +24 -57
  12. package/lib/api/identifications.cjs +15 -29
  13. package/lib/api/identifications.js +15 -40
  14. package/lib/api/index.cjs +25 -51
  15. package/lib/api/index.js +27 -54
  16. package/lib/api/push/identities.cjs +30 -46
  17. package/lib/api/push/identities.js +30 -63
  18. package/lib/api/response.cjs +30 -52
  19. package/lib/api/response.js +31 -60
  20. package/lib/api/submissions.cjs +18 -34
  21. package/lib/api/submissions.js +18 -48
  22. package/lib/api/webchat/messages.cjs +44 -64
  23. package/lib/api/webchat/messages.js +44 -80
  24. package/lib/api/webchats.cjs +37 -56
  25. package/lib/api/webchats.js +37 -65
  26. package/lib/api/whatsapp_widgets.cjs +49 -72
  27. package/lib/api/whatsapp_widgets.js +48 -91
  28. package/lib/builders/input_builder.cjs +36 -48
  29. package/lib/builders/input_builder.js +36 -48
  30. package/lib/builders/logo_builder.cjs +10 -29
  31. package/lib/builders/logo_builder.js +20 -28
  32. package/lib/channels/application_channel.cjs +136 -178
  33. package/lib/channels/application_channel.js +137 -180
  34. package/lib/channels/webchat_channel.cjs +125 -170
  35. package/lib/channels/webchat_channel.js +125 -170
  36. package/lib/controllers/form_controller.cjs +82 -121
  37. package/lib/controllers/form_controller.js +82 -130
  38. package/lib/controllers/message_controller.cjs +211 -282
  39. package/lib/controllers/message_controller.js +209 -284
  40. package/lib/controllers/mixins/usePopover.cjs +3 -6
  41. package/lib/controllers/mixins/usePopover.js +17 -22
  42. package/lib/controllers/webchat/emoji_picker_controller.cjs +106 -150
  43. package/lib/controllers/webchat/emoji_picker_controller.js +105 -170
  44. package/lib/controllers/webchat/useBehaviour.js +5 -5
  45. package/lib/controllers/webchat/useOpeningSequence.js +6 -6
  46. package/lib/controllers/webchat/useTeaser.js +9 -9
  47. package/lib/controllers/webchat_controller.cjs +916 -1088
  48. package/lib/controllers/webchat_controller.js +926 -1152
  49. package/lib/core/configuration/forms.cjs +21 -35
  50. package/lib/core/configuration/forms.js +20 -35
  51. package/lib/core/configuration/locale.cjs +36 -71
  52. package/lib/core/configuration/locale.js +36 -70
  53. package/lib/core/configuration/push.cjs +9 -21
  54. package/lib/core/configuration/push.js +8 -20
  55. package/lib/core/configuration/webchat.cjs +142 -182
  56. package/lib/core/configuration/webchat.js +145 -189
  57. package/lib/core/configuration/whatsapp.cjs +76 -102
  58. package/lib/core/configuration/whatsapp.js +76 -105
  59. package/lib/core/configuration.cjs +60 -78
  60. package/lib/core/configuration.js +59 -78
  61. package/lib/core/event.cjs +36 -59
  62. package/lib/core/event.js +35 -61
  63. package/lib/core/sanitize_html.js +4 -4
  64. package/lib/errors/invalid_event.cjs +5 -26
  65. package/lib/errors/invalid_event.js +5 -26
  66. package/lib/errors/not_initialized_error.cjs +5 -26
  67. package/lib/errors/not_initialized_error.js +5 -26
  68. package/lib/hellotext.cjs +185 -223
  69. package/lib/hellotext.js +188 -247
  70. package/lib/index.js +1 -1
  71. package/lib/models/business.cjs +114 -152
  72. package/lib/models/business.js +117 -162
  73. package/lib/models/cookies.cjs +34 -51
  74. package/lib/models/cookies.js +34 -51
  75. package/lib/models/fingerprint.cjs +8 -23
  76. package/lib/models/fingerprint.js +25 -58
  77. package/lib/models/form.cjs +106 -142
  78. package/lib/models/form.js +105 -153
  79. package/lib/models/form_collection.cjs +63 -101
  80. package/lib/models/form_collection.js +61 -107
  81. package/lib/models/page.cjs +106 -129
  82. package/lib/models/page.js +106 -131
  83. package/lib/models/push.cjs +278 -322
  84. package/lib/models/push.js +284 -357
  85. package/lib/models/query.cjs +21 -41
  86. package/lib/models/query.js +21 -41
  87. package/lib/models/session.cjs +33 -65
  88. package/lib/models/session.js +30 -63
  89. package/lib/models/user.cjs +29 -51
  90. package/lib/models/user.js +29 -51
  91. package/lib/models/utm.cjs +15 -27
  92. package/lib/models/utm.js +17 -32
  93. package/lib/models/webchat.cjs +52 -76
  94. package/lib/models/webchat.js +52 -90
  95. package/lib/models/whatsapp_widget.cjs +41 -59
  96. package/lib/models/whatsapp_widget.js +41 -73
  97. package/lib/vanilla.cjs +4 -7
  98. package/lib/vanilla.js +2 -1
  99. package/package.json +1 -9
  100. package/src/index.bundle.js +0 -1
  101. package/src/vanilla.js +2 -1
  102. package/styles/index.css +0 -30
@@ -7,23 +7,17 @@ exports.Push = void 0;
7
7
  var _api = _interopRequireDefault(require("../api"));
8
8
  var _core = require("../core");
9
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
11
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
12
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
13
- function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
14
- function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
15
10
  /**
16
11
  * Manages browser Push subscriptions for Hellotext.
17
12
  *
18
13
  * @property {Promise<void>|null} ready - Initialization promise, available after initialize().
19
14
  */
20
- let Push = /*#__PURE__*/function () {
15
+ class Push {
21
16
  /**
22
17
  * @param {Object} data - Push configuration from the business response.
23
18
  * @param {String} data.public_key - Base64url-encoded VAPID public key.
24
19
  */
25
- function Push(data) {
26
- _classCallCheck(this, Push);
20
+ constructor(data) {
27
21
  this.publicKey = data.public_key;
28
22
  this.serviceWorkerUrl = _core.Configuration.push.serviceWorkerUrl;
29
23
  this.channelId = _core.Configuration.push.channelId;
@@ -43,347 +37,309 @@ let Push = /*#__PURE__*/function () {
43
37
  *
44
38
  * @returns {Promise<void>}
45
39
  */
46
- _createClass(Push, [{
47
- key: "initialize",
48
- value: function initialize() {
49
- this.ready = this.restoreSubscription();
50
- return this.ready;
51
- }
40
+ initialize() {
41
+ this.ready = this.restoreSubscription();
42
+ return this.ready;
43
+ }
52
44
 
53
- /**
54
- * Registers an existing Hellotext subscription with the server without prompting.
55
- *
56
- * @private
57
- * @returns {Promise<void>}
58
- */
59
- }, {
60
- key: "restoreSubscription",
61
- value: async function restoreSubscription() {
62
- const registration = await this.getRegistration();
63
- const subscription = await registration.pushManager.getSubscription();
64
- if (this.disposed || this.unsubscribePromise || !subscription || !this.owns(subscription)) {
65
- return;
66
- }
67
- this.subscription = subscription;
68
- await this.sync();
45
+ /**
46
+ * Registers an existing Hellotext subscription with the server without prompting.
47
+ *
48
+ * @private
49
+ * @returns {Promise<void>}
50
+ */
51
+ async restoreSubscription() {
52
+ const registration = await this.getRegistration();
53
+ const subscription = await registration.pushManager.getSubscription();
54
+ if (this.disposed || this.unsubscribePromise || !subscription || !this.owns(subscription)) {
55
+ return;
69
56
  }
57
+ this.subscription = subscription;
58
+ await this.sync();
59
+ }
70
60
 
71
- /**
72
- * Creates or reuses a Push subscription. Call from a user click handler.
73
- * Concurrent calls share the same pending request.
74
- *
75
- * @returns {Promise<import('../api/response').Response|void>} Server registration response,
76
- * or no value when disposed.
77
- * Rejects when permission is denied or a browser or network operation fails.
78
- */
79
- }, {
80
- key: "subscribe",
81
- value: function subscribe() {
82
- if (this.disposed) return Promise.resolve();
83
- if (this.unsubscribePromise) return Promise.reject(new Error('Push unsubscribe is in progress'));
84
- if (this.subscribePromise) return this.subscribePromise;
61
+ /**
62
+ * Creates or reuses a Push subscription. Call from a user click handler.
63
+ * Concurrent calls share the same pending request.
64
+ *
65
+ * @returns {Promise<import('../api/response').Response|void>} Server registration response,
66
+ * or no value when disposed.
67
+ * Rejects when permission is denied or a browser or network operation fails.
68
+ */
69
+ subscribe() {
70
+ if (this.disposed) return Promise.resolve();
71
+ if (this.unsubscribePromise) return Promise.reject(new Error('Push unsubscribe is in progress'));
72
+ if (this.subscribePromise) return this.subscribePromise;
85
73
 
86
- // Request permission before awaiting worker readiness to retain the click's user activation.
87
- const permission = Notification.permission === 'default' ? Notification.requestPermission() : Promise.resolve(Notification.permission);
88
- this.subscribePromise = this.createSubscription(permission).finally(() => {
89
- this.subscribePromise = null;
90
- });
91
- return this.subscribePromise;
92
- }
74
+ // Request permission before awaiting worker readiness to retain the click's user activation.
75
+ const permission = Notification.permission === 'default' ? Notification.requestPermission() : Promise.resolve(Notification.permission);
76
+ this.subscribePromise = this.createSubscription(permission).finally(() => {
77
+ this.subscribePromise = null;
78
+ });
79
+ return this.subscribePromise;
80
+ }
93
81
 
94
- /**
95
- * Waits for permission and worker readiness, then subscribes and registers with Hellotext.
96
- *
97
- * @private
98
- * @param {Promise<NotificationPermission>} permission - Pending notification permission result.
99
- * @returns {Promise<import('../api/response').Response|void>}
100
- */
101
- }, {
102
- key: "createSubscription",
103
- value: async function createSubscription(permission) {
104
- if ((await permission) !== 'granted') throw new Error('Push permission was not granted');
105
- const registration = await this.getRegistration();
106
- if (this.disposed) return;
107
- let subscription = await registration.pushManager.getSubscription();
108
- if (this.disposed) return;
109
- if (subscription && !this.owns(subscription)) {
110
- throw new Error('The existing Push subscription belongs to a different application');
111
- }
112
- subscription || (subscription = await registration.pushManager.subscribe({
113
- userVisibleOnly: true,
114
- applicationServerKey: this.applicationServerKey
115
- }));
116
- if (this.disposed) return;
117
- this.subscription = subscription;
118
- return this.sync();
82
+ /**
83
+ * Waits for permission and worker readiness, then subscribes and registers with Hellotext.
84
+ *
85
+ * @private
86
+ * @param {Promise<NotificationPermission>} permission - Pending notification permission result.
87
+ * @returns {Promise<import('../api/response').Response|void>}
88
+ */
89
+ async createSubscription(permission) {
90
+ if ((await permission) !== 'granted') throw new Error('Push permission was not granted');
91
+ const registration = await this.getRegistration();
92
+ if (this.disposed) return;
93
+ let subscription = await registration.pushManager.getSubscription();
94
+ if (this.disposed) return;
95
+ if (subscription && !this.owns(subscription)) {
96
+ throw new Error('The existing Push subscription belongs to a different application');
119
97
  }
98
+ subscription ||= await registration.pushManager.subscribe({
99
+ userVisibleOnly: true,
100
+ applicationServerKey: this.applicationServerKey
101
+ });
102
+ if (this.disposed) return;
103
+ this.subscription = subscription;
104
+ return this.sync();
105
+ }
120
106
 
121
- /**
122
- * Disables the server identity and removes the browser subscription.
123
- * Keeps the subscription when the server request fails so the caller can retry.
124
- *
125
- * @returns {Promise<import('../api/response').Response|null|void>} Server response, null when
126
- * no subscription exists, or no value when disposed. Rejects when a browser or network
127
- * operation fails.
128
- */
129
- }, {
130
- key: "unsubscribe",
131
- value: function unsubscribe() {
132
- if (this.disposed) return Promise.resolve();
133
- if (this.unsubscribePromise) return this.unsubscribePromise;
134
- this.clearRetryTimeout();
135
- this.unsubscribePromise = this.removeSubscription().finally(() => {
136
- this.unsubscribePromise = null;
137
- });
138
- return this.unsubscribePromise;
139
- }
107
+ /**
108
+ * Disables the server identity and removes the browser subscription.
109
+ * Keeps the subscription when the server request fails so the caller can retry.
110
+ *
111
+ * @returns {Promise<import('../api/response').Response|null|void>} Server response, null when
112
+ * no subscription exists, or no value when disposed. Rejects when a browser or network
113
+ * operation fails.
114
+ */
115
+ unsubscribe() {
116
+ if (this.disposed) return Promise.resolve();
117
+ if (this.unsubscribePromise) return this.unsubscribePromise;
118
+ this.clearRetryTimeout();
119
+ this.unsubscribePromise = this.removeSubscription().finally(() => {
120
+ this.unsubscribePromise = null;
121
+ });
122
+ return this.unsubscribePromise;
123
+ }
140
124
 
141
- /**
142
- * Finishes pending registration before disabling and removing the subscription.
143
- *
144
- * @private
145
- * @returns {Promise<import('../api/response').Response|null|void>}
146
- */
147
- }, {
148
- key: "removeSubscription",
149
- value: async function removeSubscription() {
150
- var _this$ready, _this$subscribePromis, _this$syncPromise;
151
- await ((_this$ready = this.ready) === null || _this$ready === void 0 ? void 0 : _this$ready.catch(() => {}));
152
- await ((_this$subscribePromis = this.subscribePromise) === null || _this$subscribePromis === void 0 ? void 0 : _this$subscribePromis.catch(() => {}));
153
- await ((_this$syncPromise = this.syncPromise) === null || _this$syncPromise === void 0 ? void 0 : _this$syncPromise.catch(() => {}));
154
- const registration = await this.getRegistration();
155
- const subscription = (await registration.pushManager.getSubscription()) || this.subscription;
156
- if (this.disposed) return;
157
- if (!subscription) return null;
158
- if (!this.owns(subscription)) {
159
- throw new Error('The existing Push subscription belongs to a different application');
160
- }
161
- this.subscription = subscription;
162
- const response = await _api.default.pushIdentities.destroy({
163
- subscription: subscription.toJSON()
164
- });
165
- if (response.failed) return response;
166
- if (this.disposed) return;
167
- await subscription.unsubscribe();
168
- this.subscription = null;
169
- this.clearRetryTimeout();
170
- return response;
125
+ /**
126
+ * Finishes pending registration before disabling and removing the subscription.
127
+ *
128
+ * @private
129
+ * @returns {Promise<import('../api/response').Response|null|void>}
130
+ */
131
+ async removeSubscription() {
132
+ await this.ready?.catch(() => {});
133
+ await this.subscribePromise?.catch(() => {});
134
+ await this.syncPromise?.catch(() => {});
135
+ const registration = await this.getRegistration();
136
+ const subscription = (await registration.pushManager.getSubscription()) || this.subscription;
137
+ if (this.disposed) return;
138
+ if (!subscription) return null;
139
+ if (!this.owns(subscription)) {
140
+ throw new Error('The existing Push subscription belongs to a different application');
171
141
  }
142
+ this.subscription = subscription;
143
+ const response = await _api.default.pushIdentities.destroy({
144
+ subscription: subscription.toJSON()
145
+ });
146
+ if (response.failed) return response;
147
+ if (this.disposed) return;
148
+ await subscription.unsubscribe();
149
+ this.subscription = null;
150
+ this.clearRetryTimeout();
151
+ return response;
152
+ }
172
153
 
173
- /**
174
- * Registers the current subscription, sharing any request already in progress.
175
- *
176
- * @private
177
- * @returns {Promise<import('../api/response').Response|void>}
178
- */
179
- }, {
180
- key: "sync",
181
- value: function sync() {
182
- if (this.disposed) return Promise.resolve();
183
- if (this.syncPromise) return this.syncPromise;
184
- this.clearRetryTimeout();
185
- this.syncPromise = this.registerIdentity().finally(() => {
186
- this.syncPromise = null;
187
- });
188
- return this.syncPromise;
189
- }
154
+ /**
155
+ * Registers the current subscription, sharing any request already in progress.
156
+ *
157
+ * @private
158
+ * @returns {Promise<import('../api/response').Response|void>}
159
+ */
160
+ sync() {
161
+ if (this.disposed) return Promise.resolve();
162
+ if (this.syncPromise) return this.syncPromise;
163
+ this.clearRetryTimeout();
164
+ this.syncPromise = this.registerIdentity().finally(() => {
165
+ this.syncPromise = null;
166
+ });
167
+ return this.syncPromise;
168
+ }
190
169
 
191
- /**
192
- * Sends the subscription to Hellotext and schedules a retry on failure.
193
- *
194
- * @private
195
- * @returns {Promise<import('../api/response').Response>}
196
- */
197
- }, {
198
- key: "registerIdentity",
199
- value: async function registerIdentity() {
200
- try {
201
- const response = await _api.default.pushIdentities.create({
202
- subscription: this.subscription.toJSON(),
203
- ...(this.channelId ? {
204
- channel_id: this.channelId
205
- } : {})
206
- });
207
- if (response.succeeded) {
208
- this.retryAttempts = 0;
209
- } else {
210
- this.scheduleRetry();
211
- }
212
- return response;
213
- } catch (error) {
170
+ /**
171
+ * Sends the subscription to Hellotext and schedules a retry on failure.
172
+ *
173
+ * @private
174
+ * @returns {Promise<import('../api/response').Response>}
175
+ */
176
+ async registerIdentity() {
177
+ try {
178
+ const response = await _api.default.pushIdentities.create({
179
+ subscription: this.subscription.toJSON(),
180
+ ...(this.channelId ? {
181
+ channel_id: this.channelId
182
+ } : {})
183
+ });
184
+ if (response.succeeded) {
185
+ this.retryAttempts = 0;
186
+ } else {
214
187
  this.scheduleRetry();
215
- throw error;
216
188
  }
189
+ return response;
190
+ } catch (error) {
191
+ this.scheduleRetry();
192
+ throw error;
217
193
  }
194
+ }
218
195
 
219
- /**
220
- * Schedules up to three registration retries with increasing delays.
221
- *
222
- * @private
223
- * @returns {void}
224
- */
225
- }, {
226
- key: "scheduleRetry",
227
- value: function scheduleRetry() {
228
- if (this.disposed || this.unsubscribePromise || this.retryTimeout || this.retryAttempts >= 3) return;
229
- this.retryTimeout = setTimeout(() => {
230
- this.retryTimeout = null;
231
- this.sync().catch(() => {});
232
- }, 1000 * 2 ** this.retryAttempts);
233
- this.retryAttempts += 1;
234
- }
235
-
236
- /**
237
- * Cancels a pending registration retry.
238
- *
239
- * @private
240
- * @returns {void}
241
- */
242
- }, {
243
- key: "clearRetryTimeout",
244
- value: function clearRetryTimeout() {
245
- clearTimeout(this.retryTimeout);
196
+ /**
197
+ * Schedules up to three registration retries with increasing delays.
198
+ *
199
+ * @private
200
+ * @returns {void}
201
+ */
202
+ scheduleRetry() {
203
+ if (this.disposed || this.unsubscribePromise || this.retryTimeout || this.retryAttempts >= 3) return;
204
+ this.retryTimeout = setTimeout(() => {
246
205
  this.retryTimeout = null;
247
- }
206
+ this.sync().catch(() => {});
207
+ }, 1000 * 2 ** this.retryAttempts);
208
+ this.retryAttempts += 1;
209
+ }
248
210
 
249
- /**
250
- * Stops registration retries and prevents further use of this instance.
251
- *
252
- * @returns {void}
253
- */
254
- }, {
255
- key: "dispose",
256
- value: function dispose() {
257
- this.disposed = true;
258
- this.clearRetryTimeout();
259
- }
211
+ /**
212
+ * Cancels a pending registration retry.
213
+ *
214
+ * @private
215
+ * @returns {void}
216
+ */
217
+ clearRetryTimeout() {
218
+ clearTimeout(this.retryTimeout);
219
+ this.retryTimeout = null;
220
+ }
260
221
 
261
- /**
262
- * Whether this instance has a browser subscription, regardless of server registration.
263
- *
264
- * @returns {Boolean}
265
- */
266
- }, {
267
- key: "subscribed",
268
- get: function () {
269
- return !!this.subscription;
270
- }
222
+ /**
223
+ * Stops registration retries and prevents further use of this instance.
224
+ *
225
+ * @returns {void}
226
+ */
227
+ dispose() {
228
+ this.disposed = true;
229
+ this.clearRetryTimeout();
230
+ }
271
231
 
272
- /**
273
- * Decodes the public key into the bytes expected by PushManager.subscribe().
274
- *
275
- * @private
276
- * @returns {Uint8Array}
277
- */
278
- }, {
279
- key: "applicationServerKey",
280
- get: function () {
281
- const base64 = this.publicKey.replace(/-/g, '+').replace(/_/g, '/');
282
- return Uint8Array.from(atob(base64.padEnd(Math.ceil(base64.length / 4) * 4, '=')), char => char.charCodeAt(0));
283
- }
232
+ /**
233
+ * Whether this instance has a browser subscription, regardless of server registration.
234
+ *
235
+ * @returns {Boolean}
236
+ */
237
+ get subscribed() {
238
+ return !!this.subscription;
239
+ }
284
240
 
285
- /**
286
- * Checks whether a subscription uses this instance's public key.
287
- *
288
- * @private
289
- * @param {PushSubscription} subscription - Browser subscription to check.
290
- * @returns {Boolean}
291
- */
292
- }, {
293
- key: "owns",
294
- value: function owns(subscription) {
295
- var _subscription$options;
296
- const key = (_subscription$options = subscription.options) === null || _subscription$options === void 0 ? void 0 : _subscription$options.applicationServerKey;
297
- if (!key) return false;
298
- const actual = new Uint8Array(key);
299
- const expected = this.applicationServerKey;
300
- return actual.length === expected.length && actual.every((value, index) => value === expected[index]);
301
- }
241
+ /**
242
+ * Decodes the public key into the bytes expected by PushManager.subscribe().
243
+ *
244
+ * @private
245
+ * @returns {Uint8Array}
246
+ */
247
+ get applicationServerKey() {
248
+ const base64 = this.publicKey.replace(/-/g, '+').replace(/_/g, '/');
249
+ return Uint8Array.from(atob(base64.padEnd(Math.ceil(base64.length / 4) * 4, '=')), char => char.charCodeAt(0));
250
+ }
302
251
 
303
- /**
304
- * Gets the worker registration, sharing any pending lookup.
305
- * Failed lookups can be retried by a later call.
306
- *
307
- * @private
308
- * @returns {Promise<ServiceWorkerRegistration>}
309
- */
310
- }, {
311
- key: "getRegistration",
312
- value: function getRegistration() {
313
- if (!this.registrationPromise) {
314
- this.registrationPromise = this.loadRegistration().catch(error => {
315
- this.registrationPromise = null;
316
- throw error;
317
- });
318
- }
319
- return this.registrationPromise;
252
+ /**
253
+ * Checks whether a subscription uses this instance's public key.
254
+ *
255
+ * @private
256
+ * @param {PushSubscription} subscription - Browser subscription to check.
257
+ * @returns {Boolean}
258
+ */
259
+ owns(subscription) {
260
+ const key = subscription.options?.applicationServerKey;
261
+ if (!key) return false;
262
+ const actual = new Uint8Array(key);
263
+ const expected = this.applicationServerKey;
264
+ return actual.length === expected.length && actual.every((value, index) => value === expected[index]);
265
+ }
266
+
267
+ /**
268
+ * Gets the worker registration, sharing any pending lookup.
269
+ * Failed lookups can be retried by a later call.
270
+ *
271
+ * @private
272
+ * @returns {Promise<ServiceWorkerRegistration>}
273
+ */
274
+ getRegistration() {
275
+ if (!this.registrationPromise) {
276
+ this.registrationPromise = this.loadRegistration().catch(error => {
277
+ this.registrationPromise = null;
278
+ throw error;
279
+ });
320
280
  }
281
+ return this.registrationPromise;
282
+ }
321
283
 
322
- /**
323
- * Registers the configured worker or waits for the page's existing registration.
324
- *
325
- * @private
326
- * @returns {Promise<ServiceWorkerRegistration>} An active registration.
327
- * Rejects if registration fails or the worker readiness wait times out.
328
- */
329
- }, {
330
- key: "loadRegistration",
331
- value: async function loadRegistration() {
332
- if (this.serviceWorkerUrl) {
333
- const registration = await navigator.serviceWorker.register(this.serviceWorkerUrl);
334
- if (registration.active && !registration.installing && !registration.waiting) {
335
- // A returning visitor may have an older worker that does not include our Push handlers.
336
- // Calling register() with the same URL can return that existing registration without
337
- // checking whether the script served at that URL has changed since their last visit.
338
- //
339
- // If no replacement is already installing or waiting, explicitly check for an update
340
- // before treating the active worker as ready. Awaiting update() completes the update
341
- // check, but does not wait for a replacement worker to activate. The code below selects
342
- // that replacement, if one was found, and waits for its activation before subscribing.
343
- await registration.update();
344
- }
345
- const worker = registration.installing || registration.waiting || registration.active;
346
- if ((worker === null || worker === void 0 ? void 0 : worker.state) === 'activated') return registration;
347
- return new Promise((resolve, reject) => {
348
- const timeout = setTimeout(() => finish(new Error('Push service worker did not become active')), 10000);
349
- const finish = error => {
350
- clearTimeout(timeout);
351
- worker === null || worker === void 0 ? void 0 : worker.removeEventListener('statechange', changed);
352
- error ? reject(error) : resolve(registration);
353
- };
354
- const changed = () => {
355
- if ((worker === null || worker === void 0 ? void 0 : worker.state) === 'activated') finish();
356
- if ((worker === null || worker === void 0 ? void 0 : worker.state) === 'redundant') finish(new Error('Push service worker installation failed'));
357
- };
358
- worker === null || worker === void 0 ? void 0 : worker.addEventListener('statechange', changed);
359
- changed();
360
- });
284
+ /**
285
+ * Registers the configured worker or waits for the page's existing registration.
286
+ *
287
+ * @private
288
+ * @returns {Promise<ServiceWorkerRegistration>} An active registration.
289
+ * Rejects if registration fails or the worker readiness wait times out.
290
+ */
291
+ async loadRegistration() {
292
+ if (this.serviceWorkerUrl) {
293
+ const registration = await navigator.serviceWorker.register(this.serviceWorkerUrl);
294
+ if (registration.active && !registration.installing && !registration.waiting) {
295
+ // A returning visitor may have an older worker that does not include our Push handlers.
296
+ // Calling register() with the same URL can return that existing registration without
297
+ // checking whether the script served at that URL has changed since their last visit.
298
+ //
299
+ // If no replacement is already installing or waiting, explicitly check for an update
300
+ // before treating the active worker as ready. Awaiting update() completes the update
301
+ // check, but does not wait for a replacement worker to activate. The code below selects
302
+ // that replacement, if one was found, and waits for its activation before subscribing.
303
+ await registration.update();
361
304
  }
362
-
363
- // Reuse the service worker already registered for this page.
305
+ const worker = registration.installing || registration.waiting || registration.active;
306
+ if (worker?.state === 'activated') return registration;
364
307
  return new Promise((resolve, reject) => {
365
- const timeout = setTimeout(() => reject(new Error('Push service worker is not available')), 10000);
366
- navigator.serviceWorker.ready.then(registration => {
308
+ const timeout = setTimeout(() => finish(new Error('Push service worker did not become active')), 10000);
309
+ const finish = error => {
367
310
  clearTimeout(timeout);
368
- resolve(registration);
369
- }, error => {
370
- clearTimeout(timeout);
371
- reject(error);
372
- });
311
+ worker?.removeEventListener('statechange', changed);
312
+ error ? reject(error) : resolve(registration);
313
+ };
314
+ const changed = () => {
315
+ if (worker?.state === 'activated') finish();
316
+ if (worker?.state === 'redundant') finish(new Error('Push service worker installation failed'));
317
+ };
318
+ worker?.addEventListener('statechange', changed);
319
+ changed();
373
320
  });
374
321
  }
375
322
 
376
- /**
377
- * Whether the current page provides the browser APIs required for Push.
378
- *
379
- * @returns {Boolean}
380
- */
381
- }], [{
382
- key: "supported",
383
- get: function () {
384
- return typeof window !== 'undefined' && window.isSecureContext === true && typeof navigator !== 'undefined' && 'serviceWorker' in navigator && typeof PushManager !== 'undefined' && typeof Notification !== 'undefined';
385
- }
386
- }]);
387
- return Push;
388
- }();
323
+ // Reuse the service worker already registered for this page.
324
+ return new Promise((resolve, reject) => {
325
+ const timeout = setTimeout(() => reject(new Error('Push service worker is not available')), 10000);
326
+ navigator.serviceWorker.ready.then(registration => {
327
+ clearTimeout(timeout);
328
+ resolve(registration);
329
+ }, error => {
330
+ clearTimeout(timeout);
331
+ reject(error);
332
+ });
333
+ });
334
+ }
335
+
336
+ /**
337
+ * Whether the current page provides the browser APIs required for Push.
338
+ *
339
+ * @returns {Boolean}
340
+ */
341
+ static get supported() {
342
+ return typeof window !== 'undefined' && window.isSecureContext === true && typeof navigator !== 'undefined' && 'serviceWorker' in navigator && typeof PushManager !== 'undefined' && typeof Notification !== 'undefined';
343
+ }
344
+ }
389
345
  exports.Push = Push;