@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/index.mjs CHANGED
@@ -506,6 +506,10 @@ async function fetchContent(options) {
506
506
 
507
507
  // src/index.ts
508
508
  var SESSION_IDLE_GAP_MS = 30 * 60 * 1e3;
509
+ var DWELL_MILESTONES_SEC = [15, 30, 60, 120, 300];
510
+ var DWELL_CHECKPOINT_SEC = 15 * 60;
511
+ var DWELL_ACTIVITY_IDLE_MS = 2 * 60 * 1e3;
512
+ var DWELL_POLL_MS = 5e3;
509
513
  function readPreviewQueryOverrides() {
510
514
  if (typeof window === "undefined") return {};
511
515
  const params = new URLSearchParams(window.location.search);
@@ -576,7 +580,10 @@ var AmplifyUpSDK = class {
576
580
  visibleSince: null,
577
581
  lastDwellSecondsSent: 0,
578
582
  /** When the tab last became hidden — used for idle-resume re-page. */
579
- hiddenAt: null
583
+ hiddenAt: null,
584
+ /** Last user interaction — freezes dwell when stale while visible. */
585
+ lastActivityAt: 0,
586
+ activityIdle: false
580
587
  };
581
588
  this.adapter = adapter || new AWSAdapter();
582
589
  if (typeof window !== "undefined") {
@@ -799,8 +806,10 @@ var AmplifyUpSDK = class {
799
806
  return window.location.pathname || "/";
800
807
  }
801
808
  /**
802
- * Automatic page-level Scroll Depth + Time on Page (dwell heartbeat).
803
- * State lives on the instance so SPA route changes can reset milestones.
809
+ * Automatic page-level Scroll Depth + Time on Page.
810
+ * Dwell uses milestones / sparse checkpoints (not a fixed 15s heartbeat),
811
+ * freezes while the tab is visible but the user is idle, and always flushes
812
+ * on hide / unload / SPA route change.
804
813
  */
805
814
  setupPageEngagement() {
806
815
  if (typeof window === "undefined" || typeof document === "undefined") return;
@@ -813,6 +822,8 @@ var AmplifyUpSDK = class {
813
822
  state.visibleSince = document.visibilityState === "visible" ? Date.now() : null;
814
823
  state.lastDwellSecondsSent = 0;
815
824
  state.hiddenAt = document.visibilityState === "hidden" ? Date.now() : null;
825
+ state.lastActivityAt = Date.now();
826
+ state.activityIdle = false;
816
827
  let scrollRaf = null;
817
828
  const path = () => this.currentPath();
818
829
  const measureScrollPercent = () => {
@@ -844,6 +855,7 @@ var AmplifyUpSDK = class {
844
855
  }
845
856
  };
846
857
  const onScroll = () => {
858
+ noteActivity();
847
859
  if (scrollRaf != null) return;
848
860
  scrollRaf = window.requestAnimationFrame(() => {
849
861
  scrollRaf = null;
@@ -855,19 +867,58 @@ var AmplifyUpSDK = class {
855
867
  state.visibleMs += Date.now() - state.visibleSince;
856
868
  state.visibleSince = Date.now();
857
869
  };
858
- const emitDwell = (_force = false) => {
859
- if (this.isPreviewMode()) return;
870
+ const freezeActivityIdle = () => {
871
+ if (state.activityIdle) return;
860
872
  accumulateVisible();
873
+ state.visibleSince = null;
874
+ state.activityIdle = true;
875
+ };
876
+ const noteActivity = () => {
877
+ state.lastActivityAt = Date.now();
878
+ if (state.activityIdle) {
879
+ state.activityIdle = false;
880
+ if (document.visibilityState === "visible" && state.visibleSince == null) {
881
+ state.visibleSince = Date.now();
882
+ }
883
+ }
884
+ };
885
+ const nextEmitTarget = (lastSent) => {
886
+ for (const m of DWELL_MILESTONES_SEC) {
887
+ if (m > lastSent) return { seconds: m, reason: "milestone" };
888
+ }
889
+ const nextCheckpoint = Math.floor(lastSent / DWELL_CHECKPOINT_SEC) * DWELL_CHECKPOINT_SEC + DWELL_CHECKPOINT_SEC;
890
+ const target = nextCheckpoint > lastSent ? nextCheckpoint : lastSent + DWELL_CHECKPOINT_SEC;
891
+ return { seconds: target, reason: "checkpoint" };
892
+ };
893
+ const emitDwell = (reason, force = false) => {
894
+ if (this.isPreviewMode()) return;
895
+ if (!state.activityIdle) {
896
+ accumulateVisible();
897
+ }
861
898
  const seconds = Math.floor(state.visibleMs / 1e3);
862
899
  if (seconds <= 0) return;
863
900
  if (seconds <= state.lastDwellSecondsSent) return;
901
+ if (!force) {
902
+ const target = nextEmitTarget(state.lastDwellSecondsSent);
903
+ if (!target || seconds < target.seconds) return;
904
+ reason = target.reason;
905
+ }
864
906
  state.lastDwellSecondsSent = seconds;
865
907
  this.track("Time on Page", {
866
908
  seconds,
867
- path: this.lastTrackedPath || path()
909
+ path: this.lastTrackedPath || path(),
910
+ reason
868
911
  });
869
912
  };
870
- this._emitPageDwell = emitDwell;
913
+ const evaluateDwell = () => {
914
+ if (document.visibilityState !== "visible") return;
915
+ if (Date.now() - state.lastActivityAt >= DWELL_ACTIVITY_IDLE_MS) {
916
+ freezeActivityIdle();
917
+ return;
918
+ }
919
+ emitDwell("milestone", false);
920
+ };
921
+ this._emitPageDwell = (force) => emitDwell("route", force !== false);
871
922
  const onVisibility = () => {
872
923
  if (document.visibilityState === "visible") {
873
924
  const idleMs = state.hiddenAt != null ? Date.now() - state.hiddenAt : 0;
@@ -885,35 +936,51 @@ var AmplifyUpSDK = class {
885
936
  );
886
937
  }
887
938
  }
939
+ noteActivity();
888
940
  state.visibleSince = Date.now();
941
+ state.activityIdle = false;
889
942
  } else {
890
- emitDwell(true);
943
+ emitDwell("hidden", true);
891
944
  state.hiddenAt = Date.now();
892
945
  state.visibleSince = null;
946
+ state.activityIdle = false;
893
947
  }
894
948
  };
895
949
  const onPageHide = () => {
896
- emitDwell(true);
950
+ emitDwell("unload", true);
897
951
  if (state.hiddenAt == null) {
898
952
  state.hiddenAt = Date.now();
899
953
  }
900
954
  state.visibleSince = null;
901
955
  };
956
+ const activityEvents = [
957
+ "pointerdown",
958
+ "keydown",
959
+ "scroll",
960
+ "touchstart"
961
+ ];
962
+ const onActivity = () => noteActivity();
902
963
  window.addEventListener("scroll", onScroll, { passive: true });
903
964
  document.addEventListener("visibilitychange", onVisibility);
904
965
  window.addEventListener("pagehide", onPageHide);
966
+ for (const evt of activityEvents) {
967
+ if (evt === "scroll") continue;
968
+ window.addEventListener(evt, onActivity, { passive: true });
969
+ }
905
970
  checkScroll();
906
971
  const heartbeat = setInterval(() => {
907
- if (document.visibilityState === "visible") {
908
- emitDwell(false);
909
- }
910
- }, 15e3);
972
+ evaluateDwell();
973
+ }, DWELL_POLL_MS);
911
974
  this.trackingIntervals.push(heartbeat);
912
975
  const previousCleanup = this.trackingCleanup;
913
976
  this.trackingCleanup = () => {
914
977
  window.removeEventListener("scroll", onScroll);
915
978
  document.removeEventListener("visibilitychange", onVisibility);
916
979
  window.removeEventListener("pagehide", onPageHide);
980
+ for (const evt of activityEvents) {
981
+ if (evt === "scroll") continue;
982
+ window.removeEventListener(evt, onActivity);
983
+ }
917
984
  if (scrollRaf != null) {
918
985
  window.cancelAnimationFrame(scrollRaf);
919
986
  scrollRaf = null;
@@ -939,6 +1006,8 @@ var AmplifyUpSDK = class {
939
1006
  state.visibleMs = 0;
940
1007
  state.lastDwellSecondsSent = 0;
941
1008
  state.hiddenAt = null;
1009
+ state.lastActivityAt = Date.now();
1010
+ state.activityIdle = false;
942
1011
  state.visibleSince = typeof document !== "undefined" && document.visibilityState === "visible" ? Date.now() : null;
943
1012
  this.componentViewSeen.clear();
944
1013
  }
@@ -2688,6 +2757,6 @@ var verifyAWSConnection = () => {
2688
2757
  };
2689
2758
  var index_default = getSDK();
2690
2759
 
2691
- export { AmplifyUpSDK, EdgeResolveError, SESSION_IDLE_GAP_MS, buildLayoutProviderUrl, buildPageRenderUrl, cleanupEventTracking, index_default as default, fetchContent, fetchEdgeResolve, fetchPageConfig, getDiagnostics, getInstanceId2 as getInstanceId, getOrchestratorUrl, getSDK, getStatus, getTarget, getTrackingId, getUserId2 as getUserId, identify, init, isAmplifyUpTarget, isComposerPreview, isPreviewRequest, mapResolvedToPageConfig, normalizeAmplifyUpTarget, normalizeRoute, page, refreshEventTracking, reset, resolveAmplifyUpTarget, resolveAmplifyUpUrls, routeChange, setProfileFields, setupComponentViewTracking, setupEventTracking, testTracking, track, trackClick, trackContentEngagement, trackContentView, trackFormFieldInteraction, trackFormSubmit, verifyAWSConnection };
2760
+ export { AmplifyUpSDK, DWELL_ACTIVITY_IDLE_MS, DWELL_CHECKPOINT_SEC, DWELL_MILESTONES_SEC, EdgeResolveError, SESSION_IDLE_GAP_MS, buildLayoutProviderUrl, buildPageRenderUrl, cleanupEventTracking, index_default as default, fetchContent, fetchEdgeResolve, fetchPageConfig, getDiagnostics, getInstanceId2 as getInstanceId, getOrchestratorUrl, getSDK, getStatus, getTarget, getTrackingId, getUserId2 as getUserId, identify, init, isAmplifyUpTarget, isComposerPreview, isPreviewRequest, mapResolvedToPageConfig, normalizeAmplifyUpTarget, normalizeRoute, page, refreshEventTracking, reset, resolveAmplifyUpTarget, resolveAmplifyUpUrls, routeChange, setProfileFields, setupComponentViewTracking, setupEventTracking, testTracking, track, trackClick, trackContentEngagement, trackContentView, trackFormFieldInteraction, trackFormSubmit, verifyAWSConnection };
2692
2761
  //# sourceMappingURL=index.mjs.map
2693
2762
  //# sourceMappingURL=index.mjs.map