@grainql/analytics-web 1.7.2 → 2.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.
- package/README.md +71 -777
- package/dist/cjs/index.d.ts +35 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/react/GrainProvider.d.ts +11 -0
- package/dist/cjs/react/GrainProvider.d.ts.map +1 -0
- package/dist/cjs/react/GrainProvider.js +79 -0
- package/dist/cjs/react/GrainProvider.js.map +1 -0
- package/dist/cjs/react/context.d.ts +11 -0
- package/dist/cjs/react/context.d.ts.map +1 -0
- package/dist/cjs/react/context.js +43 -0
- package/dist/cjs/react/context.js.map +1 -0
- package/dist/cjs/react/hooks/useAllConfigs.d.ts +8 -0
- package/dist/cjs/react/hooks/useAllConfigs.d.ts.map +1 -0
- package/dist/cjs/react/hooks/useAllConfigs.js +112 -0
- package/dist/cjs/react/hooks/useAllConfigs.js.map +1 -0
- package/dist/cjs/react/hooks/useConfig.d.ts +9 -0
- package/dist/cjs/react/hooks/useConfig.d.ts.map +1 -0
- package/dist/cjs/react/hooks/useConfig.js +116 -0
- package/dist/cjs/react/hooks/useConfig.js.map +1 -0
- package/dist/cjs/react/hooks/useGrainAnalytics.d.ts +6 -0
- package/dist/cjs/react/hooks/useGrainAnalytics.d.ts.map +1 -0
- package/dist/cjs/react/hooks/useGrainAnalytics.js +50 -0
- package/dist/cjs/react/hooks/useGrainAnalytics.js.map +1 -0
- package/dist/cjs/react/hooks/useTrack.d.ts +9 -0
- package/dist/cjs/react/hooks/useTrack.d.ts.map +1 -0
- package/dist/cjs/react/hooks/useTrack.js +53 -0
- package/dist/cjs/react/hooks/useTrack.js.map +1 -0
- package/dist/cjs/react/index.d.ts +36 -0
- package/dist/cjs/react/index.d.ts.map +1 -0
- package/dist/cjs/react/index.js +45 -0
- package/dist/cjs/react/index.js.map +1 -0
- package/dist/cjs/react/types.d.ts +33 -0
- package/dist/cjs/react/types.d.ts.map +1 -0
- package/dist/cjs/react/types.js +6 -0
- package/dist/cjs/react/types.js.map +1 -0
- package/dist/esm/index.d.ts +35 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/GrainProvider.d.ts +11 -0
- package/dist/esm/react/GrainProvider.d.ts.map +1 -0
- package/dist/esm/react/GrainProvider.js +43 -0
- package/dist/esm/react/GrainProvider.js.map +1 -0
- package/dist/esm/react/context.d.ts +11 -0
- package/dist/esm/react/context.d.ts.map +1 -0
- package/dist/esm/react/context.js +7 -0
- package/dist/esm/react/context.js.map +1 -0
- package/dist/esm/react/hooks/useAllConfigs.d.ts +8 -0
- package/dist/esm/react/hooks/useAllConfigs.d.ts.map +1 -0
- package/dist/esm/react/hooks/useAllConfigs.js +76 -0
- package/dist/esm/react/hooks/useAllConfigs.js.map +1 -0
- package/dist/esm/react/hooks/useConfig.d.ts +9 -0
- package/dist/esm/react/hooks/useConfig.d.ts.map +1 -0
- package/dist/esm/react/hooks/useConfig.js +80 -0
- package/dist/esm/react/hooks/useConfig.js.map +1 -0
- package/dist/esm/react/hooks/useGrainAnalytics.d.ts +6 -0
- package/dist/esm/react/hooks/useGrainAnalytics.d.ts.map +1 -0
- package/dist/esm/react/hooks/useGrainAnalytics.js +14 -0
- package/dist/esm/react/hooks/useGrainAnalytics.js.map +1 -0
- package/dist/esm/react/hooks/useTrack.d.ts +9 -0
- package/dist/esm/react/hooks/useTrack.d.ts.map +1 -0
- package/dist/esm/react/hooks/useTrack.js +17 -0
- package/dist/esm/react/hooks/useTrack.js.map +1 -0
- package/dist/esm/react/index.d.ts +36 -0
- package/dist/esm/react/index.d.ts.map +1 -0
- package/dist/esm/react/index.js +37 -0
- package/dist/esm/react/index.js.map +1 -0
- package/dist/esm/react/types.d.ts +33 -0
- package/dist/esm/react/types.d.ts.map +1 -0
- package/dist/esm/react/types.js +5 -0
- package/dist/esm/react/types.js.map +1 -0
- package/dist/index.d.ts +35 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +124 -14
- package/dist/index.global.dev.js.map +2 -2
- package/dist/index.global.js +2 -2
- package/dist/index.global.js.map +3 -3
- package/dist/index.js +147 -15
- package/dist/index.mjs +147 -15
- package/dist/react/index.d.ts +405 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +1181 -0
- package/dist/react/index.mjs +1176 -0
- package/dist/react/react/GrainProvider.d.ts +11 -0
- package/dist/react/react/GrainProvider.d.ts.map +1 -0
- package/dist/react/react/GrainProvider.js +45 -0
- package/dist/react/react/GrainProvider.mjs +42 -0
- package/dist/react/react/context.d.ts +11 -0
- package/dist/react/react/context.d.ts.map +1 -0
- package/dist/react/react/context.js +9 -0
- package/dist/react/react/context.mjs +6 -0
- package/dist/react/react/hooks/useAllConfigs.d.ts +8 -0
- package/dist/react/react/hooks/useAllConfigs.d.ts.map +1 -0
- package/dist/react/react/hooks/useAllConfigs.js +78 -0
- package/dist/react/react/hooks/useAllConfigs.mjs +75 -0
- package/dist/react/react/hooks/useConfig.d.ts +9 -0
- package/dist/react/react/hooks/useConfig.d.ts.map +1 -0
- package/dist/react/react/hooks/useConfig.js +82 -0
- package/dist/react/react/hooks/useConfig.mjs +79 -0
- package/dist/react/react/hooks/useGrainAnalytics.d.ts +6 -0
- package/dist/react/react/hooks/useGrainAnalytics.d.ts.map +1 -0
- package/dist/react/react/hooks/useGrainAnalytics.js +16 -0
- package/dist/react/react/hooks/useGrainAnalytics.mjs +13 -0
- package/dist/react/react/hooks/useTrack.d.ts +9 -0
- package/dist/react/react/hooks/useTrack.d.ts.map +1 -0
- package/dist/react/react/hooks/useTrack.js +19 -0
- package/dist/react/react/hooks/useTrack.mjs +16 -0
- package/dist/react/react/index.d.ts +36 -0
- package/dist/react/react/index.d.ts.map +1 -0
- package/dist/react/react/index.js +44 -0
- package/dist/react/react/index.mjs +36 -0
- package/dist/react/react/types.d.ts +33 -0
- package/dist/react/react/types.d.ts.map +1 -0
- package/dist/react/react/types.js +5 -0
- package/dist/react/react/types.mjs +4 -0
- package/package.json +20 -2
package/dist/index.mjs
CHANGED
|
@@ -67,10 +67,10 @@ export class GrainAnalytics {
|
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
|
-
*
|
|
70
|
+
* Generate a proper UUIDv4 identifier for anonymous user ID
|
|
71
71
|
*/
|
|
72
|
-
|
|
73
|
-
return
|
|
72
|
+
generateAnonymousUserId() {
|
|
73
|
+
return this.generateUUID();
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
76
|
* Initialize persistent anonymous user ID from localStorage or create new one
|
|
@@ -86,9 +86,8 @@ export class GrainAnalytics {
|
|
|
86
86
|
this.log('Loaded persistent anonymous user ID:', this.persistentAnonymousUserId);
|
|
87
87
|
}
|
|
88
88
|
else {
|
|
89
|
-
// Generate new anonymous user ID
|
|
90
|
-
|
|
91
|
-
this.persistentAnonymousUserId = this.formatAnonymousUserId(uuid);
|
|
89
|
+
// Generate new UUIDv4 anonymous user ID
|
|
90
|
+
this.persistentAnonymousUserId = this.generateAnonymousUserId();
|
|
92
91
|
localStorage.setItem(storageKey, this.persistentAnonymousUserId);
|
|
93
92
|
this.log('Generated new persistent anonymous user ID:', this.persistentAnonymousUserId);
|
|
94
93
|
}
|
|
@@ -96,15 +95,32 @@ export class GrainAnalytics {
|
|
|
96
95
|
catch (error) {
|
|
97
96
|
this.log('Failed to initialize persistent anonymous user ID:', error);
|
|
98
97
|
// Fallback: generate temporary ID without persistence
|
|
99
|
-
|
|
100
|
-
this.persistentAnonymousUserId = this.formatAnonymousUserId(uuid);
|
|
98
|
+
this.persistentAnonymousUserId = this.generateAnonymousUserId();
|
|
101
99
|
}
|
|
102
100
|
}
|
|
103
101
|
/**
|
|
104
102
|
* Get the effective user ID (global userId or persistent anonymous ID)
|
|
105
103
|
*/
|
|
106
104
|
getEffectiveUserId() {
|
|
107
|
-
|
|
105
|
+
if (this.globalUserId) {
|
|
106
|
+
return this.globalUserId;
|
|
107
|
+
}
|
|
108
|
+
if (this.persistentAnonymousUserId) {
|
|
109
|
+
return this.persistentAnonymousUserId;
|
|
110
|
+
}
|
|
111
|
+
// Generate a new UUIDv4 identifier as fallback
|
|
112
|
+
this.persistentAnonymousUserId = this.generateAnonymousUserId();
|
|
113
|
+
// Try to persist it
|
|
114
|
+
if (typeof window !== 'undefined') {
|
|
115
|
+
try {
|
|
116
|
+
const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;
|
|
117
|
+
localStorage.setItem(storageKey, this.persistentAnonymousUserId);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
this.log('Failed to persist generated anonymous user ID:', error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return this.persistentAnonymousUserId;
|
|
108
124
|
}
|
|
109
125
|
log(...args) {
|
|
110
126
|
if (this.config.debug) {
|
|
@@ -462,10 +478,26 @@ export class GrainAnalytics {
|
|
|
462
478
|
setUserId(userId) {
|
|
463
479
|
this.log(`Set global user ID: ${userId}`);
|
|
464
480
|
this.globalUserId = userId;
|
|
465
|
-
// Clear persistent anonymous user ID if setting a real user ID
|
|
466
481
|
if (userId) {
|
|
482
|
+
// Clear persistent anonymous user ID if setting a real user ID
|
|
467
483
|
this.persistentAnonymousUserId = null;
|
|
468
484
|
}
|
|
485
|
+
else {
|
|
486
|
+
// If clearing user ID, ensure we have a UUIDv4 identifier
|
|
487
|
+
if (!this.persistentAnonymousUserId) {
|
|
488
|
+
this.persistentAnonymousUserId = this.generateAnonymousUserId();
|
|
489
|
+
// Try to persist the new anonymous ID
|
|
490
|
+
if (typeof window !== 'undefined') {
|
|
491
|
+
try {
|
|
492
|
+
const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;
|
|
493
|
+
localStorage.setItem(storageKey, this.persistentAnonymousUserId);
|
|
494
|
+
}
|
|
495
|
+
catch (error) {
|
|
496
|
+
this.log('Failed to persist new anonymous user ID:', error);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
469
501
|
}
|
|
470
502
|
/**
|
|
471
503
|
* Get current global user ID
|
|
@@ -479,6 +511,106 @@ export class GrainAnalytics {
|
|
|
479
511
|
getEffectiveUserIdPublic() {
|
|
480
512
|
return this.getEffectiveUserId();
|
|
481
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* Login with auth token or userId on the fly
|
|
516
|
+
*
|
|
517
|
+
* @example
|
|
518
|
+
* // Login with userId only
|
|
519
|
+
* client.login({ userId: 'user123' });
|
|
520
|
+
*
|
|
521
|
+
* // Login with auth token (automatically sets authStrategy to JWT)
|
|
522
|
+
* client.login({ authToken: 'jwt-token-here' });
|
|
523
|
+
*
|
|
524
|
+
* // Login with both userId and auth token
|
|
525
|
+
* client.login({ userId: 'user123', authToken: 'jwt-token-here' });
|
|
526
|
+
*
|
|
527
|
+
* // Override auth strategy
|
|
528
|
+
* client.login({ userId: 'user123', authStrategy: 'SERVER_SIDE' });
|
|
529
|
+
*/
|
|
530
|
+
login(options) {
|
|
531
|
+
try {
|
|
532
|
+
if (this.isDestroyed) {
|
|
533
|
+
const error = new Error('Grain Analytics: Client has been destroyed');
|
|
534
|
+
const formattedError = this.formatError(error, 'login (client destroyed)');
|
|
535
|
+
this.logError(formattedError);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
// Set userId if provided
|
|
539
|
+
if (options.userId) {
|
|
540
|
+
this.log(`Login: Setting user ID to ${options.userId}`);
|
|
541
|
+
this.globalUserId = options.userId;
|
|
542
|
+
// Clear persistent anonymous user ID since we now have a real user ID
|
|
543
|
+
this.persistentAnonymousUserId = null;
|
|
544
|
+
}
|
|
545
|
+
// Handle auth token if provided
|
|
546
|
+
if (options.authToken) {
|
|
547
|
+
this.log('Login: Setting auth token');
|
|
548
|
+
// Update auth strategy to JWT if not already set
|
|
549
|
+
if (this.config.authStrategy === 'NONE') {
|
|
550
|
+
this.config.authStrategy = 'JWT';
|
|
551
|
+
}
|
|
552
|
+
// Create a simple auth provider that returns the provided token
|
|
553
|
+
this.config.authProvider = {
|
|
554
|
+
getToken: () => options.authToken
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
// Override auth strategy if provided
|
|
558
|
+
if (options.authStrategy) {
|
|
559
|
+
this.log(`Login: Setting auth strategy to ${options.authStrategy}`);
|
|
560
|
+
this.config.authStrategy = options.authStrategy;
|
|
561
|
+
}
|
|
562
|
+
this.log(`Login successful. Effective user ID: ${this.getEffectiveUserId()}`);
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
const formattedError = this.formatError(error, 'login');
|
|
566
|
+
this.logError(formattedError);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Logout and clear user session, fall back to UUIDv4 identifier
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* // Logout user and return to anonymous mode
|
|
574
|
+
* client.logout();
|
|
575
|
+
*
|
|
576
|
+
* // After logout, events will use the persistent UUIDv4 identifier
|
|
577
|
+
* client.track('page_view', { page: 'home' });
|
|
578
|
+
*/
|
|
579
|
+
logout() {
|
|
580
|
+
try {
|
|
581
|
+
if (this.isDestroyed) {
|
|
582
|
+
const error = new Error('Grain Analytics: Client has been destroyed');
|
|
583
|
+
const formattedError = this.formatError(error, 'logout (client destroyed)');
|
|
584
|
+
this.logError(formattedError);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
this.log('Logout: Clearing user session');
|
|
588
|
+
// Clear global user ID
|
|
589
|
+
this.globalUserId = null;
|
|
590
|
+
// Reset auth strategy to NONE
|
|
591
|
+
this.config.authStrategy = 'NONE';
|
|
592
|
+
this.config.authProvider = undefined;
|
|
593
|
+
// Generate new UUIDv4 identifier if we don't have one
|
|
594
|
+
if (!this.persistentAnonymousUserId) {
|
|
595
|
+
this.persistentAnonymousUserId = this.generateAnonymousUserId();
|
|
596
|
+
// Try to persist the new anonymous ID
|
|
597
|
+
if (typeof window !== 'undefined') {
|
|
598
|
+
try {
|
|
599
|
+
const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;
|
|
600
|
+
localStorage.setItem(storageKey, this.persistentAnonymousUserId);
|
|
601
|
+
}
|
|
602
|
+
catch (error) {
|
|
603
|
+
this.log('Failed to persist new anonymous user ID after logout:', error);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
this.log(`Logout successful. Effective user ID: ${this.getEffectiveUserId()}`);
|
|
608
|
+
}
|
|
609
|
+
catch (error) {
|
|
610
|
+
const formattedError = this.formatError(error, 'logout');
|
|
611
|
+
this.logError(formattedError);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
482
614
|
/**
|
|
483
615
|
* Set user properties
|
|
484
616
|
*/
|
|
@@ -948,7 +1080,8 @@ export class GrainAnalytics {
|
|
|
948
1080
|
clearInterval(this.configRefreshTimer);
|
|
949
1081
|
}
|
|
950
1082
|
this.configRefreshTimer = window.setInterval(() => {
|
|
951
|
-
if (!this.isDestroyed
|
|
1083
|
+
if (!this.isDestroyed) {
|
|
1084
|
+
// Use effective userId (will be generated if not set)
|
|
952
1085
|
this.fetchConfig().catch((error) => {
|
|
953
1086
|
const formattedError = this.formatError(error, 'auto-config refresh');
|
|
954
1087
|
this.logError(formattedError);
|
|
@@ -970,10 +1103,9 @@ export class GrainAnalytics {
|
|
|
970
1103
|
*/
|
|
971
1104
|
async preloadConfig(immediateKeys = [], properties) {
|
|
972
1105
|
try {
|
|
973
|
-
if
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
}
|
|
1106
|
+
// Use effective userId (will be generated if not set)
|
|
1107
|
+
const effectiveUserId = this.getEffectiveUserId();
|
|
1108
|
+
this.log(`Preloading config for user: ${effectiveUserId}`);
|
|
977
1109
|
const response = await this.fetchConfig({ immediateKeys, properties });
|
|
978
1110
|
if (response) {
|
|
979
1111
|
this.startConfigRefreshTimer();
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grain Analytics Web SDK
|
|
3
|
+
* A lightweight, dependency-free TypeScript SDK for sending analytics events to Grain's REST API
|
|
4
|
+
*/
|
|
5
|
+
export interface GrainEvent {
|
|
6
|
+
eventName: string;
|
|
7
|
+
userId?: string;
|
|
8
|
+
properties?: Record<string, unknown>;
|
|
9
|
+
timestamp?: Date;
|
|
10
|
+
}
|
|
11
|
+
export interface EventPayload {
|
|
12
|
+
eventName: string;
|
|
13
|
+
userId: string;
|
|
14
|
+
properties: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export type AuthStrategy = 'NONE' | 'SERVER_SIDE' | 'JWT';
|
|
17
|
+
export interface AuthProvider {
|
|
18
|
+
getToken(): Promise<string> | string;
|
|
19
|
+
}
|
|
20
|
+
export interface GrainConfig {
|
|
21
|
+
tenantId: string;
|
|
22
|
+
apiUrl?: string;
|
|
23
|
+
authStrategy?: AuthStrategy;
|
|
24
|
+
secretKey?: string;
|
|
25
|
+
authProvider?: AuthProvider;
|
|
26
|
+
userId?: string;
|
|
27
|
+
batchSize?: number;
|
|
28
|
+
flushInterval?: number;
|
|
29
|
+
retryAttempts?: number;
|
|
30
|
+
retryDelay?: number;
|
|
31
|
+
maxEventsPerRequest?: number;
|
|
32
|
+
debug?: boolean;
|
|
33
|
+
defaultConfigurations?: Record<string, string>;
|
|
34
|
+
configCacheKey?: string;
|
|
35
|
+
configRefreshInterval?: number;
|
|
36
|
+
enableConfigCache?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface SendEventOptions {
|
|
39
|
+
flush?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface SetPropertyOptions {
|
|
42
|
+
userId?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface LoginOptions {
|
|
45
|
+
userId?: string;
|
|
46
|
+
authToken?: string;
|
|
47
|
+
authStrategy?: AuthStrategy;
|
|
48
|
+
}
|
|
49
|
+
export interface PropertyPayload {
|
|
50
|
+
userId: string;
|
|
51
|
+
[key: string]: string;
|
|
52
|
+
}
|
|
53
|
+
export interface RemoteConfigRequest {
|
|
54
|
+
userId: string;
|
|
55
|
+
immediateKeys: string[];
|
|
56
|
+
properties?: Record<string, string>;
|
|
57
|
+
}
|
|
58
|
+
export interface RemoteConfigResponse {
|
|
59
|
+
userId: string;
|
|
60
|
+
snapshotId: string;
|
|
61
|
+
configurations: Record<string, string>;
|
|
62
|
+
isFinal: boolean;
|
|
63
|
+
qualifiedSegments: string[];
|
|
64
|
+
qualifiedRuleSets: string[];
|
|
65
|
+
timestamp: string;
|
|
66
|
+
isFromCache: boolean;
|
|
67
|
+
}
|
|
68
|
+
export interface RemoteConfigOptions {
|
|
69
|
+
immediateKeys?: string[];
|
|
70
|
+
properties?: Record<string, string>;
|
|
71
|
+
userId?: string;
|
|
72
|
+
forceRefresh?: boolean;
|
|
73
|
+
}
|
|
74
|
+
export interface RemoteConfigCache {
|
|
75
|
+
configurations: Record<string, string>;
|
|
76
|
+
snapshotId: string;
|
|
77
|
+
timestamp: string;
|
|
78
|
+
userId: string;
|
|
79
|
+
}
|
|
80
|
+
export type ConfigChangeListener = (configurations: Record<string, string>) => void;
|
|
81
|
+
export interface LoginEventProperties extends Record<string, unknown> {
|
|
82
|
+
method?: string;
|
|
83
|
+
success?: boolean;
|
|
84
|
+
errorMessage?: string;
|
|
85
|
+
loginAttempt?: number;
|
|
86
|
+
rememberMe?: boolean;
|
|
87
|
+
twoFactorEnabled?: boolean;
|
|
88
|
+
}
|
|
89
|
+
export interface SignupEventProperties extends Record<string, unknown> {
|
|
90
|
+
method?: string;
|
|
91
|
+
source?: string;
|
|
92
|
+
plan?: string;
|
|
93
|
+
success?: boolean;
|
|
94
|
+
errorMessage?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface CheckoutEventProperties extends Record<string, unknown> {
|
|
97
|
+
orderId?: string;
|
|
98
|
+
total?: number;
|
|
99
|
+
currency?: string;
|
|
100
|
+
items?: Array<{
|
|
101
|
+
id: string;
|
|
102
|
+
name: string;
|
|
103
|
+
price: number;
|
|
104
|
+
quantity: number;
|
|
105
|
+
}>;
|
|
106
|
+
paymentMethod?: string;
|
|
107
|
+
success?: boolean;
|
|
108
|
+
errorMessage?: string;
|
|
109
|
+
couponCode?: string;
|
|
110
|
+
discount?: number;
|
|
111
|
+
}
|
|
112
|
+
export interface PageViewEventProperties extends Record<string, unknown> {
|
|
113
|
+
page?: string;
|
|
114
|
+
title?: string;
|
|
115
|
+
referrer?: string;
|
|
116
|
+
url?: string;
|
|
117
|
+
userAgent?: string;
|
|
118
|
+
screenResolution?: string;
|
|
119
|
+
viewportSize?: string;
|
|
120
|
+
}
|
|
121
|
+
export interface PurchaseEventProperties extends Record<string, unknown> {
|
|
122
|
+
orderId?: string;
|
|
123
|
+
total?: number;
|
|
124
|
+
currency?: string;
|
|
125
|
+
items?: Array<{
|
|
126
|
+
id: string;
|
|
127
|
+
name: string;
|
|
128
|
+
price: number;
|
|
129
|
+
quantity: number;
|
|
130
|
+
category?: string;
|
|
131
|
+
}>;
|
|
132
|
+
paymentMethod?: string;
|
|
133
|
+
shippingMethod?: string;
|
|
134
|
+
tax?: number;
|
|
135
|
+
shipping?: number;
|
|
136
|
+
discount?: number;
|
|
137
|
+
couponCode?: string;
|
|
138
|
+
}
|
|
139
|
+
export interface SearchEventProperties extends Record<string, unknown> {
|
|
140
|
+
query?: string;
|
|
141
|
+
results?: number;
|
|
142
|
+
filters?: Record<string, unknown>;
|
|
143
|
+
sortBy?: string;
|
|
144
|
+
category?: string;
|
|
145
|
+
success?: boolean;
|
|
146
|
+
}
|
|
147
|
+
export interface AddToCartEventProperties extends Record<string, unknown> {
|
|
148
|
+
itemId?: string;
|
|
149
|
+
itemName?: string;
|
|
150
|
+
price?: number;
|
|
151
|
+
quantity?: number;
|
|
152
|
+
currency?: string;
|
|
153
|
+
category?: string;
|
|
154
|
+
variant?: string;
|
|
155
|
+
}
|
|
156
|
+
export interface RemoveFromCartEventProperties extends Record<string, unknown> {
|
|
157
|
+
itemId?: string;
|
|
158
|
+
itemName?: string;
|
|
159
|
+
price?: number;
|
|
160
|
+
quantity?: number;
|
|
161
|
+
currency?: string;
|
|
162
|
+
category?: string;
|
|
163
|
+
variant?: string;
|
|
164
|
+
}
|
|
165
|
+
export interface ErrorDigest {
|
|
166
|
+
eventCount: number;
|
|
167
|
+
totalProperties: number;
|
|
168
|
+
totalSize: number;
|
|
169
|
+
eventNames: string[];
|
|
170
|
+
userIds: string[];
|
|
171
|
+
}
|
|
172
|
+
export interface FormattedError {
|
|
173
|
+
code: string;
|
|
174
|
+
message: string;
|
|
175
|
+
digest: ErrorDigest;
|
|
176
|
+
timestamp: string;
|
|
177
|
+
context: string;
|
|
178
|
+
originalError?: unknown;
|
|
179
|
+
}
|
|
180
|
+
export declare class GrainAnalytics {
|
|
181
|
+
private config;
|
|
182
|
+
private eventQueue;
|
|
183
|
+
private flushTimer;
|
|
184
|
+
private isDestroyed;
|
|
185
|
+
private globalUserId;
|
|
186
|
+
private persistentAnonymousUserId;
|
|
187
|
+
private configCache;
|
|
188
|
+
private configRefreshTimer;
|
|
189
|
+
private configChangeListeners;
|
|
190
|
+
private configFetchPromise;
|
|
191
|
+
constructor(config: GrainConfig);
|
|
192
|
+
private validateConfig;
|
|
193
|
+
/**
|
|
194
|
+
* Generate a UUID v4 string
|
|
195
|
+
*/
|
|
196
|
+
private generateUUID;
|
|
197
|
+
/**
|
|
198
|
+
* Generate a proper UUIDv4 identifier for anonymous user ID
|
|
199
|
+
*/
|
|
200
|
+
private generateAnonymousUserId;
|
|
201
|
+
/**
|
|
202
|
+
* Initialize persistent anonymous user ID from localStorage or create new one
|
|
203
|
+
*/
|
|
204
|
+
private initializePersistentAnonymousUserId;
|
|
205
|
+
/**
|
|
206
|
+
* Get the effective user ID (global userId or persistent anonymous ID)
|
|
207
|
+
*/
|
|
208
|
+
private getEffectiveUserId;
|
|
209
|
+
private log;
|
|
210
|
+
/**
|
|
211
|
+
* Create error digest from events
|
|
212
|
+
*/
|
|
213
|
+
private createErrorDigest;
|
|
214
|
+
/**
|
|
215
|
+
* Format error with beautiful structure
|
|
216
|
+
*/
|
|
217
|
+
private formatError;
|
|
218
|
+
/**
|
|
219
|
+
* Log formatted error gracefully
|
|
220
|
+
*/
|
|
221
|
+
private logError;
|
|
222
|
+
/**
|
|
223
|
+
* Safely execute a function with error handling
|
|
224
|
+
*/
|
|
225
|
+
private safeExecute;
|
|
226
|
+
private formatEvent;
|
|
227
|
+
private getAuthHeaders;
|
|
228
|
+
private delay;
|
|
229
|
+
private isRetriableError;
|
|
230
|
+
private sendEvents;
|
|
231
|
+
private sendEventsWithBeacon;
|
|
232
|
+
private startFlushTimer;
|
|
233
|
+
private setupBeforeUnload;
|
|
234
|
+
/**
|
|
235
|
+
* Track an analytics event
|
|
236
|
+
*/
|
|
237
|
+
track(eventName: string, properties?: Record<string, unknown>, options?: SendEventOptions): Promise<void>;
|
|
238
|
+
track(event: GrainEvent, options?: SendEventOptions): Promise<void>;
|
|
239
|
+
/**
|
|
240
|
+
* Identify a user (sets userId for subsequent events)
|
|
241
|
+
*/
|
|
242
|
+
identify(userId: string): void;
|
|
243
|
+
/**
|
|
244
|
+
* Set global user ID for all subsequent events
|
|
245
|
+
*/
|
|
246
|
+
setUserId(userId: string | null): void;
|
|
247
|
+
/**
|
|
248
|
+
* Get current global user ID
|
|
249
|
+
*/
|
|
250
|
+
getUserId(): string | null;
|
|
251
|
+
/**
|
|
252
|
+
* Get current effective user ID (global userId or persistent anonymous ID)
|
|
253
|
+
*/
|
|
254
|
+
getEffectiveUserIdPublic(): string;
|
|
255
|
+
/**
|
|
256
|
+
* Login with auth token or userId on the fly
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* // Login with userId only
|
|
260
|
+
* client.login({ userId: 'user123' });
|
|
261
|
+
*
|
|
262
|
+
* // Login with auth token (automatically sets authStrategy to JWT)
|
|
263
|
+
* client.login({ authToken: 'jwt-token-here' });
|
|
264
|
+
*
|
|
265
|
+
* // Login with both userId and auth token
|
|
266
|
+
* client.login({ userId: 'user123', authToken: 'jwt-token-here' });
|
|
267
|
+
*
|
|
268
|
+
* // Override auth strategy
|
|
269
|
+
* client.login({ userId: 'user123', authStrategy: 'SERVER_SIDE' });
|
|
270
|
+
*/
|
|
271
|
+
login(options: LoginOptions): void;
|
|
272
|
+
/**
|
|
273
|
+
* Logout and clear user session, fall back to UUIDv4 identifier
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* // Logout user and return to anonymous mode
|
|
277
|
+
* client.logout();
|
|
278
|
+
*
|
|
279
|
+
* // After logout, events will use the persistent UUIDv4 identifier
|
|
280
|
+
* client.track('page_view', { page: 'home' });
|
|
281
|
+
*/
|
|
282
|
+
logout(): void;
|
|
283
|
+
/**
|
|
284
|
+
* Set user properties
|
|
285
|
+
*/
|
|
286
|
+
setProperty(properties: Record<string, unknown>, options?: SetPropertyOptions): Promise<void>;
|
|
287
|
+
/**
|
|
288
|
+
* Send properties to the API
|
|
289
|
+
*/
|
|
290
|
+
private sendProperties;
|
|
291
|
+
/**
|
|
292
|
+
* Track user login event
|
|
293
|
+
*/
|
|
294
|
+
trackLogin(properties?: LoginEventProperties, options?: SendEventOptions): Promise<void>;
|
|
295
|
+
/**
|
|
296
|
+
* Track user signup event
|
|
297
|
+
*/
|
|
298
|
+
trackSignup(properties?: SignupEventProperties, options?: SendEventOptions): Promise<void>;
|
|
299
|
+
/**
|
|
300
|
+
* Track checkout event
|
|
301
|
+
*/
|
|
302
|
+
trackCheckout(properties?: CheckoutEventProperties, options?: SendEventOptions): Promise<void>;
|
|
303
|
+
/**
|
|
304
|
+
* Track page view event
|
|
305
|
+
*/
|
|
306
|
+
trackPageView(properties?: PageViewEventProperties, options?: SendEventOptions): Promise<void>;
|
|
307
|
+
/**
|
|
308
|
+
* Track purchase event
|
|
309
|
+
*/
|
|
310
|
+
trackPurchase(properties?: PurchaseEventProperties, options?: SendEventOptions): Promise<void>;
|
|
311
|
+
/**
|
|
312
|
+
* Track search event
|
|
313
|
+
*/
|
|
314
|
+
trackSearch(properties?: SearchEventProperties, options?: SendEventOptions): Promise<void>;
|
|
315
|
+
/**
|
|
316
|
+
* Track add to cart event
|
|
317
|
+
*/
|
|
318
|
+
trackAddToCart(properties?: AddToCartEventProperties, options?: SendEventOptions): Promise<void>;
|
|
319
|
+
/**
|
|
320
|
+
* Track remove from cart event
|
|
321
|
+
*/
|
|
322
|
+
trackRemoveFromCart(properties?: RemoveFromCartEventProperties, options?: SendEventOptions): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* Manually flush all queued events
|
|
325
|
+
*/
|
|
326
|
+
flush(): Promise<void>;
|
|
327
|
+
/**
|
|
328
|
+
* Initialize configuration cache from localStorage
|
|
329
|
+
*/
|
|
330
|
+
private initializeConfigCache;
|
|
331
|
+
/**
|
|
332
|
+
* Save configuration cache to localStorage
|
|
333
|
+
*/
|
|
334
|
+
private saveConfigCache;
|
|
335
|
+
/**
|
|
336
|
+
* Get configuration value with fallback to defaults
|
|
337
|
+
*/
|
|
338
|
+
getConfig(key: string): string | undefined;
|
|
339
|
+
/**
|
|
340
|
+
* Get all configurations with fallback to defaults
|
|
341
|
+
*/
|
|
342
|
+
getAllConfigs(): Record<string, string>;
|
|
343
|
+
/**
|
|
344
|
+
* Fetch configurations from API
|
|
345
|
+
*/
|
|
346
|
+
fetchConfig(options?: RemoteConfigOptions): Promise<RemoteConfigResponse | null>;
|
|
347
|
+
/**
|
|
348
|
+
* Get configuration asynchronously (cache-first with fallback to API)
|
|
349
|
+
*/
|
|
350
|
+
getConfigAsync(key: string, options?: RemoteConfigOptions): Promise<string | undefined>;
|
|
351
|
+
/**
|
|
352
|
+
* Get all configurations asynchronously (cache-first with fallback to API)
|
|
353
|
+
*/
|
|
354
|
+
getAllConfigsAsync(options?: RemoteConfigOptions): Promise<Record<string, string>>;
|
|
355
|
+
/**
|
|
356
|
+
* Update configuration cache and notify listeners
|
|
357
|
+
*/
|
|
358
|
+
private updateConfigCache;
|
|
359
|
+
/**
|
|
360
|
+
* Add configuration change listener
|
|
361
|
+
*/
|
|
362
|
+
addConfigChangeListener(listener: ConfigChangeListener): void;
|
|
363
|
+
/**
|
|
364
|
+
* Remove configuration change listener
|
|
365
|
+
*/
|
|
366
|
+
removeConfigChangeListener(listener: ConfigChangeListener): void;
|
|
367
|
+
/**
|
|
368
|
+
* Notify all configuration change listeners
|
|
369
|
+
*/
|
|
370
|
+
private notifyConfigChangeListeners;
|
|
371
|
+
/**
|
|
372
|
+
* Start automatic configuration refresh timer
|
|
373
|
+
*/
|
|
374
|
+
private startConfigRefreshTimer;
|
|
375
|
+
/**
|
|
376
|
+
* Stop automatic configuration refresh timer
|
|
377
|
+
*/
|
|
378
|
+
private stopConfigRefreshTimer;
|
|
379
|
+
/**
|
|
380
|
+
* Preload configurations for immediate access
|
|
381
|
+
*/
|
|
382
|
+
preloadConfig(immediateKeys?: string[], properties?: Record<string, string>): Promise<void>;
|
|
383
|
+
/**
|
|
384
|
+
* Split events array into chunks of specified size
|
|
385
|
+
*/
|
|
386
|
+
private chunkEvents;
|
|
387
|
+
/**
|
|
388
|
+
* Destroy the client and clean up resources
|
|
389
|
+
*/
|
|
390
|
+
destroy(): void;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Create a new Grain Analytics client
|
|
394
|
+
*/
|
|
395
|
+
export declare function createGrainAnalytics(config: GrainConfig): GrainAnalytics;
|
|
396
|
+
export default GrainAnalytics;
|
|
397
|
+
declare global {
|
|
398
|
+
interface Window {
|
|
399
|
+
Grain?: {
|
|
400
|
+
GrainAnalytics: typeof GrainAnalytics;
|
|
401
|
+
createGrainAnalytics: typeof createGrainAnalytics;
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|