@justanalyticsapp/node 0.1.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.
Files changed (52) hide show
  1. package/dist/client.d.ts +286 -0
  2. package/dist/client.js +681 -0
  3. package/dist/client.js.map +1 -0
  4. package/dist/context.d.ts +126 -0
  5. package/dist/context.js +170 -0
  6. package/dist/context.js.map +1 -0
  7. package/dist/errors.d.ts +135 -0
  8. package/dist/errors.js +180 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/index.d.ts +301 -0
  11. package/dist/index.js +314 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/integrations/express.d.ts +77 -0
  14. package/dist/integrations/express.js +87 -0
  15. package/dist/integrations/express.js.map +1 -0
  16. package/dist/integrations/http.d.ts +129 -0
  17. package/dist/integrations/http.js +465 -0
  18. package/dist/integrations/http.js.map +1 -0
  19. package/dist/integrations/metrics.d.ts +110 -0
  20. package/dist/integrations/metrics.js +313 -0
  21. package/dist/integrations/metrics.js.map +1 -0
  22. package/dist/integrations/next.d.ts +252 -0
  23. package/dist/integrations/next.js +480 -0
  24. package/dist/integrations/next.js.map +1 -0
  25. package/dist/integrations/pg.d.ts +169 -0
  26. package/dist/integrations/pg.js +616 -0
  27. package/dist/integrations/pg.js.map +1 -0
  28. package/dist/integrations/pino.d.ts +52 -0
  29. package/dist/integrations/pino.js +153 -0
  30. package/dist/integrations/pino.js.map +1 -0
  31. package/dist/integrations/redis.d.ts +190 -0
  32. package/dist/integrations/redis.js +597 -0
  33. package/dist/integrations/redis.js.map +1 -0
  34. package/dist/integrations/winston.d.ts +48 -0
  35. package/dist/integrations/winston.js +99 -0
  36. package/dist/integrations/winston.js.map +1 -0
  37. package/dist/logger.d.ts +148 -0
  38. package/dist/logger.js +162 -0
  39. package/dist/logger.js.map +1 -0
  40. package/dist/span.d.ts +192 -0
  41. package/dist/span.js +197 -0
  42. package/dist/span.js.map +1 -0
  43. package/dist/transport.d.ts +246 -0
  44. package/dist/transport.js +654 -0
  45. package/dist/transport.js.map +1 -0
  46. package/dist/utils/headers.d.ts +60 -0
  47. package/dist/utils/headers.js +93 -0
  48. package/dist/utils/headers.js.map +1 -0
  49. package/dist/utils/id.d.ts +23 -0
  50. package/dist/utils/id.js +36 -0
  51. package/dist/utils/id.js.map +1 -0
  52. package/package.json +65 -0
package/dist/span.js ADDED
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ /**
3
+ * @file packages/node-sdk/src/span.ts
4
+ * @description Span class for distributed tracing with high-resolution timing.
5
+ *
6
+ * Implements Story 035 - Node.js SDK Core
7
+ *
8
+ * Each Span records a timed operation within a trace. Spans are created by
9
+ * `JA.startSpan()` and automatically ended when the callback completes.
10
+ * The `toJSON()` method serializes the span to the exact format expected by
11
+ * `POST /api/ingest/spans` (see the Zod schema in route.ts).
12
+ *
13
+ * Timing uses `process.hrtime.bigint()` for nanosecond-resolution monotonic
14
+ * measurement, then converts to integer milliseconds via Math.round.
15
+ *
16
+ * References:
17
+ * - src/app/api/ingest/spans/route.ts (Zod schema the payload must match)
18
+ * - W3C Trace Context (traceId/spanId format)
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.Span = void 0;
22
+ const id_1 = require("./utils/id");
23
+ /**
24
+ * Span represents a single timed operation within a distributed trace.
25
+ *
26
+ * Spans are created by `JA.startSpan()` and ended either automatically
27
+ * when the callback completes, or manually via `span.end()`.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * JA.startSpan('process-order', (span) => {
32
+ * span.setAttribute('order.id', '12345');
33
+ * span.addEvent('payment.processed');
34
+ * // span.end() is called automatically
35
+ * });
36
+ * ```
37
+ */
38
+ class Span {
39
+ constructor(params) {
40
+ this._endTime = null;
41
+ this._duration = null;
42
+ this._status = 'unset';
43
+ this._statusMessage = null;
44
+ this._events = [];
45
+ this._ended = false;
46
+ this.id = (0, id_1.generateSpanId)();
47
+ this.traceId = params.traceId;
48
+ this.parentSpanId = params.parentSpanId;
49
+ this.operationName = params.operationName;
50
+ this.serviceName = params.serviceName;
51
+ this.kind = params.kind;
52
+ this.startTime = new Date();
53
+ this.startHrTime = process.hrtime.bigint();
54
+ this._attributes = { ...(params.attributes || {}) };
55
+ }
56
+ /**
57
+ * Set a single attribute on the span.
58
+ *
59
+ * @param key - Attribute key (e.g. "http.method", "db.statement")
60
+ * @param value - Attribute value
61
+ * @returns this (for chaining)
62
+ */
63
+ setAttribute(key, value) {
64
+ if (this._ended)
65
+ return this;
66
+ this._attributes[key] = value;
67
+ return this;
68
+ }
69
+ /**
70
+ * Set multiple attributes on the span.
71
+ *
72
+ * @param attrs - Key-value pairs to merge into attributes
73
+ * @returns this (for chaining)
74
+ */
75
+ setAttributes(attrs) {
76
+ if (this._ended)
77
+ return this;
78
+ Object.assign(this._attributes, attrs);
79
+ return this;
80
+ }
81
+ /**
82
+ * Set the span's status.
83
+ *
84
+ * @param status - One of 'ok', 'error', 'unset'
85
+ * @param message - Optional status message (typically for errors)
86
+ * @returns this (for chaining)
87
+ */
88
+ setStatus(status, message) {
89
+ if (this._ended)
90
+ return this;
91
+ this._status = status;
92
+ this._statusMessage = message ?? null;
93
+ return this;
94
+ }
95
+ /**
96
+ * Add a timestamped event to the span.
97
+ *
98
+ * Events represent notable moments during the span's lifetime
99
+ * (e.g. "cache.miss", "retry.attempt", "payment.processed").
100
+ *
101
+ * @param name - Event name
102
+ * @param attributes - Optional event attributes
103
+ * @returns this (for chaining)
104
+ */
105
+ addEvent(name, attributes) {
106
+ if (this._ended)
107
+ return this;
108
+ const event = {
109
+ name,
110
+ timestamp: new Date().toISOString(),
111
+ };
112
+ if (attributes) {
113
+ event.attributes = attributes;
114
+ }
115
+ this._events.push(event);
116
+ return this;
117
+ }
118
+ /**
119
+ * Update the operation name after span creation.
120
+ *
121
+ * Used by auto-instrumentation integrations to refine the operation name
122
+ * after additional context is available (e.g., Express route matching
123
+ * provides `/api/users/:id` instead of the raw URL `/api/users/42`).
124
+ *
125
+ * No-op if the span has already ended.
126
+ *
127
+ * @param name - The new operation name
128
+ * @returns this (for chaining)
129
+ */
130
+ updateOperationName(name) {
131
+ if (this._ended)
132
+ return this;
133
+ this.operationName = name;
134
+ return this;
135
+ }
136
+ /**
137
+ * Mark the span as ended.
138
+ *
139
+ * Calculates duration using `process.hrtime.bigint()` for sub-millisecond
140
+ * precision, then rounds to an integer millisecond value to match the
141
+ * server's `z.number().int()` Zod validation.
142
+ *
143
+ * Calling `end()` multiple times is a no-op (idempotent).
144
+ */
145
+ end() {
146
+ if (this._ended)
147
+ return;
148
+ this._ended = true;
149
+ this._endTime = new Date();
150
+ const endHrTime = process.hrtime.bigint();
151
+ // Convert nanoseconds to integer milliseconds
152
+ this._duration = Math.round(Number(endHrTime - this.startHrTime) / 1000000);
153
+ }
154
+ /** Whether this span has been ended */
155
+ get isEnded() {
156
+ return this._ended;
157
+ }
158
+ /**
159
+ * Serialize the span to the JSON payload format expected by
160
+ * `POST /api/ingest/spans`.
161
+ *
162
+ * The output matches the Zod schema defined in
163
+ * `src/app/api/ingest/spans/route.ts` exactly:
164
+ * - `id`: 16-char hex
165
+ * - `traceId`: 32-char hex
166
+ * - `parentSpanId`: 16-char hex or null
167
+ * - `operationName`: string (1-256 chars)
168
+ * - `serviceName`: string (1-128 chars)
169
+ * - `kind`: one of the SpanKind values
170
+ * - `startTime`: ISO 8601 string
171
+ * - `endTime`: ISO 8601 string or null
172
+ * - `duration`: integer milliseconds or null
173
+ * - `status`: one of the SpanStatus values
174
+ * - `statusMessage`: string or null
175
+ * - `attributes`: object
176
+ * - `events`: array of event objects
177
+ */
178
+ toJSON() {
179
+ return {
180
+ id: this.id,
181
+ traceId: this.traceId,
182
+ parentSpanId: this.parentSpanId,
183
+ operationName: this.operationName,
184
+ serviceName: this.serviceName,
185
+ kind: this.kind,
186
+ startTime: this.startTime.toISOString(),
187
+ endTime: this._endTime ? this._endTime.toISOString() : null,
188
+ duration: this._duration,
189
+ status: this._status,
190
+ statusMessage: this._statusMessage,
191
+ attributes: { ...this._attributes },
192
+ events: [...this._events],
193
+ };
194
+ }
195
+ }
196
+ exports.Span = Span;
197
+ //# sourceMappingURL=span.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"span.js","sourceRoot":"","sources":["../src/span.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * @file packages/node-sdk/src/transport.ts
3
+ * @description Batched HTTP transport for sending span and error data to the JustAnalytics server.
4
+ *
5
+ * Implements Story 035 - Node.js SDK Core
6
+ * Updated for Story 041 - Server-Side Error Tracking via SDK
7
+ * Updated for Story 046 - SDK Log Integration
8
+ * Updated for Story 048 - Infrastructure Metrics Collection
9
+ *
10
+ * The BatchTransport collects ended spans, error events, log entries, and
11
+ * infrastructure metrics in separate in-memory buffers and periodically
12
+ * flushes them to their respective endpoints:
13
+ * - Spans: `POST /api/ingest/spans` (batched, 1-100 per request)
14
+ * - Errors: `POST /api/ingest/errors` (individual, one per request)
15
+ * - Logs: `POST /api/ingest/logs` (batched, 1-100 per request)
16
+ * - Metrics: `POST /api/ingest/metrics` (batched, 1-500 per request)
17
+ *
18
+ * It uses Node.js built-in `http`/`https` modules (not fetch, not axios)
19
+ * for maximum compatibility with Node.js 18+.
20
+ *
21
+ * Flush behavior:
22
+ * - Timer-based: flushes every `flushIntervalMs` milliseconds (default: 2000)
23
+ * - Size-based: flushes immediately when buffer reaches `maxBatchSize` (default: 100)
24
+ * - Manual: `flush()` can be called explicitly
25
+ *
26
+ * Error handling:
27
+ * - HTTP 429 (rate limited): doubles flush interval for 60 seconds, then resets
28
+ * - Network errors / non-2xx: logs warning (in debug mode), drops the batch
29
+ * - Never throws unhandled exceptions that could crash the host process
30
+ *
31
+ * References:
32
+ * - src/app/api/ingest/spans/route.ts (target endpoint and expected payload format)
33
+ * - src/app/api/ingest/errors/route.ts (error ingestion endpoint)
34
+ */
35
+ import { SpanPayload } from './span';
36
+ import { ServerErrorPayload } from './errors';
37
+ import { LogPayload } from './logger';
38
+ import { MetricPayload } from './integrations/metrics';
39
+ /** Configuration options for BatchTransport */
40
+ export interface TransportOptions {
41
+ /** Base URL of the JustAnalytics server */
42
+ serverUrl: string;
43
+ /** API key for authentication */
44
+ apiKey: string;
45
+ /** Flush interval in milliseconds */
46
+ flushIntervalMs: number;
47
+ /** Maximum spans per batch before immediate flush */
48
+ maxBatchSize: number;
49
+ /** Enable debug logging */
50
+ debug: boolean;
51
+ }
52
+ /**
53
+ * BatchTransport collects spans and errors in memory and sends them
54
+ * in batches to the JustAnalytics ingestion endpoints.
55
+ *
56
+ * Uses Node.js built-in `http`/`https` modules for HTTP communication.
57
+ * Implements timer-based and size-based flushing with 429 backoff.
58
+ */
59
+ export declare class BatchTransport {
60
+ private buffer;
61
+ private errorBuffer;
62
+ private logBuffer;
63
+ private metricBuffer;
64
+ private readonly flushIntervalMs;
65
+ private readonly maxBatchSize;
66
+ private readonly serverUrl;
67
+ private readonly apiKey;
68
+ private readonly debug;
69
+ private timer;
70
+ /** Independent flushing guards for spans, errors, logs, and metrics */
71
+ private isFlushingSpans;
72
+ private isFlushingErrors;
73
+ private isFlushingLogs;
74
+ private isFlushingMetrics;
75
+ /** Original flush interval for resetting after 429 backoff */
76
+ private readonly originalFlushIntervalMs;
77
+ /** Current effective flush interval (may be doubled during backoff) */
78
+ private currentFlushIntervalMs;
79
+ /** Timer for resetting flush interval after 429 backoff */
80
+ private backoffResetTimer;
81
+ constructor(options: TransportOptions);
82
+ /**
83
+ * Enqueue a span payload for batched sending.
84
+ *
85
+ * If the buffer reaches `maxBatchSize`, triggers an immediate flush.
86
+ *
87
+ * @param span - Serialized span payload to enqueue
88
+ */
89
+ enqueue(span: SpanPayload): void;
90
+ /**
91
+ * Enqueue an error event payload for batched sending.
92
+ * Errors are flushed alongside spans on the periodic timer.
93
+ *
94
+ * @param payload - Error event payload to enqueue
95
+ */
96
+ enqueueError(payload: ServerErrorPayload): void;
97
+ /**
98
+ * Enqueue a log entry payload for batched sending.
99
+ * Logs are flushed alongside spans and errors on the periodic timer.
100
+ *
101
+ * If the buffer reaches `maxBatchSize`, triggers an immediate flush.
102
+ *
103
+ * @param entry - Log entry payload to enqueue
104
+ */
105
+ enqueueLog(entry: LogPayload): void;
106
+ /**
107
+ * Enqueue an infrastructure metric payload for batched sending.
108
+ * Metrics are flushed alongside spans, errors, and logs on the periodic timer.
109
+ *
110
+ * If the buffer reaches `maxBatchSize`, triggers an immediate flush.
111
+ *
112
+ * @param metric - Metric data point payload to enqueue
113
+ */
114
+ enqueueMetric(metric: MetricPayload): void;
115
+ /**
116
+ * Send a single error immediately (non-batched).
117
+ * Used for uncaughtException where the process is about to exit.
118
+ *
119
+ * Fire-and-forget: the promise result is intentionally not awaited
120
+ * by the caller because the process is exiting.
121
+ *
122
+ * @param payload - Error event payload to send immediately
123
+ */
124
+ sendErrorImmediate(payload: ServerErrorPayload): void;
125
+ /**
126
+ * Flush all pending spans and errors to the server.
127
+ *
128
+ * Delegates to `flushSpans()` and `flushErrors()` in parallel.
129
+ * Each sub-method has its own isFlushing guard.
130
+ *
131
+ * @returns Promise that resolves when both flushes complete
132
+ */
133
+ flush(): Promise<void>;
134
+ /**
135
+ * Flush all pending span payloads to `POST /api/ingest/spans`.
136
+ *
137
+ * Sends all buffered spans in a single HTTP request.
138
+ * The buffer is cleared before sending, so new spans that arrive
139
+ * during the flush are queued for the next flush.
140
+ *
141
+ * @returns Promise that resolves when the flush completes (or fails)
142
+ */
143
+ private flushSpans;
144
+ /**
145
+ * Flush all pending error event payloads to `POST /api/ingest/errors`.
146
+ *
147
+ * Each error is sent as an individual POST request because the server-side
148
+ * fingerprinting and upsert logic operates on individual events.
149
+ *
150
+ * @returns Promise that resolves when all errors are sent (or dropped)
151
+ */
152
+ flushErrors(): Promise<void>;
153
+ /**
154
+ * Start the periodic flush timer.
155
+ *
156
+ * Uses `setInterval` with the current effective flush interval.
157
+ * The timer is `unref()`'d so it does not keep the process alive.
158
+ */
159
+ start(): void;
160
+ /**
161
+ * Stop the periodic flush timer.
162
+ */
163
+ stop(): void;
164
+ /**
165
+ * Number of spans currently in the buffer awaiting flush.
166
+ */
167
+ get pendingCount(): number;
168
+ /**
169
+ * Number of errors currently in the error buffer awaiting flush.
170
+ */
171
+ get pendingErrorCount(): number;
172
+ /**
173
+ * Number of log entries currently in the buffer awaiting flush.
174
+ */
175
+ get pendingLogCount(): number;
176
+ /**
177
+ * Number of metrics currently in the buffer awaiting flush.
178
+ */
179
+ get pendingMetricCount(): number;
180
+ /**
181
+ * Send a batch of spans via HTTP POST to /api/ingest/spans.
182
+ *
183
+ * Uses Node.js built-in `http` or `https` module based on the server URL
184
+ * protocol. Handles HTTP 429 with backoff.
185
+ *
186
+ * @param batch - Array of span payloads to send
187
+ */
188
+ private sendBatch;
189
+ /**
190
+ * Send a batch of error events via HTTP POST.
191
+ * Each error is sent as an individual POST to /api/ingest/errors
192
+ * because the server-side fingerprinting and upsert logic operates
193
+ * on individual events.
194
+ *
195
+ * @param batch - Array of error payloads to send
196
+ */
197
+ private sendErrorBatch;
198
+ /**
199
+ * Send a single error event via HTTP POST to /api/ingest/errors.
200
+ *
201
+ * @param payload - Error event payload to send
202
+ */
203
+ private sendSingleError;
204
+ /**
205
+ * Flush all pending log entry payloads to POST /api/ingest/logs.
206
+ *
207
+ * Sends all buffered logs in a single HTTP POST request.
208
+ * The buffer is cleared before sending, so new logs that arrive
209
+ * during the flush are queued for the next flush.
210
+ *
211
+ * @returns Promise that resolves when the flush completes (or fails)
212
+ */
213
+ private flushLogs;
214
+ /**
215
+ * Send a batch of log entries via HTTP POST to /api/ingest/logs.
216
+ *
217
+ * Uses Node.js built-in `http`/`https` module based on the server URL
218
+ * protocol. Handles HTTP 429 with backoff.
219
+ *
220
+ * @param batch - Array of log entry payloads to send
221
+ */
222
+ private sendLogBatch;
223
+ /**
224
+ * Flush all pending metric payloads to POST /api/ingest/metrics.
225
+ *
226
+ * Sends all buffered metrics in a single HTTP POST request.
227
+ * The buffer is cleared before sending, so new metrics that arrive
228
+ * during the flush are queued for the next flush.
229
+ *
230
+ * @returns Promise that resolves when the flush completes (or fails)
231
+ */
232
+ private flushMetrics;
233
+ /**
234
+ * Send a batch of metrics via HTTP POST to /api/ingest/metrics.
235
+ *
236
+ * Uses Node.js built-in `http`/`https` module based on the server URL
237
+ * protocol. Handles HTTP 429 with backoff.
238
+ *
239
+ * @param batch - Array of metric payloads to send
240
+ */
241
+ private sendMetricBatch;
242
+ /**
243
+ * Handle HTTP 429 backoff: double the flush interval for 60 seconds, then reset.
244
+ */
245
+ private handleBackoff;
246
+ }