@liiift-studio/sanity-visitor-insights 0.14.0 → 0.15.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.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +44 -0
- package/dist/index.mjs.map +1 -1
- package/dist/{ranges-CEHxJQE6.d.mts → ranges-BD8XH1Ef.d.mts} +143 -1
- package/dist/{ranges-CEHxJQE6.d.ts → ranges-BD8XH1Ef.d.ts} +143 -1
- package/dist/server.d.mts +4 -4
- package/dist/server.d.ts +4 -4
- package/dist/server.js +154 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +147 -1
- package/dist/server.mjs.map +1 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/{vercel-CL2w9Jqs.d.mts → vercel-CYZFSqz1.d.mts} +41 -1
- package/dist/{vercel-CL2w9Jqs.d.ts → vercel-CYZFSqz1.d.ts} +41 -1
- package/package.json +1 -1
- package/src/core/capture.ts +206 -0
- package/src/core/core.test.ts +74 -0
- package/src/core/siteConfig.ts +16 -0
- package/src/index.ts +1 -0
- package/src/reportData.ts +13 -0
- package/src/server/orders.ts +107 -0
- package/src/server/reports/measurementHealth.ts +42 -2
- package/src/server.ts +4 -2
- package/src/studio/Figure.tsx +28 -0
- package/src/studio/panels.test.tsx +69 -0
- package/src/studio/panels.tsx +46 -0
- package/src/types.ts +21 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-
|
|
4
|
-
export { C as
|
|
3
|
+
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-BD8XH1Ef.mjs';
|
|
4
|
+
export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as DailyPoint, i as DateRange, j as DiagnosticCheck, E as EventCutover, k as JourneyOutcome, l as JourneyStep, L as LandingPage, P as PREEXISTING, m as REPORT_NAMES, n as ReportError, S as SiteAnalyticsConfig, o as SourceName, p as SourceRow, q as SourceStatus, r as TypefaceInterestRow, U as UnavailableReason, s as coverageForRange, t as estimated, u as isReportName, v as ok, w as partial, x as previousRange, y as resolveRange, z as unavailable, B as validateSiteConfig, F as valueOrNull } from './ranges-BD8XH1Ef.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The Visitor Insights Studio tool.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-
|
|
4
|
-
export { C as
|
|
3
|
+
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-BD8XH1Ef.js';
|
|
4
|
+
export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as DailyPoint, i as DateRange, j as DiagnosticCheck, E as EventCutover, k as JourneyOutcome, l as JourneyStep, L as LandingPage, P as PREEXISTING, m as REPORT_NAMES, n as ReportError, S as SiteAnalyticsConfig, o as SourceName, p as SourceRow, q as SourceStatus, r as TypefaceInterestRow, U as UnavailableReason, s as coverageForRange, t as estimated, u as isReportName, v as ok, w as partial, x as previousRange, y as resolveRange, z as unavailable, B as validateSiteConfig, F as valueOrNull } from './ranges-BD8XH1Ef.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The Visitor Insights Studio tool.
|
package/dist/index.js
CHANGED
|
@@ -47,6 +47,7 @@ __export(index_exports, {
|
|
|
47
47
|
VisitorInsightsTool: () => VisitorInsightsTool,
|
|
48
48
|
coverageForRange: () => coverageForRange,
|
|
49
49
|
default: () => index_default,
|
|
50
|
+
estimated: () => estimated,
|
|
50
51
|
formatCount: () => formatCount,
|
|
51
52
|
formatMoney: () => formatMoney,
|
|
52
53
|
formatPercent: () => formatPercent,
|
|
@@ -213,6 +214,21 @@ function MetricFigure({ metric, label, size = 4, unit = "count" }) {
|
|
|
213
214
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Badge, { tone: "caution", fontSize: 0, children: "Partial" })
|
|
214
215
|
] });
|
|
215
216
|
}
|
|
217
|
+
if (metric.status === "estimated") {
|
|
218
|
+
const range = unit === "percent" ? `${metric.low.toFixed(1)}% to ${metric.high.toFixed(1)}%` : `${formatCount(metric.low)} to ${formatCount(metric.high)}`;
|
|
219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_sanity_ui_compat.Stack, { space: 2, children: [
|
|
220
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_sanity_ui_compat.Text, { size, "aria-label": `${label}: estimated ${formatted}, between ${range}. ${metric.basis}`, children: [
|
|
221
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: "~" }),
|
|
222
|
+
formatted
|
|
223
|
+
] }),
|
|
224
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 0, muted: true, children: range }),
|
|
225
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Badge, { tone: "primary", fontSize: 0, children: "Estimated" })
|
|
226
|
+
] });
|
|
227
|
+
}
|
|
228
|
+
if (metric.status !== "ok") {
|
|
229
|
+
const unhandled = metric;
|
|
230
|
+
void unhandled;
|
|
231
|
+
}
|
|
216
232
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size, "aria-label": `${label}: ${formatted}`, children: formatted });
|
|
217
233
|
}
|
|
218
234
|
function ComparisonBar({ label, metric, max, tone = "default" }) {
|
|
@@ -889,6 +905,28 @@ function MeasurementHealthPanel({ data, previous }) {
|
|
|
889
905
|
data.shortfallRatio !== null && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, weight: "semibold", children: data.shortfallRatio >= 0 ? `GA4 saw ${formatPercent(data.shortfallRatio, 1)} fewer pageviews than Vercel` : `GA4 saw ${formatPercent(-data.shortfallRatio, 1)} more pageviews than Vercel` }),
|
|
890
906
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, muted: true, children: data.interpretation })
|
|
891
907
|
] }) }),
|
|
908
|
+
((data.capture?.estimates?.length ?? 0) > 0 || data.estimatedSessions?.status === "estimated") && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Stack, { space: 3, children: [
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Heading, { size: 1, style: sectionHeading, children: "How much GA4 is seeing" }),
|
|
910
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: cardGrid, children: (data.capture?.estimates ?? []).map((estimate) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Card, { padding: 3, radius: 2, tone: "transparent", border: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Stack, { space: 3, children: [
|
|
911
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Label, { size: 1, muted: true, children: estimate.basis === "orders" ? "Measured against orders" : estimate.basis === "email" ? "Measured against email clicks" : "Measured against Vercel" }),
|
|
912
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 4, children: formatPercent(Math.min(1, estimate.rate), 0) }),
|
|
913
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Text, { size: 0, muted: true, children: [
|
|
914
|
+
formatCount(estimate.observed),
|
|
915
|
+
" of ",
|
|
916
|
+
formatCount(estimate.actual),
|
|
917
|
+
". ",
|
|
918
|
+
estimate.note
|
|
919
|
+
] })
|
|
920
|
+
] }) }, estimate.basis)) }),
|
|
921
|
+
data.capture?.discrepancy && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Card, { padding: 3, radius: 2, tone: "caution", border: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Stack, { space: 2, children: [
|
|
922
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, weight: "medium", children: "The sources disagree, and that is informative" }),
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, children: data.capture.discrepancy })
|
|
924
|
+
] }) }),
|
|
925
|
+
data.estimatedSessions && data.estimatedSessions.status === "estimated" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Card, { padding: 3, radius: 2, tone: "transparent", border: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Stack, { space: 3, children: [
|
|
926
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Label, { size: 1, muted: true, children: "Sessions, corrected for what GA4 misses" }),
|
|
927
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MetricFigure, { metric: data.estimatedSessions, label: "Estimated sessions" })
|
|
928
|
+
] }) })
|
|
929
|
+
] }),
|
|
892
930
|
(data.daily?.length ?? 0) >= 3 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Stack, { space: 3, children: [
|
|
893
931
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Heading, { size: 1, style: sectionHeading, children: "Day by day" }),
|
|
894
932
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, muted: true, children: "A gap that has always been there is consent and blocking. A gap that opens on one day is an incident." }),
|
|
@@ -1598,6 +1636,9 @@ function VisitorInsightsTool(props) {
|
|
|
1598
1636
|
}
|
|
1599
1637
|
|
|
1600
1638
|
// src/types.ts
|
|
1639
|
+
function estimated(value, low, high, basis) {
|
|
1640
|
+
return { status: "estimated", value, low, high, basis };
|
|
1641
|
+
}
|
|
1601
1642
|
function ok(value) {
|
|
1602
1643
|
return { status: "ok", value };
|
|
1603
1644
|
}
|
|
@@ -1686,6 +1727,9 @@ function validateSiteConfig(config) {
|
|
|
1686
1727
|
["orders.totalField", config.orders?.totalField],
|
|
1687
1728
|
["orders.typefacesField", config.orders?.typefacesField]
|
|
1688
1729
|
];
|
|
1730
|
+
for (const name of Object.keys(config.orders?.licenceFields ?? {})) {
|
|
1731
|
+
fieldSlots.push([`orders.licenceFields.${name}`, name]);
|
|
1732
|
+
}
|
|
1689
1733
|
for (const [field, value] of fieldSlots) {
|
|
1690
1734
|
if (!value) continue;
|
|
1691
1735
|
if (!FIELD_PATH.test(value)) {
|
|
@@ -1840,6 +1884,7 @@ var index_default = visitorInsights;
|
|
|
1840
1884
|
TypefaceInterestPanel,
|
|
1841
1885
|
VisitorInsightsTool,
|
|
1842
1886
|
coverageForRange,
|
|
1887
|
+
estimated,
|
|
1843
1888
|
formatCount,
|
|
1844
1889
|
formatMoney,
|
|
1845
1890
|
formatPercent,
|