udi-yac 0.2.3 → 0.3.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/README.md +38 -25
- package/dist/{ce-entry-CLKEbGj8.js → ce-entry-BN36qTNy.js} +21608 -21351
- package/dist/src/app/ErrorBoundary.d.ts +1 -1
- package/dist/src/app/UDIChatConfig.d.ts +9 -0
- package/dist/src/app/validateConfig.d.ts +0 -12
- package/dist/src/components/FieldTooltipContent.d.ts +12 -0
- package/dist/src/components/ui/accordion.d.ts +8 -1
- package/dist/src/features/chat/components/BrushFilterWidgets.d.ts +8 -0
- package/dist/src/features/dashboard/components/VizTweakComponent.types.d.ts +9 -0
- package/dist/src/features/dashboard/hooks/useBrushFilters.d.ts +45 -0
- package/dist/src/features/dashboard/hooks/useBrushFilters.test.d.ts +1 -0
- package/dist/src/features/dashboard/index.d.ts +1 -0
- package/dist/src/features/dashboard/utils/relevantTableMapping.d.ts +21 -0
- package/dist/src/features/dashboard/utils/relevantTableMapping.test.d.ts +1 -0
- package/dist/src/features/dashboard/utils/tweakability.d.ts +31 -14
- package/dist/src/features/data-package/components/DataOverviewPanel.d.ts +10 -0
- package/dist/src/features/data-package/components/DataOverviewPanel.test.d.ts +1 -0
- package/dist/src/features/data-package/components/EntityOverview.d.ts +10 -0
- package/dist/src/features/data-package/index.d.ts +1 -0
- package/dist/src/features/data-package/stores/dataPackageStore.d.ts +14 -0
- package/dist/src/features/data-package/utils/entityOverview.d.ts +136 -0
- package/dist/src/features/data-package/utils/entityOverview.test.d.ts +1 -0
- package/dist/src/features/tool-calls/components/IntervalFilterComponent.d.ts +8 -1
- package/dist/src/features/tool-calls/components/PointFilterComponent.d.ts +7 -1
- package/dist/src/features/tool-calls/components/PointFilterComponent.test.d.ts +1 -0
- package/dist/src/features/tool-calls/index.d.ts +2 -0
- package/dist/src/lib/chatRoot.d.ts +7 -0
- package/dist/src/stores/globalStore.d.ts +10 -0
- package/dist/src/utils/entityIcons.d.ts +10 -0
- package/dist/src/utils/highlightMatch.d.ts +7 -0
- package/dist/src/utils/httpError.d.ts +11 -0
- package/dist/src/utils/httpError.test.d.ts +1 -0
- package/dist/src/utils/specMutations.d.ts +73 -17
- package/dist/udi-yac.css +1 -1
- package/dist/udi-yac.js +29202 -27869
- package/package.json +5 -5
|
@@ -14,6 +14,6 @@ export declare class ErrorBoundary extends Component<Props, State> {
|
|
|
14
14
|
private handleCopy;
|
|
15
15
|
private handleReset;
|
|
16
16
|
private handleExport;
|
|
17
|
-
render(): string | number | bigint | boolean |
|
|
17
|
+
render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react").JSX.Element | null | undefined;
|
|
18
18
|
}
|
|
19
19
|
export {};
|
|
@@ -19,6 +19,15 @@ export type TrackerFn = (name: string, properties?: Record<string, unknown>) =>
|
|
|
19
19
|
*/
|
|
20
20
|
export interface UDIChatConfig {
|
|
21
21
|
apiBaseUrl: string;
|
|
22
|
+
/**
|
|
23
|
+
* Name of a server-side data package (configured on the agent server's
|
|
24
|
+
* query backends). When set, the chat fetches introspected metadata from
|
|
25
|
+
* GET /v1/yac/metadata and routes all data queries through
|
|
26
|
+
* POST /v1/yac/query — no CSVs are loaded into the browser, and
|
|
27
|
+
* cross-filtering becomes non-interactive (commit on mouse-up with a
|
|
28
|
+
* loading overlay). Takes precedence over `dataPackage`/`dataPackagePath`.
|
|
29
|
+
*/
|
|
30
|
+
remotePackage?: string;
|
|
22
31
|
/** URL to fetch a datapackage_udi.json from. Ignored when `dataPackage` is provided. */
|
|
23
32
|
dataPackagePath?: string;
|
|
24
33
|
/** Provide a DataPackage object directly instead of fetching from a URL. Takes precedence over `dataPackagePath`. */
|
|
@@ -1,14 +1,2 @@
|
|
|
1
1
|
import { UDIChatConfig } from '../../app/UDIChatConfig';
|
|
2
|
-
/**
|
|
3
|
-
* Lightweight runtime validation for the UDIChatConfig shape.
|
|
4
|
-
*
|
|
5
|
-
* Catches the most common consumer mistakes (missing apiBaseUrl, malformed
|
|
6
|
-
* URL, no data source provided, malformed DataPackage) before they fail deep
|
|
7
|
-
* inside Arquero or fetch with opaque stack traces. Errors are thrown so the
|
|
8
|
-
* surrounding ErrorBoundary renders a useful message.
|
|
9
|
-
*
|
|
10
|
-
* This is intentionally NOT a full schema validator — it covers the failure
|
|
11
|
-
* modes we've actually seen in practice. If a field has a bad type that React
|
|
12
|
-
* itself will surface clearly, we don't duplicate that check here.
|
|
13
|
-
*/
|
|
14
2
|
export declare function validateConfig(config: UDIChatConfig): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface FieldTooltipContentProps {
|
|
2
|
+
field: string;
|
|
3
|
+
dataType?: string | undefined;
|
|
4
|
+
description?: string | undefined;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The hover card for a data-package field: its name, its `udi:data_type`, and
|
|
8
|
+
* its description. Shared by the chat's field chips and the data overview's
|
|
9
|
+
* field list so a field looks the same wherever it is hovered.
|
|
10
|
+
*/
|
|
11
|
+
export declare function FieldTooltipContent({ field, dataType, description }: FieldTooltipContentProps): import("react").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Accordion as AccordionPrimitive } from '@base-ui/react/accordion';
|
|
2
2
|
declare function Accordion({ className, ...props }: AccordionPrimitive.Root.Props): import("react").JSX.Element;
|
|
3
3
|
declare function AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props): import("react").JSX.Element;
|
|
4
|
-
declare function AccordionTrigger({ className, children, ...props }: AccordionPrimitive.Trigger.Props
|
|
4
|
+
declare function AccordionTrigger({ className, headerClassName, children, ...props }: AccordionPrimitive.Trigger.Props & {
|
|
5
|
+
/**
|
|
6
|
+
* Applied to the wrapping `<Header>` rather than the trigger button. Lets a
|
|
7
|
+
* consumer make the header `sticky` — which has to sit on the header, since
|
|
8
|
+
* the button is a flex child of it.
|
|
9
|
+
*/
|
|
10
|
+
headerClassName?: string;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
5
12
|
declare function AccordionContent({ className, children, ...props }: AccordionPrimitive.Panel.Props): import("react").JSX.Element;
|
|
6
13
|
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders an adjustment widget in the chat for each active visualization brush
|
|
3
|
+
* filter. Each one is presented like an LLM-originated `FilterData` filter, so
|
|
4
|
+
* a brush filter reads as a chat message. Brush selections live in the shared
|
|
5
|
+
* Pinia store (mirrored into `dataFiltersStore.internalDataSelections`), not
|
|
6
|
+
* the conversation, so these never leak into the LLM message history.
|
|
7
|
+
*/
|
|
8
|
+
export declare function BrushFilterWidgets(): import("react").JSX.Element | null;
|
|
@@ -5,9 +5,18 @@
|
|
|
5
5
|
* introspect without depending on the full upstream type graph.
|
|
6
6
|
*/
|
|
7
7
|
export interface TweakableParam {
|
|
8
|
+
/** Value shown in the dropdown: the source field (field/dimension) or, for a
|
|
9
|
+
* measure, the rollup's input field. */
|
|
8
10
|
field: string;
|
|
9
11
|
encoding: string;
|
|
10
12
|
options: string[];
|
|
13
|
+
/** How a swap is applied:
|
|
14
|
+
* - 'field': plain encoding rewrite (setMappingFieldByEncoding)
|
|
15
|
+
* - 'dimension': group-by field, rewrite encoding + groupby (swapDimensionField)
|
|
16
|
+
* - 'measure': aggregated rollup input, rewrite via swapMeasureField */
|
|
17
|
+
kind: 'field' | 'dimension' | 'measure';
|
|
18
|
+
/** For 'measure': the rollup output column the encoding is bound to. */
|
|
19
|
+
outputKey?: string;
|
|
11
20
|
}
|
|
12
21
|
export interface MappingLike {
|
|
13
22
|
field?: string;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { DataSelection, DataSelections } from '../stores/dataFiltersStore';
|
|
2
|
+
import { ActiveVisualization } from '../stores/dashboardStore';
|
|
3
|
+
export interface BrushFilter {
|
|
4
|
+
/** Stable identity for chips/widgets and per-filter clearing: the viz uuid
|
|
5
|
+
* for interval brushes, `${uuid}::${field}` for point selections (which
|
|
6
|
+
* are split into one filter per field). */
|
|
7
|
+
id: string;
|
|
8
|
+
/** Selection key — the source visualization's uuid. */
|
|
9
|
+
uuid: string;
|
|
10
|
+
/** Dashboard key of the source visualization (for remount/hover coordination). */
|
|
11
|
+
vizKey: string;
|
|
12
|
+
/** Human-readable label for the source visualization. */
|
|
13
|
+
title: string;
|
|
14
|
+
/** For point selections: the single field this filter covers. Edits and
|
|
15
|
+
* clears must merge back into the uuid's full multi-field selection. */
|
|
16
|
+
field?: string;
|
|
17
|
+
/** For point filters, narrowed to `field`; the full selection for interval. */
|
|
18
|
+
selection: DataSelection;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Whether a brush selection currently constrains anything. An interval brush
|
|
22
|
+
* always has a range; a point brush with every value unchecked is "present but
|
|
23
|
+
* empty" — its widget should persist for re-selection, but it shouldn't render
|
|
24
|
+
* a (valueless) toolbar chip.
|
|
25
|
+
*/
|
|
26
|
+
export declare function brushHasValue(selection: DataSelection): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Pure derivation of brush filters from the store's `internalDataSelections`
|
|
29
|
+
* (brush/click selections mirrored out of the shared Pinia DataSourcesStore,
|
|
30
|
+
* keyed by the source viz's uuid) + the active visualizations. Gated to
|
|
31
|
+
* currently-active vizzes so a closed viz's stale selection never shows, and
|
|
32
|
+
* to a present (non-null) selection. A point brush whose values are all
|
|
33
|
+
* unchecked is kept so its chat widget persists; callers that only want
|
|
34
|
+
* value-carrying filters (e.g. the toolbar) filter with `brushHasValue`.
|
|
35
|
+
* Exported for unit testing.
|
|
36
|
+
*/
|
|
37
|
+
export declare function selectBrushFilters(internalSelections: DataSelections, activeVisualizations: Map<string, ActiveVisualization>): BrushFilter[];
|
|
38
|
+
/**
|
|
39
|
+
* Brush/click selections created by interacting with a visualization are
|
|
40
|
+
* mirrored into `dataFiltersStore.internalDataSelections` (keyed by the source
|
|
41
|
+
* viz's uuid) by `DashboardCard`'s selection handler. This hook surfaces them
|
|
42
|
+
* as first-class filters for the filter toolbar and the chat adjustment
|
|
43
|
+
* widgets.
|
|
44
|
+
*/
|
|
45
|
+
export declare function useBrushFilters(): BrushFilter[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -7,4 +7,5 @@ export { VizTweakComponent } from './components/VizTweakComponent';
|
|
|
7
7
|
export { createDashboardStore, extractAllUdiSpecsFromMessage, type DashboardState, type ActiveVisualization, } from './stores/dashboardStore';
|
|
8
8
|
export { createDataFiltersStore, extractFilterSpecFromMessage, messageFilterKeyWithToolCall, messageFilterKey, type DataFiltersState, type DataSelection, type DataSelections, } from './stores/dataFiltersStore';
|
|
9
9
|
export { createMemoryBankStore, type MemoryBankState } from './stores/memoryBankStore';
|
|
10
|
+
export { useBrushFilters, selectBrushFilters, brushHasValue, type BrushFilter, } from './hooks/useBrushFilters';
|
|
10
11
|
export type { DownloadAction, DownloadActionContext, EntityIconComponent, EntityIconMap, } from './types';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { UDIGrammar } from 'udi-toolkit/react';
|
|
2
|
+
interface RowMappingEntry {
|
|
3
|
+
encoding: 'text';
|
|
4
|
+
mark: 'text';
|
|
5
|
+
field: string;
|
|
6
|
+
type: 'quantitative' | 'ordinal' | 'nominal';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Build the "relevant fields" row mapping for a visualization's table view:
|
|
10
|
+
* the entity's key columns (primary/foreign/unique) followed by the fields
|
|
11
|
+
* the chart maps — e.g. a donor height×weight scatterplot tables as
|
|
12
|
+
* [uuid, hubmap_id, height, weight] instead of all 40+ columns.
|
|
13
|
+
*
|
|
14
|
+
* Key columns are omitted when the pipeline aggregates (rollup/kde): the
|
|
15
|
+
* output rows are groups, not entities, so key columns don't exist there.
|
|
16
|
+
*
|
|
17
|
+
* Returns null when nothing useful can be derived (no represented fields) —
|
|
18
|
+
* callers fall back to the all-fields default (`field: '*'`).
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildRelevantRowMapping(spec: UDIGrammar, keyFields: string[]): RowMappingEntry[] | null;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,20 +1,37 @@
|
|
|
1
1
|
import { UDIGrammar } from 'udi-toolkit/react';
|
|
2
|
+
import { TweakableParam } from '../components/VizTweakComponent.types';
|
|
3
|
+
type FieldMap = Record<string, string[]> | null;
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* not a duplicate encoding within the same spec.
|
|
5
|
+
* Compute the tweakable parameters for a spec — the single source of truth
|
|
6
|
+
* shared by VizTweakComponent (renders one dropdown per param) and
|
|
7
|
+
* hasTweakableFields (gates the gear button). Keeping both on this function
|
|
8
|
+
* means the panel and the gate can't drift.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* the
|
|
10
|
+
* Each representation mapping (first per encoding, `row` marks skipped) is
|
|
11
|
+
* classified into one of three kinds:
|
|
12
|
+
* - 'measure': the mapping is bound to a rollup *output* column that has an
|
|
13
|
+
* input field (mean/sum/… — not count/frequency). The swap
|
|
14
|
+
* changes the aggregated input field; options are quantitative.
|
|
15
|
+
* - 'dimension': the mapping field is a group-by dimension in the raw schema.
|
|
16
|
+
* The swap rewrites the groupby too; options are categorical.
|
|
17
|
+
* - 'field': a plain in-schema field, not locked, not aggregated. Options
|
|
18
|
+
* follow the mapping's type.
|
|
19
|
+
* Mappings referencing a locked field (binby/kde/join) or a derived column with
|
|
20
|
+
* no supported swap (e.g. a bare count output) are dropped.
|
|
15
21
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
|
|
22
|
+
* The option-list maps may be null (e.g. hasTweakableFields only needs to know
|
|
23
|
+
* whether any param exists); in that case options come back empty.
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeTweakableParams(spec: UDIGrammar, sourceFields: FieldMap, quantitativeSourceFields: FieldMap, categoricalSourceFields: FieldMap): TweakableParam[];
|
|
26
|
+
/**
|
|
27
|
+
* Returns true if the spec has at least one tweakable parameter. DashboardCard
|
|
28
|
+
* calls this to decide whether the gear-toggle button is actionable — without
|
|
29
|
+
* it the user could open a panel that just rendered `null`. Option lists aren't
|
|
30
|
+
* needed to decide existence, so callers pass only `sourceFields`.
|
|
31
|
+
*
|
|
32
|
+
* Lives in `utils/` rather than alongside VizTweakComponent so the component
|
|
33
|
+
* file stays component-only — exporting non-component helpers from a `.tsx`
|
|
34
|
+
* breaks react-refresh.
|
|
19
35
|
*/
|
|
20
36
|
export declare function hasTweakableFields(spec: UDIGrammar, sourceFields: Record<string, string[]> | null): boolean;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Overview: what is actually in the loaded data package. One accordion
|
|
3
|
+
* item per entity (ranges for numeric fields, leading categories for
|
|
4
|
+
* categorical ones, relationships, and the rows left after active filters),
|
|
5
|
+
* below a tree of how the entities join.
|
|
6
|
+
*
|
|
7
|
+
* Everything comes from `dataPackageStore`, so it renders the same for
|
|
8
|
+
* CSV-backed and server-side (remote) packages.
|
|
9
|
+
*/
|
|
10
|
+
export declare function DataOverviewPanel(): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface EntityOverviewProps {
|
|
2
|
+
entity: string;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Body of one entity's accordion item: its foreign-key relationships, every
|
|
6
|
+
* field with its range or leading categories, and a table of the rows that
|
|
7
|
+
* survive the currently active filters.
|
|
8
|
+
*/
|
|
9
|
+
export declare function EntityOverview({ entity }: EntityOverviewProps): import("react").JSX.Element | null;
|
|
10
|
+
export {};
|
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
* must go through this barrel; intra-feature imports use relative paths.
|
|
4
4
|
*/
|
|
5
5
|
export { createDataPackageStore, type DataPackageState, type LoadingPhase, } from './stores/dataPackageStore';
|
|
6
|
+
export { DataOverviewPanel } from './components/DataOverviewPanel';
|
|
6
7
|
export { joinDataPath } from './utils/joinDataPath';
|
|
7
8
|
export { evaluateStructuredText, hasStructuredReferences, type StructuredTextSegment, } from './utils/structuredTextParser';
|
|
@@ -14,12 +14,26 @@ export interface DataPackageState {
|
|
|
14
14
|
/** Maps entity names to canonical data URLs (from udi:path + resource.path). */
|
|
15
15
|
sourceResolver: Record<string, string>;
|
|
16
16
|
filteredData: Map<string, ExportRowSet>;
|
|
17
|
+
/** False when the package is served by a remote query backend — live
|
|
18
|
+
* (per-brush-tick) cross-filtering is unavailable; brushes commit on
|
|
19
|
+
* mouse-up with a server round-trip. */
|
|
20
|
+
interactiveMode: boolean;
|
|
21
|
+
/** True while a remote batched query round-trip is in flight. */
|
|
22
|
+
remoteQueryPending: boolean;
|
|
17
23
|
fetchDataPackage: (path: string, fetchOptions?: RequestInit) => Promise<void>;
|
|
24
|
+
/** Load a server-side package: fetches introspected metadata from
|
|
25
|
+
* GET /v1/yac/metadata and routes all queries through POST /v1/yac/query
|
|
26
|
+
* instead of loading CSVs into the browser. */
|
|
27
|
+
fetchRemotePackage: (apiBaseUrl: string, packageName: string, authToken?: string) => Promise<void>;
|
|
18
28
|
setDataPackage: (dataPackage: DataPackage, precomputedDomains?: DataFieldDomain[], fetchOptions?: RequestInit) => Promise<void>;
|
|
19
29
|
getDomainForField: (entity: string, field: string) => DataFieldDomain | undefined;
|
|
20
30
|
isValidIntervalFilter: (entity: string, field: string) => ValidStatus;
|
|
21
31
|
isValidPointFilter: (entity: string, field: string, values: unknown[]) => ValidStatus;
|
|
22
32
|
getEntityRelationship: (originSource: string, targetSource: string) => EntityRelationship | null;
|
|
33
|
+
/** Key columns of an entity — primary key, foreign keys, and udi:unique
|
|
34
|
+
* fields, in schema field order. Used by the table view's "relevant
|
|
35
|
+
* fields" mode so rows stay identifiable. */
|
|
36
|
+
getKeyFields: (entity: string) => string[];
|
|
23
37
|
setFilteredData: (entity: string, data: ExportRowSet) => void;
|
|
24
38
|
}
|
|
25
39
|
export declare function createDataPackageStore(): import('zustand').StoreApi<DataPackageState>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { DataFieldDomain, DataPackage } from '../../../../types/dataPackage';
|
|
2
|
+
export interface RelationshipLine {
|
|
3
|
+
/** `out`: this entity references `target`. `in`: `target` references it. */
|
|
4
|
+
direction: 'out' | 'in';
|
|
5
|
+
target: string;
|
|
6
|
+
/** Column on the entity being described. */
|
|
7
|
+
fromField: string;
|
|
8
|
+
/** Column on `target`. */
|
|
9
|
+
toField: string;
|
|
10
|
+
/** e.g. `many-to-one`, read from the entity's own perspective. */
|
|
11
|
+
cardinality?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SchemaNode {
|
|
14
|
+
name: string;
|
|
15
|
+
/** Distance from a root (an entity with no outgoing foreign keys). */
|
|
16
|
+
rank: number;
|
|
17
|
+
/** Index of this node within its rank. */
|
|
18
|
+
col: number;
|
|
19
|
+
rowCount: number;
|
|
20
|
+
}
|
|
21
|
+
export interface SchemaEdge {
|
|
22
|
+
from: string;
|
|
23
|
+
to: string;
|
|
24
|
+
cardinality?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface SchemaGraph {
|
|
27
|
+
nodes: SchemaNode[];
|
|
28
|
+
edges: SchemaEdge[];
|
|
29
|
+
/** Number of ranks (rows) the diagram needs. */
|
|
30
|
+
rankCount: number;
|
|
31
|
+
/** Widest rank, in nodes. */
|
|
32
|
+
maxCols: number;
|
|
33
|
+
}
|
|
34
|
+
export interface SchemaTreeNode {
|
|
35
|
+
name: string;
|
|
36
|
+
rowCount: number;
|
|
37
|
+
/** Cardinality of the edge to this node's parent, read outward. */
|
|
38
|
+
cardinality?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Edges nesting cannot express. Non-empty means this package is a graph, not
|
|
41
|
+
* a hierarchy — see {@link countCrossEdges}, which is what makes the panel
|
|
42
|
+
* render {@link buildJoinGroups} instead of the tree.
|
|
43
|
+
*/
|
|
44
|
+
otherEdges: SchemaEdge[];
|
|
45
|
+
children: SchemaTreeNode[];
|
|
46
|
+
}
|
|
47
|
+
export interface JoinGroup {
|
|
48
|
+
entity: string;
|
|
49
|
+
rowCount: number;
|
|
50
|
+
/** This entity's outgoing foreign keys, in declaration order. Often empty. */
|
|
51
|
+
edges: SchemaEdge[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Foreign keys touching `entity`, in both directions. Outgoing keys come from
|
|
55
|
+
* the entity's own schema; incoming ones are found by scanning every other
|
|
56
|
+
* resource for a reference back to it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function describeRelationships(dataPackage: DataPackage | null, entity: string): RelationshipLine[];
|
|
59
|
+
/**
|
|
60
|
+
* Lays the package out as ranked rows: entities with no outgoing foreign keys
|
|
61
|
+
* are roots, and every other entity sits one rank below the deepest thing it
|
|
62
|
+
* references. Yields `donors → samples → datasets` for the HuBMAP package and a
|
|
63
|
+
* `Patient` hub above its four child tables for the star-shaped pcx package.
|
|
64
|
+
*
|
|
65
|
+
* ponytail: rank-by-row placement with straight edges — no crossing
|
|
66
|
+
* minimisation. Reach for a layout library only if packages get much denser.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildSchemaGraph(dataPackage: DataPackage | null): SchemaGraph;
|
|
69
|
+
/**
|
|
70
|
+
* Reshapes the schema graph into a forest for the overview panel.
|
|
71
|
+
*
|
|
72
|
+
* The panel is a ~376px column, so a box-and-line diagram laid out in ranked rows
|
|
73
|
+
* grows past it as soon as one rank is wide — pcx's four children of `Patient`
|
|
74
|
+
* needed 452px. Nesting turns breadth into rows instead, making the rendered
|
|
75
|
+
* width independent of how many entities the package has.
|
|
76
|
+
*
|
|
77
|
+
* Only used when the package really is a hierarchy: each node is parented to the
|
|
78
|
+
* referenced entity with the greatest rank strictly below its own, and any edge
|
|
79
|
+
* left over lands in `otherEdges` — one of those is enough for the panel to show
|
|
80
|
+
* the join list instead. That `<` is what keeps this a forest: parent ranks
|
|
81
|
+
* strictly decrease, so a cyclic package — which `buildSchemaGraph` already
|
|
82
|
+
* terminates on by treating a back edge as rank 0 — drops the back edge into
|
|
83
|
+
* `otherEdges` instead of forming a parent cycle.
|
|
84
|
+
*
|
|
85
|
+
* ponytail: composite keys stay unsupported, matching `describeRelationships`.
|
|
86
|
+
*/
|
|
87
|
+
export declare function buildSchemaTree(dataPackage: DataPackage | null): SchemaTreeNode[];
|
|
88
|
+
/**
|
|
89
|
+
* How many foreign keys the tree had to demote to `otherEdges` — i.e. how far
|
|
90
|
+
* the package is from being a clean hierarchy. Zero means every relationship is
|
|
91
|
+
* expressible as nesting; anything else means the tree is telling a partial
|
|
92
|
+
* story and the panel should show the join list instead.
|
|
93
|
+
*/
|
|
94
|
+
export declare function countCrossEdges(nodes: SchemaTreeNode[]): number;
|
|
95
|
+
/**
|
|
96
|
+
* One entry per entity, each carrying the foreign keys it declares. This is the
|
|
97
|
+
* view for packages that are graphs rather than hierarchies: unlike the tree it
|
|
98
|
+
* demotes nothing, so a junction table's four parents all read equally instead
|
|
99
|
+
* of one becoming an arbitrary parent and the rest becoming footnotes.
|
|
100
|
+
*
|
|
101
|
+
* Every entity gets an entry even when it declares no keys — a pure reference
|
|
102
|
+
* target like HuBMAP's `donors` would otherwise appear only as an arrow head,
|
|
103
|
+
* with no row count anywhere in the map. Resource order, so the list runs
|
|
104
|
+
* parallel to the accordion beneath it.
|
|
105
|
+
*
|
|
106
|
+
* Returns nothing when the package declares no relationships at all: with no
|
|
107
|
+
* edges to add, this would just be a second copy of that accordion.
|
|
108
|
+
*/
|
|
109
|
+
export declare function buildJoinGroups(dataPackage: DataPackage | null): JoinGroup[];
|
|
110
|
+
/**
|
|
111
|
+
* Numeric range for an interval domain: `"1.2K – 4.1G"`.
|
|
112
|
+
*
|
|
113
|
+
* All-null columns reach us as `{ min: Infinity, max: -Infinity }` from the
|
|
114
|
+
* toolkit's domain worker, so non-finite bounds must degrade, not render.
|
|
115
|
+
*/
|
|
116
|
+
export declare function formatIntervalDomain(domain: DataFieldDomain): string;
|
|
117
|
+
/**
|
|
118
|
+
* The distinct values of a categorical (point) domain, cleaned for display.
|
|
119
|
+
*
|
|
120
|
+
* The toolkit's domain worker builds these with `Array.from(new Set(values))`
|
|
121
|
+
* and casts to `string[]` without filtering, so nulls and blanks come through
|
|
122
|
+
* and the count is uncapped — an id-like column can carry one value per row.
|
|
123
|
+
*/
|
|
124
|
+
export declare function categoricalValues(domain: DataFieldDomain): string[];
|
|
125
|
+
/**
|
|
126
|
+
* Fields that actually act as keys in this entity's relationships: its declared
|
|
127
|
+
* primary key, the columns of its own foreign keys, and the columns other
|
|
128
|
+
* entities point at.
|
|
129
|
+
*
|
|
130
|
+
* Deliberately narrower than `dataPackageStore.getKeyFields`, which also counts
|
|
131
|
+
* any field flagged `udi:unique`. That flag means "no repeated values", which a
|
|
132
|
+
* timestamp column satisfies by accident — marking it a key field is misleading.
|
|
133
|
+
* The store's broader notion still drives the row table's column projection,
|
|
134
|
+
* where an incidentally-unique column is a useful identifier.
|
|
135
|
+
*/
|
|
136
|
+
export declare function relationshipKeyFields(dataPackage: DataPackage | null, entity: string): Set<string>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -4,6 +4,13 @@ interface IntervalFilterComponentProps {
|
|
|
4
4
|
fieldIndex: number;
|
|
5
5
|
tweakable: boolean;
|
|
6
6
|
filterKey: string;
|
|
7
|
+
/**
|
|
8
|
+
* Optional override for where an edit is written. Defaults to
|
|
9
|
+
* `dataFiltersStore.setDataSelection(filterKey, …)` (the LLM-filter path).
|
|
10
|
+
* Brush-originated filters pass a writer that targets the brush store
|
|
11
|
+
* instead, so the same widget can drive a visualization brush.
|
|
12
|
+
*/
|
|
13
|
+
onCommit?: (selection: DataSelection) => void;
|
|
7
14
|
}
|
|
8
|
-
export declare function IntervalFilterComponent({ dataSelection, fieldIndex, tweakable, filterKey, }: IntervalFilterComponentProps): import("react").JSX.Element;
|
|
15
|
+
export declare function IntervalFilterComponent({ dataSelection, fieldIndex, tweakable, filterKey, onCommit, }: IntervalFilterComponentProps): import("react").JSX.Element;
|
|
9
16
|
export {};
|
|
@@ -3,6 +3,12 @@ interface PointFilterComponentProps {
|
|
|
3
3
|
dataSelection: DataSelection;
|
|
4
4
|
tweakable: boolean;
|
|
5
5
|
filterKey: string;
|
|
6
|
+
/**
|
|
7
|
+
* Optional override for where an edit is written. Defaults to
|
|
8
|
+
* `dataFiltersStore.setDataSelection(filterKey, …)` (the LLM-filter path).
|
|
9
|
+
* Brush-originated filters pass a writer that targets the brush store.
|
|
10
|
+
*/
|
|
11
|
+
onCommit?: (selection: DataSelection) => void;
|
|
6
12
|
}
|
|
7
|
-
export declare function PointFilterComponent({ dataSelection, tweakable, filterKey, }: PointFilterComponentProps): import("react").JSX.Element;
|
|
13
|
+
export declare function PointFilterComponent({ dataSelection, tweakable, filterKey, onCommit, }: PointFilterComponentProps): import("react").JSX.Element;
|
|
8
14
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,4 +3,6 @@
|
|
|
3
3
|
* must go through this barrel; intra-feature imports use relative paths.
|
|
4
4
|
*/
|
|
5
5
|
export { ToolCallRenderer } from './components/ToolCallRenderer';
|
|
6
|
+
export { IntervalFilterComponent } from './components/IntervalFilterComponent';
|
|
7
|
+
export { PointFilterComponent } from './components/PointFilterComponent';
|
|
6
8
|
export type { FreeTextExplainArgs, RebuffArgs, ClarifyVariableArgs, FilterDataArgs, TextSegment, CreateVisualizationArgs, } from './types';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
export declare const ChatRootProvider: import('react').Provider<RefObject<HTMLElement | null> | null>;
|
|
3
|
+
/**
|
|
4
|
+
* The chat root ref, or `undefined` when unmounted outside UDIChat — pass
|
|
5
|
+
* straight to a Base UI `Portal`'s `container` prop.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useChatRoot(): RefObject<HTMLElement | null> | undefined;
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
export interface GlobalState {
|
|
2
2
|
debugMode: boolean;
|
|
3
3
|
isProduction: boolean;
|
|
4
|
+
/** Whether the Data Overview view is showing in the left region. */
|
|
5
|
+
overviewOpen: boolean;
|
|
6
|
+
/** Entity whose overview accordion item should be expanded, if any. */
|
|
7
|
+
overviewEntity: string | null;
|
|
4
8
|
toggleDebugMode: () => void;
|
|
9
|
+
/**
|
|
10
|
+
* Open/close the Data Overview and optionally pick the entity to expand.
|
|
11
|
+
* Omitting `entity` leaves the current one alone (so the header toggle
|
|
12
|
+
* reopens on whatever was last looked at); pass `null` to clear it.
|
|
13
|
+
*/
|
|
14
|
+
setOverview: (open: boolean, entity?: string | null) => void;
|
|
5
15
|
}
|
|
6
16
|
export declare function createGlobalStore(): import('zustand').StoreApi<GlobalState>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EntityIconMap } from '../../features/dashboard';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in entity → icon map, merged under any consumer-supplied icons from
|
|
4
|
+
* `useEntityIcons()`. Shared by the dashboard's count chips and the data
|
|
5
|
+
* overview panel, so it lives outside both — the fast-refresh rule forbids
|
|
6
|
+
* exporting it from a component module.
|
|
7
|
+
*/
|
|
8
|
+
export declare const DEFAULT_ENTITY_ICONS: EntityIconMap;
|
|
9
|
+
/** Fallback for an entity with no icon of its own. */
|
|
10
|
+
export declare const FALLBACK_ENTITY_ICON: import('react').ForwardRefExoticComponent<Omit<import('lucide-react').LucideProps, "ref"> & import('react').RefAttributes<SVGSVGElement>>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Wraps the first case-insensitive occurrence of `query` in `text` with a
|
|
4
|
+
* `<mark>`. Shared by the chat's field chips and the data overview's field list
|
|
5
|
+
* so that filtering looks the same wherever fields are listed.
|
|
6
|
+
*/
|
|
7
|
+
export declare function highlightMatch(text: string, query: string): ReactNode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull a human-readable detail out of a response body: FastAPI's `detail`
|
|
3
|
+
* (string or validation-error array), our handlers' `error`/`message`, or a
|
|
4
|
+
* short plain-text body. Returns '' when there's nothing safe to show (e.g. an
|
|
5
|
+
* HTML error page or a multi-line stack trace).
|
|
6
|
+
*/
|
|
7
|
+
export declare function extractErrorDetail(body: string): string;
|
|
8
|
+
/** Format a status + body into `Label: detail` (or just `Label`). */
|
|
9
|
+
export declare function formatHttpError(status: number, body: string): string;
|
|
10
|
+
/** Read a failed Response and build a friendly Error to throw. */
|
|
11
|
+
export declare function httpError(response: Response): Promise<Error>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|