@visulima/pail 4.0.2 → 4.1.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/LICENSE.md +346 -0
  3. package/README.md +17 -0
  4. package/dist/error.d.ts +69 -69
  5. package/dist/index.browser.d.ts +446 -445
  6. package/dist/index.browser.js +17 -17
  7. package/dist/index.server.d.ts +582 -582
  8. package/dist/index.server.js +27 -27
  9. package/dist/middleware/elysia.d.ts +44 -42
  10. package/dist/middleware/elysia.js +1 -1
  11. package/dist/middleware/express.d.ts +58 -59
  12. package/dist/middleware/express.js +1 -1
  13. package/dist/middleware/fastify.d.ts +55 -56
  14. package/dist/middleware/fastify.js +1 -1
  15. package/dist/middleware/hono.d.ts +56 -57
  16. package/dist/middleware/hono.js +1 -1
  17. package/dist/middleware/next/handler.d.ts +67 -68
  18. package/dist/middleware/next/handler.js +1 -1
  19. package/dist/middleware/sveltekit.d.ts +72 -73
  20. package/dist/middleware/sveltekit.js +1 -1
  21. package/dist/object-tree.d.ts +44 -44
  22. package/dist/packem_shared/AbstractJsonReporter-BpWRnN0L.js +1 -0
  23. package/dist/packem_shared/AbstractJsonReporter-DxZwImm5.js +1 -0
  24. package/dist/packem_shared/JsonReporter-9IcELa1m.js +2 -0
  25. package/dist/packem_shared/JsonReporter-Dd3kuj8X.js +1 -0
  26. package/dist/packem_shared/{PrettyReporter-DsHfKOU7.js → PrettyReporter-BUWNEg3_.js} +1 -1
  27. package/dist/packem_shared/{PrettyReporter-CcDdPQSt.js → PrettyReporter-DbgD89ck.js} +56 -30
  28. package/dist/packem_shared/abstract-json-reporter.d-B6NoO-hG.d.ts +61 -0
  29. package/dist/packem_shared/{abstract-pretty-reporter-DrLBJ6ds.js → abstract-pretty-reporter-CyfTvmKf.js} +41 -39
  30. package/dist/packem_shared/create-middleware-logger.d-BRkkBMlk.d.ts +47 -0
  31. package/dist/packem_shared/headers-DI58djdG.js +1 -0
  32. package/dist/packem_shared/index-CbkPnylC.js +1 -0
  33. package/dist/packem_shared/serializeError-52C4oiKx-CrnRcq9R.js +1 -0
  34. package/dist/packem_shared/storage-DVcJumyk.js +1 -0
  35. package/dist/packem_shared/types.d-4ge_rME4.d.ts +246 -0
  36. package/dist/packem_shared/{types.d-Cz9S7jZh.d.ts → types.d-BW8kAXUv.d.ts} +95 -95
  37. package/dist/packem_shared/types.d-DGHeA2iJ.d.ts +194 -0
  38. package/dist/packem_shared/useLogger-7p55yvvc.js +1 -0
  39. package/dist/packem_shared/wide-event.d-BMLastMR.d.ts +716 -0
  40. package/dist/packem_shared/write-stream-ytl_vhg_.js +1 -0
  41. package/dist/processor/caller/caller-processor.d.ts +32 -33
  42. package/dist/processor/environment-processor.d.ts +83 -84
  43. package/dist/processor/message-formatter-processor.d.ts +40 -45
  44. package/dist/processor/message-formatter-processor.js +1 -1
  45. package/dist/processor/opentelemetry-processor.d.ts +51 -52
  46. package/dist/processor/redact-processor.d.ts +57 -65
  47. package/dist/processor/sampling-processor.d.ts +90 -91
  48. package/dist/reporter/file/json-file-reporter.d.ts +77 -78
  49. package/dist/reporter/file/json-file-reporter.js +1 -1
  50. package/dist/reporter/http/abstract-http-reporter.d.ts +125 -121
  51. package/dist/reporter/http/abstract-http-reporter.js +2 -2
  52. package/dist/reporter/http/http-reporter.d.ts +33 -34
  53. package/dist/reporter/http/http-reporter.edge-light.d.ts +235 -230
  54. package/dist/reporter/http/http-reporter.edge-light.js +2 -2
  55. package/dist/reporter/json/index.browser.d.ts +62 -61
  56. package/dist/reporter/json/index.browser.js +1 -1
  57. package/dist/reporter/json/index.d.ts +36 -37
  58. package/dist/reporter/json/index.js +1 -1
  59. package/dist/reporter/pretty/index.browser.d.ts +57 -56
  60. package/dist/reporter/pretty/index.browser.js +1 -1
  61. package/dist/reporter/pretty/index.d.ts +133 -133
  62. package/dist/reporter/pretty/index.js +1 -1
  63. package/dist/reporter/simple/simple-reporter.server.d.ts +91 -90
  64. package/dist/reporter/simple/simple-reporter.server.js +7 -7
  65. package/dist/wide-event.d.ts +2 -3
  66. package/dist/wide-event.js +1 -1
  67. package/package.json +58 -37
  68. package/dist/packem_shared/AbstractJsonReporter-Bp_JCrMQ.js +0 -1
  69. package/dist/packem_shared/AbstractJsonReporter-w_bGGiD-.js +0 -1
  70. package/dist/packem_shared/JsonReporter-Sd_lJGS-.js +0 -2
  71. package/dist/packem_shared/JsonReporter-bmem9lcg.js +0 -1
  72. package/dist/packem_shared/abstract-json-reporter.d-wfESoEa-.d.ts +0 -62
  73. package/dist/packem_shared/addKnownErrorConstructor-C1OJTj2D-0FlJMfXz.js +0 -25
  74. package/dist/packem_shared/create-middleware-logger.d-B-JmQ1Sl.d.ts +0 -47
  75. package/dist/packem_shared/headers-DH0H2s8W.js +0 -1
  76. package/dist/packem_shared/index-Q1764hvO.js +0 -1
  77. package/dist/packem_shared/serializeError-C-NFvZ8_-D0CA_Qlx.js +0 -1
  78. package/dist/packem_shared/storage-DaXAlpiO.js +0 -1
  79. package/dist/packem_shared/types.d-bWnqHJKL.d.ts +0 -211
  80. package/dist/packem_shared/types.d-xxE3FOD3.d.ts +0 -229
  81. package/dist/packem_shared/useLogger-DB34CuU5.js +0 -1
  82. package/dist/packem_shared/wide-event.d-D3ATYpoK.d.ts +0 -717
  83. package/dist/packem_shared/write-stream-C7jxLxIT.js +0 -1
@@ -1,105 +1,107 @@
1
- import { LiteralUnion } from 'type-fest';
2
- import { E as ExtendedRfc5424LogLevels, S as StringifyAwareReporter } from "../../packem_shared/types.d-bWnqHJKL.js";
3
- import { A as AbstractJsonReporterOptions, a as AbstractJsonReporter } from "../../packem_shared/abstract-json-reporter.d-wfESoEa-.js";
1
+ import { E as ExtendedRfc5424LogLevels, L as LiteralUnion, S as StringifyAwareReporter } from "../../packem_shared/types.d-4ge_rME4.js";
2
+ import { A as AbstractJsonReporterOptions, a as AbstractJsonReporter } from "../../packem_shared/abstract-json-reporter.d-B6NoO-hG.js";
4
3
  import '@visulima/colorize';
5
4
  import '@visulima/interactive-manager';
6
5
  import "../../packem_shared/index.d-T71KjNAr.js";
7
6
  /**
8
- * Configuration options for the HTTP reporter.
9
- */
7
+ * Configuration options for the HTTP reporter.
8
+ */
10
9
  type AbstractHttpReporterOptions = AbstractJsonReporterOptions & {
11
10
  /**
12
- * Content type for batch log requests. User-specified headers take precedence.
13
- * @default "application/json"
14
- */
11
+ * Content type for batch log requests. User-specified headers take precedence.
12
+ * @default "application/json"
13
+ */
15
14
  batchContentType?: string;
16
15
  /**
17
- * Field name to wrap batch entries in when batchMode is "field" (e.g., "batch" for Logflare)
18
- * @default undefined
19
- */
16
+ * Field name to wrap batch entries in when batchMode is "field" (e.g., "batch" for Logflare)
17
+ * @default undefined
18
+ */
20
19
  batchFieldName?: string;
21
20
  /**
22
- * Batch mode for sending multiple log entries
23
- * - "delimiter": Join entries with a delimiter (default)
24
- * - "field": Wrap entries in an object with a field name
25
- * - "array": Send entries as a plain JSON array
26
- * @default "delimiter"
27
- */
21
+ * Batch mode for sending multiple log entries
22
+ * - "delimiter": Join entries with a delimiter (default)
23
+ * - "field": Wrap entries in an object with a field name
24
+ * - "array": Send entries as a plain JSON array
25
+ * @default "delimiter"
26
+ */
28
27
  batchMode?: "delimiter" | "field" | "array";
29
28
  /**
30
- * Delimiter to use between log entries in batch mode
31
- * @default "\n"
32
- */
29
+ * Delimiter to use between log entries in batch mode
30
+ * @default "\n"
31
+ */
33
32
  batchSendDelimiter?: string;
34
33
  /**
35
- * Timeout in milliseconds for sending batches regardless of size
36
- * @default 5000
37
- */
34
+ * Timeout in milliseconds for sending batches regardless of size
35
+ * @default 5000
36
+ */
38
37
  batchSendTimeout?: number;
39
38
  /**
40
- * Number of log entries to batch before sending
41
- * @default 100
42
- */
39
+ * Number of log entries to batch before sending
40
+ * @default 100
41
+ */
43
42
  batchSize?: number;
44
43
  /**
45
- * Whether to use gzip compression
46
- * @default false
47
- */
44
+ * Whether to use gzip compression
45
+ * @default false
46
+ */
48
47
  compression?: boolean;
49
48
  /**
50
- * Content type for single log requests. User-specified headers take precedence.
51
- * @default "application/json"
52
- */
49
+ * Content type for single log requests. User-specified headers take precedence.
50
+ * @default "application/json"
51
+ */
53
52
  contentType?: string;
54
53
  /**
55
- * Whether to enable Edge Runtime compatibility mode
56
- * When enabled, TextEncoder and compression are disabled
57
- * @default false
58
- */
54
+ * Whether to enable Edge Runtime compatibility mode.
55
+ *
56
+ * When enabled, gzip compression is skipped so the reporter never depends on a
57
+ * compression implementation the runtime may not provide. Payload size accounting
58
+ * always uses the Web-standard `TextEncoder` and is unaffected by this flag.
59
+ * @default false
60
+ */
59
61
  edgeCompat?: boolean;
60
62
  /**
61
- * Whether to enable batch sending
62
- * @default true
63
- */
63
+ * Whether to enable batch sending
64
+ * @default true
65
+ */
64
66
  enableBatchSend?: boolean;
65
67
  /**
66
- * Headers to include in the request. Can be an object or a function that returns headers.
67
- */
68
+ * Headers to include in the request. Can be an object or a function that returns headers.
69
+ */
68
70
  headers?: Record<string, string> | (() => Record<string, string>);
69
71
  /**
70
- * Maximum size of a single log entry in bytes
71
- * @default 1048576 (1MB)
72
- */
72
+ * Maximum size of a single log entry in bytes
73
+ * @default 1048576 (1MB)
74
+ */
73
75
  maxLogSize?: number;
74
76
  /**
75
- * Maximum size of the payload (uncompressed) in bytes
76
- * @default 5242880 (5MB)
77
- */
77
+ * Maximum size of the payload (uncompressed) in bytes
78
+ * @default 5242880 (5MB)
79
+ */
78
80
  maxPayloadSize?: number;
79
81
  /**
80
- * Maximum number of entries to keep queued while the endpoint is unavailable.
81
- * When the queue exceeds this limit, the oldest entries are dropped (drop-oldest)
82
- * so a sustained outage cannot grow memory without bound.
83
- * @default 10000
84
- */
82
+ * Maximum number of entries to keep queued while the endpoint is unavailable.
83
+ * When the queue exceeds this limit, the oldest entries are dropped (drop-oldest)
84
+ * so a sustained outage cannot grow memory without bound.
85
+ * @default 10000
86
+ */
85
87
  maxQueueSize?: number;
86
88
  /**
87
- * Number of retry attempts before giving up
88
- * @default 3
89
- */
89
+ * Number of retry attempts before giving up
90
+ * @default 3
91
+ */
90
92
  maxRetries?: number;
91
93
  /**
92
- * HTTP method to use for requests
93
- * @default "POST"
94
- */
94
+ * HTTP method to use for requests
95
+ * @default "POST"
96
+ */
95
97
  method?: string;
96
98
  /**
97
- * Optional callback for debugging log entries before they are sent
98
- */
99
+ * Optional callback for debugging log entries before they are sent
100
+ */
99
101
  onDebug?: (entry: Record<string, unknown>) => void;
100
102
  /**
101
- * Optional callback for debugging HTTP requests and responses
102
- */
103
+ * Optional callback for debugging HTTP requests and responses
104
+ */
103
105
  onDebugRequestResponse?: (requestResponse: {
104
106
  req: {
105
107
  body: string | Uint8Array;
@@ -115,45 +117,45 @@ type AbstractHttpReporterOptions = AbstractJsonReporterOptions & {
115
117
  };
116
118
  }) => void;
117
119
  /**
118
- * Optional callback invoked when queued log entries are dropped because the queue
119
- * exceeded `maxQueueSize`. Receives the number of dropped entries.
120
- */
120
+ * Optional callback invoked when queued log entries are dropped because the queue
121
+ * exceeded `maxQueueSize`. Receives the number of dropped entries.
122
+ */
121
123
  onDrop?: (droppedCount: number) => void;
122
124
  /**
123
- * Optional callback for error handling
124
- */
125
+ * Optional callback for error handling
126
+ */
125
127
  onError?: (error: Error) => void;
126
128
  /**
127
- * Function to transform log data into the payload format.
128
- * By default, uses the JSON stringified log entry.
129
- */
129
+ * Function to transform log data into the payload format.
130
+ * By default, uses the JSON stringified log entry.
131
+ */
130
132
  payloadTemplate?: (data: {
131
133
  data?: Record<string, unknown>;
132
134
  logLevel: string;
133
135
  message: string;
134
136
  }) => string;
135
137
  /**
136
- * Whether to respect rate limiting by waiting when a 429 response is received
137
- * @default true
138
- */
138
+ * Whether to respect rate limiting by waiting when a 429 response is received
139
+ * @default true
140
+ */
139
141
  respectRateLimit?: boolean;
140
142
  /**
141
- * Base delay between retries in milliseconds
142
- * @default 1000
143
- */
143
+ * Base delay between retries in milliseconds
144
+ * @default 1000
145
+ */
144
146
  retryDelay?: number;
145
147
  /**
146
- * The URL to send logs to
147
- */
148
+ * The URL to send logs to
149
+ */
148
150
  url: string;
149
151
  };
150
152
  /**
151
- * Abstract HTTP Reporter.
152
- *
153
- * Base class for HTTP-based reporters that sends logs to HTTP endpoints.
154
- * Supports batching, compression, retries, and rate limiting.
155
- * @template L - The log level type
156
- */
153
+ * Abstract HTTP Reporter.
154
+ *
155
+ * Base class for HTTP-based reporters that sends logs to HTTP endpoints.
156
+ * Supports batching, compression, retries, and rate limiting.
157
+ * @template L - The log level type
158
+ */
157
159
  declare abstract class AbstractHttpReporter<L extends string = string> extends AbstractJsonReporter<L> implements StringifyAwareReporter<L> {
158
160
  #private;
159
161
  protected url: string;
@@ -198,63 +200,65 @@ declare abstract class AbstractHttpReporter<L extends string = string> extends A
198
200
  protected maxPayloadSize: number;
199
201
  protected edgeCompat: boolean;
200
202
  protected batchQueue: string[];
203
+ /** Per-entry UTF-8 byte sizes, kept in lockstep with `batchQueue`, so the tracked queue size never re-encodes payloads. */
204
+ protected batchSizeQueue: number[];
201
205
  protected batchTimeout?: ReturnType<typeof setTimeout>;
202
206
  protected isProcessingBatch: boolean;
203
207
  protected currentBatchSize: number;
204
208
  /**
205
- * Creates a new instance of AbstractHttpReporter.
206
- * @param config Configuration options for the reporter
207
- */
209
+ * Creates a new instance of AbstractHttpReporter.
210
+ * @param config Configuration options for the reporter
211
+ */
208
212
  constructor(config: AbstractHttpReporterOptions);
209
213
  /**
210
- * Flushes all queued log entries to the HTTP endpoint immediately.
211
- *
212
- * Returns a promise that resolves once the queue has been drained (or rejects
213
- * if a batch send fails terminally). Use this before a serverless function or
214
- * short-lived process exits so the tail of the batch is not lost.
215
- * @example
216
- * ```typescript
217
- * await reporter.flush();
218
- * ```
219
- */
214
+ * Flushes all queued log entries to the HTTP endpoint immediately.
215
+ *
216
+ * Returns a promise that resolves once the queue has been drained (or rejects
217
+ * if a batch send fails terminally). Use this before a serverless function or
218
+ * short-lived process exits so the tail of the batch is not lost.
219
+ * @example
220
+ * ```typescript
221
+ * await reporter.flush();
222
+ * ```
223
+ */
220
224
  flush(): Promise<void>;
221
225
  /**
222
- * Flushes any remaining queued entries and clears pending timers.
223
- *
224
- * Counterpart to a transport lifecycle `end`/`dispose`. After calling `close()`
225
- * the reporter can still be used, but any pending batch timeout is cleared.
226
- * @example
227
- * ```typescript
228
- * process.on("beforeExit", () => reporter.close());
229
- * ```
230
- */
226
+ * Flushes any remaining queued entries and clears pending timers.
227
+ *
228
+ * Counterpart to a transport lifecycle `end`/`dispose`. After calling `close()`
229
+ * the reporter can still be used, but any pending batch timeout is cleared.
230
+ * @example
231
+ * ```typescript
232
+ * process.on("beforeExit", () => reporter.close());
233
+ * ```
234
+ */
231
235
  close(): Promise<void>;
232
236
  /**
233
- * Alias for {@link close} to match common transport `dispose` conventions.
234
- */
237
+ * Alias for {@link close} to match common transport `dispose` conventions.
238
+ */
235
239
  dispose(): Promise<void>;
236
240
  /**
237
- * Processes and ships log entries to the HTTP endpoint.
238
- * @param message The JSON-formatted log message
239
- * @param logLevel The log level of the message
240
- * @protected
241
- */
241
+ * Processes and ships log entries to the HTTP endpoint.
242
+ * @param message The JSON-formatted log message
243
+ * @param logLevel The log level of the message
244
+ * @protected
245
+ */
242
246
  protected override _log(message: string, logLevel: LiteralUnion<ExtendedRfc5424LogLevels, L>): void;
243
247
  /**
244
- * Adds a payload to the batch queue and triggers sending if conditions are met.
245
- */
248
+ * Adds a payload to the batch queue and triggers sending if conditions are met.
249
+ */
246
250
  protected addToBatch(payload: string, logEntrySize: number): void;
247
251
  /**
248
- * Processes the current batch and sends it to the HTTP endpoint.
249
- */
252
+ * Processes the current batch and sends it to the HTTP endpoint.
253
+ */
250
254
  protected processBatch(): Promise<void>;
251
255
  /**
252
- * Sends a batch of payloads to the HTTP endpoint.
253
- */
256
+ * Sends a batch of payloads to the HTTP endpoint.
257
+ */
254
258
  protected sendBatch(batch: string[]): Promise<void>;
255
259
  /**
256
- * Sends a single payload to the HTTP endpoint.
257
- */
260
+ * Sends a single payload to the HTTP endpoint.
261
+ */
258
262
  protected sendPayload(payload: string, contentType?: string): Promise<void>;
259
263
  }
260
264
  export { AbstractHttpReporter, AbstractHttpReporterOptions };
@@ -1,2 +1,2 @@
1
- import{createRequire as S}from"node:module";import{AbstractJsonReporter as w}from"../../packem_shared/AbstractJsonReporter-w_bGGiD-.js";const T=S(import.meta.url),m=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,f=i=>{if(typeof m<"u"&&m.versions&&m.versions.node){const[t,e]=m.versions.node.split(".").map(Number);if(t>22||t===22&&e>=3||t===20&&e>=16)return m.getBuiltinModule(i)}return T(i)},{Buffer:g}=f("node:buffer"),{gzipSync:x}=f("node:zlib"),z=async i=>{const t=globalThis.CompressionStream;if(t){const e=new t("gzip"),s=e.writable.getWriter(),a=e.readable.getReader(),o=new TextEncoder,n=[];await s.write(o.encode(i)),await s.close();let u=!1;for(;!u;){const h=await a.read();u=h.done,h.value&&n.push(h.value)}const c=n.reduce((h,d)=>h+d.length,0),r=new Uint8Array(c);let l=0;for(let h=0;h<n.length;h+=1){const d=n[h];r.set(d,l),l+=d.length}return r}return x(i)};class D extends Error{logData;actualSize;maxSize;constructor(t,e,s,a){super(t),this.name="LogSizeError",this.logData=e,this.actualSize=s,this.maxSize=a}}const b=(i,t)=>i*2**t,B=/^\d+$/,E=i=>{const t=i.trim();if(B.test(t)){const a=Number.parseInt(t,10);return Math.min(Math.max(a,0)*1e3,6e4)}const e=Date.parse(t);if(Number.isNaN(e))return;const s=e-Date.now();return Math.min(Math.max(s,0),6e4)},y=i=>new Promise(t=>{setTimeout(t,i)}),R=i=>typeof i=="string"?i:new Uint8Array(i.buffer,i.byteOffset,i.byteLength),P=async(i,t,e,s,a,o,n)=>{const u={};i.headers.forEach((l,h)=>{u[h]=l});const c=await i.text(),r={req:{body:a,headers:s,method:e,url:t},res:{body:c,headers:u,status:i.status,statusText:i.statusText}};if(o&&o(r),i.ok)return!1;if(i.status<500&&i.status!==429){const l=new Error(`HTTP ${String(i.status)}: ${i.statusText}`);throw n&&n(l),l}return!0},Q=(i,t,e,s,a)=>{if(i.status===429&&t&&s<a){const o=i.headers.get("retry-after");return(o?E(o):void 0)??b(e,s)}},L=(i,t,e,s)=>{if(i.status>=500&&e<s)return b(t,e)},N=(i,t,e,s,a)=>{const o=Q(i,t,e,s,a);return o!==void 0?o:L(i,e,s,a)},v=async(i,t,e,s,a)=>{if(t<e){const o=b(s,t);return await y(o),!0}return a&&a(i),!1},_=async(i,t,e,s,a,o,n,u,c)=>{let r=0;for(;r<=a;)try{const l=R(s),h=await fetch(i,{body:l,headers:e,method:t});if(!await P(h,i,t,e,s,u,c))return;const d=N(h,n,o,r,a);if(d!==void 0){await y(d),r+=1;continue}if(!h.ok){const p=new Error(`HTTP ${String(h.status)}: ${h.statusText}`);throw c&&c(p),p}return}catch(l){if(await v(l,r,a,o,c)){r+=1;continue}throw l}};class $ extends w{url;method;headers;contentType;batchContentType;onError;onDrop;maxQueueSize;onDebug;onDebugRequestResponse;payloadTemplate;compression;maxRetries;retryDelay;respectRateLimit;enableBatchSend;batchSize;batchSendTimeout;batchSendDelimiter;batchMode;batchFieldName;maxLogSize;maxPayloadSize;edgeCompat;batchQueue=[];batchTimeout;isProcessingBatch=!1;currentBatchSize=0;constructor(t){if(super(t),this.url=t.url,this.method=t.method??"POST",this.headers=t.headers??{},this.contentType=t.contentType??"application/json",this.batchContentType=t.batchContentType??"application/json",this.onError=t.onError,this.onDrop=t.onDrop,this.maxQueueSize=t.maxQueueSize??1e4,this.onDebug=t.onDebug,this.onDebugRequestResponse=t.onDebugRequestResponse,this.payloadTemplate=t.payloadTemplate??(e=>JSON.stringify(e)),this.compression=t.compression??!1,this.maxRetries=t.maxRetries??3,this.retryDelay=t.retryDelay??1e3,this.respectRateLimit=t.respectRateLimit??!0,this.enableBatchSend=t.enableBatchSend??!0,this.batchSize=t.batchSize??100,this.batchSendTimeout=t.batchSendTimeout??5e3,this.batchSendDelimiter=t.batchSendDelimiter??`
2
- `,this.batchMode=t.batchMode??"delimiter",this.batchFieldName=t.batchFieldName,this.batchMode==="field"&&!this.batchFieldName)throw new Error("batchFieldName is required when batchMode is 'field'");this.maxLogSize=t.maxLogSize??1048576,this.maxPayloadSize=t.maxPayloadSize??5242880,this.edgeCompat=t.edgeCompat??!1}async flush(){for(this.batchTimeout&&(clearTimeout(this.batchTimeout),this.batchTimeout=void 0);this.batchQueue.length>0||this.isProcessingBatch;){if(this.isProcessingBatch){await new Promise(t=>setTimeout(t,0));continue}await this.processBatch()}}async close(){await this.flush()}async dispose(){await this.close()}_log(t,e){try{const s=JSON.parse(t),a=e,o=s.message,n={logLevel:a,message:o??""};if(s.data)n.data=s.data;else if(s.context)n.data=s.context;else{const r={...s};delete r.message,Object.keys(r).length>0&&(n.data=r)}const u=this.payloadTemplate(n);this.onDebug&&this.onDebug({data:n.data,logLevel:a,message:o});const c=this.edgeCompat||typeof TextEncoder>"u"?g.byteLength(u,"utf8"):new TextEncoder().encode(u).length;if(c>this.maxLogSize){const r=new D(`Log entry exceeds maximum size of ${String(this.maxLogSize)} bytes. Size: ${String(c)} bytes`,{data:n.data,logLevel:a,message:o},c,this.maxLogSize);this.onError&&this.onError(r);return}this.enableBatchSend?this.addToBatch(u,c):this.sendPayload(u).catch(r=>{this.onError&&this.onError(r)})}catch(s){this.onError&&this.onError(s)}}addToBatch(t,e){const s=this.currentBatchSize+e+this.batchSendDelimiter.length,a=this.maxPayloadSize*.9;if(s>a&&this.batchQueue.length>0&&this.processBatch(),this.batchQueue.push(t),this.currentBatchSize+=e+this.batchSendDelimiter.length,this.batchQueue.length>this.maxQueueSize){const o=this.batchQueue.splice(0,this.batchQueue.length-this.maxQueueSize);this.currentBatchSize=this.#t(),this.onDrop&&this.onDrop(o.length)}this.batchTimeout??=setTimeout(()=>{this.processBatch()},this.batchSendTimeout),this.batchQueue.length>=this.batchSize&&this.processBatch()}#t(){let t=0;for(let e=0;e<this.batchQueue.length;e+=1){const s=this.batchQueue[e],a=this.edgeCompat||typeof TextEncoder>"u"?g.byteLength(s,"utf8"):new TextEncoder().encode(s).length;t+=a+(e<this.batchQueue.length-1?this.batchSendDelimiter.length:0)}return t}async processBatch(){if(this.isProcessingBatch||this.batchQueue.length===0)return;this.isProcessingBatch=!0,this.batchTimeout&&(clearTimeout(this.batchTimeout),this.batchTimeout=void 0);const t=this.batchQueue.splice(0,this.batchSize);this.currentBatchSize=this.#t();try{await this.sendBatch(t)}catch(e){this.onError&&this.onError(e)}finally{this.isProcessingBatch=!1,this.batchQueue.length>0&&this.processBatch()}}async sendBatch(t){let e;switch(this.batchMode){case"array":{const s=t.map(a=>JSON.parse(a));e=JSON.stringify(s);break}case"field":{const s=t.map(o=>JSON.parse(o)),a=this.batchFieldName?{[this.batchFieldName]:s}:{};e=JSON.stringify(a);break}default:{e=t.join(this.batchSendDelimiter);break}}await this.sendPayload(e,this.batchContentType)}async sendPayload(t,e){const s=typeof this.headers=="function"?this.headers():{...this.headers};s["content-type"]??=e??this.contentType;let a=t;if(this.compression&&!this.edgeCompat)try{a=await z(t),s["content-encoding"]="gzip"}catch(o){this.onError&&this.onError(new Error(`Compression failed: ${String(o)}`))}await _(this.url,this.method,s,a,this.maxRetries,this.retryDelay,this.respectRateLimit,this.onDebugRequestResponse,this.onError)}}export{$ as AbstractHttpReporter};
1
+ import{AbstractJsonReporter as z}from"../../packem_shared/AbstractJsonReporter-DxZwImm5.js";const T=async()=>{try{const{gzipSync:e}=await import("node:zlib");return typeof e=="function"?e:void 0}catch{return}},w=async e=>{const t=globalThis.CompressionStream;if(t){const i=new t("gzip"),a=i.writable.getWriter(),r=i.readable.getReader(),o=new TextEncoder,h=[];await a.write(o.encode(e)),await a.close();let l=!1;for(;!l;){const u=await r.read();l=u.done,u.value&&h.push(u.value)}const c=h.reduce((u,m)=>u+m.length,0),n=new Uint8Array(c);let d=0;for(let u=0;u<h.length;u+=1){const m=h[u];n.set(m,d),d+=m.length}return n}const s=await T();if(s===void 0)throw new Error("gzip compression is unavailable: this runtime provides neither CompressionStream nor node:zlib.");return s(e)};class x extends Error{logData;actualSize;maxSize;constructor(t,s,i,a){super(t),this.name="LogSizeError",this.logData=s,this.actualSize=i,this.maxSize=a}}let S=class extends Error{};const b=(e,t)=>e*2**t,g=6e4,D=/^\d+$/,E=e=>{const t=e.trim();if(D.test(t)){const a=Number.parseInt(t,10);return Math.min(Math.max(a,0)*1e3,g)}const s=Date.parse(t);if(Number.isNaN(s))return;const i=s-Date.now();return Math.min(Math.max(i,0),g)},f=e=>new Promise(t=>{setTimeout(t,e)}),R=e=>typeof e=="string"?e:new Uint8Array(e.buffer,e.byteOffset,e.byteLength),B=async(e,t,s,i,a,r,o)=>{const h={};e.headers.forEach((n,d)=>{h[d]=n});const l=await e.text(),c={req:{body:a,headers:i,method:s,url:t},res:{body:l,headers:h,status:e.status,statusText:e.statusText}};if(r&&r(c),e.ok)return!1;if(e.status<500&&e.status!==429){const n=new S(`HTTP ${String(e.status)}: ${e.statusText}`);throw o&&o(n),n}return!0},Q=(e,t,s,i,a)=>{if(e.status===429&&t&&i<a){const r=e.headers.get("retry-after");return(r?E(r):void 0)??b(s,i)}},P=(e,t,s,i)=>{if(e.status>=500&&s<i)return b(t,s)},L=(e,t,s,i,a)=>{const r=Q(e,t,s,i,a);return r!==void 0?r:P(e,s,i,a)},N=async(e,t,s,i,a)=>{if(t<s){const r=b(i,t);return await f(r),!0}return a&&a(e),!1},v=async(e,t)=>{const{body:s,headers:i,maxRetries:a,method:r,onDebugRequestResponse:o,onError:h,respectRateLimit:l,retryDelay:c,url:n}=e,d=R(s),u=await fetch(n,{body:d,headers:i,method:r});if(!await B(u,n,r,i,s,o,h))return{done:!0};const m=L(u,l,c,t,a);if(m!==void 0)return{retryInMs:m};if(!u.ok){const p=new Error(`HTTP ${String(u.status)}: ${u.statusText}`);throw h&&h(p),p}return{done:!0}},M=async(e,t,s,i,a,r,o,h,l)=>{const c={body:i,headers:s,maxRetries:a,method:t,onDebugRequestResponse:h,onError:l,respectRateLimit:o,retryDelay:r,url:e};let n=0;for(;n<=a;)try{const d=await v(c,n);if("retryInMs"in d)await f(d.retryInMs),n+=1;else return}catch(d){if(d instanceof S||!await N(d,n,a,r,l))throw d;n+=1}},$=e=>{let t=0;for(const s of e){const i=s.codePointAt(0);i<128?t+=1:i<2048?t+=2:i<65536?t+=3:t+=4}return t};let y;const C=e=>typeof TextEncoder=="function"?(y??=new TextEncoder,y.encode(e).length):$(e);class k extends z{url;method;headers;contentType;batchContentType;onError;onDrop;maxQueueSize;onDebug;onDebugRequestResponse;payloadTemplate;compression;maxRetries;retryDelay;respectRateLimit;enableBatchSend;batchSize;batchSendTimeout;batchSendDelimiter;batchMode;batchFieldName;maxLogSize;maxPayloadSize;edgeCompat;batchQueue=[];batchSizeQueue=[];batchTimeout;isProcessingBatch=!1;currentBatchSize=0;constructor(t){if(super(t),this.url=t.url,this.method=t.method??"POST",this.headers=t.headers??{},this.contentType=t.contentType??"application/json",this.batchContentType=t.batchContentType??"application/json",this.onError=t.onError,this.onDrop=t.onDrop,this.maxQueueSize=t.maxQueueSize??1e4,this.onDebug=t.onDebug,this.onDebugRequestResponse=t.onDebugRequestResponse,this.payloadTemplate=t.payloadTemplate??(s=>JSON.stringify(s)),this.compression=t.compression??!1,this.maxRetries=t.maxRetries??3,this.retryDelay=t.retryDelay??1e3,this.respectRateLimit=t.respectRateLimit??!0,this.enableBatchSend=t.enableBatchSend??!0,this.batchSize=t.batchSize??100,this.batchSendTimeout=t.batchSendTimeout??5e3,this.batchSendDelimiter=t.batchSendDelimiter??`
2
+ `,this.batchMode=t.batchMode??"delimiter",this.batchFieldName=t.batchFieldName,this.batchMode==="field"&&!this.batchFieldName)throw new Error("batchFieldName is required when batchMode is 'field'");this.maxLogSize=t.maxLogSize??1048576,this.maxPayloadSize=t.maxPayloadSize??5242880,this.edgeCompat=t.edgeCompat??!1}async flush(){for(this.batchTimeout&&(clearTimeout(this.batchTimeout),this.batchTimeout=void 0);this.batchQueue.length>0||this.isProcessingBatch;){if(this.isProcessingBatch){await new Promise(t=>setTimeout(t,0));continue}await this.processBatch()}}async close(){await this.flush()}async dispose(){await this.close()}_log(t,s){try{const i=JSON.parse(t),a=s,r=i.message,o={logLevel:a,message:r??""};if(i.data)o.data=i.data;else if(i.context)o.data=i.context;else{const c={...i};delete c.message,Object.keys(c).length>0&&(o.data=c)}const h=this.payloadTemplate(o);this.onDebug&&this.onDebug({data:o.data,logLevel:a,message:r});const l=C(h);if(l>this.maxLogSize){const c=new x(`Log entry exceeds maximum size of ${String(this.maxLogSize)} bytes. Size: ${String(l)} bytes`,{data:o.data,logLevel:a,message:r},l,this.maxLogSize);this.onError&&this.onError(c);return}this.enableBatchSend?this.addToBatch(h,l):this.sendPayload(h).catch(c=>{this.onError&&this.onError(c)})}catch(i){this.onError&&this.onError(i)}}addToBatch(t,s){const i=this.currentBatchSize+s+this.batchSendDelimiter.length,a=this.maxPayloadSize*.9;if(i>a&&this.batchQueue.length>0&&this.processBatch(),this.batchQueue.push(t),this.batchSizeQueue.push(s),this.currentBatchSize+=s+this.batchSendDelimiter.length,this.batchQueue.length>this.maxQueueSize){const r=this.batchQueue.length-this.maxQueueSize,o=this.batchQueue.splice(0,r);this.batchSizeQueue.splice(0,r),this.currentBatchSize=this.#t(),this.onDrop&&this.onDrop(o.length)}this.batchTimeout??=setTimeout(()=>{this.processBatch()},this.batchSendTimeout),this.batchQueue.length>=this.batchSize&&this.processBatch()}#t(){let t=0;for(let s=0;s<this.batchSizeQueue.length;s+=1)t+=this.batchSizeQueue[s]+(s<this.batchSizeQueue.length-1?this.batchSendDelimiter.length:0);return t}async processBatch(){if(this.isProcessingBatch||this.batchQueue.length===0)return;this.isProcessingBatch=!0,this.batchTimeout&&(clearTimeout(this.batchTimeout),this.batchTimeout=void 0);const t=this.batchQueue.splice(0,this.batchSize);this.batchSizeQueue.splice(0,this.batchSize),this.currentBatchSize=this.#t();try{await this.sendBatch(t)}catch(s){this.onError&&this.onError(s)}finally{this.isProcessingBatch=!1,this.batchQueue.length>0&&this.processBatch()}}async sendBatch(t){let s;switch(this.batchMode){case"array":{const i=t.map(a=>JSON.parse(a));s=JSON.stringify(i);break}case"field":{const i=t.map(r=>JSON.parse(r)),a=this.batchFieldName?{[this.batchFieldName]:i}:{};s=JSON.stringify(a);break}default:{s=t.join(this.batchSendDelimiter);break}}await this.sendPayload(s,this.batchContentType)}async sendPayload(t,s){const i=typeof this.headers=="function"?this.headers():{...this.headers};i["content-type"]??=s??this.contentType;let a=t;if(this.compression&&!this.edgeCompat)try{a=await w(t),i["content-encoding"]="gzip"}catch(r){this.onError&&this.onError(new Error(`Compression failed: ${String(r)}`))}await M(this.url,this.method,i,a,this.maxRetries,this.retryDelay,this.respectRateLimit,this.onDebugRequestResponse,this.onError)}}export{k as AbstractHttpReporter};
@@ -1,44 +1,43 @@
1
1
  import { AbstractHttpReporterOptions, AbstractHttpReporter } from "./abstract-http-reporter.js";
2
- import 'type-fest';
3
- import "../../packem_shared/types.d-bWnqHJKL.js";
2
+ import "../../packem_shared/types.d-4ge_rME4.js";
4
3
  import '@visulima/colorize';
5
4
  import '@visulima/interactive-manager';
6
- import "../../packem_shared/abstract-json-reporter.d-wfESoEa-.js";
5
+ import "../../packem_shared/abstract-json-reporter.d-B6NoO-hG.js";
7
6
  import "../../packem_shared/index.d-T71KjNAr.js";
8
7
  /**
9
- * HTTP Reporter.
10
- *
11
- * A reporter that sends logs to HTTP endpoints.
12
- * Supports batching, compression, retries, and rate limiting.
13
- * Works in both Node.js server and browser environments.
14
- * @template L - The log level type
15
- * @example
16
- * ```typescript
17
- * import { createPail } from "@visulima/pail";
18
- * import { HttpReporter } from "@visulima/pail/reporter/http";
19
- *
20
- * const logger = createPail({
21
- * reporters: [
22
- * new HttpReporter({
23
- * url: "https://api.example.com/logs",
24
- * method: "POST",
25
- * headers: {
26
- * "Authorization": "Bearer token"
27
- * },
28
- * enableBatchSend: true,
29
- * batchSize: 100
30
- * })
31
- * ]
32
- * });
33
- *
34
- * logger.info("Application started", { version: "1.0.0" });
35
- * ```
36
- */
8
+ * HTTP Reporter.
9
+ *
10
+ * A reporter that sends logs to HTTP endpoints.
11
+ * Supports batching, compression, retries, and rate limiting.
12
+ * Works in both Node.js server and browser environments.
13
+ * @template L - The log level type
14
+ * @example
15
+ * ```typescript
16
+ * import { createPail } from "@visulima/pail";
17
+ * import { HttpReporter } from "@visulima/pail/reporter/http";
18
+ *
19
+ * const logger = createPail({
20
+ * reporters: [
21
+ * new HttpReporter({
22
+ * url: "https://api.example.com/logs",
23
+ * method: "POST",
24
+ * headers: {
25
+ * "Authorization": "Bearer token"
26
+ * },
27
+ * enableBatchSend: true,
28
+ * batchSize: 100
29
+ * })
30
+ * ]
31
+ * });
32
+ *
33
+ * logger.info("Application started", { version: "1.0.0" });
34
+ * ```
35
+ */
37
36
  declare class HttpReporter<L extends string = string> extends AbstractHttpReporter<L> {
38
37
  /**
39
- * Creates a new HTTP Reporter instance.
40
- * @param options Configuration options for HTTP reporting
41
- */
38
+ * Creates a new HTTP Reporter instance.
39
+ * @param options Configuration options for HTTP reporting
40
+ */
42
41
  constructor(options: AbstractHttpReporterOptions);
43
42
  }
44
43
  export { HttpReporter as default };