@cross-deck/web 0.1.1 → 0.3.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 +35 -0
- package/README.md +70 -16
- package/dist/index.d.mts +145 -12
- package/dist/index.d.ts +145 -12
- package/dist/index.js +479 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +479 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
## [0.3.0] — 2026-05-08
|
|
6
|
+
|
|
7
|
+
This release reconciles the web SDK with the Crossdeck SDK NorthStar Addendum (§4 Shared Contract, §11.1 Web SDK pattern, §13.1 wire envelope, §15 sensitive properties, §16 debug signal vocabulary). The public surface now matches what the iOS, Android, and Node SDKs will expose — `init`, `flush`, `syncPurchases`, `setDebugMode`.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`Crossdeck.init({ appId, publicKey, environment })`** — canonical lifecycle method per NorthStar §4. The trio is required and validated up-front: a publishable-key prefix that disagrees with the declared `environment` throws `CrossdeckError({ code: "environment_mismatch" })` at boot, so a typo can't silently route prod data into sandbox dashboards.
|
|
12
|
+
- **`Crossdeck.flush()`** — alias of the old `flushEvents()`, matching the standardised name.
|
|
13
|
+
- **`Crossdeck.syncPurchases(input)`** — replaces `purchaseApple`. Posts to `/v1/purchases/sync` and accepts an optional `rail` field for future Stripe/Google support.
|
|
14
|
+
- **`Crossdeck.setDebugMode(enabled)`** + `debug` init option — toggle the §16 debug signal vocabulary (`sdk.configured`, `sdk.first_event_sent`, `sdk.no_identity`, `sdk.purchase_evidence_sent`, `sdk.environment_mismatch`, `sdk.sensitive_property_warning`).
|
|
15
|
+
- **Sensitive-property warnings** — when debug mode is on, `track()` warns once per call if any property key matches `email|password|token|secret|card|phone` (NorthStar §15). The event is still sent unmodified; the warning surfaces accidental PII in the dashboard onboarding feed.
|
|
16
|
+
- **NorthStar §13.1 wire envelope** — every `/v1/events` POST now includes `appId`, `environment`, and `sdk: { name, version }` at the batch level. The backend validates these against the API-key-resolved app and rejects mismatches with `permission_error / env_mismatch`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- `Crossdeck.start()` is now a deprecated alias of `init()` and emits a `console.warn` once per call. The signature is unchanged, but the new `appId` and `environment` options are still required even when calling `start`.
|
|
21
|
+
- `Crossdeck.purchaseApple()` is now a deprecated alias of `syncPurchases({ rail: "apple", ... })`. The new method posts to `/v1/purchases/sync`; the legacy `/v1/purchases` route is kept on the backend for v0.2.x callers.
|
|
22
|
+
- The `not_started` configuration error code is now `not_initialized` to match the rename.
|
|
23
|
+
|
|
24
|
+
### Removed
|
|
25
|
+
|
|
26
|
+
Nothing. v0.3.0 is fully source-compatible with v0.2.x callers — the legacy method names log a deprecation but continue to work. Plan to drop them in v0.5.0.
|
|
27
|
+
|
|
28
|
+
## [0.2.0] — 2026-05-06
|
|
29
|
+
|
|
30
|
+
- Added auto-tracking: sessions, page views, and device-info enrichment are on by default in browsers. See `autoTrack` config to disable individually or wholesale.
|
|
31
|
+
- Stable `Diagnostics` shape regardless of whether `start()` has been called — pre-start values are sensible empties.
|
|
32
|
+
|
|
33
|
+
## [0.1.0] — 2026-05-05
|
|
34
|
+
|
|
35
|
+
Initial public release.
|
package/README.md
CHANGED
|
@@ -12,7 +12,11 @@ npm install @cross-deck/web
|
|
|
12
12
|
import { Crossdeck } from "@cross-deck/web";
|
|
13
13
|
|
|
14
14
|
// 1. Boot once at app start
|
|
15
|
-
Crossdeck.
|
|
15
|
+
Crossdeck.init({
|
|
16
|
+
appId: "app_web_xxx", // from the Crossdeck dashboard
|
|
17
|
+
publicKey: "cd_pub_live_…", // publishable key, safe in client code
|
|
18
|
+
environment: "production", // "production" or "sandbox"
|
|
19
|
+
});
|
|
16
20
|
|
|
17
21
|
// 2. After the user logs in, link the device to your user ID
|
|
18
22
|
await Crossdeck.identify("user_847");
|
|
@@ -33,29 +37,71 @@ That's the full happy path.
|
|
|
33
37
|
|
|
34
38
|
## What it does
|
|
35
39
|
|
|
40
|
+
- **Auto-tracking, on by default.** Sessions, page views, and device info (OS, browser, locale, timezone, screen size, app version) ship from boot. No instrumentation needed for the basics. Disable any of them via `autoTrack: { sessions: false }` etc.
|
|
36
41
|
- **One identity for every device + user.** Pre-login events get an `anonymousId`. After login, `identify()` links them to your user ID through Crossdeck's identity graph. The SDK persists both so subsequent app launches resume where you left off.
|
|
37
42
|
- **Synchronous entitlement reads.** `getEntitlements()` populates a local cache. `isEntitled("pro")` is a Set lookup — no network call, no waiting.
|
|
38
43
|
- **Batched telemetry.** `track()` queues events in memory; the SDK flushes every 5 seconds (configurable) or when the buffer hits 20 events. Network failures re-queue the batch — events aren't lost on a flaky connection.
|
|
39
|
-
- **Boot heartbeat.** On `
|
|
44
|
+
- **Boot heartbeat.** On `init()` the SDK pings `/v1/sdk/heartbeat` so the dashboard's Apps page can show you "last seen" per install. Disable with `autoHeartbeat: false`.
|
|
40
45
|
- **Stripe-style errors.** Every async method throws `CrossdeckError` with `type`, `code`, `requestId`, and `status` — same shape as Stripe's SDKs, so generic error handlers transfer.
|
|
41
46
|
|
|
47
|
+
## Auto-tracked events
|
|
48
|
+
|
|
49
|
+
| Event | When |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `session.started` | On boot. Carries `sessionId`. |
|
|
52
|
+
| `session.ended` | On `pagehide` / `beforeunload`, OR when returning to a tab after >30 min idle. Carries `sessionId` and `durationMs`. |
|
|
53
|
+
| `page.viewed` | On initial load + every SPA navigation (`history.pushState`, `replaceState`, `popstate`). Carries `path`, `url`, `search`, `hash`, `title`, `referrer`. |
|
|
54
|
+
|
|
55
|
+
Every event — auto-tracked and developer-emitted — is enriched with the device-info payload below. Quick tab switches (Cmd-Tab, switching browser tabs) don't end the session — only real closes do, matching GA4's session-window convention.
|
|
56
|
+
|
|
57
|
+
## Auto-attached device info
|
|
58
|
+
|
|
59
|
+
Every event's `properties` is enriched with whatever the SDK can detect:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
{
|
|
63
|
+
os: "macOS" | "iOS" | "Android" | "Windows" | "Linux",
|
|
64
|
+
osVersion: "14.4",
|
|
65
|
+
browser: "Safari" | "Chrome" | "Firefox" | "Edge" | "Opera",
|
|
66
|
+
browserVersion: "17.5",
|
|
67
|
+
locale: "en-US",
|
|
68
|
+
timezone: "Africa/Johannesburg",
|
|
69
|
+
screenWidth: 2560,
|
|
70
|
+
screenHeight: 1440,
|
|
71
|
+
viewportWidth: 1440,
|
|
72
|
+
viewportHeight: 900,
|
|
73
|
+
devicePixelRatio: 2,
|
|
74
|
+
appVersion: "1.2.3", // only when you set Crossdeck.start({ appVersion })
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
No fingerprinting, no IP collection on the event document, no canvas hashing. Privacy by default. Caller-supplied properties always override auto-detected ones, so you can override `appVersion` per event if you A/B builds.
|
|
79
|
+
|
|
42
80
|
## API
|
|
43
81
|
|
|
44
|
-
### `Crossdeck.
|
|
82
|
+
### `Crossdeck.init(options)`
|
|
45
83
|
|
|
46
|
-
Boot the client. Idempotent — calling twice with the same options is fine.
|
|
84
|
+
Boot the client. Idempotent — calling twice with the same options is fine. (`Crossdeck.start()` is kept as a deprecated alias for v0.2.x callers.)
|
|
47
85
|
|
|
48
86
|
```ts
|
|
49
|
-
Crossdeck.
|
|
87
|
+
Crossdeck.init({
|
|
88
|
+
appId: "app_web_xxx", // required — from the dashboard
|
|
50
89
|
publicKey: "cd_pub_live_…", // required
|
|
90
|
+
environment: "production", // required — "production" | "sandbox"
|
|
51
91
|
baseUrl: "https://api.cross-deck.com/v1", // override for self-host or emulator
|
|
92
|
+
appVersion: "1.2.3", // attached to every event as properties.appVersion
|
|
93
|
+
autoTrack: true, // default — sessions, page views, device info
|
|
94
|
+
// …or granular: autoTrack: { sessions: false } keeps page views + device info
|
|
52
95
|
autoHeartbeat: true, // default; set false for high-frequency boots
|
|
53
96
|
eventFlushBatchSize: 20, // default
|
|
54
97
|
eventFlushIntervalMs: 5_000, // default
|
|
55
98
|
storage: customStorage, // override the persistence adapter
|
|
99
|
+
debug: false, // verbose §16 debug signals when true
|
|
56
100
|
});
|
|
57
101
|
```
|
|
58
102
|
|
|
103
|
+
Crossdeck checks the key prefix matches `environment`: `cd_pub_test_…` must declare `"sandbox"`, `cd_pub_live_…` must declare `"production"`. Mismatches throw `CrossdeckError({ code: "environment_mismatch" })` at init time so a typo can't silently route prod telemetry into sandbox dashboards.
|
|
104
|
+
|
|
59
105
|
The publishable key is safe to ship in client code. Crossdeck enforces origin allowlists (web), bundle-ID binding (mobile), and rate limits at the edge — see [docs/api-keys](https://cross-deck.com/docs/api-keys/) for the full security model.
|
|
60
106
|
|
|
61
107
|
### `await Crossdeck.identify(userId, options?)`
|
|
@@ -92,24 +138,26 @@ Synchronous read from the local cache. Returns `false` until you've called `getE
|
|
|
92
138
|
|
|
93
139
|
### `Crossdeck.track(name, properties?)`
|
|
94
140
|
|
|
95
|
-
Queue a telemetry event. Returns immediately. Events flush in batches; force a flush with `
|
|
141
|
+
Queue a telemetry event. Returns immediately. Events flush in batches; force a flush with `flush()`:
|
|
96
142
|
|
|
97
143
|
```ts
|
|
98
144
|
Crossdeck.track("checkout_started", { product: "annual_pro" });
|
|
99
145
|
// …later, e.g. before page unload:
|
|
100
146
|
window.addEventListener("beforeunload", () => {
|
|
101
|
-
void Crossdeck.
|
|
147
|
+
void Crossdeck.flush();
|
|
102
148
|
});
|
|
103
149
|
```
|
|
104
150
|
|
|
105
151
|
Event names match `[A-Za-z0-9_.\-:]+`, max 128 chars. Properties are JSON-serialisable, max 8 KB per event after JSON encoding.
|
|
106
152
|
|
|
107
|
-
|
|
153
|
+
In `debug: true` mode the SDK warns (one signal per call) when property keys look like PII — `email`, `password`, `token`, `secret`, `card`, `phone`. Crossdeck never strips fields automatically; the warning is so accidental leaks surface during development, not in prod logs.
|
|
154
|
+
|
|
155
|
+
### `await Crossdeck.syncPurchases(input)`
|
|
108
156
|
|
|
109
|
-
Forward
|
|
157
|
+
Forward purchase evidence (Apple StoreKit 2) directly to Crossdeck for verification — closes the purchase-to-entitled latency from seconds to milliseconds (faster than waiting for the App Store webhook). (`purchaseApple()` is kept as a deprecated alias.)
|
|
110
158
|
|
|
111
159
|
```ts
|
|
112
|
-
await Crossdeck.
|
|
160
|
+
await Crossdeck.syncPurchases({
|
|
113
161
|
signedTransactionInfo: transaction.jsonRepresentation, // from StoreKit 2
|
|
114
162
|
signedRenewalInfo: subscription.signedRenewalInfo, // optional
|
|
115
163
|
appAccountToken: "uuid-…", // optional
|
|
@@ -120,15 +168,19 @@ Stripe and Google purchases are verified via webhooks (Stripe Connect platform e
|
|
|
120
168
|
|
|
121
169
|
### `await Crossdeck.heartbeat()`
|
|
122
170
|
|
|
123
|
-
Manually send a heartbeat. Called automatically by `
|
|
171
|
+
Manually send a heartbeat. Called automatically by `init()` unless `autoHeartbeat: false`. Returns the readiness summary the dashboard uses to display SDK installation status.
|
|
124
172
|
|
|
125
173
|
### `Crossdeck.reset()`
|
|
126
174
|
|
|
127
175
|
Wipe persisted identity + entitlement cache + queued events. Call on logout. The next session generates a fresh `anonymousId` and starts a clean identity-graph entry.
|
|
128
176
|
|
|
129
|
-
### `Crossdeck.
|
|
177
|
+
### `Crossdeck.flush()`
|
|
178
|
+
|
|
179
|
+
Force-flush the in-memory event queue. Useful before page unload or when shutting down a script. (`flushEvents()` is kept as a deprecated alias.)
|
|
180
|
+
|
|
181
|
+
### `Crossdeck.setDebugMode(enabled)`
|
|
130
182
|
|
|
131
|
-
|
|
183
|
+
Toggle the verbose debug-signal vocabulary at runtime (NorthStar §16). When enabled, the SDK emits a fixed set of `console.info` lines tagged `[crossdeck:sdk.<signal>]` for `sdk.configured`, `sdk.first_event_sent`, `sdk.no_identity`, `sdk.purchase_evidence_sent`, `sdk.environment_mismatch`, and `sdk.sensitive_property_warning`.
|
|
132
184
|
|
|
133
185
|
### `Crossdeck.diagnostics()`
|
|
134
186
|
|
|
@@ -149,7 +201,7 @@ Diagnostic snapshot — useful for development consoles and bug reports:
|
|
|
149
201
|
|
|
150
202
|
## Errors
|
|
151
203
|
|
|
152
|
-
Every async method can throw `CrossdeckError`. Synchronous methods throw on configuration mistakes (calling before `
|
|
204
|
+
Every async method can throw `CrossdeckError`. Synchronous methods throw on configuration mistakes (calling before `init()`, invalid key prefix, env mismatch).
|
|
153
205
|
|
|
154
206
|
```ts
|
|
155
207
|
import { CrossdeckError } from "@cross-deck/web";
|
|
@@ -183,9 +235,11 @@ The SDK works the same way in Node 18+:
|
|
|
183
235
|
```ts
|
|
184
236
|
import { Crossdeck, MemoryStorage } from "@cross-deck/web";
|
|
185
237
|
|
|
186
|
-
Crossdeck.
|
|
238
|
+
Crossdeck.init({
|
|
239
|
+
appId: process.env.CROSSDECK_APP_ID!,
|
|
187
240
|
publicKey: process.env.CROSSDECK_PUBLIC_KEY!,
|
|
188
|
-
|
|
241
|
+
environment: "sandbox", // or "production"
|
|
242
|
+
storage: new MemoryStorage(), // session-only, no localStorage
|
|
189
243
|
autoHeartbeat: false, // skip the boot ping in scripts
|
|
190
244
|
});
|
|
191
245
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -53,12 +53,36 @@ interface HeartbeatResponse {
|
|
|
53
53
|
serverTime: number;
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
|
-
* Configuration for Crossdeck.
|
|
57
|
-
*
|
|
56
|
+
* Configuration for Crossdeck.init. Three fields are mandatory —
|
|
57
|
+
* `appId`, `publicKey`, and `environment` — per NorthStar §11.1.
|
|
58
|
+
*
|
|
59
|
+
* The pair of (appId, environment) is what we put on the wire envelope
|
|
60
|
+
* (NorthStar §13.1) so the backend can correlate events against the
|
|
61
|
+
* specific app surface and refuse mismatched env declarations loudly.
|
|
58
62
|
*/
|
|
59
63
|
interface CrossdeckOptions {
|
|
64
|
+
/**
|
|
65
|
+
* Your Crossdeck App ID (e.g. "app_web_xxx"). Required.
|
|
66
|
+
*
|
|
67
|
+
* Issued in the dashboard when you create an app. Goes on the wire
|
|
68
|
+
* envelope so the backend correlates events with the specific app
|
|
69
|
+
* surface — useful when one project has multiple apps (web + iOS +
|
|
70
|
+
* Android) sharing the same publishable key family.
|
|
71
|
+
*/
|
|
72
|
+
appId: string;
|
|
60
73
|
/** Your Crossdeck publishable key (cd_pub_…). Required. */
|
|
61
74
|
publicKey: string;
|
|
75
|
+
/**
|
|
76
|
+
* Explicit environment declaration. Required.
|
|
77
|
+
*
|
|
78
|
+
* Must match the publishable key's prefix:
|
|
79
|
+
* cd_pub_test_… → "sandbox"
|
|
80
|
+
* cd_pub_live_… → "production"
|
|
81
|
+
*
|
|
82
|
+
* Mismatch is rejected at init time so a typo'd key can't silently
|
|
83
|
+
* route prod telemetry into sandbox dashboards.
|
|
84
|
+
*/
|
|
85
|
+
environment: Environment;
|
|
62
86
|
/**
|
|
63
87
|
* Override the API base URL. Default is https://api.cross-deck.com/v1.
|
|
64
88
|
* Useful for self-hosted setups or pointing at the local emulator
|
|
@@ -90,6 +114,40 @@ interface CrossdeckOptions {
|
|
|
90
114
|
eventFlushIntervalMs?: number;
|
|
91
115
|
/** Override the SDK version reported on heartbeats. Default: package version. */
|
|
92
116
|
sdkVersion?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Auto-tracking. Default: every flag is `true` in browsers, all
|
|
119
|
+
* silently no-op in Node.
|
|
120
|
+
*
|
|
121
|
+
* Pass `false` to disable everything, or a partial object to override
|
|
122
|
+
* individual flags:
|
|
123
|
+
*
|
|
124
|
+
* Crossdeck.start({
|
|
125
|
+
* publicKey: "...",
|
|
126
|
+
* autoTrack: { pageViews: false }, // sessions + deviceInfo still on
|
|
127
|
+
* });
|
|
128
|
+
*/
|
|
129
|
+
autoTrack?: boolean | Partial<AutoTrackOptions>;
|
|
130
|
+
/**
|
|
131
|
+
* Your app's version (e.g. "1.2.3"). Auto-attached to every event as
|
|
132
|
+
* `properties.appVersion` when `autoTrack.deviceInfo` is enabled.
|
|
133
|
+
* Useful for slicing dashboards by build.
|
|
134
|
+
*/
|
|
135
|
+
appVersion?: string;
|
|
136
|
+
/**
|
|
137
|
+
* Enable verbose diagnostic logging via the NorthStar §16 debug-signal
|
|
138
|
+
* vocabulary. Default: false. Equivalent to calling
|
|
139
|
+
* `Crossdeck.setDebugMode(true)` after init.
|
|
140
|
+
*/
|
|
141
|
+
debug?: boolean;
|
|
142
|
+
}
|
|
143
|
+
/** Auto-tracking flags. See CrossdeckOptions.autoTrack. */
|
|
144
|
+
interface AutoTrackOptions {
|
|
145
|
+
/** Emit `session.started` / `session.ended` automatically. Default true (browser only). */
|
|
146
|
+
sessions: boolean;
|
|
147
|
+
/** Emit `page.viewed` on initial load + SPA navigation. Default true (browser only). */
|
|
148
|
+
pageViews: boolean;
|
|
149
|
+
/** Auto-attach os/browser/locale/screen/etc to every event's `properties`. Default true (browser only). */
|
|
150
|
+
deviceInfo: boolean;
|
|
93
151
|
}
|
|
94
152
|
/** Minimal interface for any pluggable key-value persistence. */
|
|
95
153
|
interface KeyValueStorage {
|
|
@@ -137,7 +195,11 @@ interface Diagnostics {
|
|
|
137
195
|
*
|
|
138
196
|
* import { Crossdeck } from "@cross-deck/web";
|
|
139
197
|
*
|
|
140
|
-
* Crossdeck.
|
|
198
|
+
* Crossdeck.init({
|
|
199
|
+
* appId: "app_web_xxx",
|
|
200
|
+
* publicKey: "cd_pub_live_…",
|
|
201
|
+
* environment: "production",
|
|
202
|
+
* });
|
|
141
203
|
*
|
|
142
204
|
* await Crossdeck.identify("user_847");
|
|
143
205
|
* const ents = await Crossdeck.getEntitlements();
|
|
@@ -149,11 +211,12 @@ interface Diagnostics {
|
|
|
149
211
|
*
|
|
150
212
|
* Usage (Node):
|
|
151
213
|
*
|
|
152
|
-
* import { Crossdeck } from "@cross-deck/web";
|
|
153
|
-
* import { MemoryStorage } from "@cross-deck/web";
|
|
214
|
+
* import { Crossdeck, MemoryStorage } from "@cross-deck/web";
|
|
154
215
|
*
|
|
155
|
-
* Crossdeck.
|
|
216
|
+
* Crossdeck.init({
|
|
217
|
+
* appId: "app_node_xxx",
|
|
156
218
|
* publicKey: "cd_pub_test_…",
|
|
219
|
+
* environment: "sandbox",
|
|
157
220
|
* storage: new MemoryStorage(), // session-only persistence
|
|
158
221
|
* autoHeartbeat: false, // skip the boot ping in scripts
|
|
159
222
|
* });
|
|
@@ -162,9 +225,19 @@ interface Diagnostics {
|
|
|
162
225
|
declare class CrossdeckClient {
|
|
163
226
|
private state;
|
|
164
227
|
/**
|
|
165
|
-
* Boot the SDK. Idempotent — calling
|
|
228
|
+
* Boot the SDK. Idempotent — calling init twice with the same options
|
|
166
229
|
* is a no-op; calling with different options replaces the previous
|
|
167
230
|
* configuration.
|
|
231
|
+
*
|
|
232
|
+
* NorthStar §11.1: signature is `Crossdeck.init({ appId, publicKey,
|
|
233
|
+
* environment })`. The trio is validated up-front so a typo'd key or a
|
|
234
|
+
* mismatched env fails fast at boot rather than at first event-flush.
|
|
235
|
+
*/
|
|
236
|
+
init(options: CrossdeckOptions): void;
|
|
237
|
+
/**
|
|
238
|
+
* @deprecated Use `init()` instead. NorthStar §4 standardised the
|
|
239
|
+
* lifecycle method name across SDKs as `init` (formerly `start` /
|
|
240
|
+
* `configure`). `start` will be removed in a future major version.
|
|
168
241
|
*/
|
|
169
242
|
start(options: CrossdeckOptions): void;
|
|
170
243
|
/**
|
|
@@ -188,17 +261,43 @@ declare class CrossdeckClient {
|
|
|
188
261
|
/**
|
|
189
262
|
* Queue a telemetry event. Returns immediately — the network round-
|
|
190
263
|
* trip happens in the background. To flush before the page unloads,
|
|
191
|
-
* call
|
|
264
|
+
* call flush().
|
|
192
265
|
*/
|
|
193
266
|
track(name: string, properties?: EventProperties): void;
|
|
194
|
-
/**
|
|
267
|
+
/**
|
|
268
|
+
* Force-flush queued events. Useful to call from page-unload handlers.
|
|
269
|
+
*
|
|
270
|
+
* NorthStar §4: standard method name across all Crossdeck SDKs.
|
|
271
|
+
*/
|
|
272
|
+
flush(): Promise<void>;
|
|
273
|
+
/** @deprecated Use `flush()` instead. NorthStar §4 standardised the name. */
|
|
195
274
|
flushEvents(): Promise<void>;
|
|
196
|
-
/**
|
|
275
|
+
/**
|
|
276
|
+
* Forward purchase evidence to the backend for verification + entitlement
|
|
277
|
+
* projection. NorthStar §4 + §13 canonical name.
|
|
278
|
+
*
|
|
279
|
+
* Today the web SDK only supports Apple StoreKit 2 forwarding (web apps
|
|
280
|
+
* that sit alongside an iOS app). Stripe doesn't need this method —
|
|
281
|
+
* Stripe webhooks deliver evidence server-side without a client round-trip.
|
|
282
|
+
*/
|
|
283
|
+
syncPurchases(input: {
|
|
284
|
+
rail?: "apple";
|
|
285
|
+
signedTransactionInfo: string;
|
|
286
|
+
signedRenewalInfo?: string;
|
|
287
|
+
appAccountToken?: string;
|
|
288
|
+
}): Promise<PurchaseResult>;
|
|
289
|
+
/** @deprecated Use `syncPurchases()` instead. NorthStar §4 standardised the name. */
|
|
197
290
|
purchaseApple(input: {
|
|
198
291
|
signedTransactionInfo: string;
|
|
199
292
|
signedRenewalInfo?: string;
|
|
200
293
|
appAccountToken?: string;
|
|
201
294
|
}): Promise<PurchaseResult>;
|
|
295
|
+
/**
|
|
296
|
+
* Toggle verbose diagnostic logging — NorthStar §16. When enabled, the
|
|
297
|
+
* SDK emits a fixed vocabulary of debug signals to console.info that the
|
|
298
|
+
* dashboard's onboarding checklist can also surface as live events.
|
|
299
|
+
*/
|
|
300
|
+
setDebugMode(enabled: boolean): void;
|
|
202
301
|
/**
|
|
203
302
|
* Send the boot heartbeat. Called automatically by start() unless
|
|
204
303
|
* autoHeartbeat:false. Safe to call manually as a "we're still here" ping.
|
|
@@ -300,7 +399,41 @@ declare class MemoryStorage implements KeyValueStorage {
|
|
|
300
399
|
* fetch shim, no transitive deps.
|
|
301
400
|
*/
|
|
302
401
|
declare const SDK_NAME = "@cross-deck/web";
|
|
303
|
-
declare const SDK_VERSION = "0.
|
|
402
|
+
declare const SDK_VERSION = "0.3.0";
|
|
304
403
|
declare const DEFAULT_BASE_URL = "https://api.cross-deck.com/v1";
|
|
305
404
|
|
|
306
|
-
|
|
405
|
+
/**
|
|
406
|
+
* Device + environment enrichment.
|
|
407
|
+
*
|
|
408
|
+
* Auto-attached to every event the SDK emits when `autoTrack.deviceInfo` is
|
|
409
|
+
* enabled (default). Caller-supplied event properties always override
|
|
410
|
+
* auto-detected ones (so a developer can manually set `app.version` per
|
|
411
|
+
* event if they want to A/B between builds).
|
|
412
|
+
*
|
|
413
|
+
* Privacy posture:
|
|
414
|
+
* - No fingerprinting (no canvas hashes, no font enumeration).
|
|
415
|
+
* - No precise geolocation (only timezone + locale, both of which the
|
|
416
|
+
* browser exposes to every page anyway).
|
|
417
|
+
* - No IP collection — the backend logs the request IP for rate-limit
|
|
418
|
+
* purposes; it isn't stored on the event document.
|
|
419
|
+
* - All fields are typed enums or short strings; we never echo back
|
|
420
|
+
* full User-Agent strings to avoid surfacing fingerprintable detail
|
|
421
|
+
* in dashboards.
|
|
422
|
+
*/
|
|
423
|
+
interface DeviceInfo {
|
|
424
|
+
os?: string;
|
|
425
|
+
osVersion?: string;
|
|
426
|
+
browser?: string;
|
|
427
|
+
browserVersion?: string;
|
|
428
|
+
locale?: string;
|
|
429
|
+
timezone?: string;
|
|
430
|
+
screenWidth?: number;
|
|
431
|
+
screenHeight?: number;
|
|
432
|
+
viewportWidth?: number;
|
|
433
|
+
viewportHeight?: number;
|
|
434
|
+
devicePixelRatio?: number;
|
|
435
|
+
/** Caller-supplied. Set via Crossdeck.start({ appVersion: "1.2.3" }). */
|
|
436
|
+
appVersion?: string;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export { type AliasResult, type AuditRail, type AutoTrackOptions, Crossdeck, CrossdeckClient, CrossdeckError, type CrossdeckErrorPayload, type CrossdeckErrorType, type CrossdeckOptions, DEFAULT_BASE_URL, type DeviceInfo, type Diagnostics, type EntitlementsListResponse, type Environment, type EventProperties, type HeartbeatResponse, type IdentifyOptions, type KeyValueStorage, MemoryStorage, type Platform, type PublicEntitlement, type PurchaseResult, SDK_NAME, SDK_VERSION };
|
package/dist/index.d.ts
CHANGED
|
@@ -53,12 +53,36 @@ interface HeartbeatResponse {
|
|
|
53
53
|
serverTime: number;
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
|
-
* Configuration for Crossdeck.
|
|
57
|
-
*
|
|
56
|
+
* Configuration for Crossdeck.init. Three fields are mandatory —
|
|
57
|
+
* `appId`, `publicKey`, and `environment` — per NorthStar §11.1.
|
|
58
|
+
*
|
|
59
|
+
* The pair of (appId, environment) is what we put on the wire envelope
|
|
60
|
+
* (NorthStar §13.1) so the backend can correlate events against the
|
|
61
|
+
* specific app surface and refuse mismatched env declarations loudly.
|
|
58
62
|
*/
|
|
59
63
|
interface CrossdeckOptions {
|
|
64
|
+
/**
|
|
65
|
+
* Your Crossdeck App ID (e.g. "app_web_xxx"). Required.
|
|
66
|
+
*
|
|
67
|
+
* Issued in the dashboard when you create an app. Goes on the wire
|
|
68
|
+
* envelope so the backend correlates events with the specific app
|
|
69
|
+
* surface — useful when one project has multiple apps (web + iOS +
|
|
70
|
+
* Android) sharing the same publishable key family.
|
|
71
|
+
*/
|
|
72
|
+
appId: string;
|
|
60
73
|
/** Your Crossdeck publishable key (cd_pub_…). Required. */
|
|
61
74
|
publicKey: string;
|
|
75
|
+
/**
|
|
76
|
+
* Explicit environment declaration. Required.
|
|
77
|
+
*
|
|
78
|
+
* Must match the publishable key's prefix:
|
|
79
|
+
* cd_pub_test_… → "sandbox"
|
|
80
|
+
* cd_pub_live_… → "production"
|
|
81
|
+
*
|
|
82
|
+
* Mismatch is rejected at init time so a typo'd key can't silently
|
|
83
|
+
* route prod telemetry into sandbox dashboards.
|
|
84
|
+
*/
|
|
85
|
+
environment: Environment;
|
|
62
86
|
/**
|
|
63
87
|
* Override the API base URL. Default is https://api.cross-deck.com/v1.
|
|
64
88
|
* Useful for self-hosted setups or pointing at the local emulator
|
|
@@ -90,6 +114,40 @@ interface CrossdeckOptions {
|
|
|
90
114
|
eventFlushIntervalMs?: number;
|
|
91
115
|
/** Override the SDK version reported on heartbeats. Default: package version. */
|
|
92
116
|
sdkVersion?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Auto-tracking. Default: every flag is `true` in browsers, all
|
|
119
|
+
* silently no-op in Node.
|
|
120
|
+
*
|
|
121
|
+
* Pass `false` to disable everything, or a partial object to override
|
|
122
|
+
* individual flags:
|
|
123
|
+
*
|
|
124
|
+
* Crossdeck.start({
|
|
125
|
+
* publicKey: "...",
|
|
126
|
+
* autoTrack: { pageViews: false }, // sessions + deviceInfo still on
|
|
127
|
+
* });
|
|
128
|
+
*/
|
|
129
|
+
autoTrack?: boolean | Partial<AutoTrackOptions>;
|
|
130
|
+
/**
|
|
131
|
+
* Your app's version (e.g. "1.2.3"). Auto-attached to every event as
|
|
132
|
+
* `properties.appVersion` when `autoTrack.deviceInfo` is enabled.
|
|
133
|
+
* Useful for slicing dashboards by build.
|
|
134
|
+
*/
|
|
135
|
+
appVersion?: string;
|
|
136
|
+
/**
|
|
137
|
+
* Enable verbose diagnostic logging via the NorthStar §16 debug-signal
|
|
138
|
+
* vocabulary. Default: false. Equivalent to calling
|
|
139
|
+
* `Crossdeck.setDebugMode(true)` after init.
|
|
140
|
+
*/
|
|
141
|
+
debug?: boolean;
|
|
142
|
+
}
|
|
143
|
+
/** Auto-tracking flags. See CrossdeckOptions.autoTrack. */
|
|
144
|
+
interface AutoTrackOptions {
|
|
145
|
+
/** Emit `session.started` / `session.ended` automatically. Default true (browser only). */
|
|
146
|
+
sessions: boolean;
|
|
147
|
+
/** Emit `page.viewed` on initial load + SPA navigation. Default true (browser only). */
|
|
148
|
+
pageViews: boolean;
|
|
149
|
+
/** Auto-attach os/browser/locale/screen/etc to every event's `properties`. Default true (browser only). */
|
|
150
|
+
deviceInfo: boolean;
|
|
93
151
|
}
|
|
94
152
|
/** Minimal interface for any pluggable key-value persistence. */
|
|
95
153
|
interface KeyValueStorage {
|
|
@@ -137,7 +195,11 @@ interface Diagnostics {
|
|
|
137
195
|
*
|
|
138
196
|
* import { Crossdeck } from "@cross-deck/web";
|
|
139
197
|
*
|
|
140
|
-
* Crossdeck.
|
|
198
|
+
* Crossdeck.init({
|
|
199
|
+
* appId: "app_web_xxx",
|
|
200
|
+
* publicKey: "cd_pub_live_…",
|
|
201
|
+
* environment: "production",
|
|
202
|
+
* });
|
|
141
203
|
*
|
|
142
204
|
* await Crossdeck.identify("user_847");
|
|
143
205
|
* const ents = await Crossdeck.getEntitlements();
|
|
@@ -149,11 +211,12 @@ interface Diagnostics {
|
|
|
149
211
|
*
|
|
150
212
|
* Usage (Node):
|
|
151
213
|
*
|
|
152
|
-
* import { Crossdeck } from "@cross-deck/web";
|
|
153
|
-
* import { MemoryStorage } from "@cross-deck/web";
|
|
214
|
+
* import { Crossdeck, MemoryStorage } from "@cross-deck/web";
|
|
154
215
|
*
|
|
155
|
-
* Crossdeck.
|
|
216
|
+
* Crossdeck.init({
|
|
217
|
+
* appId: "app_node_xxx",
|
|
156
218
|
* publicKey: "cd_pub_test_…",
|
|
219
|
+
* environment: "sandbox",
|
|
157
220
|
* storage: new MemoryStorage(), // session-only persistence
|
|
158
221
|
* autoHeartbeat: false, // skip the boot ping in scripts
|
|
159
222
|
* });
|
|
@@ -162,9 +225,19 @@ interface Diagnostics {
|
|
|
162
225
|
declare class CrossdeckClient {
|
|
163
226
|
private state;
|
|
164
227
|
/**
|
|
165
|
-
* Boot the SDK. Idempotent — calling
|
|
228
|
+
* Boot the SDK. Idempotent — calling init twice with the same options
|
|
166
229
|
* is a no-op; calling with different options replaces the previous
|
|
167
230
|
* configuration.
|
|
231
|
+
*
|
|
232
|
+
* NorthStar §11.1: signature is `Crossdeck.init({ appId, publicKey,
|
|
233
|
+
* environment })`. The trio is validated up-front so a typo'd key or a
|
|
234
|
+
* mismatched env fails fast at boot rather than at first event-flush.
|
|
235
|
+
*/
|
|
236
|
+
init(options: CrossdeckOptions): void;
|
|
237
|
+
/**
|
|
238
|
+
* @deprecated Use `init()` instead. NorthStar §4 standardised the
|
|
239
|
+
* lifecycle method name across SDKs as `init` (formerly `start` /
|
|
240
|
+
* `configure`). `start` will be removed in a future major version.
|
|
168
241
|
*/
|
|
169
242
|
start(options: CrossdeckOptions): void;
|
|
170
243
|
/**
|
|
@@ -188,17 +261,43 @@ declare class CrossdeckClient {
|
|
|
188
261
|
/**
|
|
189
262
|
* Queue a telemetry event. Returns immediately — the network round-
|
|
190
263
|
* trip happens in the background. To flush before the page unloads,
|
|
191
|
-
* call
|
|
264
|
+
* call flush().
|
|
192
265
|
*/
|
|
193
266
|
track(name: string, properties?: EventProperties): void;
|
|
194
|
-
/**
|
|
267
|
+
/**
|
|
268
|
+
* Force-flush queued events. Useful to call from page-unload handlers.
|
|
269
|
+
*
|
|
270
|
+
* NorthStar §4: standard method name across all Crossdeck SDKs.
|
|
271
|
+
*/
|
|
272
|
+
flush(): Promise<void>;
|
|
273
|
+
/** @deprecated Use `flush()` instead. NorthStar §4 standardised the name. */
|
|
195
274
|
flushEvents(): Promise<void>;
|
|
196
|
-
/**
|
|
275
|
+
/**
|
|
276
|
+
* Forward purchase evidence to the backend for verification + entitlement
|
|
277
|
+
* projection. NorthStar §4 + §13 canonical name.
|
|
278
|
+
*
|
|
279
|
+
* Today the web SDK only supports Apple StoreKit 2 forwarding (web apps
|
|
280
|
+
* that sit alongside an iOS app). Stripe doesn't need this method —
|
|
281
|
+
* Stripe webhooks deliver evidence server-side without a client round-trip.
|
|
282
|
+
*/
|
|
283
|
+
syncPurchases(input: {
|
|
284
|
+
rail?: "apple";
|
|
285
|
+
signedTransactionInfo: string;
|
|
286
|
+
signedRenewalInfo?: string;
|
|
287
|
+
appAccountToken?: string;
|
|
288
|
+
}): Promise<PurchaseResult>;
|
|
289
|
+
/** @deprecated Use `syncPurchases()` instead. NorthStar §4 standardised the name. */
|
|
197
290
|
purchaseApple(input: {
|
|
198
291
|
signedTransactionInfo: string;
|
|
199
292
|
signedRenewalInfo?: string;
|
|
200
293
|
appAccountToken?: string;
|
|
201
294
|
}): Promise<PurchaseResult>;
|
|
295
|
+
/**
|
|
296
|
+
* Toggle verbose diagnostic logging — NorthStar §16. When enabled, the
|
|
297
|
+
* SDK emits a fixed vocabulary of debug signals to console.info that the
|
|
298
|
+
* dashboard's onboarding checklist can also surface as live events.
|
|
299
|
+
*/
|
|
300
|
+
setDebugMode(enabled: boolean): void;
|
|
202
301
|
/**
|
|
203
302
|
* Send the boot heartbeat. Called automatically by start() unless
|
|
204
303
|
* autoHeartbeat:false. Safe to call manually as a "we're still here" ping.
|
|
@@ -300,7 +399,41 @@ declare class MemoryStorage implements KeyValueStorage {
|
|
|
300
399
|
* fetch shim, no transitive deps.
|
|
301
400
|
*/
|
|
302
401
|
declare const SDK_NAME = "@cross-deck/web";
|
|
303
|
-
declare const SDK_VERSION = "0.
|
|
402
|
+
declare const SDK_VERSION = "0.3.0";
|
|
304
403
|
declare const DEFAULT_BASE_URL = "https://api.cross-deck.com/v1";
|
|
305
404
|
|
|
306
|
-
|
|
405
|
+
/**
|
|
406
|
+
* Device + environment enrichment.
|
|
407
|
+
*
|
|
408
|
+
* Auto-attached to every event the SDK emits when `autoTrack.deviceInfo` is
|
|
409
|
+
* enabled (default). Caller-supplied event properties always override
|
|
410
|
+
* auto-detected ones (so a developer can manually set `app.version` per
|
|
411
|
+
* event if they want to A/B between builds).
|
|
412
|
+
*
|
|
413
|
+
* Privacy posture:
|
|
414
|
+
* - No fingerprinting (no canvas hashes, no font enumeration).
|
|
415
|
+
* - No precise geolocation (only timezone + locale, both of which the
|
|
416
|
+
* browser exposes to every page anyway).
|
|
417
|
+
* - No IP collection — the backend logs the request IP for rate-limit
|
|
418
|
+
* purposes; it isn't stored on the event document.
|
|
419
|
+
* - All fields are typed enums or short strings; we never echo back
|
|
420
|
+
* full User-Agent strings to avoid surfacing fingerprintable detail
|
|
421
|
+
* in dashboards.
|
|
422
|
+
*/
|
|
423
|
+
interface DeviceInfo {
|
|
424
|
+
os?: string;
|
|
425
|
+
osVersion?: string;
|
|
426
|
+
browser?: string;
|
|
427
|
+
browserVersion?: string;
|
|
428
|
+
locale?: string;
|
|
429
|
+
timezone?: string;
|
|
430
|
+
screenWidth?: number;
|
|
431
|
+
screenHeight?: number;
|
|
432
|
+
viewportWidth?: number;
|
|
433
|
+
viewportHeight?: number;
|
|
434
|
+
devicePixelRatio?: number;
|
|
435
|
+
/** Caller-supplied. Set via Crossdeck.start({ appVersion: "1.2.3" }). */
|
|
436
|
+
appVersion?: string;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export { type AliasResult, type AuditRail, type AutoTrackOptions, Crossdeck, CrossdeckClient, CrossdeckError, type CrossdeckErrorPayload, type CrossdeckErrorType, type CrossdeckOptions, DEFAULT_BASE_URL, type DeviceInfo, type Diagnostics, type EntitlementsListResponse, type Environment, type EventProperties, type HeartbeatResponse, type IdentifyOptions, type KeyValueStorage, MemoryStorage, type Platform, type PublicEntitlement, type PurchaseResult, SDK_NAME, SDK_VERSION };
|