@visitor-analytics-sdk/core 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Visitor Analytics
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,418 @@
1
+ interface AnalyticsRecord {
2
+ readonly id: string;
3
+ readonly timestamp: number;
4
+ readonly sessionId: string;
5
+ readonly pageUrl: string;
6
+ readonly pagePath: string;
7
+ readonly referrer: string;
8
+ readonly screenWidth: number;
9
+ readonly screenHeight: number;
10
+ readonly viewportWidth: number;
11
+ readonly viewportHeight: number;
12
+ readonly devicePixelRatio: number;
13
+ readonly browser: BrowserData;
14
+ readonly device: DeviceData;
15
+ readonly performance: PerformanceData;
16
+ readonly environment: EnvironmentData;
17
+ readonly features: FeatureData;
18
+ readonly interaction: InteractionData;
19
+ readonly metadata: MetadataData;
20
+ }
21
+ interface BrowserData {
22
+ readonly name: string;
23
+ readonly version: string;
24
+ readonly engine: string;
25
+ readonly engineVersion: string;
26
+ readonly userAgent: string;
27
+ readonly language: string;
28
+ readonly cookiesEnabled: boolean;
29
+ readonly javaScriptEnabled: boolean;
30
+ readonly doNotTrack: boolean | null;
31
+ }
32
+ interface DeviceData {
33
+ readonly os: string;
34
+ readonly osVersion: string;
35
+ readonly platform: string;
36
+ readonly architecture: string;
37
+ readonly formFactor: DeviceFormFactor;
38
+ readonly screenWidth: number;
39
+ readonly screenHeight: number;
40
+ readonly viewportWidth: number;
41
+ readonly viewportHeight: number;
42
+ readonly devicePixelRatio: number;
43
+ readonly colorDepth: number;
44
+ readonly orientation: OrientationType;
45
+ readonly touchSupport: TouchSupport;
46
+ readonly hardwareConcurrency: number;
47
+ readonly maxTouchPoints: number;
48
+ }
49
+ type DeviceFormFactor = "desktop" | "mobile" | "tablet" | "smarttv" | "wearable" | "console" | "unknown";
50
+ type TouchSupport = "none" | "coarse" | "fine";
51
+ interface PerformanceData {
52
+ readonly navigationTiming: NavigationTiming | null;
53
+ readonly paintTiming: PaintTiming | null;
54
+ readonly largestContentfulPaint: number | null;
55
+ readonly firstContentfulPaint: number | null;
56
+ readonly cumulativeLayoutShift: number | null;
57
+ readonly interactionToNextPaint: number | null;
58
+ readonly deviceMemory: number | null;
59
+ readonly networkType: string;
60
+ readonly effectiveType: string;
61
+ readonly downlink: number | null;
62
+ readonly rtt: number | null;
63
+ readonly saveData: boolean;
64
+ }
65
+ interface NavigationTiming {
66
+ readonly redirectTime: number;
67
+ readonly dnsLookupTime: number;
68
+ readonly tcpConnectTime: number;
69
+ readonly requestTime: number;
70
+ readonly responseTime: number;
71
+ readonly domInteractiveTime: number;
72
+ readonly domContentLoadedTime: number;
73
+ readonly domCompleteTime: number;
74
+ readonly loadTime: number;
75
+ readonly duration: number;
76
+ }
77
+ interface PaintTiming {
78
+ readonly firstPaint: number;
79
+ readonly firstContentfulPaint: number;
80
+ }
81
+ interface EnvironmentData {
82
+ readonly timezone: string;
83
+ readonly timezoneOffset: number;
84
+ readonly languages: readonly string[];
85
+ readonly language: string;
86
+ readonly locale: string;
87
+ readonly prefersColorScheme: "light" | "dark" | "no-preference";
88
+ readonly prefersReducedMotion: boolean;
89
+ readonly prefersContrast: "no-preference" | "more" | "less" | "custom";
90
+ readonly colorGamut: "srgb" | "p3" | "rec2020" | "unknown";
91
+ readonly hdr: boolean;
92
+ readonly localStorageSupport: boolean;
93
+ readonly sessionStorageSupport: boolean;
94
+ readonly indexedDBSupport: boolean;
95
+ readonly cookieSupport: boolean;
96
+ readonly cacheAPISupport: boolean;
97
+ }
98
+ interface FeatureData {
99
+ readonly webgl: boolean;
100
+ readonly webgl2: boolean;
101
+ readonly webgpu: boolean;
102
+ readonly wasm: boolean;
103
+ readonly webrtc: boolean;
104
+ readonly websockets: boolean;
105
+ readonly broadcastChannel: boolean;
106
+ readonly sharedWorker: boolean;
107
+ readonly serviceWorker: boolean;
108
+ readonly notifications: boolean;
109
+ readonly clipboard: boolean;
110
+ readonly fileSystemAccess: boolean;
111
+ readonly webShare: boolean;
112
+ readonly webAuthn: boolean;
113
+ readonly pushManager: boolean;
114
+ readonly geolocation: boolean;
115
+ readonly bluetooth: boolean;
116
+ readonly usb: boolean;
117
+ readonly serial: boolean;
118
+ readonly gamepad: boolean;
119
+ readonly pictureInPicture: boolean;
120
+ readonly fullscreen: boolean;
121
+ }
122
+ interface InteractionData {
123
+ readonly sessionDuration: number;
124
+ readonly timeOnPage: number;
125
+ readonly routeChanges: number;
126
+ readonly scrollDepth: number;
127
+ readonly clickCount: number;
128
+ readonly resizeCount: number;
129
+ readonly visibilityChanges: number;
130
+ readonly focusChanges: number;
131
+ readonly landingPage: string;
132
+ readonly exitPage: string | null;
133
+ readonly utmSource: string | null;
134
+ readonly utmMedium: string | null;
135
+ readonly utmCampaign: string | null;
136
+ readonly utmTerm: string | null;
137
+ readonly utmContent: string | null;
138
+ }
139
+ interface MetadataData {
140
+ readonly sdkVersion: string;
141
+ readonly buildTarget: string;
142
+ readonly collectorVersion: string;
143
+ readonly customData: Record<string, string | number | boolean>;
144
+ }
145
+ type CollectorCategory = "browser" | "device" | "performance" | "environment" | "features" | "interaction" | "custom";
146
+ interface Collector {
147
+ readonly name: string;
148
+ readonly category: CollectorCategory;
149
+ readonly version: string;
150
+ enabled: boolean;
151
+ collect(context: CollectorContext): Promise<Partial<AnalyticsRecord>>;
152
+ init?(context: CollectorContext): Promise<void>;
153
+ destroy?(): Promise<void>;
154
+ }
155
+ interface CollectorContext {
156
+ readonly document: DocumentLike;
157
+ readonly navigator: NavigatorLike;
158
+ readonly window: WindowLike;
159
+ readonly performance: PerformanceLike;
160
+ readonly location: LocationLike;
161
+ readonly history: HistoryLike;
162
+ readonly screen: ScreenLike;
163
+ }
164
+ interface DocumentLike {
165
+ readonly cookie: string;
166
+ readonly referrer: string;
167
+ readonly title: string;
168
+ readonly visibilityState: "visible" | "hidden" | "prerender";
169
+ readonly documentElement: {
170
+ scrollHeight: number;
171
+ };
172
+ createElement(tagName: string): HTMLElement;
173
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
174
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
175
+ }
176
+ interface NavigatorLike {
177
+ readonly userAgent: string;
178
+ readonly language: string;
179
+ readonly languages: readonly string[];
180
+ readonly platform: string;
181
+ readonly hardwareConcurrency: number;
182
+ readonly maxTouchPoints: number;
183
+ readonly cookieEnabled: boolean;
184
+ readonly doNotTrack: boolean | null;
185
+ readonly deviceMemory: number | undefined;
186
+ readonly connection: NetworkInformationLike | undefined;
187
+ readonly storage: StorageManagerLike | undefined;
188
+ readonly share?: (data: ShareData) => Promise<void>;
189
+ readonly clipboard: ClipboardLike | undefined;
190
+ readonly permissions: PermissionsLike | undefined;
191
+ }
192
+ interface WindowLike {
193
+ readonly innerWidth: number;
194
+ readonly innerHeight: number;
195
+ readonly screen: ScreenLike;
196
+ readonly devicePixelRatio: number;
197
+ readonly localStorage: Storage | undefined;
198
+ readonly sessionStorage: Storage | undefined;
199
+ readonly indexedDB: IDBFactory | undefined;
200
+ matchMedia(query: string): MediaQueryList | null;
201
+ requestIdleCallback?(callback: IdleRequestCallback, options?: IdleRequestOptions): number;
202
+ cancelIdleCallback?(handle: number): void;
203
+ requestAnimationFrame?(callback: FrameRequestCallback): number;
204
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
205
+ removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
206
+ }
207
+ interface PerformanceLike {
208
+ readonly timing: PerformanceTiming | undefined;
209
+ readonly navigation: PerformanceNavigation | undefined;
210
+ getEntries(): PerformanceEntryList;
211
+ getEntriesByType(name: string): readonly PerformanceEntry[];
212
+ getEntriesByName(name: string): readonly PerformanceEntry[];
213
+ mark?(name: string): void;
214
+ measure?(name: string, startMark?: string, endMark?: string): void;
215
+ clearMarks?(name?: string): void;
216
+ clearMeasures?(name?: string): void;
217
+ now(): number;
218
+ }
219
+ interface LocationLike {
220
+ readonly href: string;
221
+ readonly origin: string;
222
+ readonly pathname: string;
223
+ readonly search: string;
224
+ readonly hash: string;
225
+ readonly host: string;
226
+ readonly hostname: string;
227
+ readonly protocol: string;
228
+ readonly port: string;
229
+ }
230
+ interface HistoryLike {
231
+ readonly length: number;
232
+ pushState(state: unknown, title: string, url?: string | URL | null): void;
233
+ replaceState(state: unknown, title: string, url?: string | URL | null): void;
234
+ }
235
+ interface ScreenLike {
236
+ readonly width: number;
237
+ readonly height: number;
238
+ readonly availWidth: number;
239
+ readonly availHeight: number;
240
+ readonly colorDepth: number;
241
+ readonly pixelDepth: number;
242
+ readonly orientation: ScreenOrientationLike | undefined;
243
+ }
244
+ interface ScreenOrientationLike {
245
+ readonly type: OrientationType;
246
+ readonly angle: number;
247
+ }
248
+ interface NetworkInformationLike {
249
+ readonly type: string;
250
+ readonly effectiveType: string;
251
+ readonly downlink: number;
252
+ readonly rtt: number;
253
+ readonly saveData: boolean;
254
+ }
255
+ interface StorageManagerLike {
256
+ estimate(): Promise<StorageEstimate>;
257
+ persist(): Promise<boolean>;
258
+ persisted(): Promise<boolean>;
259
+ }
260
+ interface ClipboardLike {
261
+ readText(): Promise<string>;
262
+ writeText(text: string): Promise<void>;
263
+ }
264
+ interface PermissionsLike {
265
+ query(desc: PermissionDesc): Promise<PermissionStatus>;
266
+ }
267
+ interface PermissionDesc {
268
+ name: string;
269
+ }
270
+ type StorageType = "memory" | "localstorage" | "indexeddb" | "custom";
271
+ interface StorageAdapter {
272
+ save(record: AnalyticsRecord): Promise<void>;
273
+ saveBatch(records: readonly AnalyticsRecord[]): Promise<void>;
274
+ load(): Promise<readonly AnalyticsRecord[]>;
275
+ loadBatch(limit: number): Promise<readonly AnalyticsRecord[]>;
276
+ remove(ids: readonly string[]): Promise<void>;
277
+ count(): Promise<number>;
278
+ clear(): Promise<void>;
279
+ export(): Promise<string>;
280
+ }
281
+ interface UploaderConfig {
282
+ readonly endpoint: string;
283
+ readonly batchSize: number;
284
+ readonly flushInterval: number;
285
+ readonly maxRetries: number;
286
+ readonly retryBaseDelay: number;
287
+ readonly retryMaxDelay: number;
288
+ readonly compressionEnabled: boolean;
289
+ readonly deduplicationEnabled: boolean;
290
+ readonly headers: Record<string, string>;
291
+ readonly timeout: number;
292
+ }
293
+ interface UploadPayload {
294
+ readonly records: readonly AnalyticsRecord[];
295
+ readonly batchId: string;
296
+ readonly timestamp: number;
297
+ readonly sdkVersion: string;
298
+ }
299
+ interface UploadResult {
300
+ readonly success: boolean;
301
+ readonly batchId: string;
302
+ readonly statusCode?: number;
303
+ readonly error?: string;
304
+ readonly retryable: boolean;
305
+ }
306
+ type UploadEventHandler = (event: UploadEvent) => void;
307
+ interface UploadEvent {
308
+ readonly type: "batch-sent" | "batch-success" | "batch-failed" | "retry-scheduled" | "queue-full";
309
+ readonly batchId: string;
310
+ readonly recordCount: number;
311
+ readonly timestamp: number;
312
+ readonly error?: string;
313
+ readonly retryCount?: number;
314
+ readonly nextRetryAt?: number;
315
+ }
316
+ interface Plugin {
317
+ readonly name: string;
318
+ readonly version: string;
319
+ readonly description: string;
320
+ install(analytics: PluginContext): void;
321
+ uninstall?(analytics: PluginContext): void;
322
+ }
323
+ interface PluginContext {
324
+ addCollector(collector: Collector): void;
325
+ removeCollector(name: string): void;
326
+ on(event: AnalyticsEvent, handler: (...args: readonly unknown[]) => void): void;
327
+ off(event: AnalyticsEvent, handler: (...args: readonly unknown[]) => void): void;
328
+ getConfig(): AnalyticsConfig;
329
+ }
330
+ type AnalyticsEvent = "start" | "stop" | "flush" | "sync" | "record-collected" | "batch-uploaded" | "batch-failed" | "error" | "collector-registered" | "collector-removed" | "plugin-installed" | "plugin-uninstalled" | "storage-saved" | "storage-loaded" | "config-changed";
331
+ interface AnalyticsConfig {
332
+ readonly endpoint: string;
333
+ readonly storage: StorageType | StorageAdapter;
334
+ readonly autoStart: boolean;
335
+ readonly batchSize: number;
336
+ readonly flushInterval: number;
337
+ readonly maxRetries: number;
338
+ readonly retryBaseDelay: number;
339
+ readonly retryMaxDelay: number;
340
+ readonly compressionEnabled: boolean;
341
+ readonly deduplicationEnabled: boolean;
342
+ readonly headers: Record<string, string>;
343
+ readonly timeout: number;
344
+ readonly collectBrowser: boolean;
345
+ readonly collectDevice: boolean;
346
+ readonly collectPerformance: boolean;
347
+ readonly collectEnvironment: boolean;
348
+ readonly collectFeatures: boolean;
349
+ readonly collectInteraction: boolean;
350
+ readonly includeUserAgent: boolean;
351
+ readonly includeReferrer: boolean;
352
+ readonly sessionTimeout: number;
353
+ readonly customData: Record<string, string | number | boolean>;
354
+ }
355
+ type AnalyticsConfigPartial = Partial<AnalyticsConfig>;
356
+ interface VisitorAnalyticsFactory {
357
+ create(config: AnalyticsConfigPartial): VisitorAnalyticsInstance;
358
+ }
359
+ interface VisitorAnalyticsInstance {
360
+ start(): void;
361
+ stop(): void;
362
+ flush(): Promise<void>;
363
+ sync(): Promise<void>;
364
+ retryFailed(): Promise<void>;
365
+ use(plugin: Plugin): void;
366
+ addCollector(collector: Collector): void;
367
+ removeCollector(name: string): void;
368
+ getCollectedData(): Promise<readonly AnalyticsRecord[]>;
369
+ export(): Promise<string>;
370
+ on(event: AnalyticsEvent, handler: (...args: readonly unknown[]) => void): void;
371
+ off(event: AnalyticsEvent, handler: (...args: readonly unknown[]) => void): void;
372
+ destroy(): Promise<void>;
373
+ }
374
+
375
+ declare class VisitorAnalytics implements VisitorAnalyticsInstance {
376
+ private config;
377
+ private eventBus;
378
+ private pluginManager;
379
+ private storage;
380
+ private uploader;
381
+ private collectors;
382
+ private collectorContext;
383
+ private isRunning;
384
+ private sessionId;
385
+ private collectTimer;
386
+ constructor(config?: AnalyticsConfigPartial);
387
+ private registerBuiltInCollectors;
388
+ private buildCollectorContext;
389
+ start(): void;
390
+ stop(): void;
391
+ flush(): Promise<void>;
392
+ sync(): Promise<void>;
393
+ retryFailed(): Promise<void>;
394
+ use(plugin: Plugin): void;
395
+ addCollector(collector: Collector): void;
396
+ removeCollector(name: string): void;
397
+ getCollectedData(): Promise<readonly AnalyticsRecord[]>;
398
+ export(): Promise<string>;
399
+ on(event: AnalyticsEvent, handler: (...args: readonly unknown[]) => void): void;
400
+ off(event: AnalyticsEvent, handler: (...args: readonly unknown[]) => void): void;
401
+ destroy(): Promise<void>;
402
+ private collectAndStore;
403
+ private collectRecord;
404
+ private createPluginContext;
405
+ }
406
+ declare function createAnalytics(config?: AnalyticsConfigPartial): VisitorAnalyticsInstance;
407
+
408
+ type Handler = (...args: readonly unknown[]) => void;
409
+ declare class EventBus {
410
+ private readonly listeners;
411
+ on(event: AnalyticsEvent, handler: Handler): void;
412
+ off(event: AnalyticsEvent, handler: Handler): void;
413
+ emit(event: AnalyticsEvent, ...args: readonly unknown[]): void;
414
+ removeAllListeners(event?: AnalyticsEvent): void;
415
+ listenerCount(event: AnalyticsEvent): number;
416
+ }
417
+
418
+ export { type AnalyticsConfig, type AnalyticsConfigPartial, type AnalyticsEvent, type AnalyticsRecord, type BrowserData, type ClipboardLike, type Collector, type CollectorCategory, type CollectorContext, type DeviceData, type DeviceFormFactor, type DocumentLike, type EnvironmentData, EventBus, type FeatureData, type HistoryLike, type InteractionData, type LocationLike, type MetadataData, type NavigationTiming, type NavigatorLike, type NetworkInformationLike, type PaintTiming, type PerformanceData, type PerformanceLike, type PermissionDesc, type PermissionsLike, type Plugin, type PluginContext, type ScreenLike, type ScreenOrientationLike, type StorageAdapter, type StorageManagerLike, type StorageType, type TouchSupport, type UploadEvent, type UploadEventHandler, type UploadPayload, type UploadResult, type UploaderConfig, VisitorAnalytics, type VisitorAnalyticsFactory, type VisitorAnalyticsInstance, type WindowLike, createAnalytics };