@flotrace/runtime 0.2.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -579,6 +579,19 @@ function safeTrackerOp(name, op) {
579
579
  console.error(`[FloTrace] ${name}:`, error);
580
580
  }
581
581
  }
582
+ function deriveWebAppName() {
583
+ if (typeof document !== "undefined") {
584
+ const metaName = document.querySelector('meta[name="application-name"]')?.getAttribute("content")?.trim();
585
+ if (metaName) return metaName;
586
+ const title = document.title?.trim();
587
+ if (title) return title;
588
+ }
589
+ if (typeof location !== "undefined" && location.hostname) return location.hostname;
590
+ return import_runtime_core3.DEFAULT_CONFIG.appName;
591
+ }
592
+ function deriveWebAppId() {
593
+ return typeof location !== "undefined" && location.origin ? location.origin : "web-app";
594
+ }
582
595
  var FloTraceContext = (0, import_react.createContext)(null);
583
596
  function useFloTrace() {
584
597
  return (0, import_react.useContext)(FloTraceContext);
@@ -590,13 +603,20 @@ function FloTraceProvider({ children, config = {}, stores, reduxStore, queryClie
590
603
  );
591
604
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
592
605
  }
606
+ const framework = (0, import_runtime_core3.detectWebFramework)();
593
607
  const mergedConfig = {
594
608
  ...import_runtime_core3.DEFAULT_CONFIG,
595
609
  // Web default: expose the current page URL as the `appUrl` in runtime:ready.
596
610
  // Runtime-core defaults this to undefined so it stays platform-agnostic.
597
611
  getAppUrl: () => typeof window !== "undefined" ? window.location.href : void 0,
598
612
  platform: "web",
599
- ...config
613
+ ...config,
614
+ // Derived values fill in only when the user didn't supply a static one.
615
+ // Placed AFTER `...config` so explicit user values still win via `??`.
616
+ appName: config.appName ?? deriveWebAppName(),
617
+ appId: config.appId ?? deriveWebAppId(),
618
+ frameworkName: config.frameworkName ?? framework.frameworkName,
619
+ frameworkVersion: config.frameworkVersion ?? framework.frameworkVersion
600
620
  };
601
621
  const [connected, setConnected] = import_react.default.useState(false);
602
622
  const trackingOptionsRef = (0, import_react.useRef)({});
@@ -631,8 +651,12 @@ function FloTraceProvider({ children, config = {}, stores, reduxStore, queryClie
631
651
  const unsubMessage = client3.onMessage((message) => {
632
652
  try {
633
653
  switch (message.type) {
654
+ // Heartbeat liveness is handled by the dedicated `runtime:pong` path
655
+ // in websocketClient. We intentionally do NOT re-send `runtime:ready`
656
+ // on every `ext:ping` — a truncated ready (only appName, no appId /
657
+ // platform / versions) would clobber the server's client registry
658
+ // metadata on every 5s tick. The initial `onopen` ready is authoritative.
634
659
  case "ext:ping":
635
- client3.sendImmediate({ type: "runtime:ready", appName: mergedConfig.appName });
636
660
  break;
637
661
  case "ext:startTracking":
638
662
  trackingOptionsRef.current = message.options || {};
package/dist/index.mjs CHANGED
@@ -25,7 +25,8 @@ import {
25
25
  uninstallTanStackQueryTracker,
26
26
  installTimelineTracker,
27
27
  uninstallTimelineTracker,
28
- getTimeline
28
+ getTimeline,
29
+ detectWebFramework
29
30
  } from "@flotrace/runtime-core";
30
31
 
31
32
  // src/routerTracker.ts
@@ -566,6 +567,19 @@ function safeTrackerOp(name, op) {
566
567
  console.error(`[FloTrace] ${name}:`, error);
567
568
  }
568
569
  }
570
+ function deriveWebAppName() {
571
+ if (typeof document !== "undefined") {
572
+ const metaName = document.querySelector('meta[name="application-name"]')?.getAttribute("content")?.trim();
573
+ if (metaName) return metaName;
574
+ const title = document.title?.trim();
575
+ if (title) return title;
576
+ }
577
+ if (typeof location !== "undefined" && location.hostname) return location.hostname;
578
+ return DEFAULT_CONFIG.appName;
579
+ }
580
+ function deriveWebAppId() {
581
+ return typeof location !== "undefined" && location.origin ? location.origin : "web-app";
582
+ }
569
583
  var FloTraceContext = createContext(null);
570
584
  function useFloTrace() {
571
585
  return useContext(FloTraceContext);
@@ -577,13 +591,20 @@ function FloTraceProvider({ children, config = {}, stores, reduxStore, queryClie
577
591
  );
578
592
  return /* @__PURE__ */ jsx(Fragment, { children });
579
593
  }
594
+ const framework = detectWebFramework();
580
595
  const mergedConfig = {
581
596
  ...DEFAULT_CONFIG,
582
597
  // Web default: expose the current page URL as the `appUrl` in runtime:ready.
583
598
  // Runtime-core defaults this to undefined so it stays platform-agnostic.
584
599
  getAppUrl: () => typeof window !== "undefined" ? window.location.href : void 0,
585
600
  platform: "web",
586
- ...config
601
+ ...config,
602
+ // Derived values fill in only when the user didn't supply a static one.
603
+ // Placed AFTER `...config` so explicit user values still win via `??`.
604
+ appName: config.appName ?? deriveWebAppName(),
605
+ appId: config.appId ?? deriveWebAppId(),
606
+ frameworkName: config.frameworkName ?? framework.frameworkName,
607
+ frameworkVersion: config.frameworkVersion ?? framework.frameworkVersion
587
608
  };
588
609
  const [connected, setConnected] = React.useState(false);
589
610
  const trackingOptionsRef = useRef({});
@@ -618,8 +639,12 @@ function FloTraceProvider({ children, config = {}, stores, reduxStore, queryClie
618
639
  const unsubMessage = client3.onMessage((message) => {
619
640
  try {
620
641
  switch (message.type) {
642
+ // Heartbeat liveness is handled by the dedicated `runtime:pong` path
643
+ // in websocketClient. We intentionally do NOT re-send `runtime:ready`
644
+ // on every `ext:ping` — a truncated ready (only appName, no appId /
645
+ // platform / versions) would clobber the server's client registry
646
+ // metadata on every 5s tick. The initial `onopen` ready is authoritative.
621
647
  case "ext:ping":
622
- client3.sendImmediate({ type: "runtime:ready", appName: mergedConfig.appName });
623
648
  break;
624
649
  case "ext:startTracking":
625
650
  trackingOptionsRef.current = message.options || {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flotrace/runtime",
3
- "version": "0.2.0",
3
+ "version": "2.0.2",
4
4
  "description": "Runtime package for FloTrace - enables real-time render tracking in your React app",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -26,7 +26,7 @@
26
26
  "release:major": "npm version major && npm publish"
27
27
  },
28
28
  "dependencies": {
29
- "@flotrace/runtime-core": "0.1.0"
29
+ "@flotrace/runtime-core": "2.0.1"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": ">=16.9.0",