react-native-qalink 0.6.0 → 0.7.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 +258 -0
- package/dist/core/MiddlewarePipeline.d.ts +37 -0
- package/dist/core/MiddlewarePipeline.d.ts.map +1 -0
- package/dist/core/MiddlewarePipeline.js +58 -0
- package/dist/core/MiddlewarePipeline.js.map +1 -0
- package/dist/core/OfflineQueue.d.ts +48 -0
- package/dist/core/OfflineQueue.d.ts.map +1 -0
- package/dist/core/OfflineQueue.js +145 -0
- package/dist/core/OfflineQueue.js.map +1 -0
- package/dist/core/session.d.ts +2 -0
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +9 -0
- package/dist/core/session.js.map +1 -1
- package/dist/index.d.ts +79 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +160 -28
- package/dist/index.js.map +1 -1
- package/dist/trackers/NavigationLoopTracker.d.ts +31 -0
- package/dist/trackers/NavigationLoopTracker.d.ts.map +1 -0
- package/dist/trackers/NavigationLoopTracker.js +73 -0
- package/dist/trackers/NavigationLoopTracker.js.map +1 -0
- package/dist/trackers/RageClickTracker.d.ts +33 -0
- package/dist/trackers/RageClickTracker.d.ts.map +1 -0
- package/dist/trackers/RageClickTracker.js +56 -0
- package/dist/trackers/RageClickTracker.js.map +1 -0
- package/dist/trackers/SilentFailureTracker.d.ts +55 -0
- package/dist/trackers/SilentFailureTracker.d.ts.map +1 -0
- package/dist/trackers/SilentFailureTracker.js +84 -0
- package/dist/trackers/SilentFailureTracker.js.map +1 -0
- package/dist/transport/websocket.d.ts +18 -9
- package/dist/transport/websocket.d.ts.map +1 -1
- package/dist/transport/websocket.js +66 -30
- package/dist/transport/websocket.js.map +1 -1
- package/dist/types/index.d.ts +90 -10
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -351,6 +351,184 @@ QALink.init({
|
|
|
351
351
|
|
|
352
352
|
---
|
|
353
353
|
|
|
354
|
+
## 🧠Advanced QA Features (v0.7.0)
|
|
355
|
+
|
|
356
|
+
### Rage Click Detection
|
|
357
|
+
|
|
358
|
+
Detects when a user taps the same element multiple times rapidly — a strong frustration signal.
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// 1. Enable (once, after init)
|
|
362
|
+
QALink.enableRageClickDetection({ threshold: 3, windowMs: 600 });
|
|
363
|
+
|
|
364
|
+
// 2. Call from any onPress handler
|
|
365
|
+
<Button
|
|
366
|
+
onPress={() => {
|
|
367
|
+
QALink.trackUIInteraction('checkout-submit-btn');
|
|
368
|
+
handleSubmit();
|
|
369
|
+
}}
|
|
370
|
+
/>
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
A `rage_click` event fires in the dashboard when the threshold is hit.
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
### Navigation Loop Detection
|
|
378
|
+
|
|
379
|
+
Detects when the user bounces back and forth between the same two screens (A→B→A→B…). Signals broken back navigation or an unresolved error state.
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
// Enable (once, after init)
|
|
383
|
+
QALink.enableNavigationLoopDetection(3); // fires after 3 alternations
|
|
384
|
+
|
|
385
|
+
// Automatically triggered by setScreen() and startPackage()
|
|
386
|
+
QALink.setScreen('CheckoutScreen');
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
A `navigation_loop` event fires in the dashboard with the full navigation pattern.
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
### Silent Failure Detection
|
|
394
|
+
|
|
395
|
+
The hardest QA bug: API returns 200 OK but the data is null/empty. No error, no crash — the app just silently breaks.
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
const orders = await fetchOrders(userId); // 200 OK
|
|
399
|
+
|
|
400
|
+
QALink.trackDataState({
|
|
401
|
+
context: 'orders_list',
|
|
402
|
+
expected: Array.isArray(orders) && orders.length > 0,
|
|
403
|
+
actual: orders,
|
|
404
|
+
statusCode: 200,
|
|
405
|
+
url: '/api/orders',
|
|
406
|
+
});
|
|
407
|
+
// If orders is [] → fires a silent_failure event in the dashboard
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Returns `true` if the check passes, `false` if a failure was detected.
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
### Middleware (Event Processing Pipeline)
|
|
415
|
+
|
|
416
|
+
Intercept, enrich, filter, or transform any event before it's sent.
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
// Drop noisy console_log events in production
|
|
420
|
+
QALink.use((event, next) => {
|
|
421
|
+
if (event.type === 'console_log') return; // drop
|
|
422
|
+
next(event);
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// Add a custom tag to every event
|
|
426
|
+
QALink.use((event, next) => {
|
|
427
|
+
next({ ...event, _release: '2.1.0' } as typeof event);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// Log every event locally for debugging
|
|
431
|
+
QALink.use((event, next) => {
|
|
432
|
+
console.log('[QALink middleware]', event.type);
|
|
433
|
+
next(event);
|
|
434
|
+
});
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
Middlewares run in insertion order. Calling `next` is optional — skipping it drops the event.
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
### Offline-First Queue
|
|
442
|
+
|
|
443
|
+
Events are buffered automatically when the connection drops. Auto-flush triggers:
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
QALink.init({
|
|
447
|
+
apiKey: 'qlk_...',
|
|
448
|
+
appVersion: '1.0.0',
|
|
449
|
+
offlineQueue: {
|
|
450
|
+
maxSize: 500, // max buffered events (drops oldest when full)
|
|
451
|
+
flushOnCount: 20, // auto-flush when 20 events are buffered
|
|
452
|
+
flushIntervalMs: 30_000, // auto-flush every 30s
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// Manual flush (e.g. before app goes to background)
|
|
457
|
+
QALink.flush();
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
If `@react-native-async-storage/async-storage` is installed, events also persist across app restarts.
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
### Sequence Numbers
|
|
465
|
+
|
|
466
|
+
Every envelope sent to the dashboard now includes a `sequenceNumber` — a monotonically increasing counter per session. The dashboard can use it to detect out-of-order or missing events.
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## 📦 Event Packages (v0.6.0)
|
|
471
|
+
|
|
472
|
+
Los **Event Packages** agrupan **todos los eventos** de una pantalla en un solo payload que se envÃa cuando el usuario sale de ella. Incluyen métricas pre-calculadas y el historial completo de eventos.
|
|
473
|
+
|
|
474
|
+
### Integración en 1 lÃnea — `useTrackedScreen`
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
import { useTrackedScreen } from 'react-native-qalink';
|
|
478
|
+
|
|
479
|
+
function CheckoutScreen() {
|
|
480
|
+
useTrackedScreen('CheckoutScreen');
|
|
481
|
+
// ↑ inicia el package al montar, lo cierra y envÃa al desmontar
|
|
482
|
+
return <View>...</View>;
|
|
483
|
+
}
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
Eso es todo. Todos los eventos generados mientras el usuario está en esa pantalla (API calls, logs, errores, breadcrumbs) se agrupan y se envÃan juntos al salir.
|
|
487
|
+
|
|
488
|
+
### API manual — `startPackage` / `endPackage`
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
// En React Navigation (App.tsx)
|
|
492
|
+
<NavigationContainer
|
|
493
|
+
onStateChange={() => {
|
|
494
|
+
const screen = navigationRef.current?.getCurrentRoute()?.name ?? '';
|
|
495
|
+
|
|
496
|
+
QALink.endPackage(); // cierra el package de la pantalla anterior
|
|
497
|
+
QALink.startPackage(screen); // inicia uno nuevo para la pantalla actual
|
|
498
|
+
}}
|
|
499
|
+
>
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Payload que recibe el dashboard
|
|
503
|
+
|
|
504
|
+
```json
|
|
505
|
+
{
|
|
506
|
+
"type": "event_package",
|
|
507
|
+
"packageId": "...",
|
|
508
|
+
"context": {
|
|
509
|
+
"screenName": "CheckoutScreen",
|
|
510
|
+
"sessionId": "...",
|
|
511
|
+
"startTime": 1710445670000,
|
|
512
|
+
"endTime": 1710445680000,
|
|
513
|
+
"durationMs": 10000
|
|
514
|
+
},
|
|
515
|
+
"events": [ ...todos los eventos capturados en esa pantalla... ],
|
|
516
|
+
"metrics": {
|
|
517
|
+
"totalApiCalls": 3,
|
|
518
|
+
"totalErrors": 1,
|
|
519
|
+
"totalLogs": 5,
|
|
520
|
+
"totalBreadcrumbs": 2,
|
|
521
|
+
"totalEvents": 11
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Backward compatibility
|
|
527
|
+
|
|
528
|
+
Si **no** llamas `startPackage` ni `useTrackedScreen`, cada evento se sigue enviando inmediatamente como antes. Sin cambios de comportamiento.
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
354
532
|
## 📊 Tipos de eventos capturados
|
|
355
533
|
|
|
356
534
|
El SDK captura automáticamente:
|
|
@@ -358,6 +536,10 @@ El SDK captura automáticamente:
|
|
|
358
536
|
| Tipo | Descripción |
|
|
359
537
|
|------|-------------|
|
|
360
538
|
| `session_start` | Inicio de sesión |
|
|
539
|
+
| `event_package` | Batch de eventos de una pantalla (v0.6.0) |
|
|
540
|
+
| `rage_click` | Usuario tapeó el mismo elemento N veces (v0.7.0) |
|
|
541
|
+
| `navigation_loop` | Usuario rebotando entre mismas pantallas (v0.7.0) |
|
|
542
|
+
| `silent_failure` | API 200 OK con datos inválidos/vacÃos (v0.7.0) |
|
|
361
543
|
| `http_request` | Request HTTP (fetch/axios) |
|
|
362
544
|
| `user_log` | Logs con debug/info/warn/error/critical |
|
|
363
545
|
| `custom_event` | Eventos custom con logEvent() |
|
|
@@ -445,6 +627,82 @@ QALink.logEvent('experiment_viewed', {
|
|
|
445
627
|
});
|
|
446
628
|
```
|
|
447
629
|
|
|
630
|
+
### 4. Event Package con React Navigation
|
|
631
|
+
|
|
632
|
+
```typescript
|
|
633
|
+
// App.tsx
|
|
634
|
+
import { useTrackedScreen } from 'react-native-qalink';
|
|
635
|
+
|
|
636
|
+
// En cada pantalla — 1 sola lÃnea:
|
|
637
|
+
function PaymentScreen() {
|
|
638
|
+
useTrackedScreen('PaymentScreen');
|
|
639
|
+
// ...
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
function ProfileScreen() {
|
|
643
|
+
useTrackedScreen('ProfileScreen');
|
|
644
|
+
// ...
|
|
645
|
+
}
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
O con `NavigationContainer` para cobertura automática de todas las pantallas:
|
|
649
|
+
|
|
650
|
+
```typescript
|
|
651
|
+
// App.tsx
|
|
652
|
+
import { NavigationContainer } from '@react-navigation/native';
|
|
653
|
+
import { QALink } from 'react-native-qalink';
|
|
654
|
+
|
|
655
|
+
<NavigationContainer
|
|
656
|
+
onStateChange={() => {
|
|
657
|
+
const screen = navigationRef.current?.getCurrentRoute()?.name ?? 'unknown';
|
|
658
|
+
QALink.endPackage(); // cierra el package de la pantalla anterior
|
|
659
|
+
QALink.startPackage(screen); // inicia uno nuevo
|
|
660
|
+
}}
|
|
661
|
+
>
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## 📋 Referencia completa de la API
|
|
667
|
+
|
|
668
|
+
| Método | Descripción |
|
|
669
|
+
|--------|-------------|
|
|
670
|
+
| **`init(config)`** | Inicializa el SDK. Requerido antes de todo. |
|
|
671
|
+
| **`interceptAxios(instance)`** | Registra una instancia de Axios. |
|
|
672
|
+
| **`use(middleware)`** | Agrega un middleware al pipeline de eventos. |
|
|
673
|
+
| **`setUserContext(ctx)`** | Adjunta datos del usuario a todos los eventos. |
|
|
674
|
+
| **`setCustomContext(ctx)`** | Adjunta datos custom a todos los eventos. |
|
|
675
|
+
| **`clearContext()`** | Limpia usuario y contexto custom. |
|
|
676
|
+
| **`debug(...args)`** | Log nivel debug. |
|
|
677
|
+
| **`info(...args)`** | Log nivel info. |
|
|
678
|
+
| **`warn(...args)`** | Log nivel warn. |
|
|
679
|
+
| **`error(...args)`** | Log nivel error. |
|
|
680
|
+
| **`critical(...args)`** | Log nivel critical. |
|
|
681
|
+
| **`logEvent(name, data?)`** | Evento custom de negocio. |
|
|
682
|
+
| **`addBreadcrumb(action, data?)`** | Breadcrumb manual. |
|
|
683
|
+
| **`logRequest(options)`** | Registra request de red manualmente. |
|
|
684
|
+
| **`setScreen(name)`** | Cambia la pantalla actual + breadcrumb + loop detection. |
|
|
685
|
+
| **`startPackage(screenName)`** | Inicia un Event Package para esa pantalla. |
|
|
686
|
+
| **`endPackage()`** | Cierra el package activo y lo envÃa. |
|
|
687
|
+
| **`flush()`** | EnvÃa inmediatamente todos los eventos en cola offline. |
|
|
688
|
+
| **`enableRageClickDetection(options?)`** | Activa detección de rage clicks. |
|
|
689
|
+
| **`trackUIInteraction(target)`** | Registra tap para rage click. |
|
|
690
|
+
| **`enableNavigationLoopDetection(threshold?)`** | Activa detección de loops de navegación. |
|
|
691
|
+
| **`trackDataState(check)`** | Detecta silent failures (API 200 con datos inválidos). |
|
|
692
|
+
| **`captureScreen(label?)`** | Captura la pantalla completa. |
|
|
693
|
+
| **`captureRef(ref, label?)`** | Captura un componente especÃfico. |
|
|
694
|
+
| **`configureHTTP(config)`** | Actualiza config HTTP en runtime. |
|
|
695
|
+
| **`getDeviceId()`** | Devuelve el deviceId de la sesión. |
|
|
696
|
+
| **`getStatus()`** | Estado de la conexión WebSocket. |
|
|
697
|
+
| **`getQueueSize()`** | Número de eventos en cola offline. |
|
|
698
|
+
| **`destroy()`** | Limpia interceptores y desconecta. |
|
|
699
|
+
|
|
700
|
+
**Hook:**
|
|
701
|
+
|
|
702
|
+
| Hook | Descripción |
|
|
703
|
+
|------|-------------|
|
|
704
|
+
| **`useTrackedScreen(name)`** | 1 lÃnea: inicia y cierra el package automáticamente al montar/desmontar la pantalla. |
|
|
705
|
+
|
|
448
706
|
---
|
|
449
707
|
|
|
450
708
|
## 🚨 Troubleshooting
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MiddlewarePipeline — chain of event processors applied before sending.
|
|
3
|
+
*
|
|
4
|
+
* Each middleware receives an event and a `next` callback:
|
|
5
|
+
* - Call `next(event)` to pass the (optionally modified) event forward.
|
|
6
|
+
* - Don't call `next` to drop the event entirely.
|
|
7
|
+
* - Mutate or replace the event to enrich/transform it.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* pipeline.use((event, next) => {
|
|
11
|
+
* // Drop noisy console logs in production
|
|
12
|
+
* if (event.type === 'console_log') return;
|
|
13
|
+
* next(event);
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* pipeline.use((event, next) => {
|
|
18
|
+
* // Enrich every event with a custom tag
|
|
19
|
+
* next({ ...event, _tag: 'v2' } as typeof event);
|
|
20
|
+
* });
|
|
21
|
+
*/
|
|
22
|
+
import type { QALinkEvent } from '../types';
|
|
23
|
+
export type EventMiddleware = (event: QALinkEvent, next: (event: QALinkEvent) => void) => void;
|
|
24
|
+
export declare class MiddlewarePipeline {
|
|
25
|
+
private readonly middlewares;
|
|
26
|
+
/** Register a middleware. Middlewares run in insertion order. */
|
|
27
|
+
use(middleware: EventMiddleware): this;
|
|
28
|
+
/** Clear all registered middlewares. */
|
|
29
|
+
clear(): void;
|
|
30
|
+
get count(): number;
|
|
31
|
+
/**
|
|
32
|
+
* Run `event` through the full middleware chain.
|
|
33
|
+
* `finalHandler` is called only if every middleware calls `next`.
|
|
34
|
+
*/
|
|
35
|
+
process(event: QALinkEvent, finalHandler: (event: QALinkEvent) => void): void;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=MiddlewarePipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiddlewarePipeline.d.ts","sourceRoot":"","sources":["../../src/core/MiddlewarePipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,MAAM,eAAe,GAAG,CAC5B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,KAC/B,IAAI,CAAC;AAEV,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;IAErD,iEAAiE;IACjE,GAAG,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI;IAKtC,wCAAwC;IACxC,KAAK,IAAI,IAAI;IAIb,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;CAa9E"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MiddlewarePipeline — chain of event processors applied before sending.
|
|
4
|
+
*
|
|
5
|
+
* Each middleware receives an event and a `next` callback:
|
|
6
|
+
* - Call `next(event)` to pass the (optionally modified) event forward.
|
|
7
|
+
* - Don't call `next` to drop the event entirely.
|
|
8
|
+
* - Mutate or replace the event to enrich/transform it.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* pipeline.use((event, next) => {
|
|
12
|
+
* // Drop noisy console logs in production
|
|
13
|
+
* if (event.type === 'console_log') return;
|
|
14
|
+
* next(event);
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* pipeline.use((event, next) => {
|
|
19
|
+
* // Enrich every event with a custom tag
|
|
20
|
+
* next({ ...event, _tag: 'v2' } as typeof event);
|
|
21
|
+
* });
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.MiddlewarePipeline = void 0;
|
|
25
|
+
class MiddlewarePipeline {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.middlewares = [];
|
|
28
|
+
}
|
|
29
|
+
/** Register a middleware. Middlewares run in insertion order. */
|
|
30
|
+
use(middleware) {
|
|
31
|
+
this.middlewares.push(middleware);
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
/** Clear all registered middlewares. */
|
|
35
|
+
clear() {
|
|
36
|
+
this.middlewares.length = 0;
|
|
37
|
+
}
|
|
38
|
+
get count() {
|
|
39
|
+
return this.middlewares.length;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Run `event` through the full middleware chain.
|
|
43
|
+
* `finalHandler` is called only if every middleware calls `next`.
|
|
44
|
+
*/
|
|
45
|
+
process(event, finalHandler) {
|
|
46
|
+
const chain = this.middlewares;
|
|
47
|
+
const run = (index, current) => {
|
|
48
|
+
if (index >= chain.length) {
|
|
49
|
+
finalHandler(current);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
chain[index](current, (next) => run(index + 1, next));
|
|
53
|
+
};
|
|
54
|
+
run(0, event);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.MiddlewarePipeline = MiddlewarePipeline;
|
|
58
|
+
//# sourceMappingURL=MiddlewarePipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiddlewarePipeline.js","sourceRoot":"","sources":["../../src/core/MiddlewarePipeline.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AASH,MAAa,kBAAkB;IAA/B;QACmB,gBAAW,GAAsB,EAAE,CAAC;IAkCvD,CAAC;IAhCC,iEAAiE;IACjE,GAAG,CAAC,UAA2B;QAC7B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wCAAwC;IACxC,KAAK;QACH,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,KAAkB,EAAE,YAA0C;QACpE,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC;QAE/B,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,OAAoB,EAAQ,EAAE;YACxD,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC1B,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,OAAO;YACT,CAAC;YACD,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC;QAEF,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAChB,CAAC;CACF;AAnCD,gDAmCC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OfflineQueue — FIFO event queue with optional AsyncStorage persistence.
|
|
3
|
+
*
|
|
4
|
+
* - Falls back to pure in-memory when AsyncStorage is not installed.
|
|
5
|
+
* - Respects a max-size limit (drops oldest event when full).
|
|
6
|
+
* - Supports two auto-flush triggers:
|
|
7
|
+
* · count-based: flush when queue reaches `flushOnCount` events.
|
|
8
|
+
* · time-based: flush every `flushIntervalMs` milliseconds.
|
|
9
|
+
* - Persists across app restarts when AsyncStorage is available.
|
|
10
|
+
*/
|
|
11
|
+
import type { QALinkEvent } from '../types';
|
|
12
|
+
export interface OfflineQueueConfig {
|
|
13
|
+
maxSize?: number;
|
|
14
|
+
/** Trigger flush when this many events are buffered. @default 20 */
|
|
15
|
+
flushOnCount?: number;
|
|
16
|
+
/** Trigger flush every N milliseconds. @default 30000 */
|
|
17
|
+
flushIntervalMs?: number;
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
}
|
|
20
|
+
type FlushCallback = (events: QALinkEvent[]) => void;
|
|
21
|
+
export declare class OfflineQueue {
|
|
22
|
+
private memory;
|
|
23
|
+
private readonly maxSize;
|
|
24
|
+
private readonly flushOnCount;
|
|
25
|
+
private readonly flushIntervalMs;
|
|
26
|
+
private readonly debug;
|
|
27
|
+
private flushTimer;
|
|
28
|
+
private onFlush;
|
|
29
|
+
private storage;
|
|
30
|
+
constructor(config?: OfflineQueueConfig);
|
|
31
|
+
private tryBindAsyncStorage;
|
|
32
|
+
setFlushCallback(cb: FlushCallback): void;
|
|
33
|
+
startAutoFlush(): void;
|
|
34
|
+
stopAutoFlush(): void;
|
|
35
|
+
push(event: QALinkEvent): Promise<void>;
|
|
36
|
+
/** Remove and return all buffered events. Clears persistence. */
|
|
37
|
+
drain(): QALinkEvent[];
|
|
38
|
+
peek(): readonly QALinkEvent[];
|
|
39
|
+
get size(): number;
|
|
40
|
+
/** Load events persisted from a previous session and merge into current queue. */
|
|
41
|
+
loadPersisted(): Promise<void>;
|
|
42
|
+
private persist;
|
|
43
|
+
private clearPersisted;
|
|
44
|
+
private triggerFlush;
|
|
45
|
+
private log;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=OfflineQueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OfflineQueue.d.ts","sourceRoot":"","sources":["../../src/core/OfflineQueue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAO5C,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,KAAK,aAAa,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;AAQrD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,OAAO,CAAoC;gBAEvC,MAAM,GAAE,kBAAuB;IAU3C,OAAO,CAAC,mBAAmB;IAa3B,gBAAgB,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;IAMzC,cAAc,IAAI,IAAI;IAUtB,aAAa,IAAI,IAAI;IASf,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAc7C,iEAAiE;IACjE,KAAK,IAAI,WAAW,EAAE;IAOtB,IAAI,IAAI,SAAS,WAAW,EAAE;IAI9B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAID,kFAAkF;IAC5E,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;YAwBtB,OAAO;IASrB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,GAAG;CAGZ"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OfflineQueue — FIFO event queue with optional AsyncStorage persistence.
|
|
4
|
+
*
|
|
5
|
+
* - Falls back to pure in-memory when AsyncStorage is not installed.
|
|
6
|
+
* - Respects a max-size limit (drops oldest event when full).
|
|
7
|
+
* - Supports two auto-flush triggers:
|
|
8
|
+
* · count-based: flush when queue reaches `flushOnCount` events.
|
|
9
|
+
* · time-based: flush every `flushIntervalMs` milliseconds.
|
|
10
|
+
* - Persists across app restarts when AsyncStorage is available.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.OfflineQueue = void 0;
|
|
14
|
+
const STORAGE_KEY = '__qalink_offline_queue__';
|
|
15
|
+
const DEFAULT_MAX_SIZE = 500;
|
|
16
|
+
const DEFAULT_FLUSH_COUNT = 20;
|
|
17
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 30000;
|
|
18
|
+
class OfflineQueue {
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
var _a, _b, _c, _d;
|
|
21
|
+
this.memory = [];
|
|
22
|
+
this.flushTimer = null;
|
|
23
|
+
this.onFlush = null;
|
|
24
|
+
this.storage = null;
|
|
25
|
+
this.maxSize = (_a = config.maxSize) !== null && _a !== void 0 ? _a : DEFAULT_MAX_SIZE;
|
|
26
|
+
this.flushOnCount = (_b = config.flushOnCount) !== null && _b !== void 0 ? _b : DEFAULT_FLUSH_COUNT;
|
|
27
|
+
this.flushIntervalMs = (_c = config.flushIntervalMs) !== null && _c !== void 0 ? _c : DEFAULT_FLUSH_INTERVAL_MS;
|
|
28
|
+
this.debug = (_d = config.debug) !== null && _d !== void 0 ? _d : false;
|
|
29
|
+
this.tryBindAsyncStorage();
|
|
30
|
+
}
|
|
31
|
+
// ─── Setup ─────────────────────────────────────────────────────────────────
|
|
32
|
+
tryBindAsyncStorage() {
|
|
33
|
+
try {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
35
|
+
const AS = require('@react-native-async-storage/async-storage').default;
|
|
36
|
+
if (AS && typeof AS.getItem === 'function') {
|
|
37
|
+
this.storage = AS;
|
|
38
|
+
this.log('AsyncStorage persistence enabled');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (_a) {
|
|
42
|
+
this.log('AsyncStorage unavailable — in-memory queue only');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
setFlushCallback(cb) {
|
|
46
|
+
this.onFlush = cb;
|
|
47
|
+
}
|
|
48
|
+
// ─── Auto-flush lifecycle ──────────────────────────────────────────────────
|
|
49
|
+
startAutoFlush() {
|
|
50
|
+
if (this.flushTimer)
|
|
51
|
+
return;
|
|
52
|
+
this.flushTimer = setInterval(() => {
|
|
53
|
+
if (this.memory.length > 0) {
|
|
54
|
+
this.log(`Auto-flush (time) — ${this.memory.length} events`);
|
|
55
|
+
this.triggerFlush();
|
|
56
|
+
}
|
|
57
|
+
}, this.flushIntervalMs);
|
|
58
|
+
}
|
|
59
|
+
stopAutoFlush() {
|
|
60
|
+
if (this.flushTimer) {
|
|
61
|
+
clearInterval(this.flushTimer);
|
|
62
|
+
this.flushTimer = null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// ─── Queue operations ──────────────────────────────────────────────────────
|
|
66
|
+
async push(event) {
|
|
67
|
+
if (this.memory.length >= this.maxSize) {
|
|
68
|
+
this.memory.shift();
|
|
69
|
+
this.log('Queue full — dropped oldest event');
|
|
70
|
+
}
|
|
71
|
+
this.memory.push(event);
|
|
72
|
+
await this.persist();
|
|
73
|
+
if (this.memory.length >= this.flushOnCount) {
|
|
74
|
+
this.log(`Auto-flush (count) — ${this.memory.length} events`);
|
|
75
|
+
this.triggerFlush();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Remove and return all buffered events. Clears persistence. */
|
|
79
|
+
drain() {
|
|
80
|
+
const events = [...this.memory];
|
|
81
|
+
this.memory = [];
|
|
82
|
+
this.clearPersisted();
|
|
83
|
+
return events;
|
|
84
|
+
}
|
|
85
|
+
peek() {
|
|
86
|
+
return this.memory;
|
|
87
|
+
}
|
|
88
|
+
get size() {
|
|
89
|
+
return this.memory.length;
|
|
90
|
+
}
|
|
91
|
+
// ─── Persistence ───────────────────────────────────────────────────────────
|
|
92
|
+
/** Load events persisted from a previous session and merge into current queue. */
|
|
93
|
+
async loadPersisted() {
|
|
94
|
+
if (!this.storage)
|
|
95
|
+
return;
|
|
96
|
+
try {
|
|
97
|
+
const raw = await this.storage.getItem(STORAGE_KEY);
|
|
98
|
+
if (!raw)
|
|
99
|
+
return;
|
|
100
|
+
const parsed = JSON.parse(raw);
|
|
101
|
+
if (!Array.isArray(parsed))
|
|
102
|
+
return;
|
|
103
|
+
const existingIds = new Set(this.memory.map((e) => e.id).filter(Boolean));
|
|
104
|
+
for (const ev of parsed) {
|
|
105
|
+
const id = ev.id;
|
|
106
|
+
if (!id || !existingIds.has(id)) {
|
|
107
|
+
this.memory.push(ev);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
this.log(`Loaded ${parsed.length} persisted events from previous session`);
|
|
111
|
+
}
|
|
112
|
+
catch (_a) {
|
|
113
|
+
this.log('Failed to load persisted queue — starting fresh');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
async persist() {
|
|
117
|
+
if (!this.storage)
|
|
118
|
+
return;
|
|
119
|
+
try {
|
|
120
|
+
await this.storage.setItem(STORAGE_KEY, JSON.stringify(this.memory));
|
|
121
|
+
}
|
|
122
|
+
catch (_a) {
|
|
123
|
+
// Ignore silently — persistence is best-effort
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
clearPersisted() {
|
|
127
|
+
var _a;
|
|
128
|
+
(_a = this.storage) === null || _a === void 0 ? void 0 : _a.removeItem(STORAGE_KEY).catch(() => { });
|
|
129
|
+
}
|
|
130
|
+
// ─── Flush trigger ─────────────────────────────────────────────────────────
|
|
131
|
+
triggerFlush() {
|
|
132
|
+
if (!this.onFlush)
|
|
133
|
+
return;
|
|
134
|
+
const events = this.drain();
|
|
135
|
+
if (events.length > 0)
|
|
136
|
+
this.onFlush(events);
|
|
137
|
+
}
|
|
138
|
+
// ─── Helpers ───────────────────────────────────────────────────────────────
|
|
139
|
+
log(...args) {
|
|
140
|
+
if (this.debug)
|
|
141
|
+
console.log('[QALink OfflineQueue]', ...args);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.OfflineQueue = OfflineQueue;
|
|
145
|
+
//# sourceMappingURL=OfflineQueue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OfflineQueue.js","sourceRoot":"","sources":["../../src/core/OfflineQueue.ts"],"names":[],"mappings":"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"}
|
package/dist/core/session.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { DeviceInfo } from '../types';
|
|
|
2
2
|
export declare function generateId(): string;
|
|
3
3
|
export declare function getSessionId(): string;
|
|
4
4
|
export declare function resetSession(): string;
|
|
5
|
+
export declare function nextSequenceNumber(): number;
|
|
6
|
+
export declare function resetSequenceCounter(): void;
|
|
5
7
|
export declare function getDeviceInfo(appVersion: string): Promise<DeviceInfo>;
|
|
6
8
|
export declare function sanitizeBody(body: unknown, logBodies: boolean): unknown;
|
|
7
9
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAKtC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAGrC;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAmB3E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAGvE"}
|
package/dist/core/session.js
CHANGED
|
@@ -3,9 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateId = generateId;
|
|
4
4
|
exports.getSessionId = getSessionId;
|
|
5
5
|
exports.resetSession = resetSession;
|
|
6
|
+
exports.nextSequenceNumber = nextSequenceNumber;
|
|
7
|
+
exports.resetSequenceCounter = resetSequenceCounter;
|
|
6
8
|
exports.getDeviceInfo = getDeviceInfo;
|
|
7
9
|
exports.sanitizeBody = sanitizeBody;
|
|
8
10
|
let currentSessionId = null;
|
|
11
|
+
let sequenceCounter = 0;
|
|
9
12
|
function generateId() {
|
|
10
13
|
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
11
14
|
}
|
|
@@ -19,6 +22,12 @@ function resetSession() {
|
|
|
19
22
|
currentSessionId = generateId();
|
|
20
23
|
return currentSessionId;
|
|
21
24
|
}
|
|
25
|
+
function nextSequenceNumber() {
|
|
26
|
+
return ++sequenceCounter;
|
|
27
|
+
}
|
|
28
|
+
function resetSequenceCounter() {
|
|
29
|
+
sequenceCounter = 0;
|
|
30
|
+
}
|
|
22
31
|
async function getDeviceInfo(appVersion) {
|
|
23
32
|
var _a, _b;
|
|
24
33
|
try {
|
package/dist/core/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":";;AAKA,gCAEC;AAED,oCAKC;AAED,oCAGC;AAED,gDAEC;AAED,oDAEC;AAED,sCAmBC;AAED,oCAGC;AAnDD,IAAI,gBAAgB,GAAkB,IAAI,CAAC;AAC3C,IAAI,eAAe,GAAG,CAAC,CAAC;AAExB,SAAgB,UAAU;IACxB,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,SAAgB,YAAY;IAC1B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,gBAAgB,GAAG,UAAU,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,SAAgB,YAAY;IAC1B,gBAAgB,GAAG,UAAU,EAAE,CAAC;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,SAAgB,kBAAkB;IAChC,OAAO,EAAE,eAAe,CAAC;AAC3B,CAAC;AAED,SAAgB,oBAAoB;IAClC,eAAe,GAAG,CAAC,CAAC;AACtB,CAAC;AAEM,KAAK,UAAU,aAAa,CAAC,UAAkB;;IACpD,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QAC7C,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,EAAuB;YAC1C,SAAS,EAAE,MAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,QAAQ,EAAE,mCAAI,SAAS;YACpD,UAAU;YACV,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC3E,CAAC;IACJ,CAAC;IAAC,WAAM,CAAC;QACP,OAAO;YACL,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,SAAS;YACpB,UAAU;YACV,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,SAAS;SACrB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,IAAa,EAAE,SAAkB;IAC5D,IAAI,CAAC,SAAS;QAAE,OAAO,0CAA0C,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC"}
|