@trackstall/sdk 0.1.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/README.md +75 -0
- package/index.d.ts +843 -0
- package/index.js +2734 -0
- package/package.json +53 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,843 @@
|
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Canonical attribution schema shared between the TrackStall SDK (clients that
|
|
5
|
+
* integrate into any app) and the Node/Lambda server. All types here are
|
|
6
|
+
* runtime-agnostic: no Hermes-only APIs, no Node-only APIs.
|
|
7
|
+
*
|
|
8
|
+
* A single `AttributionEvent` fans out to:
|
|
9
|
+
* - Meta SDK (in-app `logEvent`)
|
|
10
|
+
* - TikTok Business SDK (in-app `trackEvent`)
|
|
11
|
+
* - Meta Conversions API (server)
|
|
12
|
+
* - TikTok Events API (server)
|
|
13
|
+
* - TrackStall's own Mongo store (reporting / dashboard)
|
|
14
|
+
*
|
|
15
|
+
* Cross-channel deduplication relies on `eventId` being identical across all
|
|
16
|
+
* destinations — see `eventId.ts`.
|
|
17
|
+
*
|
|
18
|
+
* Multi-tenancy: every event carries an `appId`. The server scopes every read
|
|
19
|
+
* and write by it, and resolves the per-app provider credentials (Meta CAPI
|
|
20
|
+
* token + pixel, TikTok EAPI token + pixel) from it.
|
|
21
|
+
*/
|
|
22
|
+
/** ISO 4217 currency code (e.g. "USD", "BRL"). Always upper-case. */
|
|
23
|
+
export type Currency = string;
|
|
24
|
+
/** Runtime platform the event was emitted from. */
|
|
25
|
+
export type Platform = "ios" | "android" | "web";
|
|
26
|
+
/** Origin store of a paid transaction. */
|
|
27
|
+
export type StorePlatform = "apple" | "google" | "stripe" | "web" | "unknown";
|
|
28
|
+
/** Snapshot of App Tracking Transparency status at event time. */
|
|
29
|
+
export type AttStatus = "authorized" | "denied" | "restricted" | "undetermined" | "unavailable";
|
|
30
|
+
/**
|
|
31
|
+
* Canonical event names recognized by TrackStall. These are vendor-neutral;
|
|
32
|
+
* adapters map them to vendor-specific names at the edge (e.g. `subscribe` →
|
|
33
|
+
* `fb_mobile_subscribe` on Meta SDK, `Subscribe` on Meta CAPI, `subscribe` on
|
|
34
|
+
* TikTok Events API).
|
|
35
|
+
*
|
|
36
|
+
* Because TrackStall is multi-tenant and serves arbitrary apps, the event
|
|
37
|
+
* `name` accepts any string too — apps can emit custom events while still
|
|
38
|
+
* getting autocomplete on the canonical set. Custom names pass through to
|
|
39
|
+
* vendor `custom_data` / `properties` and to the dashboard as-is.
|
|
40
|
+
*/
|
|
41
|
+
export type CanonicalEventName = "install" | "app_open" | "onboarding_started" | "onboarding_step" | "onboarding_completed" | "paywall_shown" | "paywall_dismissed" | "start_checkout" | "trial_started" | "subscribe" | "purchase" | "renewal" | "cancellation" | "expiration" | "refund" | "add_to_cart" | "level_complete" | "tutorial_complete" | "content_view";
|
|
42
|
+
/**
|
|
43
|
+
* Event name as accepted on the wire: a canonical name (autocompleted) OR any
|
|
44
|
+
* custom string the integrating app chooses. `(string & {})` keeps the union
|
|
45
|
+
* literals in IntelliSense while still allowing arbitrary strings.
|
|
46
|
+
*/
|
|
47
|
+
export type AttributionEventName = CanonicalEventName | (string & {});
|
|
48
|
+
/**
|
|
49
|
+
* Identifiers and PII for the acting user. All PII fields (`email`, `phone`)
|
|
50
|
+
* are sent as raw values through the pipeline and hashed at the adapter layer
|
|
51
|
+
* right before being shipped to Meta CAPI / TikTok Events API — never logged
|
|
52
|
+
* raw, never persisted raw.
|
|
53
|
+
*/
|
|
54
|
+
export interface AttributionUser {
|
|
55
|
+
/** Stable internal user id supplied by the integrating app. */
|
|
56
|
+
userId?: string;
|
|
57
|
+
/** iOS Identifier for Vendor (always available, no ATT required). */
|
|
58
|
+
idfv?: string;
|
|
59
|
+
/** iOS Advertising Identifier (only available when ATT === 'authorized'). */
|
|
60
|
+
idfa?: string;
|
|
61
|
+
/** Google Advertising ID (Android only). */
|
|
62
|
+
gaid?: string;
|
|
63
|
+
/** PII — hashed at adapter boundary (Meta `em`, TikTok `email`). */
|
|
64
|
+
email?: string;
|
|
65
|
+
/** PII — hashed at adapter boundary (Meta `ph`, TikTok `phone_number`). */
|
|
66
|
+
phone?: string;
|
|
67
|
+
/** ISO 3166-1 alpha-2, lower-case (e.g. "br", "us"). */
|
|
68
|
+
country?: string;
|
|
69
|
+
/** BCP-47 locale (e.g. "pt-BR", "en-US"). */
|
|
70
|
+
locale?: string;
|
|
71
|
+
/** ATT snapshot at event time. */
|
|
72
|
+
attStatus?: AttStatus;
|
|
73
|
+
/**
|
|
74
|
+
* Client IP as observed by the server at request time. Populated SERVER-side
|
|
75
|
+
* from the request socket — never trust a wire value. Boosts Event Match
|
|
76
|
+
* Quality (Meta `client_ip_address`, TikTok `ip`). Never logged/persisted raw
|
|
77
|
+
* (PII redaction strips it before Mongo).
|
|
78
|
+
*/
|
|
79
|
+
ipAddress?: string;
|
|
80
|
+
/** User agent from the same request as `ipAddress`. Server-side capture only. */
|
|
81
|
+
userAgent?: string;
|
|
82
|
+
/** Meta browser cookie (`_fbp`). Sent to Meta CAPI as `user_data.fbp`. */
|
|
83
|
+
fbp?: string;
|
|
84
|
+
/** Meta click cookie (`_fbc`). Highest-impact field for paid Meta traffic. */
|
|
85
|
+
fbc?: string;
|
|
86
|
+
/** TikTok click id (`ttclid`). Deterministic match key for paid TikTok. */
|
|
87
|
+
ttclid?: string;
|
|
88
|
+
/** TikTok pixel cookie (`_ttp`). */
|
|
89
|
+
ttp?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Monetary information for revenue-bearing events. The server uses `netValue`
|
|
93
|
+
* to teach the ad algorithm; do not use `grossValue` for optimization (it
|
|
94
|
+
* inflates LTV by the store's commission).
|
|
95
|
+
*/
|
|
96
|
+
export interface RevenueData {
|
|
97
|
+
/** What the user paid, before any commission. Used for accounting / BI. */
|
|
98
|
+
grossValue: number;
|
|
99
|
+
/** What the app actually receives after store fee. Used for optimization. */
|
|
100
|
+
netValue: number;
|
|
101
|
+
/** ISO 4217, upper-case. */
|
|
102
|
+
currency: Currency;
|
|
103
|
+
/** Where the money came from. Determines the default fee rate. */
|
|
104
|
+
store: StorePlatform;
|
|
105
|
+
/** Store-issued transaction id (App Store original_transaction_id, etc.). */
|
|
106
|
+
transactionId?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Optional marketing attribution context. Populated by the server when a
|
|
110
|
+
* webhook/event arrives (joining `userId` → first-touch campaign captured at
|
|
111
|
+
* install) or by deep-link adapters on the client.
|
|
112
|
+
*/
|
|
113
|
+
export interface AttributionContext {
|
|
114
|
+
campaignId?: string;
|
|
115
|
+
adsetId?: string;
|
|
116
|
+
adId?: string;
|
|
117
|
+
creativeId?: string;
|
|
118
|
+
source?: "meta" | "tiktok" | "google" | "organic" | "referral" | "unknown";
|
|
119
|
+
/** Stable token returned by `POST /v1/click`. Joins user → click. */
|
|
120
|
+
clickToken?: string;
|
|
121
|
+
utmSource?: string;
|
|
122
|
+
utmMedium?: string;
|
|
123
|
+
utmCampaign?: string;
|
|
124
|
+
utmContent?: string;
|
|
125
|
+
utmTerm?: string;
|
|
126
|
+
/** 1.0 = deterministic (Universal Link); <1.0 = probabilistic fingerprint. */
|
|
127
|
+
matchConfidence?: number;
|
|
128
|
+
matchMethod?: "universal_link" | "fingerprint" | "manual" | "none";
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The single canonical event shape that flows through every layer. Adapters at
|
|
132
|
+
* the edge translate it to vendor formats; the Mongo collection stores it as-is
|
|
133
|
+
* for reporting / dashboard.
|
|
134
|
+
*/
|
|
135
|
+
export interface AttributionEvent {
|
|
136
|
+
/**
|
|
137
|
+
* Tenant scope. Every read/write on the server is filtered by this, and the
|
|
138
|
+
* per-app provider credentials are resolved from it.
|
|
139
|
+
*/
|
|
140
|
+
appId: string;
|
|
141
|
+
/**
|
|
142
|
+
* Deterministic event id (UUID v5) — see `eventId.ts`. Identical across the
|
|
143
|
+
* in-app SDK, Meta CAPI and TikTok Events API for a given underlying action.
|
|
144
|
+
* Powers the dedup that lets us double-send for resilience without
|
|
145
|
+
* double-counting.
|
|
146
|
+
*/
|
|
147
|
+
eventId: string;
|
|
148
|
+
name: AttributionEventName;
|
|
149
|
+
/** Unix epoch in **seconds** (Meta CAPI / TikTok EAPI convention). */
|
|
150
|
+
timestamp: number;
|
|
151
|
+
platform: Platform;
|
|
152
|
+
user: AttributionUser;
|
|
153
|
+
/** Present on monetization events. */
|
|
154
|
+
revenue?: RevenueData;
|
|
155
|
+
/** Store product id (e.g. "pro_weekly"). */
|
|
156
|
+
productId?: string;
|
|
157
|
+
/** Marketing attribution joined on the server side. */
|
|
158
|
+
attribution?: AttributionContext;
|
|
159
|
+
/** Free-form extras flattened into vendor `custom_data` / `properties`. */
|
|
160
|
+
properties?: Record<string, string | number | boolean | null>;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Subset of `AttributionEvent` callers supply when emitting an event; the
|
|
164
|
+
* orchestrator fills in `eventId`, `timestamp`, and `platform`. `appId` is
|
|
165
|
+
* resolved from the authenticated API key on the server, so the SDK does not
|
|
166
|
+
* need to send it explicitly (though it may).
|
|
167
|
+
*/
|
|
168
|
+
export type AttributionEventInput = Omit<AttributionEvent, "eventId" | "timestamp" | "platform" | "appId"> & {
|
|
169
|
+
appId?: string;
|
|
170
|
+
eventId?: string;
|
|
171
|
+
timestamp?: number;
|
|
172
|
+
platform?: Platform;
|
|
173
|
+
};
|
|
174
|
+
/** Allowed value types inside `properties` (JSON scalars only). */
|
|
175
|
+
export type ProductPropertyValue = string | number | boolean | null;
|
|
176
|
+
/** Lightweight device/app context captured automatically by the SDK. */
|
|
177
|
+
export interface ProductEventContext {
|
|
178
|
+
appVersion?: string;
|
|
179
|
+
osVersion?: string;
|
|
180
|
+
deviceModel?: string;
|
|
181
|
+
/** BCP-47 locale (e.g. "pt-BR"). */
|
|
182
|
+
locale?: string;
|
|
183
|
+
/** ISO 3166-1 alpha-2 (e.g. "br"). */
|
|
184
|
+
country?: string;
|
|
185
|
+
/** SDK name/version that produced the event (e.g. "trackstall-js/0.1"). */
|
|
186
|
+
sdk?: string;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* The canonical product-analytics event. One row per occurrence in the
|
|
190
|
+
* `product_events` collection; `(appId, eventId)` is the dedup key.
|
|
191
|
+
*/
|
|
192
|
+
export interface ProductEvent {
|
|
193
|
+
/** Tenant scope — stamped server-side from the authenticated API key. */
|
|
194
|
+
appId: string;
|
|
195
|
+
/** Unique id for dedup across SDK retries. UUID, client-generated. */
|
|
196
|
+
eventId: string;
|
|
197
|
+
/** Free-form event name chosen by the app (e.g. "screen_view"). */
|
|
198
|
+
name: string;
|
|
199
|
+
/** Unix epoch in **seconds** (same convention as attribution events). */
|
|
200
|
+
timestamp: number;
|
|
201
|
+
platform: Platform;
|
|
202
|
+
/**
|
|
203
|
+
* Who did it: the app's stable `userId` when identified, otherwise the
|
|
204
|
+
* SDK-generated anonymous id. Powers unique-user counts.
|
|
205
|
+
*/
|
|
206
|
+
distinctId: string;
|
|
207
|
+
/** Set when the user is identified (mirrors `distinctId` in that case). */
|
|
208
|
+
userId?: string;
|
|
209
|
+
/** Device-generated anonymous id (kept after identify for stitching). */
|
|
210
|
+
anonymousId?: string;
|
|
211
|
+
/** Optional client-managed session id for session analytics. */
|
|
212
|
+
sessionId?: string;
|
|
213
|
+
/** Free-form event payload. JSON scalars only; no PII. */
|
|
214
|
+
properties?: Record<string, ProductPropertyValue>;
|
|
215
|
+
context?: ProductEventContext;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Wire input accepted by `POST /v1/track`. The server stamps `appId` from the
|
|
219
|
+
* API key and fills `eventId`/`timestamp` when omitted. `distinctId` may be
|
|
220
|
+
* derived from `userId`/`anonymousId` when not set explicitly.
|
|
221
|
+
*/
|
|
222
|
+
export type ProductEventInput = Omit<ProductEvent, "appId" | "eventId" | "timestamp" | "distinctId"> & {
|
|
223
|
+
appId?: string;
|
|
224
|
+
eventId?: string;
|
|
225
|
+
timestamp?: number;
|
|
226
|
+
distinctId?: string;
|
|
227
|
+
};
|
|
228
|
+
export interface DeterministicEventIdInput {
|
|
229
|
+
/**
|
|
230
|
+
* Tenant scope. Included in the dedup key so the same logical action in two
|
|
231
|
+
* different apps never collides on a shared `userId`/`transactionId`.
|
|
232
|
+
*/
|
|
233
|
+
appId: string;
|
|
234
|
+
/** Stable user identifier supplied by the integrating app. */
|
|
235
|
+
userId: string;
|
|
236
|
+
eventName: AttributionEventName;
|
|
237
|
+
/**
|
|
238
|
+
* Strongest dedup key when present — App Store `original_transaction_id`,
|
|
239
|
+
* Play Store `purchaseToken`, Stripe `payment_intent`, etc. For non-purchase
|
|
240
|
+
* events, prefer a stable client-generated id (persisted) so offline retries
|
|
241
|
+
* collapse to the same `eventId`.
|
|
242
|
+
*/
|
|
243
|
+
transactionId?: string;
|
|
244
|
+
/**
|
|
245
|
+
* Unix epoch in seconds. Including it scopes dedup to a single "occurrence"
|
|
246
|
+
* of an otherwise idempotent action (e.g. two renewals on the same
|
|
247
|
+
* transactionId still produce different ids). Omit for interchangeable
|
|
248
|
+
* actions (e.g. the first `install` for a user).
|
|
249
|
+
*/
|
|
250
|
+
timestamp?: number;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Deterministic event id used as the dedup key across every channel (in-app
|
|
254
|
+
* SDK → ad platform pixel/SDK; backend webhook → Meta CAPI / TikTok EAPI).
|
|
255
|
+
* Same inputs always produce the same UUID.
|
|
256
|
+
*/
|
|
257
|
+
export declare function deterministicEventId(input: DeterministicEventIdInput): string;
|
|
258
|
+
/**
|
|
259
|
+
* Non-deterministic event id for one-off events with no stable dedup key.
|
|
260
|
+
* Avoid for monetization.
|
|
261
|
+
*/
|
|
262
|
+
export declare function randomEventId(): string;
|
|
263
|
+
export interface BuildRevenueInput {
|
|
264
|
+
/** Gross amount the user paid (default) or net amount if `netOfStoreFee`. */
|
|
265
|
+
value: number;
|
|
266
|
+
/** ISO 4217 — will be upper-cased. */
|
|
267
|
+
currency: string;
|
|
268
|
+
store: StorePlatform;
|
|
269
|
+
transactionId?: string;
|
|
270
|
+
/** Custom fee rate (0..1). Overrides `STORE_FEE_DEFAULTS[store]`. */
|
|
271
|
+
feeRateOverride?: number;
|
|
272
|
+
/** `true` if `value` is already net of the store commission. */
|
|
273
|
+
netOfStoreFee?: boolean;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Build a normalized `RevenueData` block.
|
|
277
|
+
*
|
|
278
|
+
* Why both `grossValue` and `netValue`:
|
|
279
|
+
* - `grossValue` → revenue reports / BI ("the user paid R$299").
|
|
280
|
+
* - `netValue` → the `value` sent to Meta CAPI / TikTok EAPI, so the
|
|
281
|
+
* optimization algorithm learns from money actually received, not the
|
|
282
|
+
* store's cut. The single most impactful tweak after dedup.
|
|
283
|
+
*/
|
|
284
|
+
export declare function buildRevenue(input: BuildRevenueInput): RevenueData;
|
|
285
|
+
export interface AdapterDeliveryResult {
|
|
286
|
+
ok: boolean;
|
|
287
|
+
/** Short machine code (`unmapped`, `sdk_threw`, `sdk_not_initialized`, ...). */
|
|
288
|
+
code?: string;
|
|
289
|
+
message?: string;
|
|
290
|
+
/** Whether the host could retry. Native adapters are fire-and-forget today. */
|
|
291
|
+
retriable?: boolean;
|
|
292
|
+
}
|
|
293
|
+
export interface NativeAdapter {
|
|
294
|
+
readonly name: string;
|
|
295
|
+
/** Boot the underlying native SDK. Called once from `client.initialize()`. */
|
|
296
|
+
initialize(): Promise<void>;
|
|
297
|
+
/** Propagate (or clear) user identity to the SDK. */
|
|
298
|
+
setUser(identity: UserIdentity | null): void;
|
|
299
|
+
/** Fire one canonical event into the SDK. */
|
|
300
|
+
deliver(event: AttributionEvent): Promise<AdapterDeliveryResult>;
|
|
301
|
+
/** Flush the SDK's internal buffer, if it has one. */
|
|
302
|
+
flush?(): Promise<void>;
|
|
303
|
+
/** Update ATT/advertiser-tracking consent (Meta). */
|
|
304
|
+
setAdvertiserTracking?(enabled: boolean): Promise<void>;
|
|
305
|
+
}
|
|
306
|
+
export interface MetaAdapterOptions {
|
|
307
|
+
/** Meta App ID (developers.facebook.com). */
|
|
308
|
+
appId: string;
|
|
309
|
+
/** Meta Client Token (Settings → Advanced → Client Token). */
|
|
310
|
+
clientToken: string;
|
|
311
|
+
/**
|
|
312
|
+
* Send `AdvertiserTrackingEnabled` based on ATT status. Default true —
|
|
313
|
+
* required on iOS 14.5+ to reach Meta's algorithms (not just SKAdNetwork).
|
|
314
|
+
*/
|
|
315
|
+
honorAtt?: boolean;
|
|
316
|
+
/** Override the adapter name (default `'meta'`). */
|
|
317
|
+
name?: string;
|
|
318
|
+
/** Injectable Meta SDK module — for tests. Default: lazy `require`. */
|
|
319
|
+
sdkLoader?: () => MetaSdkModule;
|
|
320
|
+
}
|
|
321
|
+
/** Minimal slice of `react-native-fbsdk-next` the adapter uses. */
|
|
322
|
+
export interface MetaSdkModule {
|
|
323
|
+
Settings: {
|
|
324
|
+
setAppID(appId: string): void;
|
|
325
|
+
setClientToken(token: string): void;
|
|
326
|
+
initializeSDK(): void;
|
|
327
|
+
setAdvertiserTrackingEnabled?(enabled: boolean): Promise<void> | void;
|
|
328
|
+
setAdvertiserIDCollectionEnabled?(enabled: boolean): Promise<void> | void;
|
|
329
|
+
setAutoLogAppEventsEnabled?(enabled: boolean): Promise<void> | void;
|
|
330
|
+
};
|
|
331
|
+
AppEventsLogger: {
|
|
332
|
+
logEvent(eventName: string, parameters?: Record<string, unknown>): void;
|
|
333
|
+
logEvent(eventName: string, valueToSum: number, parameters?: Record<string, unknown>): void;
|
|
334
|
+
logPurchase(amount: number, currency: string, parameters?: Record<string, unknown>): void;
|
|
335
|
+
setUserID(userId: string): void;
|
|
336
|
+
clearUserID(): void;
|
|
337
|
+
setUserData(userData: Record<string, string | null | undefined>): void;
|
|
338
|
+
flush(): void;
|
|
339
|
+
clearUserData?(): void;
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
export declare class MetaAdapter implements NativeAdapter {
|
|
343
|
+
private readonly options;
|
|
344
|
+
readonly name: string;
|
|
345
|
+
private sdk;
|
|
346
|
+
private readonly honorAtt;
|
|
347
|
+
constructor(options: MetaAdapterOptions);
|
|
348
|
+
initialize(): Promise<void>;
|
|
349
|
+
setUser(identity: UserIdentity | null): void;
|
|
350
|
+
deliver(event: AttributionEvent): Promise<AdapterDeliveryResult>;
|
|
351
|
+
flush(): Promise<void>;
|
|
352
|
+
setAdvertiserTracking(enabled: boolean): Promise<void>;
|
|
353
|
+
private loadSdk;
|
|
354
|
+
}
|
|
355
|
+
export interface MetaMappedEvent {
|
|
356
|
+
name: string;
|
|
357
|
+
kind: "purchase" | "standard" | "custom";
|
|
358
|
+
amount?: number;
|
|
359
|
+
currency?: string;
|
|
360
|
+
valueToSum?: number;
|
|
361
|
+
parameters: Record<string, unknown>;
|
|
362
|
+
}
|
|
363
|
+
/** Map TrackStall canonical names → Meta `AppEvents`. `null` = skip silently. */
|
|
364
|
+
export declare function mapToMetaEvent(event: AttributionEvent): MetaMappedEvent | null;
|
|
365
|
+
export interface TikTokAdapterOptions {
|
|
366
|
+
/** App bundle id (iOS) / package name (Android). */
|
|
367
|
+
appId: string;
|
|
368
|
+
/** TikTok App ID (Business Center → App → Settings). */
|
|
369
|
+
tiktokAppId: string;
|
|
370
|
+
/** Access token the TikTok SDK needs at `initialize()`. */
|
|
371
|
+
accessToken: string;
|
|
372
|
+
/** Default false. True while validating in TikTok Events Manager. */
|
|
373
|
+
debugMode?: boolean;
|
|
374
|
+
/** Override adapter name (default `'tiktok'`). */
|
|
375
|
+
name?: string;
|
|
376
|
+
/** Injectable SDK module — for tests. */
|
|
377
|
+
sdkLoader?: () => TikTokSdkModule;
|
|
378
|
+
}
|
|
379
|
+
/** Minimal surface of `@layers/expo-tiktok-business`. */
|
|
380
|
+
export interface TikTokSdkModule {
|
|
381
|
+
default: {
|
|
382
|
+
initialize(appId: string, tiktokAppId: string, options: {
|
|
383
|
+
accessToken: string;
|
|
384
|
+
debugMode?: boolean;
|
|
385
|
+
autoTrackAppLifecycle?: boolean;
|
|
386
|
+
autoTrackRouteChanges?: boolean;
|
|
387
|
+
}): Promise<boolean>;
|
|
388
|
+
trackEvent(name: string, params?: Record<string, unknown>): Promise<boolean>;
|
|
389
|
+
trackCompletePurchase(value: number, currency: string, contents: Array<{
|
|
390
|
+
content_id: string;
|
|
391
|
+
content_type?: string;
|
|
392
|
+
content_name?: string;
|
|
393
|
+
quantity?: number;
|
|
394
|
+
price?: number;
|
|
395
|
+
}>, additionalParams?: Record<string, unknown>): Promise<boolean>;
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
export declare class TikTokAdapter implements NativeAdapter {
|
|
399
|
+
private readonly options;
|
|
400
|
+
readonly name: string;
|
|
401
|
+
private sdk;
|
|
402
|
+
private currentUserId;
|
|
403
|
+
constructor(options: TikTokAdapterOptions);
|
|
404
|
+
initialize(): Promise<void>;
|
|
405
|
+
setUser(identity: UserIdentity | null): void;
|
|
406
|
+
deliver(event: AttributionEvent): Promise<AdapterDeliveryResult>;
|
|
407
|
+
private loadSdk;
|
|
408
|
+
}
|
|
409
|
+
export interface TikTokMappedEvent {
|
|
410
|
+
name: string;
|
|
411
|
+
kind: "purchase" | "standard" | "custom";
|
|
412
|
+
value?: number;
|
|
413
|
+
currency?: string;
|
|
414
|
+
contents?: Array<{
|
|
415
|
+
content_id: string;
|
|
416
|
+
content_type?: string;
|
|
417
|
+
content_name?: string;
|
|
418
|
+
quantity?: number;
|
|
419
|
+
price?: number;
|
|
420
|
+
}>;
|
|
421
|
+
params: Record<string, unknown>;
|
|
422
|
+
}
|
|
423
|
+
/** Map TrackStall canonical names → TikTok standard events. `null` = skip. */
|
|
424
|
+
export declare function mapToTikTokEvent(event: AttributionEvent, userId: string | null): TikTokMappedEvent | null;
|
|
425
|
+
/**
|
|
426
|
+
* Minimal slice of the tracking-transparency packages. Either pair works:
|
|
427
|
+
* Expo (`requestTrackingPermissionsAsync`) or bare RN
|
|
428
|
+
* (`requestTrackingPermission`).
|
|
429
|
+
*/
|
|
430
|
+
export interface AttSdkModule {
|
|
431
|
+
requestTrackingPermissionsAsync?(): Promise<{
|
|
432
|
+
status: string;
|
|
433
|
+
}>;
|
|
434
|
+
getTrackingPermissionsAsync?(): Promise<{
|
|
435
|
+
status: string;
|
|
436
|
+
}>;
|
|
437
|
+
/** expo-tracking-transparency: returns the IDFA once tracking is authorized. */
|
|
438
|
+
getAdvertisingId?(): string | null;
|
|
439
|
+
requestTrackingPermission?(): Promise<string>;
|
|
440
|
+
getTrackingStatus?(): Promise<string>;
|
|
441
|
+
}
|
|
442
|
+
export declare function loadAttModule(injected?: AttSdkModule): AttSdkModule | null;
|
|
443
|
+
/** Show the native ATT prompt and return the normalized status. */
|
|
444
|
+
export declare function requestAttStatus(mod: AttSdkModule): Promise<AttStatus>;
|
|
445
|
+
/**
|
|
446
|
+
* Read the device advertising id (IDFA) when tracking is authorized. Returns
|
|
447
|
+
* `undefined` when the module can't provide it or tracking isn't authorized
|
|
448
|
+
* (the vendor returns a zeroed UUID in that case, which we filter out).
|
|
449
|
+
*/
|
|
450
|
+
export declare function readAdvertisingId(mod: AttSdkModule): string | undefined;
|
|
451
|
+
/** Read the current ATT status without prompting. */
|
|
452
|
+
export declare function getAttStatus(mod: AttSdkModule): Promise<AttStatus>;
|
|
453
|
+
/** Map vendor status strings onto TrackStall's canonical `AttStatus`. */
|
|
454
|
+
export declare function normalizeAttStatus(raw: string | undefined): AttStatus;
|
|
455
|
+
/**
|
|
456
|
+
* Exponential-backoff retry calculator for backend deliveries. Pure functions —
|
|
457
|
+
* no timers, no `Date.now()`. The queue stores `nextRetryAt` (epoch ms) and the
|
|
458
|
+
* flush loop pulls ready rows on each tick.
|
|
459
|
+
*
|
|
460
|
+
* delay(attempt) = clamp(initialDelay * 2^(attempt-1), 0, maxDelay) ± jitter
|
|
461
|
+
*/
|
|
462
|
+
export interface RetryConfig {
|
|
463
|
+
/** Max attempts (including the first). Default 6. */
|
|
464
|
+
maxAttempts?: number;
|
|
465
|
+
/** First retry delay in ms. Default 1000ms. */
|
|
466
|
+
initialDelayMs?: number;
|
|
467
|
+
/** Cap on individual delays. Default 5 minutes. */
|
|
468
|
+
maxDelayMs?: number;
|
|
469
|
+
/** Jitter factor [0, 1). Default 0.2 → ±20%. */
|
|
470
|
+
jitter?: number;
|
|
471
|
+
}
|
|
472
|
+
export declare const DEFAULT_RETRY: Required<RetryConfig>;
|
|
473
|
+
export declare function resolveRetryConfig(input?: RetryConfig): Required<RetryConfig>;
|
|
474
|
+
export declare function computeRetryDelayMs(attempt: number, config: Required<RetryConfig>, random?: () => number): number;
|
|
475
|
+
export declare function shouldRetry(attemptsSoFar: number, retriable: boolean | undefined, config: Required<RetryConfig>): boolean;
|
|
476
|
+
/**
|
|
477
|
+
* Minimal async key-value contract the SDK persists against. Deliberately a
|
|
478
|
+
* subset of `@react-native-async-storage/async-storage` so that package drops
|
|
479
|
+
* in directly; `localStorage` and an in-memory fallback are adapted to it too.
|
|
480
|
+
*/
|
|
481
|
+
export interface KeyValueStorage {
|
|
482
|
+
getItem(key: string): Promise<string | null>;
|
|
483
|
+
setItem(key: string, value: string): Promise<void>;
|
|
484
|
+
removeItem(key: string): Promise<void>;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Client-safe runtime config served by `GET /v1/config`. Mirrors the server's
|
|
488
|
+
* `ClientRuntimeConfig`. Holds ONLY values the device may hold (App IDs, client
|
|
489
|
+
* token, device access token) — never the CAPI/EAPI server tokens.
|
|
490
|
+
*/
|
|
491
|
+
export interface RemoteConfig {
|
|
492
|
+
appId: string;
|
|
493
|
+
sandbox: boolean;
|
|
494
|
+
meta: {
|
|
495
|
+
appId: string;
|
|
496
|
+
clientToken: string;
|
|
497
|
+
} | null;
|
|
498
|
+
tiktok: {
|
|
499
|
+
appId: string;
|
|
500
|
+
ttAppId: string;
|
|
501
|
+
accessToken: string;
|
|
502
|
+
} | null;
|
|
503
|
+
}
|
|
504
|
+
export interface ClientLogger {
|
|
505
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
506
|
+
info(message: string, context?: Record<string, unknown>): void;
|
|
507
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
508
|
+
error(message: string, error?: unknown, context?: Record<string, unknown>): void;
|
|
509
|
+
}
|
|
510
|
+
export interface DeviceContext {
|
|
511
|
+
bundleId?: string;
|
|
512
|
+
appVersion?: string;
|
|
513
|
+
/** Two-letter country (e.g. `BR`). Improves match quality. */
|
|
514
|
+
country?: string;
|
|
515
|
+
/** IETF language tag (e.g. `pt-BR`). */
|
|
516
|
+
locale?: string;
|
|
517
|
+
timezone?: string;
|
|
518
|
+
/** Device advertising identifiers, when available + permitted. */
|
|
519
|
+
idfa?: string;
|
|
520
|
+
idfv?: string;
|
|
521
|
+
gaid?: string;
|
|
522
|
+
attStatus?: AttStatus;
|
|
523
|
+
/**
|
|
524
|
+
* Probabilistic-match fingerprint signals. Feeding these lifts install
|
|
525
|
+
* matching from the weak IP+locale tier (0.60–0.85) to the strong
|
|
526
|
+
* device-fingerprint tiers (0.82–0.90). Without them, click→install
|
|
527
|
+
* matching on iOS (no deterministic id from Safari) is effectively blind.
|
|
528
|
+
* Populate from React Native `Dimensions`/`Platform`/`expo-device`.
|
|
529
|
+
*/
|
|
530
|
+
screenW?: number;
|
|
531
|
+
screenH?: number;
|
|
532
|
+
pixelRatio?: number;
|
|
533
|
+
osVersion?: string;
|
|
534
|
+
deviceModel?: string;
|
|
535
|
+
}
|
|
536
|
+
export interface UserIdentity {
|
|
537
|
+
/** Stable internal id — matches the server's `user.userId`. Required. */
|
|
538
|
+
userId: string;
|
|
539
|
+
email?: string;
|
|
540
|
+
phone?: string;
|
|
541
|
+
country?: string;
|
|
542
|
+
locale?: string;
|
|
543
|
+
}
|
|
544
|
+
export interface TrackEventInput {
|
|
545
|
+
name: AttributionEventName;
|
|
546
|
+
revenue?: RevenueData;
|
|
547
|
+
productId?: string;
|
|
548
|
+
/** Free-form extras → server `properties`. No PII here. */
|
|
549
|
+
properties?: Record<string, string | number | boolean | null>;
|
|
550
|
+
/** Override the deterministic event id. */
|
|
551
|
+
eventId?: string;
|
|
552
|
+
/** Override event timestamp (epoch ms). Defaults to now. */
|
|
553
|
+
timestampMs?: number;
|
|
554
|
+
/** Per-event user override (log an event for a different user). */
|
|
555
|
+
user?: UserIdentity;
|
|
556
|
+
/** Mark this event as sandbox/test traffic. */
|
|
557
|
+
sandbox?: boolean;
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Optional knobs for `logEvent()` — the product-analytics lane (Mixpanel
|
|
561
|
+
* style). Most apps never need this: `ts.logEvent('screen_view', { screen:
|
|
562
|
+
* 'home' })` is the whole integration.
|
|
563
|
+
*/
|
|
564
|
+
export interface LogEventOptions {
|
|
565
|
+
/** Override the random event id (dedup key on the server). */
|
|
566
|
+
eventId?: string;
|
|
567
|
+
/** Override event timestamp (epoch ms). Defaults to now. */
|
|
568
|
+
timestampMs?: number;
|
|
569
|
+
/** Client-managed session id for session analytics. */
|
|
570
|
+
sessionId?: string;
|
|
571
|
+
}
|
|
572
|
+
/** Free-form product-analytics payload. JSON scalars only; no PII. */
|
|
573
|
+
export type LogEventProperties = Record<string, ProductPropertyValue>;
|
|
574
|
+
/** Click capture input — fields mirror `POST /v1/click`. */
|
|
575
|
+
export interface RecordClickInput {
|
|
576
|
+
fbclid?: string;
|
|
577
|
+
ttclid?: string;
|
|
578
|
+
gclid?: string;
|
|
579
|
+
fbp?: string;
|
|
580
|
+
fbc?: string;
|
|
581
|
+
ttp?: string;
|
|
582
|
+
utmSource?: string;
|
|
583
|
+
utmMedium?: string;
|
|
584
|
+
utmCampaign?: string;
|
|
585
|
+
utmContent?: string;
|
|
586
|
+
utmTerm?: string;
|
|
587
|
+
campaignId?: string;
|
|
588
|
+
adsetId?: string;
|
|
589
|
+
adId?: string;
|
|
590
|
+
creativeId?: string;
|
|
591
|
+
landingUrl?: string;
|
|
592
|
+
referrer?: string;
|
|
593
|
+
locale?: string;
|
|
594
|
+
timezone?: string;
|
|
595
|
+
country?: string;
|
|
596
|
+
screenW?: number;
|
|
597
|
+
screenH?: number;
|
|
598
|
+
pixelRatio?: number;
|
|
599
|
+
osVersion?: string;
|
|
600
|
+
deviceModel?: string;
|
|
601
|
+
}
|
|
602
|
+
export interface RecordClickResult {
|
|
603
|
+
clickToken: string;
|
|
604
|
+
expiresAt: string;
|
|
605
|
+
}
|
|
606
|
+
/** Install-match input — fields mirror `POST /v1/match`. */
|
|
607
|
+
export interface MatchInstallInput {
|
|
608
|
+
userId?: string;
|
|
609
|
+
clickToken?: string;
|
|
610
|
+
locale?: string;
|
|
611
|
+
timezone?: string;
|
|
612
|
+
screenW?: number;
|
|
613
|
+
screenH?: number;
|
|
614
|
+
pixelRatio?: number;
|
|
615
|
+
osVersion?: string;
|
|
616
|
+
deviceModel?: string;
|
|
617
|
+
}
|
|
618
|
+
export interface MatchInstallResult {
|
|
619
|
+
matched: boolean;
|
|
620
|
+
matchMethod: string;
|
|
621
|
+
matchConfidence: number;
|
|
622
|
+
source: string | null;
|
|
623
|
+
campaignId: string | null;
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Install-referrer input (Android) — fields mirror `POST /v1/referrer`. Pass the
|
|
627
|
+
* raw referrer string read from the Play Install Referrer API
|
|
628
|
+
* (`com.android.installreferrer` / `react-native-play-install-referrer`).
|
|
629
|
+
*/
|
|
630
|
+
export interface InstallReferrerInput {
|
|
631
|
+
userId?: string;
|
|
632
|
+
referrer: string;
|
|
633
|
+
locale?: string;
|
|
634
|
+
timezone?: string;
|
|
635
|
+
country?: string;
|
|
636
|
+
screenW?: number;
|
|
637
|
+
screenH?: number;
|
|
638
|
+
pixelRatio?: number;
|
|
639
|
+
osVersion?: string;
|
|
640
|
+
deviceModel?: string;
|
|
641
|
+
}
|
|
642
|
+
/** Mirrors `MatchInstallResult` — the referrer match is deterministic (conf 1.0). */
|
|
643
|
+
export type InstallReferrerResult = MatchInstallResult;
|
|
644
|
+
export interface TrackStallConfig {
|
|
645
|
+
/** Tenant id assigned by TrackStall. */
|
|
646
|
+
appId: string;
|
|
647
|
+
/** Public API key (`tsk_pub_...`). Authenticates the SDK. */
|
|
648
|
+
publicKey: string;
|
|
649
|
+
/** Base URL of the TrackStall API (no trailing slash), e.g. `https://api.trackstall.io`. */
|
|
650
|
+
endpoint: string;
|
|
651
|
+
/** Runtime platform. Defaults to `'ios'` if unset and not inferable. */
|
|
652
|
+
platform?: Platform;
|
|
653
|
+
device?: DeviceContext;
|
|
654
|
+
storage?: KeyValueStorage;
|
|
655
|
+
logger?: ClientLogger;
|
|
656
|
+
/** Master kill-switch. When `false`, every call silently no-ops. */
|
|
657
|
+
enabled?: boolean;
|
|
658
|
+
/** Inject a fetch implementation (default: global `fetch`). */
|
|
659
|
+
fetchImpl?: typeof fetch;
|
|
660
|
+
/** Per-request timeout in ms. Default 8000. */
|
|
661
|
+
requestTimeoutMs?: number;
|
|
662
|
+
/** Offline buffer capacity (FIFO drop when full). Default 500. */
|
|
663
|
+
bufferCapacity?: number;
|
|
664
|
+
/** Flush batch size for `/v1/events`. Default 20. */
|
|
665
|
+
batchSize?: number;
|
|
666
|
+
retry?: RetryConfig;
|
|
667
|
+
now?: () => number;
|
|
668
|
+
/**
|
|
669
|
+
* Disable best-effort device auto-collection on `initialize()` (screen/OS/model
|
|
670
|
+
* fingerprint signals from React Native / `expo-device`). Host-supplied
|
|
671
|
+
* `config.device` values always take precedence regardless. Default false.
|
|
672
|
+
*/
|
|
673
|
+
disableAutoDeviceContext?: boolean;
|
|
674
|
+
/**
|
|
675
|
+
* Inject the native SDK modules. By default each adapter lazy-`require()`s
|
|
676
|
+
* its package (`react-native-fbsdk-next`, `@layers/expo-tiktok-business`,
|
|
677
|
+
* `expo-tracking-transparency` / `react-native-tracking-transparency`).
|
|
678
|
+
* Pass these to inject explicitly (tests, or non-standard resolution).
|
|
679
|
+
*/
|
|
680
|
+
native?: {
|
|
681
|
+
meta?: MetaSdkModule;
|
|
682
|
+
tiktok?: TikTokSdkModule;
|
|
683
|
+
att?: AttSdkModule;
|
|
684
|
+
};
|
|
685
|
+
/**
|
|
686
|
+
* Disable the `GET /v1/config` fetch and native dual-send entirely — only the
|
|
687
|
+
* backend (HTTP → CAPI/EAPI) lane runs. Use on web/server. Default false.
|
|
688
|
+
*/
|
|
689
|
+
disableNativeDualSend?: boolean;
|
|
690
|
+
/**
|
|
691
|
+
* Override the remote config (skip the `/v1/config` fetch). Tests / advanced
|
|
692
|
+
* setups that already hold the client-safe config.
|
|
693
|
+
*/
|
|
694
|
+
remoteConfig?: RemoteConfig;
|
|
695
|
+
}
|
|
696
|
+
export interface FlushResult {
|
|
697
|
+
attempted: number;
|
|
698
|
+
delivered: number;
|
|
699
|
+
retryScheduled: number;
|
|
700
|
+
dropped: number;
|
|
701
|
+
}
|
|
702
|
+
export interface ClientDiagnostics {
|
|
703
|
+
initialized: boolean;
|
|
704
|
+
enabled: boolean;
|
|
705
|
+
appId: string;
|
|
706
|
+
userId: string | null;
|
|
707
|
+
anonymousId: string | null;
|
|
708
|
+
queueSize: number;
|
|
709
|
+
analyticsQueueSize: number;
|
|
710
|
+
}
|
|
711
|
+
export interface TrackStallClient {
|
|
712
|
+
initialize(): Promise<void>;
|
|
713
|
+
setUser(identity: UserIdentity | null): void;
|
|
714
|
+
recordClick(input: RecordClickInput): Promise<RecordClickResult>;
|
|
715
|
+
matchInstall(input?: MatchInstallInput): Promise<MatchInstallResult>;
|
|
716
|
+
/**
|
|
717
|
+
* ANDROID deterministic attribution: report the Google Play Install Referrer
|
|
718
|
+
* string (read once on first launch via the Play Install Referrer API). The
|
|
719
|
+
* backend parses the ad-network click id out of it and enriches future events
|
|
720
|
+
* at confidence 1.0 — the Android equivalent of a Universal Link `clickToken`.
|
|
721
|
+
*/
|
|
722
|
+
reportInstallReferrer(input: InstallReferrerInput): Promise<InstallReferrerResult>;
|
|
723
|
+
/**
|
|
724
|
+
* ATTRIBUTION lane: enqueue a marketing event for durable delivery to the
|
|
725
|
+
* ad networks (Meta CAPI / TikTok EAPI). Returns the canonical `eventId`.
|
|
726
|
+
*/
|
|
727
|
+
track(input: TrackEventInput): Promise<string>;
|
|
728
|
+
/**
|
|
729
|
+
* PRODUCT ANALYTICS lane (Mixpanel-style): log an in-app event to the
|
|
730
|
+
* TrackStall dashboard only — never forwarded to ad networks.
|
|
731
|
+
*
|
|
732
|
+
* ts.logEvent('screen_view', { screen: 'home' });
|
|
733
|
+
*
|
|
734
|
+
* Identity is automatic: the current user's `userId` when set, otherwise a
|
|
735
|
+
* persistent device-generated anonymous id. Returns the `eventId`.
|
|
736
|
+
*/
|
|
737
|
+
logEvent(name: string, properties?: LogEventProperties, options?: LogEventOptions): Promise<string>;
|
|
738
|
+
/**
|
|
739
|
+
* Show the native ATT prompt (iOS) and report the resulting status to the
|
|
740
|
+
* TrackStall backend automatically — no extra code needed in the app.
|
|
741
|
+
* Resolves the tracking-transparency module lazily (`expo-tracking-transparency`
|
|
742
|
+
* or `react-native-tracking-transparency`); returns `'unavailable'` when the
|
|
743
|
+
* platform isn't iOS or no module is installed.
|
|
744
|
+
*/
|
|
745
|
+
requestAttPermission(): Promise<AttStatus>;
|
|
746
|
+
/**
|
|
747
|
+
* Report an ATT status obtained by the app itself (when the host app manages
|
|
748
|
+
* the prompt). Also stamps `attStatus` on subsequent attribution events.
|
|
749
|
+
*/
|
|
750
|
+
setAttStatus(status: AttStatus): Promise<void>;
|
|
751
|
+
flush(): Promise<FlushResult>;
|
|
752
|
+
getDiagnostics(): ClientDiagnostics;
|
|
753
|
+
}
|
|
754
|
+
export declare function createTrackStallClient(config: TrackStallConfig): TrackStallClient;
|
|
755
|
+
/**
|
|
756
|
+
* HTTP transport for the TrackStall API. Adds the public-key auth header,
|
|
757
|
+
* enforces a per-request timeout, and classifies the response so the queue
|
|
758
|
+
* knows whether to retry (5xx / 408 / 429 / network) or drop (4xx schema/auth).
|
|
759
|
+
*/
|
|
760
|
+
export interface TransportResponse {
|
|
761
|
+
ok: boolean;
|
|
762
|
+
status: number;
|
|
763
|
+
body: unknown;
|
|
764
|
+
retriable: boolean;
|
|
765
|
+
errorMessage?: string;
|
|
766
|
+
}
|
|
767
|
+
export interface TransportOptions {
|
|
768
|
+
endpoint: string;
|
|
769
|
+
publicKey: string;
|
|
770
|
+
fetchImpl?: typeof fetch;
|
|
771
|
+
timeoutMs?: number;
|
|
772
|
+
}
|
|
773
|
+
export declare class Transport {
|
|
774
|
+
private readonly endpoint;
|
|
775
|
+
private readonly publicKey;
|
|
776
|
+
private readonly fetchImpl;
|
|
777
|
+
private readonly timeoutMs;
|
|
778
|
+
constructor(options: TransportOptions);
|
|
779
|
+
get(path: string): Promise<TransportResponse>;
|
|
780
|
+
post(path: string, body: unknown): Promise<TransportResponse>;
|
|
781
|
+
private send;
|
|
782
|
+
}
|
|
783
|
+
export declare function isRetriableStatus(status: number): boolean;
|
|
784
|
+
export interface QueuedEvent {
|
|
785
|
+
/** Local queue id (not the attribution eventId). */
|
|
786
|
+
id: string;
|
|
787
|
+
/** Server dedup id — also used to match per-event results on flush. */
|
|
788
|
+
eventId: string;
|
|
789
|
+
/** The wire body posted inside `{ events: [...] }`. */
|
|
790
|
+
body: Record<string, unknown>;
|
|
791
|
+
attempts: number;
|
|
792
|
+
nextRetryAt: number;
|
|
793
|
+
createdAt: number;
|
|
794
|
+
}
|
|
795
|
+
export interface EventQueueOptions {
|
|
796
|
+
storage: KeyValueStorage;
|
|
797
|
+
logger: ClientLogger;
|
|
798
|
+
capacity?: number;
|
|
799
|
+
storageKey?: string;
|
|
800
|
+
now?: () => number;
|
|
801
|
+
}
|
|
802
|
+
export declare class EventQueue {
|
|
803
|
+
private readonly storage;
|
|
804
|
+
private readonly logger;
|
|
805
|
+
private readonly capacity;
|
|
806
|
+
private readonly storageKey;
|
|
807
|
+
private readonly now;
|
|
808
|
+
private entries;
|
|
809
|
+
private hydrated;
|
|
810
|
+
private counter;
|
|
811
|
+
private chain;
|
|
812
|
+
constructor(options: EventQueueOptions);
|
|
813
|
+
hydrate(): Promise<void>;
|
|
814
|
+
size(): number;
|
|
815
|
+
enqueue(eventId: string, body: Record<string, unknown>): Promise<void>;
|
|
816
|
+
/** Snapshot of entries eligible to send now (does not mutate). */
|
|
817
|
+
pullReady(limit: number): QueuedEvent[];
|
|
818
|
+
markDelivered(ids: string[]): Promise<void>;
|
|
819
|
+
markFailed(ids: string[], nextRetryAt: number): Promise<void>;
|
|
820
|
+
clear(): Promise<void>;
|
|
821
|
+
private persist;
|
|
822
|
+
private serialize;
|
|
823
|
+
}
|
|
824
|
+
/** In-memory storage. Default when no persistence is provided — the offline
|
|
825
|
+
* buffer is then lost across app launches (fine for web sessions / tests). */
|
|
826
|
+
export declare class MemoryStorage implements KeyValueStorage {
|
|
827
|
+
private readonly map;
|
|
828
|
+
getItem(key: string): Promise<string | null>;
|
|
829
|
+
setItem(key: string, value: string): Promise<void>;
|
|
830
|
+
removeItem(key: string): Promise<void>;
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Adapts a synchronous Web Storage (`localStorage`) to the async contract.
|
|
834
|
+
* Returns a `MemoryStorage` when no Web Storage is available (RN, SSR, Node).
|
|
835
|
+
*/
|
|
836
|
+
export declare function defaultStorage(): KeyValueStorage;
|
|
837
|
+
/**
|
|
838
|
+
* Collect whatever device signals are available without any user permission.
|
|
839
|
+
* Returns a partial `DeviceContext`; missing fields are simply omitted.
|
|
840
|
+
*/
|
|
841
|
+
export declare function collectDeviceContext(): Partial<DeviceContext>;
|
|
842
|
+
|
|
843
|
+
export {};
|