@ordersune/crm-web-sdk 1.0.6 → 1.0.7
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/dist/types/index.d.ts +26 -2
- package/dist/web-sdk.d.ts +15 -3
- package/dist/web-sdk.js +251 -70
- package/package.json +1 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export interface UserProfile {
|
|
2
2
|
id: string;
|
|
3
|
-
user_type: string;
|
|
4
|
-
traits: Record<string, any>;
|
|
5
3
|
}
|
|
6
4
|
export interface EventOptions {
|
|
7
5
|
timestamp?: string;
|
|
@@ -11,4 +9,30 @@ export interface SDKConfig {
|
|
|
11
9
|
apiKey: string;
|
|
12
10
|
endpoint: string;
|
|
13
11
|
debug?: boolean;
|
|
12
|
+
batchSize?: number;
|
|
13
|
+
batchInterval?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PurchasePayload {
|
|
16
|
+
externalId: string;
|
|
17
|
+
itemId: string;
|
|
18
|
+
itemName: string;
|
|
19
|
+
unitPrice: number;
|
|
20
|
+
quantity: number;
|
|
21
|
+
source: string;
|
|
22
|
+
channel: string;
|
|
23
|
+
itemCategory?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface DeviceDetails {
|
|
26
|
+
deviceId: string;
|
|
27
|
+
deviceModel: string;
|
|
28
|
+
browser: string;
|
|
29
|
+
browserVersion: string;
|
|
30
|
+
language: string;
|
|
31
|
+
screenResolution: string;
|
|
32
|
+
userAgent: string;
|
|
33
|
+
platform: string;
|
|
34
|
+
}
|
|
35
|
+
export interface BrowserInfo {
|
|
36
|
+
browserType: string;
|
|
37
|
+
browserVersion: string;
|
|
14
38
|
}
|
package/dist/web-sdk.d.ts
CHANGED
|
@@ -10,18 +10,30 @@ export declare class WebSDK {
|
|
|
10
10
|
private deviceDetails?;
|
|
11
11
|
private currentUser?;
|
|
12
12
|
private eventQueue;
|
|
13
|
+
private purchaseBatch;
|
|
14
|
+
private attributeQueue;
|
|
13
15
|
private isProcessingQueue;
|
|
14
|
-
private
|
|
16
|
+
private batchProcessingInterval?;
|
|
15
17
|
constructor(config: SDKConfig);
|
|
16
|
-
|
|
18
|
+
private initialize;
|
|
19
|
+
identify(userId: string): void;
|
|
20
|
+
clearUserData(): void;
|
|
17
21
|
trackEvent(eventName: string, properties?: Record<string, any>, options?: EventOptions): void;
|
|
18
22
|
trackCustomAttribute(attributeName: string, attributeValue: any): void;
|
|
23
|
+
logProductPurchase(orderId: string, itemId: string, itemName: string, unitPrice: number, quantity: number, source: string, channel: string, itemCategory?: string): void;
|
|
19
24
|
getUserProfile(): UserProfile | undefined;
|
|
20
|
-
|
|
25
|
+
forceSend(): Promise<void>;
|
|
26
|
+
dispose(): void;
|
|
21
27
|
private getStoredDeviceId;
|
|
28
|
+
private getStoredUserProfile;
|
|
22
29
|
private storeDeviceId;
|
|
30
|
+
private storeUserProfile;
|
|
31
|
+
private storeCustomAttributes;
|
|
32
|
+
private loadCustomAttributes;
|
|
23
33
|
private getGuestUserId;
|
|
34
|
+
private buildPurchasePayload;
|
|
24
35
|
private initializeDeviceDetails;
|
|
36
|
+
private getBrowserInfo;
|
|
25
37
|
private detectDeviceType;
|
|
26
38
|
private detectBrowserType;
|
|
27
39
|
private detectBrowserVersion;
|
package/dist/web-sdk.js
CHANGED
|
@@ -6,76 +6,229 @@ const uuid_1 = require("uuid");
|
|
|
6
6
|
const STORAGE_PREFIX = "os.";
|
|
7
7
|
const DEFAULT_BATCH_SIZE = 10;
|
|
8
8
|
const DEFAULT_BATCH_INTERVAL = 10000;
|
|
9
|
-
const SDK_VERSION = "1.0.
|
|
9
|
+
const SDK_VERSION = "1.0.7";
|
|
10
10
|
class WebSDK {
|
|
11
11
|
constructor(config) {
|
|
12
|
-
var _a;
|
|
12
|
+
var _a, _b, _c;
|
|
13
13
|
this.maxBatchSize = DEFAULT_BATCH_SIZE;
|
|
14
14
|
this.batchInterval = DEFAULT_BATCH_INTERVAL;
|
|
15
15
|
this.sdkVersion = SDK_VERSION;
|
|
16
16
|
this.eventQueue = [];
|
|
17
|
+
this.purchaseBatch = [];
|
|
18
|
+
this.attributeQueue = {};
|
|
17
19
|
this.isProcessingQueue = false;
|
|
18
|
-
|
|
20
|
+
if (!config.apiKey || !config.endpoint) {
|
|
21
|
+
throw new Error("API key and endpoint are required");
|
|
22
|
+
}
|
|
19
23
|
this.apiKey = config.apiKey;
|
|
20
24
|
this.endpoint = config.endpoint;
|
|
21
25
|
this.debug = (_a = config.debug) !== null && _a !== void 0 ? _a : false;
|
|
26
|
+
this.maxBatchSize = (_b = config.batchSize) !== null && _b !== void 0 ? _b : DEFAULT_BATCH_SIZE;
|
|
27
|
+
this.batchInterval = (_c = config.batchInterval) !== null && _c !== void 0 ? _c : DEFAULT_BATCH_INTERVAL;
|
|
22
28
|
this.deviceId = this.getStoredDeviceId() || (0, uuid_1.v4)();
|
|
23
|
-
|
|
29
|
+
// Initialize async
|
|
30
|
+
this.initialize().catch((error) => {
|
|
31
|
+
(0, utils_1.log)(this.debug, "Async initialization failed", error);
|
|
32
|
+
});
|
|
24
33
|
}
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
async initialize() {
|
|
35
|
+
try {
|
|
36
|
+
(0, utils_1.log)(this.debug, "SDK Initialized");
|
|
37
|
+
this.storeDeviceId();
|
|
38
|
+
await this.initializeDeviceDetails();
|
|
39
|
+
await this.loadCustomAttributes();
|
|
40
|
+
const storedUser = this.getStoredUserProfile();
|
|
41
|
+
if (storedUser) {
|
|
42
|
+
this.currentUser = storedUser;
|
|
43
|
+
(0, utils_1.log)(this.debug, "Loaded user profile", this.currentUser);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.identify("");
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
50
|
+
this.trackCustomAttribute("timezone", timezone);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
(0, utils_1.log)(this.debug, "Failed to detect timezone", error);
|
|
54
|
+
}
|
|
55
|
+
this.startBatchProcessing();
|
|
56
|
+
this.trackEvent("app_started", {});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
(0, utils_1.log)(this.debug, "Initialization failed", error);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
identify(userId) {
|
|
64
|
+
if (typeof userId !== "string") {
|
|
65
|
+
throw new Error("User ID must be a string");
|
|
66
|
+
}
|
|
67
|
+
const storedUser = this.getStoredUserProfile();
|
|
68
|
+
if ((storedUser === null || storedUser === void 0 ? void 0 : storedUser.id) === userId)
|
|
69
|
+
return;
|
|
70
|
+
(0, utils_1.log)(this.debug, "Identifying user", userId);
|
|
27
71
|
this.currentUser = {
|
|
28
72
|
id: userId || this.getGuestUserId(),
|
|
29
|
-
user_type: userId ? "registered" : "guest",
|
|
30
|
-
traits: { ...(_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.traits, ...traits },
|
|
31
73
|
};
|
|
32
|
-
this.
|
|
33
|
-
|
|
34
|
-
|
|
74
|
+
this.storeUserProfile();
|
|
75
|
+
}
|
|
76
|
+
clearUserData() {
|
|
77
|
+
this.currentUser = {
|
|
78
|
+
id: this.getGuestUserId(),
|
|
79
|
+
};
|
|
80
|
+
this.attributeQueue = {};
|
|
81
|
+
this.eventQueue = [];
|
|
82
|
+
this.purchaseBatch = [];
|
|
83
|
+
sessionStorage.setItem(`${STORAGE_PREFIX}${this.apiKey}.current_user`, JSON.stringify(this.currentUser));
|
|
84
|
+
sessionStorage.removeItem(`${STORAGE_PREFIX}${this.apiKey}.custom_attributes`);
|
|
85
|
+
this.trackEvent("user_logged_out", {
|
|
86
|
+
device_id: this.deviceId,
|
|
35
87
|
});
|
|
88
|
+
if (this.debug) {
|
|
89
|
+
(0, utils_1.log)(this.debug, "User data cleared");
|
|
90
|
+
}
|
|
36
91
|
}
|
|
37
92
|
trackEvent(eventName, properties = {}, options = {}) {
|
|
93
|
+
if (!eventName || typeof eventName !== "string") {
|
|
94
|
+
throw new Error("Event name is required and must be a string");
|
|
95
|
+
}
|
|
38
96
|
const payload = {
|
|
39
97
|
deviceId: this.deviceId,
|
|
40
98
|
eventName,
|
|
41
99
|
timestamp: options.timestamp || Date.now(),
|
|
42
100
|
requestId: options.requestId || (0, uuid_1.v4)(),
|
|
43
|
-
properties,
|
|
101
|
+
properties: properties,
|
|
44
102
|
};
|
|
45
103
|
this.queueEvent(payload);
|
|
46
104
|
}
|
|
47
105
|
trackCustomAttribute(attributeName, attributeValue) {
|
|
48
|
-
|
|
106
|
+
if (!attributeName || typeof attributeName !== "string") {
|
|
107
|
+
throw new Error("Attribute name is required and must be a string");
|
|
108
|
+
}
|
|
109
|
+
this.attributeQueue = {
|
|
110
|
+
...this.attributeQueue,
|
|
111
|
+
[attributeName]: attributeValue,
|
|
112
|
+
};
|
|
113
|
+
(0, utils_1.log)(this.debug, "Custom attribute queued", attributeName, attributeValue);
|
|
114
|
+
this.storeCustomAttributes();
|
|
115
|
+
}
|
|
116
|
+
logProductPurchase(orderId, itemId, itemName, unitPrice, quantity, source, channel, itemCategory) {
|
|
117
|
+
const purchasePayload = this.buildPurchasePayload({
|
|
118
|
+
externalId: orderId,
|
|
119
|
+
itemId,
|
|
120
|
+
itemName,
|
|
121
|
+
unitPrice,
|
|
122
|
+
quantity,
|
|
123
|
+
source,
|
|
124
|
+
channel,
|
|
125
|
+
itemCategory,
|
|
126
|
+
});
|
|
127
|
+
this.purchaseBatch.push(purchasePayload);
|
|
128
|
+
if (this.debug) {
|
|
129
|
+
(0, utils_1.log)(this.debug, "Purchase event queued", purchasePayload);
|
|
130
|
+
}
|
|
49
131
|
}
|
|
50
132
|
getUserProfile() {
|
|
51
133
|
return this.currentUser;
|
|
52
134
|
}
|
|
53
|
-
|
|
54
|
-
this.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
135
|
+
async forceSend() {
|
|
136
|
+
if (this.eventQueue.length > 0 ||
|
|
137
|
+
this.purchaseBatch.length > 0 ||
|
|
138
|
+
this.attributeQueue.length > 0) {
|
|
139
|
+
await this.processBatch();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
dispose() {
|
|
143
|
+
if (this.batchProcessingInterval) {
|
|
144
|
+
clearInterval(this.batchProcessingInterval);
|
|
145
|
+
}
|
|
146
|
+
if (this.eventQueue.length > 0 ||
|
|
147
|
+
this.purchaseBatch.length > 0 ||
|
|
148
|
+
this.attributeQueue.length > 0) {
|
|
149
|
+
this.processBatch().catch((error) => {
|
|
150
|
+
(0, utils_1.log)(this.debug, "Error during disposal", error);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
59
153
|
}
|
|
60
154
|
getStoredDeviceId() {
|
|
61
155
|
return localStorage.getItem(`${STORAGE_PREFIX}${this.apiKey}.device_id`);
|
|
62
156
|
}
|
|
157
|
+
getStoredUserProfile() {
|
|
158
|
+
const storedUser = sessionStorage.getItem(`${STORAGE_PREFIX}${this.apiKey}.current_user`);
|
|
159
|
+
return storedUser ? JSON.parse(storedUser) : null;
|
|
160
|
+
}
|
|
63
161
|
storeDeviceId() {
|
|
64
162
|
localStorage.setItem(`${STORAGE_PREFIX}${this.apiKey}.device_id`, this.deviceId);
|
|
65
163
|
}
|
|
164
|
+
storeUserProfile() {
|
|
165
|
+
if (this.currentUser) {
|
|
166
|
+
sessionStorage.setItem(`${STORAGE_PREFIX}${this.apiKey}.current_user`, JSON.stringify(this.currentUser));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
storeCustomAttributes() {
|
|
170
|
+
const existingAttributes = sessionStorage.getItem(`${STORAGE_PREFIX}${this.apiKey}.custom_attributes`);
|
|
171
|
+
const existingParsed = existingAttributes
|
|
172
|
+
? JSON.parse(existingAttributes)
|
|
173
|
+
: {};
|
|
174
|
+
const mergedAttributes = {
|
|
175
|
+
...existingParsed,
|
|
176
|
+
...this.attributeQueue,
|
|
177
|
+
};
|
|
178
|
+
sessionStorage.setItem(`${STORAGE_PREFIX}${this.apiKey}.custom_attributes`, JSON.stringify(mergedAttributes));
|
|
179
|
+
}
|
|
180
|
+
async loadCustomAttributes() {
|
|
181
|
+
const stored = sessionStorage.getItem(`${STORAGE_PREFIX}${this.apiKey}.custom_attributes`);
|
|
182
|
+
if (stored) {
|
|
183
|
+
this.attributeQueue = {
|
|
184
|
+
...this.attributeQueue,
|
|
185
|
+
...JSON.parse(stored),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
66
189
|
getGuestUserId() {
|
|
67
190
|
return `guest_user_${this.deviceId}`;
|
|
68
191
|
}
|
|
192
|
+
buildPurchasePayload({ externalId, itemId, itemName, unitPrice, quantity, source, channel, itemCategory, }) {
|
|
193
|
+
const timestamp = Date.now();
|
|
194
|
+
return {
|
|
195
|
+
external_id: externalId,
|
|
196
|
+
item_id: itemId,
|
|
197
|
+
item_name: itemName,
|
|
198
|
+
item_category: itemCategory,
|
|
199
|
+
quantity: quantity,
|
|
200
|
+
unit_price: unitPrice,
|
|
201
|
+
total_price: unitPrice * quantity,
|
|
202
|
+
source: source,
|
|
203
|
+
channel: channel,
|
|
204
|
+
purchased_at: timestamp,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
69
207
|
async initializeDeviceDetails() {
|
|
208
|
+
const deviceType = await this.detectDeviceType();
|
|
209
|
+
const browserInfo = await this.getBrowserInfo();
|
|
70
210
|
this.deviceDetails = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
211
|
+
deviceId: this.deviceId,
|
|
212
|
+
deviceModel: deviceType,
|
|
213
|
+
browser: browserInfo.browserType,
|
|
214
|
+
browserVersion: browserInfo.browserVersion,
|
|
215
|
+
language: navigator.language,
|
|
216
|
+
screenResolution: `${window.screen.width}x${window.screen.height}`,
|
|
217
|
+
userAgent: navigator.userAgent,
|
|
218
|
+
platform: navigator.platform,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
async getBrowserInfo() {
|
|
222
|
+
const browserType = this.detectBrowserType();
|
|
223
|
+
const browserVersion = this.detectBrowserVersion();
|
|
224
|
+
return {
|
|
225
|
+
browserType,
|
|
226
|
+
browserVersion,
|
|
74
227
|
};
|
|
75
228
|
}
|
|
76
229
|
async detectDeviceType() {
|
|
77
|
-
|
|
78
|
-
|
|
230
|
+
try {
|
|
231
|
+
if ("userAgentData" in navigator) {
|
|
79
232
|
const data = await navigator.userAgentData.getHighEntropyValues(["platform", "mobile"]);
|
|
80
233
|
if (data.mobile) {
|
|
81
234
|
return data.platform.toLowerCase().includes("ios")
|
|
@@ -90,9 +243,9 @@ class WebSDK {
|
|
|
90
243
|
if (platform.includes("linux"))
|
|
91
244
|
return "linux";
|
|
92
245
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
(0, utils_1.log)(this.debug, "Client Hints API failed", error);
|
|
96
249
|
}
|
|
97
250
|
const userAgent = navigator.userAgent.toLowerCase();
|
|
98
251
|
if (/iphone|ipad|ipod/.test(userAgent))
|
|
@@ -108,58 +261,64 @@ class WebSDK {
|
|
|
108
261
|
return "unknown";
|
|
109
262
|
}
|
|
110
263
|
detectBrowserType() {
|
|
111
|
-
|
|
112
|
-
|
|
264
|
+
try {
|
|
265
|
+
if ("userAgentData" in navigator) {
|
|
113
266
|
const brands = navigator.userAgentData.brands;
|
|
114
267
|
const brand = brands.find((b) => !["Chrome HTML", "Chromium", "Not A(Brand"].includes(b.brand));
|
|
115
268
|
if (brand)
|
|
116
269
|
return brand.brand.toLowerCase();
|
|
117
270
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
271
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
272
|
+
if (/edg\//.test(userAgent))
|
|
273
|
+
return "edge";
|
|
274
|
+
if (/chrome/.test(userAgent) && !/edg\//.test(userAgent))
|
|
275
|
+
return "chrome";
|
|
276
|
+
if (/firefox/.test(userAgent))
|
|
277
|
+
return "firefox";
|
|
278
|
+
if (/safari/.test(userAgent) && !/chrome/.test(userAgent))
|
|
279
|
+
return "safari";
|
|
280
|
+
return "unknown";
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
(0, utils_1.log)(this.debug, "Browser detection failed", error);
|
|
284
|
+
return "unknown";
|
|
121
285
|
}
|
|
122
|
-
const userAgent = navigator.userAgent.toLowerCase();
|
|
123
|
-
if (/edg\//.test(userAgent))
|
|
124
|
-
return "edge";
|
|
125
|
-
if (/chrome/.test(userAgent) && !/edg\//.test(userAgent))
|
|
126
|
-
return "chrome";
|
|
127
|
-
if (/firefox/.test(userAgent))
|
|
128
|
-
return "firefox";
|
|
129
|
-
if (/safari/.test(userAgent) && !/chrome/.test(userAgent))
|
|
130
|
-
return "safari";
|
|
131
|
-
return "unknown";
|
|
132
286
|
}
|
|
133
287
|
detectBrowserVersion() {
|
|
134
|
-
|
|
135
|
-
|
|
288
|
+
try {
|
|
289
|
+
if ("userAgentData" in navigator) {
|
|
136
290
|
const brands = navigator.userAgentData.brands;
|
|
137
291
|
const brand = brands.find((b) => !["Chrome HTML", "Chromium", "Not A(Brand"].includes(b.brand));
|
|
138
292
|
if (brand)
|
|
139
293
|
return brand.version;
|
|
140
294
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
295
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
296
|
+
const browserPatterns = {
|
|
297
|
+
chrome: /chrome\/(\d+)/,
|
|
298
|
+
firefox: /firefox\/(\d+)/,
|
|
299
|
+
safari: /version\/(\d+)/,
|
|
300
|
+
edge: /edg\/(\d+)/,
|
|
301
|
+
};
|
|
302
|
+
const browserType = this.detectBrowserType();
|
|
303
|
+
const pattern = browserPatterns[browserType];
|
|
304
|
+
if (!pattern)
|
|
305
|
+
return "unknown";
|
|
306
|
+
const match = userAgent.match(pattern);
|
|
307
|
+
return match ? match[1] : "unknown";
|
|
144
308
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
chrome: /chrome\/(\d+)/,
|
|
148
|
-
firefox: /firefox\/(\d+)/,
|
|
149
|
-
safari: /version\/(\d+)/,
|
|
150
|
-
edge: /edg\/(\d+)/,
|
|
151
|
-
};
|
|
152
|
-
const browserType = this.detectBrowserType();
|
|
153
|
-
const pattern = browserPatterns[browserType];
|
|
154
|
-
if (!pattern)
|
|
309
|
+
catch (error) {
|
|
310
|
+
(0, utils_1.log)(this.debug, "Browser version detection failed", error);
|
|
155
311
|
return "unknown";
|
|
156
|
-
|
|
157
|
-
return match ? match[1] : "unknown";
|
|
312
|
+
}
|
|
158
313
|
}
|
|
159
314
|
startBatchProcessing() {
|
|
160
|
-
setInterval(() => {
|
|
161
|
-
if (this.eventQueue.length > 0
|
|
162
|
-
this.
|
|
315
|
+
this.batchProcessingInterval = setInterval(() => {
|
|
316
|
+
if (this.eventQueue.length > 0 ||
|
|
317
|
+
this.purchaseBatch.length > 0 ||
|
|
318
|
+
this.attributeQueue.length > 0) {
|
|
319
|
+
this.processBatch().catch((error) => {
|
|
320
|
+
(0, utils_1.log)(this.debug, "Batch processing failed", error);
|
|
321
|
+
});
|
|
163
322
|
}
|
|
164
323
|
}, this.batchInterval);
|
|
165
324
|
}
|
|
@@ -167,33 +326,48 @@ class WebSDK {
|
|
|
167
326
|
this.eventQueue.push(payload);
|
|
168
327
|
(0, utils_1.log)(this.debug, "Event queued", payload);
|
|
169
328
|
if (this.eventQueue.length >= this.maxBatchSize) {
|
|
170
|
-
this.processBatch()
|
|
329
|
+
this.processBatch().catch((error) => {
|
|
330
|
+
(0, utils_1.log)(this.debug, "Batch processing failed", error);
|
|
331
|
+
});
|
|
171
332
|
}
|
|
172
333
|
}
|
|
173
334
|
async processBatch() {
|
|
174
335
|
if (this.isProcessingQueue)
|
|
175
336
|
return;
|
|
176
337
|
this.isProcessingQueue = true;
|
|
177
|
-
const
|
|
338
|
+
const eventsToSend = [...this.eventQueue];
|
|
339
|
+
const purchasesToSend = [...this.purchaseBatch];
|
|
340
|
+
const attributesToSend = { ...this.attributeQueue };
|
|
341
|
+
this.eventQueue = [];
|
|
342
|
+
this.purchaseBatch = [];
|
|
343
|
+
this.attributeQueue = {};
|
|
178
344
|
try {
|
|
179
|
-
await this.sendBatchToServer(
|
|
345
|
+
await this.sendBatchToServer(eventsToSend, purchasesToSend, attributesToSend);
|
|
180
346
|
}
|
|
181
347
|
catch (error) {
|
|
182
|
-
this.eventQueue.unshift(...
|
|
348
|
+
this.eventQueue.unshift(...eventsToSend);
|
|
349
|
+
this.purchaseBatch.unshift(...purchasesToSend);
|
|
350
|
+
this.attributeQueue = { ...this.attributeQueue, ...attributesToSend };
|
|
183
351
|
(0, utils_1.log)(this.debug, "Batch processing failed", error);
|
|
352
|
+
throw error;
|
|
184
353
|
}
|
|
185
354
|
finally {
|
|
186
355
|
this.isProcessingQueue = false;
|
|
187
356
|
}
|
|
188
357
|
}
|
|
189
|
-
async sendBatchToServer(
|
|
358
|
+
async sendBatchToServer(events, purchases, currentAttributes) {
|
|
190
359
|
var _a;
|
|
360
|
+
if (!this.deviceDetails) {
|
|
361
|
+
await this.initializeDeviceDetails();
|
|
362
|
+
}
|
|
191
363
|
const payload = {
|
|
192
364
|
sdkVersion: this.sdkVersion,
|
|
193
365
|
deviceInfo: this.deviceDetails,
|
|
194
366
|
userId: (_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.id,
|
|
195
|
-
|
|
196
|
-
|
|
367
|
+
time: Date.now(),
|
|
368
|
+
events: events,
|
|
369
|
+
purchases: purchases,
|
|
370
|
+
userAttributes: currentAttributes,
|
|
197
371
|
};
|
|
198
372
|
try {
|
|
199
373
|
const response = await fetch(`${this.endpoint}/analytics/data`, {
|
|
@@ -207,10 +381,17 @@ class WebSDK {
|
|
|
207
381
|
if (!response.ok) {
|
|
208
382
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
209
383
|
}
|
|
384
|
+
if (this.debug) {
|
|
385
|
+
(0, utils_1.log)(this.debug, `Batch dispatched successfully: ${payload.events.length} events, ${payload.purchases.length} purchases, ${Object.keys(payload.userAttributes).length} attributes`);
|
|
386
|
+
}
|
|
210
387
|
await response.json();
|
|
388
|
+
if (Object.keys(currentAttributes).length > 0) {
|
|
389
|
+
this.attributeQueue = {};
|
|
390
|
+
sessionStorage.removeItem(`${STORAGE_PREFIX}${this.apiKey}.custom_attributes`);
|
|
391
|
+
}
|
|
211
392
|
}
|
|
212
393
|
catch (error) {
|
|
213
|
-
(0, utils_1.log)(this.debug, "Failed to send
|
|
394
|
+
(0, utils_1.log)(this.debug, "Failed to send payload to server", error);
|
|
214
395
|
throw error;
|
|
215
396
|
}
|
|
216
397
|
}
|