@liiift-studio/sanity-visitor-insights 0.63.0 → 0.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2074,38 +2074,62 @@ function OverviewPanel({ data, previous, onBrush }) {
2074
2074
  source: "GA4",
2075
2075
  complete: true,
2076
2076
  unit: "percent",
2077
- // Fixed, not scaled to its own best day — otherwise a site at a flat 20%
2078
- // draws a full-height line and reads as healthy.
2079
- domain: [0, 1],
2077
+ // Fixed at the bottom, open at the top.
2078
+ //
2079
+ // The lower bound is fixed so a site at a flat 20% cannot scale itself
2080
+ // to full height and read as healthy. The UPPER bound is not clamped,
2081
+ // because over-counting is a real fault with its own interpretation
2082
+ // branch — and the card further down this very file refuses the same
2083
+ // clamp in prose, saying `Math.min(1, …)` rendered a tag reporting
2084
+ // 250% of reality as a flat 100% under the heading "How much GA4 is
2085
+ // seeing", i.e. perfect. One quantity, two opposite policies, one
2086
+ // file: the row drew a double-firing tag as a healthy flat line while
2087
+ // the sentence beside it called the over-count out.
2088
+ domain: [0, Math.max(1, ...(data.crossSource ?? []).map((d) => d.vercelPageviews !== null && d.ga4Pageviews !== null && d.vercelPageviews > 0 ? d.ga4Pageviews / d.vercelPageviews : 0))],
2080
2089
  points: (data.crossSource ?? []).map((d) => ({
2081
2090
  date: d.date,
2082
- value: d.vercelPageviews !== null && d.ga4Pageviews !== null && d.vercelPageviews > 0 ? Math.min(1, d.ga4Pageviews / d.vercelPageviews) : null
2091
+ value: d.vercelPageviews !== null && d.ga4Pageviews !== null && d.vercelPageviews > 0 ? d.ga4Pageviews / d.vercelPageviews : null
2083
2092
  })),
2084
2093
  // The most valuable ghost in the chart: a collapse reads as a step away
2085
2094
  // from last period's flat line, whether or not the detector fired.
2086
2095
  comparison: (previous?.crossSource ?? []).map((d) => ({
2087
2096
  date: d.date,
2088
- value: d.vercelPageviews !== null && d.ga4Pageviews !== null && d.vercelPageviews > 0 ? Math.min(1, d.ga4Pageviews / d.vercelPageviews) : null
2097
+ value: d.vercelPageviews !== null && d.ga4Pageviews !== null && d.vercelPageviews > 0 ? d.ga4Pageviews / d.vercelPageviews : null
2089
2098
  }))
2090
2099
  }] : [],
2091
- ...data.crossSource?.some((d) => d.revenue !== null) ? [{
2092
- key: "revenue",
2093
- label: "Revenue",
2094
- source: "Sanity",
2095
- complete: true,
2096
- unit: "money",
2097
- // A sale is an event on a date, not a level that varies day to day.
2098
- mark: "events",
2099
- points: (data.crossSource ?? []).map((d) => ({ date: d.date, value: d.revenue }))
2100
- }] : [{
2100
+ // ORDERS ALWAYS, revenue only when it covers every order.
2101
+ //
2102
+ // This used to draw revenue whenever ANY day had a revenue figure, and
2103
+ // otherwise orders — never both. Combined with the server filling a day's
2104
+ // revenue as `revenueByDate[date] ?? 0`, that meant a day carrying a real
2105
+ // order with no recorded amount arrived as a measured ZERO, and the row drew
2106
+ // a zero-tick on it: the mark whose own comment says "measured, and it was
2107
+ // nothing".
2108
+ //
2109
+ // At Darden 11 of 69 orders carry an amount, so the flagship chart was
2110
+ // asserting that no sale happened on 58 days that had sales — the package's
2111
+ // founding distinction inverted inside its most prominent encoding. Orders
2112
+ // are exact and complete whatever the amounts say, so they are the row that
2113
+ // is always honest.
2114
+ {
2101
2115
  key: "orders",
2102
2116
  label: "Orders",
2103
2117
  source: "Sanity",
2104
2118
  complete: true,
2105
2119
  unit: "count",
2120
+ // A sale is an event on a date, not a level that varies day to day.
2106
2121
  mark: "events",
2107
2122
  points: (data.crossSource ?? []).map((d) => ({ date: d.date, value: d.orders }))
2108
- }]
2123
+ },
2124
+ ...revenueCoversEveryOrder(data) ? [{
2125
+ key: "revenue",
2126
+ label: "Revenue",
2127
+ source: "Sanity",
2128
+ complete: true,
2129
+ unit: "money",
2130
+ mark: "events",
2131
+ points: (data.crossSource ?? []).map((d) => ({ date: d.date, value: d.revenue }))
2132
+ }] : []
2109
2133
  ]
2110
2134
  }
2111
2135
  ),
@@ -2679,6 +2703,12 @@ function SegmentTable({ segments, dimension }) {
2679
2703
  ] }) })
2680
2704
  ] });
2681
2705
  }
2706
+ function revenueCoversEveryOrder(data) {
2707
+ const counted = metricSortValue(data.orders);
2708
+ const withTotal = finiteOrNull(data.ordersWithTotal);
2709
+ if (counted === null || withTotal === null) return false;
2710
+ return counted === withTotal;
2711
+ }
2682
2712
  function JourneyPanel({ data }) {
2683
2713
  const segments = data.segments ?? [];
2684
2714
  const allSteps = data.steps ?? [];