@amplifyup/sdk 0.1.19 → 0.1.21

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
@@ -359,6 +359,15 @@ var AmplifyUpSDK = class {
359
359
  this.componentViewObservers = [];
360
360
  this.componentViewSeen = /* @__PURE__ */ new Set();
361
361
  this.pageEngagementActive = false;
362
+ /** Path of the last page() / routeChange — avoids duplicate SPA fires. */
363
+ this.lastTrackedPath = null;
364
+ this.historyHooksInstalled = false;
365
+ this.pageEngagementState = {
366
+ reached: /* @__PURE__ */ new Set(),
367
+ visibleMs: 0,
368
+ visibleSince: null,
369
+ lastDwellSecondsSent: 0
370
+ };
362
371
  this.adapter = adapter || new AWSAdapter();
363
372
  if (typeof window !== "undefined") {
364
373
  this.isVisualEditorMode = this.detectVisualEditorMode();
@@ -531,7 +540,9 @@ var AmplifyUpSDK = class {
531
540
  this.initialPageSent = true;
532
541
  const url = window.location.pathname;
533
542
  this.page(url);
543
+ this.lastTrackedPath = url;
534
544
  this.setupPageEngagement();
545
+ this.installHistoryHooks();
535
546
  }
536
547
  }
537
548
  if (this.config?.debug && this.initialized) {
@@ -574,16 +585,18 @@ var AmplifyUpSDK = class {
574
585
  }
575
586
  /**
576
587
  * Automatic page-level Scroll Depth + Time on Page (dwell heartbeat).
588
+ * State lives on the instance so SPA route changes can reset milestones.
577
589
  */
578
590
  setupPageEngagement() {
579
591
  if (typeof window === "undefined" || typeof document === "undefined") return;
580
592
  if (this.isPreviewMode() || this.pageEngagementActive) return;
581
593
  this.pageEngagementActive = true;
582
594
  const milestones = [25, 50, 75, 100];
583
- const reached = /* @__PURE__ */ new Set();
584
- let visibleMs = 0;
585
- let visibleSince = document.visibilityState === "visible" ? Date.now() : null;
586
- let lastDwellSecondsSent = 0;
595
+ const state = this.pageEngagementState;
596
+ state.reached = /* @__PURE__ */ new Set();
597
+ state.visibleMs = 0;
598
+ state.visibleSince = document.visibilityState === "visible" ? Date.now() : null;
599
+ state.lastDwellSecondsSent = 0;
587
600
  let scrollRaf = null;
588
601
  const path = () => this.currentPath();
589
602
  const measureScrollPercent = () => {
@@ -605,8 +618,8 @@ var AmplifyUpSDK = class {
605
618
  if (this.isPreviewMode()) return;
606
619
  const pct = measureScrollPercent();
607
620
  for (const milestone of milestones) {
608
- if (pct >= milestone && !reached.has(milestone)) {
609
- reached.add(milestone);
621
+ if (pct >= milestone && !state.reached.has(milestone)) {
622
+ state.reached.add(milestone);
610
623
  this.track("Scroll Depth", {
611
624
  percentage: milestone,
612
625
  path: path()
@@ -622,28 +635,29 @@ var AmplifyUpSDK = class {
622
635
  });
623
636
  };
624
637
  const accumulateVisible = () => {
625
- if (visibleSince == null) return;
626
- visibleMs += Date.now() - visibleSince;
627
- visibleSince = Date.now();
638
+ if (state.visibleSince == null) return;
639
+ state.visibleMs += Date.now() - state.visibleSince;
640
+ state.visibleSince = Date.now();
628
641
  };
629
642
  const emitDwell = (force = false) => {
630
643
  if (this.isPreviewMode()) return;
631
644
  accumulateVisible();
632
- const seconds = Math.floor(visibleMs / 1e3);
645
+ const seconds = Math.floor(state.visibleMs / 1e3);
633
646
  if (seconds <= 0) return;
634
- if (!force && seconds <= lastDwellSecondsSent) return;
635
- lastDwellSecondsSent = seconds;
647
+ if (!force && seconds <= state.lastDwellSecondsSent) return;
648
+ state.lastDwellSecondsSent = seconds;
636
649
  this.track("Time on Page", {
637
650
  seconds,
638
- path: path()
651
+ path: this.lastTrackedPath || path()
639
652
  });
640
653
  };
654
+ this._emitPageDwell = emitDwell;
641
655
  const onVisibility = () => {
642
656
  if (document.visibilityState === "visible") {
643
- visibleSince = Date.now();
657
+ state.visibleSince = Date.now();
644
658
  } else {
645
659
  emitDwell(true);
646
- visibleSince = null;
660
+ state.visibleSince = null;
647
661
  }
648
662
  };
649
663
  const onPageHide = () => {
@@ -670,11 +684,64 @@ var AmplifyUpSDK = class {
670
684
  }
671
685
  previousCleanup?.();
672
686
  this.pageEngagementActive = false;
687
+ delete this._emitPageDwell;
673
688
  };
674
689
  if (this.config?.debug) {
675
690
  console.log("[AmplifyUp SDK] Page engagement tracking enabled");
676
691
  }
677
692
  }
693
+ resetEngagementForNewPage() {
694
+ const emit = this._emitPageDwell;
695
+ emit?.(true);
696
+ const state = this.pageEngagementState;
697
+ state.reached = /* @__PURE__ */ new Set();
698
+ state.visibleMs = 0;
699
+ state.lastDwellSecondsSent = 0;
700
+ state.visibleSince = typeof document !== "undefined" && document.visibilityState === "visible" ? Date.now() : null;
701
+ this.componentViewSeen.clear();
702
+ }
703
+ /**
704
+ * SPA / soft navigation: fire a page view and reset engagement.
705
+ * No-op when the path has not changed. Safe for React Strict Mode remounts.
706
+ */
707
+ routeChange(url, properties) {
708
+ if (this.isPreviewMode()) return;
709
+ if (!this.isInitialized()) return;
710
+ if (typeof window === "undefined") return;
711
+ const path = url || window.location.pathname || "/";
712
+ if (path === this.lastTrackedPath) return;
713
+ this.resetEngagementForNewPage();
714
+ this.page(path, properties);
715
+ this.lastTrackedPath = path;
716
+ if (!this.pageEngagementActive) {
717
+ this.setupPageEngagement();
718
+ }
719
+ if (this.config?.debug) {
720
+ console.log("[AmplifyUp SDK] Route change page view", path);
721
+ }
722
+ }
723
+ /**
724
+ * Patch history.pushState / replaceState + popstate for non-React SPAs.
725
+ * React/Next apps should also call routeChange from the provider.
726
+ */
727
+ installHistoryHooks() {
728
+ if (typeof window === "undefined" || this.historyHooksInstalled) return;
729
+ this.historyHooksInstalled = true;
730
+ const notify = () => {
731
+ queueMicrotask(() => this.routeChange(window.location.pathname));
732
+ };
733
+ const wrap = (method) => {
734
+ const original = history[method].bind(history);
735
+ history[method] = (...args) => {
736
+ const result = original(...args);
737
+ notify();
738
+ return result;
739
+ };
740
+ };
741
+ wrap("pushState");
742
+ wrap("replaceState");
743
+ window.addEventListener("popstate", notify);
744
+ }
678
745
  /**
679
746
  * Automatic Component View when component hosts enter the viewport.
680
747
  */
@@ -749,6 +816,7 @@ var AmplifyUpSDK = class {
749
816
  ...properties
750
817
  };
751
818
  this.adapter.page(pageProperties);
819
+ this.lastTrackedPath = url;
752
820
  }
753
821
  /**
754
822
  * Track an event
@@ -2289,6 +2357,7 @@ async function init(config) {
2289
2357
  await sdk.init(config);
2290
2358
  }
2291
2359
  var page = (url, properties) => getSDK().page(url, properties);
2360
+ var routeChange = (url, properties) => getSDK().routeChange(url, properties);
2292
2361
  var track = (eventName, properties) => getSDK().track(eventName, properties);
2293
2362
  var trackClick = (elementId, elementText, properties) => getSDK().trackClick(elementId, elementText, properties);
2294
2363
  var trackFormSubmit = (formId, formData) => getSDK().trackFormSubmit(formId, formData);
@@ -2324,6 +2393,6 @@ var verifyAWSConnection = () => {
2324
2393
  };
2325
2394
  var index_default = getSDK();
2326
2395
 
2327
- export { AmplifyUpSDK, buildLayoutProviderUrl, buildPageRenderUrl, cleanupEventTracking, index_default as default, fetchPageConfig, getDiagnostics, getInstanceId2 as getInstanceId, getOrchestratorUrl, getSDK, getStatus, getTarget, getTrackingId, getUserId2 as getUserId, identify, init, isAmplifyUpTarget, isComposerPreview, isPreviewRequest, normalizeAmplifyUpTarget, page, refreshEventTracking, reset, resolveAmplifyUpTarget, resolveAmplifyUpUrls, setupComponentViewTracking, setupEventTracking, testTracking, track, trackClick, trackContentEngagement, trackContentView, trackFormFieldInteraction, trackFormSubmit, verifyAWSConnection };
2396
+ export { AmplifyUpSDK, buildLayoutProviderUrl, buildPageRenderUrl, cleanupEventTracking, index_default as default, fetchPageConfig, getDiagnostics, getInstanceId2 as getInstanceId, getOrchestratorUrl, getSDK, getStatus, getTarget, getTrackingId, getUserId2 as getUserId, identify, init, isAmplifyUpTarget, isComposerPreview, isPreviewRequest, normalizeAmplifyUpTarget, page, refreshEventTracking, reset, resolveAmplifyUpTarget, resolveAmplifyUpUrls, routeChange, setupComponentViewTracking, setupEventTracking, testTracking, track, trackClick, trackContentEngagement, trackContentView, trackFormFieldInteraction, trackFormSubmit, verifyAWSConnection };
2328
2397
  //# sourceMappingURL=index.mjs.map
2329
2398
  //# sourceMappingURL=index.mjs.map