@getlimelight/sdk 0.1.1
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.md +21 -0
- package/README.md +488 -0
- package/dist/index.d.mts +399 -0
- package/dist/index.d.ts +399 -0
- package/dist/index.js +1244 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1207 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +74 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Limelight
|
|
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,488 @@
|
|
|
1
|
+
# Limelight SDK
|
|
2
|
+
|
|
3
|
+
> **Chrome DevTools for React Native** - Real-time debugging with GraphQL-first network inspection, console streaming, and intelligent issue detection.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@getlimelight/sdk)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 🔍 **Network Inspection** - Capture and analyze all network requests (fetch & XMLHttpRequest)
|
|
12
|
+
- 🎯 **GraphQL-First** - Automatic GraphQL operation detection, complexity analysis, and query parsing
|
|
13
|
+
- 📊 **Console Streaming** - Real-time console logs with source detection and stack traces
|
|
14
|
+
- 🛡️ **Privacy-First** - Automatic redaction of sensitive headers and configurable data filtering
|
|
15
|
+
- ⚡ **Zero Config** - Works out of the box with sensible defaults
|
|
16
|
+
- 🎨 **Type Safe** - Full TypeScript support with comprehensive type definitions
|
|
17
|
+
- 🔌 **Framework Agnostic** - Works with React Native, Expo, and web applications
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @getlimelight/sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
yarn add @getlimelight/sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add @getlimelight/sdk
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Basic Usage
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
39
|
+
|
|
40
|
+
// That's it! One line to start debugging
|
|
41
|
+
Limelight.connect();
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### React Native
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
48
|
+
|
|
49
|
+
Limelight.connect();
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Expo
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
56
|
+
import Constants from "expo-constants";
|
|
57
|
+
|
|
58
|
+
Limelight.connect({
|
|
59
|
+
enabled: __DEV__,
|
|
60
|
+
appName: Constants.expoConfig?.name,
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Configuration
|
|
65
|
+
|
|
66
|
+
### Configuration Options
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { Limelight } from '@getlimelight/sdk';
|
|
70
|
+
|
|
71
|
+
Limelight.connect({
|
|
72
|
+
// Optional: Platform identifier (auto-detected)
|
|
73
|
+
platform?: string;
|
|
74
|
+
|
|
75
|
+
// Optional: Custom server URL (defaults to ws://localhost:8080)
|
|
76
|
+
serverUrl?: string;
|
|
77
|
+
|
|
78
|
+
// Optional: Your app name
|
|
79
|
+
appName?: string;
|
|
80
|
+
|
|
81
|
+
// Optional: Enable/disable the SDK (defaults to true)
|
|
82
|
+
enabled?: boolean;
|
|
83
|
+
|
|
84
|
+
// Optional: Enable network request interception (defaults to true)
|
|
85
|
+
enableNetworkInspector?: boolean;
|
|
86
|
+
|
|
87
|
+
// Optional: Enable console log capture (defaults to true)
|
|
88
|
+
enableConsole?: boolean;
|
|
89
|
+
|
|
90
|
+
// Optional: Enable GraphQL operation detection (defaults to true)
|
|
91
|
+
enableGraphQL?: boolean;
|
|
92
|
+
|
|
93
|
+
// Optional: Disable request/response body capture (defaults to false)
|
|
94
|
+
disableBodyCapture?: boolean;
|
|
95
|
+
|
|
96
|
+
// Optional: Filter or modify events before sending
|
|
97
|
+
beforeSend?: (event: LimelightMessage) => LimelightMessage | null;
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Example: Production-Safe Setup
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
105
|
+
|
|
106
|
+
Limelight.connect({
|
|
107
|
+
enabled: __DEV__, // Only enable in development
|
|
108
|
+
appName: "MyAwesomeApp",
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Example: Custom Server URL
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
116
|
+
|
|
117
|
+
Limelight.connect({
|
|
118
|
+
serverUrl: "ws://192.168.1.100:8080", // Your computer's IP
|
|
119
|
+
appName: "MyApp",
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### beforeSend Hook
|
|
124
|
+
|
|
125
|
+
Filter or modify events before they're sent to the server:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
129
|
+
|
|
130
|
+
Limelight.connect({
|
|
131
|
+
beforeSend: (event) => {
|
|
132
|
+
// Filter out specific URLs
|
|
133
|
+
if (event.phase === "NETWORK" && event.url.includes("/analytics")) {
|
|
134
|
+
return null; // Don't send this event
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Redact sensitive data from console logs
|
|
138
|
+
if (event.phase === "CONSOLE") {
|
|
139
|
+
event.args = event.args.map((arg) =>
|
|
140
|
+
typeof arg === "string"
|
|
141
|
+
? arg.replace(/password=\w+/g, "password=***")
|
|
142
|
+
: arg
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return event;
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## What Gets Captured
|
|
152
|
+
|
|
153
|
+
### Network Requests
|
|
154
|
+
|
|
155
|
+
- ✅ Fetch API requests
|
|
156
|
+
- ✅ XMLHttpRequest (XHR)
|
|
157
|
+
- ✅ Request/response headers
|
|
158
|
+
- ✅ Request/response bodies
|
|
159
|
+
- ✅ GraphQL operations (queries, mutations, subscriptions)
|
|
160
|
+
- ✅ GraphQL complexity analysis
|
|
161
|
+
- ✅ Request timing and duration
|
|
162
|
+
- ✅ Error responses
|
|
163
|
+
|
|
164
|
+
**Automatically Redacted Headers:**
|
|
165
|
+
|
|
166
|
+
- `authorization`
|
|
167
|
+
- `cookie`
|
|
168
|
+
- `x-api-key`
|
|
169
|
+
- `x-auth-token`
|
|
170
|
+
- And more...
|
|
171
|
+
|
|
172
|
+
### Console Logs
|
|
173
|
+
|
|
174
|
+
- ✅ All console methods (log, warn, error, info, debug, trace)
|
|
175
|
+
- ✅ Stack traces
|
|
176
|
+
- ✅ Source detection (app, library, React Native, native)
|
|
177
|
+
- ✅ Timestamps
|
|
178
|
+
- ✅ Argument serialization (with circular reference handling)
|
|
179
|
+
|
|
180
|
+
### GraphQL Support
|
|
181
|
+
|
|
182
|
+
Limelight automatically detects and parses GraphQL operations:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// This request will be detected as a GraphQL query
|
|
186
|
+
fetch("/graphql", {
|
|
187
|
+
method: "POST",
|
|
188
|
+
body: JSON.stringify({
|
|
189
|
+
query: `
|
|
190
|
+
query GetUser($id: ID!) {
|
|
191
|
+
user(id: $id) {
|
|
192
|
+
name
|
|
193
|
+
email
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
`,
|
|
197
|
+
variables: { id: "123" },
|
|
198
|
+
}),
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// Limelight captures:
|
|
202
|
+
// - Operation type (query/mutation/subscription)
|
|
203
|
+
// - Operation name (GetUser)
|
|
204
|
+
// - Query complexity
|
|
205
|
+
// - Variables
|
|
206
|
+
// - Response data
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## API Reference
|
|
210
|
+
|
|
211
|
+
### Limelight
|
|
212
|
+
|
|
213
|
+
#### Methods
|
|
214
|
+
|
|
215
|
+
##### `Limelight.connect(config?: LimelightConfig): void`
|
|
216
|
+
|
|
217
|
+
Connects to the Limelight server and starts intercepting network requests and console logs.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
221
|
+
|
|
222
|
+
// Minimal usage
|
|
223
|
+
Limelight.connect();
|
|
224
|
+
|
|
225
|
+
// With configuration
|
|
226
|
+
Limelight.connect({
|
|
227
|
+
enabled: __DEV__,
|
|
228
|
+
appName: "MyApp",
|
|
229
|
+
serverUrl: "ws://localhost:8080",
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
##### `Limelight.disconnect(): void`
|
|
234
|
+
|
|
235
|
+
Disconnects from the Limelight server and stops all interception.
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
Limelight.disconnect();
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Event Types
|
|
242
|
+
|
|
243
|
+
### Network Events
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
interface NetworkEvent {
|
|
247
|
+
id: string;
|
|
248
|
+
phase: "NETWORK_REQUEST" | "NETWORK_RESPONSE";
|
|
249
|
+
type: "NETWORK";
|
|
250
|
+
timestamp: number;
|
|
251
|
+
sessionId: string;
|
|
252
|
+
url: string;
|
|
253
|
+
method: string;
|
|
254
|
+
headers: Record<string, string>;
|
|
255
|
+
body?: string;
|
|
256
|
+
status?: number;
|
|
257
|
+
duration?: number;
|
|
258
|
+
isGraphQL?: boolean;
|
|
259
|
+
graphQLOperation?: {
|
|
260
|
+
type: "query" | "mutation" | "subscription";
|
|
261
|
+
name: string;
|
|
262
|
+
complexity: number;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Console Events
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
interface ConsoleEvent {
|
|
271
|
+
id: string;
|
|
272
|
+
phase: "CONSOLE";
|
|
273
|
+
type: "CONSOLE";
|
|
274
|
+
level: "log" | "warn" | "error" | "info" | "debug" | "trace";
|
|
275
|
+
timestamp: number;
|
|
276
|
+
sessionId: string;
|
|
277
|
+
source: "APP" | "LIBRARY" | "REACT_NATIVE" | "NATIVE";
|
|
278
|
+
args: string[];
|
|
279
|
+
stackTrace?: string;
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Advanced Usage
|
|
284
|
+
|
|
285
|
+
### Disable Specific Features
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
289
|
+
|
|
290
|
+
Limelight.connect({
|
|
291
|
+
enableNetworkInspector: true, // Capture network requests
|
|
292
|
+
enableConsole: true, // Capture console logs
|
|
293
|
+
enableGraphQL: false, // Disable GraphQL parsing
|
|
294
|
+
disableBodyCapture: false, // Capture request/response bodies
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Environment-Specific Configuration
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
302
|
+
|
|
303
|
+
const getConfig = () => {
|
|
304
|
+
if (process.env.NODE_ENV === "production") {
|
|
305
|
+
return { enabled: false };
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (process.env.STAGING === "true") {
|
|
309
|
+
return {
|
|
310
|
+
serverUrl: "wss://limelight-staging.yourcompany.com",
|
|
311
|
+
enabled: true,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return {
|
|
316
|
+
serverUrl: "ws://localhost:8080",
|
|
317
|
+
enabled: true,
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
Limelight.connect(getConfig());
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Filtering Sensitive Routes
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
328
|
+
|
|
329
|
+
const SENSITIVE_ROUTES = ["/auth", "/payment", "/checkout"];
|
|
330
|
+
|
|
331
|
+
Limelight.connect({
|
|
332
|
+
beforeSend: (event) => {
|
|
333
|
+
if (event.phase === "NETWORK" || event.phase === "NETWORK_REQUEST") {
|
|
334
|
+
const isSensitive = SENSITIVE_ROUTES.some((route) =>
|
|
335
|
+
event.url.includes(route)
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
if (isSensitive) {
|
|
339
|
+
return null; // Don't send sensitive requests
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
return event;
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## TypeScript Support
|
|
349
|
+
|
|
350
|
+
Limelight is written in TypeScript and provides full type definitions:
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
import {
|
|
354
|
+
Limelight,
|
|
355
|
+
LimelightConfig,
|
|
356
|
+
LimelightMessage,
|
|
357
|
+
NetworkEvent,
|
|
358
|
+
ConsoleEvent,
|
|
359
|
+
} from "@getlimelight/sdk";
|
|
360
|
+
|
|
361
|
+
const config: LimelightConfig = {
|
|
362
|
+
enabled: __DEV__,
|
|
363
|
+
appName: "MyApp",
|
|
364
|
+
beforeSend: (event: LimelightMessage) => {
|
|
365
|
+
// Full type safety
|
|
366
|
+
if (event.phase === "NETWORK") {
|
|
367
|
+
console.log(event.url); // TypeScript knows this exists
|
|
368
|
+
}
|
|
369
|
+
return event;
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
Limelight.connect(config);
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## Performance
|
|
377
|
+
|
|
378
|
+
Limelight is designed to have minimal performance impact:
|
|
379
|
+
|
|
380
|
+
- **Non-blocking**: All network interception happens asynchronously
|
|
381
|
+
- **Efficient serialization**: Smart stringification with circular reference handling
|
|
382
|
+
- **Message queuing**: Buffers messages when disconnected to prevent blocking
|
|
383
|
+
- **Configurable depth limits**: Prevents deep object traversal overhead
|
|
384
|
+
- **Production safe**: Easy to disable in production builds
|
|
385
|
+
|
|
386
|
+
## Security & Privacy
|
|
387
|
+
|
|
388
|
+
### Automatic Redaction
|
|
389
|
+
|
|
390
|
+
Limelight automatically redacts sensitive headers:
|
|
391
|
+
|
|
392
|
+
- Authorization tokens
|
|
393
|
+
- API keys
|
|
394
|
+
- Cookies
|
|
395
|
+
- Session tokens
|
|
396
|
+
|
|
397
|
+
### Custom Filtering
|
|
398
|
+
|
|
399
|
+
Use the `beforeSend` hook to implement custom privacy rules:
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
403
|
+
|
|
404
|
+
Limelight.connect({
|
|
405
|
+
beforeSend: (event) => {
|
|
406
|
+
// Remove PII from request bodies
|
|
407
|
+
if (event.phase === "NETWORK_REQUEST" && event.body) {
|
|
408
|
+
try {
|
|
409
|
+
const body = JSON.parse(event.body);
|
|
410
|
+
delete body.ssn;
|
|
411
|
+
delete body.creditCard;
|
|
412
|
+
event.body = JSON.stringify(body);
|
|
413
|
+
} catch {
|
|
414
|
+
// Not JSON, leave as-is
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return event;
|
|
418
|
+
},
|
|
419
|
+
});
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Disable Body Capture
|
|
423
|
+
|
|
424
|
+
For maximum privacy, disable request/response body capture entirely:
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
Limelight.connect({
|
|
428
|
+
disableBodyCapture: true, // Only capture headers and metadata
|
|
429
|
+
});
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Troubleshooting
|
|
433
|
+
|
|
434
|
+
### Connection Issues
|
|
435
|
+
|
|
436
|
+
If you're having trouble connecting:
|
|
437
|
+
|
|
438
|
+
1. **Check your server is running** - Make sure the Limelight server is running on the specified port
|
|
439
|
+
2. **Verify the URL** - Default is `ws://localhost:8080`, but you may need your computer's IP address for physical devices
|
|
440
|
+
3. **Enable in config** - Ensure `enabled: true` (or omit it, as it defaults to true)
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
import { Limelight } from "@getlimelight/sdk";
|
|
444
|
+
|
|
445
|
+
// For physical devices, use your computer's IP
|
|
446
|
+
Limelight.connect({
|
|
447
|
+
serverUrl: "ws://192.168.1.100:8080", // Replace with your IP
|
|
448
|
+
enabled: true,
|
|
449
|
+
});
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Not Seeing Network Requests
|
|
453
|
+
|
|
454
|
+
1. Make sure `enableNetworkInspector` is not set to `false`
|
|
455
|
+
2. Ensure `Limelight.connect()` is called early in your app
|
|
456
|
+
3. Check if `beforeSend` is filtering out requests
|
|
457
|
+
|
|
458
|
+
### Console Logs Not Appearing
|
|
459
|
+
|
|
460
|
+
1. Ensure `enableConsole` is not set to `false`
|
|
461
|
+
2. Verify `Limelight.connect()` is called before logs occur
|
|
462
|
+
3. Check the WebSocket connection is established
|
|
463
|
+
|
|
464
|
+
## Examples
|
|
465
|
+
|
|
466
|
+
See the `/examples` directory for complete working examples:
|
|
467
|
+
|
|
468
|
+
- Basic React Native app
|
|
469
|
+
- Expo app with environment configuration
|
|
470
|
+
- Next.js web application
|
|
471
|
+
- Custom filtering and privacy controls
|
|
472
|
+
|
|
473
|
+
## Contributing
|
|
474
|
+
|
|
475
|
+
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
476
|
+
|
|
477
|
+
## License
|
|
478
|
+
|
|
479
|
+
MIT © [Your Name/Company]
|
|
480
|
+
|
|
481
|
+
## Support
|
|
482
|
+
|
|
483
|
+
- 📧 Email: support@getlimelight.io
|
|
484
|
+
- 🐛 Issues: [GitHub Issues](https://github.com/getlimelight/limelight/issues)
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
Built with ❤️ for React Native developers
|