@cross-deck/web 1.9.1 → 1.10.3

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.cjs CHANGED
@@ -98,7 +98,7 @@ function typeMapForStatus(status) {
98
98
  }
99
99
 
100
100
  // src/_version.ts
101
- var SDK_VERSION = "1.9.1";
101
+ var SDK_VERSION = "1.10.3";
102
102
  var SDK_NAME = "@cross-deck/web";
103
103
 
104
104
  // src/http.ts
@@ -1662,24 +1662,32 @@ var AutoTracker = class {
1662
1662
  this.emitSessionStart();
1663
1663
  }
1664
1664
  const onVisChange = () => {
1665
- if (!this.session) return;
1666
- const doc2 = globalThis.document;
1667
- if (doc2.visibilityState === "hidden") {
1668
- this.session.hiddenAt = Date.now();
1669
- this.persistSession();
1670
- } else if (doc2.visibilityState === "visible") {
1671
- const idleFor = Date.now() - this.session.lastActivityAt;
1672
- if (idleFor >= SESSION_RESUME_THRESHOLD_MS) {
1673
- this.pageviewId = null;
1674
- this.session = this.startNewSession();
1665
+ try {
1666
+ if (!this.session) return;
1667
+ const doc2 = globalThis.document;
1668
+ if (doc2.visibilityState === "hidden") {
1669
+ this.session.hiddenAt = Date.now();
1675
1670
  this.persistSession();
1676
- this.emitSessionStart();
1677
- } else {
1678
- this.session.hiddenAt = null;
1671
+ } else if (doc2.visibilityState === "visible") {
1672
+ const idleFor = Date.now() - this.session.lastActivityAt;
1673
+ if (idleFor >= SESSION_RESUME_THRESHOLD_MS) {
1674
+ this.pageviewId = null;
1675
+ this.session = this.startNewSession();
1676
+ this.persistSession();
1677
+ this.emitSessionStart();
1678
+ } else {
1679
+ this.session.hiddenAt = null;
1680
+ }
1679
1681
  }
1682
+ } catch {
1683
+ }
1684
+ };
1685
+ const onPageHide = () => {
1686
+ try {
1687
+ this.persistSession();
1688
+ } catch {
1680
1689
  }
1681
1690
  };
1682
- const onPageHide = () => this.persistSession();
1683
1691
  const w = globalThis.window;
1684
1692
  const doc = globalThis.document;
1685
1693
  doc.addEventListener("visibilitychange", onVisChange);
@@ -2543,17 +2551,20 @@ var WebVitalsTracker = class {
2543
2551
  } catch {
2544
2552
  }
2545
2553
  const flush = () => {
2546
- if (lcpValue > 0 && !this.flushed.has("lcp")) {
2547
- this.flushed.add("lcp");
2548
- this.report("webvitals.lcp", { valueMs: Math.round(lcpValue) });
2549
- }
2550
- if (this.cls > 0 && !this.flushed.has("cls")) {
2551
- this.flushed.add("cls");
2552
- this.report("webvitals.cls", { value: Math.round(this.cls * 1e3) / 1e3 });
2553
- }
2554
- if (this.inp > 0 && !this.flushed.has("inp")) {
2555
- this.flushed.add("inp");
2556
- this.report("webvitals.inp", { valueMs: Math.round(this.inp) });
2554
+ try {
2555
+ if (lcpValue > 0 && !this.flushed.has("lcp")) {
2556
+ this.flushed.add("lcp");
2557
+ this.report("webvitals.lcp", { valueMs: Math.round(lcpValue) });
2558
+ }
2559
+ if (this.cls > 0 && !this.flushed.has("cls")) {
2560
+ this.flushed.add("cls");
2561
+ this.report("webvitals.cls", { value: Math.round(this.cls * 1e3) / 1e3 });
2562
+ }
2563
+ if (this.inp > 0 && !this.flushed.has("inp")) {
2564
+ this.flushed.add("inp");
2565
+ this.report("webvitals.inp", { valueMs: Math.round(this.inp) });
2566
+ }
2567
+ } catch {
2557
2568
  }
2558
2569
  };
2559
2570
  const onHidden = () => {
@@ -3816,6 +3827,8 @@ function buildFrame(input) {
3816
3827
  function isInAppFrame(filename) {
3817
3828
  if (!filename) return true;
3818
3829
  if (/^(?:chrome|moz|safari|webkit)-extension:\/\//.test(filename)) return false;
3830
+ if (/^iabjs:\/\//.test(filename)) return false;
3831
+ if (/^(?:webview|inappbrowser):\/\//i.test(filename)) return false;
3819
3832
  if (/\bcdn\.jsdelivr\.net\b/.test(filename)) return false;
3820
3833
  if (/\bunpkg\.com\b/.test(filename)) return false;
3821
3834
  if (/\bgoogletagmanager\.com\b/.test(filename)) return false;
@@ -3824,7 +3837,18 @@ function isInAppFrame(filename) {
3824
3837
  if (/\/crossdeck\.umd\.min\.js$/.test(filename)) return false;
3825
3838
  return true;
3826
3839
  }
3840
+ var BROWSER_INJECTED_GLOBAL = /(__firefox__|__gCrWeb|zaloJSV2)/;
3841
+ function injectedGlobalName(message) {
3842
+ const m = BROWSER_INJECTED_GLOBAL.exec(message ?? "");
3843
+ return m ? m[1] : null;
3844
+ }
3845
+ function demoteVendorInjectedFrames(frames, message) {
3846
+ if (!injectedGlobalName(message)) return frames;
3847
+ return frames.map((f) => f.in_app ? { ...f, in_app: false } : f);
3848
+ }
3827
3849
  function fingerprintError(message, frames, location2) {
3850
+ const injected = injectedGlobalName(message);
3851
+ if (injected) return djb2Hex(`injected-global:${injected}`);
3828
3852
  const inAppFrames = frames.filter((f) => f.in_app).slice(0, 3);
3829
3853
  const parts = [
3830
3854
  (message || "").slice(0, 200),
@@ -4181,7 +4205,7 @@ var ErrorTracker = class {
4181
4205
  const payload = coerceErrorPayload(err);
4182
4206
  const message = (payload.message || event.message || "Unknown error").slice(0, 1024);
4183
4207
  const stack = err instanceof Error ? err.stack ?? null : null;
4184
- const frames = parseStack(stack);
4208
+ const frames = demoteVendorInjectedFrames(parseStack(stack), message);
4185
4209
  const errorType = payload.errorType ?? null;
4186
4210
  const context = payload.extras ? { ...this.opts.getContext(), __error_extras: payload.extras } : this.opts.getContext();
4187
4211
  return {
@@ -4213,7 +4237,7 @@ var ErrorTracker = class {
4213
4237
  const payload = coerceErrorPayload(err);
4214
4238
  const message = (payload.message || "Unknown error").slice(0, 1024);
4215
4239
  const stack = err instanceof Error ? err.stack ?? null : null;
4216
- const frames = parseStack(stack);
4240
+ const frames = demoteVendorInjectedFrames(parseStack(stack), message);
4217
4241
  const errorType = payload.errorType ?? null;
4218
4242
  const context = payload.extras ? { ...this.opts.getContext(), __error_extras: payload.extras } : this.opts.getContext();
4219
4243
  return {
@@ -4777,6 +4801,9 @@ var CrossdeckClient = class {
4777
4801
  if (opts.autoHeartbeat && !localDevMode) {
4778
4802
  void this.heartbeat().catch(() => void 0);
4779
4803
  }
4804
+ if (!localDevMode) {
4805
+ void this.captureCampaignArrival().catch(() => void 0);
4806
+ }
4780
4807
  if (options.disableContractAssertions !== true) {
4781
4808
  const debugDefault = defaultDebugModeFlag();
4782
4809
  this.verifierCtx = buildVerifierContext({
@@ -4874,6 +4901,32 @@ var CrossdeckClient = class {
4874
4901
  }
4875
4902
  this.init(options);
4876
4903
  }
4904
+ /**
4905
+ * Campaign-arrival connect. If the landing URL carries a Crossdeck tag
4906
+ * (`cd_ref`), post it to the arrival endpoint so the backend binds this
4907
+ * anonymous session to the tagged person and pulls their integration
4908
+ * record (deals, pipeline) onto their journey. Browser-only; fire-and-
4909
+ * forget (never throws); backend-idempotent so a re-fire is harmless.
4910
+ */
4911
+ async captureCampaignArrival() {
4912
+ const s = this.state;
4913
+ if (!s) return;
4914
+ const loc = globalThis.location;
4915
+ if (!loc || typeof loc.search !== "string" || loc.search.length === 0) return;
4916
+ let ref = null;
4917
+ try {
4918
+ ref = new URLSearchParams(loc.search).get("cd_ref");
4919
+ } catch {
4920
+ return;
4921
+ }
4922
+ if (!ref) return;
4923
+ try {
4924
+ await s.http.request("POST", "/integrations/hubspot/arrival", {
4925
+ body: { anonymousId: s.identity.anonymousId, ref }
4926
+ });
4927
+ } catch {
4928
+ }
4929
+ }
4877
4930
  /**
4878
4931
  * Link the anonymous device to a developer-supplied user ID. Cache
4879
4932
  * the resolved Crossdeck customer for follow-up calls.
@@ -5762,9 +5815,17 @@ function installUnloadFlush(onUnload) {
5762
5815
  const doc = globalThis.document;
5763
5816
  if (!w || !doc) return () => void 0;
5764
5817
  const onVisChange = () => {
5765
- if (doc.visibilityState === "hidden") onUnload();
5818
+ try {
5819
+ if (doc.visibilityState === "hidden") onUnload();
5820
+ } catch {
5821
+ }
5822
+ };
5823
+ const onTerminal = () => {
5824
+ try {
5825
+ onUnload();
5826
+ } catch {
5827
+ }
5766
5828
  };
5767
- const onTerminal = () => onUnload();
5768
5829
  doc.addEventListener("visibilitychange", onVisChange);
5769
5830
  w.addEventListener("pagehide", onTerminal);
5770
5831
  w.addEventListener("beforeunload", onTerminal);