@logg/signals 0.1.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 +21 -0
- package/README.md +417 -0
- package/dist/index.d.mts +112 -0
- package/dist/index.d.ts +112 -0
- package/dist/index.js +514 -0
- package/dist/index.mjs +489 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Logg
|
|
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
ADDED
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
# @logg/signals
|
|
2
|
+
|
|
3
|
+
Universal event tracking SDK for Logg Signals. Track events from web, React Native, and Node.js applications.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
✅ **Universal** - Works in browsers, React Native, and Node.js
|
|
8
|
+
✅ **Type-safe** - Full TypeScript support
|
|
9
|
+
✅ **Automatic batching** - Efficient event batching with configurable thresholds
|
|
10
|
+
✅ **Persistent storage** - Uses localStorage, AsyncStorage, or memory as fallback
|
|
11
|
+
✅ **Retry logic** - Exponential backoff for failed requests
|
|
12
|
+
✅ **Auto metadata** - Automatically collects browser/device information
|
|
13
|
+
✅ **Small bundle** - <5KB gzipped
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @logg/signals
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For React Native, also install AsyncStorage:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @react-native-async-storage/async-storage
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
### Web (Browser)
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { Signals } from '@logg/signals';
|
|
33
|
+
|
|
34
|
+
const signals = new Signals({
|
|
35
|
+
apiKey: 'your-api-key',
|
|
36
|
+
endpoint: 'https://signals.yourdomain.com/events',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Track events
|
|
40
|
+
signals.event({
|
|
41
|
+
type: 'page_view',
|
|
42
|
+
page: '/dashboard',
|
|
43
|
+
userId: '12345',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
signals.event({
|
|
47
|
+
type: 'button_click',
|
|
48
|
+
element: 'signup_cta',
|
|
49
|
+
userId: '12345',
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### React Native
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { Signals } from '@logg/signals';
|
|
57
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
58
|
+
|
|
59
|
+
const signals = new Signals({
|
|
60
|
+
apiKey: 'your-api-key',
|
|
61
|
+
endpoint: 'https://signals.yourdomain.com/events',
|
|
62
|
+
// AsyncStorage is auto-detected, but you can pass it explicitly
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Track events
|
|
66
|
+
signals.event({
|
|
67
|
+
type: 'screen_view',
|
|
68
|
+
screen: 'HomeScreen',
|
|
69
|
+
userId: user.id,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
signals.event({
|
|
73
|
+
type: 'purchase',
|
|
74
|
+
productId: 'premium-plan',
|
|
75
|
+
amount: 29.99,
|
|
76
|
+
userId: user.id,
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Node.js
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { Signals } from '@logg/signals';
|
|
84
|
+
|
|
85
|
+
const signals = new Signals({
|
|
86
|
+
apiKey: 'your-api-key',
|
|
87
|
+
endpoint: 'https://signals.yourdomain.com/events',
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Track server-side events
|
|
91
|
+
await signals.event({
|
|
92
|
+
type: 'api_call',
|
|
93
|
+
endpoint: '/api/users',
|
|
94
|
+
method: 'POST',
|
|
95
|
+
userId: req.user.id,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Make sure to flush before process exit
|
|
99
|
+
process.on('beforeExit', async () => {
|
|
100
|
+
await signals.flush();
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Configuration
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
const signals = new Signals({
|
|
108
|
+
// Required
|
|
109
|
+
apiKey: 'your-api-key',
|
|
110
|
+
endpoint: 'https://signals.yourdomain.com/events',
|
|
111
|
+
|
|
112
|
+
// Optional
|
|
113
|
+
batchSize: 10, // Send after 10 events (default: 10)
|
|
114
|
+
batchInterval: 5000, // Or every 5 seconds (default: 5000)
|
|
115
|
+
maxRetries: 3, // Retry failed requests 3 times (default: 3)
|
|
116
|
+
retryDelay: 1000, // Initial retry delay in ms (default: 1000)
|
|
117
|
+
debug: false, // Enable debug logging (default: false)
|
|
118
|
+
sessionId: 'custom-id', // Custom session ID (auto-generated by default)
|
|
119
|
+
storage: customAdapter, // Custom storage adapter (auto-detected by default)
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## API Reference
|
|
124
|
+
|
|
125
|
+
### `signals.event(eventData)`
|
|
126
|
+
|
|
127
|
+
Track an event. Events are automatically batched and sent based on `batchSize` and `batchInterval` config.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
await signals.event({
|
|
131
|
+
type: 'event_type', // Required: event type
|
|
132
|
+
userId: 'user-123', // Optional: user ID
|
|
133
|
+
// ... any other properties
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Auto-added fields:**
|
|
138
|
+
- `event_id` - Unique event identifier (UUID v4)
|
|
139
|
+
- `timestamp` - ISO 8601 timestamp
|
|
140
|
+
- `session_id` - Session identifier
|
|
141
|
+
- `client` - Client metadata (type, version, user_agent, screen, locale, timezone)
|
|
142
|
+
|
|
143
|
+
### `signals.flush()`
|
|
144
|
+
|
|
145
|
+
Manually flush all pending events immediately.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
await signals.flush();
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `signals.getSessionId()`
|
|
152
|
+
|
|
153
|
+
Get the current session ID.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const sessionId = signals.getSessionId();
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### `signals.getQueueSize()`
|
|
160
|
+
|
|
161
|
+
Get the number of events in the queue.
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const queueSize = signals.getQueueSize();
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### `signals.destroy()`
|
|
168
|
+
|
|
169
|
+
Destroy the client, flush remaining events, and cleanup resources.
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
await signals.destroy();
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Event Batching
|
|
176
|
+
|
|
177
|
+
Events are automatically batched to reduce network requests:
|
|
178
|
+
|
|
179
|
+
1. **Batch by size**: Sends when `batchSize` events are queued (default: 10)
|
|
180
|
+
2. **Batch by time**: Sends every `batchInterval` milliseconds (default: 5000)
|
|
181
|
+
3. **Manual flush**: Call `signals.flush()` to send immediately
|
|
182
|
+
|
|
183
|
+
**Batch format sent to backend:**
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"api_key": "your-api-key",
|
|
188
|
+
"batch_id": "batch-uuid",
|
|
189
|
+
"timestamp": "2025-12-02T10:30:00.000Z",
|
|
190
|
+
"metadata": {
|
|
191
|
+
"type": "web",
|
|
192
|
+
"version": "0.1.0",
|
|
193
|
+
"user_agent": "Mozilla/5.0...",
|
|
194
|
+
"screen": { "width": 1920, "height": 1080 },
|
|
195
|
+
"locale": "en-US",
|
|
196
|
+
"timezone": "America/New_York"
|
|
197
|
+
},
|
|
198
|
+
"events": [
|
|
199
|
+
{
|
|
200
|
+
"event_id": "uuid-1",
|
|
201
|
+
"timestamp": "2025-12-02T10:30:00.000Z",
|
|
202
|
+
"session_id": "session-uuid",
|
|
203
|
+
"type": "page_view",
|
|
204
|
+
"userId": "12345",
|
|
205
|
+
"page": "/dashboard"
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Storage Adapters
|
|
212
|
+
|
|
213
|
+
The SDK automatically detects the best storage adapter:
|
|
214
|
+
|
|
215
|
+
1. **Web**: `LocalStorageAdapter` (uses `localStorage`)
|
|
216
|
+
2. **React Native**: `AsyncStorageAdapter` (uses `@react-native-async-storage/async-storage`)
|
|
217
|
+
3. **Node.js**: `MemoryStorageAdapter` (in-memory, no persistence)
|
|
218
|
+
|
|
219
|
+
### Custom Storage Adapter
|
|
220
|
+
|
|
221
|
+
You can provide a custom storage adapter:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
import { Signals, StorageAdapter } from '@logg/signals';
|
|
225
|
+
|
|
226
|
+
class CustomStorageAdapter implements StorageAdapter {
|
|
227
|
+
async getItem(key: string): Promise<string | null> {
|
|
228
|
+
// Your implementation
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async setItem(key: string, value: string): Promise<void> {
|
|
232
|
+
// Your implementation
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
async removeItem(key: string): Promise<void> {
|
|
236
|
+
// Your implementation
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const signals = new Signals({
|
|
241
|
+
apiKey: 'your-api-key',
|
|
242
|
+
endpoint: 'https://signals.yourdomain.com/events',
|
|
243
|
+
storage: new CustomStorageAdapter(),
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Error Handling
|
|
248
|
+
|
|
249
|
+
The SDK includes automatic retry logic with exponential backoff:
|
|
250
|
+
|
|
251
|
+
- Failed requests are retried up to `maxRetries` times (default: 3)
|
|
252
|
+
- Retry delay doubles after each attempt (exponential backoff)
|
|
253
|
+
- Events are persisted in storage and retried on next batch
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
const signals = new Signals({
|
|
257
|
+
apiKey: 'your-api-key',
|
|
258
|
+
endpoint: 'https://signals.yourdomain.com/events',
|
|
259
|
+
maxRetries: 5, // Retry up to 5 times
|
|
260
|
+
retryDelay: 2000, // Start with 2 second delay
|
|
261
|
+
debug: true, // Log retry attempts
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## React Integration
|
|
266
|
+
|
|
267
|
+
### Track Page Views
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import { useEffect } from 'react';
|
|
271
|
+
import { useLocation } from 'react-router-dom';
|
|
272
|
+
|
|
273
|
+
function App() {
|
|
274
|
+
const location = useLocation();
|
|
275
|
+
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
signals.event({
|
|
278
|
+
type: 'page_view',
|
|
279
|
+
page: location.pathname,
|
|
280
|
+
title: document.title,
|
|
281
|
+
});
|
|
282
|
+
}, [location]);
|
|
283
|
+
|
|
284
|
+
return <div>...</div>;
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Track User Actions
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
function SignupButton() {
|
|
292
|
+
const handleClick = () => {
|
|
293
|
+
signals.event({
|
|
294
|
+
type: 'button_click',
|
|
295
|
+
element: 'signup_cta',
|
|
296
|
+
page: '/landing',
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// Navigate to signup...
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
return <button onClick={handleClick}>Sign Up</button>;
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## React Native Integration
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
import { Signals } from '@logg/signals';
|
|
310
|
+
import { useEffect } from 'react';
|
|
311
|
+
import { useNavigation } from '@react-navigation/native';
|
|
312
|
+
|
|
313
|
+
const signals = new Signals({
|
|
314
|
+
apiKey: 'your-api-key',
|
|
315
|
+
endpoint: 'https://signals.yourdomain.com/events',
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
function HomeScreen() {
|
|
319
|
+
const navigation = useNavigation();
|
|
320
|
+
|
|
321
|
+
useEffect(() => {
|
|
322
|
+
// Track screen view
|
|
323
|
+
signals.event({
|
|
324
|
+
type: 'screen_view',
|
|
325
|
+
screen: 'HomeScreen',
|
|
326
|
+
});
|
|
327
|
+
}, []);
|
|
328
|
+
|
|
329
|
+
return (
|
|
330
|
+
<Button
|
|
331
|
+
title="Buy Premium"
|
|
332
|
+
onPress={() => {
|
|
333
|
+
signals.event({
|
|
334
|
+
type: 'button_press',
|
|
335
|
+
button: 'buy_premium',
|
|
336
|
+
screen: 'HomeScreen',
|
|
337
|
+
});
|
|
338
|
+
navigation.navigate('Checkout');
|
|
339
|
+
}}
|
|
340
|
+
/>
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Best Practices
|
|
346
|
+
|
|
347
|
+
### 1. Initialize Once
|
|
348
|
+
|
|
349
|
+
Create a single instance and reuse it:
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
// lib/signals.ts
|
|
353
|
+
import { Signals } from '@logg/signals';
|
|
354
|
+
|
|
355
|
+
export const signals = new Signals({
|
|
356
|
+
apiKey: process.env.SIGNALS_API_KEY!,
|
|
357
|
+
endpoint: process.env.SIGNALS_ENDPOINT!,
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// app.tsx
|
|
361
|
+
import { signals } from './lib/signals';
|
|
362
|
+
|
|
363
|
+
signals.event({ type: 'app_opened' });
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 2. Flush on Exit
|
|
367
|
+
|
|
368
|
+
Always flush events before the app closes:
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
// React Native
|
|
372
|
+
useEffect(() => {
|
|
373
|
+
return () => {
|
|
374
|
+
signals.flush();
|
|
375
|
+
};
|
|
376
|
+
}, []);
|
|
377
|
+
|
|
378
|
+
// Node.js
|
|
379
|
+
process.on('beforeExit', async () => {
|
|
380
|
+
await signals.flush();
|
|
381
|
+
});
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### 3. Type-safe Events
|
|
385
|
+
|
|
386
|
+
Define your event types for better DX:
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
type AppEvent =
|
|
390
|
+
| { type: 'page_view'; page: string; title: string }
|
|
391
|
+
| { type: 'button_click'; element: string }
|
|
392
|
+
| { type: 'purchase'; productId: string; amount: number };
|
|
393
|
+
|
|
394
|
+
const signals = new Signals({...});
|
|
395
|
+
|
|
396
|
+
function trackEvent(event: AppEvent) {
|
|
397
|
+
signals.event(event);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Now fully type-safe!
|
|
401
|
+
trackEvent({ type: 'page_view', page: '/home', title: 'Home' });
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### 4. User Identification
|
|
405
|
+
|
|
406
|
+
Include user ID in all events:
|
|
407
|
+
|
|
408
|
+
```typescript
|
|
409
|
+
function trackUserEvent(event: Omit<EventData, 'userId'>) {
|
|
410
|
+
const userId = getCurrentUserId();
|
|
411
|
+
signals.event({ ...event, userId });
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## License
|
|
416
|
+
|
|
417
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
interface EventData {
|
|
2
|
+
type: string;
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
interface Event {
|
|
6
|
+
event_id: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
session_id: string;
|
|
9
|
+
type: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
interface ClientMetadata {
|
|
13
|
+
type: 'web' | 'react-native' | 'node';
|
|
14
|
+
version: string;
|
|
15
|
+
user_agent?: string;
|
|
16
|
+
screen?: {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
locale?: string;
|
|
21
|
+
timezone?: string;
|
|
22
|
+
}
|
|
23
|
+
interface EventBatch {
|
|
24
|
+
api_key: string;
|
|
25
|
+
batch_id: string;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
metadata: ClientMetadata;
|
|
28
|
+
events: Event[];
|
|
29
|
+
}
|
|
30
|
+
interface SignalsConfig {
|
|
31
|
+
apiKey: string;
|
|
32
|
+
endpoint: string;
|
|
33
|
+
batchSize?: number;
|
|
34
|
+
batchInterval?: number;
|
|
35
|
+
maxRetries?: number;
|
|
36
|
+
retryDelay?: number;
|
|
37
|
+
debug?: boolean;
|
|
38
|
+
storage?: StorageAdapter;
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
}
|
|
41
|
+
interface StorageAdapter {
|
|
42
|
+
getItem(key: string): Promise<string | null>;
|
|
43
|
+
setItem(key: string, value: string): Promise<void>;
|
|
44
|
+
removeItem(key: string): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
interface QueuedEvent {
|
|
47
|
+
event: Event;
|
|
48
|
+
timestamp: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
declare class Signals {
|
|
52
|
+
private config;
|
|
53
|
+
private queue;
|
|
54
|
+
private flushTimer;
|
|
55
|
+
private isDestroyed;
|
|
56
|
+
private isFlushing;
|
|
57
|
+
constructor(config: SignalsConfig);
|
|
58
|
+
private init;
|
|
59
|
+
event(eventData: EventData): Promise<void>;
|
|
60
|
+
flush(): Promise<void>;
|
|
61
|
+
private sendBatch;
|
|
62
|
+
private startFlushTimer;
|
|
63
|
+
private stopFlushTimer;
|
|
64
|
+
getSessionId(): string;
|
|
65
|
+
getQueueSize(): number;
|
|
66
|
+
destroy(): Promise<void>;
|
|
67
|
+
private log;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
declare class EventQueue {
|
|
71
|
+
private queue;
|
|
72
|
+
private storage;
|
|
73
|
+
private sessionId;
|
|
74
|
+
constructor(storage: StorageAdapter, sessionId: string);
|
|
75
|
+
init(): Promise<void>;
|
|
76
|
+
add(eventData: EventData): Promise<Event>;
|
|
77
|
+
getAll(): Event[];
|
|
78
|
+
getBatch(size: number): Event[];
|
|
79
|
+
remove(count: number): Promise<void>;
|
|
80
|
+
clear(): Promise<void>;
|
|
81
|
+
size(): number;
|
|
82
|
+
isEmpty(): boolean;
|
|
83
|
+
getOldestTimestamp(): number | null;
|
|
84
|
+
private persist;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
declare class LocalStorageAdapter implements StorageAdapter {
|
|
88
|
+
getItem(key: string): Promise<string | null>;
|
|
89
|
+
setItem(key: string, value: string): Promise<void>;
|
|
90
|
+
removeItem(key: string): Promise<void>;
|
|
91
|
+
static isAvailable(): boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
declare class AsyncStorageAdapter implements StorageAdapter {
|
|
95
|
+
private asyncStorage;
|
|
96
|
+
constructor();
|
|
97
|
+
getItem(key: string): Promise<string | null>;
|
|
98
|
+
setItem(key: string, value: string): Promise<void>;
|
|
99
|
+
removeItem(key: string): Promise<void>;
|
|
100
|
+
static isAvailable(): boolean;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
declare class MemoryStorageAdapter implements StorageAdapter {
|
|
104
|
+
private storage;
|
|
105
|
+
getItem(key: string): Promise<string | null>;
|
|
106
|
+
setItem(key: string, value: string): Promise<void>;
|
|
107
|
+
removeItem(key: string): Promise<void>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
declare function getDefaultStorageAdapter(): StorageAdapter;
|
|
111
|
+
|
|
112
|
+
export { AsyncStorageAdapter, type ClientMetadata, type Event, type EventBatch, type EventData, EventQueue, LocalStorageAdapter, MemoryStorageAdapter, type QueuedEvent, Signals, type SignalsConfig, type StorageAdapter, getDefaultStorageAdapter };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
interface EventData {
|
|
2
|
+
type: string;
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
interface Event {
|
|
6
|
+
event_id: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
session_id: string;
|
|
9
|
+
type: string;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
interface ClientMetadata {
|
|
13
|
+
type: 'web' | 'react-native' | 'node';
|
|
14
|
+
version: string;
|
|
15
|
+
user_agent?: string;
|
|
16
|
+
screen?: {
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
locale?: string;
|
|
21
|
+
timezone?: string;
|
|
22
|
+
}
|
|
23
|
+
interface EventBatch {
|
|
24
|
+
api_key: string;
|
|
25
|
+
batch_id: string;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
metadata: ClientMetadata;
|
|
28
|
+
events: Event[];
|
|
29
|
+
}
|
|
30
|
+
interface SignalsConfig {
|
|
31
|
+
apiKey: string;
|
|
32
|
+
endpoint: string;
|
|
33
|
+
batchSize?: number;
|
|
34
|
+
batchInterval?: number;
|
|
35
|
+
maxRetries?: number;
|
|
36
|
+
retryDelay?: number;
|
|
37
|
+
debug?: boolean;
|
|
38
|
+
storage?: StorageAdapter;
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
}
|
|
41
|
+
interface StorageAdapter {
|
|
42
|
+
getItem(key: string): Promise<string | null>;
|
|
43
|
+
setItem(key: string, value: string): Promise<void>;
|
|
44
|
+
removeItem(key: string): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
interface QueuedEvent {
|
|
47
|
+
event: Event;
|
|
48
|
+
timestamp: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
declare class Signals {
|
|
52
|
+
private config;
|
|
53
|
+
private queue;
|
|
54
|
+
private flushTimer;
|
|
55
|
+
private isDestroyed;
|
|
56
|
+
private isFlushing;
|
|
57
|
+
constructor(config: SignalsConfig);
|
|
58
|
+
private init;
|
|
59
|
+
event(eventData: EventData): Promise<void>;
|
|
60
|
+
flush(): Promise<void>;
|
|
61
|
+
private sendBatch;
|
|
62
|
+
private startFlushTimer;
|
|
63
|
+
private stopFlushTimer;
|
|
64
|
+
getSessionId(): string;
|
|
65
|
+
getQueueSize(): number;
|
|
66
|
+
destroy(): Promise<void>;
|
|
67
|
+
private log;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
declare class EventQueue {
|
|
71
|
+
private queue;
|
|
72
|
+
private storage;
|
|
73
|
+
private sessionId;
|
|
74
|
+
constructor(storage: StorageAdapter, sessionId: string);
|
|
75
|
+
init(): Promise<void>;
|
|
76
|
+
add(eventData: EventData): Promise<Event>;
|
|
77
|
+
getAll(): Event[];
|
|
78
|
+
getBatch(size: number): Event[];
|
|
79
|
+
remove(count: number): Promise<void>;
|
|
80
|
+
clear(): Promise<void>;
|
|
81
|
+
size(): number;
|
|
82
|
+
isEmpty(): boolean;
|
|
83
|
+
getOldestTimestamp(): number | null;
|
|
84
|
+
private persist;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
declare class LocalStorageAdapter implements StorageAdapter {
|
|
88
|
+
getItem(key: string): Promise<string | null>;
|
|
89
|
+
setItem(key: string, value: string): Promise<void>;
|
|
90
|
+
removeItem(key: string): Promise<void>;
|
|
91
|
+
static isAvailable(): boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
declare class AsyncStorageAdapter implements StorageAdapter {
|
|
95
|
+
private asyncStorage;
|
|
96
|
+
constructor();
|
|
97
|
+
getItem(key: string): Promise<string | null>;
|
|
98
|
+
setItem(key: string, value: string): Promise<void>;
|
|
99
|
+
removeItem(key: string): Promise<void>;
|
|
100
|
+
static isAvailable(): boolean;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
declare class MemoryStorageAdapter implements StorageAdapter {
|
|
104
|
+
private storage;
|
|
105
|
+
getItem(key: string): Promise<string | null>;
|
|
106
|
+
setItem(key: string, value: string): Promise<void>;
|
|
107
|
+
removeItem(key: string): Promise<void>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
declare function getDefaultStorageAdapter(): StorageAdapter;
|
|
111
|
+
|
|
112
|
+
export { AsyncStorageAdapter, type ClientMetadata, type Event, type EventBatch, type EventData, EventQueue, LocalStorageAdapter, MemoryStorageAdapter, type QueuedEvent, Signals, type SignalsConfig, type StorageAdapter, getDefaultStorageAdapter };
|