@affiliateo/web 4.9.2 → 4.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/queue.d.ts +6 -6
- package/dist/queue.js +34 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -270,6 +270,10 @@ the script tag, `data-chat-color`, `data-chat-icon-color`, `data-chat-send-color
|
|
|
270
270
|
|
|
271
271
|
## Changelog
|
|
272
272
|
|
|
273
|
+
- **4.9.3:** the events still waiting when a page closes now reach Affiliateo
|
|
274
|
+
on websites with strict privacy settings too (a referrer policy of
|
|
275
|
+
`no-referrer` or `same-origin`, the defaults of Helmet and Django). Nothing
|
|
276
|
+
to change in your code.
|
|
273
277
|
- **4.9.2:** events are sent as plain text, so the browser no longer makes an
|
|
274
278
|
extra check request before each one. Nothing to change in your code.
|
|
275
279
|
- **4.9.1:** a different user signing in with `identify()` (no `logout()` in
|
package/dist/queue.d.ts
CHANGED
|
@@ -84,15 +84,15 @@ export declare class EventQueue {
|
|
|
84
84
|
* burst path + the timer firing simultaneously) only run one
|
|
85
85
|
* flush at a time. */
|
|
86
86
|
flush(): Promise<void>;
|
|
87
|
-
/** Best-effort sync flush triggered on page unload
|
|
88
|
-
*
|
|
89
|
-
* the last chance.
|
|
87
|
+
/** Best-effort sync flush triggered on page unload: each event goes out
|
|
88
|
+
* in a way that survives the tab closing (sendAtUnload). No retry - this
|
|
89
|
+
* is the last chance.
|
|
90
90
|
*
|
|
91
91
|
* Called from the provider's pagehide / visibilitychange=hidden
|
|
92
92
|
* handlers so any events still queued at unload get one last shot.
|
|
93
|
-
* After this call, the in-memory queue is cleared (events
|
|
94
|
-
*
|
|
95
|
-
*
|
|
93
|
+
* After this call, the in-memory queue is cleared (events the browser
|
|
94
|
+
* couldn't take are lost - that's the cost of the guaranteed-fast
|
|
95
|
+
* unload path). */
|
|
96
96
|
flushOnUnload(): void;
|
|
97
97
|
/** Remove the queued events `predicate` picks (4.8.0). A sign-in uses it
|
|
98
98
|
* to drop a sign-out still waiting to be delivered: the sign-in replaces
|
package/dist/queue.js
CHANGED
|
@@ -50,6 +50,32 @@ const SIZE_FLUSH_THRESHOLD = 10;
|
|
|
50
50
|
// extra OPTIONS request before every event. The server reads the body as
|
|
51
51
|
// text and parses it itself, so nothing else changes.
|
|
52
52
|
const BODY_TYPE = 'text/plain;charset=UTF-8';
|
|
53
|
+
/** Whether a fetch here outlives the page (keepalive; Firefox only since 133). */
|
|
54
|
+
const KEEPALIVE_FETCH = typeof Request === 'function' && 'keepalive' in Request.prototype;
|
|
55
|
+
/**
|
|
56
|
+
* One last send as the page goes away. A fetch in CORS mode with keepalive,
|
|
57
|
+
* not sendBeacon: a plain-text beacon goes out as no-cors, and on a site
|
|
58
|
+
* whose referrer policy is no-referrer or same-origin (Helmet's and Django's
|
|
59
|
+
* defaults) the browser then sends "Origin: null", which the server refuses,
|
|
60
|
+
* since it takes events only from the app's own site. A CORS fetch always
|
|
61
|
+
* carries the real Origin, is still a simple request (no OPTIONS), and
|
|
62
|
+
* keepalive lets it outlive the page the way a beacon does. Browsers without
|
|
63
|
+
* keepalive keep the beacon (4.9.3). Same in t.js (public/t.js, post()).
|
|
64
|
+
*/
|
|
65
|
+
function sendAtUnload(endpoint, body) {
|
|
66
|
+
try {
|
|
67
|
+
if (KEEPALIVE_FETCH) {
|
|
68
|
+
fetch(endpoint, { method: 'POST', mode: 'cors', credentials: 'omit', headers: { 'Content-Type': BODY_TYPE }, body, keepalive: true }).catch(() => { });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (typeof navigator !== 'undefined' && navigator.sendBeacon && navigator.sendBeacon(endpoint, new Blob([body], { type: BODY_TYPE })))
|
|
72
|
+
return;
|
|
73
|
+
fetch(endpoint, { method: 'POST', headers: { 'Content-Type': BODY_TYPE }, body, keepalive: true }).catch(() => { });
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// The last chance: nothing left to do.
|
|
77
|
+
}
|
|
78
|
+
}
|
|
53
79
|
function lsGet(key) {
|
|
54
80
|
try {
|
|
55
81
|
return localStorage.getItem(key);
|
|
@@ -227,43 +253,20 @@ export class EventQueue {
|
|
|
227
253
|
this.persist();
|
|
228
254
|
this.isFlushing = false;
|
|
229
255
|
}
|
|
230
|
-
/** Best-effort sync flush triggered on page unload
|
|
231
|
-
*
|
|
232
|
-
* the last chance.
|
|
256
|
+
/** Best-effort sync flush triggered on page unload: each event goes out
|
|
257
|
+
* in a way that survives the tab closing (sendAtUnload). No retry - this
|
|
258
|
+
* is the last chance.
|
|
233
259
|
*
|
|
234
260
|
* Called from the provider's pagehide / visibilitychange=hidden
|
|
235
261
|
* handlers so any events still queued at unload get one last shot.
|
|
236
|
-
* After this call, the in-memory queue is cleared (events
|
|
237
|
-
*
|
|
238
|
-
*
|
|
262
|
+
* After this call, the in-memory queue is cleared (events the browser
|
|
263
|
+
* couldn't take are lost - that's the cost of the guaranteed-fast
|
|
264
|
+
* unload path). */
|
|
239
265
|
flushOnUnload() {
|
|
240
266
|
if (this.queue.length === 0)
|
|
241
267
|
return;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
// keepalive as a fallback. Won't actually finish, but it's our
|
|
245
|
-
// last shot.
|
|
246
|
-
for (const event of this.queue) {
|
|
247
|
-
try {
|
|
248
|
-
fetch(event.endpoint, {
|
|
249
|
-
method: 'POST',
|
|
250
|
-
headers: { 'Content-Type': BODY_TYPE },
|
|
251
|
-
body: JSON.stringify(event.payload),
|
|
252
|
-
keepalive: true,
|
|
253
|
-
}).catch(() => { });
|
|
254
|
-
}
|
|
255
|
-
catch { /* swallow */ }
|
|
256
|
-
}
|
|
257
|
-
this.queue = [];
|
|
258
|
-
this.persist();
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
for (const event of this.queue) {
|
|
262
|
-
try {
|
|
263
|
-
navigator.sendBeacon(event.endpoint, new Blob([JSON.stringify(event.payload)], { type: BODY_TYPE }));
|
|
264
|
-
}
|
|
265
|
-
catch { /* swallow */ }
|
|
266
|
-
}
|
|
268
|
+
for (const event of this.queue)
|
|
269
|
+
sendAtUnload(event.endpoint, JSON.stringify(event.payload));
|
|
267
270
|
this.queue = [];
|
|
268
271
|
this.persist();
|
|
269
272
|
}
|