@chirpier/chirpier-js 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,7 +21,8 @@ import { initialize, logEvent, stop } from "@chirpier/chirpier-js";
21
21
  initialize({ key: "chp_your_api_key" });
22
22
 
23
23
  await logEvent({
24
- agent_id: "openclaw.main",
24
+ log_id: "9f97d65f-fb30-4062-b4d0-8617c03fe4f6",
25
+ agent: "openclaw.main",
25
26
  event: "tool.errors.count",
26
27
  value: 1,
27
28
  meta: { tool_name: "browser.open", workflow: "triage" },
@@ -38,7 +39,7 @@ import { createClient } from "@chirpier/chirpier-js";
38
39
  const client = createClient({ key: "chp_your_api_key" });
39
40
 
40
41
  await client.log({
41
- agent_id: "openclaw.main",
42
+ agent: "openclaw.main",
42
43
  event: "task.duration_ms",
43
44
  value: 420,
44
45
  meta: { task_name: "email_triage", result: "success" },
@@ -64,7 +65,7 @@ Initializes the SDK singleton.
64
65
  - `timeout` (number, optional): HTTP timeout in ms.
65
66
  - `batchSize` (number, optional): Flush size threshold.
66
67
  - `flushDelay` (number, optional): Flush interval in ms.
67
- - `maxQueueSize` (number, optional): In-memory queue capacity.
68
+ - `maxQueueSize` (number, optional, deprecated): Ignored; queues grow in memory until flushed.
68
69
 
69
70
  API key resolution precedence (when `key` is omitted):
70
71
  1. `CHIRPIER_API_KEY` from process environment
@@ -73,6 +74,7 @@ API key resolution precedence (when `key` is omitted):
73
74
  Default ingest endpoint is `https://logs.chirpier.co/v1.0/logs`.
74
75
  Default servicer endpoint is `https://api.chirpier.co/v1.0`.
75
76
  The same bearer token is used for both ingest and servicer APIs.
77
+ Queued logs are not dropped locally because of queue capacity or retry exhaustion.
76
78
 
77
79
  ### `logEvent(log)`
78
80
 
@@ -82,7 +84,7 @@ Example with `occurred_at`:
82
84
 
83
85
  ```ts
84
86
  await logEvent({
85
- agent_id: "openclaw.main",
87
+ agent: "openclaw.main",
86
88
  event: "tokens.used",
87
89
  value: 1530,
88
90
  occurred_at: "2026-03-05T14:30:00Z",
@@ -90,14 +92,16 @@ await logEvent({
90
92
  ```
91
93
 
92
94
  `log`:
93
- - `agent_id` (string, optional): Free-form agent identifier text.
95
+ - `agent` (string, optional): Free-form agent identifier text.
96
+ - `log_id` (string, optional): UUID idempotency key for the log. Generated automatically when omitted.
94
97
  - `event` (string, required): Event name.
95
98
  - `value` (number, required): Numeric value.
96
99
  - `occurred_at` (string | Date, optional): Event occurrence timestamp.
97
100
  - `meta` (JSON, optional): Additional JSON-encodable metadata.
98
101
 
99
102
  Notes:
100
- - `agent_id` whitespace-only values are treated as omitted.
103
+ - `agent` whitespace-only values are treated as omitted.
104
+ - `log_id` blank values are treated as omitted and replaced with a generated UUIDv4.
101
105
  - `event` must be non-empty after trimming.
102
106
  - `occurred_at` must be within the last 30 days and no more than 1 day in the future.
103
107
  - Use ISO8601 UTC timestamps, such as `2026-03-05T14:30:00Z`, or pass a `Date` instance.
@@ -138,14 +142,14 @@ Client methods:
138
142
  const client = createClient({ key: "chp_your_api_key" });
139
143
 
140
144
  await client.log({
141
- agent_id: "openclaw.main",
145
+ agent: "openclaw.main",
142
146
  event: "tool.errors.count",
143
147
  value: 1,
144
148
  meta: { tool_name: "browser.open" },
145
149
  });
146
150
 
147
151
  await client.log({
148
- agent_id: "openclaw.main",
152
+ agent: "openclaw.main",
149
153
  event: "task.duration_ms",
150
154
  value: 780,
151
155
  meta: { task_name: "daily_digest" },
@@ -9,8 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
14
  function verb(n) { return function (v) { return step([n, v]); }; }
15
15
  function step(op) {
16
16
  if (f) throw new TypeError("Generator is already executing.");
@@ -190,7 +190,7 @@ describe("Chirpier SDK", function () {
190
190
  logLevel: 0 /* LogLevel.None */,
191
191
  });
192
192
  log = {
193
- agent_id: "api.worker",
193
+ agent: "api.worker",
194
194
  event: "request.finished",
195
195
  value: 1,
196
196
  };
@@ -204,16 +204,45 @@ describe("Chirpier SDK", function () {
204
204
  expect(mock.history.post[0].url).toBe(constants_1.DEFAULT_API_ENDPOINT);
205
205
  expect(JSON.parse(mock.history.post[0].data)).toEqual([
206
206
  {
207
- agent_id: "api.worker",
207
+ log_id: expect.any(String),
208
+ agent: "api.worker",
208
209
  event: "request.finished",
209
210
  value: 1,
210
211
  },
211
212
  ]);
213
+ expect(JSON.parse(mock.history.post[0].data)[0].log_id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
212
214
  return [2 /*return*/];
213
215
  }
214
216
  });
215
217
  }); });
216
- test("agent_id whitespace should be omitted", function () { return __awaiter(void 0, void 0, void 0, function () {
218
+ test("should preserve provided log_id", function () { return __awaiter(void 0, void 0, void 0, function () {
219
+ var mock, payload;
220
+ return __generator(this, function (_a) {
221
+ switch (_a.label) {
222
+ case 0:
223
+ mock = new axios_mock_adapter_1.default(axios_1.default);
224
+ mock.onPost(constants_1.DEFAULT_API_ENDPOINT).reply(200, { success: true });
225
+ (0, index_1.initialize)({
226
+ key: "chp_log_id_key",
227
+ logLevel: 0 /* LogLevel.None */,
228
+ });
229
+ return [4 /*yield*/, (0, index_1.logEvent)({
230
+ log_id: "9f97d65f-fb30-4062-b4d0-8617c03fe4f6",
231
+ event: "request.finished",
232
+ value: 1,
233
+ })];
234
+ case 1:
235
+ _a.sent();
236
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })];
237
+ case 2:
238
+ _a.sent();
239
+ payload = JSON.parse(mock.history.post[0].data);
240
+ expect(payload[0].log_id).toBe("9f97d65f-fb30-4062-b4d0-8617c03fe4f6");
241
+ return [2 /*return*/];
242
+ }
243
+ });
244
+ }); });
245
+ test("agent whitespace should be omitted", function () { return __awaiter(void 0, void 0, void 0, function () {
217
246
  var mock, payload;
218
247
  return __generator(this, function (_a) {
219
248
  switch (_a.label) {
@@ -225,7 +254,7 @@ describe("Chirpier SDK", function () {
225
254
  logLevel: 0 /* LogLevel.None */,
226
255
  });
227
256
  return [4 /*yield*/, (0, index_1.logEvent)({
228
- agent_id: " ",
257
+ agent: " ",
229
258
  event: "metric.tick",
230
259
  value: 42,
231
260
  })];
@@ -235,7 +264,7 @@ describe("Chirpier SDK", function () {
235
264
  case 2:
236
265
  _a.sent();
237
266
  payload = JSON.parse(mock.history.post[0].data);
238
- expect(payload[0].agent_id).toBeUndefined();
267
+ expect(payload[0].agent).toBeUndefined();
239
268
  return [2 /*return*/];
240
269
  }
241
270
  });
@@ -252,7 +281,7 @@ describe("Chirpier SDK", function () {
252
281
  logLevel: 0 /* LogLevel.None */,
253
282
  });
254
283
  return [4 /*yield*/, (0, index_1.logEvent)({
255
- agent_id: "api.worker",
284
+ agent: "api.worker",
256
285
  event: "request.finished",
257
286
  value: 200,
258
287
  meta: {
@@ -329,6 +358,13 @@ describe("Chirpier SDK", function () {
329
358
  occurred_at: new Date(Date.now() + 25 * 60 * 60 * 1000),
330
359
  })).rejects.toThrow(index_1.ChirpierError)];
331
360
  case 3:
361
+ _a.sent();
362
+ return [4 /*yield*/, expect((0, index_1.logEvent)({
363
+ log_id: "not-a-uuid",
364
+ event: "bad-log-id",
365
+ value: 1,
366
+ })).rejects.toThrow(index_1.ChirpierError)];
367
+ case 4:
332
368
  _a.sent();
333
369
  expect(mock.history.post.length).toBe(0);
334
370
  return [2 /*return*/];
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,IAAc,CAAC;AAC3C,eAAO,MAAM,eAAe,MAAgB,CAAC;AAC7C,eAAO,MAAM,kBAAkB,KAAe,CAAC;AAC/C,eAAO,MAAM,mBAAmB,KAAe,CAAC;AAChD,eAAO,MAAM,cAAc,MAAgB,CAAC;AAC5C,eAAO,MAAM,oBAAoB,sCAAgD,CAAC;AAClF,eAAO,MAAM,yBAAyB,gCAA0C,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,EAAG,EAAW,CAAC;AAC3C,eAAO,MAAM,eAAe,EAAG,IAAa,CAAC;AAC7C,eAAO,MAAM,kBAAkB,EAAG,GAAY,CAAC;AAC/C,eAAO,MAAM,mBAAmB,EAAG,GAAY,CAAC;AAChD,eAAO,MAAM,cAAc,EAAG,IAAa,CAAC;AAC5C,eAAO,MAAM,oBAAoB,EAAG,oCAA6C,CAAC;AAClF,eAAO,MAAM,yBAAyB,EAAG,8BAAuC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export interface Config {
13
13
  timeout?: number;
14
14
  batchSize?: number;
15
15
  flushDelay?: number;
16
+ /** @deprecated Queues are unbounded in memory. */
16
17
  maxQueueSize?: number;
17
18
  }
18
19
  /**
@@ -20,25 +21,22 @@ export interface Config {
20
21
  */
21
22
  export type Options = Config;
22
23
  export interface Log {
23
- agent_id?: string;
24
+ log_id?: string;
25
+ agent?: string;
24
26
  event: string;
25
27
  value: number;
26
28
  meta?: unknown;
27
29
  occurred_at?: string | Date;
28
30
  }
29
- export interface EventDefinition {
31
+ export interface Event {
30
32
  readonly event_id: string;
31
- readonly agent_id?: string;
33
+ readonly agent?: string;
32
34
  readonly event: string;
33
35
  readonly title?: string;
34
36
  readonly public: boolean;
35
37
  readonly description?: string;
36
38
  readonly unit?: string;
37
- readonly semantic_class: string;
38
- readonly default_aggregate: string;
39
- readonly enabled: boolean;
40
- readonly origin: string;
41
- readonly archived_at?: string;
39
+ readonly timezone: string;
42
40
  readonly created_at?: string;
43
41
  }
44
42
  export interface Policy {
@@ -58,7 +56,7 @@ export interface Alert {
58
56
  readonly alert_id: string;
59
57
  readonly policy_id: string;
60
58
  readonly event_id: string;
61
- readonly agent_id?: string;
59
+ readonly agent?: string;
62
60
  readonly event: string;
63
61
  readonly title: string;
64
62
  readonly period: string;
@@ -88,7 +86,7 @@ export interface AlertDelivery {
88
86
  }
89
87
  export interface EventLogPoint {
90
88
  readonly event_id: string;
91
- readonly agent_id?: string;
89
+ readonly agent?: string;
92
90
  readonly event: string;
93
91
  readonly period: string;
94
92
  readonly occurred_at: string;
@@ -118,7 +116,6 @@ export declare class Client {
118
116
  private logQueue;
119
117
  private readonly batchSize;
120
118
  private readonly flushDelay;
121
- private readonly maxQueueSize;
122
119
  private flushTimeoutId;
123
120
  private readonly queueLock;
124
121
  private readonly flushLock;
@@ -132,9 +129,9 @@ export declare class Client {
132
129
  flush(): Promise<void>;
133
130
  shutdown(): Promise<void>;
134
131
  close(): Promise<void>;
135
- listEvents(): Promise<EventDefinition[]>;
136
- getEvent(eventID: string): Promise<EventDefinition>;
137
- updateEvent(eventID: string, payload: Partial<Omit<EventDefinition, "event_id" | "created_at">>): Promise<EventDefinition>;
132
+ listEvents(): Promise<Event[]>;
133
+ getEvent(eventID: string): Promise<Event>;
134
+ updateEvent(eventID: string, payload: Partial<Omit<Event, "event_id" | "created_at">>): Promise<Event>;
138
135
  listPolicies(): Promise<Policy[]>;
139
136
  createPolicy(payload: Omit<Policy, "policy_id">): Promise<Policy>;
140
137
  listAlerts(status?: string): Promise<Alert[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -35,8 +35,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
35
35
  });
36
36
  };
37
37
  var __generator = (this && this.__generator) || function (thisArg, body) {
38
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
39
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
38
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
39
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
40
40
  function verb(n) { return function (v) { return step([n, v]); }; }
41
41
  function step(op) {
42
42
  if (f) throw new TypeError("Generator is already executing.");
@@ -74,12 +74,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
74
74
  return (mod && mod.__esModule) ? mod : { "default": mod };
75
75
  };
76
76
  Object.defineProperty(exports, "__esModule", { value: true });
77
- exports.flush = exports.stop = exports.logEvent = exports.initialize = exports.createClient = exports.Client = exports.ChirpierError = void 0;
77
+ exports.Client = exports.ChirpierError = void 0;
78
+ exports.createClient = createClient;
79
+ exports.initialize = initialize;
80
+ exports.logEvent = logEvent;
81
+ exports.stop = stop;
82
+ exports.flush = flush;
78
83
  var axios_1 = __importDefault(require("axios"));
79
84
  var axios_retry_1 = __importDefault(require("axios-retry"));
80
85
  var dotenv_1 = __importDefault(require("dotenv"));
81
86
  var constants_1 = require("./constants");
82
87
  var async_lock_1 = __importDefault(require("async-lock"));
88
+ var uuid_1 = require("uuid");
83
89
  // Custom error class for Chirpier-specific errors
84
90
  var ChirpierError = /** @class */ (function (_super) {
85
91
  __extends(ChirpierError, _super);
@@ -98,7 +104,7 @@ var Client = /** @class */ (function () {
98
104
  if (options === void 0) { options = {}; }
99
105
  this.logQueue = [];
100
106
  this.flushTimeoutId = null;
101
- var providedKey = options.key, _a = options.apiEndpoint, apiEndpoint = _a === void 0 ? constants_1.DEFAULT_API_ENDPOINT : _a, _b = options.servicerEndpoint, servicerEndpoint = _b === void 0 ? constants_1.DEFAULT_SERVICER_ENDPOINT : _b, _c = options.logLevel, logLevel = _c === void 0 ? 0 /* LogLevel.None */ : _c, _d = options.retries, retries = _d === void 0 ? constants_1.DEFAULT_RETRIES : _d, _e = options.timeout, timeout = _e === void 0 ? constants_1.DEFAULT_TIMEOUT : _e, _f = options.batchSize, batchSize = _f === void 0 ? constants_1.DEFAULT_BATCH_SIZE : _f, _g = options.flushDelay, flushDelay = _g === void 0 ? constants_1.DEFAULT_FLUSH_DELAY : _g, _h = options.maxQueueSize, maxQueueSize = _h === void 0 ? constants_1.MAX_QUEUE_SIZE : _h;
107
+ var providedKey = options.key, _a = options.apiEndpoint, apiEndpoint = _a === void 0 ? constants_1.DEFAULT_API_ENDPOINT : _a, _b = options.servicerEndpoint, servicerEndpoint = _b === void 0 ? constants_1.DEFAULT_SERVICER_ENDPOINT : _b, _c = options.logLevel, logLevel = _c === void 0 ? 0 /* LogLevel.None */ : _c, _d = options.retries, retries = _d === void 0 ? constants_1.DEFAULT_RETRIES : _d, _e = options.timeout, timeout = _e === void 0 ? constants_1.DEFAULT_TIMEOUT : _e, _f = options.batchSize, batchSize = _f === void 0 ? constants_1.DEFAULT_BATCH_SIZE : _f, _g = options.flushDelay, flushDelay = _g === void 0 ? constants_1.DEFAULT_FLUSH_DELAY : _g, maxQueueSize = options.maxQueueSize;
102
108
  var key = resolveAPIKey(providedKey);
103
109
  if (!key) {
104
110
  throw new ChirpierError("API key is required", "INVALID_KEY");
@@ -114,7 +120,7 @@ var Client = /** @class */ (function () {
114
120
  try {
115
121
  parsedURL = new URL(apiEndpoint);
116
122
  }
117
- catch (_j) {
123
+ catch (_h) {
118
124
  throw new ChirpierError("apiEndpoint must be a valid absolute URL", "INVALID_API_ENDPOINT");
119
125
  }
120
126
  if (parsedURL.protocol !== "https:" && parsedURL.protocol !== "http:") {
@@ -134,9 +140,6 @@ var Client = /** @class */ (function () {
134
140
  if (flushDelay < 0) {
135
141
  throw new ChirpierError("Flush delay must be non-negative", "INVALID_FLUSH_DELAY");
136
142
  }
137
- if (maxQueueSize <= 0 || !Number.isInteger(maxQueueSize)) {
138
- throw new ChirpierError("Max queue size must be a positive integer", "INVALID_QUEUE_SIZE");
139
- }
140
143
  this.apiEndpoint = apiEndpoint !== null && apiEndpoint !== void 0 ? apiEndpoint : constants_1.DEFAULT_API_ENDPOINT;
141
144
  this.servicerEndpoint = servicerEndpoint !== null && servicerEndpoint !== void 0 ? servicerEndpoint : constants_1.DEFAULT_SERVICER_ENDPOINT;
142
145
  this.apiKey = key;
@@ -144,10 +147,10 @@ var Client = /** @class */ (function () {
144
147
  this.timeout = timeout;
145
148
  this.batchSize = batchSize;
146
149
  this.flushDelay = flushDelay;
147
- this.maxQueueSize = maxQueueSize;
148
150
  this.logLevel = logLevel;
149
- this.queueLock = new async_lock_1.default({ maxPending: this.maxQueueSize });
150
- this.flushLock = new async_lock_1.default({ maxPending: this.maxQueueSize });
151
+ void maxQueueSize;
152
+ this.queueLock = new async_lock_1.default();
153
+ this.flushLock = new async_lock_1.default();
151
154
  this.axiosInstance = axios_1.default.create({
152
155
  headers: { Authorization: "Bearer ".concat(this.apiKey) },
153
156
  timeout: this.timeout,
@@ -175,10 +178,19 @@ var Client = /** @class */ (function () {
175
178
  if (typeof log.event !== "string" || log.event.trim().length === 0) {
176
179
  return false;
177
180
  }
181
+ if (log.log_id !== undefined) {
182
+ if (typeof log.log_id !== "string") {
183
+ return false;
184
+ }
185
+ var trimmedLogID = log.log_id.trim();
186
+ if (trimmedLogID.length > 0 && !isUUID(trimmedLogID)) {
187
+ return false;
188
+ }
189
+ }
178
190
  if (typeof log.value !== "number" || !Number.isFinite(log.value)) {
179
191
  return false;
180
192
  }
181
- if (log.agent_id !== undefined && typeof log.agent_id !== "string") {
193
+ if (log.agent !== undefined && typeof log.agent !== "string") {
182
194
  return false;
183
195
  }
184
196
  if (log.meta !== undefined) {
@@ -207,13 +219,14 @@ var Client = /** @class */ (function () {
207
219
  };
208
220
  Client.prototype.normalizeLog = function (log) {
209
221
  var normalizedLog = {
222
+ log_id: resolveLogID(log.log_id),
210
223
  event: log.event.trim(),
211
224
  value: log.value,
212
225
  };
213
- if (typeof log.agent_id === "string") {
214
- var trimmedAgentID = log.agent_id.trim();
215
- if (trimmedAgentID.length > 0) {
216
- normalizedLog.agent_id = trimmedAgentID;
226
+ if (typeof log.agent === "string") {
227
+ var trimmedAgent = log.agent.trim();
228
+ if (trimmedAgent.length > 0) {
229
+ normalizedLog.agent = trimmedAgent;
217
230
  }
218
231
  }
219
232
  if (log.meta !== undefined) {
@@ -227,31 +240,23 @@ var Client = /** @class */ (function () {
227
240
  };
228
241
  Client.prototype.log = function (log) {
229
242
  return __awaiter(this, void 0, void 0, function () {
230
- var normalizedLog, queueFull;
243
+ var normalizedLog;
231
244
  var _this = this;
232
245
  return __generator(this, function (_a) {
233
246
  switch (_a.label) {
234
247
  case 0:
235
248
  if (!this.isValidLog(log)) {
236
- throw new ChirpierError("Invalid log format: event must not be empty, value must be a finite number, agent_id must be a string when provided, meta must be JSON-encodable, and occurred_at must be within the last 30 days and no more than 1 day in the future", "INVALID_LOG");
249
+ throw new ChirpierError("Invalid log format: log_id must be a UUID when provided, event must not be empty, value must be a finite number, agent must be a string when provided, meta must be JSON-encodable, and occurred_at must be within the last 30 days and no more than 1 day in the future", "INVALID_LOG");
237
250
  }
238
251
  normalizedLog = this.normalizeLog(log);
239
- queueFull = false;
240
252
  return [4 /*yield*/, this.queueLock.acquire("queue", function () { return __awaiter(_this, void 0, void 0, function () {
241
253
  return __generator(this, function (_a) {
242
- if (this.logQueue.length >= this.maxQueueSize) {
243
- queueFull = true;
244
- return [2 /*return*/];
245
- }
246
- this.logQueue.push({ log: normalizedLog, timestamp: Date.now(), retryCount: 0 });
254
+ this.logQueue.push({ log: normalizedLog, timestamp: Date.now() });
247
255
  return [2 /*return*/];
248
256
  });
249
257
  }); })];
250
258
  case 1:
251
259
  _a.sent();
252
- if (queueFull) {
253
- throw new ChirpierError("Log queue is full (max size: ".concat(this.maxQueueSize, ")"), "QUEUE_FULL");
254
- }
255
260
  if (!(this.logQueue.length >= this.batchSize)) return [3 /*break*/, 3];
256
261
  return [4 /*yield*/, this.flushQueue()];
257
262
  case 2:
@@ -273,7 +278,7 @@ var Client = /** @class */ (function () {
273
278
  return __generator(this, function (_a) {
274
279
  switch (_a.label) {
275
280
  case 0: return [4 /*yield*/, this.flushLock.acquire("flush", function () { return __awaiter(_this, void 0, void 0, function () {
276
- var logsToSend, error_1, retryableLogs_1, _i, logsToSend_1, queuedLog;
281
+ var logsToSend, error_1;
277
282
  var _this = this;
278
283
  return __generator(this, function (_a) {
279
284
  switch (_a.label) {
@@ -312,21 +317,9 @@ var Client = /** @class */ (function () {
312
317
  if (this.logLevel >= 1 /* LogLevel.Error */) {
313
318
  console.error("Failed to send logs:", error_1);
314
319
  }
315
- retryableLogs_1 = [];
316
- for (_i = 0, logsToSend_1 = logsToSend; _i < logsToSend_1.length; _i++) {
317
- queuedLog = logsToSend_1[_i];
318
- if (queuedLog.retryCount >= this.retries) {
319
- if (this.logLevel >= 1 /* LogLevel.Error */) {
320
- console.error("Dropping log after ".concat(this.retries, " retries:"), queuedLog.log);
321
- }
322
- continue;
323
- }
324
- queuedLog.retryCount++;
325
- retryableLogs_1.push(queuedLog);
326
- }
327
320
  return [4 /*yield*/, this.queueLock.acquire("logQueue", function () { return __awaiter(_this, void 0, void 0, function () {
328
321
  return __generator(this, function (_a) {
329
- this.logQueue = __spreadArray(__spreadArray([], retryableLogs_1, true), this.logQueue, true);
322
+ this.logQueue = __spreadArray(__spreadArray([], logsToSend, true), this.logQueue, true);
330
323
  return [2 /*return*/];
331
324
  });
332
325
  }); })];
@@ -479,10 +472,10 @@ var Client = /** @class */ (function () {
479
472
  });
480
473
  });
481
474
  };
482
- Client.prototype.getAlertDeliveries = function (alertID, options) {
483
- if (options === void 0) { options = {}; }
484
- return __awaiter(this, void 0, void 0, function () {
475
+ Client.prototype.getAlertDeliveries = function (alertID_1) {
476
+ return __awaiter(this, arguments, void 0, function (alertID, options) {
485
477
  var params, suffix, response;
478
+ if (options === void 0) { options = {}; }
486
479
  return __generator(this, function (_a) {
487
480
  switch (_a.label) {
488
481
  case 0:
@@ -543,10 +536,10 @@ var Client = /** @class */ (function () {
543
536
  });
544
537
  });
545
538
  };
546
- Client.prototype.getEventLogs = function (eventID, options) {
547
- if (options === void 0) { options = {}; }
548
- return __awaiter(this, void 0, void 0, function () {
539
+ Client.prototype.getEventLogs = function (eventID_1) {
540
+ return __awaiter(this, arguments, void 0, function (eventID, options) {
549
541
  var params, suffix, response;
542
+ if (options === void 0) { options = {}; }
550
543
  return __generator(this, function (_a) {
551
544
  switch (_a.label) {
552
545
  case 0:
@@ -590,13 +583,24 @@ function createClient(config) {
590
583
  if (config === void 0) { config = {}; }
591
584
  return new Client(config);
592
585
  }
593
- exports.createClient = createClient;
594
586
  function isNodeEnvironment() {
595
587
  return typeof process !== "undefined" && !!(process.versions && process.versions.node);
596
588
  }
597
589
  function isValidAPIKey(token) {
598
590
  return token.startsWith("chp_") && token.length > "chp_".length;
599
591
  }
592
+ function isUUID(value) {
593
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
594
+ }
595
+ function resolveLogID(logID) {
596
+ if (typeof logID === "string") {
597
+ var trimmedLogID = logID.trim();
598
+ if (trimmedLogID.length > 0) {
599
+ return trimmedLogID;
600
+ }
601
+ }
602
+ return (0, uuid_1.v7)();
603
+ }
600
604
  function loadDotEnvKey() {
601
605
  if (!isNodeEnvironment()) {
602
606
  return undefined;
@@ -655,7 +659,6 @@ function initialize(options) {
655
659
  throw error;
656
660
  }
657
661
  }
658
- exports.initialize = initialize;
659
662
  function logEvent(log) {
660
663
  return __awaiter(this, void 0, void 0, function () {
661
664
  return __generator(this, function (_a) {
@@ -672,7 +675,6 @@ function logEvent(log) {
672
675
  });
673
676
  });
674
677
  }
675
- exports.logEvent = logEvent;
676
678
  function stop() {
677
679
  return __awaiter(this, void 0, void 0, function () {
678
680
  return __generator(this, function (_a) {
@@ -690,7 +692,6 @@ function stop() {
690
692
  });
691
693
  });
692
694
  }
693
- exports.stop = stop;
694
695
  function flush() {
695
696
  return __awaiter(this, void 0, void 0, function () {
696
697
  return __generator(this, function (_a) {
@@ -707,4 +708,3 @@ function flush() {
707
708
  });
708
709
  });
709
710
  }
710
- exports.flush = flush;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chirpier/chirpier-js",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Chirpier SDK for JavaScript",
5
5
  "keywords": [
6
6
  "chirpier",
@@ -32,7 +32,8 @@
32
32
  "axios-retry": "^4.5.0",
33
33
  "dotenv": "^16.4.7",
34
34
  "ts-node": "^10.9.2",
35
- "tslib": "^2.3.0"
35
+ "tslib": "^2.3.0",
36
+ "uuid": "^11.1.0"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@eslint/js": "^9.15.0",
@@ -41,13 +42,12 @@
41
42
  "@types/jest": "^29.5.13",
42
43
  "@types/mocha": "^10.0.8",
43
44
  "@types/node": "^22.7.5",
44
- "@types/uuid": "^10.0.0",
45
45
  "axios-mock-adapter": "^2.0.0",
46
46
  "eslint": "^9.15.0",
47
47
  "globals": "^15.12.0",
48
48
  "jest": "^29.7.0",
49
49
  "ts-jest": "^29.2.4",
50
- "typescript": "^4.4.3",
50
+ "typescript": "^5.6.3",
51
51
  "typescript-eslint": "^8.15.0",
52
52
  "webpack": "^5.52.0",
53
53
  "webpack-cli": "^4.8.0"
@@ -134,7 +134,7 @@ describe("Chirpier SDK", () => {
134
134
  });
135
135
 
136
136
  const log: Log = {
137
- agent_id: "api.worker",
137
+ agent: "api.worker",
138
138
  event: "request.finished",
139
139
  value: 1,
140
140
  };
@@ -146,14 +146,38 @@ describe("Chirpier SDK", () => {
146
146
  expect(mock.history.post[0].url).toBe(DEFAULT_API_ENDPOINT);
147
147
  expect(JSON.parse(mock.history.post[0].data)).toEqual([
148
148
  {
149
- agent_id: "api.worker",
149
+ log_id: expect.any(String),
150
+ agent: "api.worker",
150
151
  event: "request.finished",
151
152
  value: 1,
152
153
  },
153
154
  ]);
155
+ expect(JSON.parse(mock.history.post[0].data)[0].log_id).toMatch(
156
+ /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
157
+ );
154
158
  });
155
159
 
156
- test("agent_id whitespace should be omitted", async () => {
160
+ test("should preserve provided log_id", async () => {
161
+ const mock = new MockAdapter(axios);
162
+ mock.onPost(DEFAULT_API_ENDPOINT).reply(200, { success: true });
163
+
164
+ initialize({
165
+ key: "chp_log_id_key",
166
+ logLevel: LogLevel.None,
167
+ });
168
+
169
+ await logEvent({
170
+ log_id: "9f97d65f-fb30-4062-b4d0-8617c03fe4f6",
171
+ event: "request.finished",
172
+ value: 1,
173
+ });
174
+
175
+ await new Promise((resolve) => setTimeout(resolve, 2000));
176
+ const payload = JSON.parse(mock.history.post[0].data);
177
+ expect(payload[0].log_id).toBe("9f97d65f-fb30-4062-b4d0-8617c03fe4f6");
178
+ });
179
+
180
+ test("agent whitespace should be omitted", async () => {
157
181
  const mock = new MockAdapter(axios);
158
182
  mock.onPost(DEFAULT_API_ENDPOINT).reply(200, { success: true });
159
183
 
@@ -163,14 +187,14 @@ describe("Chirpier SDK", () => {
163
187
  });
164
188
 
165
189
  await logEvent({
166
- agent_id: " ",
190
+ agent: " ",
167
191
  event: "metric.tick",
168
192
  value: 42,
169
193
  });
170
194
 
171
195
  await new Promise((resolve) => setTimeout(resolve, 2000));
172
196
  const payload = JSON.parse(mock.history.post[0].data);
173
- expect(payload[0].agent_id).toBeUndefined();
197
+ expect(payload[0].agent).toBeUndefined();
174
198
  });
175
199
 
176
200
  test("should support meta payload", async () => {
@@ -183,7 +207,7 @@ describe("Chirpier SDK", () => {
183
207
  });
184
208
 
185
209
  await logEvent({
186
- agent_id: "api.worker",
210
+ agent: "api.worker",
187
211
  event: "request.finished",
188
212
  value: 200,
189
213
  meta: {
@@ -251,6 +275,14 @@ describe("Chirpier SDK", () => {
251
275
  })
252
276
  ).rejects.toThrow(ChirpierError);
253
277
 
278
+ await expect(
279
+ logEvent({
280
+ log_id: "not-a-uuid",
281
+ event: "bad-log-id",
282
+ value: 1,
283
+ })
284
+ ).rejects.toThrow(ChirpierError);
285
+
254
286
  expect(mock.history.post.length).toBe(0);
255
287
  });
256
288
 
package/src/index.ts CHANGED
@@ -6,11 +6,11 @@ import {
6
6
  DEFAULT_TIMEOUT,
7
7
  DEFAULT_BATCH_SIZE,
8
8
  DEFAULT_FLUSH_DELAY,
9
- MAX_QUEUE_SIZE,
10
9
  DEFAULT_API_ENDPOINT,
11
10
  DEFAULT_SERVICER_ENDPOINT,
12
11
  } from "./constants";
13
12
  import AsyncLock from "async-lock";
13
+ import { v7 as uuidv7 } from "uuid";
14
14
 
15
15
  // Define logging levels as const enum for better tree-shaking
16
16
  export const enum LogLevel {
@@ -29,6 +29,7 @@ export interface Config {
29
29
  timeout?: number;
30
30
  batchSize?: number;
31
31
  flushDelay?: number;
32
+ /** @deprecated Queues are unbounded in memory. */
32
33
  maxQueueSize?: number;
33
34
  }
34
35
 
@@ -38,26 +39,23 @@ export interface Config {
38
39
  export type Options = Config;
39
40
 
40
41
  export interface Log {
41
- agent_id?: string;
42
+ log_id?: string;
43
+ agent?: string;
42
44
  event: string;
43
45
  value: number;
44
46
  meta?: unknown;
45
47
  occurred_at?: string | Date;
46
48
  }
47
49
 
48
- export interface EventDefinition {
50
+ export interface Event {
49
51
  readonly event_id: string;
50
- readonly agent_id?: string;
52
+ readonly agent?: string;
51
53
  readonly event: string;
52
54
  readonly title?: string;
53
55
  readonly public: boolean;
54
56
  readonly description?: string;
55
57
  readonly unit?: string;
56
- readonly semantic_class: string;
57
- readonly default_aggregate: string;
58
- readonly enabled: boolean;
59
- readonly origin: string;
60
- readonly archived_at?: string;
58
+ readonly timezone: string;
61
59
  readonly created_at?: string;
62
60
  }
63
61
 
@@ -79,7 +77,7 @@ export interface Alert {
79
77
  readonly alert_id: string;
80
78
  readonly policy_id: string;
81
79
  readonly event_id: string;
82
- readonly agent_id?: string;
80
+ readonly agent?: string;
83
81
  readonly event: string;
84
82
  readonly title: string;
85
83
  readonly period: string;
@@ -111,7 +109,7 @@ export interface AlertDelivery {
111
109
 
112
110
  export interface EventLogPoint {
113
111
  readonly event_id: string;
114
- readonly agent_id?: string;
112
+ readonly agent?: string;
115
113
  readonly event: string;
116
114
  readonly period: string;
117
115
  readonly occurred_at: string;
@@ -145,7 +143,6 @@ export class ChirpierError extends Error {
145
143
  interface QueuedLog {
146
144
  readonly log: Log;
147
145
  readonly timestamp: number;
148
- retryCount: number;
149
146
  }
150
147
 
151
148
  export class Client {
@@ -158,7 +155,6 @@ export class Client {
158
155
  private logQueue: QueuedLog[] = [];
159
156
  private readonly batchSize: number;
160
157
  private readonly flushDelay: number;
161
- private readonly maxQueueSize: number;
162
158
  private flushTimeoutId: NodeJS.Timeout | null = null;
163
159
  private readonly queueLock: AsyncLock;
164
160
  private readonly flushLock: AsyncLock;
@@ -174,7 +170,7 @@ export class Client {
174
170
  timeout = DEFAULT_TIMEOUT,
175
171
  batchSize = DEFAULT_BATCH_SIZE,
176
172
  flushDelay = DEFAULT_FLUSH_DELAY,
177
- maxQueueSize = MAX_QUEUE_SIZE,
173
+ maxQueueSize,
178
174
  } = options;
179
175
 
180
176
  const key = resolveAPIKey(providedKey);
@@ -226,10 +222,6 @@ export class Client {
226
222
  if (flushDelay < 0) {
227
223
  throw new ChirpierError("Flush delay must be non-negative", "INVALID_FLUSH_DELAY");
228
224
  }
229
- if (maxQueueSize <= 0 || !Number.isInteger(maxQueueSize)) {
230
- throw new ChirpierError("Max queue size must be a positive integer", "INVALID_QUEUE_SIZE");
231
- }
232
-
233
225
  this.apiEndpoint = apiEndpoint ?? DEFAULT_API_ENDPOINT;
234
226
  this.servicerEndpoint = servicerEndpoint ?? DEFAULT_SERVICER_ENDPOINT;
235
227
  this.apiKey = key;
@@ -237,11 +229,11 @@ export class Client {
237
229
  this.timeout = timeout;
238
230
  this.batchSize = batchSize;
239
231
  this.flushDelay = flushDelay;
240
- this.maxQueueSize = maxQueueSize;
241
232
  this.logLevel = logLevel;
242
233
 
243
- this.queueLock = new AsyncLock({ maxPending: this.maxQueueSize });
244
- this.flushLock = new AsyncLock({ maxPending: this.maxQueueSize });
234
+ void maxQueueSize;
235
+ this.queueLock = new AsyncLock();
236
+ this.flushLock = new AsyncLock();
245
237
 
246
238
  this.axiosInstance = axios.create({
247
239
  headers: { Authorization: `Bearer ${this.apiKey}` },
@@ -280,11 +272,22 @@ export class Client {
280
272
  return false;
281
273
  }
282
274
 
275
+ if (log.log_id !== undefined) {
276
+ if (typeof log.log_id !== "string") {
277
+ return false;
278
+ }
279
+
280
+ const trimmedLogID = log.log_id.trim();
281
+ if (trimmedLogID.length > 0 && !isUUID(trimmedLogID)) {
282
+ return false;
283
+ }
284
+ }
285
+
283
286
  if (typeof log.value !== "number" || !Number.isFinite(log.value)) {
284
287
  return false;
285
288
  }
286
289
 
287
- if (log.agent_id !== undefined && typeof log.agent_id !== "string") {
290
+ if (log.agent !== undefined && typeof log.agent !== "string") {
288
291
  return false;
289
292
  }
290
293
 
@@ -319,14 +322,15 @@ export class Client {
319
322
 
320
323
  private normalizeLog(log: Log): Log {
321
324
  const normalizedLog: Log = {
325
+ log_id: resolveLogID(log.log_id),
322
326
  event: log.event.trim(),
323
327
  value: log.value,
324
328
  };
325
329
 
326
- if (typeof log.agent_id === "string") {
327
- const trimmedAgentID = log.agent_id.trim();
328
- if (trimmedAgentID.length > 0) {
329
- normalizedLog.agent_id = trimmedAgentID;
330
+ if (typeof log.agent === "string") {
331
+ const trimmedAgent = log.agent.trim();
332
+ if (trimmedAgent.length > 0) {
333
+ normalizedLog.agent = trimmedAgent;
330
334
  }
331
335
  }
332
336
 
@@ -346,31 +350,17 @@ export class Client {
346
350
  public async log(log: Log): Promise<void> {
347
351
  if (!this.isValidLog(log)) {
348
352
  throw new ChirpierError(
349
- "Invalid log format: event must not be empty, value must be a finite number, agent_id must be a string when provided, meta must be JSON-encodable, and occurred_at must be within the last 30 days and no more than 1 day in the future",
353
+ "Invalid log format: log_id must be a UUID when provided, event must not be empty, value must be a finite number, agent must be a string when provided, meta must be JSON-encodable, and occurred_at must be within the last 30 days and no more than 1 day in the future",
350
354
  "INVALID_LOG"
351
355
  );
352
356
  }
353
357
 
354
358
  const normalizedLog = this.normalizeLog(log);
355
359
 
356
- let queueFull = false;
357
-
358
360
  await this.queueLock.acquire("queue", async () => {
359
- if (this.logQueue.length >= this.maxQueueSize) {
360
- queueFull = true;
361
- return;
362
- }
363
-
364
- this.logQueue.push({ log: normalizedLog, timestamp: Date.now(), retryCount: 0 });
361
+ this.logQueue.push({ log: normalizedLog, timestamp: Date.now() });
365
362
  });
366
363
 
367
- if (queueFull) {
368
- throw new ChirpierError(
369
- `Log queue is full (max size: ${this.maxQueueSize})`,
370
- "QUEUE_FULL"
371
- );
372
- }
373
-
374
364
  if (this.logQueue.length >= this.batchSize) {
375
365
  await this.flushQueue();
376
366
  } else if (!this.flushTimeoutId) {
@@ -412,24 +402,8 @@ export class Client {
412
402
  console.error("Failed to send logs:", error);
413
403
  }
414
404
 
415
- const retryableLogs: QueuedLog[] = [];
416
- for (const queuedLog of logsToSend) {
417
- if (queuedLog.retryCount >= this.retries) {
418
- if (this.logLevel >= LogLevel.Error) {
419
- console.error(
420
- `Dropping log after ${this.retries} retries:`,
421
- queuedLog.log
422
- );
423
- }
424
- continue;
425
- }
426
-
427
- queuedLog.retryCount++;
428
- retryableLogs.push(queuedLog);
429
- }
430
-
431
405
  await this.queueLock.acquire("logQueue", async () => {
432
- this.logQueue = [...retryableLogs, ...this.logQueue];
406
+ this.logQueue = [...logsToSend, ...this.logQueue];
433
407
  });
434
408
  }
435
409
  });
@@ -456,21 +430,21 @@ export class Client {
456
430
  await this.shutdown();
457
431
  }
458
432
 
459
- public async listEvents(): Promise<EventDefinition[]> {
460
- const response = await this.axiosInstance.get<EventDefinition[]>(`${this.servicerEndpoint}/events`);
433
+ public async listEvents(): Promise<Event[]> {
434
+ const response = await this.axiosInstance.get<Event[]>(`${this.servicerEndpoint}/events`);
461
435
  return response.data;
462
436
  }
463
437
 
464
- public async getEvent(eventID: string): Promise<EventDefinition> {
465
- const response = await this.axiosInstance.get<EventDefinition>(`${this.servicerEndpoint}/events/${eventID}`);
438
+ public async getEvent(eventID: string): Promise<Event> {
439
+ const response = await this.axiosInstance.get<Event>(`${this.servicerEndpoint}/events/${eventID}`);
466
440
  return response.data;
467
441
  }
468
442
 
469
443
  public async updateEvent(
470
444
  eventID: string,
471
- payload: Partial<Omit<EventDefinition, "event_id" | "created_at">>
472
- ): Promise<EventDefinition> {
473
- const response = await this.axiosInstance.put<EventDefinition>(
445
+ payload: Partial<Omit<Event, "event_id" | "created_at">>
446
+ ): Promise<Event> {
447
+ const response = await this.axiosInstance.put<Event>(
474
448
  `${this.servicerEndpoint}/events/${eventID}`,
475
449
  payload
476
450
  );
@@ -562,6 +536,21 @@ function isValidAPIKey(token: string): boolean {
562
536
  return token.startsWith("chp_") && token.length > "chp_".length;
563
537
  }
564
538
 
539
+ function isUUID(value: string): boolean {
540
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
541
+ }
542
+
543
+ function resolveLogID(logID?: string): string {
544
+ if (typeof logID === "string") {
545
+ const trimmedLogID = logID.trim();
546
+ if (trimmedLogID.length > 0) {
547
+ return trimmedLogID;
548
+ }
549
+ }
550
+
551
+ return uuidv7();
552
+ }
553
+
565
554
  function loadDotEnvKey(): string | undefined {
566
555
  if (!isNodeEnvironment()) {
567
556
  return undefined;