@liiift-studio/sanity-visitor-insights 0.15.0 → 0.16.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 +53 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +53 -1
- package/dist/index.mjs.map +1 -1
- package/dist/{ranges-BD8XH1Ef.d.mts → ranges-DvICo5H2.d.mts} +43 -2
- package/dist/{ranges-BD8XH1Ef.d.ts → ranges-DvICo5H2.d.ts} +43 -2
- package/dist/server.d.mts +12 -4
- package/dist/server.d.ts +12 -4
- package/dist/server.js +165 -15
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +163 -15
- package/dist/server.mjs.map +1 -1
- package/dist/testing.d.mts +20 -2
- package/dist/testing.d.ts +20 -2
- package/dist/testing.js +14 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +13 -0
- package/dist/testing.mjs.map +1 -1
- package/dist/{vercel-CYZFSqz1.d.mts → vercel-CU5PgGrJ.d.mts} +79 -1
- package/dist/{vercel-CYZFSqz1.d.ts → vercel-CU5PgGrJ.d.ts} +79 -1
- package/package.json +1 -1
- package/src/core/siteConfig.ts +8 -0
- package/src/reportData.ts +32 -0
- package/src/server/createHandler.ts +30 -4
- package/src/server/mailchimp.ts +172 -0
- package/src/server/reports/measurementHealth.ts +70 -3
- package/src/server/reports/reports.test.ts +79 -0
- package/src/server.ts +2 -0
- package/src/studio/VisitorInsightsTool.tsx +1 -0
- package/src/studio/panels.test.tsx +5 -0
- package/src/studio/panels.tsx +62 -0
- package/src/testing/fakes.ts +23 -0
- package/src/types.ts +1 -1
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 CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as DailyPoint, i as DateRange, j as DiagnosticCheck, E 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-DvICo5H2.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 EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneyStep, L as LandingPage, P as PREEXISTING, n as REPORT_NAMES, o as ReportError, S as SiteAnalyticsConfig, p as SourceName, q as SourceRow, r as SourceStatus, s as TypefaceInterestRow, U as UnavailableReason, t as coverageForRange, u as estimated, v as isReportName, w as ok, x as partial, y as previousRange, z as resolveRange, B as unavailable, F as validateSiteConfig, G as valueOrNull } from './ranges-DvICo5H2.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 CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as DailyPoint, i as DateRange, j as DiagnosticCheck, E 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-DvICo5H2.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 EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneyStep, L as LandingPage, P as PREEXISTING, n as REPORT_NAMES, o as ReportError, S as SiteAnalyticsConfig, p as SourceName, q as SourceRow, r as SourceStatus, s as TypefaceInterestRow, U as UnavailableReason, t as coverageForRange, u as estimated, v as isReportName, w as ok, x as partial, y as previousRange, z as resolveRange, B as unavailable, F as validateSiteConfig, G as valueOrNull } from './ranges-DvICo5H2.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The Visitor Insights Studio tool.
|
package/dist/index.js
CHANGED
|
@@ -933,6 +933,43 @@ function MeasurementHealthPanel({ data, previous }) {
|
|
|
933
933
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TrendChart, { points: data.daily ?? [] }),
|
|
934
934
|
data.vercelDailyUnavailable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 0, muted: true, children: "Vercel reports this range in weekly buckets, so only the GA4 line is plotted. Choose Week or Month to see both." })
|
|
935
935
|
] }),
|
|
936
|
+
(data.campaigns?.length ?? 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Stack, { space: 3, children: [
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Heading, { size: 1, style: sectionHeading, children: "Email campaigns" }),
|
|
938
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, muted: true, children: "Clicks are distinct subscribers. Opens are inflated by Apple Mail Privacy Protection, which fetches images on the recipient\u2019s behalf \u2014 so sort on clicks, not opens." }),
|
|
939
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
940
|
+
SortableTable,
|
|
941
|
+
{
|
|
942
|
+
caption: "Email campaigns by clicks",
|
|
943
|
+
initialSort: "clicks",
|
|
944
|
+
rows: data.campaigns ?? [],
|
|
945
|
+
rowKey: (c) => `${c.sentAt}-${c.title}`,
|
|
946
|
+
filterOn: (c) => `${c.title} ${c.subject}`,
|
|
947
|
+
filterPlaceholder: "Filter campaigns",
|
|
948
|
+
exportName: "email-campaigns",
|
|
949
|
+
columns: [
|
|
950
|
+
{
|
|
951
|
+
key: "title",
|
|
952
|
+
label: "Campaign",
|
|
953
|
+
sortValue: (c) => c.title,
|
|
954
|
+
render: (c) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Stack, { space: 1, children: [
|
|
955
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, children: c.title }),
|
|
956
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 0, muted: true, children: c.sentAt.slice(0, 10) })
|
|
957
|
+
] })
|
|
958
|
+
},
|
|
959
|
+
{ key: "sent", label: "Sent", numeric: true, sortValue: (c) => c.sent, render: (c) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, children: formatCount(c.sent) }) },
|
|
960
|
+
{ key: "opens", label: "Opens", numeric: true, sortValue: (c) => c.opens, render: (c) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, muted: true, children: formatCount(c.opens) }) },
|
|
961
|
+
{ key: "clicks", label: "Clicks", numeric: true, sortValue: (c) => c.clicks, render: (c) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, children: formatCount(c.clicks) }) },
|
|
962
|
+
{
|
|
963
|
+
key: "unsub",
|
|
964
|
+
label: "Unsubscribed",
|
|
965
|
+
numeric: true,
|
|
966
|
+
sortValue: (c) => c.unsubscribed,
|
|
967
|
+
render: (c) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, muted: true, children: formatCount(c.unsubscribed) })
|
|
968
|
+
}
|
|
969
|
+
]
|
|
970
|
+
}
|
|
971
|
+
)
|
|
972
|
+
] }),
|
|
936
973
|
Object.keys(data.orderStatuses ?? {}).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_sanity_ui_compat2.Stack, { space: 3, children: [
|
|
937
974
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Heading, { size: 1, style: sectionHeading, children: "Order statuses in this range" }),
|
|
938
975
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, muted: true, children: "What the orders actually say, before any filtering. Use these values to set which statuses count as a sale." }),
|
|
@@ -945,6 +982,20 @@ function MeasurementHealthPanel({ data, previous }) {
|
|
|
945
982
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Heading, { size: 1, style: sectionHeading, children: "Context" }),
|
|
946
983
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 1, muted: true, children: "Different units to the figures above, and to each other. Shown for scale, never differenced." }),
|
|
947
984
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: cardGrid, children: [
|
|
985
|
+
/* @__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: [
|
|
986
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Label, { size: 1, muted: true, children: "Mailing list" }),
|
|
987
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: figureRow, children: [
|
|
988
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MetricFigure, { metric: metricOr(data.audience, OLDER_ROUTE), label: "Mailing list members" }),
|
|
989
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
990
|
+
Delta,
|
|
991
|
+
{
|
|
992
|
+
current: metricSortValue(data.audience),
|
|
993
|
+
previous: metricSortValue(previous?.audience)
|
|
994
|
+
}
|
|
995
|
+
)
|
|
996
|
+
] }),
|
|
997
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Text, { size: 0, muted: true, children: "Mailchimp\u2019s own count. Not consent-gated or blockable, so it replaces the site\u2019s subscribe event rather than sitting beside it." })
|
|
998
|
+
] }) }),
|
|
948
999
|
/* @__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: [
|
|
949
1000
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_sanity_ui_compat2.Label, { size: 1, muted: true, children: "Revenue" }),
|
|
950
1001
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: figureRow, children: [
|
|
@@ -1486,7 +1537,8 @@ function RangeSelector({
|
|
|
1486
1537
|
var SOURCE_LABEL = {
|
|
1487
1538
|
ga4: "Google Analytics",
|
|
1488
1539
|
vercel: "Vercel",
|
|
1489
|
-
sanity: "Orders"
|
|
1540
|
+
sanity: "Orders",
|
|
1541
|
+
mailchimp: "Mailchimp"
|
|
1490
1542
|
};
|
|
1491
1543
|
function SourceStatusRow({ sources }) {
|
|
1492
1544
|
const degraded = Object.entries(sources).filter(([, s]) => s.status !== "ok");
|