@layers/client 1.1.0 → 1.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/README.md +362 -111
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,64 +1,289 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Layers Web SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@layers/client` is the Layers analytics SDK for web browsers. It provides event tracking, screen tracking, user identification, automatic attribution capture (UTM parameters, click IDs, referrer), consent management, and lifecycle-aware event flushing with `sendBeacon` support.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- Modern browser with ES module support
|
|
8
|
+
- React 18+ (for React hooks, optional)
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
6
11
|
|
|
7
12
|
```bash
|
|
8
13
|
npm install @layers/client
|
|
9
14
|
# or
|
|
15
|
+
yarn add @layers/client
|
|
16
|
+
# or
|
|
10
17
|
pnpm add @layers/client
|
|
11
18
|
```
|
|
12
19
|
|
|
13
20
|
## Quick Start
|
|
14
21
|
|
|
15
|
-
```
|
|
22
|
+
```typescript
|
|
16
23
|
import { LayersClient } from '@layers/client';
|
|
17
24
|
|
|
18
25
|
const layers = new LayersClient({
|
|
19
|
-
apiKey: 'your-api-key',
|
|
20
26
|
appId: 'your-app-id',
|
|
21
27
|
environment: 'production'
|
|
22
28
|
});
|
|
23
|
-
|
|
24
29
|
await layers.init();
|
|
25
30
|
|
|
26
31
|
// Track events
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// Track screen views
|
|
30
|
-
await layers.screen('home_page');
|
|
32
|
+
layers.track('button_click', { button_name: 'signup' });
|
|
31
33
|
|
|
32
|
-
//
|
|
33
|
-
layers.
|
|
34
|
+
// Track page views
|
|
35
|
+
layers.screen('Home');
|
|
34
36
|
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
+
// Identify users
|
|
38
|
+
layers.setAppUserId('user_123');
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
## Configuration
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
### LayersConfig
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
interface LayersConfig {
|
|
47
|
+
appId: string;
|
|
48
|
+
environment: 'development' | 'staging' | 'production';
|
|
49
|
+
appUserId?: string;
|
|
50
|
+
enableDebug?: boolean;
|
|
51
|
+
baseUrl?: string;
|
|
52
|
+
flushIntervalMs?: number;
|
|
53
|
+
flushThreshold?: number;
|
|
54
|
+
maxQueueSize?: number;
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| Option | Type | Default | Description |
|
|
59
|
+
| ----------------- | ------------- | ------------------------- | ------------------------------------------------ |
|
|
60
|
+
| `appId` | `string` | _required_ | Your Layers application identifier. |
|
|
61
|
+
| `environment` | `Environment` | _required_ | `'development'`, `'staging'`, or `'production'`. |
|
|
62
|
+
| `appUserId` | `string` | `undefined` | Optional user ID to set at construction time. |
|
|
63
|
+
| `enableDebug` | `boolean` | `false` | Enable verbose console logging. |
|
|
64
|
+
| `baseUrl` | `string` | `"https://in.layers.com"` | Custom ingest API endpoint. |
|
|
65
|
+
| `flushIntervalMs` | `number` | `30000` | Automatic flush interval in milliseconds. |
|
|
66
|
+
| `flushThreshold` | `number` | `10` | Queue size that triggers an automatic flush. |
|
|
67
|
+
| `maxQueueSize` | `number` | `1000` | Maximum events in the queue before dropping. |
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const layers = new LayersClient({
|
|
71
|
+
appId: 'your-app-id',
|
|
72
|
+
environment: 'development',
|
|
73
|
+
enableDebug: true,
|
|
74
|
+
flushIntervalMs: 15000,
|
|
75
|
+
flushThreshold: 5,
|
|
76
|
+
maxQueueSize: 5000
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Core API
|
|
42
81
|
|
|
43
|
-
|
|
44
|
-
| ----------------- | -------------------------------------------- | ----------------------- | ------------------------------------------ |
|
|
45
|
-
| `apiKey` | `string` | _required_ | API key from the Layers dashboard |
|
|
46
|
-
| `appId` | `string` | _required_ | Application identifier |
|
|
47
|
-
| `environment` | `'development' \| 'staging' \| 'production'` | _required_ | Deployment environment |
|
|
48
|
-
| `appUserId` | `string` | `undefined` | Pre-set user ID at init time |
|
|
49
|
-
| `enableDebug` | `boolean` | `false` | Verbose console logging for all SDK calls |
|
|
50
|
-
| `baseUrl` | `string` | `https://in.layers.com` | Override the ingest endpoint |
|
|
51
|
-
| `flushIntervalMs` | `number` | `30000` | Periodic flush interval (ms) |
|
|
52
|
-
| `flushThreshold` | `number` | `10` | Queue depth that triggers auto-flush |
|
|
53
|
-
| `maxQueueSize` | `number` | `1000` | Max events in queue before dropping oldest |
|
|
82
|
+
### Constructor & Initialization
|
|
54
83
|
|
|
55
|
-
|
|
84
|
+
```typescript
|
|
85
|
+
const layers = new LayersClient(config: LayersConfig);
|
|
86
|
+
await layers.init();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The constructor creates the SDK instance with localStorage-backed persistence. Calling `init()` detects device info, attaches lifecycle listeners (online/offline, visibility change, beforeunload), captures attribution signals, and fetches remote config.
|
|
90
|
+
|
|
91
|
+
You can call `track()` and `screen()` before `init()` completes -- events are queued.
|
|
56
92
|
|
|
57
|
-
|
|
93
|
+
### Event Tracking
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
track(eventName: string, properties?: EventProperties): void
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Events are batched and flushed automatically. Attribution properties (UTM, click IDs, referrer) from the current session are automatically merged into every event.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
layers.track('purchase_completed', {
|
|
103
|
+
product_id: 'sku_123',
|
|
104
|
+
price: 9.99,
|
|
105
|
+
currency: 'USD'
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Screen/Page Tracking
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
screen(screenName: string, properties?: EventProperties): void
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Attribution properties are automatically merged.
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
layers.screen('ProductDetail', { product_id: 'sku_123' });
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### User Identity
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// Set or clear the app user ID
|
|
125
|
+
setAppUserId(appUserId: string | undefined): void
|
|
126
|
+
|
|
127
|
+
// Get the current user ID
|
|
128
|
+
getAppUserId(): string | undefined
|
|
129
|
+
|
|
130
|
+
// Deprecated aliases
|
|
131
|
+
setUserId(userId: string): void
|
|
132
|
+
getUserId(): string | undefined
|
|
133
|
+
```
|
|
58
134
|
|
|
59
|
-
|
|
135
|
+
```typescript
|
|
136
|
+
// After login
|
|
137
|
+
layers.setAppUserId('user_123');
|
|
60
138
|
|
|
61
|
-
|
|
139
|
+
// On logout
|
|
140
|
+
layers.setAppUserId(undefined);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### User Properties
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
setUserProperties(properties: UserProperties): void
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
layers.setUserProperties({
|
|
151
|
+
email: 'user@example.com',
|
|
152
|
+
plan: 'premium',
|
|
153
|
+
signup_date: '2024-01-15'
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Consent Management
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
setConsent(consent: ConsentState): void
|
|
161
|
+
getConsentState(): ConsentState
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
interface ConsentState {
|
|
166
|
+
analytics?: boolean;
|
|
167
|
+
advertising?: boolean;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// User accepts analytics only
|
|
173
|
+
layers.setConsent({ analytics: true, advertising: false });
|
|
174
|
+
|
|
175
|
+
// Read current state
|
|
176
|
+
const consent = layers.getConsentState();
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Session Management
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// Get the current session ID
|
|
183
|
+
getSessionId(): string
|
|
184
|
+
|
|
185
|
+
// End the current session and start a new one
|
|
186
|
+
startNewSession(): void
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Device Info
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
setDeviceInfo(deviceInfo: DeviceContext): void
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Override auto-detected device context fields.
|
|
196
|
+
|
|
197
|
+
### Flush & Shutdown
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// Flush all queued events to the server
|
|
201
|
+
async flush(): Promise<void>
|
|
202
|
+
|
|
203
|
+
// Shut down immediately (no flush, events persisted to localStorage)
|
|
204
|
+
shutdown(): void
|
|
205
|
+
|
|
206
|
+
// Shut down with a final flush (with timeout)
|
|
207
|
+
async shutdownAsync(timeoutMs?: number): Promise<void> // default: 3000ms
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Error Handling
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
on(event: 'error', listener: (error: Error) => void): this
|
|
214
|
+
off(event: 'error', listener: (error: Error) => void): this
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
layers.on('error', (error) => {
|
|
219
|
+
console.error('Layers error:', error.message);
|
|
220
|
+
});
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Attribution
|
|
224
|
+
|
|
225
|
+
The SDK automatically captures and persists attribution signals from the current page URL and referrer.
|
|
226
|
+
|
|
227
|
+
### Captured Signals
|
|
228
|
+
|
|
229
|
+
**Click IDs** (highest priority -- overwrites existing attribution):
|
|
230
|
+
|
|
231
|
+
- `fbclid` (Meta/Facebook)
|
|
232
|
+
- `gclid`, `gbraid`, `wbraid` (Google)
|
|
233
|
+
- `ttclid` (TikTok)
|
|
234
|
+
- `msclkid` (Microsoft/Bing)
|
|
235
|
+
- `rclid` (Reddit)
|
|
236
|
+
|
|
237
|
+
**UTM Parameters**:
|
|
238
|
+
|
|
239
|
+
- `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`
|
|
240
|
+
|
|
241
|
+
**Referrer**:
|
|
242
|
+
|
|
243
|
+
- `document.referrer`
|
|
244
|
+
|
|
245
|
+
### How It Works
|
|
246
|
+
|
|
247
|
+
1. On `init()`, the SDK reads the current URL's query parameters and `document.referrer`.
|
|
248
|
+
2. Attribution data is persisted in `localStorage` with a 30-day TTL.
|
|
249
|
+
3. Click IDs take priority -- a new click ID overwrites the entire stored record.
|
|
250
|
+
4. UTM parameters overwrite on fresh campaign visits, but preserve existing click IDs.
|
|
251
|
+
5. Attribution properties are automatically prefixed with `$attribution_` and merged into every `track()` and `screen()` call.
|
|
252
|
+
|
|
253
|
+
### Manually Reading Attribution
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import { getAttribution, getAttributionProperties } from '@layers/client';
|
|
257
|
+
|
|
258
|
+
// Get the full stored attribution data (or null if expired/missing)
|
|
259
|
+
const attribution = getAttribution();
|
|
260
|
+
|
|
261
|
+
// Get a flat property bag for merging into events
|
|
262
|
+
const props = getAttributionProperties();
|
|
263
|
+
// { '$attribution_utm_source': 'google', '$attribution_click_id_param': 'gclid', ... }
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### AttributionData Type
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
interface AttributionData {
|
|
270
|
+
click_id_param?: string;
|
|
271
|
+
click_id_value?: string;
|
|
272
|
+
utm_source?: string;
|
|
273
|
+
utm_medium?: string;
|
|
274
|
+
utm_campaign?: string;
|
|
275
|
+
utm_content?: string;
|
|
276
|
+
utm_term?: string;
|
|
277
|
+
referrer_url?: string;
|
|
278
|
+
captured_at: number;
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## React Integration
|
|
283
|
+
|
|
284
|
+
The SDK includes React hooks for idiomatic usage. Import from `@layers/client/react`.
|
|
285
|
+
|
|
286
|
+
### LayersProvider
|
|
62
287
|
|
|
63
288
|
```tsx
|
|
64
289
|
import { LayersProvider } from '@layers/client/react';
|
|
@@ -67,7 +292,6 @@ function App() {
|
|
|
67
292
|
return (
|
|
68
293
|
<LayersProvider
|
|
69
294
|
config={{
|
|
70
|
-
apiKey: 'your-api-key',
|
|
71
295
|
appId: 'your-app-id',
|
|
72
296
|
environment: 'production'
|
|
73
297
|
}}
|
|
@@ -78,73 +302,87 @@ function App() {
|
|
|
78
302
|
}
|
|
79
303
|
```
|
|
80
304
|
|
|
81
|
-
|
|
305
|
+
Initializes the client on mount and shuts it down on unmount.
|
|
82
306
|
|
|
83
|
-
###
|
|
307
|
+
### useLayers
|
|
84
308
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
309
|
+
```typescript
|
|
310
|
+
function useLayers(): LayersClient;
|
|
311
|
+
```
|
|
88
312
|
|
|
89
|
-
Returns
|
|
313
|
+
Returns the `LayersClient` instance. Throws if used outside a `<LayersProvider>`.
|
|
90
314
|
|
|
91
315
|
```tsx
|
|
92
|
-
|
|
316
|
+
function MyComponent() {
|
|
317
|
+
const layers = useLayers();
|
|
318
|
+
layers.track('component_viewed');
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### useTrack
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
function useTrack(): (eventName: string, properties?: EventProperties) => void;
|
|
326
|
+
```
|
|
93
327
|
|
|
328
|
+
Returns a stable, memoized track function.
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
94
331
|
function SignupButton() {
|
|
95
332
|
const track = useTrack();
|
|
96
333
|
|
|
97
|
-
return <button onClick={() => track('signup_click', { source: 'hero' })}>Sign
|
|
334
|
+
return <button onClick={() => track('signup_click', { source: 'hero' })}>Sign Up</button>;
|
|
98
335
|
}
|
|
99
336
|
```
|
|
100
337
|
|
|
101
|
-
|
|
338
|
+
### useScreen
|
|
102
339
|
|
|
103
|
-
|
|
340
|
+
```typescript
|
|
341
|
+
function useScreen(): (screenName: string, properties?: EventProperties) => void;
|
|
342
|
+
```
|
|
104
343
|
|
|
105
|
-
|
|
106
|
-
import { useScreen } from '@layers/client/react';
|
|
107
|
-
import { useEffect } from 'react';
|
|
344
|
+
Returns a stable, memoized screen tracking function.
|
|
108
345
|
|
|
346
|
+
```tsx
|
|
109
347
|
function Dashboard() {
|
|
110
348
|
const screen = useScreen();
|
|
111
349
|
useEffect(() => {
|
|
112
|
-
screen('
|
|
350
|
+
screen('Dashboard');
|
|
113
351
|
}, [screen]);
|
|
114
352
|
|
|
115
|
-
return <div
|
|
353
|
+
return <div>Dashboard</div>;
|
|
116
354
|
}
|
|
117
355
|
```
|
|
118
356
|
|
|
119
|
-
|
|
357
|
+
### useIdentify
|
|
120
358
|
|
|
121
|
-
|
|
359
|
+
```typescript
|
|
360
|
+
function useIdentify(): (userId: string | undefined) => void;
|
|
361
|
+
```
|
|
122
362
|
|
|
123
|
-
|
|
124
|
-
import { useIdentify } from '@layers/client/react';
|
|
363
|
+
Returns a stable, memoized identify function. Pass `undefined` to clear.
|
|
125
364
|
|
|
365
|
+
```tsx
|
|
126
366
|
function LoginForm() {
|
|
127
367
|
const identify = useIdentify();
|
|
128
368
|
|
|
129
|
-
const onLogin = (userId: string) =>
|
|
130
|
-
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const onLogout = () => {
|
|
134
|
-
identify(undefined);
|
|
135
|
-
};
|
|
369
|
+
const onLogin = (userId: string) => identify(userId);
|
|
370
|
+
const onLogout = () => identify(undefined);
|
|
136
371
|
}
|
|
137
372
|
```
|
|
138
373
|
|
|
139
|
-
|
|
374
|
+
### useConsent
|
|
140
375
|
|
|
141
|
-
|
|
376
|
+
```typescript
|
|
377
|
+
function useConsent(): {
|
|
378
|
+
setConsent: (consent: ConsentState) => void;
|
|
379
|
+
getConsentState: () => ConsentState;
|
|
380
|
+
};
|
|
381
|
+
```
|
|
142
382
|
|
|
143
383
|
```tsx
|
|
144
|
-
import { useConsent } from '@layers/client/react';
|
|
145
|
-
|
|
146
384
|
function ConsentBanner() {
|
|
147
|
-
const { setConsent
|
|
385
|
+
const { setConsent } = useConsent();
|
|
148
386
|
|
|
149
387
|
return (
|
|
150
388
|
<button onClick={() => setConsent({ analytics: true, advertising: false })}>
|
|
@@ -154,71 +392,84 @@ function ConsentBanner() {
|
|
|
154
392
|
}
|
|
155
393
|
```
|
|
156
394
|
|
|
157
|
-
|
|
395
|
+
## Automatic Behaviors
|
|
158
396
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
397
|
+
- **Attribution capture**: UTM parameters, click IDs, and referrer are captured and persisted on init.
|
|
398
|
+
- **Attribution enrichment**: Stored attribution is merged into every `track()` and `screen()` call.
|
|
399
|
+
- **Online/offline detection**: Events are flushed when the browser reconnects.
|
|
400
|
+
- **Visibility change flush**: Events are flushed via `navigator.sendBeacon` when the page is hidden (tab switch, minimize).
|
|
401
|
+
- **Before unload flush**: Events are persisted to `localStorage` on page close.
|
|
402
|
+
- **Periodic flush**: Events are flushed on a timer (configurable).
|
|
403
|
+
- **Remote config**: Server configuration is fetched during init.
|
|
404
|
+
- **Device context**: OS, browser, locale, screen size, and timezone are detected automatically.
|
|
405
|
+
- **Event persistence**: Events are persisted in `localStorage` and rehydrated on page load.
|
|
163
406
|
|
|
164
|
-
|
|
165
|
-
const layers = useLayers();
|
|
166
|
-
// layers.setUserProperties({ plan: 'pro' });
|
|
167
|
-
}
|
|
168
|
-
```
|
|
407
|
+
## SPA (Single Page App) Usage
|
|
169
408
|
|
|
170
|
-
|
|
409
|
+
For single-page apps with client-side routing, call `screen()` on route changes:
|
|
171
410
|
|
|
172
|
-
|
|
411
|
+
```typescript
|
|
412
|
+
// React Router
|
|
413
|
+
import { useLocation } from 'react-router-dom';
|
|
173
414
|
|
|
174
|
-
|
|
175
|
-
const
|
|
415
|
+
function RouteTracker() {
|
|
416
|
+
const location = useLocation();
|
|
417
|
+
const screen = useScreen();
|
|
176
418
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
});
|
|
419
|
+
useEffect(() => {
|
|
420
|
+
screen(location.pathname, { search: location.search });
|
|
421
|
+
}, [location, screen]);
|
|
181
422
|
|
|
182
|
-
|
|
183
|
-
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
184
425
|
```
|
|
185
426
|
|
|
186
|
-
|
|
427
|
+
```typescript
|
|
428
|
+
'use client';
|
|
187
429
|
|
|
188
|
-
|
|
430
|
+
import { usePathname } from 'next/navigation';
|
|
189
431
|
|
|
190
|
-
|
|
432
|
+
function PageTracker() {
|
|
433
|
+
const pathname = usePathname();
|
|
434
|
+
const screen = useScreen();
|
|
191
435
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
436
|
+
useEffect(() => {
|
|
437
|
+
screen(pathname);
|
|
438
|
+
}, [pathname, screen]);
|
|
195
439
|
|
|
196
|
-
|
|
197
|
-
|
|
440
|
+
return null;
|
|
441
|
+
}
|
|
198
442
|
```
|
|
199
443
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
444
|
+
## TypeScript Types
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
import type {
|
|
448
|
+
AttributionData,
|
|
449
|
+
BaseEvent,
|
|
450
|
+
ConsentState,
|
|
451
|
+
DeviceContext,
|
|
452
|
+
Environment,
|
|
453
|
+
ErrorListener,
|
|
454
|
+
EventProperties,
|
|
455
|
+
EventsBatchPayload,
|
|
456
|
+
LayersConfig,
|
|
457
|
+
RemoteConfigResponse,
|
|
458
|
+
UserProperties
|
|
459
|
+
} from '@layers/client';
|
|
216
460
|
```
|
|
217
461
|
|
|
218
|
-
##
|
|
462
|
+
## Wire Protocol Types
|
|
219
463
|
|
|
220
|
-
The
|
|
464
|
+
The package also exports TypeScript interfaces for the Layers wire protocol, useful for building custom integrations:
|
|
221
465
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
466
|
+
```typescript
|
|
467
|
+
import type {
|
|
468
|
+
BaseEvent,
|
|
469
|
+
ConsentPayload,
|
|
470
|
+
EventsBatchPayload,
|
|
471
|
+
RemoteConfigResponse,
|
|
472
|
+
SKANPostbackPayload,
|
|
473
|
+
UserPropertiesPayload
|
|
474
|
+
} from '@layers/client';
|
|
475
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layers/client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"dist"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@layers/core-wasm": "1.
|
|
36
|
+
"@layers/core-wasm": "1.2.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"react": ">=18"
|