@axyle/expo-sdk 1.0.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.
Files changed (43) hide show
  1. package/CONFIG.md +117 -0
  2. package/README.md +534 -0
  3. package/dist/client.d.ts +93 -0
  4. package/dist/client.js +416 -0
  5. package/dist/config.example.d.ts +8 -0
  6. package/dist/config.example.js +13 -0
  7. package/dist/configLoader.d.ts +10 -0
  8. package/dist/configLoader.js +22 -0
  9. package/dist/constants.d.ts +38 -0
  10. package/dist/constants.js +42 -0
  11. package/dist/context.d.ts +36 -0
  12. package/dist/context.js +216 -0
  13. package/dist/core.d.ts +9 -0
  14. package/dist/core.js +45 -0
  15. package/dist/hooks/useFeatureTracking.d.ts +34 -0
  16. package/dist/hooks/useFeatureTracking.js +60 -0
  17. package/dist/hooks/useOnboardingTracking.d.ts +85 -0
  18. package/dist/hooks/useOnboardingTracking.js +172 -0
  19. package/dist/hooks/useScreenTracking.d.ts +23 -0
  20. package/dist/hooks/useScreenTracking.js +52 -0
  21. package/dist/hooks/useScrollTracking.d.ts +39 -0
  22. package/dist/hooks/useScrollTracking.js +146 -0
  23. package/dist/index.d.ts +140 -0
  24. package/dist/index.js +171 -0
  25. package/dist/integrations/expoRouter.d.ts +42 -0
  26. package/dist/integrations/expoRouter.js +66 -0
  27. package/dist/integrations/reactNavigation.d.ts +27 -0
  28. package/dist/integrations/reactNavigation.js +101 -0
  29. package/dist/queue.d.ts +52 -0
  30. package/dist/queue.js +143 -0
  31. package/dist/session.d.ts +44 -0
  32. package/dist/session.js +139 -0
  33. package/dist/sessionAnalytics.d.ts +43 -0
  34. package/dist/sessionAnalytics.js +74 -0
  35. package/dist/storage.d.ts +67 -0
  36. package/dist/storage.js +210 -0
  37. package/dist/transport.d.ts +41 -0
  38. package/dist/transport.js +158 -0
  39. package/dist/types.d.ts +102 -0
  40. package/dist/types.js +5 -0
  41. package/dist/utils.d.ts +39 -0
  42. package/dist/utils.js +116 -0
  43. package/package.json +44 -0
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Main Axyle client
3
+ * Public API surface for the SDK
4
+ */
5
+ import { SessionAnalyticsStats } from "./sessionAnalytics";
6
+ import { AnalyticsEvent, AxyleInitConfig, EventProperties, UserTraits } from "./types";
7
+ export declare class AxyleClient {
8
+ private config;
9
+ private logger;
10
+ private sessionManager;
11
+ private sessionAnalytics;
12
+ private transport;
13
+ private queue;
14
+ private anonymousId;
15
+ private userId;
16
+ private _isInitialized;
17
+ private isOptedOut;
18
+ private appStateSubscription;
19
+ /**
20
+ * Check if SDK is initialized (public getter)
21
+ */
22
+ get isInitialized(): boolean;
23
+ constructor();
24
+ /**
25
+ * Initialize the SDK
26
+ * Only accepts API key - all other settings use defaults
27
+ */
28
+ init(config: AxyleInitConfig): Promise<void>;
29
+ /**
30
+ * Track a custom event
31
+ */
32
+ track(eventName: string, properties?: EventProperties): Promise<void>;
33
+ /**
34
+ * Identify a user
35
+ */
36
+ identify(userId: string, traits?: UserTraits): Promise<void>;
37
+ /**
38
+ * Reset user data (logout)
39
+ */
40
+ reset(): Promise<void>;
41
+ /**
42
+ * Opt out of tracking
43
+ */
44
+ optOut(): Promise<void>;
45
+ /**
46
+ * Opt back in to tracking
47
+ */
48
+ optIn(): Promise<void>;
49
+ /**
50
+ * Delete user data
51
+ */
52
+ deleteUser(userId: string): Promise<void>;
53
+ /**
54
+ * Get session analytics statistics
55
+ */
56
+ getSessionStats(): SessionAnalyticsStats | null;
57
+ /**
58
+ * Get all events in current session
59
+ */
60
+ getSessionEvents(): AnalyticsEvent[];
61
+ /**
62
+ * Get events by type in current session
63
+ */
64
+ getEventsByType(eventName: string): AnalyticsEvent[];
65
+ /**
66
+ * Create an event object
67
+ */
68
+ private createEvent;
69
+ /**
70
+ * Track an auto event
71
+ */
72
+ private trackAutoEvent;
73
+ /**
74
+ * Handle session start
75
+ */
76
+ private handleSessionStart;
77
+ /**
78
+ * Handle session end
79
+ */
80
+ private handleSessionEnd;
81
+ /**
82
+ * Set up app state listener for background/foreground tracking
83
+ */
84
+ private setupAppStateListener;
85
+ /**
86
+ * Manually flush all queued events to the server
87
+ */
88
+ flush(): Promise<void>;
89
+ /**
90
+ * Cleanup resources
91
+ */
92
+ shutdown(): Promise<void>;
93
+ }
package/dist/client.js ADDED
@@ -0,0 +1,416 @@
1
+ "use strict";
2
+ /**
3
+ * Main Axyle client
4
+ * Public API surface for the SDK
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.AxyleClient = void 0;
8
+ const react_native_1 = require("react-native");
9
+ const constants_1 = require("./constants");
10
+ const context_1 = require("./context");
11
+ const queue_1 = require("./queue");
12
+ const session_1 = require("./session");
13
+ const sessionAnalytics_1 = require("./sessionAnalytics");
14
+ const storage_1 = require("./storage");
15
+ const transport_1 = require("./transport");
16
+ const utils_1 = require("./utils");
17
+ class AxyleClient {
18
+ /**
19
+ * Check if SDK is initialized (public getter)
20
+ */
21
+ get isInitialized() {
22
+ return this._isInitialized;
23
+ }
24
+ constructor() {
25
+ this.sessionAnalytics = null;
26
+ this.transport = null;
27
+ this.queue = null;
28
+ this.anonymousId = "";
29
+ this.userId = null;
30
+ this._isInitialized = false;
31
+ this.isOptedOut = false;
32
+ this.appStateSubscription = null;
33
+ // Initialize with defaults, will be overridden in init()
34
+ this.config = {
35
+ apiKey: "",
36
+ environment: constants_1.DEFAULT_CONFIG.environment,
37
+ baseUrl: constants_1.DEFAULT_CONFIG.baseUrl,
38
+ debug: constants_1.DEFAULT_CONFIG.debug,
39
+ maxQueueSize: constants_1.DEFAULT_CONFIG.maxQueueSize,
40
+ flushInterval: constants_1.DEFAULT_CONFIG.flushInterval,
41
+ sessionTimeout: constants_1.DEFAULT_CONFIG.sessionTimeout,
42
+ userId: "",
43
+ };
44
+ this.logger = (0, utils_1.createLogger)(this.config.debug);
45
+ this.sessionManager = new session_1.SessionManager(this.config.sessionTimeout, this.logger, {
46
+ onSessionStart: (sessionId) => this.handleSessionStart(sessionId),
47
+ onSessionEnd: (sessionId, duration) => this.handleSessionEnd(sessionId, duration),
48
+ });
49
+ }
50
+ /**
51
+ * Initialize the SDK
52
+ * Only accepts API key - all other settings use defaults
53
+ */
54
+ async init(config) {
55
+ try {
56
+ // Extract API key from string or object
57
+ const apiKey = typeof config === "string" ? config : config.apiKey;
58
+ if (!apiKey) {
59
+ this.logger.warn("API key is required for SDK initialization");
60
+ }
61
+ // Use defaults for all settings - only API key is configurable
62
+ this.config = {
63
+ apiKey: apiKey || "",
64
+ userId: "",
65
+ environment: constants_1.DEFAULT_CONFIG.environment,
66
+ debug: constants_1.DEFAULT_CONFIG.debug,
67
+ maxQueueSize: constants_1.DEFAULT_CONFIG.maxQueueSize,
68
+ flushInterval: constants_1.DEFAULT_CONFIG.flushInterval,
69
+ sessionTimeout: constants_1.DEFAULT_CONFIG.sessionTimeout,
70
+ baseUrl: constants_1.DEFAULT_CONFIG.baseUrl, // Always use production URL
71
+ };
72
+ // Update logger
73
+ this.logger = (0, utils_1.createLogger)(this.config.debug);
74
+ // Check opt-out status
75
+ this.isOptedOut = await storage_1.Storage.isOptedOut();
76
+ if (this.isOptedOut) {
77
+ this.logger.log("User has opted out, analytics disabled");
78
+ this._isInitialized = true; // Set initialized even if opted out
79
+ return;
80
+ }
81
+ // Load anonymous ID
82
+ this.anonymousId = await storage_1.Storage.getAnonymousId();
83
+ // Load user ID from storage (not configurable at init)
84
+ this.userId = await storage_1.Storage.getUserId();
85
+ // Initialize session manager
86
+ this.sessionManager = new session_1.SessionManager(this.config.sessionTimeout, this.logger, {
87
+ onSessionStart: (sessionId) => this.handleSessionStart(sessionId),
88
+ onSessionEnd: (sessionId, duration) => this.handleSessionEnd(sessionId, duration),
89
+ });
90
+ await this.sessionManager.initialize();
91
+ // Initialize session analytics with current session start time
92
+ const sessionId = this.sessionManager.getSessionId();
93
+ if (sessionId) {
94
+ // Use current time as session start time
95
+ this.sessionAnalytics = new sessionAnalytics_1.SessionAnalytics(Date.now());
96
+ }
97
+ // Initialize transport and queue if API key is provided
98
+ if (this.config.apiKey) {
99
+ this.transport = new transport_1.Transport({
100
+ apiKey: this.config.apiKey,
101
+ baseUrl: this.config.baseUrl,
102
+ debug: this.config.debug,
103
+ }, this.logger);
104
+ this.queue = new queue_1.EventQueue({
105
+ maxQueueSize: this.config.maxQueueSize,
106
+ flushInterval: this.config.flushInterval,
107
+ }, this.transport, this.logger);
108
+ // Initialize queue (starts flush timer)
109
+ await this.queue.initialize();
110
+ this.logger.log("Event queue initialized");
111
+ }
112
+ else {
113
+ this.logger.log("No API key provided, events will only be tracked locally");
114
+ }
115
+ // Set initialized BEFORE tracking auto events
116
+ this._isInitialized = true;
117
+ this.logger.log("Axyle initialized successfully");
118
+ // Track app opened (after setting initialized flag)
119
+ await this.trackAutoEvent(constants_1.AUTO_TRACKED_EVENTS.APP_OPENED);
120
+ // Set up app state listener
121
+ this.setupAppStateListener();
122
+ }
123
+ catch (error) {
124
+ this.logger.error("Failed to initialize Axyle:", error);
125
+ this.logger.error("Error details:", error);
126
+ // Set initialized anyway to prevent infinite waiting
127
+ this._isInitialized = true;
128
+ // Fail silently - don't throw
129
+ }
130
+ }
131
+ /**
132
+ * Track a custom event
133
+ */
134
+ async track(eventName, properties = {}) {
135
+ try {
136
+ // Check if initialized and not opted out
137
+ if (!this._isInitialized) {
138
+ this.logger.warn("SDK not initialized, call init() first");
139
+ return;
140
+ }
141
+ if (this.isOptedOut) {
142
+ return;
143
+ }
144
+ // Validate event name
145
+ if (!(0, utils_1.isValidEventName)(eventName)) {
146
+ this.logger.error("Invalid event name:", eventName);
147
+ return;
148
+ }
149
+ // Update session activity
150
+ await this.sessionManager.updateActivity();
151
+ // Create event
152
+ const event = await this.createEvent(eventName, properties);
153
+ // Validate event size
154
+ if ((0, utils_1.getObjectSize)(event) > constants_1.MAX_EVENT_SIZE) {
155
+ this.logger.error("Event size exceeds limit:", eventName);
156
+ return;
157
+ }
158
+ // Add to session analytics (local counting)
159
+ if (this.sessionAnalytics) {
160
+ this.sessionAnalytics.addEvent(event);
161
+ this.logger.log(`Event tracked locally: ${eventName}`);
162
+ }
163
+ // Queue event for sending to API (if queue is initialized)
164
+ if (this.queue) {
165
+ await this.queue.enqueue(event);
166
+ }
167
+ }
168
+ catch (error) {
169
+ this.logger.error("Failed to track event:", error);
170
+ // Fail silently
171
+ }
172
+ }
173
+ /**
174
+ * Identify a user
175
+ */
176
+ async identify(userId, traits = {}) {
177
+ try {
178
+ if (!this._isInitialized || this.isOptedOut) {
179
+ return;
180
+ }
181
+ // Capture previous user ID before updating
182
+ const previousUserId = this.userId;
183
+ // Store new user ID
184
+ this.userId = userId;
185
+ await storage_1.Storage.setUserId(userId);
186
+ // Track identify event with traits
187
+ await this.track("User Identified", {
188
+ ...traits,
189
+ previousUserId: previousUserId || this.anonymousId,
190
+ });
191
+ this.logger.log("User identified:", userId);
192
+ }
193
+ catch (error) {
194
+ this.logger.error("Failed to identify user:", error);
195
+ }
196
+ }
197
+ /**
198
+ * Reset user data (logout)
199
+ */
200
+ async reset() {
201
+ try {
202
+ if (!this._isInitialized) {
203
+ return;
204
+ }
205
+ // Clear user ID
206
+ this.userId = null;
207
+ await storage_1.Storage.clearUserId();
208
+ // Reset session
209
+ await this.sessionManager.reset();
210
+ this.logger.log("User data reset");
211
+ }
212
+ catch (error) {
213
+ this.logger.error("Failed to reset:", error);
214
+ }
215
+ }
216
+ /**
217
+ * Opt out of tracking
218
+ */
219
+ async optOut() {
220
+ try {
221
+ this.isOptedOut = true;
222
+ await storage_1.Storage.setOptOut(true);
223
+ // Clear session analytics
224
+ if (this.sessionAnalytics) {
225
+ this.sessionAnalytics.clear();
226
+ }
227
+ this.logger.log("User opted out");
228
+ }
229
+ catch (error) {
230
+ this.logger.error("Failed to opt out:", error);
231
+ }
232
+ }
233
+ /**
234
+ * Opt back in to tracking
235
+ */
236
+ async optIn() {
237
+ try {
238
+ this.isOptedOut = false;
239
+ await storage_1.Storage.setOptOut(false);
240
+ // Reinitialize session if it was cleared during opt-out
241
+ if (!this.sessionManager || !this.sessionManager.getSessionId()) {
242
+ this.sessionManager = new session_1.SessionManager(this.config.sessionTimeout, this.logger, {
243
+ onSessionStart: (sessionId) => this.handleSessionStart(sessionId),
244
+ onSessionEnd: (sessionId, duration) => this.handleSessionEnd(sessionId, duration),
245
+ });
246
+ await this.sessionManager.initialize();
247
+ // Reinitialize session analytics
248
+ const sessionId = this.sessionManager.getSessionId();
249
+ if (sessionId) {
250
+ this.sessionAnalytics = new sessionAnalytics_1.SessionAnalytics(Date.now());
251
+ }
252
+ }
253
+ this.logger.log("User opted in");
254
+ }
255
+ catch (error) {
256
+ this.logger.error("Failed to opt in:", error);
257
+ }
258
+ }
259
+ /**
260
+ * Delete user data
261
+ */
262
+ async deleteUser(userId) {
263
+ try {
264
+ // Track deletion request
265
+ await this.track("User Deletion Requested", { userId });
266
+ // Clear session analytics
267
+ if (this.sessionAnalytics) {
268
+ this.sessionAnalytics.clear();
269
+ }
270
+ // Clear local data
271
+ await storage_1.Storage.clearAll();
272
+ this.logger.log("User deletion requested:", userId);
273
+ }
274
+ catch (error) {
275
+ this.logger.error("Failed to delete user:", error);
276
+ }
277
+ }
278
+ /**
279
+ * Get session analytics statistics
280
+ */
281
+ getSessionStats() {
282
+ if (!this.sessionAnalytics) {
283
+ return null;
284
+ }
285
+ return this.sessionAnalytics.getStats();
286
+ }
287
+ /**
288
+ * Get all events in current session
289
+ */
290
+ getSessionEvents() {
291
+ if (!this.sessionAnalytics) {
292
+ return [];
293
+ }
294
+ return this.sessionAnalytics.getEvents();
295
+ }
296
+ /**
297
+ * Get events by type in current session
298
+ */
299
+ getEventsByType(eventName) {
300
+ if (!this.sessionAnalytics) {
301
+ return [];
302
+ }
303
+ return this.sessionAnalytics.getEventsByType(eventName);
304
+ }
305
+ /**
306
+ * Create an event object
307
+ */
308
+ async createEvent(name, properties) {
309
+ const context = await context_1.ContextCollector.getContext(this.config.environment);
310
+ // Get session ID, fallback to generating a temporary one if not available
311
+ let sessionId = this.sessionManager?.getSessionId();
312
+ if (!sessionId) {
313
+ sessionId = `temp_session_${Date.now()}`;
314
+ this.logger.warn("Session not initialized, using temporary session ID");
315
+ }
316
+ return {
317
+ id: (0, utils_1.generateUUID)(),
318
+ name,
319
+ properties: (0, utils_1.sanitizeProperties)(properties),
320
+ timestamp: Date.now(),
321
+ userId: this.userId || this.anonymousId,
322
+ anonymousId: this.anonymousId,
323
+ sessionId,
324
+ context,
325
+ schemaVersion: constants_1.SCHEMA_VERSION,
326
+ };
327
+ }
328
+ /**
329
+ * Track an auto event
330
+ */
331
+ async trackAutoEvent(eventName, properties = {}) {
332
+ await this.track(eventName, properties);
333
+ }
334
+ /**
335
+ * Handle session start
336
+ */
337
+ handleSessionStart(sessionId) {
338
+ // Initialize or reset session analytics for new session
339
+ const sessionStartTime = Date.now();
340
+ if (this.sessionAnalytics) {
341
+ this.sessionAnalytics.resetSession(sessionStartTime);
342
+ }
343
+ else {
344
+ this.sessionAnalytics = new sessionAnalytics_1.SessionAnalytics(sessionStartTime);
345
+ }
346
+ this.trackAutoEvent(constants_1.AUTO_TRACKED_EVENTS.SESSION_STARTED, { sessionId });
347
+ }
348
+ /**
349
+ * Handle session end
350
+ */
351
+ handleSessionEnd(sessionId, duration) {
352
+ this.trackAutoEvent(constants_1.AUTO_TRACKED_EVENTS.SESSION_ENDED, {
353
+ sessionId,
354
+ duration,
355
+ });
356
+ }
357
+ /**
358
+ * Set up app state listener for background/foreground tracking
359
+ */
360
+ setupAppStateListener() {
361
+ let previousState = react_native_1.AppState.currentState;
362
+ this.appStateSubscription = react_native_1.AppState.addEventListener("change", (nextState) => {
363
+ if (previousState === "active" &&
364
+ nextState.match(/inactive|background/)) {
365
+ // App went to background
366
+ this.trackAutoEvent(constants_1.AUTO_TRACKED_EVENTS.APP_BACKGROUNDED);
367
+ }
368
+ else if (previousState.match(/inactive|background/) &&
369
+ nextState === "active") {
370
+ // App came to foreground
371
+ this.trackAutoEvent(constants_1.AUTO_TRACKED_EVENTS.APP_FOREGROUNDED);
372
+ this.sessionManager.updateActivity(); // Update session
373
+ }
374
+ previousState = nextState;
375
+ });
376
+ }
377
+ /**
378
+ * Manually flush all queued events to the server
379
+ */
380
+ async flush() {
381
+ try {
382
+ if (!this._isInitialized) {
383
+ this.logger.warn("SDK not initialized, cannot flush");
384
+ return;
385
+ }
386
+ if (this.queue) {
387
+ await this.queue.flush();
388
+ this.logger.log("Events flushed successfully");
389
+ }
390
+ }
391
+ catch (error) {
392
+ this.logger.error("Failed to flush events:", error);
393
+ }
394
+ }
395
+ /**
396
+ * Cleanup resources
397
+ */
398
+ async shutdown() {
399
+ try {
400
+ // Remove app state listener
401
+ if (this.appStateSubscription) {
402
+ this.appStateSubscription.remove();
403
+ }
404
+ // Shutdown queue (flushes remaining events)
405
+ if (this.queue) {
406
+ await this.queue.shutdown();
407
+ }
408
+ this._isInitialized = false;
409
+ this.logger.log("Axyle shut down");
410
+ }
411
+ catch (error) {
412
+ this.logger.error("Error during shutdown:", error);
413
+ }
414
+ }
415
+ }
416
+ exports.AxyleClient = AxyleClient;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Sample Configuration File (Deprecated)
3
+ *
4
+ * NOTE: This file is kept for reference but is no longer used.
5
+ * The SDK now only accepts an API key during initialization.
6
+ *
7
+ * Use Axyle.init('your-api-key') instead.
8
+ */
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * Sample Configuration File (Deprecated)
4
+ *
5
+ * NOTE: This file is kept for reference but is no longer used.
6
+ * The SDK now only accepts an API key during initialization.
7
+ *
8
+ * Use Axyle.init('your-api-key') instead.
9
+ */
10
+ // This file is deprecated - SDK now only accepts API key
11
+ // Example usage:
12
+ // import { Axyle } from '@axyle/expo-sdk';
13
+ // Axyle.init('your-api-key');
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Configuration Loader
3
+ *
4
+ * Handles API key validation for the SDK.
5
+ */
6
+ /**
7
+ * Validate API key format
8
+ * Adjust the regex pattern based on your platform's API key format
9
+ */
10
+ export declare function isValidApiKeyFormat(apiKey: string): boolean;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * Configuration Loader
4
+ *
5
+ * Handles API key validation for the SDK.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.isValidApiKeyFormat = isValidApiKeyFormat;
9
+ /**
10
+ * Validate API key format
11
+ * Adjust the regex pattern based on your platform's API key format
12
+ */
13
+ function isValidApiKeyFormat(apiKey) {
14
+ if (!apiKey || typeof apiKey !== "string") {
15
+ return false;
16
+ }
17
+ // UUID format: 550e8400-e29b-41d4-a716-446655440000
18
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
19
+ // Alphanumeric with dashes/underscores: at least 32 characters
20
+ const alphanumericRegex = /^[a-zA-Z0-9_-]{32,}$/;
21
+ return uuidRegex.test(apiKey) || alphanumericRegex.test(apiKey);
22
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Constants used throughout the SDK
3
+ */
4
+ export declare const STORAGE_PREFIX = "@axyle";
5
+ export declare const STORAGE_KEYS: {
6
+ EVENTS_QUEUE: string;
7
+ ANONYMOUS_ID: string;
8
+ USER_ID: string;
9
+ SESSION_DATA: string;
10
+ OPT_OUT: string;
11
+ };
12
+ export declare const PRODUCTION_BASE_URL = "https://axyle-server-production.up.railway.app";
13
+ export declare const DEFAULT_CONFIG: {
14
+ baseUrl: string;
15
+ debug: boolean;
16
+ maxQueueSize: number;
17
+ flushInterval: number;
18
+ sessionTimeout: number;
19
+ environment: "prod";
20
+ };
21
+ export declare const SCHEMA_VERSION = "1.0.0";
22
+ export declare const MAX_EVENT_SIZE: number;
23
+ export declare const MAX_BATCH_SIZE: number;
24
+ export declare const MAX_EVENTS_PER_BATCH = 100;
25
+ export declare const RETRY_CONFIG: {
26
+ maxRetries: number;
27
+ initialDelay: number;
28
+ maxDelay: number;
29
+ backoffMultiplier: number;
30
+ };
31
+ export declare const AUTO_TRACKED_EVENTS: {
32
+ APP_OPENED: string;
33
+ APP_BACKGROUNDED: string;
34
+ APP_FOREGROUNDED: string;
35
+ SESSION_STARTED: string;
36
+ SESSION_ENDED: string;
37
+ SCREEN_VIEWED: string;
38
+ };
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * Constants used throughout the SDK
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AUTO_TRACKED_EVENTS = exports.RETRY_CONFIG = exports.MAX_EVENTS_PER_BATCH = exports.MAX_BATCH_SIZE = exports.MAX_EVENT_SIZE = exports.SCHEMA_VERSION = exports.DEFAULT_CONFIG = exports.PRODUCTION_BASE_URL = exports.STORAGE_KEYS = exports.STORAGE_PREFIX = void 0;
7
+ exports.STORAGE_PREFIX = "@axyle";
8
+ exports.STORAGE_KEYS = {
9
+ EVENTS_QUEUE: `${exports.STORAGE_PREFIX}/events-queue`,
10
+ ANONYMOUS_ID: `${exports.STORAGE_PREFIX}/anonymous-id`,
11
+ USER_ID: `${exports.STORAGE_PREFIX}/user-id`,
12
+ SESSION_DATA: `${exports.STORAGE_PREFIX}/session-data`,
13
+ OPT_OUT: `${exports.STORAGE_PREFIX}/opt-out`,
14
+ };
15
+ // Production server URL - not configurable by users
16
+ exports.PRODUCTION_BASE_URL = "https://axyle-server-production.up.railway.app";
17
+ exports.DEFAULT_CONFIG = {
18
+ baseUrl: exports.PRODUCTION_BASE_URL,
19
+ debug: false,
20
+ maxQueueSize: 100,
21
+ flushInterval: 10000, // 10 seconds
22
+ sessionTimeout: 30 * 60 * 1000, // 30 minutes
23
+ environment: "prod",
24
+ };
25
+ exports.SCHEMA_VERSION = "1.0.0";
26
+ exports.MAX_EVENT_SIZE = 32 * 1024; // 32KB per event
27
+ exports.MAX_BATCH_SIZE = 500 * 1024; // 500KB per batch
28
+ exports.MAX_EVENTS_PER_BATCH = 100;
29
+ exports.RETRY_CONFIG = {
30
+ maxRetries: 3,
31
+ initialDelay: 1000, // 1 second
32
+ maxDelay: 32000, // 32 seconds
33
+ backoffMultiplier: 2,
34
+ };
35
+ exports.AUTO_TRACKED_EVENTS = {
36
+ APP_OPENED: "App Opened",
37
+ APP_BACKGROUNDED: "App Backgrounded",
38
+ APP_FOREGROUNDED: "App Foregrounded",
39
+ SESSION_STARTED: "Session Started",
40
+ SESSION_ENDED: "Session Ended",
41
+ SCREEN_VIEWED: "Screen Viewed",
42
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Device and app context collection using Expo APIs
3
+ */
4
+ import { EventContext } from "./types";
5
+ export declare class ContextCollector {
6
+ private static cachedContext;
7
+ /**
8
+ * Get device and app context
9
+ * Caches result for performance
10
+ */
11
+ static getContext(environment: "dev" | "prod"): Promise<EventContext>;
12
+ /**
13
+ * Get device ID (may be null on some platforms)
14
+ */
15
+ private static getDeviceId;
16
+ /**
17
+ * Determine device type
18
+ */
19
+ private static getDeviceType;
20
+ /**
21
+ * Get device locale
22
+ */
23
+ private static getLocale;
24
+ /**
25
+ * Get device timezone
26
+ */
27
+ private static getTimezone;
28
+ /**
29
+ * Get minimal context as fallback
30
+ */
31
+ private static getMinimalContext;
32
+ /**
33
+ * Clear cached context (useful for testing or when app info changes)
34
+ */
35
+ static clearCache(): void;
36
+ }