@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/CHANGELOG.md CHANGED
@@ -2,6 +2,72 @@
2
2
 
3
3
  All notable changes to `@cross-deck/web` will be documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
 
5
+ ## [1.10.3] — 2026-07-22
6
+
7
+ **Fixed — browser-injected globals no longer blamed on your code.** A browser (not
8
+ your app) injects private globals into every page — `window.__firefox__` (Firefox
9
+ for iOS reader mode), `__gCrWeb` (Chrome for iOS), `zaloJSV2` (Zalo). Their content
10
+ script races page setup and throws in the page's own global scope, so the throwing
11
+ frame wears your URL (`https://you.app/x:1:19`, "global code") and looked like your
12
+ code. Now: when the message names one of these globals, every frame is marked
13
+ `in_app: false` (it's the browser's code, not yours), and the error is fingerprinted
14
+ by the injected global — so the whole class, across pages and both race shapes
15
+ (`.reader` vs `Can't find variable`), collapses into a single grouped, de-emphasised
16
+ issue instead of thousands of per-page reds. Same family as the `iabjs://` in-app
17
+ browser handling. No public API change.
18
+
19
+ ## [1.10.2] — 2026-07-22
20
+
21
+ **First published 1.10.x — same SDK, release pipeline fully green.** 1.10.0/1.10.1
22
+ were staged but blocked in CI before publish (1.10.0: `npm@latest` engine mismatch;
23
+ 1.10.1: the bundle-size budget, which the 1.10.x feature growth crossed by ~80 bytes
24
+ on core CJS). Both fixed (npm pinned to `npm@^11`; core budget raised 60 → 62 KB for
25
+ a ~2 KB margin). SDK contents are identical to 1.10.0 below — see that entry for the
26
+ campaign-arrival feature and the in-app-browser fixes.
27
+
28
+ ## [1.10.1] — 2026-07-22
29
+
30
+ **Republish of 1.10.0 — same SDK, working release pipeline.** The 1.10.0 tag never
31
+ reached npm: the release runner upgraded npm via `npm@latest`, which had rolled to
32
+ 12.x (Node ≥22) and hard-failed `EBADENGINE` on the Node 20 runner, before the
33
+ publish step. That's fixed (the workflow now pins `npm@^11`). This is the first
34
+ version to actually publish; the SDK contents are identical to 1.10.0 below —
35
+ see that entry for the campaign-arrival feature and the in-app-browser fixes.
36
+
37
+ ## [1.10.0] — 2026-07-22
38
+
39
+ **Added — campaign-arrival connect (the HubSpot identity bridge).** When a page is
40
+ reached from a Crossdeck-tagged campaign link, the landing URL carries an opaque
41
+ `cd_ref` tag (the partner contact id — **never an email**). On session start the
42
+ SDK posts `{ anonymousId, ref }` once to the arrival endpoint, so the backend binds
43
+ this anonymous session to the tagged person and pulls their integration record
44
+ (deals, pipeline) onto their journey — no login required. A later real login still
45
+ converges (the anon anchor leaves `developerUserId` free — never a blind email
46
+ merge). Browser-only, fire-and-forget (never throws, never blocks init), and
47
+ backend-idempotent so a re-fire is harmless. Automatic; no new public method.
48
+
49
+ **Fixed — don't manufacture noise from in-app browsers.** Instagram/Facebook's
50
+ Android in-app browser injects its own script (`iabjs://…`) into its WebView and,
51
+ during page teardown, its Java bridge is garbage-collected and throws
52
+ `Error invoking …: Java object is gone`. Two changes so the SDK never turns the
53
+ host shell's own teardown into the developer's error:
54
+
55
+ - **Unload handlers are now exception-safe.** The SDK's terminal-flush and
56
+ session-persist work fires on `pagehide` / `beforeunload` /
57
+ `visibilitychange→hidden` — exactly when the in-app browser hooks browser APIs
58
+ and throws from its own teardown. Every such handler (auto-track session
59
+ persist, web-vitals flush, the shared unload flush) now swallows a throw at the
60
+ handler boundary, so a host-shell teardown error can no longer propagate to
61
+ `window.onerror` and be self-reported. The page is going away; nothing there can
62
+ be meaningfully handled.
63
+ - **Injected in-app-browser frames are no longer marked `in_app`.** The stack
64
+ parser treats `iabjs://` / `webview://` / `inappbrowser://` frames as
65
+ third-party (like extension frames), so the dashboard's "your code vs library
66
+ code" view no longer attributes the in-app browser's errors to the developer.
67
+
68
+ No new or changed public methods (campaign-arrival is automatic; the iabjs work is
69
+ internal robustness).
70
+
5
71
  ## [1.9.1] — 2026-06-30
6
72
 
7
73
  **Docs — knowledge-backbone governance release.** No runtime API change. This
package/README.md CHANGED
@@ -97,6 +97,8 @@ Every event — auto-tracked and developer-emitted — is enriched with the devi
97
97
 
98
98
  **Per-session acquisition (v0.6.0+):** when a session starts the SDK reads `window.location.search` and `document.referrer` and captures `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, plus `referrer`. Non-empty values are auto-attached to every subsequent event of that session — first-touch attribution stays pinned to the entry URL even after SPA route changes strip the params away, and now stays pinned across full-page navigations within the session too. A new session (>30 min idle) re-reads the URL.
99
99
 
100
+ **Campaign-arrival connect (v1.10.0+):** when a page is reached from a Crossdeck-tagged campaign link, the landing URL carries an opaque `cd_ref` tag (a partner contact id — never an email). On session start the SDK posts it once to the arrival endpoint so the backend can bind this anonymous session to the tagged person and pull their integration record (e.g. HubSpot deals/pipeline) onto their journey — no login required. It's automatic (no method to call), browser-only, fire-and-forget (never throws, never blocks page init), and idempotent server-side. A later real `identify(userId)` still converges the same person.
101
+
100
102
  ## Auto-attached device info
101
103
 
102
104
  Every event's `properties` is enriched with whatever the SDK can detect:
@@ -254,7 +256,7 @@ Diagnostic snapshot — useful for development consoles and bug reports:
254
256
  anonymousId: "anon_…",
255
257
  crossdeckCustomerId: "cdcust_…" | null,
256
258
  developerUserId: "user_…" | null,
257
- sdkVersion: "1.9.0",
259
+ sdkVersion: "1.9.1",
258
260
  baseUrl: "https://api.cross-deck.com/v1",
259
261
  entitlements: { count: 2, lastUpdated: 1717891200000 },
260
262
  events: { buffered: 0, dropped: 0, inFlight: 0, lastFlushAt: 1717891200000, lastError: null },
@@ -276,8 +278,8 @@ CrossdeckContracts.byId("per-user-cache-isolation");
276
278
  CrossdeckContracts.byPillar("entitlements");
277
279
  CrossdeckContracts.withStatus("proposed");
278
280
  CrossdeckContracts.findByTestName("identify(B) makes A's entitlements unreachable from in-memory");
279
- CrossdeckContracts.sdkVersion; // "1.9.0"
280
- CrossdeckContracts.bundledIn; // "@cross-deck/web@1.9.0"
281
+ CrossdeckContracts.sdkVersion; // "1.9.1"
282
+ CrossdeckContracts.bundledIn; // "@cross-deck/web@1.9.1"
281
283
  ```
282
284
 
283
285
  The `Contract` type is exported alongside; the binary-stability promise (which fields are guaranteed across patch/minor releases) is documented inline on `src/contracts.ts` and in [`contracts/README.md`](https://github.com/VistaApps-za/crossdeck/blob/main/contracts/README.md).