@levi123/trackers 4.0.0-dev.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 +220 -0
- package/dist/esm/index.js +402 -0
- package/dist/esm/index.mjs +402 -0
- package/dist/esm/tooling/tsconfig/dist/callback-worker.d.ts +1 -0
- package/dist/esm/tooling/tsconfig/dist/data/callbackStore.d.ts +20 -0
- package/dist/esm/tooling/tsconfig/dist/data/eventStore.d.ts +14 -0
- package/dist/esm/tooling/tsconfig/dist/data/index.d.ts +2 -0
- package/dist/esm/tooling/tsconfig/dist/debug/index.d.ts +9 -0
- package/dist/esm/tooling/tsconfig/dist/event-worker.d.ts +1 -0
- package/dist/esm/tooling/tsconfig/dist/handlers/event-worker/click-handler.d.ts +2 -0
- package/dist/esm/tooling/tsconfig/dist/handlers/event-worker/index.d.ts +5 -0
- package/dist/esm/tooling/tsconfig/dist/handlers/event-worker/page-view-handler.d.ts +2 -0
- package/dist/esm/tooling/tsconfig/dist/handlers/event-worker/performance-entry-handler.d.ts +2 -0
- package/dist/esm/tooling/tsconfig/dist/handlers/event-worker/performance-handler.d.ts +2 -0
- package/dist/esm/tooling/tsconfig/dist/handlers/event-worker/scroll-handler.d.ts +2 -0
- package/dist/esm/tooling/tsconfig/dist/handlers/index.d.ts +1 -0
- package/dist/esm/tooling/tsconfig/dist/index.d.ts +2 -0
- package/dist/esm/tooling/tsconfig/dist/tracking-sdk.d.ts +54 -0
- package/dist/esm/tooling/tsconfig/dist/types/callback.d.ts +43 -0
- package/dist/esm/tooling/tsconfig/dist/types/event.d.ts +91 -0
- package/dist/esm/tooling/tsconfig/dist/types/index.d.ts +4 -0
- package/dist/esm/tooling/tsconfig/dist/types/tracking.d.ts +16 -0
- package/dist/esm/tooling/tsconfig/dist/types/worker.d.ts +21 -0
- package/dist/esm/tooling/tsconfig/dist/utils/event-worker.d.ts +1 -0
- package/dist/esm/tooling/tsconfig/dist/utils/index.d.ts +1 -0
- package/dist/umd/index.js +1 -0
- package/dist/umd/tooling/tsconfig/dist/callback-worker.d.ts +1 -0
- package/dist/umd/tooling/tsconfig/dist/data/callbackStore.d.ts +20 -0
- package/dist/umd/tooling/tsconfig/dist/data/eventStore.d.ts +14 -0
- package/dist/umd/tooling/tsconfig/dist/data/index.d.ts +2 -0
- package/dist/umd/tooling/tsconfig/dist/debug/index.d.ts +9 -0
- package/dist/umd/tooling/tsconfig/dist/event-worker.d.ts +1 -0
- package/dist/umd/tooling/tsconfig/dist/handlers/event-worker/click-handler.d.ts +2 -0
- package/dist/umd/tooling/tsconfig/dist/handlers/event-worker/index.d.ts +5 -0
- package/dist/umd/tooling/tsconfig/dist/handlers/event-worker/page-view-handler.d.ts +2 -0
- package/dist/umd/tooling/tsconfig/dist/handlers/event-worker/performance-entry-handler.d.ts +2 -0
- package/dist/umd/tooling/tsconfig/dist/handlers/event-worker/performance-handler.d.ts +2 -0
- package/dist/umd/tooling/tsconfig/dist/handlers/event-worker/scroll-handler.d.ts +2 -0
- package/dist/umd/tooling/tsconfig/dist/handlers/index.d.ts +1 -0
- package/dist/umd/tooling/tsconfig/dist/index.d.ts +2 -0
- package/dist/umd/tooling/tsconfig/dist/tracking-sdk.d.ts +54 -0
- package/dist/umd/tooling/tsconfig/dist/types/callback.d.ts +43 -0
- package/dist/umd/tooling/tsconfig/dist/types/event.d.ts +91 -0
- package/dist/umd/tooling/tsconfig/dist/types/index.d.ts +4 -0
- package/dist/umd/tooling/tsconfig/dist/types/tracking.d.ts +16 -0
- package/dist/umd/tooling/tsconfig/dist/types/worker.d.ts +21 -0
- package/dist/umd/tooling/tsconfig/dist/utils/event-worker.d.ts +1 -0
- package/dist/umd/tooling/tsconfig/dist/utils/index.d.ts +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
class DebugTrackers {
|
|
3
|
+
constructor(enableLog) {
|
|
4
|
+
this.enableLog = !!enableLog;
|
|
5
|
+
}
|
|
6
|
+
log(message, ...args) {
|
|
7
|
+
this.enableLog && console.log(message, ...args);
|
|
8
|
+
}
|
|
9
|
+
warn(message, ...args) {
|
|
10
|
+
this.enableLog && console.warn(message, ...args);
|
|
11
|
+
}
|
|
12
|
+
error(message, ...args) {
|
|
13
|
+
this.enableLog && console.error(message, ...args);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const debugTrackers = new DebugTrackers();
|
|
17
|
+
|
|
18
|
+
// ----- Enums -----
|
|
19
|
+
var ITrackingEvent;
|
|
20
|
+
(function (ITrackingEvent) {
|
|
21
|
+
ITrackingEvent["PAGE_LOAD"] = "pageLoad";
|
|
22
|
+
ITrackingEvent["CLICK"] = "click";
|
|
23
|
+
ITrackingEvent["PERFORMANCE"] = "performance";
|
|
24
|
+
ITrackingEvent["PERFORMANCE_ENTRY"] = "performanceEntry";
|
|
25
|
+
ITrackingEvent["SCROLL"] = "scroll";
|
|
26
|
+
ITrackingEvent["MANUAL_CLICK"] = "manualClick";
|
|
27
|
+
})(ITrackingEvent || (ITrackingEvent = {}));
|
|
28
|
+
|
|
29
|
+
class GXTrackingSDK {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.config = {
|
|
32
|
+
events: [ITrackingEvent.PAGE_LOAD, ITrackingEvent.CLICK],
|
|
33
|
+
workerTimeout: 5000,
|
|
34
|
+
};
|
|
35
|
+
this.isInitialized = false;
|
|
36
|
+
this.eventWorker = null;
|
|
37
|
+
this.callbackWorker = null;
|
|
38
|
+
this.callbacks = {};
|
|
39
|
+
this.workerStatus = {
|
|
40
|
+
eventWorker: 'idle',
|
|
41
|
+
callbackWorker: 'idle',
|
|
42
|
+
};
|
|
43
|
+
this.perEventCallbacks = new Map();
|
|
44
|
+
// Private event handlers
|
|
45
|
+
this.handlePageLoad = () => {
|
|
46
|
+
this.trackEvent(ITrackingEvent.PAGE_LOAD, {
|
|
47
|
+
timestamp: Date.now(),
|
|
48
|
+
url: window.location.href,
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
this.handleClick = (e) => {
|
|
52
|
+
const target = e.target;
|
|
53
|
+
if (target.tagName !== 'SCRIPT' && target.tagName !== 'STYLE')
|
|
54
|
+
return;
|
|
55
|
+
this.trackEvent(ITrackingEvent.CLICK, {
|
|
56
|
+
target: target.tagName,
|
|
57
|
+
targetId: target.id || '',
|
|
58
|
+
targetClass: target.className || '',
|
|
59
|
+
x: e.clientX,
|
|
60
|
+
y: e.clientY,
|
|
61
|
+
timestamp: Date.now(),
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
if (typeof window !== 'undefined' && !window.Worker) {
|
|
65
|
+
debugTrackers.warn('Web Worker not supported. Falling back to main thread.');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
init(userConfig = {}) {
|
|
70
|
+
if (this.isInitialized) {
|
|
71
|
+
debugTrackers.warn('SDK already initialized');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Merge config
|
|
75
|
+
Object.assign(this.config, userConfig);
|
|
76
|
+
debugTrackers.log('🚀 GXTrackingSDK initialized with config:', this.config);
|
|
77
|
+
// Initialize workers
|
|
78
|
+
this.initWorkers();
|
|
79
|
+
const handleStartTracking = () => {
|
|
80
|
+
setTimeout(() => {
|
|
81
|
+
this.isInitialized = true;
|
|
82
|
+
this.startTracking();
|
|
83
|
+
debugTrackers.log('✅ All workers are running');
|
|
84
|
+
}, 0);
|
|
85
|
+
};
|
|
86
|
+
if (document.readyState === 'complete') {
|
|
87
|
+
handleStartTracking();
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
window.addEventListener('load', handleStartTracking);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
initWorkers() {
|
|
94
|
+
this.initEventWorker();
|
|
95
|
+
this.initCallbackWorker();
|
|
96
|
+
}
|
|
97
|
+
initEventWorker() {
|
|
98
|
+
try {
|
|
99
|
+
// Create Event Worker from package source (bundled by the app/bundler)
|
|
100
|
+
this.eventWorker = new Worker(new URL('./event-worker.ts', import.meta.url), {
|
|
101
|
+
type: 'module',
|
|
102
|
+
});
|
|
103
|
+
this.eventWorker.onmessage = (e) => {
|
|
104
|
+
const { type, data } = e.data;
|
|
105
|
+
this.workerStatus.eventWorker = 'active';
|
|
106
|
+
switch (type) {
|
|
107
|
+
case 'processed':
|
|
108
|
+
this.sendToCallbackWorker({
|
|
109
|
+
type: 'processedResult',
|
|
110
|
+
event: data.event,
|
|
111
|
+
eventType: data.event,
|
|
112
|
+
processedData: data.processedData,
|
|
113
|
+
timestamp: Date.now(),
|
|
114
|
+
});
|
|
115
|
+
break;
|
|
116
|
+
case 'error':
|
|
117
|
+
this.handleError(data);
|
|
118
|
+
break;
|
|
119
|
+
default:
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
this.eventWorker.onerror = (error) => {
|
|
123
|
+
this.workerStatus.eventWorker = 'error';
|
|
124
|
+
this.handleError({ message: 'Event Worker crashed', error });
|
|
125
|
+
};
|
|
126
|
+
// Send initial config to Event Worker
|
|
127
|
+
this.sendToEventWorker({ type: 'init', config: this.config });
|
|
128
|
+
this.workerStatus.eventWorker = 'ready';
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
this.handleError({ message: 'Failed to create Event Worker', error });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
initCallbackWorker() {
|
|
135
|
+
try {
|
|
136
|
+
this.callbackWorker = new Worker(new URL('./callback-worker.ts', import.meta.url), {
|
|
137
|
+
type: 'module',
|
|
138
|
+
});
|
|
139
|
+
this.callbackWorker.onmessage = (e) => {
|
|
140
|
+
const { type, data } = e.data;
|
|
141
|
+
this.workerStatus.callbackWorker = 'active';
|
|
142
|
+
switch (type) {
|
|
143
|
+
case 'executeCallbacks': {
|
|
144
|
+
// Execute registered callbacks on main thread and send result back
|
|
145
|
+
const { eventType, requestId, payload } = e.data || {};
|
|
146
|
+
const callbacks = (eventType && this.callbacks[eventType]) || [];
|
|
147
|
+
let successCount = 0;
|
|
148
|
+
let errorCount = 0;
|
|
149
|
+
const start = Date.now();
|
|
150
|
+
const perEventId = (payload && payload.data && payload.data.eventId);
|
|
151
|
+
const perEventCb = perEventId ? this.perEventCallbacks.get(perEventId) : undefined;
|
|
152
|
+
if (perEventCb) {
|
|
153
|
+
try {
|
|
154
|
+
perEventCb(payload);
|
|
155
|
+
successCount++;
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
errorCount++;
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
this.perEventCallbacks.delete(perEventId);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (callbacks.length > 0) {
|
|
165
|
+
callbacks.forEach((cb) => {
|
|
166
|
+
try {
|
|
167
|
+
cb(payload);
|
|
168
|
+
successCount++;
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
errorCount++;
|
|
172
|
+
// also forward error to error handlers if any
|
|
173
|
+
if (this.callbacks.error) {
|
|
174
|
+
this.callbacks.error.forEach((eCb) => {
|
|
175
|
+
try {
|
|
176
|
+
eCb({
|
|
177
|
+
type: 'error',
|
|
178
|
+
data: {
|
|
179
|
+
message: 'Callback error',
|
|
180
|
+
error: this.serializeError(err),
|
|
181
|
+
},
|
|
182
|
+
timestamp: Date.now(),
|
|
183
|
+
processingTime: 0,
|
|
184
|
+
workerId: 'tracking-sdk',
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
catch (_a) { }
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
const executionTime = Date.now() - start;
|
|
194
|
+
// Respond to worker with results
|
|
195
|
+
this.sendToCallbackWorker({
|
|
196
|
+
type: 'executionResult',
|
|
197
|
+
requestId,
|
|
198
|
+
successCount,
|
|
199
|
+
errorCount,
|
|
200
|
+
executionTime,
|
|
201
|
+
});
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
case 'callbackReady':
|
|
205
|
+
debugTrackers.log('📨 Callback processed successfully');
|
|
206
|
+
break;
|
|
207
|
+
case 'error':
|
|
208
|
+
this.handleError(data);
|
|
209
|
+
break;
|
|
210
|
+
default:
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
this.callbackWorker.onerror = (error) => {
|
|
214
|
+
this.workerStatus.callbackWorker = 'error';
|
|
215
|
+
this.handleError({ message: 'Callback Worker crashed', error });
|
|
216
|
+
};
|
|
217
|
+
// Send initial config to Callback Worker
|
|
218
|
+
this.sendToCallbackWorker({
|
|
219
|
+
type: 'init',
|
|
220
|
+
config: this.config,
|
|
221
|
+
callbacks: Object.keys(this.callbacks), // Inform about registered callbacks
|
|
222
|
+
});
|
|
223
|
+
this.workerStatus.callbackWorker = 'ready';
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
this.handleError({ message: 'Failed to create Callback Worker', error });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
startTracking() {
|
|
230
|
+
if (typeof window === 'undefined')
|
|
231
|
+
return;
|
|
232
|
+
debugTrackers.log('👁️ Starting event tracking...', this.config.events);
|
|
233
|
+
// Track page load events
|
|
234
|
+
if (this.config.events.includes(ITrackingEvent.PAGE_LOAD)) {
|
|
235
|
+
this.handlePageLoad();
|
|
236
|
+
}
|
|
237
|
+
// Track user clicks
|
|
238
|
+
this.config.events.includes(ITrackingEvent.CLICK) && document.addEventListener('click', this.handleClick);
|
|
239
|
+
// Track performance metrics
|
|
240
|
+
if (this.config.events.includes(ITrackingEvent.PERFORMANCE) && 'PerformanceObserver' in window) {
|
|
241
|
+
const observer = new PerformanceObserver((list) => {
|
|
242
|
+
list.getEntries().forEach((entry) => {
|
|
243
|
+
this.trackEvent(ITrackingEvent.PERFORMANCE_ENTRY, {
|
|
244
|
+
name: entry.name,
|
|
245
|
+
entryType: entry.entryType,
|
|
246
|
+
duration: Math.round(entry.duration),
|
|
247
|
+
startTime: Math.round(entry.startTime),
|
|
248
|
+
timestamp: Date.now(),
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
observer.observe({
|
|
253
|
+
entryTypes: ['navigation', 'paint', 'resource', 'largest-contentful-paint'],
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
debugTrackers.log('✅ All event listeners attached');
|
|
257
|
+
}
|
|
258
|
+
trackEvent(eventName, data, callback) {
|
|
259
|
+
if (!this.isInitialized) {
|
|
260
|
+
debugTrackers.warn('SDK not initialized. Call init() first.');
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const eventId = data.eventId || `ev_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
264
|
+
if (callback) {
|
|
265
|
+
this.perEventCallbacks.set(eventId, callback);
|
|
266
|
+
}
|
|
267
|
+
const eventData = {
|
|
268
|
+
type: 'track',
|
|
269
|
+
event: eventName,
|
|
270
|
+
data: Object.assign(Object.assign({}, data), { timestamp: Date.now(), eventId }),
|
|
271
|
+
};
|
|
272
|
+
debugTrackers.log('📤 Sending event to Event Worker:', eventName, eventData.data);
|
|
273
|
+
this.sendToEventWorker(eventData);
|
|
274
|
+
}
|
|
275
|
+
// Communication methods
|
|
276
|
+
sendToEventWorker(message) {
|
|
277
|
+
if (!this.eventWorker) {
|
|
278
|
+
debugTrackers.error('Event Worker not initialized');
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
this.eventWorker.postMessage(message);
|
|
282
|
+
}
|
|
283
|
+
sendToCallbackWorker(message) {
|
|
284
|
+
if (!this.callbackWorker) {
|
|
285
|
+
debugTrackers.error('Callback Worker not initialized');
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
this.callbackWorker.postMessage(message);
|
|
289
|
+
}
|
|
290
|
+
// Callback registration
|
|
291
|
+
on(eventType, callback) {
|
|
292
|
+
if (!this.callbacks[eventType]) {
|
|
293
|
+
this.callbacks[eventType] = [];
|
|
294
|
+
}
|
|
295
|
+
this.callbacks[eventType].push(callback);
|
|
296
|
+
debugTrackers.log(`🔗 Registered callback for "${eventType}". Total: ${this.callbacks[eventType].length}`);
|
|
297
|
+
// Notify Callback Worker about new callback
|
|
298
|
+
this.sendToCallbackWorker({
|
|
299
|
+
type: 'registerCallback',
|
|
300
|
+
eventType: eventType,
|
|
301
|
+
callbackCount: this.callbacks[eventType].length,
|
|
302
|
+
});
|
|
303
|
+
return () => {
|
|
304
|
+
// Return unsubscribe function
|
|
305
|
+
if (!this.callbacks[eventType])
|
|
306
|
+
return;
|
|
307
|
+
const index = this.callbacks[eventType].indexOf(callback);
|
|
308
|
+
if (index > -1) {
|
|
309
|
+
this.callbacks[eventType].splice(index, 1);
|
|
310
|
+
debugTrackers.log(`❌ Unregistered callback for "${eventType}"`);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
// Error handling
|
|
315
|
+
handleError(errorData) {
|
|
316
|
+
const serialized = this.serializeError(errorData);
|
|
317
|
+
if (this.callbacks.error) {
|
|
318
|
+
this.callbacks.error.forEach((cb) => cb(serialized));
|
|
319
|
+
}
|
|
320
|
+
this.sendToCallbackWorker({
|
|
321
|
+
type: 'error',
|
|
322
|
+
data: serialized,
|
|
323
|
+
timestamp: Date.now(),
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
serializeError(input) {
|
|
327
|
+
try {
|
|
328
|
+
if (!input)
|
|
329
|
+
return { message: 'Unknown error' };
|
|
330
|
+
if (input instanceof Error) {
|
|
331
|
+
return { message: input.message, name: input.name, stack: input.stack };
|
|
332
|
+
}
|
|
333
|
+
if (typeof input === 'string')
|
|
334
|
+
return { message: input };
|
|
335
|
+
if (input.message || input.error) {
|
|
336
|
+
const err = input.error;
|
|
337
|
+
const base = {
|
|
338
|
+
message: input.message || 'Error',
|
|
339
|
+
context: undefined,
|
|
340
|
+
};
|
|
341
|
+
if (err instanceof Error) {
|
|
342
|
+
return Object.assign(Object.assign({}, base), { error: { message: err.message, name: err.name, stack: err.stack } });
|
|
343
|
+
}
|
|
344
|
+
try {
|
|
345
|
+
return Object.assign(Object.assign({}, base), { error: JSON.parse(JSON.stringify(err)) });
|
|
346
|
+
}
|
|
347
|
+
catch (_a) {
|
|
348
|
+
return Object.assign(Object.assign({}, base), { error: String(err) });
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return JSON.parse(JSON.stringify(input));
|
|
352
|
+
}
|
|
353
|
+
catch (_b) {
|
|
354
|
+
return { message: 'Unserializable error' };
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// Health check
|
|
358
|
+
getStatus() {
|
|
359
|
+
return {
|
|
360
|
+
isInitialized: this.isInitialized,
|
|
361
|
+
workerStatus: this.workerStatus,
|
|
362
|
+
registeredCallbacks: Object.keys(this.callbacks),
|
|
363
|
+
totalCallbacks: Object.values(this.callbacks).reduce((sum, cbs) => sum + cbs.length, 0),
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
// Cleanup
|
|
367
|
+
destroy() {
|
|
368
|
+
debugTrackers.log('🧹 Destroying GXTrackingSDK...');
|
|
369
|
+
// Remove event listeners
|
|
370
|
+
if (typeof window !== 'undefined') {
|
|
371
|
+
window.removeEventListener('load', this.handlePageLoad);
|
|
372
|
+
document.removeEventListener('click', this.handleClick);
|
|
373
|
+
}
|
|
374
|
+
// Terminate workers
|
|
375
|
+
if (this.eventWorker) {
|
|
376
|
+
this.eventWorker.terminate();
|
|
377
|
+
this.eventWorker = null;
|
|
378
|
+
debugTrackers.log('🔌 Event Worker terminated');
|
|
379
|
+
}
|
|
380
|
+
if (this.callbackWorker) {
|
|
381
|
+
this.callbackWorker.terminate();
|
|
382
|
+
this.callbackWorker = null;
|
|
383
|
+
debugTrackers.log('🔌 Callback Worker terminated');
|
|
384
|
+
}
|
|
385
|
+
// Clear callbacks
|
|
386
|
+
this.callbacks = {};
|
|
387
|
+
this.isInitialized = false;
|
|
388
|
+
this.workerStatus = {
|
|
389
|
+
eventWorker: 'destroyed',
|
|
390
|
+
callbackWorker: 'destroyed',
|
|
391
|
+
};
|
|
392
|
+
debugTrackers.log('✅ GXTrackingSDK destroyed successfully');
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
// Create and expose the SDK instance
|
|
396
|
+
const gxTrackingSDK = new GXTrackingSDK();
|
|
397
|
+
// Make it available globally
|
|
398
|
+
if (typeof window !== 'undefined') {
|
|
399
|
+
window.GXTrackingSDK = gxTrackingSDK;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export { ITrackingEvent, gxTrackingSDK };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ICallbackQueueItem, ICallbackStats, IPerformanceMetrics, IProcessedEventData, ITrackingConfig } from '../types';
|
|
2
|
+
interface CallbackStore {
|
|
3
|
+
getRegisteredCallbacks(): Record<string, number>;
|
|
4
|
+
getCallbackQueue(): ICallbackQueueItem[];
|
|
5
|
+
getIsProcessingCallbacks(): boolean;
|
|
6
|
+
getCallbackStats(): ICallbackStats;
|
|
7
|
+
getPendingExecutions(): Record<string, (result: {
|
|
8
|
+
successCount: number;
|
|
9
|
+
errorCount: number;
|
|
10
|
+
executionTime: number;
|
|
11
|
+
}) => void>;
|
|
12
|
+
setConfig(newConfig: ITrackingConfig): void;
|
|
13
|
+
setRegisteredCallbacks(newRegisteredCallbacks: Record<string, number>): void;
|
|
14
|
+
executeCallbacksForEvent(queueItem: ICallbackQueueItem): Promise<void>;
|
|
15
|
+
processCallbackQueue(): Promise<void>;
|
|
16
|
+
handleProcessedEvent(eventType: string, processedData: IProcessedEventData, metrics?: IPerformanceMetrics): void;
|
|
17
|
+
handleErrorEvent(eventType: string, errorData: IProcessedEventData): void;
|
|
18
|
+
}
|
|
19
|
+
export declare const callbackStore: CallbackStore;
|
|
20
|
+
export default callbackStore;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IEventData, IProcessingQueueItem, ITrackingConfig } from '../types';
|
|
2
|
+
interface EventStore {
|
|
3
|
+
getConfig(): ITrackingConfig;
|
|
4
|
+
getProcessingQueue(): IProcessingQueueItem[];
|
|
5
|
+
getIsProcessing(): boolean;
|
|
6
|
+
setConfig(newConfig: ITrackingConfig): void;
|
|
7
|
+
setProcessingQueue(newProcessingQueue: IProcessingQueueItem[]): void;
|
|
8
|
+
setIsProcessing(newIsProcessing: boolean): void;
|
|
9
|
+
processSingleEvent(eventName: string, eventData: IEventData): Promise<void>;
|
|
10
|
+
processQueue(): Promise<void>;
|
|
11
|
+
processEvent(eventName: string, eventData: IEventData): void;
|
|
12
|
+
}
|
|
13
|
+
export declare const eventStore: EventStore;
|
|
14
|
+
export default eventStore;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare class DebugTrackers {
|
|
2
|
+
private enableLog;
|
|
3
|
+
constructor(enableLog?: boolean);
|
|
4
|
+
log(message: string, ...args: any[]): void;
|
|
5
|
+
warn(message: string, ...args: any[]): void;
|
|
6
|
+
error(message: string, ...args: any[]): void;
|
|
7
|
+
}
|
|
8
|
+
export declare const debugTrackers: DebugTrackers;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './event-worker';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { EventCallback, IEventData, ITrackingConfig, ITrackingSDKStatus, IWorkerMessage, IWorkerStatus, UnsubscribeFunction } from './types';
|
|
2
|
+
import { ITrackingEvent } from './types';
|
|
3
|
+
declare global {
|
|
4
|
+
interface Window {
|
|
5
|
+
GXTrackingSDK: ITrackingSDKInterface;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export interface ITrackingSDKInterface {
|
|
9
|
+
config: ITrackingConfig;
|
|
10
|
+
isInitialized: boolean;
|
|
11
|
+
eventWorker: Worker | null;
|
|
12
|
+
callbackWorker: Worker | null;
|
|
13
|
+
callbacks: Record<string, EventCallback[]>;
|
|
14
|
+
workerStatus: IWorkerStatus;
|
|
15
|
+
init(userConfig?: Partial<ITrackingConfig>): void;
|
|
16
|
+
initWorkers(): void;
|
|
17
|
+
initEventWorker(): void;
|
|
18
|
+
initCallbackWorker(): void;
|
|
19
|
+
startTracking(): void;
|
|
20
|
+
trackEvent(eventName: ITrackingEvent, data: IEventData, callback?: EventCallback): void;
|
|
21
|
+
sendToEventWorker(message: IWorkerMessage): void;
|
|
22
|
+
sendToCallbackWorker(message: IWorkerMessage): void;
|
|
23
|
+
on(eventType: string, callback: EventCallback): UnsubscribeFunction;
|
|
24
|
+
handleError(errorData: any): void;
|
|
25
|
+
getStatus(): ITrackingSDKStatus;
|
|
26
|
+
destroy(): void;
|
|
27
|
+
}
|
|
28
|
+
declare class GXTrackingSDK implements ITrackingSDKInterface {
|
|
29
|
+
config: ITrackingConfig;
|
|
30
|
+
isInitialized: boolean;
|
|
31
|
+
eventWorker: Worker | null;
|
|
32
|
+
callbackWorker: Worker | null;
|
|
33
|
+
callbacks: Record<string, EventCallback[]>;
|
|
34
|
+
workerStatus: IWorkerStatus;
|
|
35
|
+
private perEventCallbacks;
|
|
36
|
+
constructor();
|
|
37
|
+
init(userConfig?: Partial<ITrackingConfig>): void;
|
|
38
|
+
initWorkers(): void;
|
|
39
|
+
initEventWorker(): void;
|
|
40
|
+
initCallbackWorker(): void;
|
|
41
|
+
startTracking(): void;
|
|
42
|
+
trackEvent(eventName: ITrackingEvent, data: IEventData, callback?: EventCallback): void;
|
|
43
|
+
sendToEventWorker(message: IWorkerMessage): void;
|
|
44
|
+
sendToCallbackWorker(message: IWorkerMessage): void;
|
|
45
|
+
on(eventType: string, callback: EventCallback): UnsubscribeFunction;
|
|
46
|
+
handleError(errorData: any): void;
|
|
47
|
+
private serializeError;
|
|
48
|
+
getStatus(): ITrackingSDKStatus;
|
|
49
|
+
destroy(): void;
|
|
50
|
+
private handlePageLoad;
|
|
51
|
+
private handleClick;
|
|
52
|
+
}
|
|
53
|
+
declare const gxTrackingSDK: GXTrackingSDK;
|
|
54
|
+
export { gxTrackingSDK };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { IPerformanceMetrics, IProcessedEventData } from './event';
|
|
2
|
+
import type { ITrackingConfig } from './tracking';
|
|
3
|
+
import type { IWorkerMessage } from './worker';
|
|
4
|
+
export interface ICallbackQueueItem {
|
|
5
|
+
eventType: string;
|
|
6
|
+
processedData: IProcessedEventData;
|
|
7
|
+
metrics?: IPerformanceMetrics;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
attempt: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ICallbackStats {
|
|
12
|
+
totalProcessed: number;
|
|
13
|
+
totalErrors: number;
|
|
14
|
+
lastProcessed: number | null;
|
|
15
|
+
}
|
|
16
|
+
export interface ICallbackWorkerMessage extends IWorkerMessage {
|
|
17
|
+
type: 'init' | 'registerCallback' | 'processedResult' | 'error' | 'healthCheck' | 'executionResult';
|
|
18
|
+
eventType?: string;
|
|
19
|
+
processedData?: IProcessedEventData;
|
|
20
|
+
metrics?: IPerformanceMetrics;
|
|
21
|
+
config?: ITrackingConfig;
|
|
22
|
+
callbackCount?: number;
|
|
23
|
+
requestId?: string;
|
|
24
|
+
successCount?: number;
|
|
25
|
+
errorCount?: number;
|
|
26
|
+
executionTime?: number;
|
|
27
|
+
}
|
|
28
|
+
export interface ICallbackWorkerResponse {
|
|
29
|
+
type: 'ready' | 'health' | 'callbackReady' | 'executionSummary' | 'callbackFailed' | 'heartbeat';
|
|
30
|
+
message?: string;
|
|
31
|
+
status?: 'busy' | 'idle';
|
|
32
|
+
queueLength?: number;
|
|
33
|
+
stats?: ICallbackStats;
|
|
34
|
+
eventType?: string;
|
|
35
|
+
successCount?: number;
|
|
36
|
+
errorCount?: number;
|
|
37
|
+
executionTime?: number;
|
|
38
|
+
dataSample?: IProcessedEventData;
|
|
39
|
+
error?: string;
|
|
40
|
+
finalAttempt?: boolean;
|
|
41
|
+
timestamp?: number;
|
|
42
|
+
processing?: boolean;
|
|
43
|
+
}
|