@bliplogs/sdk 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/CHANGELOG.md ADDED
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+
3
+ All notable changes to the BlipLogs SDK will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-02-03
9
+
10
+ ### Added
11
+
12
+ - Initial release of the BlipLogs SDK
13
+ - Zero-dependency event tracking for browser and server environments
14
+ - `BlipLogs.configure()` for global configuration
15
+ - `BlipLogs.track()` for general event tracking
16
+ - `BlipLogs.info()`, `BlipLogs.warn()`, `BlipLogs.error()` convenience methods
17
+ - Instance-based API for multiple configurations
18
+ - Automatic browser context capture (URL, referrer, user agent)
19
+ - Sensitive URL parameter redaction for privacy
20
+ - Session tracking with 30-minute timeout
21
+ - `sendBeacon` primary transport with `fetch` fallback
22
+ - Server-side support for Node 18+, Cloudflare Workers, and edge runtimes
23
+ - Debug mode and error callbacks for troubleshooting
24
+ - Full TypeScript support with exported types
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 BlipLogs
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,356 @@
1
+ # BlipLogs SDK
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@bliplogs/sdk.svg)](https://www.npmjs.com/package/@bliplogs/sdk)
4
+ [![npm bundle size](https://img.shields.io/bundlephobia/minzip/@bliplogs/sdk)](https://bundlephobia.com/package/@bliplogs/sdk)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Lightweight event tracking for browser and server. Zero dependencies, under 2KB gzipped.
8
+
9
+ ## Why BlipLogs?
10
+
11
+ - **Tiny** – Under 2KB gzipped, no dependencies
12
+ - **Universal** – Works in browsers, Node 18+, Cloudflare Workers, edge runtimes
13
+ - **Fast** – Uses `sendBeacon` for non-blocking delivery, falls back to `fetch`
14
+ - **Simple** – Configure once, track anywhere
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @bliplogs/sdk
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```typescript
25
+ import BlipLogs from '@bliplogs/sdk';
26
+
27
+ BlipLogs.configure({
28
+ apiKey: 'your-api-key',
29
+ projectId: 'your-project-id'
30
+ });
31
+
32
+ BlipLogs.track('signup_clicked', { plan: 'pro' });
33
+ ```
34
+
35
+ That's it. Three lines to start tracking.
36
+
37
+ ## Log Levels
38
+
39
+ ```typescript
40
+ BlipLogs.info('page_viewed', { page: '/dashboard' });
41
+ BlipLogs.warn('slow_request', { duration: 5000 });
42
+ BlipLogs.error('api_error', { status: 500 });
43
+ ```
44
+
45
+ ## Framework Examples
46
+
47
+ ### React / Next.js
48
+
49
+ **1. Create `lib/bliplogs.ts`:**
50
+
51
+ ```typescript
52
+ import BlipLogs from '@bliplogs/sdk';
53
+
54
+ BlipLogs.configure({
55
+ apiKey: process.env.NEXT_PUBLIC_BLIPLOGS_API_KEY || '',
56
+ projectId: process.env.NEXT_PUBLIC_BLIPLOGS_PROJECT_ID || ''
57
+ });
58
+ ```
59
+
60
+ **2. Import in your app entry** (`app/layout.tsx` or `pages/_app.tsx`):
61
+
62
+ ```typescript
63
+ import '../lib/bliplogs';
64
+ ```
65
+
66
+ **3. Use anywhere:**
67
+
68
+ ```tsx
69
+ import BlipLogs from '@bliplogs/sdk';
70
+
71
+ function SignupButton() {
72
+ return (
73
+ <button onClick={() => BlipLogs.track('signup_clicked')}>
74
+ Sign Up
75
+
76
+ );
77
+ }
78
+ ```
79
+
80
+ ### Astro
81
+
82
+ **1. Configure in your layout** (`src/layouts/Layout.astro`):
83
+
84
+ ```astro
85
+ ---
86
+ // Configuration runs at build time, but the SDK handles this gracefully
87
+ import BlipLogs from '@bliplogs/sdk';
88
+
89
+ BlipLogs.configure({
90
+ apiKey: import.meta.env.PUBLIC_BLIPLOGS_API_KEY,
91
+ projectId: import.meta.env.PUBLIC_BLIPLOGS_PROJECT_ID
92
+ });
93
+ ---
94
+
95
+ <html>
96
+ <body>
97
+ <slot />
98
+ </body>
99
+ </html>
100
+ ```
101
+
102
+ **2. Track events with a script tag:**
103
+
104
+ ```astro
105
+ <button id="signup">Sign Up</button>
106
+
107
+ <script>
108
+ import BlipLogs from '@bliplogs/sdk';
109
+
110
+ document.getElementById('signup')?.addEventListener('click', () => {
111
+ BlipLogs.track('signup_clicked');
112
+ });
113
+ </script>
114
+ ```
115
+
116
+ **Or use a React/Svelte/Vue component with `client:load`:**
117
+
118
+ ```astro
119
+ ---
120
+ import SignupButton from '../components/SignupButton.tsx';
121
+ ---
122
+
123
+ <SignupButton client:load />
124
+ ```
125
+
126
+ ### Vanilla JavaScript
127
+
128
+ ```html
129
+
130
+ import BlipLogs from './node_modules/@bliplogs/sdk/dist/index.mjs';
131
+
132
+ BlipLogs.configure({
133
+ apiKey: 'your-api-key',
134
+ projectId: 'your-project-id'
135
+ });
136
+
137
+ document.getElementById('myButton').addEventListener('click', () => {
138
+ BlipLogs.track('button_clicked');
139
+ });
140
+
141
+ ```
142
+
143
+ ## Server-Side Usage
144
+
145
+ The SDK works anywhere with global `fetch`: Node 18+, Cloudflare Workers, Astro actions, and most serverless runtimes.
146
+
147
+ ### Node.js
148
+
149
+ ```typescript
150
+ import BlipLogs from '@bliplogs/sdk';
151
+
152
+ BlipLogs.configure({
153
+ apiKey: process.env.BLIPLOGS_API_KEY!,
154
+ projectId: process.env.BLIPLOGS_PROJECT_ID!
155
+ });
156
+
157
+ // In your request handler
158
+ BlipLogs.info('order_created', { orderId: '123', amount: 4999 });
159
+ ```
160
+
161
+ ### Cloudflare Workers
162
+
163
+ ```typescript
164
+ import BlipLogs from '@bliplogs/sdk';
165
+
166
+ export default {
167
+ async fetch(req: Request, env: Env) {
168
+ BlipLogs.configure({
169
+ apiKey: env.BLIPLOGS_API_KEY,
170
+ projectId: env.BLIPLOGS_PROJECT_ID
171
+ });
172
+
173
+ BlipLogs.track('worker_request', {
174
+ path: new URL(req.url).pathname,
175
+ method: req.method
176
+ });
177
+
178
+ return new Response('OK');
179
+ }
180
+ };
181
+ ```
182
+
183
+ ### Server-Side Limitations
184
+
185
+ | Feature | Browser | Server |
186
+ |---------|---------|--------|
187
+ | Session ID | ✓ Auto-generated | ✗ Not available |
188
+ | URL/Referrer/User Agent | ✓ Auto-captured | ✗ Not captured |
189
+ | Transport | sendBeacon → fetch | fetch only |
190
+
191
+ Pass any server-specific context via metadata:
192
+
193
+ ```typescript
194
+ BlipLogs.track('api_request', {
195
+ path: req.url,
196
+ userAgent: req.headers['user-agent'],
197
+ duration: 120
198
+ });
199
+ ```
200
+
201
+ ## Configuration Options
202
+
203
+ ```typescript
204
+ BlipLogs.configure({
205
+ apiKey: 'your-api-key', // Required
206
+ projectId: 'your-project-id', // Required
207
+ debug: true, // Log errors to console
208
+ onError: (error) => { // Custom error handling
209
+ console.error(error.type, error.message);
210
+ },
211
+ privacy: { // GDPR/privacy controls
212
+ anonymizeIp: true, // Don't store IP or geo data
213
+ collectUrl: false, // Don't collect page URL
214
+ collectReferrer: false, // Don't collect referrer
215
+ collectUserAgent: false, // Don't collect user agent
216
+ collectSessionId: false // Don't track sessions
217
+ }
218
+ });
219
+ ```
220
+
221
+ ## API Reference
222
+
223
+ ### `BlipLogs.configure(config)`
224
+
225
+ Configure the SDK. Call once at app startup.
226
+
227
+ ### `BlipLogs.track(event, metadata?, level?)`
228
+
229
+ Track an event. Returns `boolean` indicating if the event was queued.
230
+
231
+ ```typescript
232
+ BlipLogs.track('checkout_started', { cartValue: 99.99 }, 'info');
233
+ ```
234
+
235
+ ### `BlipLogs.info(event, metadata?)`
236
+ ### `BlipLogs.warn(event, metadata?)`
237
+ ### `BlipLogs.error(event, metadata?)`
238
+
239
+ Convenience methods for specific log levels.
240
+
241
+ ### Instance-Based Usage
242
+
243
+ Need multiple configurations? Create instances:
244
+
245
+ ```typescript
246
+ const analytics = new BlipLogs({
247
+ apiKey: 'analytics-key',
248
+ projectId: 'analytics-project'
249
+ });
250
+
251
+ const errors = new BlipLogs({
252
+ apiKey: 'errors-key',
253
+ projectId: 'errors-project'
254
+ });
255
+
256
+ analytics.track('page_view');
257
+ errors.error('unhandled_exception', { stack: '...' });
258
+ ```
259
+
260
+ ## Error Handling
261
+
262
+ The SDK is fire-and-forget by default – errors won't crash your app. Enable visibility when needed:
263
+
264
+ ```typescript
265
+ BlipLogs.configure({
266
+ apiKey: 'your-api-key',
267
+ projectId: 'your-project-id',
268
+ debug: true,
269
+ onError: (error) => {
270
+ if (error.type === 'rate_limit') {
271
+ console.warn('Rate limit hit');
272
+ }
273
+ }
274
+ });
275
+ ```
276
+
277
+ **Error types:** `network`, `rate_limit`, `auth`, `validation`, `unknown`
278
+
279
+ ## TypeScript
280
+
281
+ Full type definitions included:
282
+
283
+ ```typescript
284
+ import BlipLogs, {
285
+ BlipMetadata,
286
+ BlipLevel,
287
+ BlipLogsConfig,
288
+ BlipLogsError,
289
+ BlipContext,
290
+ BlipPayload,
291
+ BlipPrivacyConfig
292
+ } from '@bliplogs/sdk';
293
+ ```
294
+
295
+ ## How It Works
296
+
297
+ 1. **Browser:** Uses `navigator.sendBeacon()` for fast, non-blocking delivery
298
+ 2. **Fallback:** Automatically uses `fetch()` with `keepalive: true` if sendBeacon is unavailable
299
+ 3. **Server:** Uses `fetch()` directly
300
+ 4. **Context:** Auto-captures URL, referrer, and user agent in browsers
301
+
302
+ ## Privacy
303
+
304
+ The SDK collects minimal data by default and provides controls for GDPR compliance.
305
+
306
+ ### Data Collected
307
+
308
+ | Data | Default | Privacy Option |
309
+ |------|---------|----------------|
310
+ | Page URL | Collected | `collectUrl: false` |
311
+ | Referrer | Collected | `collectReferrer: false` |
312
+ | User Agent | Collected | `collectUserAgent: false` |
313
+ | Session ID | Generated | `collectSessionId: false` |
314
+ | IP Address | Stored server-side | `anonymizeIp: true` |
315
+
316
+ ### Privacy-First Configuration
317
+
318
+ For maximum privacy (e.g., before cookie consent):
319
+
320
+ ```typescript
321
+ BlipLogs.configure({
322
+ apiKey: 'your-api-key',
323
+ projectId: 'your-project-id',
324
+ privacy: {
325
+ anonymizeIp: true,
326
+ collectUrl: false,
327
+ collectReferrer: false,
328
+ collectUserAgent: false,
329
+ collectSessionId: false
330
+ }
331
+ });
332
+ ```
333
+
334
+ ### Automatic Protections
335
+
336
+ The SDK automatically redacts sensitive URL parameters:
337
+ - Auth tokens (`token`, `access_token`, `api_key`)
338
+ - OAuth params (`code`, `state`, `nonce`)
339
+ - PII (`email`, `phone`, `ssn`)
340
+ - Payment data (`credit_card`, `cvv`)
341
+
342
+ ### Your Responsibilities
343
+
344
+ 1. **Privacy policy** – Disclose BlipLogs in your privacy policy
345
+ 2. **Consent** – Obtain consent if required (cookie banner)
346
+ 3. **Data deletion** – Contact support for deletion requests
347
+
348
+ ## Links
349
+
350
+ - [Dashboard](https://bliplogs.co.uk) – Sign up and manage projects
351
+ - [Documentation](https://bliplogs.co.uk/docs) – Full docs
352
+ - [GitHub Issues](https://github.com/NoSweatWebsites/bliplogs-sdk/issues) – Bugs and feature requests
353
+
354
+ ## License
355
+
356
+ MIT
@@ -0,0 +1,185 @@
1
+ type BlipLevel = 'info' | 'warn' | 'error';
2
+ interface BlipMetadata {
3
+ [key: string]: unknown;
4
+ }
5
+ interface BlipContext {
6
+ projectId?: string;
7
+ url?: string;
8
+ referrer?: string;
9
+ userAgent?: string;
10
+ }
11
+ interface BlipPayload {
12
+ event: string;
13
+ level: BlipLevel;
14
+ metadata?: BlipMetadata;
15
+ context: BlipContext;
16
+ timestamp: string;
17
+ session_id?: string;
18
+ timestamp_ms?: number;
19
+ api_key?: string;
20
+ anonymize_ip?: boolean;
21
+ }
22
+ interface BlipLogsError {
23
+ type: 'network' | 'rate_limit' | 'auth' | 'validation' | 'unknown';
24
+ message: string;
25
+ statusCode?: number;
26
+ originalError?: Error;
27
+ }
28
+ /**
29
+ * Privacy configuration options for GDPR compliance
30
+ */
31
+ interface BlipPrivacyConfig {
32
+ /** Anonymize IP address on server (default: false) */
33
+ anonymizeIp?: boolean;
34
+ /** Collect page URL (default: true) */
35
+ collectUrl?: boolean;
36
+ /** Collect referrer URL (default: true) */
37
+ collectReferrer?: boolean;
38
+ /** Collect user agent string (default: true) */
39
+ collectUserAgent?: boolean;
40
+ /** Enable session tracking (default: true) */
41
+ collectSessionId?: boolean;
42
+ }
43
+ interface BlipLogsConfig {
44
+ apiKey: string;
45
+ projectId: string;
46
+ /** Enable debug mode to log errors to console (default: false) */
47
+ debug?: boolean;
48
+ /** Callback fired when an error occurs during event tracking */
49
+ onError?: (error: BlipLogsError) => void;
50
+ /** Privacy settings for GDPR compliance */
51
+ privacy?: BlipPrivacyConfig;
52
+ }
53
+ /**
54
+ * BlipLogs SDK - Zero-dependency event logging client
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * // Global configuration (recommended for Astro/React apps)
59
+ * BlipLogs.configure({ apiKey: 'your-api-key', projectId: 'your-project-id' });
60
+ * BlipLogs.track('button_clicked', { buttonId: 'signup' });
61
+ *
62
+ * // Or use instance-based API
63
+ * const blip = new BlipLogs({ apiKey: 'your-api-key', projectId: 'your-project-id' });
64
+ * blip.track('error_occurred', { message: 'Failed to load' }, 'error');
65
+ * ```
66
+ */
67
+ declare class BlipLogs {
68
+ private static globalInstance;
69
+ private static readonly API_ENDPOINT;
70
+ private apiKey;
71
+ private projectId;
72
+ private debug;
73
+ private onError?;
74
+ private privacy;
75
+ constructor(config: BlipLogsConfig);
76
+ /**
77
+ * Configure the global BlipLogs instance
78
+ * Call this once at the start of your application (e.g., in your Astro layout)
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * // In Astro layout or initialization script
83
+ * BlipLogs.configure({
84
+ * apiKey: import.meta.env.PUBLIC_BLIPLOGS_API_KEY,
85
+ * projectId: import.meta.env.PUBLIC_BLIPLOGS_PROJECT_ID
86
+ * });
87
+ * ```
88
+ */
89
+ static configure(config: BlipLogsConfig): void;
90
+ /**
91
+ * Get the global BlipLogs instance
92
+ * Throws an error if not configured
93
+ */
94
+ private static getInstance;
95
+ /**
96
+ * Track an event using the global instance
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * BlipLogs.track('button_clicked', { buttonId: 'signup' });
101
+ * ```
102
+ */
103
+ static track(event: string, metadata?: BlipMetadata, level?: BlipLevel): boolean;
104
+ /**
105
+ * Track an info-level event using the global instance
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * BlipLogs.info('page_viewed', { page: '/dashboard' });
110
+ * ```
111
+ */
112
+ static info(event: string, metadata?: BlipMetadata): boolean;
113
+ /**
114
+ * Track a warn-level event using the global instance
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * BlipLogs.warn('slow_request', { duration: 5000 });
119
+ * ```
120
+ */
121
+ static warn(event: string, metadata?: BlipMetadata): boolean;
122
+ /**
123
+ * Track an error-level event using the global instance
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * BlipLogs.error('api_error', { message: 'Failed to fetch' });
128
+ * ```
129
+ */
130
+ static error(event: string, metadata?: BlipMetadata): boolean;
131
+ /**
132
+ * Gets or creates a session ID from sessionStorage
133
+ * Sessions expire after 30 minutes of inactivity
134
+ */
135
+ private getSessionId;
136
+ /**
137
+ * Sensitive URL parameters that should be redacted
138
+ */
139
+ private static readonly SENSITIVE_PARAMS;
140
+ /**
141
+ * Sanitize a URL by removing sensitive query parameters
142
+ */
143
+ private sanitizeUrl;
144
+ /**
145
+ * Auto-captures browser context information with sensitive data sanitization
146
+ * Respects privacy configuration settings
147
+ */
148
+ private getContext;
149
+ /**
150
+ * Track an event with optional metadata and level
151
+ *
152
+ * @param event - The event name (e.g., 'signup_modal_opened')
153
+ * @param metadata - Optional custom data to attach to the event
154
+ * @param level - Event level: 'info' (default), 'warn', or 'error'
155
+ * @returns boolean - Whether the event was queued for delivery
156
+ */
157
+ track(event: string, metadata?: BlipMetadata, level?: BlipLevel): boolean;
158
+ /**
159
+ * Convenience method for info-level events
160
+ */
161
+ info(event: string, metadata?: BlipMetadata): boolean;
162
+ /**
163
+ * Convenience method for warn-level events
164
+ */
165
+ warn(event: string, metadata?: BlipMetadata): boolean;
166
+ /**
167
+ * Convenience method for error-level events
168
+ */
169
+ error(event: string, metadata?: BlipMetadata): boolean;
170
+ /**
171
+ * Sends the payload using sendBeacon for speed and reliability
172
+ * Falls back to fetch if sendBeacon is unavailable or blocked
173
+ */
174
+ private send;
175
+ /**
176
+ * Handle and report errors
177
+ */
178
+ private handleError;
179
+ /**
180
+ * Fallback method using fetch API
181
+ */
182
+ private sendWithFetch;
183
+ }
184
+
185
+ export { type BlipContext, type BlipLevel, BlipLogs, type BlipLogsConfig, type BlipLogsError, type BlipMetadata, type BlipPayload, type BlipPrivacyConfig, BlipLogs as default };