@sqlrooms/mosaic 0.29.0-rc.1 → 0.29.0-rc.2
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 +41 -2
- package/dist/MosaicChart.d.ts +20 -0
- package/dist/MosaicChart.d.ts.map +1 -0
- package/dist/MosaicChart.js +25 -0
- package/dist/MosaicChart.js.map +1 -0
- package/dist/MosaicChartBuilder.d.ts +32 -0
- package/dist/MosaicChartBuilder.d.ts.map +1 -0
- package/dist/MosaicChartBuilder.js +35 -0
- package/dist/MosaicChartBuilder.js.map +1 -0
- package/dist/MosaicColorLegend.d.ts +18 -0
- package/dist/MosaicColorLegend.d.ts.map +1 -0
- package/dist/MosaicColorLegend.js +117 -0
- package/dist/MosaicColorLegend.js.map +1 -0
- package/dist/MosaicSlice.d.ts +16 -13
- package/dist/MosaicSlice.d.ts.map +1 -1
- package/dist/MosaicSlice.js +67 -32
- package/dist/MosaicSlice.js.map +1 -1
- package/dist/VgPlotChart.d.ts +8 -0
- package/dist/VgPlotChart.d.ts.map +1 -1
- package/dist/VgPlotChart.js +26 -6
- package/dist/VgPlotChart.js.map +1 -1
- package/dist/chart-builders/ChartBuilderContent.d.ts +26 -0
- package/dist/chart-builders/ChartBuilderContent.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderContent.js +59 -0
- package/dist/chart-builders/ChartBuilderContent.js.map +1 -0
- package/dist/chart-builders/ChartBuilderContext.d.ts +11 -0
- package/dist/chart-builders/ChartBuilderContext.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderContext.js +10 -0
- package/dist/chart-builders/ChartBuilderContext.js.map +1 -0
- package/dist/chart-builders/ChartBuilderDialog.d.ts +23 -0
- package/dist/chart-builders/ChartBuilderDialog.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderDialog.js +15 -0
- package/dist/chart-builders/ChartBuilderDialog.js.map +1 -0
- package/dist/chart-builders/FieldSelectorInput.d.ts +13 -0
- package/dist/chart-builders/FieldSelectorInput.d.ts.map +1 -0
- package/dist/chart-builders/FieldSelectorInput.js +19 -0
- package/dist/chart-builders/FieldSelectorInput.js.map +1 -0
- package/dist/chart-builders/builders.d.ts +7 -0
- package/dist/chart-builders/builders.d.ts.map +1 -0
- package/dist/chart-builders/builders.js +280 -0
- package/dist/chart-builders/builders.js.map +1 -0
- package/dist/chart-builders/chartSpecTitle.d.ts +7 -0
- package/dist/chart-builders/chartSpecTitle.d.ts.map +1 -0
- package/dist/chart-builders/chartSpecTitle.js +10 -0
- package/dist/chart-builders/chartSpecTitle.js.map +1 -0
- package/dist/chart-builders/createMosaicChartTool.d.ts +45 -0
- package/dist/chart-builders/createMosaicChartTool.d.ts.map +1 -0
- package/dist/chart-builders/createMosaicChartTool.js +109 -0
- package/dist/chart-builders/createMosaicChartTool.js.map +1 -0
- package/dist/chart-builders/describeChartSpecs.d.ts +7 -0
- package/dist/chart-builders/describeChartSpecs.d.ts.map +1 -0
- package/dist/chart-builders/describeChartSpecs.js +38 -0
- package/dist/chart-builders/describeChartSpecs.js.map +1 -0
- package/dist/chart-builders/types.d.ts +40 -0
- package/dist/chart-builders/types.d.ts.map +1 -0
- package/dist/chart-builders/types.js +2 -0
- package/dist/chart-builders/types.js.map +1 -0
- package/dist/dashboard/MosaicDashboard.d.ts +20 -0
- package/dist/dashboard/MosaicDashboard.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboard.js +68 -0
- package/dist/dashboard/MosaicDashboard.js.map +1 -0
- package/dist/dashboard/MosaicDashboardChartPanel.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardChartPanel.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardChartPanel.js +49 -0
- package/dist/dashboard/MosaicDashboardChartPanel.js.map +1 -0
- package/dist/dashboard/MosaicDashboardCharts.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardCharts.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardCharts.js +45 -0
- package/dist/dashboard/MosaicDashboardCharts.js.map +1 -0
- package/dist/dashboard/MosaicDashboardContext.d.ts +11 -0
- package/dist/dashboard/MosaicDashboardContext.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardContext.js +10 -0
- package/dist/dashboard/MosaicDashboardContext.js.map +1 -0
- package/dist/dashboard/MosaicDashboardProfiler.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardProfiler.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardProfiler.js +21 -0
- package/dist/dashboard/MosaicDashboardProfiler.js.map +1 -0
- package/dist/dashboard/MosaicDashboardSlice.d.ts +68 -0
- package/dist/dashboard/MosaicDashboardSlice.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardSlice.js +230 -0
- package/dist/dashboard/MosaicDashboardSlice.js.map +1 -0
- package/dist/dashboard/MosaicDashboardToolbar.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardToolbar.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardToolbar.js +19 -0
- package/dist/dashboard/MosaicDashboardToolbar.js.map +1 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts +8 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts.map +1 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.js +40 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.js.map +1 -0
- package/dist/editor/MosaicChartContainer.d.ts +51 -0
- package/dist/editor/MosaicChartContainer.d.ts.map +1 -0
- package/dist/editor/MosaicChartContainer.js +39 -0
- package/dist/editor/MosaicChartContainer.js.map +1 -0
- package/dist/editor/MosaicChartDisplay.d.ts +18 -0
- package/dist/editor/MosaicChartDisplay.d.ts.map +1 -0
- package/dist/editor/MosaicChartDisplay.js +21 -0
- package/dist/editor/MosaicChartDisplay.js.map +1 -0
- package/dist/editor/MosaicChartEditorActions.d.ts +20 -0
- package/dist/editor/MosaicChartEditorActions.d.ts.map +1 -0
- package/dist/editor/MosaicChartEditorActions.js +18 -0
- package/dist/editor/MosaicChartEditorActions.js.map +1 -0
- package/dist/editor/MosaicCodeMirrorEditor.d.ts +15 -0
- package/dist/editor/MosaicCodeMirrorEditor.d.ts.map +1 -0
- package/dist/editor/MosaicCodeMirrorEditor.js +26 -0
- package/dist/editor/MosaicCodeMirrorEditor.js.map +1 -0
- package/dist/editor/MosaicEditorContext.d.ts +8 -0
- package/dist/editor/MosaicEditorContext.d.ts.map +1 -0
- package/dist/editor/MosaicEditorContext.js +14 -0
- package/dist/editor/MosaicEditorContext.js.map +1 -0
- package/dist/editor/MosaicSpecEditorPanel.d.ts +20 -0
- package/dist/editor/MosaicSpecEditorPanel.d.ts.map +1 -0
- package/dist/editor/MosaicSpecEditorPanel.js +25 -0
- package/dist/editor/MosaicSpecEditorPanel.js.map +1 -0
- package/dist/editor/mosaicSchema.d.ts +20 -0
- package/dist/editor/mosaicSchema.d.ts.map +1 -0
- package/dist/editor/mosaicSchema.js +57 -0
- package/dist/editor/mosaicSchema.js.map +1 -0
- package/dist/editor/types.d.ts +72 -0
- package/dist/editor/types.d.ts.map +1 -0
- package/dist/editor/types.js +2 -0
- package/dist/editor/types.js.map +1 -0
- package/dist/editor/useMosaicChartEditor.d.ts +9 -0
- package/dist/editor/useMosaicChartEditor.d.ts.map +1 -0
- package/dist/editor/useMosaicChartEditor.js +199 -0
- package/dist/editor/useMosaicChartEditor.js.map +1 -0
- package/dist/index.d.ts +27 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/profiler/MosaicProfiler.d.ts +32 -0
- package/dist/profiler/MosaicProfiler.d.ts.map +1 -0
- package/dist/profiler/MosaicProfiler.js +57 -0
- package/dist/profiler/MosaicProfiler.js.map +1 -0
- package/dist/profiler/MosaicProfilerHeader.d.ts +7 -0
- package/dist/profiler/MosaicProfilerHeader.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerHeader.js +196 -0
- package/dist/profiler/MosaicProfilerHeader.js.map +1 -0
- package/dist/profiler/MosaicProfilerRows.d.ts +9 -0
- package/dist/profiler/MosaicProfilerRows.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerRows.js +65 -0
- package/dist/profiler/MosaicProfilerRows.js.map +1 -0
- package/dist/profiler/MosaicProfilerStatusBar.d.ts +9 -0
- package/dist/profiler/MosaicProfilerStatusBar.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerStatusBar.js +28 -0
- package/dist/profiler/MosaicProfilerStatusBar.js.map +1 -0
- package/dist/profiler/ProfilerCategoryClient.d.ts +50 -0
- package/dist/profiler/ProfilerCategoryClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerCategoryClient.js +121 -0
- package/dist/profiler/ProfilerCategoryClient.js.map +1 -0
- package/dist/profiler/ProfilerCountClient.d.ts +28 -0
- package/dist/profiler/ProfilerCountClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerCountClient.js +51 -0
- package/dist/profiler/ProfilerCountClient.js.map +1 -0
- package/dist/profiler/ProfilerHistogramClient.d.ts +69 -0
- package/dist/profiler/ProfilerHistogramClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerHistogramClient.js +179 -0
- package/dist/profiler/ProfilerHistogramClient.js.map +1 -0
- package/dist/profiler/ProfilerPageClient.d.ts +37 -0
- package/dist/profiler/ProfilerPageClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerPageClient.js +65 -0
- package/dist/profiler/ProfilerPageClient.js.map +1 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts +24 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.js +51 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.js.map +1 -0
- package/dist/profiler/createProfilerStore.d.ts +45 -0
- package/dist/profiler/createProfilerStore.d.ts.map +1 -0
- package/dist/profiler/createProfilerStore.js +120 -0
- package/dist/profiler/createProfilerStore.js.map +1 -0
- package/dist/profiler/layout.d.ts +7 -0
- package/dist/profiler/layout.d.ts.map +1 -0
- package/dist/profiler/layout.js +13 -0
- package/dist/profiler/layout.js.map +1 -0
- package/dist/profiler/profilerController.d.ts +64 -0
- package/dist/profiler/profilerController.d.ts.map +1 -0
- package/dist/profiler/profilerController.js +123 -0
- package/dist/profiler/profilerController.js.map +1 -0
- package/dist/profiler/types.d.ts +86 -0
- package/dist/profiler/types.d.ts.map +1 -0
- package/dist/profiler/types.js +2 -0
- package/dist/profiler/types.js.map +1 -0
- package/dist/profiler/useMosaicProfiler.d.ts +7 -0
- package/dist/profiler/useMosaicProfiler.d.ts.map +1 -0
- package/dist/profiler/useMosaicProfiler.js +339 -0
- package/dist/profiler/useMosaicProfiler.js.map +1 -0
- package/dist/profiler/utils.d.ts +61 -0
- package/dist/profiler/utils.d.ts.map +1 -0
- package/dist/profiler/utils.js +347 -0
- package/dist/profiler/utils.js.map +1 -0
- package/dist/tableInterop.d.ts +30 -0
- package/dist/tableInterop.d.ts.map +1 -0
- package/dist/tableInterop.js +85 -0
- package/dist/tableInterop.js.map +1 -0
- package/dist/use-mosaic.d.ts +11 -0
- package/dist/use-mosaic.d.ts.map +1 -0
- package/dist/use-mosaic.js +42 -0
- package/dist/use-mosaic.js.map +1 -0
- package/dist/useMosaicClient.d.ts +5 -4
- package/dist/useMosaicClient.d.ts.map +1 -1
- package/dist/useMosaicClient.js +13 -3
- package/dist/useMosaicClient.js.map +1 -1
- package/package.json +24 -6
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { Selection } from '@uwdata/mosaic-core';
|
|
2
|
+
import type { Interval1D } from '@uwdata/mosaic-plot';
|
|
3
|
+
import type { Field, Table } from 'apache-arrow';
|
|
4
|
+
import type { Dispatch, SetStateAction } from 'react';
|
|
5
|
+
export type MosaicProfilerSorting = Array<{
|
|
6
|
+
id: string;
|
|
7
|
+
desc: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
export type MosaicProfilerPaginationState = {
|
|
10
|
+
pageIndex: number;
|
|
11
|
+
pageSize: number;
|
|
12
|
+
};
|
|
13
|
+
export type MosaicProfilerBinValue = number | Date;
|
|
14
|
+
export type MosaicProfilerBin = {
|
|
15
|
+
x0: MosaicProfilerBinValue;
|
|
16
|
+
x1: MosaicProfilerBinValue;
|
|
17
|
+
length: number;
|
|
18
|
+
};
|
|
19
|
+
export type MosaicProfilerSummaryStatus = {
|
|
20
|
+
error?: Error;
|
|
21
|
+
isLoading: boolean;
|
|
22
|
+
};
|
|
23
|
+
export type MosaicProfilerHistogramSummary = MosaicProfilerSummaryStatus & {
|
|
24
|
+
filteredBins: MosaicProfilerBin[];
|
|
25
|
+
filteredNullCount: number;
|
|
26
|
+
interactor: Interval1D | null;
|
|
27
|
+
kind: 'histogram';
|
|
28
|
+
totalBins: MosaicProfilerBin[];
|
|
29
|
+
totalNullCount: number;
|
|
30
|
+
valueType: 'date' | 'number';
|
|
31
|
+
};
|
|
32
|
+
export type MosaicProfilerCategoryBucket = {
|
|
33
|
+
filteredCount: number;
|
|
34
|
+
key: string;
|
|
35
|
+
kind: 'null' | 'overflow' | 'unique' | 'value';
|
|
36
|
+
label: string;
|
|
37
|
+
selectable: boolean;
|
|
38
|
+
totalCount: number;
|
|
39
|
+
};
|
|
40
|
+
export type MosaicProfilerCategorySummary = MosaicProfilerSummaryStatus & {
|
|
41
|
+
bucketCount: number;
|
|
42
|
+
buckets: MosaicProfilerCategoryBucket[];
|
|
43
|
+
kind: 'category';
|
|
44
|
+
selectedKey?: string;
|
|
45
|
+
toggleValue: (key: string) => void;
|
|
46
|
+
};
|
|
47
|
+
export type MosaicProfilerUnsupportedSummary = MosaicProfilerSummaryStatus & {
|
|
48
|
+
kind: 'unsupported';
|
|
49
|
+
label: string;
|
|
50
|
+
};
|
|
51
|
+
export type MosaicProfilerSummaryState = MosaicProfilerCategorySummary | MosaicProfilerHistogramSummary | MosaicProfilerUnsupportedSummary;
|
|
52
|
+
export type MosaicProfilerColumnKind = 'category' | 'histogram' | 'unsupported';
|
|
53
|
+
export type MosaicProfilerColumnState = {
|
|
54
|
+
field: Field;
|
|
55
|
+
kind: MosaicProfilerColumnKind;
|
|
56
|
+
name: string;
|
|
57
|
+
summary: MosaicProfilerSummaryState;
|
|
58
|
+
};
|
|
59
|
+
export type MosaicProfilerOptions = {
|
|
60
|
+
categoryLimit?: number;
|
|
61
|
+
columns?: string[];
|
|
62
|
+
initialSorting?: MosaicProfilerSorting;
|
|
63
|
+
pageSize?: number;
|
|
64
|
+
selection?: Selection;
|
|
65
|
+
selectionName?: string;
|
|
66
|
+
summaryBins?: number;
|
|
67
|
+
tableName: string;
|
|
68
|
+
};
|
|
69
|
+
export type UseMosaicProfilerReturn = {
|
|
70
|
+
columns: MosaicProfilerColumnState[];
|
|
71
|
+
filteredRowCount?: number;
|
|
72
|
+
hasFilters: boolean;
|
|
73
|
+
isLoading: boolean;
|
|
74
|
+
pageQuery: string;
|
|
75
|
+
pageTable?: Table;
|
|
76
|
+
pagination: MosaicProfilerPaginationState;
|
|
77
|
+
reset: () => void;
|
|
78
|
+
selection: Selection;
|
|
79
|
+
setPagination: Dispatch<SetStateAction<MosaicProfilerPaginationState>>;
|
|
80
|
+
setSorting: Dispatch<SetStateAction<MosaicProfilerSorting>>;
|
|
81
|
+
sorting: MosaicProfilerSorting;
|
|
82
|
+
sql: string;
|
|
83
|
+
tableError?: Error;
|
|
84
|
+
totalRowCount?: number;
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/profiler/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAC,KAAK,EAAE,KAAK,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAC,QAAQ,EAAE,cAAc,EAAC,MAAM,OAAO,CAAC;AAEpD,MAAM,MAAM,qBAAqB,GAAG,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,CAAC,CAAC;AAEvE,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,IAAI,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,sBAAsB,CAAC;IAC3B,EAAE,EAAE,sBAAsB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG,2BAA2B,GAAG;IACzE,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG,2BAA2B,GAAG;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,4BAA4B,EAAE,CAAC;IACxC,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG,2BAA2B,GAAG;IAC3E,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAClC,6BAA6B,GAC7B,8BAA8B,GAC9B,gCAAgC,CAAC;AAErC,MAAM,MAAM,wBAAwB,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;AAEhF,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,wBAAwB,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,0BAA0B,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,yBAAyB,EAAE,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,UAAU,EAAE,6BAA6B,CAAC;IAC1C,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,aAAa,EAAE,QAAQ,CAAC,cAAc,CAAC,6BAA6B,CAAC,CAAC,CAAC;IACvE,UAAU,EAAE,QAAQ,CAAC,cAAc,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC5D,OAAO,EAAE,qBAAqB,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/profiler/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {Selection} from '@uwdata/mosaic-core';\nimport type {Interval1D} from '@uwdata/mosaic-plot';\nimport type {Field, Table} from 'apache-arrow';\nimport type {Dispatch, SetStateAction} from 'react';\n\nexport type MosaicProfilerSorting = Array<{id: string; desc: boolean}>;\n\nexport type MosaicProfilerPaginationState = {\n pageIndex: number;\n pageSize: number;\n};\n\nexport type MosaicProfilerBinValue = number | Date;\n\nexport type MosaicProfilerBin = {\n x0: MosaicProfilerBinValue;\n x1: MosaicProfilerBinValue;\n length: number;\n};\n\nexport type MosaicProfilerSummaryStatus = {\n error?: Error;\n isLoading: boolean;\n};\n\nexport type MosaicProfilerHistogramSummary = MosaicProfilerSummaryStatus & {\n filteredBins: MosaicProfilerBin[];\n filteredNullCount: number;\n interactor: Interval1D | null;\n kind: 'histogram';\n totalBins: MosaicProfilerBin[];\n totalNullCount: number;\n valueType: 'date' | 'number';\n};\n\nexport type MosaicProfilerCategoryBucket = {\n filteredCount: number;\n key: string;\n kind: 'null' | 'overflow' | 'unique' | 'value';\n label: string;\n selectable: boolean;\n totalCount: number;\n};\n\nexport type MosaicProfilerCategorySummary = MosaicProfilerSummaryStatus & {\n bucketCount: number;\n buckets: MosaicProfilerCategoryBucket[];\n kind: 'category';\n selectedKey?: string;\n toggleValue: (key: string) => void;\n};\n\nexport type MosaicProfilerUnsupportedSummary = MosaicProfilerSummaryStatus & {\n kind: 'unsupported';\n label: string;\n};\n\nexport type MosaicProfilerSummaryState =\n | MosaicProfilerCategorySummary\n | MosaicProfilerHistogramSummary\n | MosaicProfilerUnsupportedSummary;\n\nexport type MosaicProfilerColumnKind = 'category' | 'histogram' | 'unsupported';\n\nexport type MosaicProfilerColumnState = {\n field: Field;\n kind: MosaicProfilerColumnKind;\n name: string;\n summary: MosaicProfilerSummaryState;\n};\n\nexport type MosaicProfilerOptions = {\n categoryLimit?: number;\n columns?: string[];\n initialSorting?: MosaicProfilerSorting;\n pageSize?: number;\n selection?: Selection;\n selectionName?: string;\n summaryBins?: number;\n tableName: string;\n};\n\nexport type UseMosaicProfilerReturn = {\n columns: MosaicProfilerColumnState[];\n filteredRowCount?: number;\n hasFilters: boolean;\n isLoading: boolean;\n pageQuery: string;\n pageTable?: Table;\n pagination: MosaicProfilerPaginationState;\n reset: () => void;\n selection: Selection;\n setPagination: Dispatch<SetStateAction<MosaicProfilerPaginationState>>;\n setSorting: Dispatch<SetStateAction<MosaicProfilerSorting>>;\n sorting: MosaicProfilerSorting;\n sql: string;\n tableError?: Error;\n totalRowCount?: number;\n};\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MosaicProfilerOptions, UseMosaicProfilerReturn } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Aggregates Mosaic-backed schema, rows, counts, and summaries into the stable
|
|
4
|
+
* public profiler API consumed by the React table UI.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useMosaicProfiler(options: MosaicProfilerOptions): UseMosaicProfilerReturn;
|
|
7
|
+
//# sourceMappingURL=useMosaicProfiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMosaicProfiler.d.ts","sourceRoot":"","sources":["../../src/profiler/useMosaicProfiler.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAEV,qBAAqB,EAGrB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAmbjB;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,qBAAqB,GAC7B,uBAAuB,CAqGzB"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { createId } from '@paralleldrive/cuid2';
|
|
2
|
+
import { useDebounce } from '@sqlrooms/ui';
|
|
3
|
+
import { Selection as MosaicSelection, } from '@uwdata/mosaic-core';
|
|
4
|
+
import { useEffect, useMemo, useState, } from 'react';
|
|
5
|
+
import { useStore } from 'zustand';
|
|
6
|
+
import { useStoreWithMosaic } from '../MosaicSlice';
|
|
7
|
+
import { createProfilerStore, } from './createProfilerStore';
|
|
8
|
+
import { connectProfilerCountClient, connectProfilerPageClient, connectProfilerSummaryClients, loadProfilerSchema, } from './profilerController';
|
|
9
|
+
import { buildProfilerBaseQuery, buildProfilerPageQuery, createEmptySummaryState, isProfilerHistogramType, isProfilerUnsupportedSummaryType, } from './utils';
|
|
10
|
+
/**
|
|
11
|
+
* Tracks Mosaic selection updates as a monotonically increasing version so
|
|
12
|
+
* memoized queries and lifecycle effects can respond to crossfilter changes.
|
|
13
|
+
*/
|
|
14
|
+
function useSelectionVersion(selection) {
|
|
15
|
+
const [version, setVersion] = useState(0);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const handleChange = () => setVersion((value) => value + 1);
|
|
18
|
+
selection.addEventListener('value', handleChange);
|
|
19
|
+
return () => selection.removeEventListener('value', handleChange);
|
|
20
|
+
}, [selection]);
|
|
21
|
+
return version;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolves the profiler selection, creating a crossfilter selection when the
|
|
25
|
+
* caller does not supply one, and exposes a version that changes with it.
|
|
26
|
+
*/
|
|
27
|
+
function useProfilerSelection(options) {
|
|
28
|
+
const { selection: providedSelection, selectionName } = options;
|
|
29
|
+
const generatedSelectionName = useMemo(() => `mosaic-profiler-${createId()}`, []);
|
|
30
|
+
const selectionKey = selectionName ?? generatedSelectionName;
|
|
31
|
+
const existingSelection = useStoreWithMosaic((state) => state.mosaic.selections[selectionKey]);
|
|
32
|
+
const getSelection = useStoreWithMosaic((state) => state.mosaic.getSelection);
|
|
33
|
+
const [fallbackSelection] = useState(() => MosaicSelection.crossfilter());
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!providedSelection && !existingSelection) {
|
|
36
|
+
getSelection(selectionKey, 'crossfilter');
|
|
37
|
+
}
|
|
38
|
+
}, [existingSelection, getSelection, providedSelection, selectionKey]);
|
|
39
|
+
const selection = providedSelection ?? existingSelection ?? fallbackSelection;
|
|
40
|
+
return {
|
|
41
|
+
selection,
|
|
42
|
+
selectionVersion: useSelectionVersion(selection),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Creates the per-profiler local store and subscribes to the raw state slices
|
|
47
|
+
* that the public profiler hook exposes.
|
|
48
|
+
*/
|
|
49
|
+
function useProfilerStoreState(options) {
|
|
50
|
+
const [profilerStore] = useState(() => createProfilerStore({
|
|
51
|
+
initialSorting: options.initialSorting,
|
|
52
|
+
pageSize: options.pageSize,
|
|
53
|
+
}));
|
|
54
|
+
return {
|
|
55
|
+
filteredCount: useStore(profilerStore, (state) => state.filteredCount),
|
|
56
|
+
lastNonEmptyPageTable: useStore(profilerStore, (state) => state.lastNonEmptyPageTable),
|
|
57
|
+
page: useStore(profilerStore, (state) => state.page),
|
|
58
|
+
pagination: useStore(profilerStore, (state) => state.pagination),
|
|
59
|
+
profilerStore,
|
|
60
|
+
schema: useStore(profilerStore, (state) => state.schema),
|
|
61
|
+
setPagination: useStore(profilerStore, (state) => state.setPagination),
|
|
62
|
+
setSorting: useStore(profilerStore, (state) => state.setSorting),
|
|
63
|
+
sorting: useStore(profilerStore, (state) => state.sorting),
|
|
64
|
+
summaries: useStore(profilerStore, (state) => state.summaries),
|
|
65
|
+
totalCount: useStore(profilerStore, (state) => state.totalCount),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Derives the profiler's field and SQL state from the current schema,
|
|
70
|
+
* selection, sorting, and pagination state.
|
|
71
|
+
*/
|
|
72
|
+
function useProfilerQueryState(options) {
|
|
73
|
+
const { pagination, rowSelectionVersion, schema, selection, selectionVersion, sorting, tableName, } = options;
|
|
74
|
+
const fields = schema.fields;
|
|
75
|
+
const fieldNames = useMemo(() => fields.map((field) => field.name), [fields]);
|
|
76
|
+
const filter = useMemo(() => {
|
|
77
|
+
void selectionVersion;
|
|
78
|
+
return selection.predicate();
|
|
79
|
+
}, [selection, selectionVersion]);
|
|
80
|
+
const rowFilter = useMemo(() => {
|
|
81
|
+
void rowSelectionVersion;
|
|
82
|
+
return selection.predicate();
|
|
83
|
+
}, [rowSelectionVersion, selection]);
|
|
84
|
+
const baseQuery = useMemo(() => buildProfilerBaseQuery({
|
|
85
|
+
columns: fieldNames,
|
|
86
|
+
filter,
|
|
87
|
+
sorting,
|
|
88
|
+
tableName,
|
|
89
|
+
}), [fieldNames, filter, sorting, tableName]);
|
|
90
|
+
const pageBaseQuery = useMemo(() => buildProfilerBaseQuery({
|
|
91
|
+
columns: fieldNames,
|
|
92
|
+
filter: rowFilter,
|
|
93
|
+
sorting,
|
|
94
|
+
tableName,
|
|
95
|
+
}), [fieldNames, rowFilter, sorting, tableName]);
|
|
96
|
+
return {
|
|
97
|
+
baseQuery,
|
|
98
|
+
datasetId: [tableName, ...fieldNames].join('\u0001'),
|
|
99
|
+
fieldNames,
|
|
100
|
+
fields,
|
|
101
|
+
hasFilters: Array.isArray(filter) ? filter.length > 0 : Boolean(filter),
|
|
102
|
+
pageQuery: buildProfilerPageQuery(pageBaseQuery, pagination).toString(),
|
|
103
|
+
rowFilter,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Owns the coordinator-backed schema, row, count, and summary client
|
|
108
|
+
* lifecycles for a profiler instance.
|
|
109
|
+
*/
|
|
110
|
+
function useProfilerLifecycles(options) {
|
|
111
|
+
const { categoryLimit, columns, connection, fieldNames, fields, pageSize, pagination, profilerStore, rowFilter, selection, selectionVersion, sorting, summaryBins, tableName, } = options;
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
profilerStore.getState().syncPageSize(pageSize);
|
|
114
|
+
}, [pageSize, profilerStore]);
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
profilerStore.getState().resetPageIndex();
|
|
117
|
+
}, [profilerStore, selectionVersion, tableName]);
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (connection.status !== 'ready' || !tableName) {
|
|
120
|
+
profilerStore.getState().setSchemaSuccess([]);
|
|
121
|
+
profilerStore.getState().setSchemaError(undefined);
|
|
122
|
+
profilerStore
|
|
123
|
+
.getState()
|
|
124
|
+
.setSchemaLoading(connection.status === 'loading');
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
void loadProfilerSchema({
|
|
128
|
+
columns,
|
|
129
|
+
coordinator: connection.coordinator,
|
|
130
|
+
store: profilerStore,
|
|
131
|
+
tableName,
|
|
132
|
+
});
|
|
133
|
+
}, [columns, connection, profilerStore, tableName]);
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
if (connection.status !== 'ready' || !tableName || !fieldNames.length) {
|
|
136
|
+
profilerStore.getState().setPage({ isLoading: false });
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
return connectProfilerPageClient({
|
|
140
|
+
connection,
|
|
141
|
+
fieldNames,
|
|
142
|
+
filter: rowFilter,
|
|
143
|
+
pagination,
|
|
144
|
+
sorting,
|
|
145
|
+
store: profilerStore,
|
|
146
|
+
tableName,
|
|
147
|
+
});
|
|
148
|
+
}, [
|
|
149
|
+
connection,
|
|
150
|
+
fieldNames,
|
|
151
|
+
pagination,
|
|
152
|
+
profilerStore,
|
|
153
|
+
rowFilter,
|
|
154
|
+
sorting,
|
|
155
|
+
tableName,
|
|
156
|
+
]);
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
if (connection.status !== 'ready' || !tableName) {
|
|
159
|
+
profilerStore.getState().setFilteredCount({ isLoading: false });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
return connectProfilerCountClient({
|
|
163
|
+
connection,
|
|
164
|
+
filterStable: true,
|
|
165
|
+
selection,
|
|
166
|
+
store: profilerStore,
|
|
167
|
+
tableName,
|
|
168
|
+
target: 'filtered',
|
|
169
|
+
});
|
|
170
|
+
}, [connection, profilerStore, selection, tableName]);
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
if (connection.status !== 'ready' || !tableName) {
|
|
173
|
+
profilerStore.getState().setTotalCount({ isLoading: false });
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
return connectProfilerCountClient({
|
|
177
|
+
connection,
|
|
178
|
+
store: profilerStore,
|
|
179
|
+
tableName,
|
|
180
|
+
target: 'total',
|
|
181
|
+
});
|
|
182
|
+
}, [connection, profilerStore, tableName]);
|
|
183
|
+
useEffect(() => {
|
|
184
|
+
if (connection.status !== 'ready' || !fields.length) {
|
|
185
|
+
profilerStore.getState().clearSummaries();
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
return connectProfilerSummaryClients({
|
|
189
|
+
categoryLimit,
|
|
190
|
+
connection,
|
|
191
|
+
fields,
|
|
192
|
+
selection,
|
|
193
|
+
store: profilerStore,
|
|
194
|
+
summaryBins,
|
|
195
|
+
tableName,
|
|
196
|
+
});
|
|
197
|
+
}, [
|
|
198
|
+
categoryLimit,
|
|
199
|
+
connection,
|
|
200
|
+
fields,
|
|
201
|
+
profilerStore,
|
|
202
|
+
selection,
|
|
203
|
+
summaryBins,
|
|
204
|
+
tableName,
|
|
205
|
+
]);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Maps the schema fields and summary state into the column model consumed by
|
|
209
|
+
* the profiler header and summary cells.
|
|
210
|
+
*/
|
|
211
|
+
function useProfilerColumns(options) {
|
|
212
|
+
const { fields, summaries } = options;
|
|
213
|
+
return useMemo(() => fields.map((field) => ({
|
|
214
|
+
field,
|
|
215
|
+
kind: isProfilerUnsupportedSummaryType(field.type)
|
|
216
|
+
? 'unsupported'
|
|
217
|
+
: isProfilerHistogramType(field.type)
|
|
218
|
+
? 'histogram'
|
|
219
|
+
: 'category',
|
|
220
|
+
name: field.name,
|
|
221
|
+
summary: summaries[field.name] ?? createEmptySummaryState(field),
|
|
222
|
+
})), [fields, summaries]);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Collapses the aggregated profiler client state into the loading and error
|
|
226
|
+
* signals exposed from the public hook.
|
|
227
|
+
*/
|
|
228
|
+
function useProfilerStatus(options) {
|
|
229
|
+
const { fields, filteredCount, page, schema, summaries, totalCount } = options;
|
|
230
|
+
const hasPendingSummaryInitialization = fields.length > 0 && Object.keys(summaries).length < fields.length;
|
|
231
|
+
return {
|
|
232
|
+
isLoading: schema.isLoading ||
|
|
233
|
+
page.isLoading ||
|
|
234
|
+
filteredCount.isLoading ||
|
|
235
|
+
totalCount.isLoading ||
|
|
236
|
+
hasPendingSummaryInitialization ||
|
|
237
|
+
Object.values(summaries).some((summary) => summary.isLoading),
|
|
238
|
+
tableError: schema.error ??
|
|
239
|
+
page.error ??
|
|
240
|
+
filteredCount.error ??
|
|
241
|
+
totalCount.error ??
|
|
242
|
+
Object.values(summaries).find((summary) => summary.error)?.error,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Keeps the last non-empty page result visible while live brushing has moved
|
|
247
|
+
* ahead of the deferred row query, avoiding transient "No rows" flashes.
|
|
248
|
+
*/
|
|
249
|
+
function useProfilerVisiblePageState(options) {
|
|
250
|
+
const { lastNonEmptyPageTable, page, pageDatasetId, rowSelectionVersion, selectionVersion, } = options;
|
|
251
|
+
const isRowDisplayStale = selectionVersion !== rowSelectionVersion;
|
|
252
|
+
const hasCurrentRows = !!page.pageTable && page.pageTable.numRows > 0;
|
|
253
|
+
const canReuseLastNonEmptyPage = !!lastNonEmptyPageTable &&
|
|
254
|
+
lastNonEmptyPageTable.datasetId === pageDatasetId;
|
|
255
|
+
const canShowStableEmpty = !page.isLoading &&
|
|
256
|
+
!isRowDisplayStale &&
|
|
257
|
+
(!page.pageTable || page.pageTable.numRows === 0);
|
|
258
|
+
const showStableEmpty = useDebounce(canShowStableEmpty, 120);
|
|
259
|
+
if (hasCurrentRows || !canReuseLastNonEmptyPage) {
|
|
260
|
+
return page.pageTable;
|
|
261
|
+
}
|
|
262
|
+
return showStableEmpty ? page.pageTable : lastNonEmptyPageTable.pageTable;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Aggregates Mosaic-backed schema, rows, counts, and summaries into the stable
|
|
266
|
+
* public profiler API consumed by the React table UI.
|
|
267
|
+
*/
|
|
268
|
+
export function useMosaicProfiler(options) {
|
|
269
|
+
const { categoryLimit = 20, columns, initialSorting = [], pageSize = 100, selection: providedSelection, selectionName, summaryBins = 18, tableName, } = options;
|
|
270
|
+
const connection = useStoreWithMosaic((state) => state.mosaic.connection);
|
|
271
|
+
const { selection, selectionVersion } = useProfilerSelection({
|
|
272
|
+
selection: providedSelection,
|
|
273
|
+
selectionName,
|
|
274
|
+
});
|
|
275
|
+
const rowSelectionVersion = useDebounce(selectionVersion, 100);
|
|
276
|
+
const { filteredCount, lastNonEmptyPageTable, page, pagination, profilerStore, schema, setPagination, setSorting, sorting, summaries, totalCount, } = useProfilerStoreState({
|
|
277
|
+
initialSorting,
|
|
278
|
+
pageSize,
|
|
279
|
+
});
|
|
280
|
+
const { baseQuery, datasetId, fieldNames, fields, hasFilters, pageQuery, rowFilter, } = useProfilerQueryState({
|
|
281
|
+
pagination,
|
|
282
|
+
rowSelectionVersion,
|
|
283
|
+
schema,
|
|
284
|
+
selection,
|
|
285
|
+
selectionVersion,
|
|
286
|
+
sorting,
|
|
287
|
+
tableName,
|
|
288
|
+
});
|
|
289
|
+
useProfilerLifecycles({
|
|
290
|
+
categoryLimit,
|
|
291
|
+
columns,
|
|
292
|
+
connection,
|
|
293
|
+
fieldNames,
|
|
294
|
+
fields,
|
|
295
|
+
pageSize,
|
|
296
|
+
pagination,
|
|
297
|
+
profilerStore,
|
|
298
|
+
rowFilter,
|
|
299
|
+
selection,
|
|
300
|
+
selectionVersion,
|
|
301
|
+
sorting,
|
|
302
|
+
summaryBins,
|
|
303
|
+
tableName,
|
|
304
|
+
});
|
|
305
|
+
const profilerColumns = useProfilerColumns({ fields, summaries });
|
|
306
|
+
const { isLoading, tableError } = useProfilerStatus({
|
|
307
|
+
fields,
|
|
308
|
+
filteredCount,
|
|
309
|
+
page,
|
|
310
|
+
schema,
|
|
311
|
+
summaries,
|
|
312
|
+
totalCount,
|
|
313
|
+
});
|
|
314
|
+
const visiblePage = useProfilerVisiblePageState({
|
|
315
|
+
lastNonEmptyPageTable,
|
|
316
|
+
page,
|
|
317
|
+
pageDatasetId: datasetId,
|
|
318
|
+
rowSelectionVersion,
|
|
319
|
+
selectionVersion,
|
|
320
|
+
});
|
|
321
|
+
return {
|
|
322
|
+
columns: profilerColumns,
|
|
323
|
+
filteredRowCount: filteredCount.count,
|
|
324
|
+
hasFilters,
|
|
325
|
+
isLoading,
|
|
326
|
+
pageQuery,
|
|
327
|
+
pageTable: visiblePage,
|
|
328
|
+
pagination,
|
|
329
|
+
reset: () => selection.reset(),
|
|
330
|
+
selection,
|
|
331
|
+
setPagination,
|
|
332
|
+
setSorting,
|
|
333
|
+
sorting,
|
|
334
|
+
sql: baseQuery.toString(),
|
|
335
|
+
tableError,
|
|
336
|
+
totalRowCount: totalCount.count,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=useMosaicProfiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMosaicProfiler.js","sourceRoot":"","sources":["../../src/profiler/useMosaicProfiler.ts"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {useDebounce} from '@sqlrooms/ui';\nimport {\n Selection as MosaicSelection,\n type Selection,\n} from '@uwdata/mosaic-core';\nimport {\n useEffect,\n useMemo,\n useState,\n type Dispatch,\n type SetStateAction,\n} from 'react';\nimport {useStore} from 'zustand';\nimport {type MosaicSliceState, useStoreWithMosaic} from '../MosaicSlice';\nimport type {\n MosaicProfilerColumnState,\n MosaicProfilerOptions,\n MosaicProfilerPaginationState,\n MosaicProfilerSorting,\n UseMosaicProfilerReturn,\n} from './types';\nimport {\n createProfilerStore,\n type ProfilerStore,\n type ProfilerStoreState,\n} from './createProfilerStore';\nimport {\n connectProfilerCountClient,\n connectProfilerPageClient,\n connectProfilerSummaryClients,\n loadProfilerSchema,\n} from './profilerController';\nimport {\n buildProfilerBaseQuery,\n buildProfilerPageQuery,\n createEmptySummaryState,\n isProfilerHistogramType,\n isProfilerUnsupportedSummaryType,\n} from './utils';\n\ntype ProfilerSelectionState = {\n selection: Selection;\n selectionVersion: number;\n};\n\ntype ProfilerStoreSlice = {\n filteredCount: ProfilerStoreState['filteredCount'];\n lastNonEmptyPageTable: ProfilerStoreState['lastNonEmptyPageTable'];\n page: ProfilerStoreState['page'];\n pagination: MosaicProfilerPaginationState;\n profilerStore: ProfilerStore;\n schema: ProfilerStoreState['schema'];\n setPagination: Dispatch<SetStateAction<MosaicProfilerPaginationState>>;\n setSorting: Dispatch<SetStateAction<MosaicProfilerSorting>>;\n sorting: MosaicProfilerSorting;\n summaries: ProfilerStoreState['summaries'];\n totalCount: ProfilerStoreState['totalCount'];\n};\n\ntype ProfilerQueryState = {\n baseQuery: ReturnType<typeof buildProfilerBaseQuery>;\n datasetId: string;\n fieldNames: string[];\n fields: ProfilerStoreState['schema']['fields'];\n hasFilters: boolean;\n pageQuery: string;\n rowFilter: ReturnType<Selection['predicate']>;\n};\n\n/**\n * Tracks Mosaic selection updates as a monotonically increasing version so\n * memoized queries and lifecycle effects can respond to crossfilter changes.\n */\nfunction useSelectionVersion(selection: Selection) {\n const [version, setVersion] = useState(0);\n\n useEffect(() => {\n const handleChange = () => setVersion((value) => value + 1);\n selection.addEventListener('value', handleChange);\n return () => selection.removeEventListener('value', handleChange);\n }, [selection]);\n\n return version;\n}\n\n/**\n * Resolves the profiler selection, creating a crossfilter selection when the\n * caller does not supply one, and exposes a version that changes with it.\n */\nfunction useProfilerSelection(\n options: Pick<MosaicProfilerOptions, 'selection' | 'selectionName'>,\n): ProfilerSelectionState {\n const {selection: providedSelection, selectionName} = options;\n const generatedSelectionName = useMemo(\n () => `mosaic-profiler-${createId()}`,\n [],\n );\n const selectionKey = selectionName ?? generatedSelectionName;\n const existingSelection = useStoreWithMosaic(\n (state) => state.mosaic.selections[selectionKey],\n );\n const getSelection = useStoreWithMosaic((state) => state.mosaic.getSelection);\n const [fallbackSelection] = useState(() => MosaicSelection.crossfilter());\n\n useEffect(() => {\n if (!providedSelection && !existingSelection) {\n getSelection(selectionKey, 'crossfilter');\n }\n }, [existingSelection, getSelection, providedSelection, selectionKey]);\n\n const selection =\n providedSelection ?? existingSelection ?? fallbackSelection;\n\n return {\n selection,\n selectionVersion: useSelectionVersion(selection),\n };\n}\n\n/**\n * Creates the per-profiler local store and subscribes to the raw state slices\n * that the public profiler hook exposes.\n */\nfunction useProfilerStoreState(options: {\n initialSorting: MosaicProfilerSorting;\n pageSize: number;\n}): ProfilerStoreSlice {\n const [profilerStore] = useState(() =>\n createProfilerStore({\n initialSorting: options.initialSorting,\n pageSize: options.pageSize,\n }),\n );\n\n return {\n filteredCount: useStore(profilerStore, (state) => state.filteredCount),\n lastNonEmptyPageTable: useStore(\n profilerStore,\n (state) => state.lastNonEmptyPageTable,\n ),\n page: useStore(profilerStore, (state) => state.page),\n pagination: useStore(profilerStore, (state) => state.pagination),\n profilerStore,\n schema: useStore(profilerStore, (state) => state.schema),\n setPagination: useStore(profilerStore, (state) => state.setPagination),\n setSorting: useStore(profilerStore, (state) => state.setSorting),\n sorting: useStore(profilerStore, (state) => state.sorting),\n summaries: useStore(profilerStore, (state) => state.summaries),\n totalCount: useStore(profilerStore, (state) => state.totalCount),\n };\n}\n\n/**\n * Derives the profiler's field and SQL state from the current schema,\n * selection, sorting, and pagination state.\n */\nfunction useProfilerQueryState(options: {\n pagination: MosaicProfilerPaginationState;\n rowSelectionVersion: number;\n schema: ProfilerStoreState['schema'];\n selection: Selection;\n selectionVersion: number;\n sorting: MosaicProfilerSorting;\n tableName: string;\n}): ProfilerQueryState {\n const {\n pagination,\n rowSelectionVersion,\n schema,\n selection,\n selectionVersion,\n sorting,\n tableName,\n } = options;\n const fields = schema.fields;\n const fieldNames = useMemo(() => fields.map((field) => field.name), [fields]);\n const filter = useMemo(() => {\n void selectionVersion;\n return selection.predicate();\n }, [selection, selectionVersion]);\n const rowFilter = useMemo(() => {\n void rowSelectionVersion;\n return selection.predicate();\n }, [rowSelectionVersion, selection]);\n const baseQuery = useMemo(\n () =>\n buildProfilerBaseQuery({\n columns: fieldNames,\n filter,\n sorting,\n tableName,\n }),\n [fieldNames, filter, sorting, tableName],\n );\n const pageBaseQuery = useMemo(\n () =>\n buildProfilerBaseQuery({\n columns: fieldNames,\n filter: rowFilter,\n sorting,\n tableName,\n }),\n [fieldNames, rowFilter, sorting, tableName],\n );\n\n return {\n baseQuery,\n datasetId: [tableName, ...fieldNames].join('\\u0001'),\n fieldNames,\n fields,\n hasFilters: Array.isArray(filter) ? filter.length > 0 : Boolean(filter),\n pageQuery: buildProfilerPageQuery(pageBaseQuery, pagination).toString(),\n rowFilter,\n };\n}\n\n/**\n * Owns the coordinator-backed schema, row, count, and summary client\n * lifecycles for a profiler instance.\n */\nfunction useProfilerLifecycles(options: {\n categoryLimit: number;\n columns?: string[];\n connection: MosaicSliceState['mosaic']['connection'];\n fieldNames: string[];\n fields: ProfilerStoreState['schema']['fields'];\n pageSize: number;\n pagination: MosaicProfilerPaginationState;\n profilerStore: ProfilerStore;\n rowFilter: ReturnType<Selection['predicate']>;\n selection: Selection;\n selectionVersion: number;\n sorting: MosaicProfilerSorting;\n summaryBins: number;\n tableName: string;\n}) {\n const {\n categoryLimit,\n columns,\n connection,\n fieldNames,\n fields,\n pageSize,\n pagination,\n profilerStore,\n rowFilter,\n selection,\n selectionVersion,\n sorting,\n summaryBins,\n tableName,\n } = options;\n\n useEffect(() => {\n profilerStore.getState().syncPageSize(pageSize);\n }, [pageSize, profilerStore]);\n\n useEffect(() => {\n profilerStore.getState().resetPageIndex();\n }, [profilerStore, selectionVersion, tableName]);\n\n useEffect(() => {\n if (connection.status !== 'ready' || !tableName) {\n profilerStore.getState().setSchemaSuccess([]);\n profilerStore.getState().setSchemaError(undefined);\n profilerStore\n .getState()\n .setSchemaLoading(connection.status === 'loading');\n return;\n }\n\n void loadProfilerSchema({\n columns,\n coordinator: connection.coordinator,\n store: profilerStore,\n tableName,\n });\n }, [columns, connection, profilerStore, tableName]);\n\n useEffect(() => {\n if (connection.status !== 'ready' || !tableName || !fieldNames.length) {\n profilerStore.getState().setPage({isLoading: false});\n return;\n }\n\n return connectProfilerPageClient({\n connection,\n fieldNames,\n filter: rowFilter,\n pagination,\n sorting,\n store: profilerStore,\n tableName,\n });\n }, [\n connection,\n fieldNames,\n pagination,\n profilerStore,\n rowFilter,\n sorting,\n tableName,\n ]);\n\n useEffect(() => {\n if (connection.status !== 'ready' || !tableName) {\n profilerStore.getState().setFilteredCount({isLoading: false});\n return;\n }\n\n return connectProfilerCountClient({\n connection,\n filterStable: true,\n selection,\n store: profilerStore,\n tableName,\n target: 'filtered',\n });\n }, [connection, profilerStore, selection, tableName]);\n\n useEffect(() => {\n if (connection.status !== 'ready' || !tableName) {\n profilerStore.getState().setTotalCount({isLoading: false});\n return;\n }\n\n return connectProfilerCountClient({\n connection,\n store: profilerStore,\n tableName,\n target: 'total',\n });\n }, [connection, profilerStore, tableName]);\n\n useEffect(() => {\n if (connection.status !== 'ready' || !fields.length) {\n profilerStore.getState().clearSummaries();\n return;\n }\n\n return connectProfilerSummaryClients({\n categoryLimit,\n connection,\n fields,\n selection,\n store: profilerStore,\n summaryBins,\n tableName,\n });\n }, [\n categoryLimit,\n connection,\n fields,\n profilerStore,\n selection,\n summaryBins,\n tableName,\n ]);\n}\n\n/**\n * Maps the schema fields and summary state into the column model consumed by\n * the profiler header and summary cells.\n */\nfunction useProfilerColumns(options: {\n fields: ProfilerStoreState['schema']['fields'];\n summaries: ProfilerStoreState['summaries'];\n}) {\n const {fields, summaries} = options;\n\n return useMemo<MosaicProfilerColumnState[]>(\n () =>\n fields.map((field) => ({\n field,\n kind: isProfilerUnsupportedSummaryType(field.type)\n ? 'unsupported'\n : isProfilerHistogramType(field.type)\n ? 'histogram'\n : 'category',\n name: field.name,\n summary: summaries[field.name] ?? createEmptySummaryState(field),\n })),\n [fields, summaries],\n );\n}\n\n/**\n * Collapses the aggregated profiler client state into the loading and error\n * signals exposed from the public hook.\n */\nfunction useProfilerStatus(options: {\n filteredCount: ProfilerStoreState['filteredCount'];\n fields: ProfilerStoreState['schema']['fields'];\n page: ProfilerStoreState['page'];\n schema: ProfilerStoreState['schema'];\n summaries: ProfilerStoreState['summaries'];\n totalCount: ProfilerStoreState['totalCount'];\n}) {\n const {fields, filteredCount, page, schema, summaries, totalCount} = options;\n const hasPendingSummaryInitialization =\n fields.length > 0 && Object.keys(summaries).length < fields.length;\n\n return {\n isLoading:\n schema.isLoading ||\n page.isLoading ||\n filteredCount.isLoading ||\n totalCount.isLoading ||\n hasPendingSummaryInitialization ||\n Object.values(summaries).some((summary) => summary.isLoading),\n tableError:\n schema.error ??\n page.error ??\n filteredCount.error ??\n totalCount.error ??\n Object.values(summaries).find((summary) => summary.error)?.error,\n };\n}\n\n/**\n * Keeps the last non-empty page result visible while live brushing has moved\n * ahead of the deferred row query, avoiding transient \"No rows\" flashes.\n */\nfunction useProfilerVisiblePageState(options: {\n lastNonEmptyPageTable: ProfilerStoreState['lastNonEmptyPageTable'];\n pageDatasetId: string;\n page: ProfilerStoreState['page'];\n rowSelectionVersion: number;\n selectionVersion: number;\n}) {\n const {\n lastNonEmptyPageTable,\n page,\n pageDatasetId,\n rowSelectionVersion,\n selectionVersion,\n } = options;\n const isRowDisplayStale = selectionVersion !== rowSelectionVersion;\n const hasCurrentRows = !!page.pageTable && page.pageTable.numRows > 0;\n const canReuseLastNonEmptyPage =\n !!lastNonEmptyPageTable &&\n lastNonEmptyPageTable.datasetId === pageDatasetId;\n const canShowStableEmpty =\n !page.isLoading &&\n !isRowDisplayStale &&\n (!page.pageTable || page.pageTable.numRows === 0);\n const showStableEmpty = useDebounce(canShowStableEmpty, 120);\n\n if (hasCurrentRows || !canReuseLastNonEmptyPage) {\n return page.pageTable;\n }\n\n return showStableEmpty ? page.pageTable : lastNonEmptyPageTable.pageTable;\n}\n\n/**\n * Aggregates Mosaic-backed schema, rows, counts, and summaries into the stable\n * public profiler API consumed by the React table UI.\n */\nexport function useMosaicProfiler(\n options: MosaicProfilerOptions,\n): UseMosaicProfilerReturn {\n const {\n categoryLimit = 20,\n columns,\n initialSorting = [],\n pageSize = 100,\n selection: providedSelection,\n selectionName,\n summaryBins = 18,\n tableName,\n } = options;\n\n const connection = useStoreWithMosaic((state) => state.mosaic.connection);\n const {selection, selectionVersion} = useProfilerSelection({\n selection: providedSelection,\n selectionName,\n });\n const rowSelectionVersion = useDebounce(selectionVersion, 100);\n const {\n filteredCount,\n lastNonEmptyPageTable,\n page,\n pagination,\n profilerStore,\n schema,\n setPagination,\n setSorting,\n sorting,\n summaries,\n totalCount,\n } = useProfilerStoreState({\n initialSorting,\n pageSize,\n });\n const {\n baseQuery,\n datasetId,\n fieldNames,\n fields,\n hasFilters,\n pageQuery,\n rowFilter,\n } = useProfilerQueryState({\n pagination,\n rowSelectionVersion,\n schema,\n selection,\n selectionVersion,\n sorting,\n tableName,\n });\n useProfilerLifecycles({\n categoryLimit,\n columns,\n connection,\n fieldNames,\n fields,\n pageSize,\n pagination,\n profilerStore,\n rowFilter,\n selection,\n selectionVersion,\n sorting,\n summaryBins,\n tableName,\n });\n const profilerColumns = useProfilerColumns({fields, summaries});\n const {isLoading, tableError} = useProfilerStatus({\n fields,\n filteredCount,\n page,\n schema,\n summaries,\n totalCount,\n });\n const visiblePage = useProfilerVisiblePageState({\n lastNonEmptyPageTable,\n page,\n pageDatasetId: datasetId,\n rowSelectionVersion,\n selectionVersion,\n });\n\n return {\n columns: profilerColumns,\n filteredRowCount: filteredCount.count,\n hasFilters,\n isLoading,\n pageQuery,\n pageTable: visiblePage,\n pagination,\n reset: () => selection.reset(),\n selection,\n setPagination,\n setSorting,\n sorting,\n sql: baseQuery.toString(),\n tableError,\n totalRowCount: totalCount.count,\n };\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { FieldInfo } from '@uwdata/mosaic-core';
|
|
2
|
+
import { Query } from '@uwdata/mosaic-sql';
|
|
3
|
+
import * as arrow from 'apache-arrow';
|
|
4
|
+
import type { MosaicProfilerBin, MosaicProfilerCategoryBucket, MosaicProfilerPaginationState, MosaicProfilerSorting, MosaicProfilerSummaryState } from './types';
|
|
5
|
+
export type CategoryCountRow = {
|
|
6
|
+
bucketKind: 'null' | 'unique' | 'value';
|
|
7
|
+
total: number;
|
|
8
|
+
typedValue: unknown;
|
|
9
|
+
};
|
|
10
|
+
type QueryWhereInput = Parameters<ReturnType<typeof Query.from>['where']>[0];
|
|
11
|
+
export declare function isProfilerHistogramType(type: arrow.DataType): boolean;
|
|
12
|
+
export declare function isProfilerUnsupportedSummaryType(type: arrow.DataType): boolean;
|
|
13
|
+
export declare function getProfilerValueType(type: arrow.DataType): 'date' | 'number' | 'string';
|
|
14
|
+
export declare function buildSchemaQuery(tableName: string, columns?: string[]): ReturnType<typeof Query.from>;
|
|
15
|
+
export declare function fieldInfoToProfilerField(info: FieldInfo): arrow.Field;
|
|
16
|
+
export declare function buildProfilerBaseQuery(args: {
|
|
17
|
+
columns?: string[];
|
|
18
|
+
filter?: QueryWhereInput;
|
|
19
|
+
sorting?: MosaicProfilerSorting;
|
|
20
|
+
tableName: string;
|
|
21
|
+
}): import("@uwdata/mosaic-sql").SelectQuery;
|
|
22
|
+
export declare function buildProfilerPageQuery(baseQuery: ReturnType<typeof buildProfilerBaseQuery>, pagination: MosaicProfilerPaginationState): import("@uwdata/mosaic-sql").SelectQuery;
|
|
23
|
+
export declare function normalizeProfilerPagination(pagination: Partial<MosaicProfilerPaginationState> | undefined): MosaicProfilerPaginationState;
|
|
24
|
+
export declare function buildCountQuery(args: {
|
|
25
|
+
filter?: QueryWhereInput;
|
|
26
|
+
tableName: string;
|
|
27
|
+
}): import("@uwdata/mosaic-sql").SelectQuery;
|
|
28
|
+
export declare function buildDistinctCountQuery(args: {
|
|
29
|
+
filter?: QueryWhereInput;
|
|
30
|
+
fieldName: string;
|
|
31
|
+
tableName: string;
|
|
32
|
+
}): import("@uwdata/mosaic-sql").SelectQuery;
|
|
33
|
+
export declare function readCountData(data: unknown): number | undefined;
|
|
34
|
+
export declare function rowsFromQueryResult<T>(data: unknown): T[];
|
|
35
|
+
export declare function buildCategorySummaryQuery(tableName: string, fieldName: string, filter?: QueryWhereInput): import("@uwdata/mosaic-sql").SelectQuery;
|
|
36
|
+
export declare function splitHistogramBins(rows: Array<{
|
|
37
|
+
x1: MosaicProfilerBin['x0'] | null;
|
|
38
|
+
x2: MosaicProfilerBin['x1'] | null;
|
|
39
|
+
y: number;
|
|
40
|
+
}>): {
|
|
41
|
+
bins: MosaicProfilerBin[];
|
|
42
|
+
nullCount: number;
|
|
43
|
+
};
|
|
44
|
+
export declare function buildCategoryBuckets(filteredRows: CategoryCountRow[], totalRows: CategoryCountRow[], categoryLimit: number, selectedKey?: string): {
|
|
45
|
+
bucketCount: number;
|
|
46
|
+
buckets: MosaicProfilerCategoryBucket[];
|
|
47
|
+
selectedKey: string | undefined;
|
|
48
|
+
};
|
|
49
|
+
export declare function isSelectableCategoryKey(key: string): boolean;
|
|
50
|
+
export declare function categoryKeyToSelectionValue(key?: string): unknown;
|
|
51
|
+
export declare function serializeCategoryBucketKey(row: {
|
|
52
|
+
bucketKind: CategoryCountRow['bucketKind'];
|
|
53
|
+
typedValue: unknown;
|
|
54
|
+
}): string;
|
|
55
|
+
export declare function parseCategoryBucketKey(key: string): {
|
|
56
|
+
bucketKind: CategoryCountRow['bucketKind'];
|
|
57
|
+
typedValue: unknown;
|
|
58
|
+
} | undefined;
|
|
59
|
+
export declare function createEmptySummaryState(field: arrow.Field): MosaicProfilerSummaryState;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/profiler/utils.ts"],"names":[],"mappings":"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"}
|