@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 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
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AA2DA,OAAO,EAGL,aAAa,EAEb,SAAS,EAEV,MAAM,WAAW,CAAA;AAElB,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,CAgCX;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"}
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.42";
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
- this.attribution = hasAttribution(parsed) ? setFirstTouchOnce(parsed) : getFirstTouch() ?? parsed;
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