@cross-deck/web 1.6.4 → 1.8.0

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,26 +2,43 @@
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.6.4] — 2026-06-01
6
-
7
- Patch contract-integrity fixes. Two issues found by adversarial testing of
8
- the shipped contracts against real wire traffic. No public API change.
9
-
10
- **`super-property-merge-precedence` — registered super-properties now win over
11
- auto-collected fields, as the contract claims.** The merge had an inverted
12
- guard (`if (!(k in enriched))`) so a device-seeded key (`os`, `locale`,
13
- `timezone`, …) silently clobbered a value set via `register()`. Effective order
14
- is now **caller > super > auto-collected**; caller properties still win.
15
-
16
- **Three contracts were stamped `runtimeVerified: true` but only had a boot-time
17
- self-test (off by default in production) now they run on real production
18
- hot-path hooks.** `flush-interval-parity` validates the live flush interval on
19
- every `track()`; `sdk-error-codes-catalogue` confirms each real wire error's
20
- code carries remediation on `onErrorParse`; `contract-failed-payload-schema-lock`
21
- schema-locks the actual outgoing telemetry on the emit path. The bundled-manifest
22
- generator now derives `runtimeVerified` from the presence of a hot-path hook
23
- (not merely a registered verifier), so the flag can no longer claim runtime
24
- enforcement a verifier doesn't deliver.
5
+ ## [1.8.0] — 2026-06-11
6
+
7
+ **PARK on version-rejection events are held, never dropped.** A third
8
+ event-queue outcome for the day the server stops accepting an outdated event
9
+ format. Purely additive; no public API change.
10
+
11
+ **Added:**
12
+
13
+ - **PARK (HTTP `426` / `sdk_version_unsupported`).** Previously a permanent 4xx
14
+ dropped the batch. Now a version-rejection is recognised as its own outcome —
15
+ distinct from retry (transient) and drop (invalid): the data is good, only the
16
+ wire dialect is stale. The queue **holds** the events (folded to the front of
17
+ the durable localStorage queue, FIFO-capped at 1000), **hushes** (stops
18
+ flushing a known-too-old payload no wasted battery/bandwidth), **signals**
19
+ once (one `console.warn` + a typed `sdk.parked` debug event the dashboard
20
+ reads), and **backfills** on the next page load after you upgrade. So "paused,
21
+ not lost held on-device, resumes on upgrade" is literally true.
22
+ - **`sdk_version_unsupported`** added to the error-codes catalogue with
23
+ remediation, and `version_error` to `CrossdeckErrorType`. `CrossdeckError`
24
+ now carries `minVersion` / `surface` (parsed from the 426 body) so the PARK
25
+ message names the exact version to update to.
26
+ - New `onParked` queue callback (host → dashboard heartbeat channel).
27
+ - Bundle-size budget: UMD min 33 → 35 KB gzipped (~0.5 KB for the PARK branch +
28
+ onParked + catalogue entry + minVersion/surface). core/react/vue unchanged,
29
+ under budget.
30
+
31
+ See https://cross-deck.com/docs/sdk-event-durability/ for the full durability
32
+ contract.
33
+
34
+ ## [1.7.0] — 2026-06-10
35
+
36
+ Event Envelope v1 conformance (`backend/docs/event-envelope-spec-v1.md`). Wire-breaking change (pre-launch; free). No public API change.
37
+
38
+ - **`envelopeVersion: 1`** (integer) added to every batch POST body (spec §1). Distinct from `sdk.version`; the server uses it to gate parsing and will refuse payloads without it once enforcement deploys.
39
+ - **`seq`** (number) on every event (spec §3). Per-session monotonic integer, assigned synchronously at `track()` time alongside `timestamp` (one sample). Counter lives in `AutoTracker`, resets to 0 at every session boundary (`session.started`, `resetSession()`, 30-min idle rollover), and persists across tab hide/show within a session. The deterministic tiebreak for events sharing a timestamp.
40
+ - **`context`** object on every event (spec §4). Device/platform facts (`os`, `osVersion`, `appVersion`, `sdkName`, `sdkVersion`, `locale`, `timezone`, `browser`, `browserVersion`) are promoted OUT of `properties` into a standardised top-level object. `properties` retains screen dimensions and all app-supplied properties. This aligns the Web SDK field-set with Swift (which ships `os`, `osVersion`, `sdkName`, `sdkVersion`, `locale`, `timezone`, `deviceModel`), closing the Q3 drift documented in the spec's Phase-0 audit matrix.
41
+ - Bundle-size budget: core ESM + CJS 58 → 60 KB gzipped (~0.5 KB for the envelope fields + browser/browserVersion detection; CJS landed at 58.26, over the old ceiling). react/vue ESM and UMD unchanged, comfortably under budget.
25
42
 
26
43
  ## [1.6.3] — 2026-06-01
27
44
 
@@ -45,38 +62,46 @@ regardless, so context is preserved on other errors.
45
62
 
46
63
  ## [1.6.2] — 2026-05-31
47
64
 
48
- Patch — session-boundary correctness. A stored session could span a gap
49
- longer than the 30-minute inactivity window in two cases the resume logic
50
- missed, fragmenting journey grouping. Both are now fixed. No public API
51
- change; `session.ended` emission timing changes as described, so read
52
- before upgrading if you have downstream logic keyed on it.
65
+ Session-boundary correctness, plus the per-platform contract runtime status
66
+ that had been sitting unreleased. No public API change; `session.ended`
67
+ emission timing changes as described, so read before upgrading if you key
68
+ downstream logic on it.
53
69
 
54
- **A tab left open and idle, then used again, no longer stretches one
55
- session across the gap.** `markActivity()` now rolls to a new session when
56
- an event lands after the 30-minute window has lapsed — covering the case
57
- the page-load and tab-return resume checks miss entirely (a tab kept open
58
- and idle, then interacted with, with no visibility transition). A single
59
- stored session can no longer contain a >30-minute gap.
70
+ **A tab left open and idle, then used again, no longer stretches one session
71
+ across the gap.** `markActivity()` now rolls to a new session when an event
72
+ lands after the 30-minute inactivity window has lapsed — covering the case the
73
+ page-load and tab-return resume checks miss entirely (a tab kept open and idle,
74
+ then interacted with, with no visibility transition). A single stored session
75
+ can no longer contain a >30-minute gap.
60
76
 
61
77
  **Returning to a long-idle tab no longer back-dates `session.ended`.** The
62
- visibility-resume path emitted `session.ended` at the moment of return —
63
- more than 30 minutes after the session's last real event — which itself
64
- opened an intra-session gap. The prior session now ends implicitly (its
65
- end inferred from its last event), consistent with the page-load resume
66
- path. If you key downstream logic on `session.ended`, note it no longer
67
- fires on a >30-minute tab-return.
68
-
69
- ## [1.6.1] 2026-05-30
70
-
71
- Minor two autocapture fidelity fixes, plus a repair to the release
72
- pipeline itself. (1.6.0 carried the same two fixes but never reached npm:
73
- its automated publish hit a pre-existing broken test gate a schema-lock
74
- test that loaded a contract via a monorepo-only path that doesn't exist
75
- in the published package. Fixed by reading the contract from the copy
76
- bundled into the SDK, so this is the first build of these changes to
77
- ship.) No public API change; event emission behaviour changes as
78
- described, so read before upgrading if you have downstream logic keyed on
79
- `session.ended` timing.
78
+ visibility-resume path emitted `session.ended` at the moment of return — more
79
+ than 30 minutes after the session's last real event — which itself opened an
80
+ intra-session gap. The prior session now ends implicitly (its end inferred from
81
+ its last event), consistent with the page-load resume path. If you key
82
+ downstream logic on `session.ended`, note it no longer fires on a >30-minute
83
+ tab-return.
84
+
85
+ **Per-platform contract runtime status + a 7th live verifier.** Each bundled
86
+
87
+ **Per-platform contract runtime status + a 7th live verifier.** Each bundled
88
+ contract now carries `runtimeVerified` whether *this* SDK self-verifies it
89
+ at runtime vs. proving it in CI only. It is derived at build time from the
90
+ SDK's `STATIC_VERIFIERS` registry (never hand-set), so the registry can't
91
+ disagree with what actually runs. `CrossdeckContracts` consumers can read it
92
+ to distinguish "watch it pass live" from "CI-proven every release".
93
+
94
+ - New runtime verifier `sdk-error-codes-catalogue` (boot self-test: every
95
+ backend wire code carries a description + resolution in the shipped
96
+ catalogue). Web now self-verifies **7** contracts live.
97
+ - Bundle-size budget: UMD min 32 → 33 KB (~0.4 KB gzipped for the flag + the
98
+ new verifier's frozen 15-code list). Other bundles unchanged, under budget.
99
+
100
+ ## [1.6.0] — 2026-05-30
101
+
102
+ Minor — two autocapture fidelity fixes. No public API change; event
103
+ emission behaviour changes as described, so read before upgrading if you
104
+ have downstream logic keyed on `session.ended` timing.
80
105
 
81
106
  **Sessions now survive full-page navigations.** Session state was
82
107
  in-memory only, so on a multi-page site (where the SDK re-installs on