@kortyx/usage-telemetry 0.0.0-stage → 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,720 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ classifyUsageError: () => classifyUsageError,
24
+ createCollectorTransport: () => createCollectorTransport,
25
+ createPostHogTransport: () => createPostHogTransport,
26
+ createUsageTelemetry: () => createUsageTelemetry,
27
+ publicCatalog: () => publicCatalog,
28
+ sanitizeProperties: () => sanitizeProperties,
29
+ scale: () => scale
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/catalog.ts
34
+ var operations = [
35
+ "sdk.initialize",
36
+ "sdk.registry",
37
+ "sdk.execute",
38
+ "sdk.resume",
39
+ "sdk.chat.admission",
40
+ "sdk.execution",
41
+ "sdk.response",
42
+ "sdk.model",
43
+ "sdk.tool",
44
+ "sdk.node",
45
+ "sdk.parallel",
46
+ "sdk.child",
47
+ "sdk.structured",
48
+ "sdk.complete_response",
49
+ "sdk.prompt.resolve",
50
+ "sdk.prompt.refresh",
51
+ "sdk.eval",
52
+ "sdk.mcp.connect",
53
+ "sdk.mcp.discover",
54
+ "sdk.mcp.close",
55
+ "sdk.checkpoint.read",
56
+ "sdk.checkpoint.list",
57
+ "sdk.checkpoint.fork",
58
+ "sdk.checkpoint.rollback",
59
+ "sdk.export",
60
+ "studio.setup",
61
+ "studio.connection",
62
+ "studio.read",
63
+ "studio.render",
64
+ "studio.navigation",
65
+ "studio.inspect",
66
+ "studio.filter",
67
+ "studio.saved_view",
68
+ "studio.live",
69
+ "studio.prompt",
70
+ "studio.eval",
71
+ "studio.review",
72
+ "studio.settings",
73
+ "studio.update",
74
+ "studio.ingest",
75
+ "cli.topology",
76
+ "cli.eval"
77
+ ];
78
+ var outcomes = [
79
+ "success",
80
+ "failed",
81
+ "cancelled",
82
+ "suspended",
83
+ "denied",
84
+ "limit_reached",
85
+ "quality_failed",
86
+ "ungraded"
87
+ ];
88
+ var publicCatalog = {
89
+ products: ["sdk", "oss_studio"],
90
+ operations,
91
+ properties: {
92
+ phase: [
93
+ "admission",
94
+ "execution",
95
+ "delivery",
96
+ "parse",
97
+ "network",
98
+ "http",
99
+ "configuration",
100
+ "preflight",
101
+ "state",
102
+ "pull",
103
+ "ports",
104
+ "compose",
105
+ "rollback",
106
+ "backup",
107
+ "migration",
108
+ "health"
109
+ ],
110
+ source: [
111
+ "memory",
112
+ "file",
113
+ "custom",
114
+ "local",
115
+ "studio",
116
+ "cache",
117
+ "fallback",
118
+ "eval",
119
+ "mcp",
120
+ "native"
121
+ ],
122
+ storage: ["in-memory", "redis", "postgres", "custom"],
123
+ calling_mode: ["direct", "model"],
124
+ provider: [
125
+ "openai",
126
+ "anthropic",
127
+ "google",
128
+ "mistral",
129
+ "groq",
130
+ "deepseek",
131
+ "openrouter"
132
+ ],
133
+ transport: ["stdio", "sse", "http", "custom"],
134
+ format: [
135
+ "text",
136
+ "json",
137
+ "json_schema",
138
+ "set",
139
+ "append",
140
+ "text-delta",
141
+ "final"
142
+ ],
143
+ resource: [
144
+ "runs",
145
+ "sessions",
146
+ "interrupts",
147
+ "workflows",
148
+ "prompts",
149
+ "evals",
150
+ "diagnostics",
151
+ "settings",
152
+ "home"
153
+ ],
154
+ surface: [
155
+ "runs",
156
+ "sessions",
157
+ "interrupts",
158
+ "workflows",
159
+ "prompts",
160
+ "evals",
161
+ "settings",
162
+ "other"
163
+ ],
164
+ action: [
165
+ "view",
166
+ "select",
167
+ "retry",
168
+ "first_use",
169
+ "observed",
170
+ "copy",
171
+ "create",
172
+ "draft",
173
+ "save",
174
+ "discard-draft",
175
+ "update",
176
+ "promote",
177
+ "review",
178
+ "policy",
179
+ "tag-set",
180
+ "tag-remove",
181
+ "bulk-update",
182
+ "category-create",
183
+ "category-update",
184
+ "category-delete",
185
+ "group-create",
186
+ "group-update",
187
+ "group-delete",
188
+ "import",
189
+ "export",
190
+ "launch",
191
+ "cancel",
192
+ "compare",
193
+ "inspect",
194
+ "clear",
195
+ "apply",
196
+ "delete",
197
+ "enable",
198
+ "disable",
199
+ "manual_refresh",
200
+ "fallback_refresh",
201
+ "refresh",
202
+ "change"
203
+ ],
204
+ tab: [
205
+ "overview",
206
+ "trace",
207
+ "events",
208
+ "model-io",
209
+ "calls",
210
+ "feedback",
211
+ "content",
212
+ "versions",
213
+ "reviews",
214
+ "usage",
215
+ "diff",
216
+ "cases",
217
+ "results",
218
+ "definition"
219
+ ],
220
+ origin: ["foreground", "background", "server", "browser", "cli"],
221
+ status: [
222
+ "empty",
223
+ "nonempty",
224
+ "off",
225
+ "connecting",
226
+ "live",
227
+ "reconnecting",
228
+ "paused",
229
+ "running",
230
+ "completed",
231
+ "failed",
232
+ "interrupted",
233
+ "pending",
234
+ "expired"
235
+ ],
236
+ filter: [
237
+ "search",
238
+ "status",
239
+ "provider",
240
+ "model",
241
+ "environment",
242
+ "version",
243
+ "duration",
244
+ "cost",
245
+ "tokens",
246
+ "time",
247
+ "sort",
248
+ "other"
249
+ ],
250
+ scale: ["1", "2-5", "6-20", "21-100", "101+"],
251
+ error_category: [
252
+ "configuration",
253
+ "provider",
254
+ "validation",
255
+ "domain",
256
+ "workflow",
257
+ "persistence",
258
+ "request",
259
+ "transport",
260
+ "internal",
261
+ "unknown"
262
+ ],
263
+ http_status: [
264
+ "400",
265
+ "401",
266
+ "403",
267
+ "404",
268
+ "409",
269
+ "413",
270
+ "422",
271
+ "429",
272
+ "500",
273
+ "502",
274
+ "503",
275
+ "504"
276
+ ],
277
+ prompts: "boolean",
278
+ observability: "boolean",
279
+ tools: "boolean",
280
+ streaming: "boolean",
281
+ requested_streaming: "boolean",
282
+ executed: "boolean",
283
+ cache: "boolean",
284
+ reused: "boolean",
285
+ continue_on_disconnect: "boolean",
286
+ write_available: "boolean"
287
+ },
288
+ // Built-in contracts only; application codes and provider response text are excluded.
289
+ errorCodes: [
290
+ "EXECUTION_FAILED",
291
+ "INVALID_REQUEST",
292
+ "INVALID_RESUME",
293
+ "INVALID_RESPONSE",
294
+ "INVALID_SESSION",
295
+ "RESUME_MISMATCH",
296
+ "RESUME_FAILED",
297
+ "CONTRACT_MISMATCH",
298
+ "INVALID_INPUT",
299
+ "INVALID_OUTPUT",
300
+ "MISSING_CONTRACT",
301
+ "UNKNOWN_WORKFLOW",
302
+ "DOMAIN_ERROR",
303
+ "PERSISTENCE_ERROR",
304
+ "WORKFLOW_CONTRACT_ERROR",
305
+ "PROVIDER_REFUSAL",
306
+ "PROVIDER_HTTP_ERROR",
307
+ "PROVIDER_INVALID_RESPONSE",
308
+ "PROVIDER_TRANSPORT_ERROR",
309
+ "PROVIDER_REQUEST_FAILED",
310
+ "INVALID_MODEL_JSON",
311
+ "MODEL_OUTPUT_SCHEMA",
312
+ "OUTPUT_TRUNCATED",
313
+ "SCHEMA_VALIDATION",
314
+ "PARALLEL_FAILED",
315
+ "EVAL_TIMEOUT",
316
+ "EVAL_HOOK_FAILED",
317
+ "EVAL_INTERRUPT_CLEANUP_FAILED",
318
+ "PROMPT_SOURCE_NOT_CONFIGURED",
319
+ "PROMPT_REASON_CONFLICT",
320
+ "PROMPT_REASON_INVALID",
321
+ "REASON_OUTPUT_BUDGET_EXHAUSTED",
322
+ "REASON_OUTPUT_CONTRACT_CORRECTION_EXHAUSTED",
323
+ "PROMPT_CACHE_INVALID",
324
+ "PROMPT_ENVIRONMENT_MISMATCH",
325
+ "PROMPT_EVAL_PIN_CONFLICT",
326
+ "PROMPT_EVAL_SNAPSHOT_INVALID",
327
+ "PROMPT_NOT_ASSIGNED",
328
+ "PROMPT_NOT_FOUND",
329
+ "PROMPT_NOT_REGISTERED",
330
+ "PROMPT_PIN_MISMATCH",
331
+ "PROMPT_REFERENCE_DUPLICATE",
332
+ "PROMPT_SNAPSHOT_INVALID",
333
+ "PROMPT_SNAPSHOT_LIMIT",
334
+ "PROMPT_SOURCE_HTTP",
335
+ "PROMPT_SOURCE_INVALID",
336
+ "PROMPT_TAG_MISMATCH",
337
+ "PROMPT_CONTRACT_MISMATCH",
338
+ "PROMPT_REFERENCE_INVALID",
339
+ "PROMPT_SCHEMA_INVALID",
340
+ "PROMPT_VARIABLE_CONFIG_OVERLAP",
341
+ "PROMPT_VARIABLE_MISSING",
342
+ "PROMPT_VARIABLE_UNKNOWN",
343
+ "PROMPT_DEPENDENCY_CYCLE",
344
+ "PROMPT_DEPENDENCY_MISMATCH",
345
+ "PROMPT_HASH_MISMATCH",
346
+ "PROMPT_REFERENCE_LIMIT",
347
+ "PROMPT_REFERENCE_MISSING",
348
+ "PROMPT_REFERENCE_ROLE",
349
+ "STUDIO_PROTOCOL_MISMATCH"
350
+ ]
351
+ };
352
+ function scale(value) {
353
+ return value <= 1 ? "1" : value <= 5 ? "2-5" : value <= 20 ? "6-20" : value <= 100 ? "21-100" : "101+";
354
+ }
355
+
356
+ // src/client.ts
357
+ function property(value, key) {
358
+ try {
359
+ if (!value || typeof value !== "object") return void 0;
360
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
361
+ return descriptor && "value" in descriptor ? descriptor.value : void 0;
362
+ } catch {
363
+ return void 0;
364
+ }
365
+ }
366
+ function classifyUsageError(error, catalog = publicCatalog) {
367
+ const name = property(error, "name");
368
+ const code = property(error, "code") ?? property(property(error, "failure"), "code");
369
+ if (name === "AbortError" || code === "EXECUTION_CANCELLED")
370
+ return { outcome: "cancelled", properties: {} };
371
+ if (code === "EXECUTION_LIMIT_REACHED" || name === "ExecutionLimitReached")
372
+ return { outcome: "limit_reached", properties: {} };
373
+ if (name === "GraphInterrupt" || name === "NodeInterrupt" || name === "Interrupt")
374
+ return { outcome: "suspended", properties: {} };
375
+ const known = typeof code === "string" && catalog.errorCodes.includes(code);
376
+ const category = known && code !== "EXECUTION_FAILED" ? property(error, "category") ?? property(property(error, "failure"), "category") ?? "unknown" : "unknown";
377
+ const status = property(error, "status") ?? property(property(error, "failure"), "status");
378
+ return {
379
+ outcome: "failed",
380
+ properties: {
381
+ error_code: known ? code : "other",
382
+ error_category: category,
383
+ ...typeof status === "number" ? { http_status: String(status) } : {}
384
+ }
385
+ };
386
+ }
387
+ function sanitizeProperties(input, catalog = publicCatalog) {
388
+ const safe = {};
389
+ for (const [key, rule] of Object.entries(catalog.properties)) {
390
+ const value = property(input, key);
391
+ if (value === void 0) continue;
392
+ if (rule === "boolean") {
393
+ if (typeof value === "boolean") safe[key] = value;
394
+ } else if (typeof value === "string")
395
+ safe[key] = rule.includes(value) ? value : "other";
396
+ }
397
+ const code = property(input, "error_code");
398
+ if (typeof code === "string")
399
+ safe.error_code = catalog.errorCodes.includes(code) ? code : "other";
400
+ return safe;
401
+ }
402
+ var durationBounds = [10, 100, 1e3, 1e4, 6e4];
403
+ var noopOperation = { end() {
404
+ }, fail() {
405
+ } };
406
+ function schedule(callback, ms) {
407
+ const timer = setTimeout(callback, ms);
408
+ timer.unref?.();
409
+ return { cancel: () => clearTimeout(timer) };
410
+ }
411
+ function createUsageTelemetry(options) {
412
+ const catalog = options.catalog ?? publicCatalog;
413
+ const now = options.now ?? Date.now;
414
+ const pending = /* @__PURE__ */ new Map();
415
+ let timer;
416
+ let flight;
417
+ let disposed = false;
418
+ let dropped = 0;
419
+ let delivered = 0;
420
+ let hour = Math.floor(now() / 36e5);
421
+ let sent = 0;
422
+ const active = () => {
423
+ try {
424
+ return !disposed && (options.enabled?.() ?? true);
425
+ } catch {
426
+ return false;
427
+ }
428
+ };
429
+ const clear = () => {
430
+ pending.clear();
431
+ try {
432
+ timer?.cancel();
433
+ } catch {
434
+ }
435
+ timer = void 0;
436
+ };
437
+ const configured = catalog.products.includes(options.context.product) && /^[a-z][a-z0-9_]{0,31}$/.test(options.context.component) && /^(?:\d+\.\d+\.\d+(?:-[a-z0-9.-]+)?|development|unknown)$/.test(
438
+ options.context.version
439
+ ) && options.context.version.length <= 64;
440
+ const flush = async () => {
441
+ if (flight) return flight;
442
+ if (!active() || !configured) {
443
+ clear();
444
+ return;
445
+ }
446
+ try {
447
+ timer?.cancel();
448
+ } catch {
449
+ }
450
+ timer = void 0;
451
+ const records = [...pending.values()];
452
+ pending.clear();
453
+ if (!records.length) return;
454
+ let attempted = records.length;
455
+ flight = (async () => {
456
+ try {
457
+ if (options.debug?.()) {
458
+ options.inspect?.(records);
459
+ return;
460
+ }
461
+ const currentHour = Math.floor(now() / 36e5);
462
+ if (hour !== currentHour) {
463
+ hour = currentHour;
464
+ sent = 0;
465
+ }
466
+ const allowance = Math.max(
467
+ 0,
468
+ (options.maxRecordsPerHour ?? 120) - sent
469
+ );
470
+ const batch = records.slice(0, allowance);
471
+ dropped += records.length - batch.length;
472
+ attempted = batch.length;
473
+ if (!batch.length || !active()) return;
474
+ const identified = await options.identity();
475
+ const identity = typeof identified === "string" ? identified : identified.id;
476
+ if (typeof identified !== "string")
477
+ for (const record2 of batch) record2.identity_scope = identified.scope;
478
+ if (!active() || options.debug?.()) return;
479
+ if (!/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(
480
+ identity
481
+ )) {
482
+ dropped += batch.length;
483
+ return;
484
+ }
485
+ sent += batch.length;
486
+ await options.transport(batch, identity);
487
+ delivered += batch.length;
488
+ } catch {
489
+ dropped += attempted;
490
+ }
491
+ })().finally(() => {
492
+ flight = void 0;
493
+ try {
494
+ if (pending.size && active() && !timer)
495
+ timer = (options.schedule ?? schedule)(
496
+ () => void flush(),
497
+ options.flushIntervalMs ?? 6e4
498
+ );
499
+ } catch {
500
+ clear();
501
+ }
502
+ });
503
+ return flight;
504
+ };
505
+ const record = (event, operation, outcome, duration, input) => {
506
+ try {
507
+ if (!active()) {
508
+ clear();
509
+ return;
510
+ }
511
+ if (!configured || !catalog.operations.includes(operation) || !outcomes.includes(outcome))
512
+ return;
513
+ const properties = sanitizeProperties(input, catalog);
514
+ const key = JSON.stringify([event, operation, outcome, properties]);
515
+ let existing = pending.get(key);
516
+ if (!existing) {
517
+ if (pending.size >= (options.maxGroups ?? 64)) {
518
+ dropped++;
519
+ return;
520
+ }
521
+ existing = {
522
+ schema_version: 1,
523
+ event_id: crypto.randomUUID(),
524
+ timestamp: new Date(now()).toISOString(),
525
+ event,
526
+ product: options.context.product,
527
+ component: options.context.component,
528
+ version: options.context.version,
529
+ analytics_environment: options.context.environment ?? "production",
530
+ runtime_mode: options.context.runtimeMode ?? "unknown",
531
+ identity_scope: options.context.identityScope ?? "installation",
532
+ operation,
533
+ outcome,
534
+ properties,
535
+ count: 0,
536
+ duration_total_ms: 0,
537
+ duration_buckets: [0, 0, 0, 0, 0, 0]
538
+ };
539
+ pending.set(key, existing);
540
+ }
541
+ const elapsed = Math.max(
542
+ 0,
543
+ Math.min(864e5, Number.isFinite(duration) ? duration : 0)
544
+ );
545
+ existing.count = Math.min(Number.MAX_SAFE_INTEGER, existing.count + 1);
546
+ existing.duration_total_ms = Math.min(
547
+ Number.MAX_SAFE_INTEGER,
548
+ existing.duration_total_ms + elapsed
549
+ );
550
+ const index = durationBounds.findIndex((bound) => elapsed <= bound);
551
+ const bucket = index === -1 ? durationBounds.length : index;
552
+ existing.duration_buckets[bucket] = (existing.duration_buckets[bucket] ?? 0) + 1;
553
+ if (!timer)
554
+ timer = (options.schedule ?? schedule)(
555
+ () => void flush(),
556
+ options.flushIntervalMs ?? 6e4
557
+ );
558
+ } catch {
559
+ }
560
+ };
561
+ const start = (operation, properties = {}) => {
562
+ if (!active()) {
563
+ clear();
564
+ return noopOperation;
565
+ }
566
+ try {
567
+ const initial = sanitizeProperties(properties, catalog);
568
+ const began = now();
569
+ let ended = false;
570
+ return {
571
+ end(outcome = "success", extra = {}) {
572
+ if (ended) return;
573
+ ended = true;
574
+ try {
575
+ record("usage.operation", operation, outcome, now() - began, {
576
+ ...initial,
577
+ ...sanitizeProperties(extra, catalog)
578
+ });
579
+ } catch {
580
+ }
581
+ },
582
+ fail(error, extra = {}) {
583
+ if (ended) return;
584
+ try {
585
+ const failure = classifyUsageError(error, catalog);
586
+ this.end(failure.outcome, {
587
+ ...sanitizeProperties(extra, catalog),
588
+ ...failure.properties
589
+ });
590
+ } catch {
591
+ }
592
+ }
593
+ };
594
+ } catch {
595
+ return noopOperation;
596
+ }
597
+ };
598
+ return {
599
+ start,
600
+ feature(operation, properties = {}) {
601
+ record("usage.feature", operation, "success", 0, properties);
602
+ },
603
+ async measure(operation, callback, properties = {}, outcome) {
604
+ const operationScope = start(operation, properties);
605
+ try {
606
+ const result = await callback();
607
+ let status = "success";
608
+ try {
609
+ status = outcome?.(result) ?? status;
610
+ } catch {
611
+ }
612
+ operationScope.end(status);
613
+ return result;
614
+ } catch (error) {
615
+ operationScope.fail(error);
616
+ throw error;
617
+ }
618
+ },
619
+ flush,
620
+ dispose() {
621
+ disposed = true;
622
+ clear();
623
+ },
624
+ stats: () => ({ pending: pending.size, dropped, delivered })
625
+ };
626
+ }
627
+
628
+ // src/transport.ts
629
+ function createPostHogTransport(options) {
630
+ if (!/^phc_[a-zA-Z0-9]+$/.test(options.key))
631
+ throw new Error("Usage telemetry requires a public PostHog capture key.");
632
+ const host = new URL(options.host ?? "https://eu.i.posthog.com");
633
+ if (host.username || host.password || host.search || host.hash)
634
+ throw new Error(
635
+ "Usage endpoint must not contain credentials or query parameters."
636
+ );
637
+ if (host.protocol !== "https:" && host.hostname !== "localhost" && host.hostname !== "127.0.0.1")
638
+ throw new Error("Usage telemetry requires HTTPS.");
639
+ return async (records, identity) => {
640
+ const batch = records.map((record) => ({
641
+ event: record.event,
642
+ timestamp: record.timestamp,
643
+ distinct_id: identity,
644
+ uuid: record.event_id,
645
+ properties: {
646
+ ...record.properties,
647
+ schema_version: record.schema_version,
648
+ product: record.product,
649
+ component: record.component,
650
+ version: record.version,
651
+ analytics_environment: record.analytics_environment,
652
+ runtime_mode: record.runtime_mode,
653
+ identity_scope: record.identity_scope,
654
+ operation: record.operation,
655
+ outcome: record.outcome,
656
+ count: record.count,
657
+ duration_total_ms: record.duration_total_ms,
658
+ duration_buckets: record.duration_buckets,
659
+ $process_person_profile: false,
660
+ $geoip_disable: true,
661
+ $ip: null
662
+ }
663
+ }));
664
+ const controller = new AbortController();
665
+ const timeout = setTimeout(
666
+ () => controller.abort(),
667
+ options.timeoutMs ?? 2e3
668
+ );
669
+ timeout.unref?.();
670
+ try {
671
+ const response = await (options.fetch ?? globalThis.fetch)(
672
+ new URL("/batch/", host),
673
+ {
674
+ method: "POST",
675
+ credentials: "omit",
676
+ referrerPolicy: "no-referrer",
677
+ headers: { "content-type": "application/json" },
678
+ body: JSON.stringify({ api_key: options.key, batch }),
679
+ signal: controller.signal
680
+ }
681
+ );
682
+ await response.body?.cancel();
683
+ if (!response.ok) throw new Error("Usage delivery failed.");
684
+ } finally {
685
+ clearTimeout(timeout);
686
+ }
687
+ };
688
+ }
689
+ function createCollectorTransport(options) {
690
+ const endpoint = new URL(options.endpoint);
691
+ if (endpoint.username || endpoint.password || endpoint.search || endpoint.hash)
692
+ throw new Error(
693
+ "Usage endpoint must not contain credentials or query parameters."
694
+ );
695
+ if (endpoint.protocol !== "https:" && !["localhost", "127.0.0.1"].includes(endpoint.hostname))
696
+ throw new Error("Usage telemetry requires HTTPS.");
697
+ return async (records, identity) => {
698
+ const response = await (options.fetch ?? globalThis.fetch)(endpoint, {
699
+ method: "POST",
700
+ credentials: "omit",
701
+ referrerPolicy: "no-referrer",
702
+ headers: { "content-type": "application/json" },
703
+ body: JSON.stringify({ identity, records }),
704
+ signal: AbortSignal.timeout(2e3)
705
+ });
706
+ await response.body?.cancel();
707
+ if (!response.ok) throw new Error("Usage delivery failed.");
708
+ };
709
+ }
710
+ // Annotate the CommonJS export names for ESM import in node:
711
+ 0 && (module.exports = {
712
+ classifyUsageError,
713
+ createCollectorTransport,
714
+ createPostHogTransport,
715
+ createUsageTelemetry,
716
+ publicCatalog,
717
+ sanitizeProperties,
718
+ scale
719
+ });
720
+ //# sourceMappingURL=index.js.map