@qurvo/sdk-node 0.0.2

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 ADDED
@@ -0,0 +1,190 @@
1
+ # @qurvo/sdk-node
2
+
3
+ Server-side SDK for [Qurvo](https://qurvo.ru) analytics. Track events, identify users, and manage user properties from your Node.js backend.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @qurvo/sdk-node
9
+ # or
10
+ pnpm add @qurvo/sdk-node
11
+ # or
12
+ yarn add @qurvo/sdk-node
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { Qurvo } from '@qurvo/sdk-node';
19
+
20
+ const qurvo = new Qurvo({
21
+ apiKey: 'qk_your_api_key',
22
+ endpoint: 'https://ingest.yourapp.com',
23
+ });
24
+
25
+ // Track events
26
+ qurvo.track({
27
+ distinct_id: 'user-123',
28
+ event: 'purchase',
29
+ properties: { plan: 'premium', amount: 49.99 },
30
+ });
31
+
32
+ // Identify a user
33
+ qurvo.identify({
34
+ distinct_id: 'user-123',
35
+ user_properties: { email: 'jane@example.com', name: 'Jane Doe' },
36
+ });
37
+
38
+ // Flush remaining events on shutdown
39
+ await qurvo.shutdown();
40
+ ```
41
+
42
+ ## Configuration
43
+
44
+ ```typescript
45
+ const qurvo = new Qurvo({
46
+ apiKey: 'qk_...', // Required. Your project API key
47
+ endpoint: 'https://...', // Ingest API URL (default: http://localhost:3001)
48
+ flushInterval: 5000, // Batch send interval in ms (default: 5000)
49
+ flushSize: 20, // Send batch when queue reaches this size (default: 20)
50
+ maxQueueSize: 1000, // Maximum events in queue (default: 1000)
51
+ });
52
+ ```
53
+
54
+ ## API
55
+
56
+ ### `qurvo.track({ distinct_id, event, properties? })`
57
+
58
+ Track a custom event.
59
+
60
+ ```typescript
61
+ qurvo.track({
62
+ distinct_id: 'user-123',
63
+ event: 'file_uploaded',
64
+ properties: {
65
+ file_type: 'pdf',
66
+ file_size_mb: 4.2,
67
+ },
68
+ });
69
+ ```
70
+
71
+ ### `qurvo.identify({ distinct_id, user_properties })`
72
+
73
+ Identify a user and set their properties. Sends a `$identify` event.
74
+
75
+ ```typescript
76
+ qurvo.identify({
77
+ distinct_id: 'user-123',
78
+ user_properties: {
79
+ email: 'jane@example.com',
80
+ name: 'Jane Doe',
81
+ created_at: '2025-01-15',
82
+ },
83
+ });
84
+ ```
85
+
86
+ ### `qurvo.set({ distinct_id, properties })`
87
+
88
+ Set user properties. Overwrites existing values.
89
+
90
+ ```typescript
91
+ qurvo.set({
92
+ distinct_id: 'user-123',
93
+ properties: { plan: 'enterprise', company: 'Acme Inc.' },
94
+ });
95
+ ```
96
+
97
+ ### `qurvo.setOnce({ distinct_id, properties })`
98
+
99
+ Set user properties only if they haven't been set before.
100
+
101
+ ```typescript
102
+ qurvo.setOnce({
103
+ distinct_id: 'user-123',
104
+ properties: { referral_source: 'google', first_seen: new Date().toISOString() },
105
+ });
106
+ ```
107
+
108
+ ### `qurvo.screen({ distinct_id, screen_name, properties? })`
109
+
110
+ Track a screen view (useful for mobile apps or SSR).
111
+
112
+ ```typescript
113
+ qurvo.screen({
114
+ distinct_id: 'user-123',
115
+ screen_name: 'HomeScreen',
116
+ properties: { tab: 'trending' },
117
+ });
118
+ ```
119
+
120
+ ### `await qurvo.shutdown()`
121
+
122
+ Flush all remaining events and stop the queue. Call this before your process exits to ensure no events are lost.
123
+
124
+ ```typescript
125
+ process.on('SIGTERM', async () => {
126
+ await qurvo.shutdown();
127
+ process.exit(0);
128
+ });
129
+ ```
130
+
131
+ ## How It Works
132
+
133
+ - **Event queue** batches events and sends them every 5 seconds or when the batch reaches 20 events.
134
+ - **Retry with backoff** on network failures: 1s, 2s, 4s, 8s... up to 30s between retries.
135
+ - **Overflow protection**: when the queue reaches `maxQueueSize`, the oldest events are dropped.
136
+ - **Graceful shutdown**: `shutdown()` stops the timer and flushes all remaining events.
137
+
138
+ ## Special Events
139
+
140
+ | Event | Trigger |
141
+ |---|---|
142
+ | `$identify` | `identify()` call |
143
+ | `$set` | `set()` call |
144
+ | `$set_once` | `setOnce()` call |
145
+ | `$screen` | `screen()` call |
146
+
147
+ ## Express Example
148
+
149
+ ```typescript
150
+ import express from 'express';
151
+ import { Qurvo } from '@qurvo/sdk-node';
152
+
153
+ const app = express();
154
+ const qurvo = new Qurvo({
155
+ apiKey: 'qk_your_api_key',
156
+ endpoint: 'https://ingest.yourapp.com',
157
+ });
158
+
159
+ app.post('/api/checkout', (req, res) => {
160
+ const userId = req.user.id;
161
+
162
+ qurvo.track({
163
+ distinct_id: userId,
164
+ event: 'checkout_completed',
165
+ properties: { cart_total: req.body.total, items: req.body.items.length },
166
+ });
167
+
168
+ res.json({ ok: true });
169
+ });
170
+
171
+ // Graceful shutdown
172
+ process.on('SIGTERM', async () => {
173
+ await qurvo.shutdown();
174
+ process.exit(0);
175
+ });
176
+
177
+ app.listen(3000);
178
+ ```
179
+
180
+ ## TypeScript
181
+
182
+ The package ships with full TypeScript type definitions.
183
+
184
+ ```typescript
185
+ import { Qurvo, type NodeSdkConfig } from '@qurvo/sdk-node';
186
+ ```
187
+
188
+ ## License
189
+
190
+ MIT
@@ -0,0 +1,33 @@
1
+ import type { SdkConfig } from '@qurvo/sdk-core';
2
+ export interface NodeSdkConfig extends SdkConfig {
3
+ endpoint?: string;
4
+ }
5
+ export declare class Qurvo {
6
+ private queue;
7
+ private config;
8
+ constructor(config: NodeSdkConfig);
9
+ track(params: {
10
+ distinct_id: string;
11
+ event: string;
12
+ properties?: Record<string, unknown>;
13
+ }): void;
14
+ identify(params: {
15
+ distinct_id: string;
16
+ user_properties: Record<string, unknown>;
17
+ }): void;
18
+ set(params: {
19
+ distinct_id: string;
20
+ properties: Record<string, unknown>;
21
+ }): void;
22
+ setOnce(params: {
23
+ distinct_id: string;
24
+ properties: Record<string, unknown>;
25
+ }): void;
26
+ screen(params: {
27
+ distinct_id: string;
28
+ screen_name: string;
29
+ properties?: Record<string, unknown>;
30
+ }): void;
31
+ shutdown(): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,iBAAiB,CAAC;AAK/D,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,aAAa;IAejC,KAAK,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;IAc1F,QAAQ,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;IAclF,GAAG,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;IAcxE,OAAO,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;IAc5E,MAAM,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;IAc3F,QAAQ;CAIf"}
package/dist/index.js ADDED
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Qurvo = void 0;
4
+ const sdk_core_1 = require("@qurvo/sdk-core");
5
+ const SDK_NAME = '@qurvo/sdk-node';
6
+ const SDK_VERSION = '0.0.1';
7
+ class Qurvo {
8
+ queue;
9
+ config;
10
+ constructor(config) {
11
+ this.config = config;
12
+ const endpoint = config.endpoint || 'http://localhost:3001';
13
+ const transport = new sdk_core_1.FetchTransport();
14
+ this.queue = new sdk_core_1.EventQueue(transport, `${endpoint}/v1/batch`, config.apiKey, config.flushInterval || 5000, config.flushSize || 20, config.maxQueueSize || 1000);
15
+ this.queue.start();
16
+ }
17
+ track(params) {
18
+ const payload = {
19
+ event: params.event,
20
+ distinct_id: params.distinct_id,
21
+ properties: params.properties,
22
+ context: {
23
+ sdk_name: SDK_NAME,
24
+ sdk_version: SDK_VERSION,
25
+ },
26
+ timestamp: new Date().toISOString(),
27
+ };
28
+ this.queue.enqueue(payload);
29
+ }
30
+ identify(params) {
31
+ const payload = {
32
+ event: '$identify',
33
+ distinct_id: params.distinct_id,
34
+ user_properties: params.user_properties,
35
+ context: {
36
+ sdk_name: SDK_NAME,
37
+ sdk_version: SDK_VERSION,
38
+ },
39
+ timestamp: new Date().toISOString(),
40
+ };
41
+ this.queue.enqueue(payload);
42
+ }
43
+ set(params) {
44
+ const payload = {
45
+ event: '$set',
46
+ distinct_id: params.distinct_id,
47
+ user_properties: { $set: params.properties },
48
+ context: {
49
+ sdk_name: SDK_NAME,
50
+ sdk_version: SDK_VERSION,
51
+ },
52
+ timestamp: new Date().toISOString(),
53
+ };
54
+ this.queue.enqueue(payload);
55
+ }
56
+ setOnce(params) {
57
+ const payload = {
58
+ event: '$set_once',
59
+ distinct_id: params.distinct_id,
60
+ user_properties: { $set_once: params.properties },
61
+ context: {
62
+ sdk_name: SDK_NAME,
63
+ sdk_version: SDK_VERSION,
64
+ },
65
+ timestamp: new Date().toISOString(),
66
+ };
67
+ this.queue.enqueue(payload);
68
+ }
69
+ screen(params) {
70
+ const payload = {
71
+ event: '$screen',
72
+ distinct_id: params.distinct_id,
73
+ properties: { $screen_name: params.screen_name, ...params.properties },
74
+ context: {
75
+ sdk_name: SDK_NAME,
76
+ sdk_version: SDK_VERSION,
77
+ },
78
+ timestamp: new Date().toISOString(),
79
+ };
80
+ this.queue.enqueue(payload);
81
+ }
82
+ async shutdown() {
83
+ this.queue.stop();
84
+ await this.queue.flush();
85
+ }
86
+ }
87
+ exports.Qurvo = Qurvo;
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@qurvo/sdk-node",
3
+ "version": "0.0.2",
4
+ "description": "Server-side SDK for Qurvo analytics — event tracking, user identification",
5
+ "license": "MIT",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "dependencies": {
15
+ "@qurvo/sdk-core": "0.0.2"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^22.0.0",
19
+ "typescript": "^5.7.0",
20
+ "@qurvo/tsconfig": "0.0.0"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "dev": "tsc --watch",
25
+ "clean": "rm -rf dist .turbo"
26
+ }
27
+ }