@tell-rs/node 0.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 +138 -0
- package/dist/chunk-HYQWDHQT.js +330 -0
- package/dist/chunk-HYQWDHQT.js.map +1 -0
- package/dist/events.cjs +85 -0
- package/dist/events.cjs.map +1 -0
- package/dist/events.d.cts +1 -0
- package/dist/events.d.ts +1 -0
- package/dist/events.js +7 -0
- package/dist/events.js.map +1 -0
- package/dist/index.cjs +829 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +68 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.js +498 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Batcher,
|
|
3
|
+
ClosedError,
|
|
4
|
+
ConfigurationError,
|
|
5
|
+
Events,
|
|
6
|
+
NetworkError,
|
|
7
|
+
SENSITIVE_PARAMS,
|
|
8
|
+
SerializationError,
|
|
9
|
+
TellError,
|
|
10
|
+
ValidationError,
|
|
11
|
+
redact,
|
|
12
|
+
redactLog,
|
|
13
|
+
runBeforeSend,
|
|
14
|
+
validateApiKey,
|
|
15
|
+
validateEventName,
|
|
16
|
+
validateLogMessage,
|
|
17
|
+
validateUserId
|
|
18
|
+
} from "./chunk-HYQWDHQT.js";
|
|
19
|
+
|
|
20
|
+
// src/config.ts
|
|
21
|
+
import { hostname } from "os";
|
|
22
|
+
var DEFAULTS = {
|
|
23
|
+
endpoint: "https://collect.tell.app",
|
|
24
|
+
batchSize: 100,
|
|
25
|
+
flushInterval: 1e4,
|
|
26
|
+
maxRetries: 3,
|
|
27
|
+
closeTimeout: 5e3,
|
|
28
|
+
networkTimeout: 3e4,
|
|
29
|
+
logLevel: "info",
|
|
30
|
+
source: hostname(),
|
|
31
|
+
disabled: false,
|
|
32
|
+
maxQueueSize: 1e3,
|
|
33
|
+
gzip: false
|
|
34
|
+
};
|
|
35
|
+
function resolveConfig(config) {
|
|
36
|
+
return { ...DEFAULTS, ...config };
|
|
37
|
+
}
|
|
38
|
+
function development(apiKey, overrides) {
|
|
39
|
+
return {
|
|
40
|
+
endpoint: "http://localhost:8080",
|
|
41
|
+
batchSize: 10,
|
|
42
|
+
flushInterval: 2e3,
|
|
43
|
+
logLevel: "debug",
|
|
44
|
+
...overrides,
|
|
45
|
+
apiKey
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function production(apiKey, overrides) {
|
|
49
|
+
return {
|
|
50
|
+
logLevel: "error",
|
|
51
|
+
...overrides,
|
|
52
|
+
apiKey
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/transport.ts
|
|
57
|
+
import { gzipSync } from "zlib";
|
|
58
|
+
var HttpTransport = class {
|
|
59
|
+
endpoint;
|
|
60
|
+
apiKey;
|
|
61
|
+
maxRetries;
|
|
62
|
+
networkTimeout;
|
|
63
|
+
gzip;
|
|
64
|
+
onError;
|
|
65
|
+
onPayloadTooLarge;
|
|
66
|
+
constructor(config) {
|
|
67
|
+
this.endpoint = config.endpoint;
|
|
68
|
+
this.apiKey = config.apiKey;
|
|
69
|
+
this.maxRetries = config.maxRetries;
|
|
70
|
+
this.networkTimeout = config.networkTimeout;
|
|
71
|
+
this.gzip = config.gzip;
|
|
72
|
+
this.onError = config.onError;
|
|
73
|
+
this.onPayloadTooLarge = config.onPayloadTooLarge;
|
|
74
|
+
}
|
|
75
|
+
async sendEvents(events) {
|
|
76
|
+
if (events.length === 0) return;
|
|
77
|
+
const body = events.map((e) => JSON.stringify(e)).join("\n");
|
|
78
|
+
await this.send("/v1/events", body);
|
|
79
|
+
}
|
|
80
|
+
async sendLogs(logs) {
|
|
81
|
+
if (logs.length === 0) return;
|
|
82
|
+
const body = logs.map((l) => JSON.stringify(l)).join("\n");
|
|
83
|
+
await this.send("/v1/logs", body);
|
|
84
|
+
}
|
|
85
|
+
async send(path, body) {
|
|
86
|
+
const url = `${this.endpoint}${path}`;
|
|
87
|
+
const headers = {
|
|
88
|
+
"Content-Type": "application/x-ndjson",
|
|
89
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
90
|
+
};
|
|
91
|
+
let payload = body;
|
|
92
|
+
if (this.gzip) {
|
|
93
|
+
payload = gzipSync(body);
|
|
94
|
+
headers["Content-Encoding"] = "gzip";
|
|
95
|
+
}
|
|
96
|
+
let lastError;
|
|
97
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
98
|
+
if (attempt > 0) {
|
|
99
|
+
await this.backoff(attempt);
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const response = await globalThis.fetch(url, {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers,
|
|
105
|
+
body: payload,
|
|
106
|
+
signal: AbortSignal.timeout(this.networkTimeout)
|
|
107
|
+
});
|
|
108
|
+
if (response.status === 202) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (response.status === 207) {
|
|
112
|
+
if (this.onError) {
|
|
113
|
+
const data = await response.json().catch(() => null);
|
|
114
|
+
this.onError(
|
|
115
|
+
new NetworkError(
|
|
116
|
+
`Partial success: ${data?.rejected ?? "unknown"} items rejected`,
|
|
117
|
+
207
|
|
118
|
+
)
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (response.status === 413) {
|
|
124
|
+
if (this.onPayloadTooLarge) {
|
|
125
|
+
this.onPayloadTooLarge();
|
|
126
|
+
}
|
|
127
|
+
throw new NetworkError("Payload too large", 413);
|
|
128
|
+
}
|
|
129
|
+
if (response.status === 401) {
|
|
130
|
+
throw new NetworkError("Invalid API key", 401);
|
|
131
|
+
}
|
|
132
|
+
if (response.status >= 400 && response.status < 500) {
|
|
133
|
+
throw new NetworkError(
|
|
134
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
135
|
+
response.status
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
lastError = new NetworkError(
|
|
139
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
140
|
+
response.status
|
|
141
|
+
);
|
|
142
|
+
} catch (err) {
|
|
143
|
+
if (err instanceof NetworkError && err.statusCode === 413) {
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
146
|
+
if (err instanceof NetworkError && err.statusCode && err.statusCode < 500) {
|
|
147
|
+
if (this.onError) this.onError(err);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
lastError = err instanceof Error ? err : new NetworkError(String(err));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (lastError && this.onError) {
|
|
154
|
+
this.onError(lastError);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
backoff(attempt) {
|
|
158
|
+
const base = 1e3 * Math.pow(1.5, attempt - 1);
|
|
159
|
+
const jitter = base * 0.2 * Math.random();
|
|
160
|
+
const delay = Math.min(base + jitter, 3e4);
|
|
161
|
+
return new Promise((resolve) => setTimeout(resolve, delay));
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// src/index.ts
|
|
166
|
+
var LOG_LEVELS = {
|
|
167
|
+
error: 0,
|
|
168
|
+
warn: 1,
|
|
169
|
+
info: 2,
|
|
170
|
+
debug: 3
|
|
171
|
+
};
|
|
172
|
+
function uuid() {
|
|
173
|
+
return crypto.randomUUID();
|
|
174
|
+
}
|
|
175
|
+
var Tell = class {
|
|
176
|
+
transport;
|
|
177
|
+
eventBatcher;
|
|
178
|
+
logBatcher;
|
|
179
|
+
deviceId;
|
|
180
|
+
sessionId;
|
|
181
|
+
onError;
|
|
182
|
+
source;
|
|
183
|
+
closeTimeout;
|
|
184
|
+
sdkLogLevel;
|
|
185
|
+
beforeSend;
|
|
186
|
+
beforeSendLog;
|
|
187
|
+
superProperties = {};
|
|
188
|
+
closed = false;
|
|
189
|
+
_disabled;
|
|
190
|
+
constructor(config) {
|
|
191
|
+
validateApiKey(config.apiKey);
|
|
192
|
+
const resolved = resolveConfig(config);
|
|
193
|
+
this.onError = resolved.onError;
|
|
194
|
+
this.source = resolved.source;
|
|
195
|
+
this.closeTimeout = resolved.closeTimeout;
|
|
196
|
+
this.sdkLogLevel = LOG_LEVELS[resolved.logLevel] ?? 2;
|
|
197
|
+
this._disabled = resolved.disabled;
|
|
198
|
+
this.beforeSend = resolved.beforeSend;
|
|
199
|
+
this.beforeSendLog = resolved.beforeSendLog;
|
|
200
|
+
this.deviceId = uuid();
|
|
201
|
+
this.sessionId = uuid();
|
|
202
|
+
this.transport = new HttpTransport({
|
|
203
|
+
endpoint: resolved.endpoint,
|
|
204
|
+
apiKey: resolved.apiKey,
|
|
205
|
+
maxRetries: resolved.maxRetries,
|
|
206
|
+
networkTimeout: resolved.networkTimeout,
|
|
207
|
+
gzip: resolved.gzip,
|
|
208
|
+
onError: this.onError,
|
|
209
|
+
onPayloadTooLarge: () => {
|
|
210
|
+
this.eventBatcher.halveBatchSize();
|
|
211
|
+
this.logBatcher.halveBatchSize();
|
|
212
|
+
this.sdkDebug("413 received, halved batch size");
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
this.eventBatcher = new Batcher({
|
|
216
|
+
size: resolved.batchSize,
|
|
217
|
+
interval: resolved.flushInterval,
|
|
218
|
+
maxQueueSize: resolved.maxQueueSize,
|
|
219
|
+
send: (items) => this.transport.sendEvents(items),
|
|
220
|
+
onOverflow: () => {
|
|
221
|
+
this.sdkDebug("event queue overflow, dropping oldest item");
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
this.logBatcher = new Batcher({
|
|
225
|
+
size: resolved.batchSize,
|
|
226
|
+
interval: resolved.flushInterval,
|
|
227
|
+
maxQueueSize: resolved.maxQueueSize,
|
|
228
|
+
send: (items) => this.transport.sendLogs(items),
|
|
229
|
+
onOverflow: () => {
|
|
230
|
+
this.sdkDebug("log queue overflow, dropping oldest item");
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
this.sdkDebug(`initialized (endpoint=${resolved.endpoint}, batch=${resolved.batchSize}, flush=${resolved.flushInterval}ms)`);
|
|
234
|
+
}
|
|
235
|
+
// --- Super Properties ---
|
|
236
|
+
register(properties) {
|
|
237
|
+
Object.assign(this.superProperties, properties);
|
|
238
|
+
}
|
|
239
|
+
unregister(key) {
|
|
240
|
+
delete this.superProperties[key];
|
|
241
|
+
}
|
|
242
|
+
// --- Disabled ---
|
|
243
|
+
disable() {
|
|
244
|
+
this._disabled = true;
|
|
245
|
+
}
|
|
246
|
+
enable() {
|
|
247
|
+
this._disabled = false;
|
|
248
|
+
}
|
|
249
|
+
// --- Events ---
|
|
250
|
+
track(userId, eventName, properties) {
|
|
251
|
+
if (this._disabled) return;
|
|
252
|
+
if (this.closed) {
|
|
253
|
+
this.reportError(new ClosedError());
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
validateUserId(userId);
|
|
258
|
+
validateEventName(eventName);
|
|
259
|
+
} catch (err) {
|
|
260
|
+
this.reportError(err);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
let event = {
|
|
264
|
+
type: "track",
|
|
265
|
+
event: eventName,
|
|
266
|
+
device_id: this.deviceId,
|
|
267
|
+
session_id: this.sessionId,
|
|
268
|
+
user_id: userId,
|
|
269
|
+
timestamp: Date.now(),
|
|
270
|
+
properties: { ...this.superProperties, ...properties }
|
|
271
|
+
};
|
|
272
|
+
if (this.beforeSend) {
|
|
273
|
+
event = runBeforeSend(event, this.beforeSend);
|
|
274
|
+
if (event === null) return;
|
|
275
|
+
}
|
|
276
|
+
this.eventBatcher.add(event);
|
|
277
|
+
}
|
|
278
|
+
identify(userId, traits) {
|
|
279
|
+
if (this._disabled) return;
|
|
280
|
+
if (this.closed) {
|
|
281
|
+
this.reportError(new ClosedError());
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
validateUserId(userId);
|
|
286
|
+
} catch (err) {
|
|
287
|
+
this.reportError(err);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
let event = {
|
|
291
|
+
type: "identify",
|
|
292
|
+
device_id: this.deviceId,
|
|
293
|
+
session_id: this.sessionId,
|
|
294
|
+
user_id: userId,
|
|
295
|
+
timestamp: Date.now(),
|
|
296
|
+
traits
|
|
297
|
+
};
|
|
298
|
+
if (this.beforeSend) {
|
|
299
|
+
event = runBeforeSend(event, this.beforeSend);
|
|
300
|
+
if (event === null) return;
|
|
301
|
+
}
|
|
302
|
+
this.eventBatcher.add(event);
|
|
303
|
+
}
|
|
304
|
+
group(userId, groupId, properties) {
|
|
305
|
+
if (this._disabled) return;
|
|
306
|
+
if (this.closed) {
|
|
307
|
+
this.reportError(new ClosedError());
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
validateUserId(userId);
|
|
312
|
+
if (!groupId) throw new ValidationError("groupId", "is required");
|
|
313
|
+
} catch (err) {
|
|
314
|
+
this.reportError(err);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
let event = {
|
|
318
|
+
type: "group",
|
|
319
|
+
device_id: this.deviceId,
|
|
320
|
+
session_id: this.sessionId,
|
|
321
|
+
user_id: userId,
|
|
322
|
+
group_id: groupId,
|
|
323
|
+
timestamp: Date.now(),
|
|
324
|
+
properties: { ...this.superProperties, ...properties }
|
|
325
|
+
};
|
|
326
|
+
if (this.beforeSend) {
|
|
327
|
+
event = runBeforeSend(event, this.beforeSend);
|
|
328
|
+
if (event === null) return;
|
|
329
|
+
}
|
|
330
|
+
this.eventBatcher.add(event);
|
|
331
|
+
}
|
|
332
|
+
revenue(userId, amount, currency, orderId, properties) {
|
|
333
|
+
if (this._disabled) return;
|
|
334
|
+
if (this.closed) {
|
|
335
|
+
this.reportError(new ClosedError());
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
try {
|
|
339
|
+
validateUserId(userId);
|
|
340
|
+
if (amount <= 0) throw new ValidationError("amount", "must be positive");
|
|
341
|
+
if (!currency) throw new ValidationError("currency", "is required");
|
|
342
|
+
if (!orderId) throw new ValidationError("orderId", "is required");
|
|
343
|
+
} catch (err) {
|
|
344
|
+
this.reportError(err);
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
let event = {
|
|
348
|
+
type: "track",
|
|
349
|
+
event: "Order Completed",
|
|
350
|
+
device_id: this.deviceId,
|
|
351
|
+
session_id: this.sessionId,
|
|
352
|
+
user_id: userId,
|
|
353
|
+
timestamp: Date.now(),
|
|
354
|
+
properties: {
|
|
355
|
+
...this.superProperties,
|
|
356
|
+
...properties,
|
|
357
|
+
order_id: orderId,
|
|
358
|
+
amount,
|
|
359
|
+
currency
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
if (this.beforeSend) {
|
|
363
|
+
event = runBeforeSend(event, this.beforeSend);
|
|
364
|
+
if (event === null) return;
|
|
365
|
+
}
|
|
366
|
+
this.eventBatcher.add(event);
|
|
367
|
+
}
|
|
368
|
+
alias(previousId, userId) {
|
|
369
|
+
if (this._disabled) return;
|
|
370
|
+
if (this.closed) {
|
|
371
|
+
this.reportError(new ClosedError());
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
try {
|
|
375
|
+
if (!previousId) throw new ValidationError("previousId", "is required");
|
|
376
|
+
validateUserId(userId);
|
|
377
|
+
} catch (err) {
|
|
378
|
+
this.reportError(err);
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
let event = {
|
|
382
|
+
type: "alias",
|
|
383
|
+
device_id: this.deviceId,
|
|
384
|
+
session_id: this.sessionId,
|
|
385
|
+
user_id: userId,
|
|
386
|
+
timestamp: Date.now(),
|
|
387
|
+
properties: { previous_id: previousId }
|
|
388
|
+
};
|
|
389
|
+
if (this.beforeSend) {
|
|
390
|
+
event = runBeforeSend(event, this.beforeSend);
|
|
391
|
+
if (event === null) return;
|
|
392
|
+
}
|
|
393
|
+
this.eventBatcher.add(event);
|
|
394
|
+
}
|
|
395
|
+
resetSession() {
|
|
396
|
+
this.sessionId = uuid();
|
|
397
|
+
}
|
|
398
|
+
// --- Logging ---
|
|
399
|
+
log(level, message, service, data) {
|
|
400
|
+
if (this._disabled) return;
|
|
401
|
+
if (this.closed) {
|
|
402
|
+
this.reportError(new ClosedError());
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
try {
|
|
406
|
+
validateLogMessage(message);
|
|
407
|
+
} catch (err) {
|
|
408
|
+
this.reportError(err);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
let logEntry = {
|
|
412
|
+
level,
|
|
413
|
+
message,
|
|
414
|
+
source: this.source,
|
|
415
|
+
service: service ?? "app",
|
|
416
|
+
session_id: this.sessionId,
|
|
417
|
+
timestamp: Date.now(),
|
|
418
|
+
data
|
|
419
|
+
};
|
|
420
|
+
if (this.beforeSendLog) {
|
|
421
|
+
logEntry = runBeforeSend(logEntry, this.beforeSendLog);
|
|
422
|
+
if (logEntry === null) return;
|
|
423
|
+
}
|
|
424
|
+
this.logBatcher.add(logEntry);
|
|
425
|
+
}
|
|
426
|
+
logEmergency(message, service, data) {
|
|
427
|
+
this.log("emergency", message, service, data);
|
|
428
|
+
}
|
|
429
|
+
logAlert(message, service, data) {
|
|
430
|
+
this.log("alert", message, service, data);
|
|
431
|
+
}
|
|
432
|
+
logCritical(message, service, data) {
|
|
433
|
+
this.log("critical", message, service, data);
|
|
434
|
+
}
|
|
435
|
+
logError(message, service, data) {
|
|
436
|
+
this.log("error", message, service, data);
|
|
437
|
+
}
|
|
438
|
+
logWarning(message, service, data) {
|
|
439
|
+
this.log("warning", message, service, data);
|
|
440
|
+
}
|
|
441
|
+
logNotice(message, service, data) {
|
|
442
|
+
this.log("notice", message, service, data);
|
|
443
|
+
}
|
|
444
|
+
logInfo(message, service, data) {
|
|
445
|
+
this.log("info", message, service, data);
|
|
446
|
+
}
|
|
447
|
+
logDebug(message, service, data) {
|
|
448
|
+
this.log("debug", message, service, data);
|
|
449
|
+
}
|
|
450
|
+
logTrace(message, service, data) {
|
|
451
|
+
this.log("trace", message, service, data);
|
|
452
|
+
}
|
|
453
|
+
// --- Lifecycle ---
|
|
454
|
+
async flush() {
|
|
455
|
+
await Promise.all([this.eventBatcher.flush(), this.logBatcher.flush()]);
|
|
456
|
+
}
|
|
457
|
+
async close() {
|
|
458
|
+
if (this.closed) return;
|
|
459
|
+
this.closed = true;
|
|
460
|
+
this.sdkDebug("closing...");
|
|
461
|
+
const work = Promise.all([this.eventBatcher.close(), this.logBatcher.close()]);
|
|
462
|
+
const timeout = new Promise(
|
|
463
|
+
(_, reject) => setTimeout(() => reject(new Error("close timed out")), this.closeTimeout)
|
|
464
|
+
);
|
|
465
|
+
try {
|
|
466
|
+
await Promise.race([work, timeout]);
|
|
467
|
+
} catch (err) {
|
|
468
|
+
this.reportError(err);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
// --- Internal ---
|
|
472
|
+
reportError(err) {
|
|
473
|
+
if (this.onError && err instanceof Error) {
|
|
474
|
+
this.onError(err);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
sdkDebug(msg) {
|
|
478
|
+
if (this.sdkLogLevel >= LOG_LEVELS.debug) {
|
|
479
|
+
console.debug(`[Tell] ${msg}`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
export {
|
|
484
|
+
ClosedError,
|
|
485
|
+
ConfigurationError,
|
|
486
|
+
Events,
|
|
487
|
+
NetworkError,
|
|
488
|
+
SENSITIVE_PARAMS,
|
|
489
|
+
SerializationError,
|
|
490
|
+
Tell,
|
|
491
|
+
TellError,
|
|
492
|
+
ValidationError,
|
|
493
|
+
development,
|
|
494
|
+
production,
|
|
495
|
+
redact,
|
|
496
|
+
redactLog
|
|
497
|
+
};
|
|
498
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/transport.ts","../src/index.ts"],"sourcesContent":["import type { TellError } from \"@tell-rs/core\";\nimport type { BeforeSendFn } from \"@tell-rs/core\";\nimport type { JsonEvent, JsonLog } from \"@tell-rs/core\";\nimport { hostname } from \"node:os\";\n\nexport interface TellConfig {\n apiKey: string;\n endpoint?: string;\n batchSize?: number;\n flushInterval?: number;\n maxRetries?: number;\n closeTimeout?: number;\n networkTimeout?: number;\n logLevel?: \"error\" | \"warn\" | \"info\" | \"debug\";\n source?: string;\n onError?: (error: TellError) => void;\n disabled?: boolean;\n maxQueueSize?: number;\n gzip?: boolean;\n beforeSend?: BeforeSendFn<JsonEvent> | BeforeSendFn<JsonEvent>[];\n beforeSendLog?: BeforeSendFn<JsonLog> | BeforeSendFn<JsonLog>[];\n}\n\nexport const DEFAULTS = {\n endpoint: \"https://collect.tell.app\",\n batchSize: 100,\n flushInterval: 10_000,\n maxRetries: 3,\n closeTimeout: 5_000,\n networkTimeout: 30_000,\n logLevel: \"info\" as const,\n source: hostname(),\n disabled: false,\n maxQueueSize: 1000,\n gzip: false,\n} as const;\n\nexport type ResolvedConfig = Required<\n Omit<TellConfig, \"onError\" | \"beforeSend\" | \"beforeSendLog\">\n> &\n Pick<TellConfig, \"onError\" | \"beforeSend\" | \"beforeSendLog\">;\n\nexport function resolveConfig(config: TellConfig): ResolvedConfig {\n return { ...DEFAULTS, ...config } as ResolvedConfig;\n}\n\n/** Development preset: localhost, small batches, fast flush, debug logging. */\nexport function development(\n apiKey: string,\n overrides?: Partial<TellConfig>\n): TellConfig {\n return {\n endpoint: \"http://localhost:8080\",\n batchSize: 10,\n flushInterval: 2_000,\n logLevel: \"debug\",\n ...overrides,\n apiKey,\n };\n}\n\n/** Production preset: default endpoint, default batching, error-only logging. */\nexport function production(\n apiKey: string,\n overrides?: Partial<TellConfig>\n): TellConfig {\n return {\n logLevel: \"error\",\n ...overrides,\n apiKey,\n };\n}\n","import type { JsonEvent, JsonLog } from \"@tell-rs/core\";\nimport { NetworkError } from \"@tell-rs/core\";\nimport { gzipSync } from \"node:zlib\";\n\nexport interface TransportConfig {\n endpoint: string;\n apiKey: string;\n maxRetries: number;\n networkTimeout: number;\n gzip: boolean;\n onError?: (error: Error) => void;\n onPayloadTooLarge?: () => void;\n}\n\nexport class HttpTransport {\n private readonly endpoint: string;\n private readonly apiKey: string;\n private readonly maxRetries: number;\n private readonly networkTimeout: number;\n private readonly gzip: boolean;\n private readonly onError?: (error: Error) => void;\n private readonly onPayloadTooLarge?: () => void;\n\n constructor(config: TransportConfig) {\n this.endpoint = config.endpoint;\n this.apiKey = config.apiKey;\n this.maxRetries = config.maxRetries;\n this.networkTimeout = config.networkTimeout;\n this.gzip = config.gzip;\n this.onError = config.onError;\n this.onPayloadTooLarge = config.onPayloadTooLarge;\n }\n\n async sendEvents(events: JsonEvent[]): Promise<void> {\n if (events.length === 0) return;\n const body = events.map((e) => JSON.stringify(e)).join(\"\\n\");\n await this.send(\"/v1/events\", body);\n }\n\n async sendLogs(logs: JsonLog[]): Promise<void> {\n if (logs.length === 0) return;\n const body = logs.map((l) => JSON.stringify(l)).join(\"\\n\");\n await this.send(\"/v1/logs\", body);\n }\n\n private async send(path: string, body: string): Promise<void> {\n const url = `${this.endpoint}${path}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/x-ndjson\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n\n let payload: string | Buffer = body;\n if (this.gzip) {\n payload = gzipSync(body);\n headers[\"Content-Encoding\"] = \"gzip\";\n }\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n if (attempt > 0) {\n await this.backoff(attempt);\n }\n\n try {\n const response = await globalThis.fetch(url, {\n method: \"POST\",\n headers,\n body: payload,\n signal: AbortSignal.timeout(this.networkTimeout),\n });\n\n if (response.status === 202) {\n return;\n }\n\n if (response.status === 207) {\n if (this.onError) {\n const data = (await response.json().catch(() => null)) as Record<string, unknown> | null;\n this.onError(\n new NetworkError(\n `Partial success: ${data?.rejected ?? \"unknown\"} items rejected`,\n 207\n )\n );\n }\n return;\n }\n\n if (response.status === 413) {\n if (this.onPayloadTooLarge) {\n this.onPayloadTooLarge();\n }\n throw new NetworkError(\"Payload too large\", 413);\n }\n\n if (response.status === 401) {\n throw new NetworkError(\"Invalid API key\", 401);\n }\n\n if (response.status >= 400 && response.status < 500) {\n throw new NetworkError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status\n );\n }\n\n lastError = new NetworkError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status\n );\n } catch (err) {\n if (err instanceof NetworkError && err.statusCode === 413) {\n throw err;\n }\n\n if (err instanceof NetworkError && err.statusCode && err.statusCode < 500) {\n if (this.onError) this.onError(err);\n return;\n }\n lastError =\n err instanceof Error ? err : new NetworkError(String(err));\n }\n }\n\n if (lastError && this.onError) {\n this.onError(lastError);\n }\n }\n\n private backoff(attempt: number): Promise<void> {\n const base = 1000 * Math.pow(1.5, attempt - 1);\n const jitter = base * 0.2 * Math.random();\n const delay = Math.min(base + jitter, 30_000);\n return new Promise((resolve) => setTimeout(resolve, delay));\n }\n}\n","import type { TellConfig } from \"./config.js\";\nimport type { JsonEvent, JsonLog, LogLevel, Properties, BeforeSendFn } from \"@tell-rs/core\";\nimport { resolveConfig } from \"./config.js\";\nimport { ClosedError, ValidationError, validateApiKey, validateEventName, validateLogMessage, validateUserId, Batcher, runBeforeSend } from \"@tell-rs/core\";\nimport { HttpTransport } from \"./transport.js\";\n\n// Re-export core types and values\nexport { Events, type EventName } from \"@tell-rs/core\";\nexport type { Properties, LogLevel, JsonEvent, JsonLog, BeforeSendFn } from \"@tell-rs/core\";\nexport { redact, redactLog, SENSITIVE_PARAMS, type RedactOptions } from \"@tell-rs/core\";\nexport { TellError, ConfigurationError, ValidationError, NetworkError, ClosedError, SerializationError } from \"@tell-rs/core\";\n\n// Re-export node-specific config\nexport type { TellConfig } from \"./config.js\";\nexport { development, production } from \"./config.js\";\n\nconst LOG_LEVELS: Record<string, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n};\n\nfunction uuid(): string {\n return crypto.randomUUID();\n}\n\nexport class Tell {\n private readonly transport: HttpTransport;\n private readonly eventBatcher: Batcher<JsonEvent>;\n private readonly logBatcher: Batcher<JsonLog>;\n private readonly deviceId: string;\n private sessionId: string;\n private readonly onError?: (error: Error) => void;\n private readonly source: string;\n private readonly closeTimeout: number;\n private readonly sdkLogLevel: number;\n private readonly beforeSend?: BeforeSendFn<JsonEvent> | BeforeSendFn<JsonEvent>[];\n private readonly beforeSendLog?: BeforeSendFn<JsonLog> | BeforeSendFn<JsonLog>[];\n private superProperties: Properties = {};\n private closed = false;\n private _disabled: boolean;\n\n constructor(config: TellConfig) {\n validateApiKey(config.apiKey);\n\n const resolved = resolveConfig(config);\n this.onError = resolved.onError;\n this.source = resolved.source;\n this.closeTimeout = resolved.closeTimeout;\n this.sdkLogLevel = LOG_LEVELS[resolved.logLevel] ?? 2;\n this._disabled = resolved.disabled;\n this.beforeSend = resolved.beforeSend;\n this.beforeSendLog = resolved.beforeSendLog;\n this.deviceId = uuid();\n this.sessionId = uuid();\n\n this.transport = new HttpTransport({\n endpoint: resolved.endpoint,\n apiKey: resolved.apiKey,\n maxRetries: resolved.maxRetries,\n networkTimeout: resolved.networkTimeout,\n gzip: resolved.gzip,\n onError: this.onError,\n onPayloadTooLarge: () => {\n this.eventBatcher.halveBatchSize();\n this.logBatcher.halveBatchSize();\n this.sdkDebug(\"413 received, halved batch size\");\n },\n });\n\n this.eventBatcher = new Batcher<JsonEvent>({\n size: resolved.batchSize,\n interval: resolved.flushInterval,\n maxQueueSize: resolved.maxQueueSize,\n send: (items) => this.transport.sendEvents(items),\n onOverflow: () => {\n this.sdkDebug(\"event queue overflow, dropping oldest item\");\n },\n });\n\n this.logBatcher = new Batcher<JsonLog>({\n size: resolved.batchSize,\n interval: resolved.flushInterval,\n maxQueueSize: resolved.maxQueueSize,\n send: (items) => this.transport.sendLogs(items),\n onOverflow: () => {\n this.sdkDebug(\"log queue overflow, dropping oldest item\");\n },\n });\n\n this.sdkDebug(`initialized (endpoint=${resolved.endpoint}, batch=${resolved.batchSize}, flush=${resolved.flushInterval}ms)`);\n }\n\n // --- Super Properties ---\n\n register(properties: Properties): void {\n Object.assign(this.superProperties, properties);\n }\n\n unregister(key: string): void {\n delete this.superProperties[key];\n }\n\n // --- Disabled ---\n\n disable(): void {\n this._disabled = true;\n }\n\n enable(): void {\n this._disabled = false;\n }\n\n // --- Events ---\n\n track(userId: string, eventName: string, properties?: Properties): void {\n if (this._disabled) return;\n if (this.closed) { this.reportError(new ClosedError()); return; }\n try {\n validateUserId(userId);\n validateEventName(eventName);\n } catch (err) {\n this.reportError(err);\n return;\n }\n\n let event: JsonEvent | null = {\n type: \"track\",\n event: eventName,\n device_id: this.deviceId,\n session_id: this.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n properties: { ...this.superProperties, ...properties },\n };\n\n if (this.beforeSend) {\n event = runBeforeSend(event, this.beforeSend);\n if (event === null) return;\n }\n\n this.eventBatcher.add(event);\n }\n\n identify(userId: string, traits?: Properties): void {\n if (this._disabled) return;\n if (this.closed) { this.reportError(new ClosedError()); return; }\n try {\n validateUserId(userId);\n } catch (err) {\n this.reportError(err);\n return;\n }\n\n let event: JsonEvent | null = {\n type: \"identify\",\n device_id: this.deviceId,\n session_id: this.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n traits,\n };\n\n if (this.beforeSend) {\n event = runBeforeSend(event, this.beforeSend);\n if (event === null) return;\n }\n\n this.eventBatcher.add(event);\n }\n\n group(userId: string, groupId: string, properties?: Properties): void {\n if (this._disabled) return;\n if (this.closed) { this.reportError(new ClosedError()); return; }\n try {\n validateUserId(userId);\n if (!groupId) throw new ValidationError(\"groupId\", \"is required\");\n } catch (err) {\n this.reportError(err);\n return;\n }\n\n let event: JsonEvent | null = {\n type: \"group\",\n device_id: this.deviceId,\n session_id: this.sessionId,\n user_id: userId,\n group_id: groupId,\n timestamp: Date.now(),\n properties: { ...this.superProperties, ...properties },\n };\n\n if (this.beforeSend) {\n event = runBeforeSend(event, this.beforeSend);\n if (event === null) return;\n }\n\n this.eventBatcher.add(event);\n }\n\n revenue(\n userId: string,\n amount: number,\n currency: string,\n orderId: string,\n properties?: Properties\n ): void {\n if (this._disabled) return;\n if (this.closed) { this.reportError(new ClosedError()); return; }\n try {\n validateUserId(userId);\n if (amount <= 0) throw new ValidationError(\"amount\", \"must be positive\");\n if (!currency) throw new ValidationError(\"currency\", \"is required\");\n if (!orderId) throw new ValidationError(\"orderId\", \"is required\");\n } catch (err) {\n this.reportError(err);\n return;\n }\n\n let event: JsonEvent | null = {\n type: \"track\",\n event: \"Order Completed\",\n device_id: this.deviceId,\n session_id: this.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n properties: {\n ...this.superProperties,\n ...properties,\n order_id: orderId,\n amount,\n currency,\n },\n };\n\n if (this.beforeSend) {\n event = runBeforeSend(event, this.beforeSend);\n if (event === null) return;\n }\n\n this.eventBatcher.add(event);\n }\n\n alias(previousId: string, userId: string): void {\n if (this._disabled) return;\n if (this.closed) { this.reportError(new ClosedError()); return; }\n try {\n if (!previousId) throw new ValidationError(\"previousId\", \"is required\");\n validateUserId(userId);\n } catch (err) {\n this.reportError(err);\n return;\n }\n\n let event: JsonEvent | null = {\n type: \"alias\",\n device_id: this.deviceId,\n session_id: this.sessionId,\n user_id: userId,\n timestamp: Date.now(),\n properties: { previous_id: previousId },\n };\n\n if (this.beforeSend) {\n event = runBeforeSend(event, this.beforeSend);\n if (event === null) return;\n }\n\n this.eventBatcher.add(event);\n }\n\n resetSession(): void {\n this.sessionId = uuid();\n }\n\n // --- Logging ---\n\n log(level: LogLevel, message: string, service?: string, data?: Properties): void {\n if (this._disabled) return;\n if (this.closed) { this.reportError(new ClosedError()); return; }\n try {\n validateLogMessage(message);\n } catch (err) {\n this.reportError(err);\n return;\n }\n\n let logEntry: JsonLog | null = {\n level,\n message,\n source: this.source,\n service: service ?? \"app\",\n session_id: this.sessionId,\n timestamp: Date.now(),\n data,\n };\n\n if (this.beforeSendLog) {\n logEntry = runBeforeSend(logEntry, this.beforeSendLog);\n if (logEntry === null) return;\n }\n\n this.logBatcher.add(logEntry);\n }\n\n logEmergency(message: string, service?: string, data?: Properties): void {\n this.log(\"emergency\", message, service, data);\n }\n logAlert(message: string, service?: string, data?: Properties): void {\n this.log(\"alert\", message, service, data);\n }\n logCritical(message: string, service?: string, data?: Properties): void {\n this.log(\"critical\", message, service, data);\n }\n logError(message: string, service?: string, data?: Properties): void {\n this.log(\"error\", message, service, data);\n }\n logWarning(message: string, service?: string, data?: Properties): void {\n this.log(\"warning\", message, service, data);\n }\n logNotice(message: string, service?: string, data?: Properties): void {\n this.log(\"notice\", message, service, data);\n }\n logInfo(message: string, service?: string, data?: Properties): void {\n this.log(\"info\", message, service, data);\n }\n logDebug(message: string, service?: string, data?: Properties): void {\n this.log(\"debug\", message, service, data);\n }\n logTrace(message: string, service?: string, data?: Properties): void {\n this.log(\"trace\", message, service, data);\n }\n\n // --- Lifecycle ---\n\n async flush(): Promise<void> {\n await Promise.all([this.eventBatcher.flush(), this.logBatcher.flush()]);\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.sdkDebug(\"closing...\");\n const work = Promise.all([this.eventBatcher.close(), this.logBatcher.close()]);\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error(\"close timed out\")), this.closeTimeout)\n );\n try {\n await Promise.race([work, timeout]);\n } catch (err) {\n this.reportError(err);\n }\n }\n\n // --- Internal ---\n\n private reportError(err: unknown): void {\n if (this.onError && err instanceof Error) {\n this.onError(err);\n }\n }\n\n private sdkDebug(msg: string): void {\n if (this.sdkLogLevel >= LOG_LEVELS.debug) {\n console.debug(`[Tell] ${msg}`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tell-rs/node",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Tell SDK for Node.js — analytics events and structured logging",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./events": {
|
|
16
|
+
"types": "./dist/events.d.ts",
|
|
17
|
+
"import": "./dist/events.js",
|
|
18
|
+
"require": "./dist/events.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"test": "node --import tsx --test test/*.test.ts",
|
|
27
|
+
"test:e2e": "TELL_E2E=1 node --import tsx --test test/e2e.test.ts",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"clean": "rm -rf dist"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@tell-rs/core": "*",
|
|
33
|
+
"@types/node": "^22.0.0",
|
|
34
|
+
"tsup": "^8.0.0",
|
|
35
|
+
"tsx": "^4.0.0",
|
|
36
|
+
"typescript": "^5.5.0"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
},
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/tell-rs/tell-js.git",
|
|
44
|
+
"directory": "packages/node"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://tell.rs",
|
|
47
|
+
"keywords": [
|
|
48
|
+
"analytics",
|
|
49
|
+
"logging",
|
|
50
|
+
"telemetry",
|
|
51
|
+
"events",
|
|
52
|
+
"observability",
|
|
53
|
+
"tell"
|
|
54
|
+
],
|
|
55
|
+
"license": "MIT",
|
|
56
|
+
"author": "Arcade Labs Inc."
|
|
57
|
+
}
|