@cross-deck/web 0.2.0 → 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 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.start({ publicKey: "cd_pub_live_…" });
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");
@@ -37,7 +41,7 @@ That's the full happy path.
37
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.
38
42
  - **Synchronous entitlement reads.** `getEntitlements()` populates a local cache. `isEntitled("pro")` is a Set lookup — no network call, no waiting.
39
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.
40
- - **Boot heartbeat.** On `start()` the SDK pings `/v1/sdk/heartbeat` so the dashboard's Apps page can show you "last seen" per install. Disable with `autoHeartbeat: false`.
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`.
41
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.
42
46
 
43
47
  ## Auto-tracked events
@@ -75,13 +79,15 @@ No fingerprinting, no IP collection on the event document, no canvas hashing. Pr
75
79
 
76
80
  ## API
77
81
 
78
- ### `Crossdeck.start(options)`
82
+ ### `Crossdeck.init(options)`
79
83
 
80
- 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.)
81
85
 
82
86
  ```ts
83
- Crossdeck.start({
87
+ Crossdeck.init({
88
+ appId: "app_web_xxx", // required — from the dashboard
84
89
  publicKey: "cd_pub_live_…", // required
90
+ environment: "production", // required — "production" | "sandbox"
85
91
  baseUrl: "https://api.cross-deck.com/v1", // override for self-host or emulator
86
92
  appVersion: "1.2.3", // attached to every event as properties.appVersion
87
93
  autoTrack: true, // default — sessions, page views, device info
@@ -90,9 +96,12 @@ Crossdeck.start({
90
96
  eventFlushBatchSize: 20, // default
91
97
  eventFlushIntervalMs: 5_000, // default
92
98
  storage: customStorage, // override the persistence adapter
99
+ debug: false, // verbose §16 debug signals when true
93
100
  });
94
101
  ```
95
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
+
96
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.
97
106
 
98
107
  ### `await Crossdeck.identify(userId, options?)`
@@ -129,24 +138,26 @@ Synchronous read from the local cache. Returns `false` until you've called `getE
129
138
 
130
139
  ### `Crossdeck.track(name, properties?)`
131
140
 
132
- Queue a telemetry event. Returns immediately. Events flush in batches; force a flush with `flushEvents()`:
141
+ Queue a telemetry event. Returns immediately. Events flush in batches; force a flush with `flush()`:
133
142
 
134
143
  ```ts
135
144
  Crossdeck.track("checkout_started", { product: "annual_pro" });
136
145
  // …later, e.g. before page unload:
137
146
  window.addEventListener("beforeunload", () => {
138
- void Crossdeck.flushEvents();
147
+ void Crossdeck.flush();
139
148
  });
140
149
  ```
141
150
 
142
151
  Event names match `[A-Za-z0-9_.\-:]+`, max 128 chars. Properties are JSON-serialisable, max 8 KB per event after JSON encoding.
143
152
 
144
- ### `await Crossdeck.purchaseApple(input)`
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)`
145
156
 
146
- Forward a StoreKit 2 transaction directly to Crossdeck for verification — closes the purchase-to-entitled latency from seconds to milliseconds (faster than waiting for the App Store webhook).
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.)
147
158
 
148
159
  ```ts
149
- await Crossdeck.purchaseApple({
160
+ await Crossdeck.syncPurchases({
150
161
  signedTransactionInfo: transaction.jsonRepresentation, // from StoreKit 2
151
162
  signedRenewalInfo: subscription.signedRenewalInfo, // optional
152
163
  appAccountToken: "uuid-…", // optional
@@ -157,15 +168,19 @@ Stripe and Google purchases are verified via webhooks (Stripe Connect platform e
157
168
 
158
169
  ### `await Crossdeck.heartbeat()`
159
170
 
160
- Manually send a heartbeat. Called automatically by `start()` unless `autoHeartbeat: false`. Returns the readiness summary the dashboard uses to display SDK installation status.
171
+ Manually send a heartbeat. Called automatically by `init()` unless `autoHeartbeat: false`. Returns the readiness summary the dashboard uses to display SDK installation status.
161
172
 
162
173
  ### `Crossdeck.reset()`
163
174
 
164
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.
165
176
 
166
- ### `Crossdeck.flushEvents()`
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)`
167
182
 
168
- Force-flush the in-memory event queue. Useful before page unload or when shutting down a script.
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`.
169
184
 
170
185
  ### `Crossdeck.diagnostics()`
171
186
 
@@ -186,7 +201,7 @@ Diagnostic snapshot — useful for development consoles and bug reports:
186
201
 
187
202
  ## Errors
188
203
 
189
- Every async method can throw `CrossdeckError`. Synchronous methods throw on configuration mistakes (calling before `start()`, invalid key prefix).
204
+ Every async method can throw `CrossdeckError`. Synchronous methods throw on configuration mistakes (calling before `init()`, invalid key prefix, env mismatch).
190
205
 
191
206
  ```ts
192
207
  import { CrossdeckError } from "@cross-deck/web";
@@ -220,9 +235,11 @@ The SDK works the same way in Node 18+:
220
235
  ```ts
221
236
  import { Crossdeck, MemoryStorage } from "@cross-deck/web";
222
237
 
223
- Crossdeck.start({
238
+ Crossdeck.init({
239
+ appId: process.env.CROSSDECK_APP_ID!,
224
240
  publicKey: process.env.CROSSDECK_PUBLIC_KEY!,
225
- storage: new MemoryStorage(), // session-only, no localStorage
241
+ environment: "sandbox", // or "production"
242
+ storage: new MemoryStorage(), // session-only, no localStorage
226
243
  autoHeartbeat: false, // skip the boot ping in scripts
227
244
  });
228
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.start. Most fields have sensible defaults
57
- * only `publicKey` is mandatory.
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
@@ -109,6 +133,12 @@ interface CrossdeckOptions {
109
133
  * Useful for slicing dashboards by build.
110
134
  */
111
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;
112
142
  }
113
143
  /** Auto-tracking flags. See CrossdeckOptions.autoTrack. */
114
144
  interface AutoTrackOptions {
@@ -165,7 +195,11 @@ interface Diagnostics {
165
195
  *
166
196
  * import { Crossdeck } from "@cross-deck/web";
167
197
  *
168
- * Crossdeck.start({ publicKey: "cd_pub_live_…" });
198
+ * Crossdeck.init({
199
+ * appId: "app_web_xxx",
200
+ * publicKey: "cd_pub_live_…",
201
+ * environment: "production",
202
+ * });
169
203
  *
170
204
  * await Crossdeck.identify("user_847");
171
205
  * const ents = await Crossdeck.getEntitlements();
@@ -177,11 +211,12 @@ interface Diagnostics {
177
211
  *
178
212
  * Usage (Node):
179
213
  *
180
- * import { Crossdeck } from "@cross-deck/web";
181
- * import { MemoryStorage } from "@cross-deck/web";
214
+ * import { Crossdeck, MemoryStorage } from "@cross-deck/web";
182
215
  *
183
- * Crossdeck.start({
216
+ * Crossdeck.init({
217
+ * appId: "app_node_xxx",
184
218
  * publicKey: "cd_pub_test_…",
219
+ * environment: "sandbox",
185
220
  * storage: new MemoryStorage(), // session-only persistence
186
221
  * autoHeartbeat: false, // skip the boot ping in scripts
187
222
  * });
@@ -190,9 +225,19 @@ interface Diagnostics {
190
225
  declare class CrossdeckClient {
191
226
  private state;
192
227
  /**
193
- * Boot the SDK. Idempotent — calling start twice with the same options
228
+ * Boot the SDK. Idempotent — calling init twice with the same options
194
229
  * is a no-op; calling with different options replaces the previous
195
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.
196
241
  */
197
242
  start(options: CrossdeckOptions): void;
198
243
  /**
@@ -216,17 +261,43 @@ declare class CrossdeckClient {
216
261
  /**
217
262
  * Queue a telemetry event. Returns immediately — the network round-
218
263
  * trip happens in the background. To flush before the page unloads,
219
- * call flushEvents().
264
+ * call flush().
220
265
  */
221
266
  track(name: string, properties?: EventProperties): void;
222
- /** Force-flush queued events. Useful to call from page-unload handlers. */
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. */
223
274
  flushEvents(): Promise<void>;
224
- /** Forward an Apple StoreKit 2 transaction for verification + projection. */
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. */
225
290
  purchaseApple(input: {
226
291
  signedTransactionInfo: string;
227
292
  signedRenewalInfo?: string;
228
293
  appAccountToken?: string;
229
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;
230
301
  /**
231
302
  * Send the boot heartbeat. Called automatically by start() unless
232
303
  * autoHeartbeat:false. Safe to call manually as a "we're still here" ping.
@@ -328,7 +399,7 @@ declare class MemoryStorage implements KeyValueStorage {
328
399
  * fetch shim, no transitive deps.
329
400
  */
330
401
  declare const SDK_NAME = "@cross-deck/web";
331
- declare const SDK_VERSION = "0.2.0";
402
+ declare const SDK_VERSION = "0.3.0";
332
403
  declare const DEFAULT_BASE_URL = "https://api.cross-deck.com/v1";
333
404
 
334
405
  /**
package/dist/index.d.ts CHANGED
@@ -53,12 +53,36 @@ interface HeartbeatResponse {
53
53
  serverTime: number;
54
54
  }
55
55
  /**
56
- * Configuration for Crossdeck.start. Most fields have sensible defaults
57
- * only `publicKey` is mandatory.
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
@@ -109,6 +133,12 @@ interface CrossdeckOptions {
109
133
  * Useful for slicing dashboards by build.
110
134
  */
111
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;
112
142
  }
113
143
  /** Auto-tracking flags. See CrossdeckOptions.autoTrack. */
114
144
  interface AutoTrackOptions {
@@ -165,7 +195,11 @@ interface Diagnostics {
165
195
  *
166
196
  * import { Crossdeck } from "@cross-deck/web";
167
197
  *
168
- * Crossdeck.start({ publicKey: "cd_pub_live_…" });
198
+ * Crossdeck.init({
199
+ * appId: "app_web_xxx",
200
+ * publicKey: "cd_pub_live_…",
201
+ * environment: "production",
202
+ * });
169
203
  *
170
204
  * await Crossdeck.identify("user_847");
171
205
  * const ents = await Crossdeck.getEntitlements();
@@ -177,11 +211,12 @@ interface Diagnostics {
177
211
  *
178
212
  * Usage (Node):
179
213
  *
180
- * import { Crossdeck } from "@cross-deck/web";
181
- * import { MemoryStorage } from "@cross-deck/web";
214
+ * import { Crossdeck, MemoryStorage } from "@cross-deck/web";
182
215
  *
183
- * Crossdeck.start({
216
+ * Crossdeck.init({
217
+ * appId: "app_node_xxx",
184
218
  * publicKey: "cd_pub_test_…",
219
+ * environment: "sandbox",
185
220
  * storage: new MemoryStorage(), // session-only persistence
186
221
  * autoHeartbeat: false, // skip the boot ping in scripts
187
222
  * });
@@ -190,9 +225,19 @@ interface Diagnostics {
190
225
  declare class CrossdeckClient {
191
226
  private state;
192
227
  /**
193
- * Boot the SDK. Idempotent — calling start twice with the same options
228
+ * Boot the SDK. Idempotent — calling init twice with the same options
194
229
  * is a no-op; calling with different options replaces the previous
195
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.
196
241
  */
197
242
  start(options: CrossdeckOptions): void;
198
243
  /**
@@ -216,17 +261,43 @@ declare class CrossdeckClient {
216
261
  /**
217
262
  * Queue a telemetry event. Returns immediately — the network round-
218
263
  * trip happens in the background. To flush before the page unloads,
219
- * call flushEvents().
264
+ * call flush().
220
265
  */
221
266
  track(name: string, properties?: EventProperties): void;
222
- /** Force-flush queued events. Useful to call from page-unload handlers. */
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. */
223
274
  flushEvents(): Promise<void>;
224
- /** Forward an Apple StoreKit 2 transaction for verification + projection. */
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. */
225
290
  purchaseApple(input: {
226
291
  signedTransactionInfo: string;
227
292
  signedRenewalInfo?: string;
228
293
  appAccountToken?: string;
229
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;
230
301
  /**
231
302
  * Send the boot heartbeat. Called automatically by start() unless
232
303
  * autoHeartbeat:false. Safe to call manually as a "we're still here" ping.
@@ -328,7 +399,7 @@ declare class MemoryStorage implements KeyValueStorage {
328
399
  * fetch shim, no transitive deps.
329
400
  */
330
401
  declare const SDK_NAME = "@cross-deck/web";
331
- declare const SDK_VERSION = "0.2.0";
402
+ declare const SDK_VERSION = "0.3.0";
332
403
  declare const DEFAULT_BASE_URL = "https://api.cross-deck.com/v1";
333
404
 
334
405
  /**