@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/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":";;;;;;;;;;;;;;;;;;;;AAGA,SAAS,gBAAgB;AAoBlB,IAAM,WAAW;AAAA,EACtB,UAAU;AAAA,EACV,WAAW;AAAA,EACX,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,QAAQ,SAAS;AAAA,EACjB,UAAU;AAAA,EACV,cAAc;AAAA,EACd,MAAM;AACR;AAOO,SAAS,cAAc,QAAoC;AAChE,SAAO,EAAE,GAAG,UAAU,GAAG,OAAO;AAClC;AAGO,SAAS,YACd,QACA,WACY;AACZ,SAAO;AAAA,IACL,UAAU;AAAA,IACV,WAAW;AAAA,IACX,eAAe;AAAA,IACf,UAAU;AAAA,IACV,GAAG;AAAA,IACH;AAAA,EACF;AACF;AAGO,SAAS,WACd,QACA,WACY;AACZ,SAAO;AAAA,IACL,UAAU;AAAA,IACV,GAAG;AAAA,IACH;AAAA,EACF;AACF;;;ACrEA,SAAS,gBAAgB;AAYlB,IAAM,gBAAN,MAAoB;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,QAAyB;AACnC,SAAK,WAAW,OAAO;AACvB,SAAK,SAAS,OAAO;AACrB,SAAK,aAAa,OAAO;AACzB,SAAK,iBAAiB,OAAO;AAC7B,SAAK,OAAO,OAAO;AACnB,SAAK,UAAU,OAAO;AACtB,SAAK,oBAAoB,OAAO;AAAA,EAClC;AAAA,EAEA,MAAM,WAAW,QAAoC;AACnD,QAAI,OAAO,WAAW,EAAG;AACzB,UAAM,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI;AAC3D,UAAM,KAAK,KAAK,cAAc,IAAI;AAAA,EACpC;AAAA,EAEA,MAAM,SAAS,MAAgC;AAC7C,QAAI,KAAK,WAAW,EAAG;AACvB,UAAM,OAAO,KAAK,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI;AACzD,UAAM,KAAK,KAAK,YAAY,IAAI;AAAA,EAClC;AAAA,EAEA,MAAc,KAAK,MAAc,MAA6B;AAC5D,UAAM,MAAM,GAAG,KAAK,QAAQ,GAAG,IAAI;AACnC,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK,MAAM;AAAA,IACtC;AAEA,QAAI,UAA2B;AAC/B,QAAI,KAAK,MAAM;AACb,gBAAU,SAAS,IAAI;AACvB,cAAQ,kBAAkB,IAAI;AAAA,IAChC;AAEA,QAAI;AAEJ,aAAS,UAAU,GAAG,WAAW,KAAK,YAAY,WAAW;AAC3D,UAAI,UAAU,GAAG;AACf,cAAM,KAAK,QAAQ,OAAO;AAAA,MAC5B;AAEA,UAAI;AACF,cAAM,WAAW,MAAM,WAAW,MAAM,KAAK;AAAA,UAC3C,QAAQ;AAAA,UACR;AAAA,UACA,MAAM;AAAA,UACN,QAAQ,YAAY,QAAQ,KAAK,cAAc;AAAA,QACjD,CAAC;AAED,YAAI,SAAS,WAAW,KAAK;AAC3B;AAAA,QACF;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,cAAI,KAAK,SAAS;AAChB,kBAAM,OAAQ,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AACpD,iBAAK;AAAA,cACH,IAAI;AAAA,gBACF,oBAAoB,MAAM,YAAY,SAAS;AAAA,gBAC/C;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA;AAAA,QACF;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,cAAI,KAAK,mBAAmB;AAC1B,iBAAK,kBAAkB;AAAA,UACzB;AACA,gBAAM,IAAI,aAAa,qBAAqB,GAAG;AAAA,QACjD;AAEA,YAAI,SAAS,WAAW,KAAK;AAC3B,gBAAM,IAAI,aAAa,mBAAmB,GAAG;AAAA,QAC/C;AAEA,YAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK;AACnD,gBAAM,IAAI;AAAA,YACR,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU;AAAA,YAC/C,SAAS;AAAA,UACX;AAAA,QACF;AAEA,oBAAY,IAAI;AAAA,UACd,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU;AAAA,UAC/C,SAAS;AAAA,QACX;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,eAAe,gBAAgB,IAAI,eAAe,KAAK;AACzD,gBAAM;AAAA,QACR;AAEA,YAAI,eAAe,gBAAgB,IAAI,cAAc,IAAI,aAAa,KAAK;AACzE,cAAI,KAAK,QAAS,MAAK,QAAQ,GAAG;AAClC;AAAA,QACF;AACA,oBACE,eAAe,QAAQ,MAAM,IAAI,aAAa,OAAO,GAAG,CAAC;AAAA,MAC7D;AAAA,IACF;AAEA,QAAI,aAAa,KAAK,SAAS;AAC7B,WAAK,QAAQ,SAAS;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,QAAQ,SAAgC;AAC9C,UAAM,OAAO,MAAO,KAAK,IAAI,KAAK,UAAU,CAAC;AAC7C,UAAM,SAAS,OAAO,MAAM,KAAK,OAAO;AACxC,UAAM,QAAQ,KAAK,IAAI,OAAO,QAAQ,GAAM;AAC5C,WAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AAAA,EAC5D;AACF;;;ACzHA,IAAM,aAAqC;AAAA,EACzC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AAEA,SAAS,OAAe;AACtB,SAAO,OAAO,WAAW;AAC3B;AAEO,IAAM,OAAN,MAAW;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EACS;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,kBAA8B,CAAC;AAAA,EAC/B,SAAS;AAAA,EACT;AAAA,EAER,YAAY,QAAoB;AAC9B,mBAAe,OAAO,MAAM;AAE5B,UAAM,WAAW,cAAc,MAAM;AACrC,SAAK,UAAU,SAAS;AACxB,SAAK,SAAS,SAAS;AACvB,SAAK,eAAe,SAAS;AAC7B,SAAK,cAAc,WAAW,SAAS,QAAQ,KAAK;AACpD,SAAK,YAAY,SAAS;AAC1B,SAAK,aAAa,SAAS;AAC3B,SAAK,gBAAgB,SAAS;AAC9B,SAAK,WAAW,KAAK;AACrB,SAAK,YAAY,KAAK;AAEtB,SAAK,YAAY,IAAI,cAAc;AAAA,MACjC,UAAU,SAAS;AAAA,MACnB,QAAQ,SAAS;AAAA,MACjB,YAAY,SAAS;AAAA,MACrB,gBAAgB,SAAS;AAAA,MACzB,MAAM,SAAS;AAAA,MACf,SAAS,KAAK;AAAA,MACd,mBAAmB,MAAM;AACvB,aAAK,aAAa,eAAe;AACjC,aAAK,WAAW,eAAe;AAC/B,aAAK,SAAS,iCAAiC;AAAA,MACjD;AAAA,IACF,CAAC;AAED,SAAK,eAAe,IAAI,QAAmB;AAAA,MACzC,MAAM,SAAS;AAAA,MACf,UAAU,SAAS;AAAA,MACnB,cAAc,SAAS;AAAA,MACvB,MAAM,CAAC,UAAU,KAAK,UAAU,WAAW,KAAK;AAAA,MAChD,YAAY,MAAM;AAChB,aAAK,SAAS,4CAA4C;AAAA,MAC5D;AAAA,IACF,CAAC;AAED,SAAK,aAAa,IAAI,QAAiB;AAAA,MACrC,MAAM,SAAS;AAAA,MACf,UAAU,SAAS;AAAA,MACnB,cAAc,SAAS;AAAA,MACvB,MAAM,CAAC,UAAU,KAAK,UAAU,SAAS,KAAK;AAAA,MAC9C,YAAY,MAAM;AAChB,aAAK,SAAS,0CAA0C;AAAA,MAC1D;AAAA,IACF,CAAC;AAED,SAAK,SAAS,yBAAyB,SAAS,QAAQ,WAAW,SAAS,SAAS,WAAW,SAAS,aAAa,KAAK;AAAA,EAC7H;AAAA;AAAA,EAIA,SAAS,YAA8B;AACrC,WAAO,OAAO,KAAK,iBAAiB,UAAU;AAAA,EAChD;AAAA,EAEA,WAAW,KAAmB;AAC5B,WAAO,KAAK,gBAAgB,GAAG;AAAA,EACjC;AAAA;AAAA,EAIA,UAAgB;AACd,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,SAAe;AACb,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA,EAIA,MAAM,QAAgB,WAAmB,YAA+B;AACtE,QAAI,KAAK,UAAW;AACpB,QAAI,KAAK,QAAQ;AAAE,WAAK,YAAY,IAAI,YAAY,CAAC;AAAG;AAAA,IAAQ;AAChE,QAAI;AACF,qBAAe,MAAM;AACrB,wBAAkB,SAAS;AAAA,IAC7B,SAAS,KAAK;AACZ,WAAK,YAAY,GAAG;AACpB;AAAA,IACF;AAEA,QAAI,QAA0B;AAAA,MAC5B,MAAM;AAAA,MACN,OAAO;AAAA,MACP,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,MACT,WAAW,KAAK,IAAI;AAAA,MACpB,YAAY,EAAE,GAAG,KAAK,iBAAiB,GAAG,WAAW;AAAA,IACvD;AAEA,QAAI,KAAK,YAAY;AACnB,cAAQ,cAAc,OAAO,KAAK,UAAU;AAC5C,UAAI,UAAU,KAAM;AAAA,IACtB;AAEA,SAAK,aAAa,IAAI,KAAK;AAAA,EAC7B;AAAA,EAEA,SAAS,QAAgB,QAA2B;AAClD,QAAI,KAAK,UAAW;AACpB,QAAI,KAAK,QAAQ;AAAE,WAAK,YAAY,IAAI,YAAY,CAAC;AAAG;AAAA,IAAQ;AAChE,QAAI;AACF,qBAAe,MAAM;AAAA,IACvB,SAAS,KAAK;AACZ,WAAK,YAAY,GAAG;AACpB;AAAA,IACF;AAEA,QAAI,QAA0B;AAAA,MAC5B,MAAM;AAAA,MACN,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,MACT,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,IACF;AAEA,QAAI,KAAK,YAAY;AACnB,cAAQ,cAAc,OAAO,KAAK,UAAU;AAC5C,UAAI,UAAU,KAAM;AAAA,IACtB;AAEA,SAAK,aAAa,IAAI,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,QAAgB,SAAiB,YAA+B;AACpE,QAAI,KAAK,UAAW;AACpB,QAAI,KAAK,QAAQ;AAAE,WAAK,YAAY,IAAI,YAAY,CAAC;AAAG;AAAA,IAAQ;AAChE,QAAI;AACF,qBAAe,MAAM;AACrB,UAAI,CAAC,QAAS,OAAM,IAAI,gBAAgB,WAAW,aAAa;AAAA,IAClE,SAAS,KAAK;AACZ,WAAK,YAAY,GAAG;AACpB;AAAA,IACF;AAEA,QAAI,QAA0B;AAAA,MAC5B,MAAM;AAAA,MACN,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,MACT,UAAU;AAAA,MACV,WAAW,KAAK,IAAI;AAAA,MACpB,YAAY,EAAE,GAAG,KAAK,iBAAiB,GAAG,WAAW;AAAA,IACvD;AAEA,QAAI,KAAK,YAAY;AACnB,cAAQ,cAAc,OAAO,KAAK,UAAU;AAC5C,UAAI,UAAU,KAAM;AAAA,IACtB;AAEA,SAAK,aAAa,IAAI,KAAK;AAAA,EAC7B;AAAA,EAEA,QACE,QACA,QACA,UACA,SACA,YACM;AACN,QAAI,KAAK,UAAW;AACpB,QAAI,KAAK,QAAQ;AAAE,WAAK,YAAY,IAAI,YAAY,CAAC;AAAG;AAAA,IAAQ;AAChE,QAAI;AACF,qBAAe,MAAM;AACrB,UAAI,UAAU,EAAG,OAAM,IAAI,gBAAgB,UAAU,kBAAkB;AACvE,UAAI,CAAC,SAAU,OAAM,IAAI,gBAAgB,YAAY,aAAa;AAClE,UAAI,CAAC,QAAS,OAAM,IAAI,gBAAgB,WAAW,aAAa;AAAA,IAClE,SAAS,KAAK;AACZ,WAAK,YAAY,GAAG;AACpB;AAAA,IACF;AAEA,QAAI,QAA0B;AAAA,MAC5B,MAAM;AAAA,MACN,OAAO;AAAA,MACP,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,MACT,WAAW,KAAK,IAAI;AAAA,MACpB,YAAY;AAAA,QACV,GAAG,KAAK;AAAA,QACR,GAAG;AAAA,QACH,UAAU;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,YAAY;AACnB,cAAQ,cAAc,OAAO,KAAK,UAAU;AAC5C,UAAI,UAAU,KAAM;AAAA,IACtB;AAEA,SAAK,aAAa,IAAI,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,YAAoB,QAAsB;AAC9C,QAAI,KAAK,UAAW;AACpB,QAAI,KAAK,QAAQ;AAAE,WAAK,YAAY,IAAI,YAAY,CAAC;AAAG;AAAA,IAAQ;AAChE,QAAI;AACF,UAAI,CAAC,WAAY,OAAM,IAAI,gBAAgB,cAAc,aAAa;AACtE,qBAAe,MAAM;AAAA,IACvB,SAAS,KAAK;AACZ,WAAK,YAAY,GAAG;AACpB;AAAA,IACF;AAEA,QAAI,QAA0B;AAAA,MAC5B,MAAM;AAAA,MACN,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,MACT,WAAW,KAAK,IAAI;AAAA,MACpB,YAAY,EAAE,aAAa,WAAW;AAAA,IACxC;AAEA,QAAI,KAAK,YAAY;AACnB,cAAQ,cAAc,OAAO,KAAK,UAAU;AAC5C,UAAI,UAAU,KAAM;AAAA,IACtB;AAEA,SAAK,aAAa,IAAI,KAAK;AAAA,EAC7B;AAAA,EAEA,eAAqB;AACnB,SAAK,YAAY,KAAK;AAAA,EACxB;AAAA;AAAA,EAIA,IAAI,OAAiB,SAAiB,SAAkB,MAAyB;AAC/E,QAAI,KAAK,UAAW;AACpB,QAAI,KAAK,QAAQ;AAAE,WAAK,YAAY,IAAI,YAAY,CAAC;AAAG;AAAA,IAAQ;AAChE,QAAI;AACF,yBAAmB,OAAO;AAAA,IAC5B,SAAS,KAAK;AACZ,WAAK,YAAY,GAAG;AACpB;AAAA,IACF;AAEA,QAAI,WAA2B;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,SAAS,WAAW;AAAA,MACpB,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,IACF;AAEA,QAAI,KAAK,eAAe;AACtB,iBAAW,cAAc,UAAU,KAAK,aAAa;AACrD,UAAI,aAAa,KAAM;AAAA,IACzB;AAEA,SAAK,WAAW,IAAI,QAAQ;AAAA,EAC9B;AAAA,EAEA,aAAa,SAAiB,SAAkB,MAAyB;AACvE,SAAK,IAAI,aAAa,SAAS,SAAS,IAAI;AAAA,EAC9C;AAAA,EACA,SAAS,SAAiB,SAAkB,MAAyB;AACnE,SAAK,IAAI,SAAS,SAAS,SAAS,IAAI;AAAA,EAC1C;AAAA,EACA,YAAY,SAAiB,SAAkB,MAAyB;AACtE,SAAK,IAAI,YAAY,SAAS,SAAS,IAAI;AAAA,EAC7C;AAAA,EACA,SAAS,SAAiB,SAAkB,MAAyB;AACnE,SAAK,IAAI,SAAS,SAAS,SAAS,IAAI;AAAA,EAC1C;AAAA,EACA,WAAW,SAAiB,SAAkB,MAAyB;AACrE,SAAK,IAAI,WAAW,SAAS,SAAS,IAAI;AAAA,EAC5C;AAAA,EACA,UAAU,SAAiB,SAAkB,MAAyB;AACpE,SAAK,IAAI,UAAU,SAAS,SAAS,IAAI;AAAA,EAC3C;AAAA,EACA,QAAQ,SAAiB,SAAkB,MAAyB;AAClE,SAAK,IAAI,QAAQ,SAAS,SAAS,IAAI;AAAA,EACzC;AAAA,EACA,SAAS,SAAiB,SAAkB,MAAyB;AACnE,SAAK,IAAI,SAAS,SAAS,SAAS,IAAI;AAAA,EAC1C;AAAA,EACA,SAAS,SAAiB,SAAkB,MAAyB;AACnE,SAAK,IAAI,SAAS,SAAS,SAAS,IAAI;AAAA,EAC1C;AAAA;AAAA,EAIA,MAAM,QAAuB;AAC3B,UAAM,QAAQ,IAAI,CAAC,KAAK,aAAa,MAAM,GAAG,KAAK,WAAW,MAAM,CAAC,CAAC;AAAA,EACxE;AAAA,EAEA,MAAM,QAAuB;AAC3B,QAAI,KAAK,OAAQ;AACjB,SAAK,SAAS;AACd,SAAK,SAAS,YAAY;AAC1B,UAAM,OAAO,QAAQ,IAAI,CAAC,KAAK,aAAa,MAAM,GAAG,KAAK,WAAW,MAAM,CAAC,CAAC;AAC7E,UAAM,UAAU,IAAI;AAAA,MAAe,CAAC,GAAG,WACrC,WAAW,MAAM,OAAO,IAAI,MAAM,iBAAiB,CAAC,GAAG,KAAK,YAAY;AAAA,IAC1E;AACA,QAAI;AACF,YAAM,QAAQ,KAAK,CAAC,MAAM,OAAO,CAAC;AAAA,IACpC,SAAS,KAAK;AACZ,WAAK,YAAY,GAAG;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAIQ,YAAY,KAAoB;AACtC,QAAI,KAAK,WAAW,eAAe,OAAO;AACxC,WAAK,QAAQ,GAAG;AAAA,IAClB;AAAA,EACF;AAAA,EAEQ,SAAS,KAAmB;AAClC,QAAI,KAAK,eAAe,WAAW,OAAO;AACxC,cAAQ,MAAM,UAAU,GAAG,EAAE;AAAA,IAC/B;AAAA,EACF;AACF;","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
+ }