@amplifyup/sdk 0.1.24 → 0.1.25

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/react.mjs CHANGED
@@ -517,6 +517,10 @@ async function fetchContent(options) {
517
517
 
518
518
  // src/index.ts
519
519
  var SESSION_IDLE_GAP_MS = 30 * 60 * 1e3;
520
+ var DWELL_MILESTONES_SEC = [15, 30, 60, 120, 300];
521
+ var DWELL_CHECKPOINT_SEC = 15 * 60;
522
+ var DWELL_ACTIVITY_IDLE_MS = 2 * 60 * 1e3;
523
+ var DWELL_POLL_MS = 5e3;
520
524
  function readPreviewQueryOverrides() {
521
525
  if (typeof window === "undefined") return {};
522
526
  const params = new URLSearchParams(window.location.search);
@@ -587,7 +591,10 @@ var AmplifyUpSDK = class {
587
591
  visibleSince: null,
588
592
  lastDwellSecondsSent: 0,
589
593
  /** When the tab last became hidden — used for idle-resume re-page. */
590
- hiddenAt: null
594
+ hiddenAt: null,
595
+ /** Last user interaction — freezes dwell when stale while visible. */
596
+ lastActivityAt: 0,
597
+ activityIdle: false
591
598
  };
592
599
  this.adapter = adapter || new AWSAdapter();
593
600
  if (typeof window !== "undefined") {
@@ -810,8 +817,10 @@ var AmplifyUpSDK = class {
810
817
  return window.location.pathname || "/";
811
818
  }
812
819
  /**
813
- * Automatic page-level Scroll Depth + Time on Page (dwell heartbeat).
814
- * State lives on the instance so SPA route changes can reset milestones.
820
+ * Automatic page-level Scroll Depth + Time on Page.
821
+ * Dwell uses milestones / sparse checkpoints (not a fixed 15s heartbeat),
822
+ * freezes while the tab is visible but the user is idle, and always flushes
823
+ * on hide / unload / SPA route change.
815
824
  */
816
825
  setupPageEngagement() {
817
826
  if (typeof window === "undefined" || typeof document === "undefined") return;
@@ -824,6 +833,8 @@ var AmplifyUpSDK = class {
824
833
  state.visibleSince = document.visibilityState === "visible" ? Date.now() : null;
825
834
  state.lastDwellSecondsSent = 0;
826
835
  state.hiddenAt = document.visibilityState === "hidden" ? Date.now() : null;
836
+ state.lastActivityAt = Date.now();
837
+ state.activityIdle = false;
827
838
  let scrollRaf = null;
828
839
  const path = () => this.currentPath();
829
840
  const measureScrollPercent = () => {
@@ -855,6 +866,7 @@ var AmplifyUpSDK = class {
855
866
  }
856
867
  };
857
868
  const onScroll = () => {
869
+ noteActivity();
858
870
  if (scrollRaf != null) return;
859
871
  scrollRaf = window.requestAnimationFrame(() => {
860
872
  scrollRaf = null;
@@ -866,19 +878,58 @@ var AmplifyUpSDK = class {
866
878
  state.visibleMs += Date.now() - state.visibleSince;
867
879
  state.visibleSince = Date.now();
868
880
  };
869
- const emitDwell = (_force = false) => {
870
- if (this.isPreviewMode()) return;
881
+ const freezeActivityIdle = () => {
882
+ if (state.activityIdle) return;
871
883
  accumulateVisible();
884
+ state.visibleSince = null;
885
+ state.activityIdle = true;
886
+ };
887
+ const noteActivity = () => {
888
+ state.lastActivityAt = Date.now();
889
+ if (state.activityIdle) {
890
+ state.activityIdle = false;
891
+ if (document.visibilityState === "visible" && state.visibleSince == null) {
892
+ state.visibleSince = Date.now();
893
+ }
894
+ }
895
+ };
896
+ const nextEmitTarget = (lastSent) => {
897
+ for (const m of DWELL_MILESTONES_SEC) {
898
+ if (m > lastSent) return { seconds: m, reason: "milestone" };
899
+ }
900
+ const nextCheckpoint = Math.floor(lastSent / DWELL_CHECKPOINT_SEC) * DWELL_CHECKPOINT_SEC + DWELL_CHECKPOINT_SEC;
901
+ const target = nextCheckpoint > lastSent ? nextCheckpoint : lastSent + DWELL_CHECKPOINT_SEC;
902
+ return { seconds: target, reason: "checkpoint" };
903
+ };
904
+ const emitDwell = (reason, force = false) => {
905
+ if (this.isPreviewMode()) return;
906
+ if (!state.activityIdle) {
907
+ accumulateVisible();
908
+ }
872
909
  const seconds = Math.floor(state.visibleMs / 1e3);
873
910
  if (seconds <= 0) return;
874
911
  if (seconds <= state.lastDwellSecondsSent) return;
912
+ if (!force) {
913
+ const target = nextEmitTarget(state.lastDwellSecondsSent);
914
+ if (!target || seconds < target.seconds) return;
915
+ reason = target.reason;
916
+ }
875
917
  state.lastDwellSecondsSent = seconds;
876
918
  this.track("Time on Page", {
877
919
  seconds,
878
- path: this.lastTrackedPath || path()
920
+ path: this.lastTrackedPath || path(),
921
+ reason
879
922
  });
880
923
  };
881
- this._emitPageDwell = emitDwell;
924
+ const evaluateDwell = () => {
925
+ if (document.visibilityState !== "visible") return;
926
+ if (Date.now() - state.lastActivityAt >= DWELL_ACTIVITY_IDLE_MS) {
927
+ freezeActivityIdle();
928
+ return;
929
+ }
930
+ emitDwell("milestone", false);
931
+ };
932
+ this._emitPageDwell = (force) => emitDwell("route", force !== false);
882
933
  const onVisibility = () => {
883
934
  if (document.visibilityState === "visible") {
884
935
  const idleMs = state.hiddenAt != null ? Date.now() - state.hiddenAt : 0;
@@ -896,35 +947,51 @@ var AmplifyUpSDK = class {
896
947
  );
897
948
  }
898
949
  }
950
+ noteActivity();
899
951
  state.visibleSince = Date.now();
952
+ state.activityIdle = false;
900
953
  } else {
901
- emitDwell(true);
954
+ emitDwell("hidden", true);
902
955
  state.hiddenAt = Date.now();
903
956
  state.visibleSince = null;
957
+ state.activityIdle = false;
904
958
  }
905
959
  };
906
960
  const onPageHide = () => {
907
- emitDwell(true);
961
+ emitDwell("unload", true);
908
962
  if (state.hiddenAt == null) {
909
963
  state.hiddenAt = Date.now();
910
964
  }
911
965
  state.visibleSince = null;
912
966
  };
967
+ const activityEvents = [
968
+ "pointerdown",
969
+ "keydown",
970
+ "scroll",
971
+ "touchstart"
972
+ ];
973
+ const onActivity = () => noteActivity();
913
974
  window.addEventListener("scroll", onScroll, { passive: true });
914
975
  document.addEventListener("visibilitychange", onVisibility);
915
976
  window.addEventListener("pagehide", onPageHide);
977
+ for (const evt of activityEvents) {
978
+ if (evt === "scroll") continue;
979
+ window.addEventListener(evt, onActivity, { passive: true });
980
+ }
916
981
  checkScroll();
917
982
  const heartbeat = setInterval(() => {
918
- if (document.visibilityState === "visible") {
919
- emitDwell(false);
920
- }
921
- }, 15e3);
983
+ evaluateDwell();
984
+ }, DWELL_POLL_MS);
922
985
  this.trackingIntervals.push(heartbeat);
923
986
  const previousCleanup = this.trackingCleanup;
924
987
  this.trackingCleanup = () => {
925
988
  window.removeEventListener("scroll", onScroll);
926
989
  document.removeEventListener("visibilitychange", onVisibility);
927
990
  window.removeEventListener("pagehide", onPageHide);
991
+ for (const evt of activityEvents) {
992
+ if (evt === "scroll") continue;
993
+ window.removeEventListener(evt, onActivity);
994
+ }
928
995
  if (scrollRaf != null) {
929
996
  window.cancelAnimationFrame(scrollRaf);
930
997
  scrollRaf = null;
@@ -950,6 +1017,8 @@ var AmplifyUpSDK = class {
950
1017
  state.visibleMs = 0;
951
1018
  state.lastDwellSecondsSent = 0;
952
1019
  state.hiddenAt = null;
1020
+ state.lastActivityAt = Date.now();
1021
+ state.activityIdle = false;
953
1022
  state.visibleSince = typeof document !== "undefined" && document.visibilityState === "visible" ? Date.now() : null;
954
1023
  this.componentViewSeen.clear();
955
1024
  }