solo-analytics 0.1.0 → 0.2.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) 2025 Céss White
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.
package/README.md CHANGED
@@ -1,83 +1,92 @@
1
1
  # 📊 Solo Analytics
2
2
 
3
- Una biblioteca TypeScript ligera y completa para recopilar información del navegador y del dispositivo de una manera simple.
3
+ A lightweight TypeScript library for comprehensive browser and device information collection with a clean API surface.
4
4
 
5
- ## Características
5
+ [![npm version](https://img.shields.io/npm/v/solo-analytics.svg?style=flat-square)](https://www.npmjs.com/package/solo-analytics)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue?style=flat-square)](https://www.typescriptlang.org/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](https://github.com/cesswhite/solo-analytics/blob/main/LICENSE)
8
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/solo-analytics?style=flat-square)](https://bundlephobia.com/package/solo-analytics)
6
9
 
7
- - 🔍 Detección completa del navegador, sistema operativo y dispositivo
8
- - 📱 Identificación de dispositivos móviles, tablets y escritorio
9
- - 🌐 Información de red y conectividad
10
- - 📏 Detalles de pantalla y orientación
11
- - ⚡ Métricas de rendimiento
12
- - 🌍 Información de ubicación y entorno
13
- - ⚙️ Detección de funcionalidades avanzadas (cámara, micrófono, batería, etc.)
14
- - 🔒 Detección de modo incógnito
15
- - 🔄 Actualización automática opcional de datos
10
+ ## Features
16
11
 
17
- ## Instalación
12
+ - 🔍 Extensive browser, OS, and device detection with full TypeScript support
13
+ - 📱 Precise mobile, tablet, and desktop device classification
14
+ - 🌐 Network connectivity and performance data
15
+ - 📏 Screen and viewport dimensions with orientation detection
16
+ - ⚡ Comprehensive performance metrics (navigation, timing, memory)
17
+ - 🌍 Locale, timezone, and environment information
18
+ - ⚙️ Advanced feature detection (camera, microphone, battery, etc.)
19
+ - 🔒 Incognito/private mode detection
20
+ - 🔄 Auto-refresh capability for dynamic metrics
21
+
22
+ ## Installation
18
23
 
19
24
  ```bash
20
25
  npm install solo-analytics
21
26
  ```
22
27
 
23
- ## Uso básico
28
+ ## Basic Usage
24
29
 
25
30
  ```typescript
26
31
  import { useSoloAnalytics } from "solo-analytics";
27
32
 
28
- // Inicializar con opciones por defecto
33
+ // Initialize with default options
29
34
  const analytics = useSoloAnalytics();
30
35
 
31
- // Obtener información básica
32
- console.log("¿Es móvil?", analytics.isMobile);
33
- console.log("Navegador:", analytics.browserName);
34
- console.log("Sistema operativo:", analytics.osName);
36
+ // Access common properties
37
+ console.log("Mobile device:", analytics.isMobile);
38
+ console.log("Browser:", analytics.browserName);
39
+ console.log("OS:", analytics.osName);
35
40
 
36
- // Obtener todos los datos completos
37
- console.log("Datos completos:", analytics.data);
41
+ // Access the complete data object
42
+ console.log("Full analytics data:", analytics.data);
38
43
  ```
39
44
 
40
- ## Opciones de configuración
45
+ ## Configuration Options
41
46
 
42
47
  ```typescript
43
48
  import { useSoloAnalytics } from "solo-analytics";
44
49
 
45
50
  const analytics = useSoloAnalytics({
46
- // Actualizar automáticamente los datos dinámicos (red, performance)
51
+ // Automatically refresh dynamic data (network, performance)
47
52
  autoRefresh: true,
48
- // Intervalo de actualización en milisegundos (por defecto: 30000)
53
+ // Refresh interval in milliseconds (default: 30000)
49
54
  refreshInterval: 10000,
50
- // Detectar cambios de visibilidad de la página
55
+ // Track page visibility changes
51
56
  trackVisibility: true,
57
+ // Skip expensive async probes (incognito, battery, media, permissions)
58
+ detectFeatures: true,
59
+ // Defer async probes to idle time (default: true, recommended)
60
+ lazyFeatures: true,
52
61
  });
53
62
  ```
54
63
 
55
- ## API de retorno
64
+ ## API Reference
56
65
 
57
- La función `useSoloAnalytics` retorna un objeto con las siguientes propiedades y métodos:
66
+ The `useSoloAnalytics()` function returns an object with the following methods and properties:
58
67
 
59
- ### Métodos
68
+ ### Methods
60
69
 
61
- - `refresh()`: Actualiza manualmente todos los datos de análisis
62
- - `destroy()`: Limpia todos los listeners y timers para evitar fugas de memoria
70
+ - `refresh()`: Manually triggers a refresh of all analytics data
71
+ - `destroy()`: Cleans up all event listeners and timers to prevent memory leaks
63
72
 
64
- ### Propiedades de conveniencia
73
+ ### Convenience Properties
65
74
 
66
- - `isMobile`: Indica si es un dispositivo móvil
67
- - `isTablet`: Indica si es una tablet
68
- - `isDesktop`: Indica si es un dispositivo de escritorio
69
- - `isOnline`: Estado de conexión a internet
70
- - `isVisible`: Si la página está visible actualmente
71
- - `browserName`: Nombre del navegador
72
- - `osName`: Nombre del sistema operativo
75
+ - `isMobile`: Whether the device is a mobile phone
76
+ - `isTablet`: Whether the device is a tablet
77
+ - `isDesktop`: Whether the device is a desktop computer
78
+ - `isOnline`: Current network connection state
79
+ - `isVisible`: Whether the page is currently visible
80
+ - `browserName`: The name of the browser
81
+ - `osName`: The name of the operating system
73
82
 
74
- ### Datos completos
83
+ ### Complete Data
75
84
 
76
- - `data`: Un objeto que contiene toda la información detallada
85
+ - `data`: An object containing all detailed analytics information
77
86
 
78
- ## Estructura de datos
87
+ ## Data Structure
79
88
 
80
- El objeto `data` contiene la siguiente estructura:
89
+ The `data` object contains the following structure:
81
90
 
82
91
  ```typescript
83
92
  interface SoloAnalyticsInfo {
@@ -161,7 +170,7 @@ interface SoloAnalyticsInfo {
161
170
  }
162
171
  ```
163
172
 
164
- ## Uso en proyectos
173
+ ## Framework Integration Examples
165
174
 
166
175
  ### React
167
176
 
@@ -173,38 +182,126 @@ function DeviceInfo() {
173
182
  const [analytics, setAnalytics] = useState<SoloAnalyticsReturn | null>(null);
174
183
 
175
184
  useEffect(() => {
176
- // Inicializar en el lado del cliente
185
+ // Initialize on the client side
177
186
  const analyticsInstance = useSoloAnalytics();
178
187
  setAnalytics(analyticsInstance);
179
188
 
180
- // Limpiar al desmontar
189
+ // Cleanup on unmount
181
190
  return () => {
182
191
  analyticsInstance.destroy();
183
192
  };
184
193
  }, []);
185
194
 
186
- if (!analytics) return <div>Cargando...</div>;
195
+ if (!analytics) return <div>Loading...</div>;
187
196
 
188
197
  return (
189
198
  <div>
190
- <h1>Información del dispositivo</h1>
199
+ <h1>Device Information</h1>
191
200
  <p>
192
- Tipo:{" "}
201
+ Type:{" "}
193
202
  {analytics.isMobile
194
- ? "Móvil"
203
+ ? "Mobile"
195
204
  : analytics.isTablet
196
205
  ? "Tablet"
197
206
  : "Desktop"}
198
207
  </p>
199
- <p>Navegador: {analytics.browserName}</p>
200
- <p>Sistema operativo: {analytics.osName}</p>
201
- <p>En línea: {analytics.isOnline ? "" : "No"}</p>
208
+ <p>Browser: {analytics.browserName}</p>
209
+ <p>Operating System: {analytics.osName}</p>
210
+ <p>Network Status: {analytics.isOnline ? "Online" : "Offline"}</p>
202
211
  </div>
203
212
  );
204
213
  }
205
214
  ```
206
215
 
207
- ### JavaScript Vanilla
216
+ ### Vue 3
217
+
218
+ ```vue
219
+ <template>
220
+ <div>
221
+ <h1>Device Information</h1>
222
+ <p>Type: {{ deviceType }}</p>
223
+ <p>Browser: {{ analytics.browserName }}</p>
224
+ <p>Operating System: {{ analytics.osName }}</p>
225
+ <p>Network Status: {{ analytics.isOnline ? "Online" : "Offline" }}</p>
226
+ </div>
227
+ </template>
228
+
229
+ <script setup lang="ts">
230
+ import { onMounted, onUnmounted, ref, computed } from "vue";
231
+ import { useSoloAnalytics, SoloAnalyticsReturn } from "solo-analytics";
232
+
233
+ const analytics = ref<SoloAnalyticsReturn | null>(null);
234
+
235
+ onMounted(() => {
236
+ analytics.value = useSoloAnalytics({
237
+ trackVisibility: true,
238
+ });
239
+ });
240
+
241
+ onUnmounted(() => {
242
+ analytics.value?.destroy();
243
+ });
244
+
245
+ const deviceType = computed(() => {
246
+ if (!analytics.value) return "Unknown";
247
+
248
+ if (analytics.value.isMobile) return "Mobile";
249
+ if (analytics.value.isTablet) return "Tablet";
250
+ return "Desktop";
251
+ });
252
+ </script>
253
+ ```
254
+
255
+ ### Nuxt 3
256
+
257
+ ```vue
258
+ <template>
259
+ <div>
260
+ <h1>Device Information</h1>
261
+ <div v-if="analytics">
262
+ <p>Type: {{ deviceType }}</p>
263
+ <p>Browser: {{ analytics.browserName }}</p>
264
+ <p>Operating System: {{ analytics.osName }}</p>
265
+ <p>Network Status: {{ analytics.isOnline ? "Online" : "Offline" }}</p>
266
+ </div>
267
+ <div v-else>
268
+ <p>Loading device information...</p>
269
+ </div>
270
+ </div>
271
+ </template>
272
+
273
+ <script setup lang="ts">
274
+ import { ref, computed } from "vue";
275
+ import { useSoloAnalytics, SoloAnalyticsReturn } from "solo-analytics";
276
+
277
+ const analytics = ref<SoloAnalyticsReturn | null>(null);
278
+
279
+ // Important: Only initialize on client-side to avoid SSR issues
280
+ onMounted(() => {
281
+ analytics.value = useSoloAnalytics({
282
+ trackVisibility: true,
283
+ autoRefresh: true,
284
+ refreshInterval: 15000,
285
+ });
286
+ });
287
+
288
+ onBeforeUnmount(() => {
289
+ if (analytics.value) {
290
+ analytics.value.destroy();
291
+ }
292
+ });
293
+
294
+ const deviceType = computed(() => {
295
+ if (!analytics.value) return "Unknown";
296
+
297
+ if (analytics.value.isMobile) return "Mobile";
298
+ if (analytics.value.isTablet) return "Tablet";
299
+ return "Desktop";
300
+ });
301
+ </script>
302
+ ```
303
+
304
+ ### Vanilla JavaScript
208
305
 
209
306
  ```html
210
307
  <script type="module">
@@ -213,18 +310,18 @@ function DeviceInfo() {
213
310
  document.addEventListener("DOMContentLoaded", () => {
214
311
  const analytics = useSoloAnalytics();
215
312
 
216
- // Mostrar información en la página
313
+ // Display information on the page
217
314
  document.getElementById("deviceType").textContent = analytics.isMobile
218
- ? "Móvil"
315
+ ? "Mobile"
219
316
  : analytics.isTablet
220
317
  ? "Tablet"
221
318
  : "Desktop";
222
319
 
223
320
  document.getElementById(
224
321
  "browserInfo"
225
- ).textContent = `${analytics.browserName} en ${analytics.osName}`;
322
+ ).textContent = `${analytics.browserName} on ${analytics.osName}`;
226
323
 
227
- // Limpiar al cerrar
324
+ // Cleanup on window close
228
325
  window.addEventListener("beforeunload", () => {
229
326
  analytics.destroy();
230
327
  });
@@ -232,6 +329,90 @@ function DeviceInfo() {
232
329
  </script>
233
330
  ```
234
331
 
235
- ## Licencia
332
+ ## Browser Compatibility
333
+
334
+ Solo Analytics is compatible with all modern browsers, including:
335
+
336
+ - Chrome 60+
337
+ - Firefox 55+
338
+ - Safari 11+
339
+ - Edge 16+
340
+ - Opera 47+
341
+ - iOS Safari 11+
342
+ - Android Browser 67+
343
+
344
+ Some advanced features may not be available in older browsers but the library includes graceful fallbacks.
345
+
346
+ ## Development
347
+
348
+ ```bash
349
+ # Install dependencies
350
+ npm install
351
+
352
+ # Run development server (demo playground)
353
+ npm run dev
354
+
355
+ # Type-check and build for production
356
+ npm run build
357
+
358
+ # Run tests
359
+ npm test
360
+
361
+ # Watch tests during development
362
+ npm run test:watch
363
+ ```
364
+
365
+ ## Performance
366
+
367
+ Solo Analytics is designed to stay off the critical path:
368
+
369
+ | Metric | Value |
370
+ |--------|-------|
371
+ | ESM bundle (gzip) | ~3.5 KB |
372
+ | UMD bundle (gzip) | ~3.1 KB |
373
+ | `sideEffects` | `false` (tree-shakeable) |
374
+
375
+ **Recommendations:**
376
+
377
+ - Use `lazyFeatures: true` (default) so async probes run during idle time
378
+ - Set `detectFeatures: false` if you only need UA, screen, and network data
379
+ - Call `destroy()` when unmounting in SPAs to clear timers and listeners
380
+ - Initialize client-side only (`onMounted` in Vue/Nuxt, `useEffect` in React)
381
+
382
+ ## Contributing
383
+
384
+ Contributions are welcome! Please feel free to submit a Pull Request.
385
+
386
+ 1. Fork the repository
387
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
388
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
389
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
390
+ 5. Open a Pull Request
391
+
392
+ ## Repository
393
+
394
+ GitHub: [https://github.com/cesswhite/solo-analytics](https://github.com/cesswhite/solo-analytics)
395
+
396
+ ## License
397
+
398
+ MIT License
399
+
400
+ Copyright (c) 2025 Céss White
401
+
402
+ Permission is hereby granted, free of charge, to any person obtaining a copy
403
+ of this software and associated documentation files (the "Software"), to deal
404
+ in the Software without restriction, including without limitation the rights
405
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
406
+ copies of the Software, and to permit persons to whom the Software is
407
+ furnished to do so, subject to the following conditions:
408
+
409
+ The above copyright notice and this permission notice shall be included in all
410
+ copies or substantial portions of the Software.
236
411
 
237
- MIT
412
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
413
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
414
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
415
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
416
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
417
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
418
+ SOFTWARE.
@@ -0,0 +1,46 @@
1
+ import { SoloAnalyticsInfo } from '../types/analytics';
2
+ /**
3
+ * Type definition for analytics options
4
+ */
5
+ export interface SoloAnalyticsOptions {
6
+ /** Automatically refresh dynamic data (network, performance) */
7
+ autoRefresh?: boolean;
8
+ /** Refresh interval in milliseconds (default: 30000) */
9
+ refreshInterval?: number;
10
+ /** Track page visibility changes */
11
+ trackVisibility?: boolean;
12
+ /**
13
+ * Run expensive async probes (incognito, battery, media, permissions).
14
+ * Set to `false` to skip entirely and reduce main-thread work.
15
+ * @default true
16
+ */
17
+ detectFeatures?: boolean;
18
+ /**
19
+ * Defer async feature probes to idle time via requestIdleCallback.
20
+ * Sync data (UA, screen, network) is collected immediately.
21
+ * @default true
22
+ */
23
+ lazyFeatures?: boolean;
24
+ }
25
+ /**
26
+ * Type definition for the return value of useSoloAnalytics
27
+ */
28
+ export interface SoloAnalyticsReturn {
29
+ data: SoloAnalyticsInfo;
30
+ refresh: () => Promise<void>;
31
+ isMobile: boolean;
32
+ isTablet: boolean;
33
+ isDesktop: boolean;
34
+ isOnline: boolean;
35
+ isVisible: boolean;
36
+ browserName: string;
37
+ osName: string;
38
+ destroy: () => void;
39
+ }
40
+ /**
41
+ * A function that provides comprehensive browser, device, and performance analytics.
42
+ * @param options Configuration options
43
+ * @returns Object with analytics data and helper methods
44
+ */
45
+ export declare function useSoloAnalytics(options?: SoloAnalyticsOptions): SoloAnalyticsReturn;
46
+ //# sourceMappingURL=useSoloAnalytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSoloAnalytics.d.ts","sourceRoot":"","sources":["../../src/composables/useSoloAnalytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAevD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA8ED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB,CA6JxF"}
@@ -0,0 +1,4 @@
1
+ export { useSoloAnalytics } from './composables/useSoloAnalytics';
2
+ export type { SoloAnalyticsOptions, SoloAnalyticsReturn } from './composables/useSoloAnalytics';
3
+ export type { SoloAnalyticsInfo, BrowserInfo, OSInfo, DeviceInfo, NetworkInfo, ScreenInfo, PerformanceInfo, LocationInfo } from './types/analytics';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAGhG,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,MAAM,EACN,UAAU,EACV,WAAW,EACX,UAAU,EACV,eAAe,EACf,YAAY,EACb,MAAM,mBAAmB,CAAC"}