trodo-node 1.0.0 → 1.0.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.
Files changed (2) hide show
  1. package/README.md +192 -192
  2. package/package.json +71 -71
package/README.md CHANGED
@@ -1,192 +1,192 @@
1
- # trodo-node
2
-
3
- Server-side Node.js SDK for [Trodo Analytics](https://trodo.ai). Track backend events, identify users, and manage people/groups — all merging seamlessly with your frontend Trodo data under the same `siteId`.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install trodo-node
9
- ```
10
-
11
- Node 18+ uses native `fetch`. For Node 16/17, install the optional peer dependency:
12
-
13
- ```bash
14
- npm install trodo-node node-fetch
15
- ```
16
-
17
- ## Quick Start
18
-
19
- ```javascript
20
- const trodo = require('trodo-node');
21
-
22
- // Initialize once at app startup
23
- trodo.init({
24
- siteId: 'your-site-id',
25
- debug: false, // optional: log API calls
26
- autoEvents: true, // optional: capture uncaughtException / unhandledRejection
27
- });
28
-
29
- // Get a user context
30
- const user = trodo.forUser('user-123');
31
-
32
- // Track a custom event
33
- await user.track('purchase_completed', { amount: 99.99, plan: 'pro' });
34
-
35
- // Identify the user (merges with frontend events under the same identity)
36
- await user.identify('user@example.com'); // distinctId becomes id_user@example.com
37
-
38
- // Update people profile
39
- await user.people.set({ plan: 'pro', company: 'Acme' });
40
-
41
- // Track a server-side error
42
- await user.captureError(new Error('payment failed'));
43
-
44
- // Flush queued events before process exit
45
- await trodo.shutdown();
46
- ```
47
-
48
- ## ESM
49
-
50
- ```javascript
51
- import trodo from 'trodo-node';
52
- trodo.init({ siteId: 'your-site-id' });
53
- ```
54
-
55
- ## Cross-SDK Identity Merging
56
-
57
- Frontend and backend events merge when both sides call `identify()` with the same value:
58
-
59
- ```javascript
60
- // Browser SDK
61
- Trodo.identify('user@example.com'); // → id_user@example.com
62
-
63
- // Node.js SDK (same value)
64
- await user.identify('user@example.com'); // → id_user@example.com
65
-
66
- // Both event streams now appear together in the Trodo dashboard
67
- ```
68
-
69
- ## API Reference
70
-
71
- ### `trodo.init(config)`
72
-
73
- | Option | Type | Default | Description |
74
- |--------|------|---------|-------------|
75
- | `siteId` | `string` | required | Your Trodo site ID |
76
- | `apiBase` | `string` | `https://sdkapi.trodo.ai` | API base URL |
77
- | `debug` | `boolean` | `false` | Log API requests/responses |
78
- | `autoEvents` | `boolean` | `false` | Hook `uncaughtException` + `unhandledRejection` |
79
- | `retries` | `number` | `3` | HTTP retry attempts on 5xx errors |
80
- | `timeout` | `number` | `10000` | HTTP timeout in milliseconds |
81
- | `batchEnabled` | `boolean` | `false` | Queue events and flush in bulk |
82
- | `batchSize` | `number` | `50` | Max events per batch flush |
83
- | `batchFlushIntervalMs` | `number` | `5000` | Flush interval in milliseconds |
84
- | `onError` | `function` | `undefined` | Callback for SDK errors |
85
-
86
- ### `trodo.forUser(distinctId, options?)`
87
-
88
- Returns a user-bound context. All subsequent calls use this user's session.
89
-
90
- ```javascript
91
- const user = trodo.forUser('user-123', {
92
- sessionId: req.cookies.trodo_session, // optional: correlate with browser session
93
- });
94
- ```
95
-
96
- ### User Context Methods
97
-
98
- ```javascript
99
- await user.track(eventName, properties?) // Track custom event
100
- await user.trackEvent(eventName, properties?) // Alias for track()
101
- await user.identify(identifyId) // Merge identity
102
- await user.walletAddress(address) // Set crypto wallet address
103
- await user.reset() // Clear session context
104
- await user.captureError(error) // Track server_error event
105
-
106
- // People profile
107
- await user.people.set(properties)
108
- await user.people.setOnce(properties)
109
- await user.people.unset(keys)
110
- await user.people.increment(properties)
111
- await user.people.append(properties)
112
- await user.people.union(properties)
113
- await user.people.remove(properties)
114
- await user.people.trackCharge(amount, properties?)
115
- await user.people.clearCharges()
116
- await user.people.deleteUser()
117
-
118
- // Groups
119
- await user.set_group(groupKey, groupId)
120
- await user.add_group(groupKey, groupId)
121
- await user.remove_group(groupKey, groupId)
122
- const group = user.get_group(groupKey, groupId)
123
- await group.set(properties)
124
- await group.set_once(properties)
125
- await group.union(properties)
126
- await group.remove(properties)
127
- await group.unset(keys)
128
- await group.increment(properties)
129
- await group.append(properties)
130
- await group.delete()
131
- ```
132
-
133
- ### Direct Call Pattern (for pipelines)
134
-
135
- ```javascript
136
- await trodo.track('user-123', 'event_name', { key: 'value' })
137
- await trodo.identify('user-123', 'identifyId')
138
- await trodo.people.set('user-123', { plan: 'pro' })
139
- await trodo.set_group('user-123', 'company', 'acme')
140
- ```
141
-
142
- ### Global Methods
143
-
144
- ```javascript
145
- trodo.enableAutoEvents() // Enable uncaughtException hooks
146
- trodo.disableAutoEvents() // Disable hooks
147
- await trodo.flush() // Flush pending batch queue
148
- await trodo.shutdown() // Flush + stop background timers
149
- ```
150
-
151
- ## Auto Events
152
-
153
- When `autoEvents: true`, the SDK hooks Node.js process error events and sends `server_error` events to Trodo:
154
-
155
- - `process.on('uncaughtException')`
156
- - `process.on('unhandledRejection')`
157
-
158
- These events use `distinct_id: 'server_global'` in the dashboard.
159
-
160
- Per-user error capture: `user.captureError(error)` uses the user's own `distinctId`.
161
-
162
- ## Batching
163
-
164
- ```javascript
165
- trodo.init({
166
- siteId: 'your-site-id',
167
- batchEnabled: true,
168
- batchSize: 100,
169
- batchFlushIntervalMs: 3000,
170
- });
171
-
172
- // Events are queued and flushed every 3s or when 100 events accumulate
173
- await user.track('page_view');
174
-
175
- // Always flush before process exit
176
- process.on('SIGTERM', () => trodo.shutdown());
177
- ```
178
-
179
- ## TypeScript
180
-
181
- Full TypeScript support with bundled type declarations:
182
-
183
- ```typescript
184
- import trodo, { TrodoConfig, ForUserOptions } from 'trodo-node';
185
-
186
- const config: TrodoConfig = { siteId: 'your-site-id' };
187
- trodo.init(config);
188
- ```
189
-
190
- ## License
191
-
192
- ISC
1
+ # trodo-node
2
+
3
+ Server-side Node.js SDK for [Trodo Analytics](https://trodo.ai). Track backend events, identify users, and manage people/groups — all merging seamlessly with your frontend Trodo data under the same `siteId`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install trodo-node
9
+ ```
10
+
11
+ Node 18+ uses native `fetch`. For Node 16/17, install the optional peer dependency:
12
+
13
+ ```bash
14
+ npm install trodo-node node-fetch
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```javascript
20
+ const trodo = require('trodo-node');
21
+
22
+ // Initialize once at app startup
23
+ trodo.init({
24
+ siteId: 'your-site-id',
25
+ debug: false, // optional: log API calls
26
+ autoEvents: true, // optional: capture uncaughtException / unhandledRejection
27
+ });
28
+
29
+ // Get a user context
30
+ const user = trodo.forUser('user-123');
31
+
32
+ // Track a custom event
33
+ await user.track('purchase_completed', { amount: 99.99, plan: 'pro' });
34
+
35
+ // Identify the user (merges with frontend events under the same identity)
36
+ await user.identify('user@example.com'); // distinctId becomes id_user@example.com
37
+
38
+ // Update people profile
39
+ await user.people.set({ plan: 'pro', company: 'Acme' });
40
+
41
+ // Track a server-side error
42
+ await user.captureError(new Error('payment failed'));
43
+
44
+ // Flush queued events before process exit
45
+ await trodo.shutdown();
46
+ ```
47
+
48
+ ## ESM
49
+
50
+ ```javascript
51
+ import trodo from 'trodo-node';
52
+ trodo.init({ siteId: 'your-site-id' });
53
+ ```
54
+
55
+ ## Cross-SDK Identity Merging
56
+
57
+ Frontend and backend events merge when both sides call `identify()` with the same value:
58
+
59
+ ```javascript
60
+ // Browser SDK
61
+ Trodo.identify('user@example.com'); // → id_user@example.com
62
+
63
+ // Node.js SDK (same value)
64
+ await user.identify('user@example.com'); // → id_user@example.com
65
+
66
+ // Both event streams now appear together in the Trodo dashboard
67
+ ```
68
+
69
+ ## API Reference
70
+
71
+ ### `trodo.init(config)`
72
+
73
+ | Option | Type | Default | Description |
74
+ |--------|------|---------|-------------|
75
+ | `siteId` | `string` | required | Your Trodo site ID |
76
+ | `apiBase` | `string` | `https://sdkapi.trodo.ai` | API base URL |
77
+ | `debug` | `boolean` | `false` | Log API requests/responses |
78
+ | `autoEvents` | `boolean` | `false` | Hook `uncaughtException` + `unhandledRejection` |
79
+ | `retries` | `number` | `3` | HTTP retry attempts on 5xx errors |
80
+ | `timeout` | `number` | `10000` | HTTP timeout in milliseconds |
81
+ | `batchEnabled` | `boolean` | `false` | Queue events and flush in bulk |
82
+ | `batchSize` | `number` | `50` | Max events per batch flush |
83
+ | `batchFlushIntervalMs` | `number` | `5000` | Flush interval in milliseconds |
84
+ | `onError` | `function` | `undefined` | Callback for SDK errors |
85
+
86
+ ### `trodo.forUser(distinctId, options?)`
87
+
88
+ Returns a user-bound context. All subsequent calls use this user's session.
89
+
90
+ ```javascript
91
+ const user = trodo.forUser('user-123', {
92
+ sessionId: req.cookies.trodo_session, // optional: correlate with browser session
93
+ });
94
+ ```
95
+
96
+ ### User Context Methods
97
+
98
+ ```javascript
99
+ await user.track(eventName, properties?) // Track custom event
100
+ await user.trackEvent(eventName, properties?) // Alias for track()
101
+ await user.identify(identifyId) // Merge identity
102
+ await user.walletAddress(address) // Set crypto wallet address
103
+ await user.reset() // Clear session context
104
+ await user.captureError(error) // Track server_error event
105
+
106
+ // People profile
107
+ await user.people.set(properties)
108
+ await user.people.setOnce(properties)
109
+ await user.people.unset(keys)
110
+ await user.people.increment(properties)
111
+ await user.people.append(properties)
112
+ await user.people.union(properties)
113
+ await user.people.remove(properties)
114
+ await user.people.trackCharge(amount, properties?)
115
+ await user.people.clearCharges()
116
+ await user.people.deleteUser()
117
+
118
+ // Groups
119
+ await user.set_group(groupKey, groupId)
120
+ await user.add_group(groupKey, groupId)
121
+ await user.remove_group(groupKey, groupId)
122
+ const group = user.get_group(groupKey, groupId)
123
+ await group.set(properties)
124
+ await group.set_once(properties)
125
+ await group.union(properties)
126
+ await group.remove(properties)
127
+ await group.unset(keys)
128
+ await group.increment(properties)
129
+ await group.append(properties)
130
+ await group.delete()
131
+ ```
132
+
133
+ ### Direct Call Pattern (for pipelines)
134
+
135
+ ```javascript
136
+ await trodo.track('user-123', 'event_name', { key: 'value' })
137
+ await trodo.identify('user-123', 'identifyId')
138
+ await trodo.people.set('user-123', { plan: 'pro' })
139
+ await trodo.set_group('user-123', 'company', 'acme')
140
+ ```
141
+
142
+ ### Global Methods
143
+
144
+ ```javascript
145
+ trodo.enableAutoEvents() // Enable uncaughtException hooks
146
+ trodo.disableAutoEvents() // Disable hooks
147
+ await trodo.flush() // Flush pending batch queue
148
+ await trodo.shutdown() // Flush + stop background timers
149
+ ```
150
+
151
+ ## Auto Events
152
+
153
+ When `autoEvents: true`, the SDK hooks Node.js process error events and sends `server_error` events to Trodo:
154
+
155
+ - `process.on('uncaughtException')`
156
+ - `process.on('unhandledRejection')`
157
+
158
+ These events use `distinct_id: 'server_global'` in the dashboard.
159
+
160
+ Per-user error capture: `user.captureError(error)` uses the user's own `distinctId`.
161
+
162
+ ## Batching
163
+
164
+ ```javascript
165
+ trodo.init({
166
+ siteId: 'your-site-id',
167
+ batchEnabled: true,
168
+ batchSize: 100,
169
+ batchFlushIntervalMs: 3000,
170
+ });
171
+
172
+ // Events are queued and flushed every 3s or when 100 events accumulate
173
+ await user.track('page_view');
174
+
175
+ // Always flush before process exit
176
+ process.on('SIGTERM', () => trodo.shutdown());
177
+ ```
178
+
179
+ ## TypeScript
180
+
181
+ Full TypeScript support with bundled type declarations:
182
+
183
+ ```typescript
184
+ import trodo, { TrodoConfig, ForUserOptions } from 'trodo-node';
185
+
186
+ const config: TrodoConfig = { siteId: 'your-site-id' };
187
+ trodo.init(config);
188
+ ```
189
+
190
+ ## License
191
+
192
+ ISC
package/package.json CHANGED
@@ -1,71 +1,71 @@
1
- {
2
- "name": "trodo-node",
3
- "version": "1.0.0",
4
- "description": "Trodo Analytics SDK for Node.js — server-side event tracking",
5
- "main": "dist/cjs/index.js",
6
- "module": "dist/esm/index.js",
7
- "types": "dist/types/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/esm/index.js",
11
- "require": "./dist/cjs/index.js",
12
- "types": "./dist/types/index.d.ts"
13
- }
14
- },
15
- "files": [
16
- "dist",
17
- "README.md"
18
- ],
19
- "scripts": {
20
- "build": "npm run build:esm && npm run build:cjs",
21
- "build:esm": "tsc -p tsconfig.json",
22
- "build:cjs": "tsc -p tsconfig.cjs.json",
23
- "test": "jest",
24
- "test:coverage": "jest --coverage",
25
- "lint": "eslint src/**/*.ts",
26
- "prepublishOnly": "npm run build"
27
- },
28
- "keywords": [
29
- "analytics",
30
- "tracking",
31
- "trodo",
32
- "server-side",
33
- "nodejs"
34
- ],
35
- "license": "ISC",
36
- "engines": {
37
- "node": ">=16.0.0"
38
- },
39
- "peerDependencies": {
40
- "node-fetch": "^3.0.0"
41
- },
42
- "peerDependenciesMeta": {
43
- "node-fetch": {
44
- "optional": true
45
- }
46
- },
47
- "devDependencies": {
48
- "@types/jest": "^29.5.12",
49
- "@types/node": "^20.12.7",
50
- "@typescript-eslint/eslint-plugin": "^7.7.1",
51
- "@typescript-eslint/parser": "^7.7.1",
52
- "eslint": "^8.57.0",
53
- "jest": "^29.7.0",
54
- "nock": "^13.5.4",
55
- "ts-jest": "^29.1.2",
56
- "typescript": "^5.4.5"
57
- },
58
- "jest": {
59
- "preset": "ts-jest",
60
- "testEnvironment": "node",
61
- "testMatch": [
62
- "**/tests/**/*.test.ts"
63
- ],
64
- "collectCoverageFrom": [
65
- "src/**/*.ts"
66
- ],
67
- "moduleNameMapper": {
68
- "^(\\.{1,2}/.*)\\.js$": "$1"
69
- }
70
- }
71
- }
1
+ {
2
+ "name": "trodo-node",
3
+ "version": "1.0.1",
4
+ "description": "Trodo Analytics SDK for Node.js — server-side event tracking",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/esm/index.js",
11
+ "require": "./dist/cjs/index.js",
12
+ "types": "./dist/types/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "npm run build:esm && npm run build:cjs",
21
+ "build:esm": "tsc -p tsconfig.json",
22
+ "build:cjs": "tsc -p tsconfig.cjs.json",
23
+ "test": "jest",
24
+ "test:coverage": "jest --coverage",
25
+ "lint": "eslint src/**/*.ts",
26
+ "prepublishOnly": "npm run build"
27
+ },
28
+ "keywords": [
29
+ "analytics",
30
+ "tracking",
31
+ "trodo",
32
+ "server-side",
33
+ "nodejs"
34
+ ],
35
+ "license": "ISC",
36
+ "engines": {
37
+ "node": ">=16.0.0"
38
+ },
39
+ "peerDependencies": {
40
+ "node-fetch": "^3.0.0"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "node-fetch": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "devDependencies": {
48
+ "@types/jest": "^29.5.12",
49
+ "@types/node": "^20.12.7",
50
+ "@typescript-eslint/eslint-plugin": "^7.7.1",
51
+ "@typescript-eslint/parser": "^7.7.1",
52
+ "eslint": "^8.57.0",
53
+ "jest": "^29.7.0",
54
+ "nock": "^13.5.4",
55
+ "ts-jest": "^29.1.2",
56
+ "typescript": "^5.4.5"
57
+ },
58
+ "jest": {
59
+ "preset": "ts-jest",
60
+ "testEnvironment": "node",
61
+ "testMatch": [
62
+ "**/tests/**/*.test.ts"
63
+ ],
64
+ "collectCoverageFrom": [
65
+ "src/**/*.ts"
66
+ ],
67
+ "moduleNameMapper": {
68
+ "^(\\.{1,2}/.*)\\.js$": "$1"
69
+ }
70
+ }
71
+ }