@hanzo/event 0.3.14 → 0.3.15
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/LICENSE.md +21 -0
- package/dist/index.cjs +124 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.mjs +124 -86
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +121 -85
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +121 -85
- package/dist/react.mjs.map +1 -1
- package/hz.js +188 -27
- package/package.json +10 -10
- package/src/anon.d.ts +14 -0
- package/src/anon.js +199 -0
- package/src/anon.test.ts +80 -0
- package/src/hz.test.ts +67 -12
- package/src/storage.test.ts +28 -0
- package/src/storage.ts +14 -99
- package/src/uid.ts +9 -35
- package/src/version.ts +1 -1
package/dist/react.mjs
CHANGED
|
@@ -204,31 +204,110 @@ function scrubText(s, capturePII = false) {
|
|
|
204
204
|
return s;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
// src/
|
|
208
|
-
var
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
for (let i = 5; i >= 0; i--) {
|
|
207
|
+
// src/anon.js
|
|
208
|
+
var HZ_ANON_KEY = "hz_anon_id";
|
|
209
|
+
var HZ_ANON_LEGACY_KEY = "hz_id";
|
|
210
|
+
var HZ_ANON_DOMAIN = "hanzo.ai";
|
|
211
|
+
var HZ_ANON_MAX_AGE = 2 * 365 * 24 * 60 * 60;
|
|
212
|
+
var hzAnonMemo;
|
|
213
|
+
function hzUuidv7(now) {
|
|
214
|
+
var b = new Uint8Array(16);
|
|
215
|
+
var i;
|
|
216
|
+
var c = typeof crypto !== "undefined" ? crypto : void 0;
|
|
217
|
+
if (c && typeof c.getRandomValues === "function") c.getRandomValues(b);
|
|
218
|
+
else for (i = 0; i < 16; i++) b[i] = Math.random() * 256 | 0;
|
|
219
|
+
var t = Math.floor(now === void 0 ? Date.now() : now);
|
|
220
|
+
for (i = 5; i >= 0; i--) {
|
|
222
221
|
b[i] = t % 256;
|
|
223
222
|
t = Math.floor(t / 256);
|
|
224
223
|
}
|
|
225
224
|
b[6] = 112 | b[6] & 15;
|
|
226
225
|
b[8] = 128 | b[8] & 63;
|
|
227
|
-
|
|
226
|
+
var h = "";
|
|
227
|
+
for (i = 0; i < 16; i++) {
|
|
228
|
+
h += (b[i] + 256).toString(16).slice(1);
|
|
229
|
+
if (i === 3 || i === 5 || i === 7 || i === 9) h += "-";
|
|
230
|
+
}
|
|
231
|
+
return h;
|
|
232
|
+
}
|
|
233
|
+
function hzAnonJar() {
|
|
234
|
+
try {
|
|
235
|
+
if (typeof document === "undefined" || typeof document.cookie !== "string") return null;
|
|
236
|
+
return document;
|
|
237
|
+
} catch (e) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function hzAnonStore() {
|
|
242
|
+
try {
|
|
243
|
+
if (typeof window === "undefined" || !window.localStorage) return null;
|
|
244
|
+
return window.localStorage;
|
|
245
|
+
} catch (e) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function hzAnonItem(store, name) {
|
|
250
|
+
try {
|
|
251
|
+
return store && store.getItem(name) || "";
|
|
252
|
+
} catch (e) {
|
|
253
|
+
return "";
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function hzAnonCookie(name) {
|
|
257
|
+
var d = hzAnonJar();
|
|
258
|
+
if (!d) return "";
|
|
259
|
+
var parts = d.cookie.split(";");
|
|
260
|
+
for (var i = 0; i < parts.length; i++) {
|
|
261
|
+
var eq = parts[i].indexOf("=");
|
|
262
|
+
if (eq < 0 || parts[i].slice(0, eq).trim() !== name) continue;
|
|
263
|
+
var v = parts[i].slice(eq + 1).trim();
|
|
264
|
+
if (!v) continue;
|
|
265
|
+
try {
|
|
266
|
+
return decodeURIComponent(v);
|
|
267
|
+
} catch (e) {
|
|
268
|
+
return v;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return "";
|
|
272
|
+
}
|
|
273
|
+
function hzAnonWrite(name, value) {
|
|
274
|
+
var d = hzAnonJar();
|
|
275
|
+
if (!d) return;
|
|
276
|
+
var host = "";
|
|
277
|
+
var secure = false;
|
|
278
|
+
try {
|
|
279
|
+
if (typeof window !== "undefined" && window.location) {
|
|
280
|
+
host = window.location.hostname || "";
|
|
281
|
+
secure = window.location.protocol === "https:";
|
|
282
|
+
}
|
|
283
|
+
} catch (e) {
|
|
284
|
+
}
|
|
285
|
+
var c = name + "=" + encodeURIComponent(value);
|
|
286
|
+
c += "; Path=/; Max-Age=" + HZ_ANON_MAX_AGE + "; SameSite=Lax";
|
|
287
|
+
if (("." + host).slice(-(HZ_ANON_DOMAIN.length + 1)) === "." + HZ_ANON_DOMAIN) {
|
|
288
|
+
c += "; Domain=" + HZ_ANON_DOMAIN;
|
|
289
|
+
}
|
|
290
|
+
if (secure) c += "; Secure";
|
|
291
|
+
try {
|
|
292
|
+
d.cookie = c;
|
|
293
|
+
} catch (e) {
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function hzAnonId() {
|
|
297
|
+
if (typeof window === "undefined") return "";
|
|
298
|
+
var s = hzAnonStore();
|
|
299
|
+
var id = hzAnonCookie(HZ_ANON_KEY) || hzAnonItem(s, HZ_ANON_KEY) || hzAnonItem(s, HZ_ANON_LEGACY_KEY) || hzAnonMemo || hzUuidv7();
|
|
300
|
+
hzAnonMemo = id;
|
|
301
|
+
hzAnonWrite(HZ_ANON_KEY, id);
|
|
302
|
+
try {
|
|
303
|
+
if (s && s.getItem(HZ_ANON_KEY) !== id) s.setItem(HZ_ANON_KEY, id);
|
|
304
|
+
} catch (e) {
|
|
305
|
+
}
|
|
306
|
+
return id;
|
|
228
307
|
}
|
|
229
308
|
|
|
230
309
|
// src/version.ts
|
|
231
|
-
var VERSION = "0.3.
|
|
310
|
+
var VERSION = "0.3.15";
|
|
232
311
|
|
|
233
312
|
// src/sentry.ts
|
|
234
313
|
var MAX_FRAMES = 50;
|
|
@@ -237,7 +316,7 @@ var MAX_LINE_LEN = 2048;
|
|
|
237
316
|
var MAX_TAG_LEN = 1024;
|
|
238
317
|
var MAX_TAGS = 50;
|
|
239
318
|
function eventId() {
|
|
240
|
-
return
|
|
319
|
+
return hzUuidv7().replace(/-/g, "");
|
|
241
320
|
}
|
|
242
321
|
function byteLen(s) {
|
|
243
322
|
if (typeof TextEncoder !== "undefined") return new TextEncoder().encode(s).length;
|
|
@@ -423,14 +502,11 @@ ${payload}
|
|
|
423
502
|
|
|
424
503
|
// src/storage.ts
|
|
425
504
|
var KEY = {
|
|
426
|
-
anon: "hz_anon_id",
|
|
427
505
|
session: "hz_session",
|
|
428
506
|
firstTouch: "hz_first_touch",
|
|
429
507
|
cohort: "hz_cohort"
|
|
430
508
|
};
|
|
431
509
|
var SESSION_TTL_MS = 30 * 60 * 1e3;
|
|
432
|
-
var ANON_DOMAIN = "hanzo.ai";
|
|
433
|
-
var ANON_MAX_AGE_S = 2 * 365 * 24 * 60 * 60;
|
|
434
510
|
function ls() {
|
|
435
511
|
try {
|
|
436
512
|
if (typeof window === "undefined" || !window.localStorage) return void 0;
|
|
@@ -439,69 +515,8 @@ function ls() {
|
|
|
439
515
|
return void 0;
|
|
440
516
|
}
|
|
441
517
|
}
|
|
442
|
-
function jar() {
|
|
443
|
-
try {
|
|
444
|
-
if (typeof document === "undefined" || typeof document.cookie !== "string") return void 0;
|
|
445
|
-
return document;
|
|
446
|
-
} catch {
|
|
447
|
-
return void 0;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
function getCookie(name) {
|
|
451
|
-
const d = jar();
|
|
452
|
-
if (!d) return void 0;
|
|
453
|
-
for (const part of d.cookie.split(";")) {
|
|
454
|
-
const eq = part.indexOf("=");
|
|
455
|
-
if (eq < 0 || part.slice(0, eq).trim() !== name) continue;
|
|
456
|
-
const v = part.slice(eq + 1).trim();
|
|
457
|
-
if (!v) continue;
|
|
458
|
-
try {
|
|
459
|
-
return decodeURIComponent(v);
|
|
460
|
-
} catch {
|
|
461
|
-
return v;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
return void 0;
|
|
465
|
-
}
|
|
466
|
-
function setCookie(name, value) {
|
|
467
|
-
const d = jar();
|
|
468
|
-
if (!d) return;
|
|
469
|
-
let host = "";
|
|
470
|
-
let secure = false;
|
|
471
|
-
try {
|
|
472
|
-
if (typeof window !== "undefined" && window.location) {
|
|
473
|
-
host = window.location.hostname || "";
|
|
474
|
-
secure = window.location.protocol === "https:";
|
|
475
|
-
}
|
|
476
|
-
} catch {
|
|
477
|
-
}
|
|
478
|
-
const attrs = [
|
|
479
|
-
// encodeURIComponent leaves a UUID byte-identical while making any value that
|
|
480
|
-
// is not one unable to forge a `;` and inject an attribute.
|
|
481
|
-
`${name}=${encodeURIComponent(value)}`,
|
|
482
|
-
"Path=/",
|
|
483
|
-
`Max-Age=${ANON_MAX_AGE_S}`,
|
|
484
|
-
"SameSite=Lax"
|
|
485
|
-
];
|
|
486
|
-
if (host === ANON_DOMAIN || host.endsWith(`.${ANON_DOMAIN}`)) attrs.push(`Domain=${ANON_DOMAIN}`);
|
|
487
|
-
if (secure) attrs.push("Secure");
|
|
488
|
-
try {
|
|
489
|
-
d.cookie = attrs.join("; ");
|
|
490
|
-
} catch {
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
var memAnon;
|
|
494
518
|
function anonId() {
|
|
495
|
-
|
|
496
|
-
const s = ls();
|
|
497
|
-
const id = getCookie(KEY.anon) || s?.getItem(KEY.anon) || memAnon || uuidv7();
|
|
498
|
-
memAnon = id;
|
|
499
|
-
setCookie(KEY.anon, id);
|
|
500
|
-
try {
|
|
501
|
-
if (s && s.getItem(KEY.anon) !== id) s.setItem(KEY.anon, id);
|
|
502
|
-
} catch {
|
|
503
|
-
}
|
|
504
|
-
return id;
|
|
519
|
+
return hzAnonId() || void 0;
|
|
505
520
|
}
|
|
506
521
|
function sessionId(now = Date.now()) {
|
|
507
522
|
const s = ls();
|
|
@@ -513,7 +528,7 @@ function sessionId(now = Date.now()) {
|
|
|
513
528
|
state = null;
|
|
514
529
|
}
|
|
515
530
|
if (!state || now - state.last > SESSION_TTL_MS) {
|
|
516
|
-
state = { id:
|
|
531
|
+
state = { id: hzUuidv7(now), last: now };
|
|
517
532
|
} else {
|
|
518
533
|
state.last = now;
|
|
519
534
|
}
|
|
@@ -849,7 +864,7 @@ var Analytics = class {
|
|
|
849
864
|
build(kind, event, extra) {
|
|
850
865
|
const anon = anonId();
|
|
851
866
|
const wire = {
|
|
852
|
-
messageId:
|
|
867
|
+
messageId: hzUuidv7(),
|
|
853
868
|
type: kind,
|
|
854
869
|
event,
|
|
855
870
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -962,6 +977,27 @@ var ErrorBoundary = class extends Component {
|
|
|
962
977
|
}
|
|
963
978
|
};
|
|
964
979
|
ErrorBoundary.contextType = Ctx;
|
|
980
|
+
/*! anon.js — THE anonymous-identity chain. ONE implementation, three distributions.
|
|
981
|
+
*
|
|
982
|
+
* One browser is ONE person on every Hanzo surface, whichever client a page
|
|
983
|
+
* happens to have loaded. There were three implementations writing TWO keys —
|
|
984
|
+
* `hz_anon_id` (the npm client, the hosted tag) and `hz_id` (hz.js) — so the same
|
|
985
|
+
* visitor was several people depending on which snippet the surface shipped.
|
|
986
|
+
*
|
|
987
|
+
* The three call sites:
|
|
988
|
+
* 1. src/storage.ts — the bundled npm client; IMPORTS this file.
|
|
989
|
+
* 2. hz.js — the no-build script tag; INLINES the marked region.
|
|
990
|
+
* 3. hanzoai/cloud apps/analytics/tag.js — the tag the door hosts at
|
|
991
|
+
* /v1/event.js; vendors this file and its tag.go serves the marked region
|
|
992
|
+
* with the tag as one asset, so the door holds no second copy either.
|
|
993
|
+
*
|
|
994
|
+
* (2) and (3) have no bundler and cannot import anything, which is why the chain
|
|
995
|
+
* lives in a file that is plain ES5 rather than in a .ts: the region between the
|
|
996
|
+
* BEGIN and END markers is COPIED VERBATIM, and src/anon.test.ts fails if hz.js's
|
|
997
|
+
* copy is so much as a byte different. Keep the region ES5, dependency-free,
|
|
998
|
+
* `hz`-prefixed (it is spliced into other people's scopes) and unformatted — a
|
|
999
|
+
* reformat of one copy is a diff against the other.
|
|
1000
|
+
*/
|
|
965
1001
|
|
|
966
1002
|
export { AnalyticsProvider, ErrorBoundary, useAnalytics, usePageview };
|
|
967
1003
|
//# sourceMappingURL=react.mjs.map
|