@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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "generatedAt": "2026-06-30T08:40:38.162Z",
3
+ "generatedAt": "2026-07-22T12:36:32.783Z",
4
4
  "sdk": "@cross-deck/web",
5
5
  "codes": [
6
6
  {
package/dist/index.cjs CHANGED
@@ -104,7 +104,7 @@ function typeMapForStatus(status) {
104
104
  }
105
105
 
106
106
  // src/_version.ts
107
- var SDK_VERSION = "1.9.1";
107
+ var SDK_VERSION = "1.10.3";
108
108
  var SDK_NAME = "@cross-deck/web";
109
109
 
110
110
  // src/http.ts
@@ -1668,24 +1668,32 @@ var AutoTracker = class {
1668
1668
  this.emitSessionStart();
1669
1669
  }
1670
1670
  const onVisChange = () => {
1671
- if (!this.session) return;
1672
- const doc2 = globalThis.document;
1673
- if (doc2.visibilityState === "hidden") {
1674
- this.session.hiddenAt = Date.now();
1675
- this.persistSession();
1676
- } else if (doc2.visibilityState === "visible") {
1677
- const idleFor = Date.now() - this.session.lastActivityAt;
1678
- if (idleFor >= SESSION_RESUME_THRESHOLD_MS) {
1679
- this.pageviewId = null;
1680
- this.session = this.startNewSession();
1671
+ try {
1672
+ if (!this.session) return;
1673
+ const doc2 = globalThis.document;
1674
+ if (doc2.visibilityState === "hidden") {
1675
+ this.session.hiddenAt = Date.now();
1681
1676
  this.persistSession();
1682
- this.emitSessionStart();
1683
- } else {
1684
- this.session.hiddenAt = null;
1677
+ } else if (doc2.visibilityState === "visible") {
1678
+ const idleFor = Date.now() - this.session.lastActivityAt;
1679
+ if (idleFor >= SESSION_RESUME_THRESHOLD_MS) {
1680
+ this.pageviewId = null;
1681
+ this.session = this.startNewSession();
1682
+ this.persistSession();
1683
+ this.emitSessionStart();
1684
+ } else {
1685
+ this.session.hiddenAt = null;
1686
+ }
1685
1687
  }
1688
+ } catch {
1689
+ }
1690
+ };
1691
+ const onPageHide = () => {
1692
+ try {
1693
+ this.persistSession();
1694
+ } catch {
1686
1695
  }
1687
1696
  };
1688
- const onPageHide = () => this.persistSession();
1689
1697
  const w = globalThis.window;
1690
1698
  const doc = globalThis.document;
1691
1699
  doc.addEventListener("visibilitychange", onVisChange);
@@ -2549,17 +2557,20 @@ var WebVitalsTracker = class {
2549
2557
  } catch {
2550
2558
  }
2551
2559
  const flush = () => {
2552
- if (lcpValue > 0 && !this.flushed.has("lcp")) {
2553
- this.flushed.add("lcp");
2554
- this.report("webvitals.lcp", { valueMs: Math.round(lcpValue) });
2555
- }
2556
- if (this.cls > 0 && !this.flushed.has("cls")) {
2557
- this.flushed.add("cls");
2558
- this.report("webvitals.cls", { value: Math.round(this.cls * 1e3) / 1e3 });
2559
- }
2560
- if (this.inp > 0 && !this.flushed.has("inp")) {
2561
- this.flushed.add("inp");
2562
- this.report("webvitals.inp", { valueMs: Math.round(this.inp) });
2560
+ try {
2561
+ if (lcpValue > 0 && !this.flushed.has("lcp")) {
2562
+ this.flushed.add("lcp");
2563
+ this.report("webvitals.lcp", { valueMs: Math.round(lcpValue) });
2564
+ }
2565
+ if (this.cls > 0 && !this.flushed.has("cls")) {
2566
+ this.flushed.add("cls");
2567
+ this.report("webvitals.cls", { value: Math.round(this.cls * 1e3) / 1e3 });
2568
+ }
2569
+ if (this.inp > 0 && !this.flushed.has("inp")) {
2570
+ this.flushed.add("inp");
2571
+ this.report("webvitals.inp", { valueMs: Math.round(this.inp) });
2572
+ }
2573
+ } catch {
2563
2574
  }
2564
2575
  };
2565
2576
  const onHidden = () => {
@@ -3822,6 +3833,8 @@ function buildFrame(input) {
3822
3833
  function isInAppFrame(filename) {
3823
3834
  if (!filename) return true;
3824
3835
  if (/^(?:chrome|moz|safari|webkit)-extension:\/\//.test(filename)) return false;
3836
+ if (/^iabjs:\/\//.test(filename)) return false;
3837
+ if (/^(?:webview|inappbrowser):\/\//i.test(filename)) return false;
3825
3838
  if (/\bcdn\.jsdelivr\.net\b/.test(filename)) return false;
3826
3839
  if (/\bunpkg\.com\b/.test(filename)) return false;
3827
3840
  if (/\bgoogletagmanager\.com\b/.test(filename)) return false;
@@ -3830,7 +3843,18 @@ function isInAppFrame(filename) {
3830
3843
  if (/\/crossdeck\.umd\.min\.js$/.test(filename)) return false;
3831
3844
  return true;
3832
3845
  }
3846
+ var BROWSER_INJECTED_GLOBAL = /(__firefox__|__gCrWeb|zaloJSV2)/;
3847
+ function injectedGlobalName(message) {
3848
+ const m = BROWSER_INJECTED_GLOBAL.exec(message ?? "");
3849
+ return m ? m[1] : null;
3850
+ }
3851
+ function demoteVendorInjectedFrames(frames, message) {
3852
+ if (!injectedGlobalName(message)) return frames;
3853
+ return frames.map((f) => f.in_app ? { ...f, in_app: false } : f);
3854
+ }
3833
3855
  function fingerprintError(message, frames, location2) {
3856
+ const injected = injectedGlobalName(message);
3857
+ if (injected) return djb2Hex(`injected-global:${injected}`);
3834
3858
  const inAppFrames = frames.filter((f) => f.in_app).slice(0, 3);
3835
3859
  const parts = [
3836
3860
  (message || "").slice(0, 200),
@@ -4187,7 +4211,7 @@ var ErrorTracker = class {
4187
4211
  const payload = coerceErrorPayload(err);
4188
4212
  const message = (payload.message || event.message || "Unknown error").slice(0, 1024);
4189
4213
  const stack = err instanceof Error ? err.stack ?? null : null;
4190
- const frames = parseStack(stack);
4214
+ const frames = demoteVendorInjectedFrames(parseStack(stack), message);
4191
4215
  const errorType = payload.errorType ?? null;
4192
4216
  const context = payload.extras ? { ...this.opts.getContext(), __error_extras: payload.extras } : this.opts.getContext();
4193
4217
  return {
@@ -4219,7 +4243,7 @@ var ErrorTracker = class {
4219
4243
  const payload = coerceErrorPayload(err);
4220
4244
  const message = (payload.message || "Unknown error").slice(0, 1024);
4221
4245
  const stack = err instanceof Error ? err.stack ?? null : null;
4222
- const frames = parseStack(stack);
4246
+ const frames = demoteVendorInjectedFrames(parseStack(stack), message);
4223
4247
  const errorType = payload.errorType ?? null;
4224
4248
  const context = payload.extras ? { ...this.opts.getContext(), __error_extras: payload.extras } : this.opts.getContext();
4225
4249
  return {
@@ -4783,6 +4807,9 @@ var CrossdeckClient = class {
4783
4807
  if (opts.autoHeartbeat && !localDevMode) {
4784
4808
  void this.heartbeat().catch(() => void 0);
4785
4809
  }
4810
+ if (!localDevMode) {
4811
+ void this.captureCampaignArrival().catch(() => void 0);
4812
+ }
4786
4813
  if (options.disableContractAssertions !== true) {
4787
4814
  const debugDefault = defaultDebugModeFlag();
4788
4815
  this.verifierCtx = buildVerifierContext({
@@ -4880,6 +4907,32 @@ var CrossdeckClient = class {
4880
4907
  }
4881
4908
  this.init(options);
4882
4909
  }
4910
+ /**
4911
+ * Campaign-arrival connect. If the landing URL carries a Crossdeck tag
4912
+ * (`cd_ref`), post it to the arrival endpoint so the backend binds this
4913
+ * anonymous session to the tagged person and pulls their integration
4914
+ * record (deals, pipeline) onto their journey. Browser-only; fire-and-
4915
+ * forget (never throws); backend-idempotent so a re-fire is harmless.
4916
+ */
4917
+ async captureCampaignArrival() {
4918
+ const s = this.state;
4919
+ if (!s) return;
4920
+ const loc = globalThis.location;
4921
+ if (!loc || typeof loc.search !== "string" || loc.search.length === 0) return;
4922
+ let ref = null;
4923
+ try {
4924
+ ref = new URLSearchParams(loc.search).get("cd_ref");
4925
+ } catch {
4926
+ return;
4927
+ }
4928
+ if (!ref) return;
4929
+ try {
4930
+ await s.http.request("POST", "/integrations/hubspot/arrival", {
4931
+ body: { anonymousId: s.identity.anonymousId, ref }
4932
+ });
4933
+ } catch {
4934
+ }
4935
+ }
4883
4936
  /**
4884
4937
  * Link the anonymous device to a developer-supplied user ID. Cache
4885
4938
  * the resolved Crossdeck customer for follow-up calls.
@@ -5768,9 +5821,17 @@ function installUnloadFlush(onUnload) {
5768
5821
  const doc = globalThis.document;
5769
5822
  if (!w || !doc) return () => void 0;
5770
5823
  const onVisChange = () => {
5771
- if (doc.visibilityState === "hidden") onUnload();
5824
+ try {
5825
+ if (doc.visibilityState === "hidden") onUnload();
5826
+ } catch {
5827
+ }
5828
+ };
5829
+ const onTerminal = () => {
5830
+ try {
5831
+ onUnload();
5832
+ } catch {
5833
+ }
5772
5834
  };
5773
- const onTerminal = () => onUnload();
5774
5835
  doc.addEventListener("visibilitychange", onVisChange);
5775
5836
  w.addEventListener("pagehide", onTerminal);
5776
5837
  w.addEventListener("beforeunload", onTerminal);