vedatrace 0.1.8 → 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.mjs CHANGED
@@ -1,26 +1,60 @@
1
- import { VedaTraceHttpTransport, VedaTraceConsoleTransport } from './transports/index.mjs';
1
+ import { VedaTraceHttpTransportBrowser, VedaTraceHttpTransport, VedaTraceConsoleTransport } from './transports/index.mjs';
2
2
 
3
3
  class VedaTraceBatcher {
4
- constructor(transports, config, onError, onSuccess, immediateFlush = false) {
4
+ constructor(transports, config, immediateFlush = false) {
5
5
  this.transports = transports;
6
6
  this.config = config;
7
- this.onError = onError;
8
- this.onSuccess = onSuccess;
9
7
  this.immediateFlush = immediateFlush;
10
- this.startFlushTimer();
8
+ this.context = config.executionContext;
11
9
  }
12
10
  queue = [];
13
11
  flushTimer = null;
12
+ flushDebounceTimer = null;
14
13
  isFlushing = false;
15
14
  pendingFlush = null;
16
- /** Add log to queue */
15
+ context;
16
+ /** Attach execution context after initialization */
17
+ setContext(ctx) {
18
+ this.context = ctx;
19
+ }
20
+ /** Get current context */
21
+ getContext() {
22
+ return this.context;
23
+ }
24
+ /** Add log to queue with context-aware flush */
17
25
  add(log) {
18
26
  this.queue.push(log);
19
- if (this.immediateFlush || this.queue.length >= this.config.batchSize) {
27
+ if (!this.flushTimer && !this.immediateFlush) {
28
+ this.startFlushTimer();
29
+ }
30
+ if (this.immediateFlush || this.context) {
31
+ this.debouncedFlush();
32
+ } else if (this.queue.length >= this.config.batchSize) {
20
33
  this.flush();
21
34
  }
22
35
  }
23
- /** Flush logs to all transports */
36
+ /** Debounced flush - prevents rapid-fire flushes */
37
+ debouncedFlush() {
38
+ if (this.flushDebounceTimer) {
39
+ clearTimeout(this.flushDebounceTimer);
40
+ }
41
+ this.flushDebounceTimer = setTimeout(() => {
42
+ this.flushDebounceTimer = null;
43
+ this.flush().catch((error) => {
44
+ if (this.config.onError) {
45
+ this.config.onError(
46
+ error instanceof Error ? error : new Error(String(error))
47
+ );
48
+ } else {
49
+ console.error(
50
+ "[VedaTrace] Debounced flush error:",
51
+ error instanceof Error ? error.message : String(error)
52
+ );
53
+ }
54
+ });
55
+ }, 100);
56
+ }
57
+ /** Flush logs to all transports with waitUntil protection */
24
58
  async flush() {
25
59
  if (this.isFlushing) {
26
60
  return this.pendingFlush ?? Promise.resolve();
@@ -31,13 +65,16 @@ class VedaTraceBatcher {
31
65
  this.isFlushing = true;
32
66
  const logsToSend = [...this.queue];
33
67
  this.queue = [];
34
- this.pendingFlush = this.sendWithRetry(logsToSend).finally(() => {
68
+ const flushPromise = this.sendWithRetry(logsToSend).finally(() => {
35
69
  this.isFlushing = false;
36
70
  this.pendingFlush = null;
37
71
  });
38
- return this.pendingFlush;
72
+ this.pendingFlush = flushPromise;
73
+ if (this.context) {
74
+ this.context.waitUntil(flushPromise);
75
+ }
76
+ return flushPromise;
39
77
  }
40
- /** Send logs with retry logic */
41
78
  async sendWithRetry(logs, attempt = 0) {
42
79
  const errors = [];
43
80
  for (const transport of this.transports) {
@@ -55,16 +92,17 @@ class VedaTraceBatcher {
55
92
  const combinedError = new Error(
56
93
  `Failed to send logs after ${this.config.maxRetries} retries: ${errors.map((e) => e.message).join(", ")}`
57
94
  );
58
- if (this.onError) {
59
- this.onError(combinedError);
95
+ if (this.config.onError) {
96
+ this.config.onError(combinedError);
60
97
  } else {
61
98
  console.error("[VedaTrace]", combinedError.message);
62
99
  }
63
100
  return;
64
101
  }
65
- this.onSuccess?.();
102
+ if (this.config.onSuccess) {
103
+ this.config.onSuccess();
104
+ }
66
105
  }
67
- /** Start the flush interval timer */
68
106
  startFlushTimer() {
69
107
  if (this.flushTimer) {
70
108
  clearInterval(this.flushTimer);
@@ -72,8 +110,8 @@ class VedaTraceBatcher {
72
110
  this.flushTimer = setInterval(() => {
73
111
  if (this.queue.length > 0) {
74
112
  this.flush().catch((error) => {
75
- if (this.onError) {
76
- this.onError(
113
+ if (this.config.onError) {
114
+ this.config.onError(
77
115
  error instanceof Error ? error : new Error(String(error))
78
116
  );
79
117
  } else {
@@ -89,30 +127,84 @@ class VedaTraceBatcher {
89
127
  this.flushTimer.unref();
90
128
  }
91
129
  }
92
- /** Stop the flush timer */
93
130
  stop() {
94
131
  if (this.flushTimer) {
95
132
  clearInterval(this.flushTimer);
96
133
  this.flushTimer = null;
97
134
  }
135
+ if (this.flushDebounceTimer) {
136
+ clearTimeout(this.flushDebounceTimer);
137
+ this.flushDebounceTimer = null;
138
+ }
139
+ }
140
+ start() {
141
+ if (!this.flushTimer && !this.immediateFlush) {
142
+ this.startFlushTimer();
143
+ }
98
144
  }
99
- /** Delay helper */
100
145
  delay(ms) {
101
146
  return new Promise((resolve) => setTimeout(resolve, ms));
102
147
  }
103
- /** Get current queue size */
104
148
  getQueueSize() {
105
149
  return this.queue.length;
106
150
  }
151
+ setExecutionContext(ctx) {
152
+ this.context = ctx;
153
+ }
154
+ }
155
+
156
+ function detectRuntime() {
157
+ if (typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers") {
158
+ return "cloudflare";
159
+ }
160
+ const g = globalThis;
161
+ if (g?.Deno && g.Deno.version?.deno) {
162
+ return "deno";
163
+ }
164
+ if (g?.Bun) {
165
+ return "bun";
166
+ }
167
+ if (typeof g?.WebSocketPair !== "undefined") {
168
+ return "cloudflare";
169
+ }
170
+ if (typeof process !== "undefined" && process.versions?.node) {
171
+ return "node";
172
+ }
173
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
174
+ return "browser";
175
+ }
176
+ if (typeof fetch !== "undefined" && typeof window === "undefined" && typeof process === "undefined") {
177
+ return "edge";
178
+ }
179
+ return "edge";
180
+ }
181
+ function isEdgeRuntime() {
182
+ const runtime = detectRuntime();
183
+ return runtime === "cloudflare" || runtime === "deno" || runtime === "bun" || runtime === "edge";
184
+ }
185
+ function isServerless() {
186
+ const runtime = detectRuntime();
187
+ return runtime === "cloudflare" || runtime === "edge";
188
+ }
189
+ function isLongRunning() {
190
+ const runtime = detectRuntime();
191
+ return runtime === "node" || runtime === "bun" || runtime === "deno";
192
+ }
193
+ function isBrowser() {
194
+ return detectRuntime() === "browser";
107
195
  }
108
196
 
109
- const SDK_VERSION = "1.0.0";
197
+ const SDK_VERSION = process.env.npm_package_version ?? "0.0.0";
110
198
  class VedaTraceLogger {
111
199
  batcher = null;
200
+ runtime;
112
201
  config;
113
202
  childDefaults;
203
+ _context;
114
204
  constructor(config = {}, childDefaults = {}) {
205
+ this.runtime = config.runtime ?? detectRuntime();
115
206
  this.childDefaults = childDefaults;
207
+ this._context = config.executionContext;
116
208
  this.config = {
117
209
  service: config.service,
118
210
  apiKey: config.apiKey,
@@ -122,61 +214,68 @@ class VedaTraceLogger {
122
214
  flushInterval: config.flushInterval ?? 5e3,
123
215
  maxRetries: config.maxRetries ?? 3,
124
216
  retryDelay: config.retryDelay ?? 1e3,
125
- onError: config.onError,
126
- onSuccess: config.onSuccess,
127
217
  debug: config.debug ?? false,
128
218
  immediateFlush: config.immediateFlush ?? false,
129
- unrefTimer: config.unrefTimer
219
+ unrefTimer: config.unrefTimer ?? false
130
220
  };
131
221
  if (!config.disabled) {
132
222
  this.initializeBatcher(config);
133
223
  }
134
224
  }
135
- /** Initialize the batcher with transports */
136
225
  initializeBatcher(config) {
137
226
  const transports = config.transports ?? [];
138
- if (config.apiKey && transports.length === 0) ;
139
227
  if (transports.length > 0) {
228
+ const batcherConfig = {
229
+ batchSize: this.config.batchSize,
230
+ flushInterval: this.config.flushInterval,
231
+ maxRetries: this.config.maxRetries,
232
+ retryDelay: this.config.retryDelay,
233
+ unrefTimer: this.config.unrefTimer,
234
+ executionContext: this._context,
235
+ onError: config.onError,
236
+ onSuccess: config.onSuccess
237
+ };
140
238
  this.batcher = new VedaTraceBatcher(
141
239
  transports,
142
- {
143
- batchSize: this.config.batchSize,
144
- flushInterval: this.config.flushInterval,
145
- maxRetries: this.config.maxRetries,
146
- retryDelay: this.config.retryDelay,
147
- unrefTimer: this.config.unrefTimer
148
- },
149
- this.config.onError,
150
- this.config.onSuccess,
240
+ batcherConfig,
151
241
  this.config.immediateFlush
152
242
  );
153
243
  }
154
244
  }
155
- /** Set batcher (called from factory function) */
156
245
  setBatcher(batcher) {
157
246
  this.batcher = batcher;
158
247
  }
159
- /** Log at debug level */
248
+ /** Attach execution context for waitUntil support (Cloudflare Workers / Pages) */
249
+ withContext(ctx) {
250
+ this._context = ctx;
251
+ if (this.batcher) {
252
+ this.batcher.setContext(ctx);
253
+ }
254
+ return this;
255
+ }
256
+ /** Check if context is attached */
257
+ hasContext() {
258
+ return this._context !== void 0;
259
+ }
260
+ /** Get current execution context */
261
+ getContext() {
262
+ return this._context;
263
+ }
160
264
  debug(message, metadata) {
161
265
  this.log("debug", message, metadata);
162
266
  }
163
- /** Log at info level */
164
267
  info(message, metadata) {
165
268
  this.log("info", message, metadata);
166
269
  }
167
- /** Log at warn level */
168
270
  warn(message, metadata) {
169
271
  this.log("warn", message, metadata);
170
272
  }
171
- /** Log at error level */
172
273
  error(message, metadata) {
173
274
  this.log("error", message, metadata);
174
275
  }
175
- /** Log at fatal level */
176
276
  fatal(message, metadata) {
177
277
  this.log("fatal", message, metadata);
178
278
  }
179
- /** Internal log method */
180
279
  log(level, message, metadata) {
181
280
  if (!this.batcher) {
182
281
  return;
@@ -191,7 +290,7 @@ class VedaTraceLogger {
191
290
  timestamp: Date.now(),
192
291
  metadata: cleanMetadata,
193
292
  _sdk: {
194
- source: this.detectEnvironment(),
293
+ source: detectRuntime(),
195
294
  version: SDK_VERSION
196
295
  }
197
296
  };
@@ -204,7 +303,6 @@ class VedaTraceLogger {
204
303
  }
205
304
  this.batcher.add(logEntry);
206
305
  }
207
- /** Create a child logger with default metadata */
208
306
  child(defaults) {
209
307
  const mergedDefaults = { ...this.childDefaults, ...defaults };
210
308
  const childLogger = new VedaTraceLogger(
@@ -213,7 +311,8 @@ class VedaTraceLogger {
213
311
  apiKey: this.config.apiKey,
214
312
  endpoint: this.config.endpoint,
215
313
  environment: this.config.environment,
216
- disabled: !this.batcher
314
+ disabled: !this.batcher,
315
+ executionContext: this._context
217
316
  },
218
317
  mergedDefaults
219
318
  );
@@ -222,27 +321,132 @@ class VedaTraceLogger {
222
321
  }
223
322
  return childLogger;
224
323
  }
225
- /** Flush pending logs */
226
324
  async flush() {
227
325
  if (this.batcher) {
228
- await this.batcher.flush();
326
+ const flushPromise = this.batcher.flush();
327
+ if (this._context) {
328
+ this._context.waitUntil(flushPromise);
329
+ }
330
+ return flushPromise;
229
331
  }
230
332
  }
231
- /** Stop the batcher and flush timer */
232
333
  stop() {
233
334
  if (this.batcher) {
234
335
  this.batcher.stop();
235
336
  }
236
337
  }
237
- /** Detect runtime environment */
238
- detectEnvironment() {
239
- if (typeof globalThis !== "undefined" && "navigator" in globalThis) {
240
- return "browser";
338
+ start() {
339
+ if (this.batcher) {
340
+ this.batcher.start();
241
341
  }
242
- if (typeof process !== "undefined" && process.versions?.node) {
243
- return "node";
342
+ }
343
+ }
344
+
345
+ class BrowserLifecycle {
346
+ constructor(config) {
347
+ this.config = config;
348
+ this.boundVisibilityHandler = this.handleVisibilityChange.bind(this);
349
+ this.boundPageHideHandler = this.handlePageHide.bind(this);
350
+ this.boundBeforeUnloadHandler = this.handleBeforeUnload.bind(this);
351
+ this.boundUnloadHandler = this.handleUnload.bind(this);
352
+ }
353
+ boundVisibilityHandler;
354
+ boundPageHideHandler;
355
+ boundBeforeUnloadHandler;
356
+ boundUnloadHandler;
357
+ isAttached = false;
358
+ pendingFlush = null;
359
+ /** Start listening for browser lifecycle events */
360
+ attach() {
361
+ if (this.isAttached) return;
362
+ if (typeof document !== "undefined") {
363
+ document.addEventListener("visibilitychange", this.boundVisibilityHandler);
364
+ window.addEventListener("pagehide", this.boundPageHideHandler);
365
+ window.addEventListener("beforeunload", this.boundBeforeUnloadHandler);
366
+ window.addEventListener("unload", this.boundUnloadHandler);
367
+ }
368
+ this.isAttached = true;
369
+ if (this.config.debug) {
370
+ console.log("[VedaTrace] Browser lifecycle handlers attached");
371
+ }
372
+ }
373
+ /** Stop listening for browser lifecycle events */
374
+ detach() {
375
+ if (!this.isAttached) return;
376
+ if (typeof document !== "undefined") {
377
+ document.removeEventListener(
378
+ "visibilitychange",
379
+ this.boundVisibilityHandler
380
+ );
381
+ window.removeEventListener("pagehide", this.boundPageHideHandler);
382
+ window.removeEventListener("beforeunload", this.boundBeforeUnloadHandler);
383
+ window.removeEventListener("unload", this.boundUnloadHandler);
384
+ }
385
+ this.isAttached = false;
386
+ if (this.config.debug) {
387
+ console.log("[VedaTrace] Browser lifecycle handlers detached");
244
388
  }
245
- return "edge";
389
+ }
390
+ /** Handle visibility change - flush when page becomes hidden */
391
+ handleVisibilityChange() {
392
+ if (document.visibilityState === "hidden") {
393
+ if (this.config.debug) {
394
+ console.log("[VedaTrace] Page became hidden, flushing logs");
395
+ }
396
+ this.scheduleFlush();
397
+ }
398
+ }
399
+ /** Handle pagehide event - primary flush handler for Safari */
400
+ handlePageHide(event) {
401
+ if (this.config.debug) {
402
+ console.log(
403
+ "[VedaTrace] Page hide event",
404
+ event.persisted ? "(cached)" : "(navigation)"
405
+ );
406
+ }
407
+ if (event.persisted) {
408
+ this.scheduleFlush();
409
+ } else {
410
+ this.finalFlush();
411
+ }
412
+ }
413
+ /** Handle beforeunload - backup flush mechanism */
414
+ handleBeforeUnload(event) {
415
+ if (this.config.debug) {
416
+ console.log("[VedaTrace] Before unload event");
417
+ }
418
+ this.finalFlush();
419
+ }
420
+ /** Handle unload - fallback for older browsers */
421
+ handleUnload() {
422
+ if (this.config.debug) {
423
+ console.log("[VedaTrace] Unload event");
424
+ }
425
+ this.finalFlush();
426
+ }
427
+ /** Schedule a debounced flush (for visibility change) */
428
+ scheduleFlush() {
429
+ if (this.pendingFlush) return;
430
+ this.pendingFlush = this.config.flush().finally(() => {
431
+ this.pendingFlush = null;
432
+ });
433
+ }
434
+ /**
435
+ * Final flush using keepalive fetch
436
+ * For sending logs after the page context is destroyed
437
+ */
438
+ finalFlush() {
439
+ for (const transport of this.config.transports) {
440
+ if (transport.name === "http" && "flush" in transport) {
441
+ transport.flush?.();
442
+ }
443
+ }
444
+ this.config.flush().catch(() => {
445
+ });
446
+ }
447
+ /** Check if handlers are attached */
448
+ isActive() {
449
+ return this.isAttached;
246
450
  }
247
451
  }
248
452
 
@@ -320,26 +524,55 @@ function redactPii(value, mask) {
320
524
  return result;
321
525
  }
322
526
 
527
+ const RUNTIME_FLUSH_INTERVALS = {
528
+ node: 3e3,
529
+ bun: 3e3,
530
+ deno: 3e3,
531
+ browser: 3e3,
532
+ cloudflare: 1e3,
533
+ edge: 1e3
534
+ };
323
535
  function vedatrace(config = {}) {
536
+ const runtime = detectRuntime();
324
537
  const logger = new VedaTraceLogger(config);
325
538
  if (config.apiKey && (!config.transports || config.transports.length === 0)) {
326
- const httpConfig = { apiKey: config.apiKey };
539
+ const isBrowserEnv = isBrowser();
540
+ const isServerlessEnv = isServerless();
541
+ const isLongRunningEnv = isLongRunning();
542
+ const HttpTransport = isBrowserEnv ? VedaTraceHttpTransportBrowser : VedaTraceHttpTransport;
543
+ const httpConfig = {
544
+ apiKey: config.apiKey,
545
+ keepalive: isBrowserEnv
546
+ };
327
547
  if (config.endpoint) httpConfig.endpoint = config.endpoint;
328
- const httpTransport = new VedaTraceHttpTransport(httpConfig);
548
+ const httpTransport = new HttpTransport(httpConfig);
549
+ let immediateFlush = config.immediateFlush ?? false;
550
+ let shouldUnrefTimer = false;
551
+ if (isServerlessEnv) {
552
+ immediateFlush = config.immediateFlush ?? !config.executionContext;
553
+ } else if (isLongRunningEnv) {
554
+ immediateFlush = config.immediateFlush ?? false;
555
+ shouldUnrefTimer = true;
556
+ } else if (isBrowserEnv) {
557
+ immediateFlush = config.immediateFlush ?? false;
558
+ }
559
+ const flushInterval = config.flushInterval ?? RUNTIME_FLUSH_INTERVALS[runtime] ?? 3e3;
329
560
  const batcher = new VedaTraceBatcher(
330
561
  [httpTransport],
331
562
  {
332
563
  batchSize: config.batchSize ?? 100,
333
- flushInterval: config.flushInterval ?? 1e3,
564
+ flushInterval,
334
565
  maxRetries: config.maxRetries ?? 3,
335
566
  retryDelay: config.retryDelay ?? 1e3,
336
- unrefTimer: config.unrefTimer
567
+ unrefTimer: config.unrefTimer ?? shouldUnrefTimer,
568
+ executionContext: config.executionContext,
569
+ onError: config.onError,
570
+ onSuccess: config.onSuccess
337
571
  },
338
- config.onError,
339
- config.onSuccess
572
+ immediateFlush
340
573
  );
341
574
  logger.setBatcher(batcher);
342
- if (typeof process !== "undefined") {
575
+ if (typeof process !== "undefined" && isLongRunningEnv) {
343
576
  const flushLogs = async () => {
344
577
  await batcher.flush();
345
578
  };
@@ -347,6 +580,15 @@ function vedatrace(config = {}) {
347
580
  process.on("SIGTERM", flushLogs);
348
581
  process.on("SIGINT", flushLogs);
349
582
  }
583
+ if (isBrowserEnv) {
584
+ const lifecycle = new BrowserLifecycle({
585
+ transports: [httpTransport],
586
+ flush: () => batcher.flush(),
587
+ debug: config.debug
588
+ });
589
+ lifecycle.attach();
590
+ logger._lifecycle = lifecycle;
591
+ }
350
592
  }
351
593
  return logger;
352
594
  }
@@ -363,4 +605,4 @@ function devVedatrace(config = {}) {
363
605
  });
364
606
  }
365
607
 
366
- export { VedaTraceBatcher, VedaTraceConsoleTransport, VedaTraceHttpTransport, VedaTraceLogger, vedatrace as default, devVedatrace, redact, vedatrace };
608
+ export { BrowserLifecycle, VedaTraceBatcher, VedaTraceConsoleTransport, VedaTraceHttpTransport, VedaTraceHttpTransportBrowser, VedaTraceLogger, vedatrace as default, detectRuntime, devVedatrace, isBrowser, isEdgeRuntime, isLongRunning, isServerless, redact, vedatrace };
@@ -1,5 +1,5 @@
1
1
  import { Request, Response, NextFunction } from 'express';
2
- import { V as VedaTraceLoggerInterface, a as VedaTraceConfig, L as LogMetadata } from '../types-CcdFb-vY.cjs';
2
+ import { V as VedaTraceLoggerInterface, a as VedaTraceConfig, L as LogMetadata } from '../types-BU0UESs9.cjs';
3
3
 
4
4
  /**
5
5
  * Express.js middleware integration for VedaTrace
@@ -1,5 +1,5 @@
1
1
  import { Request, Response, NextFunction } from 'express';
2
- import { V as VedaTraceLoggerInterface, a as VedaTraceConfig, L as LogMetadata } from '../types-CcdFb-vY.mjs';
2
+ import { V as VedaTraceLoggerInterface, a as VedaTraceConfig, L as LogMetadata } from '../types-BU0UESs9.mjs';
3
3
 
4
4
  /**
5
5
  * Express.js middleware integration for VedaTrace
@@ -1,4 +1,4 @@
1
- import { a as VedaTraceConfig, L as LogMetadata, V as VedaTraceLoggerInterface } from '../types-CcdFb-vY.cjs';
1
+ import { a as VedaTraceConfig, L as LogMetadata, V as VedaTraceLoggerInterface } from '../types-BU0UESs9.cjs';
2
2
 
3
3
  /**
4
4
  * Next.js integration for VedaTrace
@@ -1,4 +1,4 @@
1
- import { a as VedaTraceConfig, L as LogMetadata, V as VedaTraceLoggerInterface } from '../types-CcdFb-vY.mjs';
1
+ import { a as VedaTraceConfig, L as LogMetadata, V as VedaTraceLoggerInterface } from '../types-BU0UESs9.mjs';
2
2
 
3
3
  /**
4
4
  * Next.js integration for VedaTrace
@@ -39,10 +39,9 @@ function useVedaTrace() {
39
39
  function useVedaTraceChild(metadata) {
40
40
  const parentLogger = useVedaTrace();
41
41
  const metadataRef = react.useRef(metadata);
42
- const childLogger = react.useMemo(() => {
42
+ return react.useMemo(() => {
43
43
  return parentLogger.child(metadataRef.current);
44
44
  }, [parentLogger]);
45
- return childLogger;
46
45
  }
47
46
  function useVedaTraceLifecycle(componentName, metadata) {
48
47
  const logger = useVedaTrace();
@@ -1,5 +1,5 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
- import { a as VedaTraceConfig, V as VedaTraceLoggerInterface, L as LogMetadata } from '../types-CcdFb-vY.cjs';
2
+ import { a as VedaTraceConfig, V as VedaTraceLoggerInterface, L as LogMetadata } from '../types-BU0UESs9.cjs';
3
3
 
4
4
  /**
5
5
  * React integration for VedaTrace
@@ -1,5 +1,5 @@
1
1
  import { ReactNode, ReactElement } from 'react';
2
- import { a as VedaTraceConfig, V as VedaTraceLoggerInterface, L as LogMetadata } from '../types-CcdFb-vY.mjs';
2
+ import { a as VedaTraceConfig, V as VedaTraceLoggerInterface, L as LogMetadata } from '../types-BU0UESs9.mjs';
3
3
 
4
4
  /**
5
5
  * React integration for VedaTrace
@@ -37,10 +37,9 @@ function useVedaTrace() {
37
37
  function useVedaTraceChild(metadata) {
38
38
  const parentLogger = useVedaTrace();
39
39
  const metadataRef = useRef(metadata);
40
- const childLogger = useMemo(() => {
40
+ return useMemo(() => {
41
41
  return parentLogger.child(metadataRef.current);
42
42
  }, [parentLogger]);
43
- return childLogger;
44
43
  }
45
44
  function useVedaTraceLifecycle(componentName, metadata) {
46
45
  const logger = useVedaTrace();
@@ -82,11 +82,13 @@ class VedaTraceHttpTransport {
82
82
  apiKey;
83
83
  timeout;
84
84
  headers;
85
+ keepalive;
85
86
  constructor(config) {
86
87
  this.apiKey = config.apiKey;
87
88
  this.endpoint = config.endpoint ?? "https://ingest.vedatrace.dev/v1/logs";
88
89
  this.timeout = config.timeout ?? 3e4;
89
90
  this.headers = config.headers ?? {};
91
+ this.keepalive = config.keepalive ?? false;
90
92
  }
91
93
  /** Send logs via HTTP POST */
92
94
  async send(logs) {
@@ -108,7 +110,8 @@ class VedaTraceHttpTransport {
108
110
  ...this.headers
109
111
  },
110
112
  body: JSON.stringify(payload),
111
- signal: controller.signal
113
+ signal: controller.signal,
114
+ keepalive: this.keepalive
112
115
  });
113
116
  clearTimeout(timeoutId);
114
117
  if (!response.ok) {
@@ -126,7 +129,29 @@ class VedaTraceHttpTransport {
126
129
  throw new Error(String(error));
127
130
  }
128
131
  }
132
+ /** Flush pending logs - called on page unload */
133
+ async flush() {
134
+ return Promise.resolve();
135
+ }
136
+ /** Check if keepalive is enabled */
137
+ isKeepaliveEnabled() {
138
+ return this.keepalive;
139
+ }
140
+ /** Enable/disable keepalive */
141
+ setKeepalive(enabled) {
142
+ this.keepalive = enabled;
143
+ }
144
+ }
145
+ class VedaTraceHttpTransportBrowser extends VedaTraceHttpTransport {
146
+ constructor(config) {
147
+ super({ ...config, keepalive: true });
148
+ }
149
+ async flush() {
150
+ this.setKeepalive(true);
151
+ return super.flush();
152
+ }
129
153
  }
130
154
 
131
155
  exports.VedaTraceConsoleTransport = VedaTraceConsoleTransport;
132
156
  exports.VedaTraceHttpTransport = VedaTraceHttpTransport;
157
+ exports.VedaTraceHttpTransportBrowser = VedaTraceHttpTransportBrowser;