@bicharts/chart-host 0.6.15 → 0.6.17
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.
|
@@ -1582,9 +1582,9 @@ var wt = new RegExp([String.raw`\bisMeasure\b`, String.raw`\bdataType\b`, String
|
|
|
1582
1582
|
|
|
1583
1583
|
// ../shape-core/dist/index.mjs
|
|
1584
1584
|
/*! @bicharts/shape-core — Apache-2.0. Bundled reference data: GeoNames (https://www.geonames.org/) CC BY 4.0; US Census/TIGER (public domain). Full text: NOTICE in this package. */
|
|
1585
|
-
var
|
|
1585
|
+
var K3 = 2;
|
|
1586
1586
|
var Y3 = 400;
|
|
1587
|
-
function
|
|
1587
|
+
function V3(n) {
|
|
1588
1588
|
return !!E(n);
|
|
1589
1589
|
}
|
|
1590
1590
|
function T3(n) {
|
|
@@ -1598,8 +1598,8 @@ function T3(n) {
|
|
|
1598
1598
|
}
|
|
1599
1599
|
function M(n) {
|
|
1600
1600
|
let e = T3(n);
|
|
1601
|
-
if (e.length === 0 ||
|
|
1602
|
-
let t = e.filter((c2) =>
|
|
1601
|
+
if (e.length === 0 || B3(n) < 95) return false;
|
|
1602
|
+
let t = e.filter((c2) => V3(c2) && !Y(c2)).length, i = e.filter((c2) => !V3(c2) && !!Y(c2)).length;
|
|
1603
1603
|
return t >= 1 && t >= i;
|
|
1604
1604
|
}
|
|
1605
1605
|
function X3(n, e) {
|
|
@@ -1607,11 +1607,11 @@ function X3(n, e) {
|
|
|
1607
1607
|
let t = E(n);
|
|
1608
1608
|
return t ? e === "world" ? true : s3.has(t) : false;
|
|
1609
1609
|
}
|
|
1610
|
-
function
|
|
1610
|
+
function B3(n) {
|
|
1611
1611
|
let e = T3(n);
|
|
1612
1612
|
if (e.length === 0) return 0;
|
|
1613
1613
|
let t = 0;
|
|
1614
|
-
for (let i of e)
|
|
1614
|
+
for (let i of e) V3(i) && t++;
|
|
1615
1615
|
return Math.round(t / e.length * 1e3) / 10;
|
|
1616
1616
|
}
|
|
1617
1617
|
function E4(n) {
|
|
@@ -1630,7 +1630,7 @@ function $2(n) {
|
|
|
1630
1630
|
}
|
|
1631
1631
|
return Array.from(e);
|
|
1632
1632
|
}
|
|
1633
|
-
function
|
|
1633
|
+
function W2(n) {
|
|
1634
1634
|
let e = $2(n);
|
|
1635
1635
|
if (e.length === 0) return 0;
|
|
1636
1636
|
let t = 0;
|
|
@@ -1647,7 +1647,7 @@ function et2(n, e) {
|
|
|
1647
1647
|
for (let c2 of t) p3(c2, e) && i++;
|
|
1648
1648
|
return Math.round(i / t.length * 1e3) / 10;
|
|
1649
1649
|
}
|
|
1650
|
-
function
|
|
1650
|
+
function z3(n, e) {
|
|
1651
1651
|
let t = 0;
|
|
1652
1652
|
for (let i of T3(n)) e(i) && t++;
|
|
1653
1653
|
return t;
|
|
@@ -1670,7 +1670,7 @@ function tt2(n, e, t, i, c2) {
|
|
|
1670
1670
|
}
|
|
1671
1671
|
let h3 = t?.zip;
|
|
1672
1672
|
if (h3 && x2.has(h3)) {
|
|
1673
|
-
let r = d2(h3), u2 =
|
|
1673
|
+
let r = d2(h3), u2 = W2(r);
|
|
1674
1674
|
u2 < 95 ? s.push(`zip=${h3} (only ${u2}% of values read as ZIPs)`) : Z3(r, h3) ? o.zip = h3 : s.push(`zip=${h3} (all values are 3-4 digits with nothing to say they are postal)`);
|
|
1675
1675
|
}
|
|
1676
1676
|
let g3 = t?.state;
|
|
@@ -1678,23 +1678,23 @@ function tt2(n, e, t, i, c2) {
|
|
|
1678
1678
|
let r = d2(g3), u2 = T3(r);
|
|
1679
1679
|
u2.length > 0 && u2.every((m) => X3(m, i)) ? s.push(`state=${g3} (every value is "CA", which is both Canada and California)`) : M(r) ? (s.push(`state=${g3} (every value is a country, not a state)`), o.country || (o.country = g3)) : E4(r) < 95 ? s.push(`state=${g3} (only ${E4(r)}% of values are states/provinces)`) : o.state = g3;
|
|
1680
1680
|
}
|
|
1681
|
-
let S = new Set(Object.values(o).filter(Boolean)),
|
|
1681
|
+
let S = new Set(Object.values(o).filter(Boolean)), N3 = n.filter((r) => !S.has(r) && !r.startsWith("__"));
|
|
1682
1682
|
if (!o.state) {
|
|
1683
1683
|
let r = null;
|
|
1684
|
-
for (let u2 of
|
|
1684
|
+
for (let u2 of N3) {
|
|
1685
1685
|
let m = d2(u2);
|
|
1686
1686
|
if (M(m)) continue;
|
|
1687
1687
|
let p2 = E4(m);
|
|
1688
1688
|
if (p2 < 95) continue;
|
|
1689
|
-
let D3 =
|
|
1690
|
-
D3 <
|
|
1689
|
+
let D3 = z3(m, (w3) => !!Y(w3)), se = z3(m, (w3) => !!Y(w3) && !X3(w3, i));
|
|
1690
|
+
D3 < K3 && se < 1 || (!r || p2 > r.pct) && (r = { name: u2, pct: p2 });
|
|
1691
1691
|
}
|
|
1692
1692
|
r && (o.state = r.name, S.add(r.name), a4.push(`state=${r.name} (${r.pct}% states/provinces)`));
|
|
1693
1693
|
}
|
|
1694
|
-
if (!o.zip) for (let r of
|
|
1694
|
+
if (!o.zip) for (let r of N3) {
|
|
1695
1695
|
if (S.has(r)) continue;
|
|
1696
|
-
let u2 = d2(r), m =
|
|
1697
|
-
if (!(m < 95) && Z3(u2, r) && !(nt2(u2, (p2) => Z(p2).length > 0) <
|
|
1696
|
+
let u2 = d2(r), m = W2(u2);
|
|
1697
|
+
if (!(m < 95) && Z3(u2, r) && !(nt2(u2, (p2) => Z(p2).length > 0) < K3)) {
|
|
1698
1698
|
o.zip = r, S.add(r), a4.push(`zip=${r} (${m}% ZIP codes)`);
|
|
1699
1699
|
break;
|
|
1700
1700
|
}
|
|
@@ -1702,27 +1702,27 @@ function tt2(n, e, t, i, c2) {
|
|
|
1702
1702
|
let b4 = o.country;
|
|
1703
1703
|
if (!b4 || !M(d2(b4))) {
|
|
1704
1704
|
let r = null;
|
|
1705
|
-
for (let u2 of
|
|
1705
|
+
for (let u2 of N3) {
|
|
1706
1706
|
if (S.has(u2) || !M(d2(u2))) continue;
|
|
1707
|
-
let m =
|
|
1707
|
+
let m = B3(d2(u2));
|
|
1708
1708
|
(!r || m > r.pct) && (r = { name: u2, pct: m });
|
|
1709
1709
|
}
|
|
1710
|
-
r && (b4 && (s.push(`country=${b4} (only ${
|
|
1710
|
+
r && (b4 && (s.push(`country=${b4} (only ${B3(d2(b4))}% of values are country identifiers; using ${r.name} instead)`), C2.country = b4), o.country = r.name, S.add(r.name), a4.push(`country=${r.name}`));
|
|
1711
1711
|
}
|
|
1712
1712
|
if (!o.city) {
|
|
1713
1713
|
let r = null;
|
|
1714
|
-
for (let u2 of
|
|
1714
|
+
for (let u2 of N3) {
|
|
1715
1715
|
if (S.has(u2)) continue;
|
|
1716
1716
|
let m = d2(u2), p2 = et2(m, i);
|
|
1717
|
-
p2 < m3 ||
|
|
1717
|
+
p2 < m3 || z3(m, (D3) => p3(D3, i)) < K3 || (!r || p2 > r.pct) && (r = { name: u2, pct: p2 });
|
|
1718
1718
|
}
|
|
1719
1719
|
r && (o.city = r.name, a4.push(`city=${r.name} (${r.pct}% known cities)`));
|
|
1720
1720
|
}
|
|
1721
|
-
let U3 = o.country ? d2(o.country) : [],
|
|
1721
|
+
let U3 = o.country ? d2(o.country) : [], F3 = !!o.country && M(U3), ie = F3 ? new Set(U3.map((r) => E(r == null ? null : String(r))).filter(Boolean)).size : 0, H3 = F3 && ie >= 2, _2 = !!(o.lat && o.lon) && e.some((r) => {
|
|
1722
1722
|
let u2 = +String(r[o.lat] ?? "").trim(), m = +String(r[o.lon] ?? "").trim();
|
|
1723
1723
|
return isFinite(u2) && isFinite(m) && u2 >= -90 && u2 <= 90 && m >= -180 && m <= 180 && String(r[o.lat] ?? "").trim() !== "" && String(r[o.lon] ?? "").trim() !== "";
|
|
1724
1724
|
});
|
|
1725
|
-
return o.lat && o.lon && !
|
|
1725
|
+
return o.lat && o.lon && !_2 && s.push(`lat/lon=${o.lat}/${o.lon} (no row holds a usable coordinate pair)`), o.country && !H3 && !(o.city || o.state || o.zip || _2) && s.push(F3 ? `country=${o.country} (every row resolves to the same country - nothing to place apart)` : `country=${o.country} (values are not country identifiers)`), { bind: !!(o.city || o.state || o.zip || H3 || _2) ? o : null, backfilled: a4, refused: s, ...Object.keys(C2).length ? { labelFallback: C2 } : {} };
|
|
1726
1726
|
}
|
|
1727
1727
|
|
|
1728
1728
|
// src/payload.ts
|
package/dist/index.mjs
CHANGED
|
@@ -140,7 +140,7 @@ import {
|
|
|
140
140
|
unpinScrolledAxis,
|
|
141
141
|
valuePlacementFlag,
|
|
142
142
|
withoutViewOnlyKeys
|
|
143
|
-
} from "./chunk-
|
|
143
|
+
} from "./chunk-JVJKBNWB.mjs";
|
|
144
144
|
import "./chunk-A2GMXZP7.mjs";
|
|
145
145
|
import "./chunk-GHODWOAL.mjs";
|
|
146
146
|
|
|
@@ -2383,6 +2383,23 @@ function reconcileChartPick(pick, offered, autoLabel) {
|
|
|
2383
2383
|
};
|
|
2384
2384
|
}
|
|
2385
2385
|
|
|
2386
|
+
// src/duplicateGenerateGuard.ts
|
|
2387
|
+
var DUPLICATE_GENERATE_WINDOW_MS = 2500;
|
|
2388
|
+
function sameRequest(a2, b2) {
|
|
2389
|
+
return a2.schemaHash === b2.schemaHash && a2.gennew === b2.gennew && a2.trycnt === b2.trycnt && a2.favorStyle === b2.favorStyle;
|
|
2390
|
+
}
|
|
2391
|
+
function isDuplicateGenerate(prev, next, now) {
|
|
2392
|
+
if (!prev) return false;
|
|
2393
|
+
if (!sameRequest(prev, next)) return false;
|
|
2394
|
+
if (prev.inFlight) return true;
|
|
2395
|
+
const elapsed = now - prev.startedAt;
|
|
2396
|
+
if (elapsed < 0) return false;
|
|
2397
|
+
return elapsed < DUPLICATE_GENERATE_WINDOW_MS;
|
|
2398
|
+
}
|
|
2399
|
+
function armGenerateGuard(next, now) {
|
|
2400
|
+
return { ...next, startedAt: now, inFlight: true };
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2386
2403
|
// src/clientIdentity.ts
|
|
2387
2404
|
function stableFingerprintOptions() {
|
|
2388
2405
|
return { exclude: ["fonts", "system.useragent", "system.browser.version"], logging: false };
|
|
@@ -2450,6 +2467,7 @@ export {
|
|
|
2450
2467
|
DARK_TEXT,
|
|
2451
2468
|
DIM_OPACITY_DEFAULT,
|
|
2452
2469
|
DIM_OPACITY_VAR,
|
|
2470
|
+
DUPLICATE_GENERATE_WINDOW_MS,
|
|
2453
2471
|
FILTER_MIN_HEIGHT_PX,
|
|
2454
2472
|
FILTER_MIN_TERM_CHARS,
|
|
2455
2473
|
FILTER_MIN_WIDTH_PX,
|
|
@@ -2504,6 +2522,7 @@ export {
|
|
|
2504
2522
|
XFILTER_REFRESH_EVENT,
|
|
2505
2523
|
actionFor,
|
|
2506
2524
|
applyLabelContrast,
|
|
2525
|
+
armGenerateGuard,
|
|
2507
2526
|
askApplyImprovements,
|
|
2508
2527
|
assembleD3,
|
|
2509
2528
|
autoRampCanvas,
|
|
@@ -2565,6 +2584,7 @@ export {
|
|
|
2565
2584
|
invalidSentinelReason,
|
|
2566
2585
|
isBlankRender,
|
|
2567
2586
|
isBlindMarker,
|
|
2587
|
+
isDuplicateGenerate,
|
|
2568
2588
|
isExcelDateFormat,
|
|
2569
2589
|
isHorizontalLabelRow,
|
|
2570
2590
|
isInsideControl,
|
package/dist/react.mjs
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** What identifies one generate request for suppression purposes. */
|
|
2
|
+
export interface GenerateGuardKey {
|
|
3
|
+
/** Field/column fingerprint. A field change moves this, and must not be suppressed. */
|
|
4
|
+
schemaHash: number;
|
|
5
|
+
/** A fresh generation vs a fetch/regeneration - different intents. */
|
|
6
|
+
gennew: boolean;
|
|
7
|
+
/** The explicit chart-type pick ("" when the picker is free to choose). */
|
|
8
|
+
favorStyle: string;
|
|
9
|
+
/** The retry counter. Differs on every retry, so a retry is never suppressed. */
|
|
10
|
+
trycnt: number;
|
|
11
|
+
}
|
|
12
|
+
/** The last generate a host started, plus whether it is still running. */
|
|
13
|
+
export interface GenerateGuardState extends GenerateGuardKey {
|
|
14
|
+
/** The host's clock (performance.now()) when the call STARTED. */
|
|
15
|
+
startedAt: number;
|
|
16
|
+
/** True from the start of the generate until it settles. */
|
|
17
|
+
inFlight: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** Two calls this close together, with everything else equal, are one user action. */
|
|
20
|
+
export declare const DUPLICATE_GENERATE_WINDOW_MS = 2500;
|
|
21
|
+
/**
|
|
22
|
+
* Should this generate be suppressed as a duplicate of the one before it?
|
|
23
|
+
*
|
|
24
|
+
* Suppress when the request is identical AND either the previous call is still running, or it
|
|
25
|
+
* started within the window. Anything else proceeds.
|
|
26
|
+
*
|
|
27
|
+
* @param prev what the host last started, or null on its first generate
|
|
28
|
+
* @param next the request about to be made
|
|
29
|
+
* @param now the host's clock (performance.now()) at the moment of the call
|
|
30
|
+
*/
|
|
31
|
+
export declare function isDuplicateGenerate(prev: GenerateGuardState | null | undefined, next: GenerateGuardKey, now: number): boolean;
|
|
32
|
+
/** The state to record when a generate is allowed to proceed. */
|
|
33
|
+
export declare function armGenerateGuard(next: GenerateGuardKey, now: number): GenerateGuardState;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -38,5 +38,6 @@ export { resolveAutoColorScale, autoRampMinStep, autoRampCanvas, AUTO_RAMP_CLASS
|
|
|
38
38
|
export { PENDING_RECOVERY_WINDOW_MS, PENDING_RECOVERY_POLL_MS, PENDING_RECOVERY_FIRST_POLL_MS, PENDING_RECOVERY_FAST_PHASE_MS, PENDING_RECOVERY_MID_POLL_MS, PENDING_RECOVERY_SLOW_PHASE_MS, PENDING_RECOVERY_SLOW_POLL_MS, pendingRecoveryNextDelayMs, encodePendingGenerate, parsePendingGenerate, markerArmedBlind, isBlindMarker, servedCorrelationProves, sameMarker, decidePendingRecovery, recoveryPollRunning, recoveryOwnsTheSentence, latePickupAction, latePickupKeepsMarker, pollGiveUpKeepsMarker, pendingRecoveryRemainingMs, transportFailureShouldRecover, TRANSPORT_LOST_CHECKING_MESSAGE, GENERATION_CANCELLED_MESSAGE, recoveryAnswerIsCancelled, generationCancelledMessage, type PendingGenerateMarker, type PendingRecoveryDecision, type LatePickupAction, } from "./pendingGenerate";
|
|
39
39
|
export { stripJsComments } from "./codeComments";
|
|
40
40
|
export { reconcileChartPick, type ChartPickReconciliation } from "./chartPick";
|
|
41
|
+
export { isDuplicateGenerate, armGenerateGuard, DUPLICATE_GENERATE_WINDOW_MS, type GenerateGuardKey, type GenerateGuardState, } from "./duplicateGenerateGuard";
|
|
41
42
|
export { stableFingerprintOptions, fingerprintComponentDigest, type ClientIdSource } from "./clientIdentity";
|
|
42
43
|
export type { HostServices, MarkerStore, PreferenceSource, HostTheme, ThemeSource, ThumbnailConsent, SnapshotTarget, WireSigner, WireTransport, WireResponse, CredentialTriple, CredentialSource, ViewportSource, Clock, DiagnosticEntry, DiagnosticsSink, RendererId, } from "./host/services";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bicharts/chart-host",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.17",
|
|
4
4
|
"description": "Run a BIC-generated D3 chart in any web host: compiles the generated render() function, applies the shared option defaults, resolves mark clicks (through tooltip overlays), owns the selection affordance, and translates row indices between cross-filtered charts. The same contract the BIC Power BI visual implements, minus Power BI. React bindings at @bicharts/chart-host/react.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|