@hanzo/event 0.3.42 → 0.3.43
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/dist/core.d.ts +8 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/index.cjs +124 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +121 -3
- package/dist/index.mjs.map +1 -1
- package/dist/link.d.ts +28 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/react.cjs +120 -2
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +120 -2
- package/dist/react.mjs.map +1 -1
- package/dist/storage.d.ts +6 -0
- package/dist/storage.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/anon.d.ts +3 -0
- package/src/anon.js +19 -1
- package/src/core.ts +45 -3
- package/src/index.ts +2 -0
- package/src/link.test.ts +222 -0
- package/src/link.ts +103 -0
- package/src/storage.ts +14 -1
package/dist/core.d.ts
CHANGED
|
@@ -37,6 +37,14 @@ export declare class Analytics {
|
|
|
37
37
|
* auto-capture unhandled errors. Safe to call from a React effect on every
|
|
38
38
|
* render. */
|
|
39
39
|
init(): void;
|
|
40
|
+
/** link returns `url` carrying this visitor's anonymous id, session and first
|
|
41
|
+
* touch when the destination is a Hanzo-owned host, so the journey continues
|
|
42
|
+
* across the hop. Any other URL comes back unchanged. */
|
|
43
|
+
link(url: string): string;
|
|
44
|
+
/** authorize decorates an OAuth authorize URL for the redirect to IAM and flushes
|
|
45
|
+
* what is queued, because the page is about to unload. Assign the result to
|
|
46
|
+
* `location`. */
|
|
47
|
+
authorize(url: string): string;
|
|
40
48
|
/** identify binds the current visitor to a stable person id (post-login). */
|
|
41
49
|
identify(personId: string, traits?: Record<string, unknown>): void;
|
|
42
50
|
/** group associates the visitor with an org/team (analytics grouping, not the
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AA2DA,OAAO,
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AA2DA,OAAO,EAKL,aAAa,EAEb,SAAS,EAEV,MAAM,WAAW,CAAA;AAGlB,OAAO,KAAK,EACV,eAAe,EAEf,mBAAmB,EACnB,MAAM,EAKN,SAAS,EACV,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,OAAO,EAAE,CAAA;AA2KlB,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAGM;IACjB,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,KAAK,CAA6C;IAC1D,OAAO,CAAC,QAAQ,CAAC,CAAQ;IACzB,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAQ;IACvB,0DAA0D;IAC1D,OAAO,CAAC,OAAO,CAAC,CAAQ;IACxB,+DAA+D;IAC/D,OAAO,CAAC,GAAG,CAAY;IACvB,6EAA6E;IAC7E,OAAO,CAAC,SAAS,CAAQ;IAEzB,YAAY,MAAM,EAAE,eAAe,EAwClC;IAED;;;;8EAI0E;IAC1E,KAAK,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAQnC;IAED;;;mEAG+D;IAC/D,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED;4CACwC;IACxC,IAAI,cAAc,IAAI,MAAM,GAAG,SAAS,CAEvC;IAED;;;kBAGc;IACd,IAAI,IAAI,IAAI,CAgDX;IAED;;8DAE0D;IAC1D,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASxB;IAED;;sBAEkB;IAClB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI7B;IAED,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAGjE;IAED;6EACyE;IACzE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAE7D;IAED;;oEAEgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAclE;IAED;uFACmF;IACnF,OAAO,CACL,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC,GAC5E,IAAI,CAEN;IAED;;;;;;;;;;;;;0BAasB;IACtB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAuD9D;IAED;kCAC8B;IAC9B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE7B;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,MAAM,UAAQ,GAAG,IAAI,CAmC1B;IAID;;;;;6CAKyC;IACzC,OAAO,CAAC,SAAS;IAiBjB;sEACkE;IAClE,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,KAAK;IAkEb,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,UAAU;CAMnB;AAiCD;;;;;;;;;;;4DAW4D;AAC5D,wBAAgB,YAAY,IAAI,IAAI,CAGnC;AAED;;iEAEiE;AACjE,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAmBlE;AAID,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CAAA"}
|
package/dist/index.cjs
CHANGED
|
@@ -391,6 +391,15 @@ function hzAnonId() {
|
|
|
391
391
|
}
|
|
392
392
|
return id;
|
|
393
393
|
}
|
|
394
|
+
function hzAnonAdopt(id) {
|
|
395
|
+
hzAnonMemo = id;
|
|
396
|
+
hzAnonWrite(HZ_ANON_KEY, id);
|
|
397
|
+
try {
|
|
398
|
+
var s = hzAnonStore();
|
|
399
|
+
if (s) s.setItem(HZ_ANON_KEY, id);
|
|
400
|
+
} catch (e) {
|
|
401
|
+
}
|
|
402
|
+
}
|
|
394
403
|
|
|
395
404
|
// src/uid.ts
|
|
396
405
|
function uuidv7Time(id) {
|
|
@@ -398,7 +407,7 @@ function uuidv7Time(id) {
|
|
|
398
407
|
}
|
|
399
408
|
|
|
400
409
|
// package.json
|
|
401
|
-
var version = "0.3.
|
|
410
|
+
var version = "0.3.43";
|
|
402
411
|
|
|
403
412
|
// src/version.ts
|
|
404
413
|
var VERSION = version;
|
|
@@ -718,6 +727,13 @@ function sessionId(now = Date.now()) {
|
|
|
718
727
|
s.setItem(KEY.session, JSON.stringify(state));
|
|
719
728
|
return state.id;
|
|
720
729
|
}
|
|
730
|
+
function adoptSession(id, now = Date.now()) {
|
|
731
|
+
const s = ls();
|
|
732
|
+
if (s) s.setItem(KEY.session, JSON.stringify({ id, last: now }));
|
|
733
|
+
}
|
|
734
|
+
function adoptAnonId(id) {
|
|
735
|
+
hzAnonAdopt(id);
|
|
736
|
+
}
|
|
721
737
|
function getFirstTouch() {
|
|
722
738
|
const s = ls();
|
|
723
739
|
if (!s) return void 0;
|
|
@@ -757,6 +773,76 @@ function mergeCohort(patch) {
|
|
|
757
773
|
return next;
|
|
758
774
|
}
|
|
759
775
|
|
|
776
|
+
// src/link.ts
|
|
777
|
+
var LINK_PARAMS = { anon: "hz_aid", session: "hz_sid", firstTouch: "hz_ft" };
|
|
778
|
+
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
779
|
+
var isId = (v) => !!v && UUID.test(v);
|
|
780
|
+
function encodeFirstTouch(a) {
|
|
781
|
+
return JSON.stringify([
|
|
782
|
+
a.utm.source,
|
|
783
|
+
a.utm.medium,
|
|
784
|
+
a.utm.campaign,
|
|
785
|
+
a.utm.term,
|
|
786
|
+
a.utm.content,
|
|
787
|
+
a.refCode,
|
|
788
|
+
a.referrer,
|
|
789
|
+
a.channel
|
|
790
|
+
].map((v) => v ?? ""));
|
|
791
|
+
}
|
|
792
|
+
function decodeFirstTouch(raw) {
|
|
793
|
+
if (!raw || raw.length > 1024) return void 0;
|
|
794
|
+
try {
|
|
795
|
+
const t = JSON.parse(raw);
|
|
796
|
+
if (!Array.isArray(t) || t.length !== 8 || t.some((v) => typeof v !== "string")) return void 0;
|
|
797
|
+
const [source, medium, campaign, term, content, refCode, referrer, channel] = t;
|
|
798
|
+
const u = (v) => v || void 0;
|
|
799
|
+
return {
|
|
800
|
+
utm: { source: u(source), medium: u(medium), campaign: u(campaign), term: u(term), content: u(content) },
|
|
801
|
+
refCode: u(refCode),
|
|
802
|
+
referrer: u(referrer),
|
|
803
|
+
channel: u(channel)
|
|
804
|
+
};
|
|
805
|
+
} catch {
|
|
806
|
+
return void 0;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
function linkUrl(url, state, fromHost, base) {
|
|
810
|
+
let u;
|
|
811
|
+
try {
|
|
812
|
+
u = new URL(url, base);
|
|
813
|
+
} catch {
|
|
814
|
+
return url;
|
|
815
|
+
}
|
|
816
|
+
if (u.protocol !== "https:" && u.protocol !== "http:") return url;
|
|
817
|
+
if (!orgOf(u.hostname) || u.hostname === fromHost) return url;
|
|
818
|
+
const set = (k, v) => v && u.searchParams.set(k, v);
|
|
819
|
+
if (isId(state.anonId)) set(LINK_PARAMS.anon, state.anonId);
|
|
820
|
+
if (isId(state.sessionId)) set(LINK_PARAMS.session, state.sessionId);
|
|
821
|
+
if (state.firstTouch) set(LINK_PARAMS.firstTouch, encodeFirstTouch(state.firstTouch));
|
|
822
|
+
return u.toString();
|
|
823
|
+
}
|
|
824
|
+
function readLink(search) {
|
|
825
|
+
const q = new URLSearchParams(search || "");
|
|
826
|
+
const a = q.get(LINK_PARAMS.anon);
|
|
827
|
+
const s = q.get(LINK_PARAMS.session);
|
|
828
|
+
return {
|
|
829
|
+
anonId: isId(a) ? a : void 0,
|
|
830
|
+
sessionId: isId(s) ? s : void 0,
|
|
831
|
+
firstTouch: decodeFirstTouch(q.get(LINK_PARAMS.firstTouch))
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
function stripLink(href) {
|
|
835
|
+
const u = new URL(href);
|
|
836
|
+
let hit = false;
|
|
837
|
+
for (const k of Object.values(LINK_PARAMS)) {
|
|
838
|
+
if (u.searchParams.has(k)) {
|
|
839
|
+
u.searchParams.delete(k);
|
|
840
|
+
hit = true;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
return hit ? u.pathname + u.search + u.hash : void 0;
|
|
844
|
+
}
|
|
845
|
+
|
|
760
846
|
// src/core.ts
|
|
761
847
|
var EVENT_PATH = "/v1/event";
|
|
762
848
|
var DEFAULT_HOST = "https://api.hanzo.ai";
|
|
@@ -917,8 +1003,19 @@ var Analytics = class {
|
|
|
917
1003
|
if (this.started || !this.cfg.enabled) return;
|
|
918
1004
|
this.started = true;
|
|
919
1005
|
if (!isBrowser()) return;
|
|
1006
|
+
const linked = readLink(window.location.search);
|
|
1007
|
+
if (linked.anonId) adoptAnonId(linked.anonId);
|
|
1008
|
+
if (linked.sessionId) adoptSession(linked.sessionId);
|
|
1009
|
+
const clean = stripLink(window.location.href);
|
|
1010
|
+
if (clean !== void 0) {
|
|
1011
|
+
try {
|
|
1012
|
+
window.history.replaceState(window.history.state, "", clean);
|
|
1013
|
+
} catch {
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
920
1016
|
const parsed = parseAttribution(window.location.search, document.referrer);
|
|
921
|
-
|
|
1017
|
+
const first = linked.firstTouch && !getFirstTouch() ? setFirstTouchOnce(linked.firstTouch) : void 0;
|
|
1018
|
+
this.attribution = first ?? (hasAttribution(parsed) ? setFirstTouchOnce(parsed) : getFirstTouch() ?? parsed);
|
|
922
1019
|
this.cohort = mergeCohort({
|
|
923
1020
|
channel: this.attribution.channel ?? deriveChannel(this.attribution),
|
|
924
1021
|
refCode: this.attribution.refCode
|
|
@@ -937,6 +1034,27 @@ var Analytics = class {
|
|
|
937
1034
|
});
|
|
938
1035
|
}
|
|
939
1036
|
}
|
|
1037
|
+
/** link returns `url` carrying this visitor's anonymous id, session and first
|
|
1038
|
+
* touch when the destination is a Hanzo-owned host, so the journey continues
|
|
1039
|
+
* across the hop. Any other URL comes back unchanged. */
|
|
1040
|
+
link(url) {
|
|
1041
|
+
if (!isBrowser()) return url;
|
|
1042
|
+
if (!this.started) this.init();
|
|
1043
|
+
return linkUrl(
|
|
1044
|
+
url,
|
|
1045
|
+
{ anonId: anonId(), sessionId: sessionId(), firstTouch: this.attribution },
|
|
1046
|
+
window.location.hostname,
|
|
1047
|
+
window.location.href
|
|
1048
|
+
);
|
|
1049
|
+
}
|
|
1050
|
+
/** authorize decorates an OAuth authorize URL for the redirect to IAM and flushes
|
|
1051
|
+
* what is queued, because the page is about to unload. Assign the result to
|
|
1052
|
+
* `location`. */
|
|
1053
|
+
authorize(url) {
|
|
1054
|
+
const out = this.link(url);
|
|
1055
|
+
this.flush(true);
|
|
1056
|
+
return out;
|
|
1057
|
+
}
|
|
940
1058
|
/** identify binds the current visitor to a stable person id (post-login). */
|
|
941
1059
|
identify(personId, traits) {
|
|
942
1060
|
this.personId = personId;
|
|
@@ -1253,6 +1371,7 @@ Object.defineProperty(exports, "eventsOf", {
|
|
|
1253
1371
|
exports.Analytics = Analytics;
|
|
1254
1372
|
exports.COHORTS = COHORTS;
|
|
1255
1373
|
exports.GOALS = GOALS;
|
|
1374
|
+
exports.LINK_PARAMS = LINK_PARAMS;
|
|
1256
1375
|
exports.ORG_DOMAIN = ORG_DOMAIN;
|
|
1257
1376
|
exports.ORG_KEY = ORG_KEY;
|
|
1258
1377
|
exports.PRODUCT_PROJECT = PRODUCT_PROJECT;
|
|
@@ -1274,13 +1393,16 @@ exports.hostOf = hostOf;
|
|
|
1274
1393
|
exports.isoWeek = isoWeek;
|
|
1275
1394
|
exports.keyFor = keyFor;
|
|
1276
1395
|
exports.keyForPage = keyForPage;
|
|
1396
|
+
exports.linkUrl = linkUrl;
|
|
1277
1397
|
exports.orgOf = orgOf;
|
|
1278
1398
|
exports.parseAttribution = parseAttribution;
|
|
1279
1399
|
exports.parseDsn = parseDsn;
|
|
1400
|
+
exports.readLink = readLink;
|
|
1280
1401
|
exports.redactSecrets = redactSecrets;
|
|
1281
1402
|
exports.resetClients = resetClients;
|
|
1282
1403
|
exports.scrubPII = scrubPII;
|
|
1283
1404
|
exports.scrubText = scrubText;
|
|
1405
|
+
exports.stripLink = stripLink;
|
|
1284
1406
|
exports.uuidv7 = hzUuidv7;
|
|
1285
1407
|
exports.uuidv7Time = uuidv7Time;
|
|
1286
1408
|
//# sourceMappingURL=index.cjs.map
|