@liiift-studio/sanity-visitor-insights 0.28.0 → 0.30.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 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, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-D1A9JY7h.mjs';
4
- export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DailyPoint, j as DateRange, k as DiagnosticCheck, E as EmailCampaign, l as EventCutover, m as JourneyOutcome, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-D1A9JY7h.mjs';
3
+ import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-B3BWyG3q.mjs';
4
+ export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DailyPoint, j as DateRange, k as DiagnosticCheck, E as EmailCampaign, l as EventCutover, m as JourneyOutcome, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-B3BWyG3q.mjs';
5
5
 
6
6
  /**
7
7
  * Data hook for the Studio panels.
@@ -100,6 +100,62 @@ interface VisitorInsightsToolComponentProps extends Partial<VisitorInsightsToolP
100
100
  }
101
101
  declare function VisitorInsightsTool(props: VisitorInsightsToolComponentProps): React.ReactElement;
102
102
 
103
+ /**
104
+ * The tool's view, in the URL — so a finding can be sent to someone.
105
+ *
106
+ * Every piece of state here was component-local: tab, range, and the custom window. A Studio
107
+ * reload, a browser back, or an accidental navigation discarded the whole investigation, and
108
+ * "Acquisition, 24 August to 7 September" — the exact view in which someone notices the thing worth
109
+ * noticing — could not be handed to a colleague or returned to by the person who found it. There is
110
+ * a "Copy as CSV" in this tool precisely because sharing a finding is the real task; the view
111
+ * itself was the one thing that could not be shared.
112
+ *
113
+ * The HASH, not the path or the query. Sanity's own router owns the path, and writing to it would
114
+ * fight the Studio for control of navigation; the hash is unclaimed, survives a reload, is carried
115
+ * by a copied link, and is ignored by every server. The value is namespaced because other tools in
116
+ * the same Studio may want the same trick.
117
+ *
118
+ * Everything here is a pure string transformation, so it is testable without a DOM — which matters,
119
+ * because the alternative is a feature whose only proof is clicking around a deployed Studio.
120
+ */
121
+ /** The part of the tool's state worth putting in a link. */
122
+ interface ViewState {
123
+ /** Tab id, e.g. `overview`. */
124
+ tab?: string;
125
+ /** Range key, e.g. `week` or `custom`. */
126
+ range?: string;
127
+ /** Custom window start, ISO date. Only meaningful when `range` is `custom`. */
128
+ from?: string;
129
+ /** Custom window end, ISO date. */
130
+ to?: string;
131
+ }
132
+ /**
133
+ * Serialise a view to the hash fragment it should occupy.
134
+ *
135
+ * Returns an empty string for an empty view, so a default view leaves the URL clean rather than
136
+ * decorating it with state nobody set.
137
+ *
138
+ * @param view - the state to encode
139
+ */
140
+ declare function encodeView(view: ViewState): string;
141
+ /**
142
+ * Read a view out of a hash fragment.
143
+ *
144
+ * Every field is validated and an unrecognised one is dropped rather than defaulted, so a truncated
145
+ * or hand-edited link degrades to whatever it could parse instead of failing or, worse, silently
146
+ * requesting a window nobody chose.
147
+ *
148
+ * @param hash - `window.location.hash`, with or without its leading `#`
149
+ */
150
+ declare function decodeView(hash: string): ViewState;
151
+ /**
152
+ * Replace our fragment in a hash, preserving anyone else's.
153
+ *
154
+ * @param hash - the current hash
155
+ * @param view - the state to write
156
+ */
157
+ declare function mergeIntoHash(hash: string, view: ViewState): string;
158
+
103
159
  /**
104
160
  * Shared renderers for metric values and comparison bars.
105
161
  *
@@ -426,6 +482,15 @@ interface Series {
426
482
  * event, on a date, of a size. Days with nothing draw nothing, which is the truth.
427
483
  */
428
484
  mark?: 'line' | 'events';
485
+ /**
486
+ * A fixed y domain, instead of scaling the row to its own peak.
487
+ *
488
+ * Small multiples normally scale each row to itself, which is right for quantities whose
489
+ * absolute size is not comparable between rows. It is wrong for a proportion: a coverage row
490
+ * auto-scaled to its own maximum would redraw 100% at whatever the best day happened to be, so
491
+ * a site running at a flat 20% would show a full-height line and read as healthy.
492
+ */
493
+ domain?: [number, number];
429
494
  points: SeriesPoint[];
430
495
  /**
431
496
  * What a lossier source saw of the same thing.
@@ -465,12 +530,6 @@ interface CrossSourceTimelineProps {
465
530
  */
466
531
  onBrush?: (start: string, end: string) => void;
467
532
  }
468
- /**
469
- * The cross-source timeline.
470
- *
471
- * Renders nothing rather than an empty frame when there is not enough to plot — two points cannot
472
- * show a shape, and an axis with one dot on it invites a reading it cannot support.
473
- */
474
533
  declare function CrossSourceTimeline({ series, markers, currency, onBrush }: CrossSourceTimelineProps): React.ReactElement | null;
475
534
 
476
535
  /**
@@ -579,4 +638,4 @@ interface VisitorInsightsPluginOptions {
579
638
  */
580
639
  declare const visitorInsights: sanity.Plugin<VisitorInsightsPluginOptions>;
581
640
 
582
- export { AcquisitionData, AcquisitionPanel, ChartData, type ChartDataProps, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, DataHealthPanel, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, DataHealthPanel as MeasurementHealthPanel, MetricFigure, MetricValue, NoticeList, OverviewPanel, type ProportionBar, ProportionChart, type ProportionChartProps, RangeKey, ReportEnvelope, ReportName, type ReportState, type Series, type SeriesPoint, type SortColumn, SortableTable, type SortableTableProps, type TimelineMarker, TrendChart, TypefaceInterestData, TypefaceInterestPanel, type UseReportOptions, type VisitorInsightsPluginOptions, VisitorInsightsTool, type VisitorInsightsToolProps, visitorInsights as default, formatCount, formatMoney, formatPercent, knownShortfall, useReport, visitorInsights };
641
+ export { AcquisitionData, AcquisitionPanel, ChartData, type ChartDataProps, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, DataHealthPanel, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, DataHealthPanel as MeasurementHealthPanel, MetricFigure, MetricValue, NoticeList, OverviewPanel, type ProportionBar, ProportionChart, type ProportionChartProps, RangeKey, ReportEnvelope, ReportName, type ReportState, type Series, type SeriesPoint, type SortColumn, SortableTable, type SortableTableProps, type TimelineMarker, TrendChart, TypefaceInterestData, TypefaceInterestPanel, type UseReportOptions, type ViewState, type VisitorInsightsPluginOptions, VisitorInsightsTool, type VisitorInsightsToolProps, decodeView, visitorInsights as default, encodeView, formatCount, formatMoney, formatPercent, knownShortfall, mergeIntoHash, useReport, visitorInsights };
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, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-D1A9JY7h.js';
4
- export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DailyPoint, j as DateRange, k as DiagnosticCheck, E as EmailCampaign, l as EventCutover, m as JourneyOutcome, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-D1A9JY7h.js';
3
+ import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-B3BWyG3q.js';
4
+ export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DailyPoint, j as DateRange, k as DiagnosticCheck, E as EmailCampaign, l as EventCutover, m as JourneyOutcome, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-B3BWyG3q.js';
5
5
 
6
6
  /**
7
7
  * Data hook for the Studio panels.
@@ -100,6 +100,62 @@ interface VisitorInsightsToolComponentProps extends Partial<VisitorInsightsToolP
100
100
  }
101
101
  declare function VisitorInsightsTool(props: VisitorInsightsToolComponentProps): React.ReactElement;
102
102
 
103
+ /**
104
+ * The tool's view, in the URL — so a finding can be sent to someone.
105
+ *
106
+ * Every piece of state here was component-local: tab, range, and the custom window. A Studio
107
+ * reload, a browser back, or an accidental navigation discarded the whole investigation, and
108
+ * "Acquisition, 24 August to 7 September" — the exact view in which someone notices the thing worth
109
+ * noticing — could not be handed to a colleague or returned to by the person who found it. There is
110
+ * a "Copy as CSV" in this tool precisely because sharing a finding is the real task; the view
111
+ * itself was the one thing that could not be shared.
112
+ *
113
+ * The HASH, not the path or the query. Sanity's own router owns the path, and writing to it would
114
+ * fight the Studio for control of navigation; the hash is unclaimed, survives a reload, is carried
115
+ * by a copied link, and is ignored by every server. The value is namespaced because other tools in
116
+ * the same Studio may want the same trick.
117
+ *
118
+ * Everything here is a pure string transformation, so it is testable without a DOM — which matters,
119
+ * because the alternative is a feature whose only proof is clicking around a deployed Studio.
120
+ */
121
+ /** The part of the tool's state worth putting in a link. */
122
+ interface ViewState {
123
+ /** Tab id, e.g. `overview`. */
124
+ tab?: string;
125
+ /** Range key, e.g. `week` or `custom`. */
126
+ range?: string;
127
+ /** Custom window start, ISO date. Only meaningful when `range` is `custom`. */
128
+ from?: string;
129
+ /** Custom window end, ISO date. */
130
+ to?: string;
131
+ }
132
+ /**
133
+ * Serialise a view to the hash fragment it should occupy.
134
+ *
135
+ * Returns an empty string for an empty view, so a default view leaves the URL clean rather than
136
+ * decorating it with state nobody set.
137
+ *
138
+ * @param view - the state to encode
139
+ */
140
+ declare function encodeView(view: ViewState): string;
141
+ /**
142
+ * Read a view out of a hash fragment.
143
+ *
144
+ * Every field is validated and an unrecognised one is dropped rather than defaulted, so a truncated
145
+ * or hand-edited link degrades to whatever it could parse instead of failing or, worse, silently
146
+ * requesting a window nobody chose.
147
+ *
148
+ * @param hash - `window.location.hash`, with or without its leading `#`
149
+ */
150
+ declare function decodeView(hash: string): ViewState;
151
+ /**
152
+ * Replace our fragment in a hash, preserving anyone else's.
153
+ *
154
+ * @param hash - the current hash
155
+ * @param view - the state to write
156
+ */
157
+ declare function mergeIntoHash(hash: string, view: ViewState): string;
158
+
103
159
  /**
104
160
  * Shared renderers for metric values and comparison bars.
105
161
  *
@@ -426,6 +482,15 @@ interface Series {
426
482
  * event, on a date, of a size. Days with nothing draw nothing, which is the truth.
427
483
  */
428
484
  mark?: 'line' | 'events';
485
+ /**
486
+ * A fixed y domain, instead of scaling the row to its own peak.
487
+ *
488
+ * Small multiples normally scale each row to itself, which is right for quantities whose
489
+ * absolute size is not comparable between rows. It is wrong for a proportion: a coverage row
490
+ * auto-scaled to its own maximum would redraw 100% at whatever the best day happened to be, so
491
+ * a site running at a flat 20% would show a full-height line and read as healthy.
492
+ */
493
+ domain?: [number, number];
429
494
  points: SeriesPoint[];
430
495
  /**
431
496
  * What a lossier source saw of the same thing.
@@ -465,12 +530,6 @@ interface CrossSourceTimelineProps {
465
530
  */
466
531
  onBrush?: (start: string, end: string) => void;
467
532
  }
468
- /**
469
- * The cross-source timeline.
470
- *
471
- * Renders nothing rather than an empty frame when there is not enough to plot — two points cannot
472
- * show a shape, and an axis with one dot on it invites a reading it cannot support.
473
- */
474
533
  declare function CrossSourceTimeline({ series, markers, currency, onBrush }: CrossSourceTimelineProps): React.ReactElement | null;
475
534
 
476
535
  /**
@@ -579,4 +638,4 @@ interface VisitorInsightsPluginOptions {
579
638
  */
580
639
  declare const visitorInsights: sanity.Plugin<VisitorInsightsPluginOptions>;
581
640
 
582
- export { AcquisitionData, AcquisitionPanel, ChartData, type ChartDataProps, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, DataHealthPanel, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, DataHealthPanel as MeasurementHealthPanel, MetricFigure, MetricValue, NoticeList, OverviewPanel, type ProportionBar, ProportionChart, type ProportionChartProps, RangeKey, ReportEnvelope, ReportName, type ReportState, type Series, type SeriesPoint, type SortColumn, SortableTable, type SortableTableProps, type TimelineMarker, TrendChart, TypefaceInterestData, TypefaceInterestPanel, type UseReportOptions, type VisitorInsightsPluginOptions, VisitorInsightsTool, type VisitorInsightsToolProps, visitorInsights as default, formatCount, formatMoney, formatPercent, knownShortfall, useReport, visitorInsights };
641
+ export { AcquisitionData, AcquisitionPanel, ChartData, type ChartDataProps, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, DataHealthPanel, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, DataHealthPanel as MeasurementHealthPanel, MetricFigure, MetricValue, NoticeList, OverviewPanel, type ProportionBar, ProportionChart, type ProportionChartProps, RangeKey, ReportEnvelope, ReportName, type ReportState, type Series, type SeriesPoint, type SortColumn, SortableTable, type SortableTableProps, type TimelineMarker, TrendChart, TypefaceInterestData, TypefaceInterestPanel, type UseReportOptions, type ViewState, type VisitorInsightsPluginOptions, VisitorInsightsTool, type VisitorInsightsToolProps, decodeView, visitorInsights as default, encodeView, formatCount, formatMoney, formatPercent, knownShortfall, mergeIntoHash, useReport, visitorInsights };