@uniweb/core 0.10.2 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/tracker.js +46 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Core classes for the Uniweb platform - Uniweb, Website, Page, Block",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"vitest": "^4.1.7"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@uniweb/
|
|
44
|
-
"@uniweb/
|
|
43
|
+
"@uniweb/semantic-parser": "^1.3.0",
|
|
44
|
+
"@uniweb/theming": "^0.1.15"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
47
|
"test": "vitest run"
|
package/src/tracker.js
CHANGED
|
@@ -49,9 +49,10 @@
|
|
|
49
49
|
* ## Field lifetime — captured once, replayed on every page view
|
|
50
50
|
*
|
|
51
51
|
* `document.referrer` and the landing `utm_*` params exist **at arrival and
|
|
52
|
-
* nowhere afterwards
|
|
53
|
-
* the
|
|
54
|
-
*
|
|
52
|
+
* nowhere afterwards** — as does `continues`, which is derived from the same
|
|
53
|
+
* read: the referrer never changes across SPA navigation, and the params leave
|
|
54
|
+
* the URL on the first navigation. So they are captured once, here, and
|
|
55
|
+
* attached to every `page_view` of the document.
|
|
55
56
|
*
|
|
56
57
|
* ⇒ **Consequence worth knowing when reading the numbers:** a per-view facet
|
|
57
58
|
* built on them is *derived, not observed*. `utm_source` counts "views by
|
|
@@ -113,11 +114,35 @@ function captureAcquisition() {
|
|
|
113
114
|
|
|
114
115
|
// Same-origin referrers are dropped: internal navigation is not a referral,
|
|
115
116
|
// and counting it would make a site its own top referrer on every page.
|
|
117
|
+
//
|
|
118
|
+
// ⭐ **But dropping it destroys the only thing separating two different
|
|
119
|
+
// events, so the fact that it WAS same-origin is kept as one bit.** A full
|
|
120
|
+
// document load happens either because someone arrived from outside, or
|
|
121
|
+
// because a visitor already on the site triggered a real navigation — a
|
|
122
|
+
// locale switch through kit's `<Link reload>` being the shipped case. Both
|
|
123
|
+
// reach a collector with no referrer: the first never had one, the second had
|
|
124
|
+
// it discarded here. ⇒ An "entry pages" metric built on that **invents**
|
|
125
|
+
// arrivals, counting a locale switch as somebody landing on the Spanish page.
|
|
126
|
+
//
|
|
127
|
+
// ⚖️ `continues` states the FACT, not the conclusion. Whether a continuation
|
|
128
|
+
// disqualifies an entry is the consumer's call; a field named for one metric
|
|
129
|
+
// ages badly the moment a second one wants it.
|
|
130
|
+
//
|
|
131
|
+
// ⛔ **It carries no identity and links nothing.** It says only *this document
|
|
132
|
+
// continues a visit*, never *which* — so the categorical claim in this file's
|
|
133
|
+
// header, that nothing persistent is minted, is untouched. Correlating two
|
|
134
|
+
// visits would be a session, which is exactly what is refused.
|
|
116
135
|
const referrer = document.referrer
|
|
117
136
|
if (referrer) {
|
|
118
137
|
try {
|
|
119
138
|
if (new URL(referrer).origin !== window.location.origin) {
|
|
120
139
|
context.referrer = referrer
|
|
140
|
+
} else {
|
|
141
|
+
// Emitted only when true. Absent means "not a continuation" AND "an
|
|
142
|
+
// older runtime that never sent it" — indistinguishable on purpose,
|
|
143
|
+
// because that collapses to today's behaviour rather than to a wrong
|
|
144
|
+
// answer, and it keeps the common payload the size it already was.
|
|
145
|
+
context.continues = true
|
|
121
146
|
}
|
|
122
147
|
} catch {
|
|
123
148
|
// Unparseable — treat as absent rather than forwarding a malformed value.
|
|
@@ -171,13 +196,28 @@ export default class Tracker {
|
|
|
171
196
|
* @param {Object} options
|
|
172
197
|
* @param {string} [options.endpoint] - destination; **required to enable**
|
|
173
198
|
* @param {boolean} [options.consentRequired=false] - hold everything until granted
|
|
174
|
-
* @param {number} [options.
|
|
199
|
+
* @param {number} [options.flushIntervalMs=5000] - batch window, MILLISECONDS
|
|
175
200
|
* @param {number} [options.maxQueueSize=10]
|
|
176
201
|
* @param {boolean} [options.debug=false]
|
|
177
202
|
*/
|
|
178
203
|
constructor(options = {}) {
|
|
179
204
|
this.endpoint = options.endpoint || null
|
|
180
|
-
|
|
205
|
+
// ⭐ **`Ms` is in the name because the unit cannot be inferred from the
|
|
206
|
+
// value, and the failure is silent and inverted.** A bare `flushInterval:
|
|
207
|
+
// 30` meaning *thirty seconds* reads here as 30 **milliseconds** — flushing
|
|
208
|
+
// ~33x a second, the opposite of the intent, indistinguishable from working
|
|
209
|
+
// config, and paid for by the host rather than by whoever typed it. The wire
|
|
210
|
+
// field the host emits is `flushIntervalMs` for the same reason; this option
|
|
211
|
+
// is spelled to match so nothing has to translate between them.
|
|
212
|
+
//
|
|
213
|
+
// ⛔ **No floor is imposed, deliberately.** A minimum here would be a second
|
|
214
|
+
// copy of a policy the host already owns, able only to disagree with theirs —
|
|
215
|
+
// the same reason this framework never co-owns a serve location. What is
|
|
216
|
+
// rejected is not a *small* value but an *invalid* one: anything non-finite
|
|
217
|
+
// or <= 0 would arm a spinning or never-firing timer, so it falls back to the
|
|
218
|
+
// default rather than being honoured.
|
|
219
|
+
const interval = options.flushIntervalMs
|
|
220
|
+
this.flushIntervalMs = Number.isFinite(interval) && interval > 0 ? interval : 5000
|
|
181
221
|
this.maxQueueSize = options.maxQueueSize || 10
|
|
182
222
|
this.debug = options.debug || false
|
|
183
223
|
|
|
@@ -472,7 +512,7 @@ export default class Tracker {
|
|
|
472
512
|
* @private
|
|
473
513
|
*/
|
|
474
514
|
armFlushInterval() {
|
|
475
|
-
setInterval(() => this.flush(), this.
|
|
515
|
+
setInterval(() => this.flush(), this.flushIntervalMs)
|
|
476
516
|
}
|
|
477
517
|
|
|
478
518
|
/** @private */
|