@borisch/snitch 1.0.2 → 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 CHANGED
@@ -8,11 +8,13 @@ Modular analytics tracking library. Compose your tracker from small, focused plu
8
8
  npm install @borisch/snitch
9
9
  ```
10
10
 
11
- ## Quick Start
11
+ ## Quick Start (Browser)
12
12
 
13
13
  ```ts
14
14
  import {
15
15
  snitch,
16
+ devicePlugin,
17
+ userPlugin,
16
18
  sessionPlugin,
17
19
  launchPlugin,
18
20
  scrollPlugin,
@@ -22,6 +24,8 @@ import {
22
24
  } from '@borisch/snitch'
23
25
 
24
26
  const captureEvent = snitch(
27
+ devicePlugin(),
28
+ userPlugin(),
25
29
  sessionPlugin(),
26
30
  launchPlugin(),
27
31
  scrollPlugin(),
@@ -34,6 +38,47 @@ const captureEvent = snitch(
34
38
  captureEvent('button_click', { buttonId: 'signup' })
35
39
  ```
36
40
 
41
+ ## Server-Side Usage
42
+
43
+ Many plugins use browser APIs (`window`, `document`, `localStorage`). Importing `@borisch/snitch` on the server will fail because some plugins reference `window` at the module level.
44
+
45
+ Use the server entry point instead:
46
+
47
+ ```ts
48
+ import {
49
+ snitch,
50
+ userPlugin,
51
+ devicePlugin,
52
+ screenPlugin,
53
+ debugLoggerPlugin,
54
+ s2sTransportPlugin,
55
+ } from '@borisch/snitch/server'
56
+ ```
57
+
58
+ The server entry point exports only the plugins and transports that work without browser APIs:
59
+
60
+ | Export | Description |
61
+ | -------------------- | ---------------------------------------------------------- |
62
+ | `snitch` | Core factory function |
63
+ | `userPlugin` | In-memory user ID tracking |
64
+ | `devicePlugin` | Device ID (falls back to random ID without `localStorage`) |
65
+ | `screenPlugin` | Screen tracking (pure state management) |
66
+ | `debugLoggerPlugin` | Console logger (silently disabled without `localStorage`) |
67
+ | `s2sTransportPlugin` | HTTP transport via `fetch()` (available in Node 18+) |
68
+
69
+ All types are also re-exported from `@borisch/snitch/server`.
70
+
71
+ **Example — server-side event tracking:**
72
+
73
+ ```ts
74
+ import { snitch, userPlugin, s2sTransportPlugin } from '@borisch/snitch/server'
75
+
76
+ const track = snitch(userPlugin(), s2sTransportPlugin({ hostname: 'analytics.example.com' })) as any
77
+
78
+ // One-shot event with a specific user ID
79
+ track.withUserId(req.userId, 'checkout_completed', { orderId: '12345' })
80
+ ```
81
+
37
82
  The `snitch()` function accepts any number of plugins and returns a `captureEvent` function. Plugins can:
38
83
 
39
84
  - **Provide event parameters** — automatically attached to every event
@@ -206,6 +251,97 @@ Attaches to every event:
206
251
 
207
252
  ---
208
253
 
254
+ ### `devicePlugin()`
255
+
256
+ Generates a persistent device (browser) identifier stored in `localStorage` under the key `snitch:did`. The ID is created once and reused forever across all sessions — it survives page reloads, tab closes, and new sessions. It only resets if the user clears their browser storage.
257
+
258
+ If `localStorage` is unavailable, a new ID is generated per `snitch()` call (in-memory only).
259
+
260
+ Attaches to every event:
261
+ | Param | Description |
262
+ |-------|-------------|
263
+ | `did` | Persistent device ID |
264
+
265
+ ---
266
+
267
+ ### `userPlugin(userId?)`
268
+
269
+ Tracks the current user. Exposes `.setUserId(id)` and `.clearUserId()` methods on the `captureEvent` function via mixins. The user ID is stored in-memory only — no `localStorage`, no emitted events. This makes it safe to use in both browser and server-side environments.
270
+
271
+ When no user ID is set, `uid` is omitted from events entirely.
272
+
273
+ If the user ID is known at initialization time, it can be passed directly:
274
+
275
+ ```ts
276
+ const captureEvent = snitch(
277
+ userPlugin('user-123'),
278
+ // ...
279
+ ) as any
280
+ ```
281
+
282
+ Otherwise, set it later:
283
+
284
+ ```ts
285
+ captureEvent.setUserId('user-123')
286
+ ```
287
+
288
+ **Methods (mixins):**
289
+ | Method | Description |
290
+ |--------|-------------|
291
+ | `setUserId(id: string)` | Set the user ID. All subsequent events will include `uid`. |
292
+ | `clearUserId()` | Clear the user ID. `uid` is no longer attached to events. |
293
+ | `withUserId(id: string, eventName: string, eventPayload?)` | Temporarily set the user ID, send a single event, then restore the previous user ID. Designed for server-side use where a single snitch instance handles multiple users. |
294
+
295
+ Attaches to every event (while user ID is set):
296
+ | Param | Description |
297
+ |-------|-------------|
298
+ | `uid` | Current user ID |
299
+
300
+ **Usage:**
301
+
302
+ ```ts
303
+ const captureEvent = snitch(
304
+ devicePlugin(),
305
+ userPlugin(),
306
+ sessionPlugin(),
307
+ beaconTransportPlugin({ hostname: '...' }),
308
+ ) as any
309
+
310
+ // User logs in
311
+ captureEvent.setUserId('user-123')
312
+
313
+ captureEvent('add_to_cart', { productId: 'abc' })
314
+ // => { event: 'add_to_cart', productId: 'abc', uid: 'user-123', did: '...', sid: '...' }
315
+
316
+ // User logs out
317
+ captureEvent.clearUserId()
318
+ // uid is no longer attached to events
319
+
320
+ // Server-side (s2s-transport) — pass uid at init, no localStorage needed
321
+ const track = snitch(
322
+ userPlugin(req.userId),
323
+ s2sTransportPlugin({ hostname: 'analytics.example.com' }),
324
+ )
325
+ track('subscriptionRenewalPaymentFailed')
326
+ // => { event: 'subscriptionRenewalPaymentFailed', uid: 'user-123' }
327
+ ```
328
+
329
+ **Server-side with `.withUserId()`:**
330
+
331
+ When a single snitch instance handles requests from multiple users (e.g., in an Express handler), use `.withUserId()` to atomically send an event with a specific user ID without affecting other requests. The captureEvent pipeline is synchronous, so the temporary uid swap is safe — no interleaving is possible.
332
+
333
+ ```ts
334
+ const track = snitch(userPlugin(), s2sTransportPlugin({ hostname: 'analytics.example.com' })) as any
335
+
336
+ app.post('/api/checkout', (req, res) => {
337
+ // Sends this one event with uid='user-42', then restores previous state
338
+ track.withUserId(req.userId, 'checkout_completed', { orderId: req.body.orderId })
339
+ res.json({ ok: true })
340
+ })
341
+ ```
342
+
343
+ ---
344
+
209
345
  ### `debugLoggerPlugin()`
210
346
 
211
347
  Development helper. Logs every event to the browser console with timestamps and time deltas between events. When the event has a non-empty payload, it is also rendered via `console.table()`.
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ export { default as webVitalsPlugin } from './packages/snitch-plugin-web-vitals/
13
13
  export { default as flagPlugin } from './packages/snitch-plugin-flag/index';
14
14
  export { default as debugLoggerPlugin } from './packages/snitch-plugin-debug-logger/index';
15
15
  export { default as useragentPlugin } from './packages/snitch-plugin-useragent/index';
16
+ export { default as devicePlugin } from './packages/snitch-plugin-device/index';
17
+ export { default as userPlugin } from './packages/snitch-plugin-user/index';
16
18
  export { default as beaconTransportPlugin } from './packages/snitch-plugin-beacon-transport/index';
17
19
  export { default as s2sTransportPlugin } from './packages/snitch-plugin-s2s-transport/index';
18
20
  export { default as topmailruTransportPlugin } from './packages/snitch-plugin-topmailru-transport/index';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.vkmaLaunchPlugin = exports.vkBridgeTransportPlugin = exports.topmailruTransportPlugin = exports.s2sTransportPlugin = exports.beaconTransportPlugin = exports.useragentPlugin = exports.debugLoggerPlugin = exports.flagPlugin = exports.webVitalsPlugin = exports.exceptionsPlugin = exports.screenPlugin = exports.engagementPlugin = exports.launchPlugin = exports.sessionPlugin = exports.locationPlugin = exports.scrollPlugin = exports.default = exports.snitch = void 0;
6
+ exports.vkmaLaunchPlugin = exports.vkBridgeTransportPlugin = exports.topmailruTransportPlugin = exports.s2sTransportPlugin = exports.beaconTransportPlugin = exports.userPlugin = exports.devicePlugin = exports.useragentPlugin = exports.debugLoggerPlugin = exports.flagPlugin = exports.webVitalsPlugin = exports.exceptionsPlugin = exports.screenPlugin = exports.engagementPlugin = exports.launchPlugin = exports.sessionPlugin = exports.locationPlugin = exports.scrollPlugin = exports.default = exports.snitch = void 0;
7
7
  // Core
8
8
  var index_1 = require("./packages/snitch/index");
9
9
  Object.defineProperty(exports, "snitch", { enumerable: true, get: function () { return __importDefault(index_1).default; } });
@@ -32,16 +32,20 @@ var index_12 = require("./packages/snitch-plugin-debug-logger/index");
32
32
  Object.defineProperty(exports, "debugLoggerPlugin", { enumerable: true, get: function () { return __importDefault(index_12).default; } });
33
33
  var index_13 = require("./packages/snitch-plugin-useragent/index");
34
34
  Object.defineProperty(exports, "useragentPlugin", { enumerable: true, get: function () { return __importDefault(index_13).default; } });
35
+ var index_14 = require("./packages/snitch-plugin-device/index");
36
+ Object.defineProperty(exports, "devicePlugin", { enumerable: true, get: function () { return __importDefault(index_14).default; } });
37
+ var index_15 = require("./packages/snitch-plugin-user/index");
38
+ Object.defineProperty(exports, "userPlugin", { enumerable: true, get: function () { return __importDefault(index_15).default; } });
35
39
  // Transports
36
- var index_14 = require("./packages/snitch-plugin-beacon-transport/index");
37
- Object.defineProperty(exports, "beaconTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_14).default; } });
38
- var index_15 = require("./packages/snitch-plugin-s2s-transport/index");
39
- Object.defineProperty(exports, "s2sTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_15).default; } });
40
- var index_16 = require("./packages/snitch-plugin-topmailru-transport/index");
41
- Object.defineProperty(exports, "topmailruTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_16).default; } });
42
- var index_17 = require("./packages/snitch-plugin-vkbridge-transport/index");
43
- Object.defineProperty(exports, "vkBridgeTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_17).default; } });
40
+ var index_16 = require("./packages/snitch-plugin-beacon-transport/index");
41
+ Object.defineProperty(exports, "beaconTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_16).default; } });
42
+ var index_17 = require("./packages/snitch-plugin-s2s-transport/index");
43
+ Object.defineProperty(exports, "s2sTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_17).default; } });
44
+ var index_18 = require("./packages/snitch-plugin-topmailru-transport/index");
45
+ Object.defineProperty(exports, "topmailruTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_18).default; } });
46
+ var index_19 = require("./packages/snitch-plugin-vkbridge-transport/index");
47
+ Object.defineProperty(exports, "vkBridgeTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_19).default; } });
44
48
  // Platform-specific
45
- var index_18 = require("./packages/snitch-plugin-vkma-launch/index");
46
- Object.defineProperty(exports, "vkmaLaunchPlugin", { enumerable: true, get: function () { return __importDefault(index_18).default; } });
49
+ var index_20 = require("./packages/snitch-plugin-vkma-launch/index");
50
+ Object.defineProperty(exports, "vkmaLaunchPlugin", { enumerable: true, get: function () { return __importDefault(index_20).default; } });
47
51
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO;AACP,iDAA2D;AAAlD,gHAAA,OAAO,OAAU;AAC1B,iDAAiD;AAAxC,iHAAA,OAAO,OAAA;AAmBhB,UAAU;AACV,+DAA+E;AAAtE,sHAAA,OAAO,OAAgB;AAChC,iEAAmF;AAA1E,wHAAA,OAAO,OAAkB;AAClC,gEAAiF;AAAxE,uHAAA,OAAO,OAAiB;AACjC,+DAA+E;AAAtE,sHAAA,OAAO,OAAgB;AAChC,mEAAuF;AAA9E,0HAAA,OAAO,OAAoB;AACpC,gEAAgF;AAAvE,sHAAA,OAAO,OAAgB;AAChC,mEAAuF;AAA9E,0HAAA,OAAO,OAAoB;AACpC,oEAAsF;AAA7E,0HAAA,OAAO,OAAmB;AACnC,8DAA2E;AAAlE,qHAAA,OAAO,OAAc;AAC9B,sEAA0F;AAAjF,4HAAA,OAAO,OAAqB;AACrC,mEAAqF;AAA5E,0HAAA,OAAO,OAAmB;AAEnC,aAAa;AACb,0EAAkG;AAAzF,gIAAA,OAAO,OAAyB;AACzC,uEAA4F;AAAnF,6HAAA,OAAO,OAAsB;AACtC,6EAAwG;AAA/F,mIAAA,OAAO,OAA4B;AAC5C,4EAAsG;AAA7F,kIAAA,OAAO,OAA2B;AAE3C,oBAAoB;AACpB,qEAAwF;AAA/E,2HAAA,OAAO,OAAoB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO;AACP,iDAA2D;AAAlD,gHAAA,OAAO,OAAU;AAC1B,iDAAiD;AAAxC,iHAAA,OAAO,OAAA;AAmBhB,UAAU;AACV,+DAA+E;AAAtE,sHAAA,OAAO,OAAgB;AAChC,iEAAmF;AAA1E,wHAAA,OAAO,OAAkB;AAClC,gEAAiF;AAAxE,uHAAA,OAAO,OAAiB;AACjC,+DAA+E;AAAtE,sHAAA,OAAO,OAAgB;AAChC,mEAAuF;AAA9E,0HAAA,OAAO,OAAoB;AACpC,gEAAgF;AAAvE,sHAAA,OAAO,OAAgB;AAChC,mEAAuF;AAA9E,0HAAA,OAAO,OAAoB;AACpC,oEAAsF;AAA7E,0HAAA,OAAO,OAAmB;AACnC,8DAA2E;AAAlE,qHAAA,OAAO,OAAc;AAC9B,sEAA0F;AAAjF,4HAAA,OAAO,OAAqB;AACrC,mEAAqF;AAA5E,0HAAA,OAAO,OAAmB;AACnC,gEAA+E;AAAtE,uHAAA,OAAO,OAAgB;AAChC,8DAA2E;AAAlE,qHAAA,OAAO,OAAc;AAE9B,aAAa;AACb,0EAAkG;AAAzF,gIAAA,OAAO,OAAyB;AACzC,uEAA4F;AAAnF,6HAAA,OAAO,OAAsB;AACtC,6EAAwG;AAA/F,mIAAA,OAAO,OAA4B;AAC5C,4EAAsG;AAA7F,kIAAA,OAAO,OAA2B;AAE3C,oBAAoB;AACpB,qEAAwF;AAA/E,2HAAA,OAAO,OAAoB"}
@@ -1,2 +1,2 @@
1
1
  import { BeforeCaptureEventHandler, InitializationHandler } from '../common/plugin-interfaces';
2
- export default function engagementPlugin(): InitializationHandler & BeforeCaptureEventHandler;
2
+ export default function debugLoggerPlugin(): InitializationHandler & BeforeCaptureEventHandler;
@@ -1,9 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = engagementPlugin;
4
- function engagementPlugin() {
3
+ exports.default = debugLoggerPlugin;
4
+ const STORAGE_KEY = 'snitch:debug';
5
+ function debugLoggerPlugin() {
6
+ let enabled = false;
7
+ try {
8
+ enabled = localStorage.getItem(STORAGE_KEY) === 'true';
9
+ }
10
+ catch (_a) { }
5
11
  let lastLogTS = null;
6
12
  function logLine(message) {
13
+ if (!enabled)
14
+ return;
7
15
  const now = new Date();
8
16
  console.log(`%c[${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}]${lastLogTS ? ` (+${Math.floor((now.getTime() - lastLogTS) / 1e3)}s)` : ''} %cSnitch: %c${message}`, 'color: gray', 'color: black', 'font-weight: bold');
9
17
  lastLogTS = now.getTime();
@@ -14,9 +22,9 @@ function engagementPlugin() {
14
22
  },
15
23
  beforeCaptureEvent(eventName, eventPayload) {
16
24
  logLine(`captured event '${eventName}'`);
17
- if (eventPayload && Object.keys(eventPayload).length !== 0)
25
+ if (enabled && eventPayload && Object.keys(eventPayload).length !== 0)
18
26
  console.table(eventPayload);
19
- }
27
+ },
20
28
  };
21
29
  }
22
30
  //# sourceMappingURL=debug-logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug-logger.js","sourceRoot":"","sources":["../../../packages/snitch-plugin-debug-logger/debug-logger.ts"],"names":[],"mappings":";;AAEA,mCAwBC;AAxBD,SAAwB,gBAAgB;IACtC,IAAI,SAAS,GAAkB,IAAI,CAAA;IACnC,SAAS,OAAO,CAAC,OAAe;QAC9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;QACtB,OAAO,CAAC,GAAG,CACT,MAAM,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,IAC1D,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,GAAI,SAAoB,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EACpF,gBAAgB,OAAO,EAAE,EACzB,aAAa,EACb,cAAc,EACd,mBAAmB,CACpB,CAAA;QACD,SAAS,GAAG,GAAG,CAAC,OAAO,EAAE,CAAA;IAC3B,CAAC;IACD,OAAO;QACL,MAAM;YACJ,OAAO,CAAC,yBAAyB,CAAC,CAAA;QACpC,CAAC;QAED,kBAAkB,CAAC,SAAiB,EAAE,YAAiC;YACrE,OAAO,CAAC,mBAAmB,SAAS,GAAG,CAAC,CAAA;YACxC,IAAI,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QACzF,CAAC;KACF,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"debug-logger.js","sourceRoot":"","sources":["../../../packages/snitch-plugin-debug-logger/debug-logger.ts"],"names":[],"mappings":";;AAKA,oCA+BC;AAjCD,MAAM,WAAW,GAAG,cAAc,CAAA;AAElC,SAAwB,iBAAiB;IACvC,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,MAAM,CAAA;IACxD,CAAC;IAAC,WAAM,CAAC,CAAA,CAAC;IAEV,IAAI,SAAS,GAAkB,IAAI,CAAA;IACnC,SAAS,OAAO,CAAC,OAAe;QAC9B,IAAI,CAAC,OAAO;YAAE,OAAM;QACpB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;QACtB,OAAO,CAAC,GAAG,CACT,MAAM,GAAG,CAAC,QAAQ,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,IAC1D,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,GAAI,SAAoB,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EACpF,gBAAgB,OAAO,EAAE,EACzB,aAAa,EACb,cAAc,EACd,mBAAmB,CACpB,CAAA;QACD,SAAS,GAAG,GAAG,CAAC,OAAO,EAAE,CAAA;IAC3B,CAAC;IACD,OAAO;QACL,MAAM;YACJ,OAAO,CAAC,yBAAyB,CAAC,CAAA;QACpC,CAAC;QAED,kBAAkB,CAAC,SAAiB,EAAE,YAAiC;YACrE,OAAO,CAAC,mBAAmB,SAAS,GAAG,CAAC,CAAA;YACxC,IAAI,OAAO,IAAI,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC;gBACnE,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAC/B,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { EventPayloadParamsProvider } from '../common/plugin-interfaces';
2
+ export default function devicePlugin(): EventPayloadParamsProvider;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = devicePlugin;
7
+ const create_unique_id_1 = __importDefault(require("../common/create-unique-id"));
8
+ const STORAGE_KEY = 'snitch:did';
9
+ function devicePlugin() {
10
+ let deviceId;
11
+ try {
12
+ const stored = localStorage.getItem(STORAGE_KEY);
13
+ if (stored) {
14
+ deviceId = stored;
15
+ }
16
+ else {
17
+ deviceId = (0, create_unique_id_1.default)();
18
+ localStorage.setItem(STORAGE_KEY, deviceId);
19
+ }
20
+ }
21
+ catch (_a) {
22
+ deviceId = (0, create_unique_id_1.default)();
23
+ }
24
+ return {
25
+ getEventPayloadParams() {
26
+ return { did: deviceId };
27
+ },
28
+ };
29
+ }
30
+ //# sourceMappingURL=device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../../../packages/snitch-plugin-device/device.ts"],"names":[],"mappings":";;;;;AAKA,+BAoBC;AAzBD,kFAAuD;AAGvD,MAAM,WAAW,GAAG,YAAY,CAAA;AAEhC,SAAwB,YAAY;IAClC,IAAI,QAAgB,CAAA;IAEpB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAChD,IAAI,MAAM,EAAE,CAAC;YACX,QAAQ,GAAG,MAAM,CAAA;QACnB,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,IAAA,0BAAc,GAAE,CAAA;YAC3B,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;IAAC,WAAM,CAAC;QACP,QAAQ,GAAG,IAAA,0BAAc,GAAE,CAAA;IAC7B,CAAC;IAED,OAAO;QACL,qBAAqB;YACnB,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAA;QAC1B,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ import devicePlugin from './device';
2
+ export default devicePlugin;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const device_1 = __importDefault(require("./device"));
7
+ exports.default = device_1.default;
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages/snitch-plugin-device/index.ts"],"names":[],"mappings":";;;;;AAAA,sDAAmC;AACnC,kBAAe,gBAAY,CAAA"}
@@ -0,0 +1,2 @@
1
+ import userPlugin from './user';
2
+ export default userPlugin;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const user_1 = __importDefault(require("./user"));
7
+ exports.default = user_1.default;
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../packages/snitch-plugin-user/index.ts"],"names":[],"mappings":";;;;;AAAA,kDAA+B;AAC/B,kBAAe,cAAU,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { EventPayloadParamsProvider, EventSource, MixinProvider } from '../common/plugin-interfaces';
2
+ export default function userPlugin(userId?: string): EventPayloadParamsProvider & MixinProvider & EventSource;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = userPlugin;
4
+ function userPlugin(userId) {
5
+ let uid = userId !== null && userId !== void 0 ? userId : null;
6
+ let captureEvent;
7
+ return {
8
+ setEventHandler(eventHandler) {
9
+ captureEvent = eventHandler;
10
+ },
11
+ getEventPayloadParams() {
12
+ if (uid) {
13
+ return { uid };
14
+ }
15
+ return {};
16
+ },
17
+ getMixins() {
18
+ return {
19
+ setUserId(id) {
20
+ uid = id;
21
+ },
22
+ clearUserId() {
23
+ uid = null;
24
+ },
25
+ withUserId(id, eventName, eventPayload) {
26
+ const prevUid = uid;
27
+ uid = id;
28
+ captureEvent(eventName, eventPayload);
29
+ uid = prevUid;
30
+ },
31
+ };
32
+ },
33
+ };
34
+ }
35
+ //# sourceMappingURL=user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../../packages/snitch-plugin-user/user.ts"],"names":[],"mappings":";;AAGA,6BAmCC;AAnCD,SAAwB,UAAU,CAChC,MAAe;IAEf,IAAI,GAAG,GAAkB,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,IAAI,CAAA;IACvC,IAAI,YAA0B,CAAA;IAE9B,OAAO;QACL,eAAe,CAAC,YAA0B;YACxC,YAAY,GAAG,YAAY,CAAA;QAC7B,CAAC;QAED,qBAAqB;YACnB,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,EAAE,GAAG,EAAE,CAAA;YAChB,CAAC;YACD,OAAO,EAAE,CAAA;QACX,CAAC;QAED,SAAS;YACP,OAAO;gBACL,SAAS,CAAC,EAAU;oBAClB,GAAG,GAAG,EAAE,CAAA;gBACV,CAAC;gBACD,WAAW;oBACT,GAAG,GAAG,IAAI,CAAA;gBACZ,CAAC;gBACD,UAAU,CAAC,EAAU,EAAE,SAAiB,EAAE,YAAkC;oBAC1E,MAAM,OAAO,GAAG,GAAG,CAAA;oBACnB,GAAG,GAAG,EAAE,CAAA;oBACR,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;oBACrC,GAAG,GAAG,OAAO,CAAA;gBACf,CAAC;aACF,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ export { default as snitch } from './packages/snitch/index';
2
+ export { default } from './packages/snitch/index';
3
+ export type { Plugin, EventPayloadParamsProvider, InitializationHandler, EventSource, BeforeCaptureEventHandler, EventTransport, MixinProvider, } from './packages/common/plugin-interfaces';
4
+ export type { TrackerEventPayload, EventHandler, TrackerInitializationOptions, } from './packages/common/tracker-interfaces';
5
+ export { default as screenPlugin } from './packages/snitch-plugin-screens/index';
6
+ export { default as debugLoggerPlugin } from './packages/snitch-plugin-debug-logger/index';
7
+ export { default as devicePlugin } from './packages/snitch-plugin-device/index';
8
+ export { default as userPlugin } from './packages/snitch-plugin-user/index';
9
+ export { default as s2sTransportPlugin } from './packages/snitch-plugin-s2s-transport/index';
package/dist/server.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ // Server-safe entry point — no browser APIs required.
3
+ // Usage: import { snitch, userPlugin, ... } from '@borisch/snitch/server'
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.s2sTransportPlugin = exports.userPlugin = exports.devicePlugin = exports.debugLoggerPlugin = exports.screenPlugin = exports.default = exports.snitch = void 0;
9
+ // Core
10
+ var index_1 = require("./packages/snitch/index");
11
+ Object.defineProperty(exports, "snitch", { enumerable: true, get: function () { return __importDefault(index_1).default; } });
12
+ var index_2 = require("./packages/snitch/index");
13
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(index_2).default; } });
14
+ // Server-safe plugins
15
+ var index_3 = require("./packages/snitch-plugin-screens/index");
16
+ Object.defineProperty(exports, "screenPlugin", { enumerable: true, get: function () { return __importDefault(index_3).default; } });
17
+ var index_4 = require("./packages/snitch-plugin-debug-logger/index");
18
+ Object.defineProperty(exports, "debugLoggerPlugin", { enumerable: true, get: function () { return __importDefault(index_4).default; } });
19
+ var index_5 = require("./packages/snitch-plugin-device/index");
20
+ Object.defineProperty(exports, "devicePlugin", { enumerable: true, get: function () { return __importDefault(index_5).default; } });
21
+ var index_6 = require("./packages/snitch-plugin-user/index");
22
+ Object.defineProperty(exports, "userPlugin", { enumerable: true, get: function () { return __importDefault(index_6).default; } });
23
+ // Server-safe transports
24
+ var index_7 = require("./packages/snitch-plugin-s2s-transport/index");
25
+ Object.defineProperty(exports, "s2sTransportPlugin", { enumerable: true, get: function () { return __importDefault(index_7).default; } });
26
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,0EAA0E;;;;;;AAE1E,OAAO;AACP,iDAA2D;AAAlD,gHAAA,OAAO,OAAU;AAC1B,iDAAiD;AAAxC,iHAAA,OAAO,OAAA;AAmBhB,sBAAsB;AACtB,gEAAgF;AAAvE,sHAAA,OAAO,OAAgB;AAChC,qEAA0F;AAAjF,2HAAA,OAAO,OAAqB;AACrC,+DAA+E;AAAtE,sHAAA,OAAO,OAAgB;AAChC,6DAA2E;AAAlE,oHAAA,OAAO,OAAc;AAE9B,yBAAyB;AACzB,sEAA4F;AAAnF,4HAAA,OAAO,OAAsB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@borisch/snitch",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "description": "Modular analytics tracking library with pluggable transports",
5
5
  "keywords": [
6
6
  "analytics",
@@ -11,6 +11,16 @@
11
11
  ],
12
12
  "main": "dist/index.js",
13
13
  "typings": "dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./server": {
20
+ "types": "./dist/server.d.ts",
21
+ "default": "./dist/server.js"
22
+ }
23
+ },
14
24
  "files": [
15
25
  "dist"
16
26
  ],