@blyp/core 0.1.2 → 0.1.21

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 (124) hide show
  1. package/README.md +56 -3
  2. package/dist/astro.js +4602 -0
  3. package/dist/astro.js.map +1 -0
  4. package/dist/astro.mjs +4574 -0
  5. package/dist/astro.mjs.map +1 -0
  6. package/dist/client.js +7 -0
  7. package/dist/client.js.map +1 -1
  8. package/dist/client.mjs +7 -0
  9. package/dist/client.mjs.map +1 -1
  10. package/dist/connectors/betterstack.js +24 -0
  11. package/dist/connectors/betterstack.js.map +1 -1
  12. package/dist/connectors/betterstack.mjs +24 -0
  13. package/dist/connectors/betterstack.mjs.map +1 -1
  14. package/dist/connectors/databuddy/index.d.ts +7 -0
  15. package/dist/connectors/databuddy/sender.d.ts +5 -0
  16. package/dist/connectors/databuddy.js +1456 -0
  17. package/dist/connectors/databuddy.js.map +1 -0
  18. package/dist/connectors/databuddy.mjs +1451 -0
  19. package/dist/connectors/databuddy.mjs.map +1 -0
  20. package/dist/connectors/otlp.js +24 -0
  21. package/dist/connectors/otlp.js.map +1 -1
  22. package/dist/connectors/otlp.mjs +24 -0
  23. package/dist/connectors/otlp.mjs.map +1 -1
  24. package/dist/connectors/posthog.js +24 -0
  25. package/dist/connectors/posthog.js.map +1 -1
  26. package/dist/connectors/posthog.mjs +24 -0
  27. package/dist/connectors/posthog.mjs.map +1 -1
  28. package/dist/connectors/sentry.js +24 -0
  29. package/dist/connectors/sentry.js.map +1 -1
  30. package/dist/connectors/sentry.mjs +24 -0
  31. package/dist/connectors/sentry.mjs.map +1 -1
  32. package/dist/core/config.d.ts +1 -1
  33. package/dist/core/logger.d.ts +3 -0
  34. package/dist/elysia.js +455 -30
  35. package/dist/elysia.js.map +1 -1
  36. package/dist/elysia.mjs +455 -30
  37. package/dist/elysia.mjs.map +1 -1
  38. package/dist/expo.js +7 -0
  39. package/dist/expo.js.map +1 -1
  40. package/dist/expo.mjs +7 -0
  41. package/dist/expo.mjs.map +1 -1
  42. package/dist/express.js +455 -30
  43. package/dist/express.js.map +1 -1
  44. package/dist/express.mjs +455 -30
  45. package/dist/express.mjs.map +1 -1
  46. package/dist/fastify.js +455 -30
  47. package/dist/fastify.js.map +1 -1
  48. package/dist/fastify.mjs +455 -30
  49. package/dist/fastify.mjs.map +1 -1
  50. package/dist/frameworks/astro/index.d.ts +2 -0
  51. package/dist/frameworks/astro/logger.d.ts +3 -0
  52. package/dist/frameworks/nitro/index.d.ts +2 -0
  53. package/dist/frameworks/nitro/logger.d.ts +6 -0
  54. package/dist/frameworks/nuxt/index.d.ts +2 -0
  55. package/dist/frameworks/nuxt/logger.d.ts +3 -0
  56. package/dist/frameworks/react-router/index.d.ts +2 -0
  57. package/dist/frameworks/react-router/logger.d.ts +3 -0
  58. package/dist/frameworks/shared/h3.d.ts +19 -0
  59. package/dist/hono.js +455 -30
  60. package/dist/hono.js.map +1 -1
  61. package/dist/hono.mjs +455 -30
  62. package/dist/hono.mjs.map +1 -1
  63. package/dist/index.d.ts +11 -1
  64. package/dist/index.js +1142 -78
  65. package/dist/index.js.map +1 -1
  66. package/dist/index.mjs +1135 -79
  67. package/dist/index.mjs.map +1 -1
  68. package/dist/nestjs.js +455 -30
  69. package/dist/nestjs.js.map +1 -1
  70. package/dist/nestjs.mjs +455 -30
  71. package/dist/nestjs.mjs.map +1 -1
  72. package/dist/nextjs.js +455 -30
  73. package/dist/nextjs.js.map +1 -1
  74. package/dist/nextjs.mjs +455 -30
  75. package/dist/nextjs.mjs.map +1 -1
  76. package/dist/nitro.js +4726 -0
  77. package/dist/nitro.js.map +1 -0
  78. package/dist/nitro.mjs +4698 -0
  79. package/dist/nitro.mjs.map +1 -0
  80. package/dist/nuxt.js +4733 -0
  81. package/dist/nuxt.js.map +1 -0
  82. package/dist/nuxt.mjs +4705 -0
  83. package/dist/nuxt.mjs.map +1 -0
  84. package/dist/react-router.js +4644 -0
  85. package/dist/react-router.js.map +1 -0
  86. package/dist/react-router.mjs +4616 -0
  87. package/dist/react-router.mjs.map +1 -0
  88. package/dist/standalone.js +423 -53
  89. package/dist/standalone.js.map +1 -1
  90. package/dist/standalone.mjs +423 -53
  91. package/dist/standalone.mjs.map +1 -1
  92. package/dist/sveltekit.js +455 -30
  93. package/dist/sveltekit.js.map +1 -1
  94. package/dist/sveltekit.mjs +455 -30
  95. package/dist/sveltekit.mjs.map +1 -1
  96. package/dist/tanstack-start.js +455 -30
  97. package/dist/tanstack-start.js.map +1 -1
  98. package/dist/tanstack-start.mjs +455 -30
  99. package/dist/tanstack-start.mjs.map +1 -1
  100. package/dist/types/connectors/databuddy.d.ts +52 -0
  101. package/dist/types/core/config.d.ts +32 -0
  102. package/dist/types/core/logger.d.ts +2 -0
  103. package/dist/types/frameworks/astro.d.ts +32 -0
  104. package/dist/types/frameworks/nitro.d.ts +62 -0
  105. package/dist/types/frameworks/nuxt.d.ts +12 -0
  106. package/dist/types/frameworks/react-router.d.ts +33 -0
  107. package/dist/types/frameworks/shared.d.ts +24 -0
  108. package/dist/types/shared/client-log.d.ts +1 -1
  109. package/exports/connectors/databuddy.js +1 -0
  110. package/exports/connectors/databuddy.mjs +1 -0
  111. package/exports/frameworks/astro.js +1 -0
  112. package/exports/frameworks/astro.mjs +1 -0
  113. package/exports/frameworks/nitro.js +1 -0
  114. package/exports/frameworks/nitro.mjs +1 -0
  115. package/exports/frameworks/nuxt.js +1 -0
  116. package/exports/frameworks/nuxt.mjs +1 -0
  117. package/exports/frameworks/react-router.js +1 -0
  118. package/exports/frameworks/react-router.mjs +1 -0
  119. package/package.json +59 -2
  120. package/types/connectors/databuddy.d.ts +1 -0
  121. package/types/frameworks/astro.d.ts +1 -0
  122. package/types/frameworks/nitro.d.ts +1 -0
  123. package/types/frameworks/nuxt.d.ts +1 -0
  124. package/types/frameworks/react-router.d.ts +1 -0
package/dist/elysia.mjs CHANGED
@@ -14,6 +14,7 @@ import { AsyncLocalStorage } from 'async_hooks';
14
14
  import { randomUUID } from 'crypto';
15
15
  import * as Sentry from '@sentry/node';
16
16
  import { Logtail } from '@logtail/node';
17
+ import { Databuddy } from '@databuddy/sdk/node';
17
18
 
18
19
  var __defProp = Object.defineProperty;
19
20
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -333,6 +334,7 @@ var CLIENT_LOG_LEVELS = [
333
334
  ];
334
335
  var clientConnectorRequestSchema = z.union([
335
336
  z.literal("betterstack"),
337
+ z.literal("databuddy"),
336
338
  z.literal("posthog"),
337
339
  z.literal("sentry"),
338
340
  z.undefined(),
@@ -373,16 +375,16 @@ function normalizeEndpointPath(path3) {
373
375
  }
374
376
 
375
377
  // src/shared/once.ts
376
- function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()) {
378
+ function createConsoleOnceLogger(method, warnedKeys7 = /* @__PURE__ */ new Set()) {
377
379
  return (key, message, error) => {
378
- if (warnedKeys6.has(key) || typeof console === "undefined") {
380
+ if (warnedKeys7.has(key) || typeof console === "undefined") {
379
381
  return;
380
382
  }
381
383
  const writer = console[method];
382
384
  if (typeof writer !== "function") {
383
385
  return;
384
386
  }
385
- warnedKeys6.add(key);
387
+ warnedKeys7.add(key);
386
388
  if (error === void 0) {
387
389
  writer.call(console, message);
388
390
  return;
@@ -390,11 +392,11 @@ function createConsoleOnceLogger(method, warnedKeys6 = /* @__PURE__ */ new Set()
390
392
  writer.call(console, message, error);
391
393
  };
392
394
  }
393
- function createWarnOnceLogger(warnedKeys6) {
394
- return createConsoleOnceLogger("warn", warnedKeys6);
395
+ function createWarnOnceLogger(warnedKeys7) {
396
+ return createConsoleOnceLogger("warn", warnedKeys7);
395
397
  }
396
- function createErrorOnceLogger(warnedKeys6) {
397
- return createConsoleOnceLogger("error", warnedKeys6);
398
+ function createErrorOnceLogger(warnedKeys7) {
399
+ return createConsoleOnceLogger("error", warnedKeys7);
398
400
  }
399
401
 
400
402
  // src/core/config.ts
@@ -760,6 +762,28 @@ function mergePostHogConnectorConfig(base, override) {
760
762
  }
761
763
  };
762
764
  }
765
+ function mergeDatabuddyConnectorConfig(base, override) {
766
+ const enabled = override?.enabled ?? base?.enabled ?? false;
767
+ const apiKey = override?.apiKey ?? base?.apiKey;
768
+ const websiteId = override?.websiteId ?? base?.websiteId;
769
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
770
+ return {
771
+ enabled,
772
+ mode: override?.mode ?? base?.mode ?? "auto",
773
+ apiKey,
774
+ websiteId,
775
+ namespace: override?.namespace ?? base?.namespace,
776
+ source: override?.source ?? base?.source,
777
+ apiUrl: override?.apiUrl ?? base?.apiUrl,
778
+ debug: override?.debug ?? base?.debug ?? false,
779
+ enableBatching: override?.enableBatching ?? base?.enableBatching ?? true,
780
+ batchSize: override?.batchSize ?? base?.batchSize,
781
+ batchTimeout: override?.batchTimeout ?? base?.batchTimeout,
782
+ maxQueueSize: override?.maxQueueSize ?? base?.maxQueueSize,
783
+ ready,
784
+ status: ready ? "enabled" : "missing"
785
+ };
786
+ }
763
787
  function mergeBetterStackConnectorConfig(base, override) {
764
788
  const sourceToken = override?.sourceToken ?? base?.sourceToken;
765
789
  const ingestingHost = override?.ingestingHost ?? base?.ingestingHost;
@@ -850,6 +874,7 @@ function mergeOTLPConnectorsConfig(base, override) {
850
874
  function mergeConnectorsConfig(base, override) {
851
875
  return {
852
876
  betterstack: mergeBetterStackConnectorConfig(base?.betterstack, override?.betterstack),
877
+ databuddy: mergeDatabuddyConnectorConfig(base?.databuddy, override?.databuddy),
853
878
  posthog: mergePostHogConnectorConfig(base?.posthog, override?.posthog),
854
879
  sentry: mergeSentryConnectorConfig(base?.sentry, override?.sentry),
855
880
  otlp: mergeOTLPConnectorsConfig(base?.otlp, override?.otlp)
@@ -2507,12 +2532,320 @@ function createBetterStackSender(config) {
2507
2532
  };
2508
2533
  }
2509
2534
  var warnedKeys4 = /* @__PURE__ */ new Set();
2535
+ var senderCache = /* @__PURE__ */ new Map();
2510
2536
  var testHooks3 = {};
2511
2537
  var warnOnce5 = createErrorOnceLogger(warnedKeys4);
2512
- function getSentryModule2() {
2513
- return testHooks3.module ?? Sentry;
2538
+ function registerShutdownHooks3(key, shutdown) {
2539
+ const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2540
+ for (const event of handlers) {
2541
+ process.once(event, () => {
2542
+ void shutdown().catch((error) => {
2543
+ warnOnce5(
2544
+ `${key}:shutdown`,
2545
+ "[Blyp] Failed to flush Databuddy telemetry during shutdown.",
2546
+ error
2547
+ );
2548
+ });
2549
+ });
2550
+ }
2514
2551
  }
2515
2552
  function resolveConnectorConfig3(config) {
2553
+ const connector = isBlypConfig(config) ? config.connectors?.databuddy : config;
2554
+ const enabled = connector?.enabled ?? false;
2555
+ const apiKey = connector?.apiKey;
2556
+ const websiteId = connector?.websiteId;
2557
+ const ready = enabled && hasNonEmptyString(apiKey) && hasNonEmptyString(websiteId);
2558
+ return {
2559
+ enabled,
2560
+ mode: connector?.mode ?? "auto",
2561
+ apiKey,
2562
+ websiteId,
2563
+ namespace: connector?.namespace,
2564
+ source: connector?.source,
2565
+ apiUrl: connector?.apiUrl,
2566
+ debug: connector?.debug ?? false,
2567
+ enableBatching: connector?.enableBatching ?? true,
2568
+ batchSize: connector?.batchSize,
2569
+ batchTimeout: connector?.batchTimeout,
2570
+ maxQueueSize: connector?.maxQueueSize,
2571
+ ready,
2572
+ status: ready ? "enabled" : "missing"
2573
+ };
2574
+ }
2575
+ function createDefaultClient2(connector) {
2576
+ return new Databuddy({
2577
+ apiKey: connector.apiKey ?? "",
2578
+ ...connector.websiteId ? { websiteId: connector.websiteId } : {},
2579
+ ...connector.namespace ? { namespace: connector.namespace } : {},
2580
+ ...connector.source ? { source: connector.source } : {},
2581
+ ...connector.apiUrl ? { apiUrl: connector.apiUrl } : {},
2582
+ debug: connector.debug,
2583
+ enableBatching: connector.enableBatching,
2584
+ ...connector.batchSize !== void 0 ? { batchSize: connector.batchSize } : {},
2585
+ ...connector.batchTimeout !== void 0 ? { batchTimeout: connector.batchTimeout } : {},
2586
+ ...connector.maxQueueSize !== void 0 ? { maxQueueSize: connector.maxQueueSize } : {}
2587
+ });
2588
+ }
2589
+ function getDatabuddySenderKey(connector) {
2590
+ return JSON.stringify({
2591
+ enabled: connector.enabled,
2592
+ mode: connector.mode,
2593
+ apiKey: connector.apiKey ?? null,
2594
+ websiteId: connector.websiteId ?? null,
2595
+ namespace: connector.namespace ?? null,
2596
+ source: connector.source ?? null,
2597
+ apiUrl: connector.apiUrl ?? null,
2598
+ debug: connector.debug,
2599
+ enableBatching: connector.enableBatching,
2600
+ batchSize: connector.batchSize ?? null,
2601
+ batchTimeout: connector.batchTimeout ?? null,
2602
+ maxQueueSize: connector.maxQueueSize ?? null
2603
+ });
2604
+ }
2605
+ function getSessionId(record) {
2606
+ const direct = getField(record, "sessionId");
2607
+ if (hasNonEmptyString(direct)) {
2608
+ return direct;
2609
+ }
2610
+ return getClientSessionField(record, "sessionId");
2611
+ }
2612
+ function getAnonymousId(record) {
2613
+ const direct = getField(record, "anonymousId");
2614
+ if (hasNonEmptyString(direct)) {
2615
+ return direct;
2616
+ }
2617
+ const payload = getPrimaryPayload(record);
2618
+ if (isPlainObject(payload.metadata) && hasNonEmptyString(payload.metadata.databuddyAnonymousId)) {
2619
+ return payload.metadata.databuddyAnonymousId;
2620
+ }
2621
+ return void 0;
2622
+ }
2623
+ function getDatabuddyEventName(record) {
2624
+ const recordType = getRecordType(record);
2625
+ if (hasNonEmptyString(recordType)) {
2626
+ return recordType;
2627
+ }
2628
+ return "log";
2629
+ }
2630
+ function buildRecordProperties(record, source) {
2631
+ const properties = {
2632
+ blyp_level: record.level,
2633
+ blyp_source: source,
2634
+ blyp_payload: serializeLogRecord(record),
2635
+ message: typeof record.message === "string" ? record.message : String(record.message)
2636
+ };
2637
+ const caller = typeof record.caller === "string" ? record.caller : void 0;
2638
+ const groupId = getField(record, "groupId");
2639
+ const method = getField(record, "method");
2640
+ const path3 = getField(record, "path");
2641
+ const status = getField(record, "status");
2642
+ const duration = getField(record, "duration");
2643
+ const pagePath = getClientPageField(record, "pathname");
2644
+ const pageUrl = getClientPageField(record, "url");
2645
+ const sessionId = getClientSessionField(record, "sessionId");
2646
+ const pageId = getClientSessionField(record, "pageId");
2647
+ const ifTruthy = [
2648
+ ["blyp_type", getRecordType(record)],
2649
+ ["caller", caller],
2650
+ ["group_id", groupId],
2651
+ ["method", method],
2652
+ ["path", path3],
2653
+ ["page_path", pagePath],
2654
+ ["page_url", pageUrl],
2655
+ ["session_id", sessionId],
2656
+ ["page_id", pageId]
2657
+ ];
2658
+ const ifDefined = [
2659
+ ["status_code", status],
2660
+ ["duration_ms", duration]
2661
+ ];
2662
+ for (const [key, value] of ifTruthy) {
2663
+ if (value) {
2664
+ properties[key] = value;
2665
+ }
2666
+ }
2667
+ for (const [key, value] of ifDefined) {
2668
+ if (value !== void 0) {
2669
+ properties[key] = value;
2670
+ }
2671
+ }
2672
+ return properties;
2673
+ }
2674
+ function createTrackEvent(record, source) {
2675
+ return {
2676
+ name: getDatabuddyEventName(record),
2677
+ anonymousId: getAnonymousId(record),
2678
+ sessionId: getSessionId(record),
2679
+ properties: buildRecordProperties(record, source)
2680
+ };
2681
+ }
2682
+ function normalizeExceptionProperties2(value) {
2683
+ if (!isPlainObject(value)) {
2684
+ return {};
2685
+ }
2686
+ return normalizeLogValue(value);
2687
+ }
2688
+ function normalizeExceptionInput3(value, fallbackMessage) {
2689
+ if (value instanceof Error) {
2690
+ return {
2691
+ message: value.message || fallbackMessage,
2692
+ properties: {
2693
+ error_type: value.name,
2694
+ ...value.stack ? { stack: value.stack } : {},
2695
+ ...normalizeExceptionProperties2(value)
2696
+ }
2697
+ };
2698
+ }
2699
+ if (isPlainObject(value)) {
2700
+ const message = hasNonEmptyString(value.message) ? value.message : hasNonEmptyString(value.error) ? value.error : fallbackMessage;
2701
+ return {
2702
+ message,
2703
+ properties: normalizeExceptionProperties2(value)
2704
+ };
2705
+ }
2706
+ if (typeof value === "string") {
2707
+ return {
2708
+ message: value,
2709
+ properties: {
2710
+ message: value
2711
+ }
2712
+ };
2713
+ }
2714
+ return {
2715
+ message: fallbackMessage,
2716
+ properties: {
2717
+ value: normalizeLogValue(value)
2718
+ }
2719
+ };
2720
+ }
2721
+ function createDatabuddySender(config) {
2722
+ const connector = resolveConnectorConfig3(config);
2723
+ const senderKey = getDatabuddySenderKey(connector);
2724
+ const cached = senderCache.get(senderKey);
2725
+ if (cached) {
2726
+ return cached;
2727
+ }
2728
+ const key = `${connector.apiUrl ?? "default"}:${connector.mode}:${connector.apiKey ?? "missing"}`;
2729
+ const client = connector.ready ? testHooks3.createClient?.(connector) ?? createDefaultClient2(connector) : void 0;
2730
+ if (client) {
2731
+ registerShutdownHooks3(key, async () => {
2732
+ await client.flush();
2733
+ });
2734
+ }
2735
+ const emitUnavailableWarning = () => {
2736
+ warnOnce5(
2737
+ `databuddy-unavailable:${key}`,
2738
+ "[Blyp] Databuddy connector is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy delivery."
2739
+ );
2740
+ };
2741
+ const emitExceptionUnavailableWarning = () => {
2742
+ warnOnce5(
2743
+ `databuddy-exception-unavailable:${key}`,
2744
+ "[Blyp] Databuddy error tracking is not configured. Databuddy requires both apiKey and websiteId. Skipping Databuddy exception capture."
2745
+ );
2746
+ };
2747
+ const sender = {
2748
+ enabled: connector.enabled,
2749
+ ready: connector.ready,
2750
+ mode: connector.mode,
2751
+ status: connector.status,
2752
+ shouldAutoForwardServerLogs() {
2753
+ return connector.ready && connector.mode === "auto";
2754
+ },
2755
+ shouldAutoCaptureExceptions() {
2756
+ return connector.ready && connector.mode === "auto";
2757
+ },
2758
+ send(record, options = {}) {
2759
+ if (!connector.ready || !client) {
2760
+ if (options.warnIfUnavailable) {
2761
+ emitUnavailableWarning();
2762
+ }
2763
+ return;
2764
+ }
2765
+ try {
2766
+ const result = client.track(createTrackEvent(record, options.source ?? "server"));
2767
+ if (result && typeof result.catch === "function") {
2768
+ void result.catch((error) => {
2769
+ warnOnce5(
2770
+ `databuddy-send:${key}`,
2771
+ "[Blyp] Failed to deliver log to Databuddy.",
2772
+ error
2773
+ );
2774
+ });
2775
+ }
2776
+ } catch (error) {
2777
+ warnOnce5(
2778
+ `databuddy-send:${key}`,
2779
+ "[Blyp] Failed to deliver log to Databuddy.",
2780
+ error
2781
+ );
2782
+ }
2783
+ },
2784
+ captureException(error, options = {}) {
2785
+ if (!connector.ready || !client) {
2786
+ if (options.warnIfUnavailable) {
2787
+ emitExceptionUnavailableWarning();
2788
+ }
2789
+ return;
2790
+ }
2791
+ const normalized = normalizeExceptionInput3(
2792
+ error,
2793
+ options.source === "client" ? "Client error" : "Server error"
2794
+ );
2795
+ try {
2796
+ const result = client.track({
2797
+ name: "error",
2798
+ anonymousId: options.anonymousId,
2799
+ sessionId: options.sessionId,
2800
+ properties: {
2801
+ message: normalized.message,
2802
+ blyp_source: options.source ?? "server",
2803
+ blyp_level: "error",
2804
+ ...normalized.properties,
2805
+ ...options.properties ?? {}
2806
+ }
2807
+ });
2808
+ if (result && typeof result.catch === "function") {
2809
+ void result.catch((captureError) => {
2810
+ warnOnce5(
2811
+ `databuddy-capture:${key}`,
2812
+ "[Blyp] Failed to capture exception in Databuddy.",
2813
+ captureError
2814
+ );
2815
+ });
2816
+ }
2817
+ } catch (captureError) {
2818
+ warnOnce5(
2819
+ `databuddy-capture:${key}`,
2820
+ "[Blyp] Failed to capture exception in Databuddy.",
2821
+ captureError
2822
+ );
2823
+ }
2824
+ },
2825
+ async flush() {
2826
+ try {
2827
+ if (client) {
2828
+ await client.flush();
2829
+ }
2830
+ } catch (error) {
2831
+ warnOnce5(
2832
+ `databuddy-flush:${key}`,
2833
+ "[Blyp] Failed to flush Databuddy telemetry.",
2834
+ error
2835
+ );
2836
+ }
2837
+ }
2838
+ };
2839
+ senderCache.set(senderKey, sender);
2840
+ return sender;
2841
+ }
2842
+ var warnedKeys5 = /* @__PURE__ */ new Set();
2843
+ var testHooks4 = {};
2844
+ var warnOnce6 = createErrorOnceLogger(warnedKeys5);
2845
+ function getSentryModule2() {
2846
+ return testHooks4.module ?? Sentry;
2847
+ }
2848
+ function resolveConnectorConfig4(config) {
2516
2849
  const connector = isBlypConfig(config) ? config.connectors?.sentry : config;
2517
2850
  const enabled = connector?.enabled ?? false;
2518
2851
  const dsn = connector?.dsn;
@@ -2657,7 +2990,7 @@ function hasConfigMismatch(connector, client) {
2657
2990
  return hasNonEmptyString(connector.dsn) && connector.dsn !== options.dsn || hasNonEmptyString(connector.environment) && connector.environment !== options.environment || hasNonEmptyString(connector.release) && connector.release !== options.release;
2658
2991
  }
2659
2992
  function createSentrySender(config) {
2660
- const connector = resolveConnectorConfig3(config);
2993
+ const connector = resolveConnectorConfig4(config);
2661
2994
  const key = `${connector.mode}:${connector.dsn ?? "missing"}`;
2662
2995
  const module = getSentryModule2();
2663
2996
  let client = connector.enabled ? module.getClient() : void 0;
@@ -2671,7 +3004,7 @@ function createSentrySender(config) {
2671
3004
  });
2672
3005
  client = module.getClient();
2673
3006
  } catch (error) {
2674
- warnOnce5(
3007
+ warnOnce6(
2675
3008
  `sentry-init:${key}`,
2676
3009
  "[Blyp] Failed to initialize Sentry. Skipping Sentry delivery.",
2677
3010
  error
@@ -2679,14 +3012,14 @@ function createSentrySender(config) {
2679
3012
  }
2680
3013
  }
2681
3014
  if (client && hasConfigMismatch(connector, client)) {
2682
- warnOnce5(
3015
+ warnOnce6(
2683
3016
  `sentry-mismatch:${key}`,
2684
3017
  "[Blyp] Sentry is already initialized with different options. Reusing the existing Sentry client."
2685
3018
  );
2686
3019
  }
2687
3020
  const ready = connector.enabled && client !== void 0;
2688
3021
  const emitUnavailableWarning = () => {
2689
- warnOnce5(
3022
+ warnOnce6(
2690
3023
  `sentry-unavailable:${key}`,
2691
3024
  "[Blyp] Sentry connector is not configured. Skipping Sentry delivery."
2692
3025
  );
@@ -2712,7 +3045,7 @@ function createSentrySender(config) {
2712
3045
  try {
2713
3046
  logMethod(record.message, attributes);
2714
3047
  } catch (error) {
2715
- warnOnce5(
3048
+ warnOnce6(
2716
3049
  `sentry-log:${key}`,
2717
3050
  "[Blyp] Failed to deliver log to Sentry.",
2718
3051
  error
@@ -2730,7 +3063,7 @@ function createSentrySender(config) {
2730
3063
  module.captureException(exception);
2731
3064
  });
2732
3065
  } catch (error) {
2733
- warnOnce5(
3066
+ warnOnce6(
2734
3067
  `sentry-exception:${key}`,
2735
3068
  "[Blyp] Failed to capture exception in Sentry.",
2736
3069
  error
@@ -2741,7 +3074,7 @@ function createSentrySender(config) {
2741
3074
  try {
2742
3075
  await module.flush(2e3);
2743
3076
  } catch (error) {
2744
- warnOnce5(
3077
+ warnOnce6(
2745
3078
  `sentry-flush:${key}`,
2746
3079
  "[Blyp] Failed to flush Sentry logs.",
2747
3080
  error
@@ -2750,9 +3083,9 @@ function createSentrySender(config) {
2750
3083
  }
2751
3084
  };
2752
3085
  }
2753
- var warnedKeys5 = /* @__PURE__ */ new Set();
2754
- var testHooks4 = {};
2755
- var warnOnce6 = createErrorOnceLogger(warnedKeys5);
3086
+ var warnedKeys6 = /* @__PURE__ */ new Set();
3087
+ var testHooks5 = {};
3088
+ var warnOnce7 = createErrorOnceLogger(warnedKeys6);
2756
3089
  function normalizeOTLPRecord(record, connector, source = "server") {
2757
3090
  const severity = resolveSeverity2(record.level);
2758
3091
  const body = typeof record.message === "string" ? record.message : String(record.message);
@@ -2817,14 +3150,14 @@ function resolveSeverity2(level) {
2817
3150
  return { text: "info", number: SeverityNumber.INFO };
2818
3151
  }
2819
3152
  }
2820
- function registerShutdownHooks3(key, shutdown) {
3153
+ function registerShutdownHooks4(key, shutdown) {
2821
3154
  const handlers = ["beforeExit", "SIGINT", "SIGTERM"];
2822
3155
  for (const event of handlers) {
2823
3156
  process.once(event, async () => {
2824
3157
  try {
2825
3158
  await shutdown();
2826
3159
  } catch (error) {
2827
- warnOnce6(
3160
+ warnOnce7(
2828
3161
  `${key}:shutdown`,
2829
3162
  "[Blyp] Failed to flush OTLP logs during shutdown.",
2830
3163
  error
@@ -2901,7 +3234,7 @@ function createUnavailableSender(name, connector) {
2901
3234
  const senderName = name || connector?.name || "otlp";
2902
3235
  const key = `${senderName}:${connector?.serviceName ?? "blyp-app"}:${connector?.endpoint ?? "missing"}`;
2903
3236
  const emitUnavailableWarning = () => {
2904
- warnOnce6(
3237
+ warnOnce7(
2905
3238
  `otlp-unavailable:${key}`,
2906
3239
  `[Blyp] OTLP target "${senderName}" is not configured or not ready. Skipping OTLP delivery.`
2907
3240
  );
@@ -2932,7 +3265,7 @@ function createSender(connector) {
2932
3265
  ...connector,
2933
3266
  headers: resolveTransportHeaders(connector)
2934
3267
  };
2935
- const transport = testHooks4.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
3268
+ const transport = testHooks5.createTransport?.(transportConnector) ?? createDefaultTransport2(transportConnector);
2936
3269
  return {
2937
3270
  name: connector.name,
2938
3271
  enabled: connector.enabled,
@@ -2948,7 +3281,7 @@ function createSender(connector) {
2948
3281
  const result = transport.emit(normalized);
2949
3282
  if (result && typeof result.catch === "function") {
2950
3283
  void result.catch((error) => {
2951
- warnOnce6(
3284
+ warnOnce7(
2952
3285
  `otlp-emit:${key}`,
2953
3286
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
2954
3287
  error
@@ -2956,7 +3289,7 @@ function createSender(connector) {
2956
3289
  });
2957
3290
  }
2958
3291
  } catch (error) {
2959
- warnOnce6(
3292
+ warnOnce7(
2960
3293
  `otlp-emit:${key}`,
2961
3294
  `[Blyp] Failed to deliver log to OTLP target "${connector.name}".`,
2962
3295
  error
@@ -2969,7 +3302,7 @@ function createSender(connector) {
2969
3302
  await transport.flush();
2970
3303
  }
2971
3304
  } catch (error) {
2972
- warnOnce6(
3305
+ warnOnce7(
2973
3306
  `otlp-flush:${key}`,
2974
3307
  `[Blyp] Failed to flush OTLP logs for target "${connector.name}".`,
2975
3308
  error
@@ -2998,7 +3331,7 @@ function createOTLPRegistry(config) {
2998
3331
  await Promise.all(Array.from(senders.values()).map((sender) => sender.flush()));
2999
3332
  }
3000
3333
  };
3001
- registerShutdownHooks3("otlp-registry", () => registry.flush());
3334
+ registerShutdownHooks4("otlp-registry", () => registry.flush());
3002
3335
  return registry;
3003
3336
  }
3004
3337
  var _RuntimeDetector = class _RuntimeDetector {
@@ -3389,6 +3722,9 @@ function getPostHogSender(logger2) {
3389
3722
  function getBetterStackSender(logger2) {
3390
3723
  return getLoggerFactory(logger2).betterstack;
3391
3724
  }
3725
+ function getDatabuddySender(logger2) {
3726
+ return getLoggerFactory(logger2).databuddy;
3727
+ }
3392
3728
  function tryGetPostHogSender(logger2) {
3393
3729
  try {
3394
3730
  return getPostHogSender(logger2);
@@ -3403,6 +3739,13 @@ function tryGetBetterStackSender(logger2) {
3403
3739
  return null;
3404
3740
  }
3405
3741
  }
3742
+ function tryGetDatabuddySender(logger2) {
3743
+ try {
3744
+ return getDatabuddySender(logger2);
3745
+ } catch {
3746
+ return null;
3747
+ }
3748
+ }
3406
3749
  function getSentrySender(logger2) {
3407
3750
  return getLoggerFactory(logger2).sentry;
3408
3751
  }
@@ -3462,6 +3805,18 @@ function maybeSendToBetterStack(betterstack, record) {
3462
3805
  }
3463
3806
  betterstack.send(record, { source: "server", warnIfUnavailable: true });
3464
3807
  }
3808
+ function maybeSendToDatabuddy(databuddy, record) {
3809
+ if (isClientLogRecord(record)) {
3810
+ return;
3811
+ }
3812
+ if (!databuddy.shouldAutoForwardServerLogs()) {
3813
+ if (databuddy.enabled && !databuddy.ready) {
3814
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3815
+ }
3816
+ return;
3817
+ }
3818
+ databuddy.send(record, { source: "server", warnIfUnavailable: true });
3819
+ }
3465
3820
  function maybeSendToSentry(sentry, record) {
3466
3821
  if (isClientLogRecord(record)) {
3467
3822
  return;
@@ -3482,7 +3837,7 @@ function maybeSendToOTLP(otlp, record) {
3482
3837
  sender.send(record, { source: "server", warnIfUnavailable: true });
3483
3838
  }
3484
3839
  }
3485
- function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry, otlp, bindings = {}, source = "root") {
3840
+ function createLoggerInstance(rootRawLogger, sink, betterstack, databuddy, posthog, sentry, otlp, bindings = {}, source = "root") {
3486
3841
  const rawLogger = Object.keys(bindings).length > 0 ? rootRawLogger.child(bindings) : rootRawLogger;
3487
3842
  const writeRecord = (level, message, args, writeSource = source) => {
3488
3843
  if (writeSource === "root" && shouldDropRootLogWrite()) {
@@ -3508,6 +3863,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3508
3863
  );
3509
3864
  sink.write(record);
3510
3865
  maybeSendToBetterStack(betterstack, record);
3866
+ maybeSendToDatabuddy(databuddy, record);
3511
3867
  maybeSendToPostHog(posthog, record);
3512
3868
  maybeSendToSentry(sentry, record);
3513
3869
  maybeSendToOTLP(otlp, record);
@@ -3531,6 +3887,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3531
3887
  sink.write(record);
3532
3888
  }
3533
3889
  maybeSendToBetterStack(betterstack, record);
3890
+ maybeSendToDatabuddy(databuddy, record);
3534
3891
  maybeSendToPostHog(posthog, record);
3535
3892
  maybeSendToSentry(sentry, record);
3536
3893
  maybeSendToOTLP(otlp, record);
@@ -3564,8 +3921,26 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3564
3921
  }
3565
3922
  writeRecord("table", message, data === void 0 ? [] : [data]);
3566
3923
  },
3567
- flush: () => sink.flush(),
3568
- shutdown: () => sink.shutdown(),
3924
+ flush: async () => {
3925
+ await sink.flush();
3926
+ await Promise.allSettled([
3927
+ betterstack.flush(),
3928
+ databuddy.flush(),
3929
+ posthog.flush(),
3930
+ sentry.flush(),
3931
+ otlp.flush()
3932
+ ]);
3933
+ },
3934
+ shutdown: async () => {
3935
+ await sink.shutdown();
3936
+ await Promise.allSettled([
3937
+ betterstack.flush(),
3938
+ databuddy.flush(),
3939
+ posthog.flush(),
3940
+ sentry.flush(),
3941
+ otlp.flush()
3942
+ ]);
3943
+ },
3569
3944
  createStructuredLog: (groupId, initial) => {
3570
3945
  return createStructuredLogForLogger(logger2, groupId, {
3571
3946
  initialFields: initial
@@ -3577,6 +3952,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3577
3952
  rootRawLogger,
3578
3953
  sink,
3579
3954
  betterstack,
3955
+ databuddy,
3580
3956
  posthog,
3581
3957
  sentry,
3582
3958
  otlp,
@@ -3587,6 +3963,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3587
3963
  [LOGGER_FACTORY]: {
3588
3964
  bindings,
3589
3965
  betterstack,
3966
+ databuddy,
3590
3967
  posthog,
3591
3968
  sentry,
3592
3969
  otlp,
@@ -3596,6 +3973,7 @@ function createLoggerInstance(rootRawLogger, sink, betterstack, posthog, sentry,
3596
3973
  rootRawLogger,
3597
3974
  sink,
3598
3975
  betterstack,
3976
+ databuddy,
3599
3977
  posthog,
3600
3978
  sentry,
3601
3979
  otlp,
@@ -3619,6 +3997,7 @@ function createBaseLogger(config) {
3619
3997
  const rawLogger = createPinoLogger(resolvedConfig);
3620
3998
  const sink = createPrimarySink(resolvedConfig);
3621
3999
  const betterstack = createBetterStackSender(resolvedConfig);
4000
+ const databuddy = createDatabuddySender(resolvedConfig);
3622
4001
  const posthog = createPostHogSender(resolvedConfig);
3623
4002
  const sentry = createSentrySender(resolvedConfig);
3624
4003
  const otlp = createOTLPRegistry(resolvedConfig);
@@ -3626,6 +4005,7 @@ function createBaseLogger(config) {
3626
4005
  rawLogger,
3627
4006
  sink,
3628
4007
  betterstack,
4008
+ databuddy,
3629
4009
  posthog,
3630
4010
  sentry,
3631
4011
  otlp
@@ -3708,6 +4088,7 @@ function resolveServerLogger(config = {}, loggerOverride) {
3708
4088
  return {
3709
4089
  logger: logger2,
3710
4090
  betterstack: getBetterStackSender(logger2),
4091
+ databuddy: getDatabuddySender(logger2),
3711
4092
  posthog: getPostHogSender(logger2),
3712
4093
  sentry: getSentrySender(logger2),
3713
4094
  otlp: getOtlpRegistry(logger2),
@@ -3827,6 +4208,22 @@ function emitHttpErrorLog(logger2, level, request, path3, statusCode, responseTi
3827
4208
  }
3828
4209
  });
3829
4210
  }
4211
+ const databuddy = tryGetDatabuddySender(logger2);
4212
+ if (databuddy?.shouldAutoCaptureExceptions()) {
4213
+ databuddy.captureException(captureContext.error ?? error ?? message, {
4214
+ source: "server",
4215
+ warnIfUnavailable: true,
4216
+ properties: {
4217
+ method: request.method,
4218
+ path: path3,
4219
+ status_code: statusCode,
4220
+ ...request.url ? { current_url: request.url } : {},
4221
+ ...getHeaderValue(request.headers, "user-agent") ? { user_agent: getHeaderValue(request.headers, "user-agent") } : {},
4222
+ ...errorLogData.ip ? { ip: errorLogData.ip } : {},
4223
+ payload: errorLogData
4224
+ }
4225
+ });
4226
+ }
3830
4227
  return errorLogData;
3831
4228
  }
3832
4229
  async function parseClientLogPayload(request, body) {
@@ -3918,6 +4315,34 @@ async function handleClientLogIngestion(options) {
3918
4315
  });
3919
4316
  }
3920
4317
  }
4318
+ } else if (payload.connector === "databuddy") {
4319
+ headers["x-blyp-databuddy-status"] = config.databuddy.ready ? "enabled" : "missing";
4320
+ if (config.databuddy.ready) {
4321
+ const forwardedRecord = {
4322
+ timestamp: structuredPayload.receivedAt,
4323
+ level: payload.level,
4324
+ message: `[client] ${payload.message}`,
4325
+ data: structuredPayload
4326
+ };
4327
+ config.databuddy.send(forwardedRecord, {
4328
+ source: "client"
4329
+ });
4330
+ if ((payload.level === "error" || payload.level === "critical") && config.databuddy.shouldAutoCaptureExceptions()) {
4331
+ const clientErrorCandidate = payload.data && typeof payload.data === "object" && !Array.isArray(payload.data) && typeof payload.data.message === "string" ? payload.data : payload.message;
4332
+ config.databuddy.captureException(clientErrorCandidate, {
4333
+ source: "client",
4334
+ warnIfUnavailable: true,
4335
+ sessionId: payload.session.sessionId,
4336
+ properties: {
4337
+ page_url: payload.page.url,
4338
+ page_path: payload.page.pathname,
4339
+ client_runtime: payload.device?.runtime,
4340
+ metadata: payload.metadata,
4341
+ payload: structuredPayload
4342
+ }
4343
+ });
4344
+ }
4345
+ }
3921
4346
  } else if (payload.connector === "posthog") {
3922
4347
  headers["x-blyp-posthog-status"] = config.posthog.ready ? "enabled" : "missing";
3923
4348
  if (config.posthog.ready) {