@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,347 @@
|
|
|
1
|
+
import { asc, column, count, desc, Query, sql, sum } from '@uwdata/mosaic-sql';
|
|
2
|
+
import * as arrow from 'apache-arrow';
|
|
3
|
+
export function isProfilerHistogramType(type) {
|
|
4
|
+
return (arrow.DataType.isDate(type) ||
|
|
5
|
+
arrow.DataType.isTimestamp(type) ||
|
|
6
|
+
arrow.DataType.isDecimal(type) ||
|
|
7
|
+
arrow.DataType.isFloat(type) ||
|
|
8
|
+
arrow.DataType.isInt(type));
|
|
9
|
+
}
|
|
10
|
+
export function isProfilerUnsupportedSummaryType(type) {
|
|
11
|
+
return (arrow.DataType.isBinary(type) ||
|
|
12
|
+
type.toString().toLowerCase().includes('geometry'));
|
|
13
|
+
}
|
|
14
|
+
export function getProfilerValueType(type) {
|
|
15
|
+
if (arrow.DataType.isDate(type) || arrow.DataType.isTimestamp(type)) {
|
|
16
|
+
return 'date';
|
|
17
|
+
}
|
|
18
|
+
if (arrow.DataType.isDecimal(type) ||
|
|
19
|
+
arrow.DataType.isFloat(type) ||
|
|
20
|
+
arrow.DataType.isInt(type)) {
|
|
21
|
+
return 'number';
|
|
22
|
+
}
|
|
23
|
+
return 'string';
|
|
24
|
+
}
|
|
25
|
+
export function buildSchemaQuery(tableName, columns) {
|
|
26
|
+
return Query.from(tableName)
|
|
27
|
+
.select(columns?.length ? columns.map((name) => column(name)) : ['*'])
|
|
28
|
+
.limit(1);
|
|
29
|
+
}
|
|
30
|
+
function createProfilerArrowType(sqlType) {
|
|
31
|
+
const type = sqlType.toLowerCase();
|
|
32
|
+
if (/^bool(ean)?/.test(type)) {
|
|
33
|
+
return new arrow.Bool();
|
|
34
|
+
}
|
|
35
|
+
if (/^date$/.test(type)) {
|
|
36
|
+
return new arrow.DateDay();
|
|
37
|
+
}
|
|
38
|
+
if (/^time$|^timestamp|^timestamptz/.test(type)) {
|
|
39
|
+
return new arrow.TimestampMillisecond();
|
|
40
|
+
}
|
|
41
|
+
if (/^(tinyint|smallint|integer|bigint|hugeint|utinyint|usmallint|uinteger|ubigint|uhugeint)/.test(type)) {
|
|
42
|
+
return new arrow.Int64();
|
|
43
|
+
}
|
|
44
|
+
if (/^(decimal|numeric)/.test(type)) {
|
|
45
|
+
return new arrow.Decimal(38, 9);
|
|
46
|
+
}
|
|
47
|
+
if (/^(double|float|real)/.test(type)) {
|
|
48
|
+
return new arrow.Float64();
|
|
49
|
+
}
|
|
50
|
+
if (/^(blob|bytea|binary|varbinary)/.test(type)) {
|
|
51
|
+
return new arrow.Binary();
|
|
52
|
+
}
|
|
53
|
+
if (/^geometry/.test(type)) {
|
|
54
|
+
return {
|
|
55
|
+
toString() {
|
|
56
|
+
return sqlType;
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return new arrow.Utf8();
|
|
61
|
+
}
|
|
62
|
+
export function fieldInfoToProfilerField(info) {
|
|
63
|
+
return new arrow.Field(info.column, createProfilerArrowType(info.sqlType), info.nullable);
|
|
64
|
+
}
|
|
65
|
+
export function buildProfilerBaseQuery(args) {
|
|
66
|
+
const { columns, filter, sorting, tableName } = args;
|
|
67
|
+
const query = Query.from(tableName)
|
|
68
|
+
.select(columns?.length ? columns.map((name) => column(name)) : ['*'])
|
|
69
|
+
.where(filter ?? []);
|
|
70
|
+
if (sorting?.length) {
|
|
71
|
+
query.orderby(sorting.map((entry) => (entry.desc ? desc(entry.id) : asc(entry.id))));
|
|
72
|
+
}
|
|
73
|
+
return query;
|
|
74
|
+
}
|
|
75
|
+
export function buildProfilerPageQuery(baseQuery, pagination) {
|
|
76
|
+
const { pageIndex, pageSize } = normalizeProfilerPagination(pagination);
|
|
77
|
+
return baseQuery
|
|
78
|
+
.clone()
|
|
79
|
+
.limit(pageSize)
|
|
80
|
+
.offset(pageIndex * pageSize);
|
|
81
|
+
}
|
|
82
|
+
export function normalizeProfilerPagination(pagination) {
|
|
83
|
+
const pageSize = Math.min(1000, Math.max(1, Math.trunc(Number(pagination?.pageSize) || 0) || 100));
|
|
84
|
+
const pageIndex = Math.max(0, Math.trunc(Number(pagination?.pageIndex) || 0));
|
|
85
|
+
return { pageIndex, pageSize };
|
|
86
|
+
}
|
|
87
|
+
export function buildCountQuery(args) {
|
|
88
|
+
return Query.from(args.tableName)
|
|
89
|
+
.select({ count: count() })
|
|
90
|
+
.where(args.filter ?? []);
|
|
91
|
+
}
|
|
92
|
+
export function buildDistinctCountQuery(args) {
|
|
93
|
+
return Query.from(args.tableName)
|
|
94
|
+
.select({
|
|
95
|
+
count: count(column(args.fieldName)).distinct(),
|
|
96
|
+
})
|
|
97
|
+
.where(args.filter ?? []);
|
|
98
|
+
}
|
|
99
|
+
export function readCountData(data) {
|
|
100
|
+
if (!data || typeof data !== 'object') {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
if ('toArray' in data && typeof data.toArray === 'function') {
|
|
104
|
+
return data.toArray()[0]?.count;
|
|
105
|
+
}
|
|
106
|
+
if ('get' in data && typeof data.get === 'function') {
|
|
107
|
+
return data.get(0)?.count;
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
export function rowsFromQueryResult(data) {
|
|
112
|
+
if (!data ||
|
|
113
|
+
typeof data !== 'object' ||
|
|
114
|
+
!('toArray' in data) ||
|
|
115
|
+
typeof data.toArray !== 'function') {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
return Array.from(data.toArray());
|
|
119
|
+
}
|
|
120
|
+
export function buildCategorySummaryQuery(tableName, fieldName, filter) {
|
|
121
|
+
const col = column(fieldName);
|
|
122
|
+
const counts = Query.from({ source: tableName })
|
|
123
|
+
.select({
|
|
124
|
+
bucket_kind: sql `CASE
|
|
125
|
+
WHEN ${col} IS NULL THEN 'null'
|
|
126
|
+
ELSE 'value'
|
|
127
|
+
END`,
|
|
128
|
+
typed_value: col,
|
|
129
|
+
count: count(),
|
|
130
|
+
})
|
|
131
|
+
.groupby([
|
|
132
|
+
sql `CASE
|
|
133
|
+
WHEN ${col} IS NULL THEN 'null'
|
|
134
|
+
ELSE 'value'
|
|
135
|
+
END`,
|
|
136
|
+
col,
|
|
137
|
+
])
|
|
138
|
+
.where(filter ?? []);
|
|
139
|
+
return Query.with({ counts })
|
|
140
|
+
.select({
|
|
141
|
+
bucketKind: sql `CASE
|
|
142
|
+
WHEN "count" = 1 AND "bucket_kind" = 'value' THEN 'unique'
|
|
143
|
+
ELSE "bucket_kind"
|
|
144
|
+
END`,
|
|
145
|
+
typedValue: sql `CASE
|
|
146
|
+
WHEN "count" = 1 AND "bucket_kind" = 'value' THEN NULL
|
|
147
|
+
ELSE "typed_value"
|
|
148
|
+
END`,
|
|
149
|
+
total: sum('count'),
|
|
150
|
+
})
|
|
151
|
+
.from('counts')
|
|
152
|
+
.groupby([
|
|
153
|
+
sql `CASE
|
|
154
|
+
WHEN "count" = 1 AND "bucket_kind" = 'value' THEN 'unique'
|
|
155
|
+
ELSE "bucket_kind"
|
|
156
|
+
END`,
|
|
157
|
+
sql `CASE
|
|
158
|
+
WHEN "count" = 1 AND "bucket_kind" = 'value' THEN NULL
|
|
159
|
+
ELSE "typed_value"
|
|
160
|
+
END`,
|
|
161
|
+
]);
|
|
162
|
+
}
|
|
163
|
+
export function splitHistogramBins(rows) {
|
|
164
|
+
let nullCount = 0;
|
|
165
|
+
const bins = [];
|
|
166
|
+
for (const row of rows) {
|
|
167
|
+
if (row.x1 == null || row.x2 == null) {
|
|
168
|
+
nullCount += row.y;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
bins.push({
|
|
172
|
+
x0: row.x1,
|
|
173
|
+
x1: row.x2,
|
|
174
|
+
length: row.y,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
bins.sort((left, right) => {
|
|
178
|
+
const leftValue = left.x0 instanceof Date ? left.x0.getTime() : left.x0;
|
|
179
|
+
const rightValue = right.x0 instanceof Date ? right.x0.getTime() : right.x0;
|
|
180
|
+
return leftValue - rightValue;
|
|
181
|
+
});
|
|
182
|
+
return { bins, nullCount };
|
|
183
|
+
}
|
|
184
|
+
export function buildCategoryBuckets(filteredRows, totalRows, categoryLimit, selectedKey) {
|
|
185
|
+
const totalByKey = new Map(totalRows.map((row) => [serializeCategoryBucketKey(row), row.total]));
|
|
186
|
+
const filteredByKey = new Map(filteredRows.map((row) => [serializeCategoryBucketKey(row), row.total]));
|
|
187
|
+
const baseRows = totalRows
|
|
188
|
+
.filter((row) => row.bucketKind === 'value')
|
|
189
|
+
.slice()
|
|
190
|
+
.sort((left, right) => right.total - left.total);
|
|
191
|
+
const visibleRows = baseRows.slice(0, categoryLimit);
|
|
192
|
+
const overflowRows = baseRows.slice(categoryLimit);
|
|
193
|
+
const buckets = visibleRows.map((row) => ({
|
|
194
|
+
filteredCount: filteredByKey.get(serializeCategoryBucketKey(row)) ?? 0,
|
|
195
|
+
key: serializeCategoryBucketKey(row),
|
|
196
|
+
kind: 'value',
|
|
197
|
+
label: String(row.typedValue),
|
|
198
|
+
selectable: true,
|
|
199
|
+
totalCount: row.total,
|
|
200
|
+
}));
|
|
201
|
+
const overflowTotalCount = overflowRows.reduce((acc, row) => acc + row.total, 0);
|
|
202
|
+
const overflowFilteredCount = overflowRows.reduce((acc, row) => acc + (filteredByKey.get(serializeCategoryBucketKey(row)) ?? 0), 0);
|
|
203
|
+
if (overflowTotalCount > 0) {
|
|
204
|
+
buckets.push({
|
|
205
|
+
filteredCount: overflowFilteredCount,
|
|
206
|
+
key: serializeCategoryBucketKey({
|
|
207
|
+
bucketKind: 'unique',
|
|
208
|
+
typedValue: '__sqlrooms_overflow__',
|
|
209
|
+
}),
|
|
210
|
+
kind: 'overflow',
|
|
211
|
+
label: `${overflowRows.length} more`,
|
|
212
|
+
selectable: false,
|
|
213
|
+
totalCount: overflowTotalCount,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
const uniqueKey = serializeCategoryBucketKey({
|
|
217
|
+
bucketKind: 'unique',
|
|
218
|
+
typedValue: null,
|
|
219
|
+
});
|
|
220
|
+
const uniqueTotalCount = totalByKey.get(uniqueKey) ?? 0;
|
|
221
|
+
if (uniqueTotalCount > 0) {
|
|
222
|
+
buckets.push({
|
|
223
|
+
filteredCount: filteredByKey.get(uniqueKey) ?? 0,
|
|
224
|
+
key: uniqueKey,
|
|
225
|
+
kind: 'unique',
|
|
226
|
+
label: 'unique',
|
|
227
|
+
selectable: false,
|
|
228
|
+
totalCount: uniqueTotalCount,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
const nullKey = serializeCategoryBucketKey({
|
|
232
|
+
bucketKind: 'null',
|
|
233
|
+
typedValue: null,
|
|
234
|
+
});
|
|
235
|
+
const nullTotalCount = totalByKey.get(nullKey) ?? 0;
|
|
236
|
+
if (nullTotalCount > 0) {
|
|
237
|
+
buckets.push({
|
|
238
|
+
filteredCount: filteredByKey.get(nullKey) ?? 0,
|
|
239
|
+
key: nullKey,
|
|
240
|
+
kind: 'null',
|
|
241
|
+
label: 'null',
|
|
242
|
+
selectable: true,
|
|
243
|
+
totalCount: nullTotalCount,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
bucketCount: filteredRows.length,
|
|
248
|
+
buckets,
|
|
249
|
+
selectedKey,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
export function isSelectableCategoryKey(key) {
|
|
253
|
+
const parsedKey = parseCategoryBucketKey(key);
|
|
254
|
+
return (parsedKey?.bucketKind !== 'unique' &&
|
|
255
|
+
parsedKey?.typedValue !== '__sqlrooms_overflow__');
|
|
256
|
+
}
|
|
257
|
+
export function categoryKeyToSelectionValue(key) {
|
|
258
|
+
if (key === undefined)
|
|
259
|
+
return undefined;
|
|
260
|
+
const parsedKey = parseCategoryBucketKey(key);
|
|
261
|
+
if (!parsedKey || parsedKey.bucketKind === 'unique') {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
return parsedKey.bucketKind === 'null' ? null : parsedKey.typedValue;
|
|
265
|
+
}
|
|
266
|
+
function normalizeCategoryBucketValue(value) {
|
|
267
|
+
if (value instanceof Date) {
|
|
268
|
+
return {
|
|
269
|
+
type: 'date',
|
|
270
|
+
value: value.toISOString(),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
if (typeof value === 'bigint') {
|
|
274
|
+
return {
|
|
275
|
+
type: 'bigint',
|
|
276
|
+
value: value.toString(),
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
return value;
|
|
280
|
+
}
|
|
281
|
+
function denormalizeCategoryBucketValue(value) {
|
|
282
|
+
if (!value || typeof value !== 'object') {
|
|
283
|
+
return value;
|
|
284
|
+
}
|
|
285
|
+
if ('type' in value &&
|
|
286
|
+
'value' in value &&
|
|
287
|
+
value.type === 'date' &&
|
|
288
|
+
typeof value.value === 'string') {
|
|
289
|
+
return new Date(value.value);
|
|
290
|
+
}
|
|
291
|
+
if ('type' in value &&
|
|
292
|
+
'value' in value &&
|
|
293
|
+
value.type === 'bigint' &&
|
|
294
|
+
typeof value.value === 'string') {
|
|
295
|
+
return BigInt(value.value);
|
|
296
|
+
}
|
|
297
|
+
return value;
|
|
298
|
+
}
|
|
299
|
+
export function serializeCategoryBucketKey(row) {
|
|
300
|
+
return JSON.stringify([
|
|
301
|
+
row.bucketKind,
|
|
302
|
+
normalizeCategoryBucketValue(row.typedValue),
|
|
303
|
+
]);
|
|
304
|
+
}
|
|
305
|
+
export function parseCategoryBucketKey(key) {
|
|
306
|
+
try {
|
|
307
|
+
const parsed = JSON.parse(key);
|
|
308
|
+
if (!Array.isArray(parsed) || parsed.length !== 2) {
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
bucketKind: parsed[0],
|
|
313
|
+
typedValue: denormalizeCategoryBucketValue(parsed[1]),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
return undefined;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
export function createEmptySummaryState(field) {
|
|
321
|
+
if (isProfilerUnsupportedSummaryType(field.type)) {
|
|
322
|
+
return {
|
|
323
|
+
isLoading: false,
|
|
324
|
+
kind: 'unsupported',
|
|
325
|
+
label: 'No summary',
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
return isProfilerHistogramType(field.type)
|
|
329
|
+
? {
|
|
330
|
+
filteredBins: [],
|
|
331
|
+
filteredNullCount: 0,
|
|
332
|
+
interactor: null,
|
|
333
|
+
isLoading: true,
|
|
334
|
+
kind: 'histogram',
|
|
335
|
+
totalBins: [],
|
|
336
|
+
totalNullCount: 0,
|
|
337
|
+
valueType: getProfilerValueType(field.type) === 'date' ? 'date' : 'number',
|
|
338
|
+
}
|
|
339
|
+
: {
|
|
340
|
+
bucketCount: 0,
|
|
341
|
+
buckets: [],
|
|
342
|
+
isLoading: true,
|
|
343
|
+
kind: 'category',
|
|
344
|
+
toggleValue: () => { },
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/profiler/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAC,MAAM,oBAAoB,CAAC;AAC7E,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAiBtC,MAAM,UAAU,uBAAuB,CAAC,IAAoB;IAC1D,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;QAC3B,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;QAChC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC;QAC9B,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;QAC5B,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAC3B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,IAAoB;IAEpB,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CACnD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAoB;IAEpB,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACpE,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IACE,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC;QAC9B,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;QAC5B,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAC1B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,OAAkB;IAElB,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;SACzB,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACrE,KAAK,CAAC,CAAC,CAAC,CAAC;AACd,CAAC;AAED,SAAS,uBAAuB,CAAC,OAAe;IAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEnC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;IAC1C,CAAC;IAED,IACE,yFAAyF,CAAC,IAAI,CAC5F,IAAI,CACL,EACD,CAAC;QACD,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,QAAQ;gBACN,OAAO,OAAO,CAAC;YACjB,CAAC;SACgB,CAAC;IACtB,CAAC;IAED,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAe;IACtD,OAAO,IAAI,KAAK,CAAC,KAAK,CACpB,IAAI,CAAC,MAAM,EACX,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,EACrC,IAAI,CAAC,QAAQ,CACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAKtC;IACC,MAAM,EAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAC,GAAG,IAAI,CAAC;IACnD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;SAChC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACrE,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAEvB,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,KAAK,CAAC,OAAO,CACX,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CACtE,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,SAAoD,EACpD,UAAyC;IAEzC,MAAM,EAAC,SAAS,EAAE,QAAQ,EAAC,GAAG,2BAA2B,CAAC,UAAU,CAAC,CAAC;IAEtE,OAAO,SAAS;SACb,KAAK,EAAE;SACP,KAAK,CAAC,QAAQ,CAAC;SACf,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,UAA8D;IAE9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CACvB,IAAI,EACJ,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAClE,CAAC;IACF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE9E,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAG/B;IACC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;SAC9B,MAAM,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,EAAC,CAAC;SACxB,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAIvC;IACC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;SAC9B,MAAM,CAAC;QACN,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;KAChD,CAAC;SACD,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAa;IACzC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,SAAS,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC5D,OAAQ,IAAI,CAAC,OAAO,EAA8B,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;IAC/D,CAAC;IAED,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;QACpD,OAAQ,IAAI,CAAC,GAAG,CAAC,CAAC,CAAkC,EAAE,KAAK,CAAC;IAC9D,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAI,IAAa;IAClD,IACE,CAAC,IAAI;QACL,OAAO,IAAI,KAAK,QAAQ;QACxB,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC;QACpB,OAAQ,IAA4B,CAAC,OAAO,KAAK,UAAU,EAC3D,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAE,IAAyB,CAAC,OAAO,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,SAAiB,EACjB,SAAiB,EACjB,MAAwB;IAExB,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,SAAS,EAAC,CAAC;SAC3C,MAAM,CAAC;QACN,WAAW,EAAE,GAAG,CAAA;eACP,GAAG;;UAER;QACJ,WAAW,EAAE,GAAG;QAChB,KAAK,EAAE,KAAK,EAAE;KACf,CAAC;SACD,OAAO,CAAC;QACP,GAAG,CAAA;eACM,GAAG;;UAER;QACJ,GAAG;KACJ,CAAC;SACD,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;IAEvB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAC,CAAC;SACxB,MAAM,CAAC;QACN,UAAU,EAAE,GAAG,CAAA;;;UAGX;QACJ,UAAU,EAAE,GAAG,CAAA;;;UAGX;QACJ,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;KACpB,CAAC;SACD,IAAI,CAAC,QAAQ,CAAC;SACd,OAAO,CAAC;QACP,GAAG,CAAA;;;UAGC;QACJ,GAAG,CAAA;;;UAGC;KACL,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,IAIE;IAEF,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,IAAI,GAAwB,EAAE,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;YACrC,SAAS,IAAI,GAAG,CAAC,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QAED,IAAI,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,CAAC;SACd,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QACxE,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5E,OAAO,SAAS,GAAG,UAAU,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,OAAO,EAAC,IAAI,EAAE,SAAS,EAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,YAAgC,EAChC,SAA6B,EAC7B,aAAqB,EACrB,WAAoB;IAEpB,MAAM,UAAU,GAAG,IAAI,GAAG,CACxB,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,0BAA0B,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CACrE,CAAC;IACF,MAAM,aAAa,GAAG,IAAI,GAAG,CAC3B,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,0BAA0B,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CACxE,CAAC;IAEF,MAAM,QAAQ,GAAG,SAAS;SACvB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,OAAO,CAAC;SAC3C,KAAK,EAAE;SACP,IAAI,CACH,CAAC,IAAsB,EAAE,KAAuB,EAAE,EAAE,CAClD,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAC3B,CAAC;IAEJ,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACnD,MAAM,OAAO,GAAmC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxE,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACtE,GAAG,EAAE,0BAA0B,CAAC,GAAG,CAAC;QACpC,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;QAC7B,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,GAAG,CAAC,KAAK;KACtB,CAAC,CAAC,CAAC;IAEJ,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAC5C,CAAC,GAAW,EAAE,GAAqB,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,KAAK,EACvD,CAAC,CACF,CAAC;IACF,MAAM,qBAAqB,GAAG,YAAY,CAAC,MAAM,CAC/C,CAAC,GAAW,EAAE,GAAqB,EAAE,EAAE,CACrC,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,EACjE,CAAC,CACF,CAAC;IACF,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC;YACX,aAAa,EAAE,qBAAqB;YACpC,GAAG,EAAE,0BAA0B,CAAC;gBAC9B,UAAU,EAAE,QAAQ;gBACpB,UAAU,EAAE,uBAAuB;aACpC,CAAC;YACF,IAAI,EAAE,UAAU;YAChB,KAAK,EAAE,GAAG,YAAY,CAAC,MAAM,OAAO;YACpC,UAAU,EAAE,KAAK;YACjB,UAAU,EAAE,kBAAkB;SAC/B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,SAAS,GAAG,0BAA0B,CAAC;QAC3C,UAAU,EAAE,QAAQ;QACpB,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;IACH,MAAM,gBAAgB,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC;YACX,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC;YAChD,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE,KAAK;YACjB,UAAU,EAAE,gBAAgB;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,0BAA0B,CAAC;QACzC,UAAU,EAAE,MAAM;QAClB,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC;YACX,aAAa,EAAE,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;YAC9C,GAAG,EAAE,OAAO;YACZ,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,MAAM;YACb,UAAU,EAAE,IAAI;YAChB,UAAU,EAAE,cAAc;SAC3B,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,WAAW,EAAE,YAAY,CAAC,MAAM;QAChC,OAAO;QACP,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,GAAW;IACjD,MAAM,SAAS,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,CACL,SAAS,EAAE,UAAU,KAAK,QAAQ;QAClC,SAAS,EAAE,UAAU,KAAK,uBAAuB,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,GAAY;IACtD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,SAAS,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACpD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,SAAS,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC;AACvE,CAAC;AAED,SAAS,4BAA4B,CAAC,KAAc;IAClD,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE;SAC3B,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE;SACxB,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,8BAA8B,CAAC,KAAc;IACpD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IACE,MAAM,IAAI,KAAK;QACf,OAAO,IAAI,KAAK;QAChB,KAAK,CAAC,IAAI,KAAK,MAAM;QACrB,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAC/B,CAAC;QACD,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,IACE,MAAM,IAAI,KAAK;QACf,OAAO,IAAI,KAAK;QAChB,KAAK,CAAC,IAAI,KAAK,QAAQ;QACvB,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAC/B,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,GAG1C;IACC,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,GAAG,CAAC,UAAU;QACd,4BAA4B,CAAC,GAAG,CAAC,UAAU,CAAC;KAC7C,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAMhD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA8C,CAAC;QAC5E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO;YACL,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;YACrB,UAAU,EAAE,8BAA8B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;SACtD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,KAAkB;IAElB,IAAI,gCAAgC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,YAAY;SACpB,CAAC;IACJ,CAAC;IAED,OAAO,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC;QACxC,CAAC,CAAC;YACE,YAAY,EAAE,EAAE;YAChB,iBAAiB,EAAE,CAAC;YACpB,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,IAAI;YACf,IAAI,EAAE,WAAW;YACjB,SAAS,EAAE,EAAE;YACb,cAAc,EAAE,CAAC;YACjB,SAAS,EACP,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;SAClE;QACH,CAAC,CAAC;YACE,WAAW,EAAE,CAAC;YACd,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,IAAI;YACf,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;SACtB,CAAC;AACR,CAAC","sourcesContent":["import type {FieldInfo} from '@uwdata/mosaic-core';\nimport {asc, column, count, desc, Query, sql, sum} from '@uwdata/mosaic-sql';\nimport * as arrow from 'apache-arrow';\nimport type {\n MosaicProfilerBin,\n MosaicProfilerCategoryBucket,\n MosaicProfilerPaginationState,\n MosaicProfilerSorting,\n MosaicProfilerSummaryState,\n} from './types';\n\nexport type CategoryCountRow = {\n bucketKind: 'null' | 'unique' | 'value';\n total: number;\n typedValue: unknown;\n};\n\ntype QueryWhereInput = Parameters<ReturnType<typeof Query.from>['where']>[0];\n\nexport function isProfilerHistogramType(type: arrow.DataType): boolean {\n return (\n arrow.DataType.isDate(type) ||\n arrow.DataType.isTimestamp(type) ||\n arrow.DataType.isDecimal(type) ||\n arrow.DataType.isFloat(type) ||\n arrow.DataType.isInt(type)\n );\n}\n\nexport function isProfilerUnsupportedSummaryType(\n type: arrow.DataType,\n): boolean {\n return (\n arrow.DataType.isBinary(type) ||\n type.toString().toLowerCase().includes('geometry')\n );\n}\n\nexport function getProfilerValueType(\n type: arrow.DataType,\n): 'date' | 'number' | 'string' {\n if (arrow.DataType.isDate(type) || arrow.DataType.isTimestamp(type)) {\n return 'date';\n }\n if (\n arrow.DataType.isDecimal(type) ||\n arrow.DataType.isFloat(type) ||\n arrow.DataType.isInt(type)\n ) {\n return 'number';\n }\n return 'string';\n}\n\nexport function buildSchemaQuery(\n tableName: string,\n columns?: string[],\n): ReturnType<typeof Query.from> {\n return Query.from(tableName)\n .select(columns?.length ? columns.map((name) => column(name)) : ['*'])\n .limit(1);\n}\n\nfunction createProfilerArrowType(sqlType: string): arrow.DataType {\n const type = sqlType.toLowerCase();\n\n if (/^bool(ean)?/.test(type)) {\n return new arrow.Bool();\n }\n\n if (/^date$/.test(type)) {\n return new arrow.DateDay();\n }\n\n if (/^time$|^timestamp|^timestamptz/.test(type)) {\n return new arrow.TimestampMillisecond();\n }\n\n if (\n /^(tinyint|smallint|integer|bigint|hugeint|utinyint|usmallint|uinteger|ubigint|uhugeint)/.test(\n type,\n )\n ) {\n return new arrow.Int64();\n }\n\n if (/^(decimal|numeric)/.test(type)) {\n return new arrow.Decimal(38, 9);\n }\n\n if (/^(double|float|real)/.test(type)) {\n return new arrow.Float64();\n }\n\n if (/^(blob|bytea|binary|varbinary)/.test(type)) {\n return new arrow.Binary();\n }\n\n if (/^geometry/.test(type)) {\n return {\n toString() {\n return sqlType;\n },\n } as arrow.DataType;\n }\n\n return new arrow.Utf8();\n}\n\nexport function fieldInfoToProfilerField(info: FieldInfo): arrow.Field {\n return new arrow.Field(\n info.column,\n createProfilerArrowType(info.sqlType),\n info.nullable,\n );\n}\n\nexport function buildProfilerBaseQuery(args: {\n columns?: string[];\n filter?: QueryWhereInput;\n sorting?: MosaicProfilerSorting;\n tableName: string;\n}) {\n const {columns, filter, sorting, tableName} = args;\n const query = Query.from(tableName)\n .select(columns?.length ? columns.map((name) => column(name)) : ['*'])\n .where(filter ?? []);\n\n if (sorting?.length) {\n query.orderby(\n sorting.map((entry) => (entry.desc ? desc(entry.id) : asc(entry.id))),\n );\n }\n\n return query;\n}\n\nexport function buildProfilerPageQuery(\n baseQuery: ReturnType<typeof buildProfilerBaseQuery>,\n pagination: MosaicProfilerPaginationState,\n) {\n const {pageIndex, pageSize} = normalizeProfilerPagination(pagination);\n\n return baseQuery\n .clone()\n .limit(pageSize)\n .offset(pageIndex * pageSize);\n}\n\nexport function normalizeProfilerPagination(\n pagination: Partial<MosaicProfilerPaginationState> | undefined,\n): MosaicProfilerPaginationState {\n const pageSize = Math.min(\n 1000,\n Math.max(1, Math.trunc(Number(pagination?.pageSize) || 0) || 100),\n );\n const pageIndex = Math.max(0, Math.trunc(Number(pagination?.pageIndex) || 0));\n\n return {pageIndex, pageSize};\n}\n\nexport function buildCountQuery(args: {\n filter?: QueryWhereInput;\n tableName: string;\n}) {\n return Query.from(args.tableName)\n .select({count: count()})\n .where(args.filter ?? []);\n}\n\nexport function buildDistinctCountQuery(args: {\n filter?: QueryWhereInput;\n fieldName: string;\n tableName: string;\n}) {\n return Query.from(args.tableName)\n .select({\n count: count(column(args.fieldName)).distinct(),\n })\n .where(args.filter ?? []);\n}\n\nexport function readCountData(data: unknown): number | undefined {\n if (!data || typeof data !== 'object') {\n return undefined;\n }\n\n if ('toArray' in data && typeof data.toArray === 'function') {\n return (data.toArray() as Array<{count?: number}>)[0]?.count;\n }\n\n if ('get' in data && typeof data.get === 'function') {\n return (data.get(0) as {count?: number} | undefined)?.count;\n }\n\n return undefined;\n}\n\nexport function rowsFromQueryResult<T>(data: unknown): T[] {\n if (\n !data ||\n typeof data !== 'object' ||\n !('toArray' in data) ||\n typeof (data as {toArray?: unknown}).toArray !== 'function'\n ) {\n return [];\n }\n\n return Array.from((data as {toArray(): T[]}).toArray());\n}\n\nexport function buildCategorySummaryQuery(\n tableName: string,\n fieldName: string,\n filter?: QueryWhereInput,\n) {\n const col = column(fieldName);\n const counts = Query.from({source: tableName})\n .select({\n bucket_kind: sql`CASE\n WHEN ${col} IS NULL THEN 'null'\n ELSE 'value'\n END`,\n typed_value: col,\n count: count(),\n })\n .groupby([\n sql`CASE\n WHEN ${col} IS NULL THEN 'null'\n ELSE 'value'\n END`,\n col,\n ])\n .where(filter ?? []);\n\n return Query.with({counts})\n .select({\n bucketKind: sql`CASE\n WHEN \"count\" = 1 AND \"bucket_kind\" = 'value' THEN 'unique'\n ELSE \"bucket_kind\"\n END`,\n typedValue: sql`CASE\n WHEN \"count\" = 1 AND \"bucket_kind\" = 'value' THEN NULL\n ELSE \"typed_value\"\n END`,\n total: sum('count'),\n })\n .from('counts')\n .groupby([\n sql`CASE\n WHEN \"count\" = 1 AND \"bucket_kind\" = 'value' THEN 'unique'\n ELSE \"bucket_kind\"\n END`,\n sql`CASE\n WHEN \"count\" = 1 AND \"bucket_kind\" = 'value' THEN NULL\n ELSE \"typed_value\"\n END`,\n ]);\n}\n\nexport function splitHistogramBins(\n rows: Array<{\n x1: MosaicProfilerBin['x0'] | null;\n x2: MosaicProfilerBin['x1'] | null;\n y: number;\n }>,\n) {\n let nullCount = 0;\n const bins: MosaicProfilerBin[] = [];\n\n for (const row of rows) {\n if (row.x1 == null || row.x2 == null) {\n nullCount += row.y;\n continue;\n }\n\n bins.push({\n x0: row.x1,\n x1: row.x2,\n length: row.y,\n });\n }\n\n bins.sort((left, right) => {\n const leftValue = left.x0 instanceof Date ? left.x0.getTime() : left.x0;\n const rightValue = right.x0 instanceof Date ? right.x0.getTime() : right.x0;\n return leftValue - rightValue;\n });\n\n return {bins, nullCount};\n}\n\nexport function buildCategoryBuckets(\n filteredRows: CategoryCountRow[],\n totalRows: CategoryCountRow[],\n categoryLimit: number,\n selectedKey?: string,\n) {\n const totalByKey = new Map(\n totalRows.map((row) => [serializeCategoryBucketKey(row), row.total]),\n );\n const filteredByKey = new Map(\n filteredRows.map((row) => [serializeCategoryBucketKey(row), row.total]),\n );\n\n const baseRows = totalRows\n .filter((row) => row.bucketKind === 'value')\n .slice()\n .sort(\n (left: CategoryCountRow, right: CategoryCountRow) =>\n right.total - left.total,\n );\n\n const visibleRows = baseRows.slice(0, categoryLimit);\n const overflowRows = baseRows.slice(categoryLimit);\n const buckets: MosaicProfilerCategoryBucket[] = visibleRows.map((row) => ({\n filteredCount: filteredByKey.get(serializeCategoryBucketKey(row)) ?? 0,\n key: serializeCategoryBucketKey(row),\n kind: 'value',\n label: String(row.typedValue),\n selectable: true,\n totalCount: row.total,\n }));\n\n const overflowTotalCount = overflowRows.reduce(\n (acc: number, row: CategoryCountRow) => acc + row.total,\n 0,\n );\n const overflowFilteredCount = overflowRows.reduce(\n (acc: number, row: CategoryCountRow) =>\n acc + (filteredByKey.get(serializeCategoryBucketKey(row)) ?? 0),\n 0,\n );\n if (overflowTotalCount > 0) {\n buckets.push({\n filteredCount: overflowFilteredCount,\n key: serializeCategoryBucketKey({\n bucketKind: 'unique',\n typedValue: '__sqlrooms_overflow__',\n }),\n kind: 'overflow',\n label: `${overflowRows.length} more`,\n selectable: false,\n totalCount: overflowTotalCount,\n });\n }\n\n const uniqueKey = serializeCategoryBucketKey({\n bucketKind: 'unique',\n typedValue: null,\n });\n const uniqueTotalCount = totalByKey.get(uniqueKey) ?? 0;\n if (uniqueTotalCount > 0) {\n buckets.push({\n filteredCount: filteredByKey.get(uniqueKey) ?? 0,\n key: uniqueKey,\n kind: 'unique',\n label: 'unique',\n selectable: false,\n totalCount: uniqueTotalCount,\n });\n }\n\n const nullKey = serializeCategoryBucketKey({\n bucketKind: 'null',\n typedValue: null,\n });\n const nullTotalCount = totalByKey.get(nullKey) ?? 0;\n if (nullTotalCount > 0) {\n buckets.push({\n filteredCount: filteredByKey.get(nullKey) ?? 0,\n key: nullKey,\n kind: 'null',\n label: 'null',\n selectable: true,\n totalCount: nullTotalCount,\n });\n }\n\n return {\n bucketCount: filteredRows.length,\n buckets,\n selectedKey,\n };\n}\n\nexport function isSelectableCategoryKey(key: string) {\n const parsedKey = parseCategoryBucketKey(key);\n return (\n parsedKey?.bucketKind !== 'unique' &&\n parsedKey?.typedValue !== '__sqlrooms_overflow__'\n );\n}\n\nexport function categoryKeyToSelectionValue(key?: string) {\n if (key === undefined) return undefined;\n const parsedKey = parseCategoryBucketKey(key);\n if (!parsedKey || parsedKey.bucketKind === 'unique') {\n return undefined;\n }\n return parsedKey.bucketKind === 'null' ? null : parsedKey.typedValue;\n}\n\nfunction normalizeCategoryBucketValue(value: unknown): unknown {\n if (value instanceof Date) {\n return {\n type: 'date',\n value: value.toISOString(),\n };\n }\n if (typeof value === 'bigint') {\n return {\n type: 'bigint',\n value: value.toString(),\n };\n }\n return value;\n}\n\nfunction denormalizeCategoryBucketValue(value: unknown): unknown {\n if (!value || typeof value !== 'object') {\n return value;\n }\n\n if (\n 'type' in value &&\n 'value' in value &&\n value.type === 'date' &&\n typeof value.value === 'string'\n ) {\n return new Date(value.value);\n }\n\n if (\n 'type' in value &&\n 'value' in value &&\n value.type === 'bigint' &&\n typeof value.value === 'string'\n ) {\n return BigInt(value.value);\n }\n\n return value;\n}\n\nexport function serializeCategoryBucketKey(row: {\n bucketKind: CategoryCountRow['bucketKind'];\n typedValue: unknown;\n}) {\n return JSON.stringify([\n row.bucketKind,\n normalizeCategoryBucketValue(row.typedValue),\n ]);\n}\n\nexport function parseCategoryBucketKey(key: string):\n | {\n bucketKind: CategoryCountRow['bucketKind'];\n typedValue: unknown;\n }\n | undefined {\n try {\n const parsed = JSON.parse(key) as [CategoryCountRow['bucketKind'], unknown];\n if (!Array.isArray(parsed) || parsed.length !== 2) {\n return undefined;\n }\n\n return {\n bucketKind: parsed[0],\n typedValue: denormalizeCategoryBucketValue(parsed[1]),\n };\n } catch {\n return undefined;\n }\n}\n\nexport function createEmptySummaryState(\n field: arrow.Field,\n): MosaicProfilerSummaryState {\n if (isProfilerUnsupportedSummaryType(field.type)) {\n return {\n isLoading: false,\n kind: 'unsupported',\n label: 'No summary',\n };\n }\n\n return isProfilerHistogramType(field.type)\n ? {\n filteredBins: [],\n filteredNullCount: 0,\n interactor: null,\n isLoading: true,\n kind: 'histogram',\n totalBins: [],\n totalNullCount: 0,\n valueType:\n getProfilerValueType(field.type) === 'date' ? 'date' : 'number',\n }\n : {\n bucketCount: 0,\n buckets: [],\n isLoading: true,\n kind: 'category',\n toggleValue: () => {},\n };\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Table as MosaicTable } from '@uwdata/flechette';
|
|
2
|
+
import { type Table as ArrowTable } from 'apache-arrow';
|
|
3
|
+
type TableInterop = {
|
|
4
|
+
ipcBytes: Uint8Array;
|
|
5
|
+
getArrowTable: () => ArrowTable;
|
|
6
|
+
getMosaicTable: () => object;
|
|
7
|
+
};
|
|
8
|
+
export declare function getTableInterop(value: unknown): TableInterop | undefined;
|
|
9
|
+
export declare function getArrowTableFromInterop(value: unknown): ArrowTable | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Convert an Apache Arrow table into the Mosaic-native table shape while
|
|
12
|
+
* attaching Mosaic-internal IPC-backed interop metadata.
|
|
13
|
+
*
|
|
14
|
+
* Mosaic core expects Flechette tables, while SQLRooms public client APIs
|
|
15
|
+
* expose Apache Arrow. IPC remains the durable bridge. The original Arrow
|
|
16
|
+
* table is referenced weakly so Arrow-native callers can often reuse it
|
|
17
|
+
* without forcing Mosaic-only consumers to retain both table runtimes.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createMosaicTableFromArrowTable(arrowTable: ArrowTable): MosaicTable;
|
|
20
|
+
/**
|
|
21
|
+
* Convert a raw Mosaic client result to the Apache Arrow shape exposed by
|
|
22
|
+
* SQLRooms public hooks.
|
|
23
|
+
*
|
|
24
|
+
* Results produced by {@link createMosaicTableFromArrowTable} use the
|
|
25
|
+
* interop fast path. Plain third-party Flechette tables are still accepted as
|
|
26
|
+
* a compatibility fallback, but that path has to re-encode through IPC.
|
|
27
|
+
*/
|
|
28
|
+
export declare function toArrowClientResult(value: unknown): ArrowTable;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=tableInterop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableInterop.d.ts","sourceRoot":"","sources":["../src/tableInterop.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,KAAK,IAAI,WAAW,EAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA2B,KAAK,KAAK,IAAI,UAAU,EAAC,MAAM,cAAc,CAAC;AAIhF,KAAK,YAAY,GAAG;IAClB,QAAQ,EAAE,UAAU,CAAC;IACrB,aAAa,EAAE,MAAM,UAAU,CAAC;IAChC,cAAc,EAAE,MAAM,MAAM,CAAC;CAC9B,CAAC;AAmCF,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAMxE;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,UAAU,GAAG,SAAS,CAExB;AAmBD;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,UAAU,GACrB,WAAW,CASb;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAiB9D"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { decodeIPC } from '@uwdata/mosaic-core';
|
|
2
|
+
import { tableToIPC as mosaicTableToIPC, } from '@uwdata/flechette';
|
|
3
|
+
import { tableFromIPC, tableToIPC } from 'apache-arrow';
|
|
4
|
+
const TABLE_INTEROP = Symbol.for('@sqlrooms/mosaic-table-interop');
|
|
5
|
+
function attachTableInterop(table, options) {
|
|
6
|
+
if (getTableInterop(table)) {
|
|
7
|
+
return table;
|
|
8
|
+
}
|
|
9
|
+
const { ipcBytes, decodeArrowTable = (bytes) => tableFromIPC(bytes) } = options;
|
|
10
|
+
let arrowTable;
|
|
11
|
+
const interop = {
|
|
12
|
+
ipcBytes,
|
|
13
|
+
getArrowTable: () => {
|
|
14
|
+
arrowTable ??= decodeArrowTable(ipcBytes);
|
|
15
|
+
return arrowTable;
|
|
16
|
+
},
|
|
17
|
+
getMosaicTable: () => table,
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(table, TABLE_INTEROP, {
|
|
20
|
+
value: interop,
|
|
21
|
+
enumerable: false,
|
|
22
|
+
configurable: false,
|
|
23
|
+
writable: false,
|
|
24
|
+
});
|
|
25
|
+
return table;
|
|
26
|
+
}
|
|
27
|
+
export function getTableInterop(value) {
|
|
28
|
+
if (!value || typeof value !== 'object') {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return value[TABLE_INTEROP];
|
|
32
|
+
}
|
|
33
|
+
export function getArrowTableFromInterop(value) {
|
|
34
|
+
return getTableInterop(value)?.getArrowTable();
|
|
35
|
+
}
|
|
36
|
+
function isArrowTable(value) {
|
|
37
|
+
return Boolean(value &&
|
|
38
|
+
typeof value === 'object' &&
|
|
39
|
+
Array.isArray(value.batches));
|
|
40
|
+
}
|
|
41
|
+
function isMosaicTable(value) {
|
|
42
|
+
return Boolean(value &&
|
|
43
|
+
typeof value === 'object' &&
|
|
44
|
+
typeof value.toColumns === 'function' &&
|
|
45
|
+
typeof value.getChild === 'function');
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Convert an Apache Arrow table into the Mosaic-native table shape while
|
|
49
|
+
* attaching Mosaic-internal IPC-backed interop metadata.
|
|
50
|
+
*
|
|
51
|
+
* Mosaic core expects Flechette tables, while SQLRooms public client APIs
|
|
52
|
+
* expose Apache Arrow. IPC remains the durable bridge. The original Arrow
|
|
53
|
+
* table is referenced weakly so Arrow-native callers can often reuse it
|
|
54
|
+
* without forcing Mosaic-only consumers to retain both table runtimes.
|
|
55
|
+
*/
|
|
56
|
+
export function createMosaicTableFromArrowTable(arrowTable) {
|
|
57
|
+
const ipcBytes = tableToIPC(arrowTable, 'stream');
|
|
58
|
+
const arrowTableRef = typeof WeakRef === 'undefined' ? undefined : new WeakRef(arrowTable);
|
|
59
|
+
return attachTableInterop(decodeIPC(ipcBytes), {
|
|
60
|
+
ipcBytes,
|
|
61
|
+
decodeArrowTable: (bytes) => arrowTableRef?.deref() ?? tableFromIPC(bytes),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Convert a raw Mosaic client result to the Apache Arrow shape exposed by
|
|
66
|
+
* SQLRooms public hooks.
|
|
67
|
+
*
|
|
68
|
+
* Results produced by {@link createMosaicTableFromArrowTable} use the
|
|
69
|
+
* interop fast path. Plain third-party Flechette tables are still accepted as
|
|
70
|
+
* a compatibility fallback, but that path has to re-encode through IPC.
|
|
71
|
+
*/
|
|
72
|
+
export function toArrowClientResult(value) {
|
|
73
|
+
if (isArrowTable(value)) {
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
const interopArrowTable = getArrowTableFromInterop(value);
|
|
77
|
+
if (interopArrowTable) {
|
|
78
|
+
return interopArrowTable;
|
|
79
|
+
}
|
|
80
|
+
if (isMosaicTable(value)) {
|
|
81
|
+
return tableFromIPC(mosaicTableToIPC(value, { format: 'stream' }));
|
|
82
|
+
}
|
|
83
|
+
throw new Error('useMosaicClient expected a Mosaic table result that can be converted to Apache Arrow.');
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=tableInterop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableInterop.js","sourceRoot":"","sources":["../src/tableInterop.ts"],"names":[],"mappings":"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","sourcesContent":["import {decodeIPC} from '@uwdata/mosaic-core';\nimport {\n tableToIPC as mosaicTableToIPC,\n type Table as MosaicTable,\n} from '@uwdata/flechette';\nimport {tableFromIPC, tableToIPC, type Table as ArrowTable} from 'apache-arrow';\n\nconst TABLE_INTEROP = Symbol.for('@sqlrooms/mosaic-table-interop');\n\ntype TableInterop = {\n ipcBytes: Uint8Array;\n getArrowTable: () => ArrowTable;\n getMosaicTable: () => object;\n};\n\nfunction attachTableInterop<T extends object>(\n table: T,\n options: {\n ipcBytes: Uint8Array;\n decodeArrowTable?: (ipcBytes: Uint8Array) => ArrowTable;\n },\n): T {\n if (getTableInterop(table)) {\n return table;\n }\n\n const {ipcBytes, decodeArrowTable = (bytes) => tableFromIPC(bytes)} = options;\n let arrowTable: ArrowTable | undefined;\n\n const interop: TableInterop = {\n ipcBytes,\n getArrowTable: () => {\n arrowTable ??= decodeArrowTable(ipcBytes);\n return arrowTable;\n },\n getMosaicTable: () => table,\n };\n\n Object.defineProperty(table, TABLE_INTEROP, {\n value: interop,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n\n return table;\n}\n\nexport function getTableInterop(value: unknown): TableInterop | undefined {\n if (!value || typeof value !== 'object') {\n return undefined;\n }\n\n return (value as {[TABLE_INTEROP]?: TableInterop})[TABLE_INTEROP];\n}\n\nexport function getArrowTableFromInterop(\n value: unknown,\n): ArrowTable | undefined {\n return getTableInterop(value)?.getArrowTable();\n}\n\nfunction isArrowTable(value: unknown): value is ArrowTable {\n return Boolean(\n value &&\n typeof value === 'object' &&\n Array.isArray((value as {batches?: unknown}).batches),\n );\n}\n\nfunction isMosaicTable(value: unknown): value is MosaicTable {\n return Boolean(\n value &&\n typeof value === 'object' &&\n typeof (value as {toColumns?: unknown}).toColumns === 'function' &&\n typeof (value as {getChild?: unknown}).getChild === 'function',\n );\n}\n\n/**\n * Convert an Apache Arrow table into the Mosaic-native table shape while\n * attaching Mosaic-internal IPC-backed interop metadata.\n *\n * Mosaic core expects Flechette tables, while SQLRooms public client APIs\n * expose Apache Arrow. IPC remains the durable bridge. The original Arrow\n * table is referenced weakly so Arrow-native callers can often reuse it\n * without forcing Mosaic-only consumers to retain both table runtimes.\n */\nexport function createMosaicTableFromArrowTable(\n arrowTable: ArrowTable,\n): MosaicTable {\n const ipcBytes = tableToIPC(arrowTable, 'stream');\n const arrowTableRef =\n typeof WeakRef === 'undefined' ? undefined : new WeakRef(arrowTable);\n\n return attachTableInterop(decodeIPC(ipcBytes), {\n ipcBytes,\n decodeArrowTable: (bytes) => arrowTableRef?.deref() ?? tableFromIPC(bytes),\n }) as MosaicTable;\n}\n\n/**\n * Convert a raw Mosaic client result to the Apache Arrow shape exposed by\n * SQLRooms public hooks.\n *\n * Results produced by {@link createMosaicTableFromArrowTable} use the\n * interop fast path. Plain third-party Flechette tables are still accepted as\n * a compatibility fallback, but that path has to re-encode through IPC.\n */\nexport function toArrowClientResult(value: unknown): ArrowTable {\n if (isArrowTable(value)) {\n return value;\n }\n\n const interopArrowTable = getArrowTableFromInterop(value);\n if (interopArrowTable) {\n return interopArrowTable;\n }\n\n if (isMosaicTable(value)) {\n return tableFromIPC(mosaicTableToIPC(value, {format: 'stream'}));\n }\n\n throw new Error(\n 'useMosaicClient expected a Mosaic table result that can be converted to Apache Arrow.',\n );\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Connector } from '@uwdata/mosaic-core';
|
|
2
|
+
/**
|
|
3
|
+
* Hook to manage the Mosaic connector.
|
|
4
|
+
*
|
|
5
|
+
* @returns {Object} An object containing the Mosaic connector and a loading state.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useMosaic(): {
|
|
8
|
+
isMosaicLoading: boolean;
|
|
9
|
+
mosaicConnector: Connector | undefined;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=use-mosaic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mosaic.d.ts","sourceRoot":"","sources":["../src/use-mosaic.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,SAAS,EAA6B,MAAM,qBAAqB,CAAC;AA8B1E;;;;GAIG;AACH,wBAAgB,SAAS;;;EAUxB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useDuckDb, isWasmDuckDbConnector, } from '@sqlrooms/duckdb';
|
|
2
|
+
import { coordinator, wasmConnector } from '@uwdata/mosaic-core';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
let mosaicConnector;
|
|
5
|
+
// TODO: Create MosaicSlice and keep the connector in the store
|
|
6
|
+
/**
|
|
7
|
+
* Retrieves a Mosaic connector for the DuckDB database.
|
|
8
|
+
*
|
|
9
|
+
* @returns {Promise<MosaicConnector>} The Mosaic connector for the DuckDB database.
|
|
10
|
+
*/
|
|
11
|
+
async function getMosaicConnector(duckDb) {
|
|
12
|
+
if (mosaicConnector) {
|
|
13
|
+
return mosaicConnector;
|
|
14
|
+
}
|
|
15
|
+
if (!isWasmDuckDbConnector(duckDb)) {
|
|
16
|
+
throw new Error('Only WasmDuckDbConnector is currently supported');
|
|
17
|
+
}
|
|
18
|
+
await duckDb.initialize();
|
|
19
|
+
mosaicConnector = await coordinator().databaseConnector(wasmConnector({
|
|
20
|
+
// @ts-expect-error - We install a different version of duckdb-wasm
|
|
21
|
+
duckDb: duckDb.getDb(),
|
|
22
|
+
connection: duckDb.getConnection(),
|
|
23
|
+
}));
|
|
24
|
+
return mosaicConnector;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Hook to manage the Mosaic connector.
|
|
28
|
+
*
|
|
29
|
+
* @returns {Object} An object containing the Mosaic connector and a loading state.
|
|
30
|
+
*/
|
|
31
|
+
export function useMosaic() {
|
|
32
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
33
|
+
const [connector, setConnector] = useState();
|
|
34
|
+
const duckDb = useDuckDb();
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
getMosaicConnector(duckDb)
|
|
37
|
+
.then(setConnector)
|
|
38
|
+
.finally(() => setIsLoading(false));
|
|
39
|
+
}, [duckDb]);
|
|
40
|
+
return { isMosaicLoading: isLoading, mosaicConnector: connector };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=use-mosaic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mosaic.js","sourceRoot":"","sources":["../src/use-mosaic.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EACT,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAY,WAAW,EAAE,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAE1C,IAAI,eAA0B,CAAC;AAE/B,+DAA+D;AAE/D;;;;GAIG;AACH,KAAK,UAAU,kBAAkB,CAAC,MAAuB;IACvD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC1B,eAAe,GAAG,MAAM,WAAW,EAAE,CAAC,iBAAiB,CACrD,aAAa,CAAC;QACZ,mEAAmE;QACnE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE;QACtB,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE;KACnC,CAAC,CACH,CAAC;IACF,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,EAAa,CAAC;IACxD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,SAAS,CAAC,GAAG,EAAE;QACb,kBAAkB,CAAC,MAAM,CAAC;aACvB,IAAI,CAAC,YAAY,CAAC;aAClB,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACb,OAAO,EAAC,eAAe,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAC,CAAC;AAClE,CAAC","sourcesContent":["import {\n DuckDbConnector,\n useDuckDb,\n isWasmDuckDbConnector,\n} from '@sqlrooms/duckdb';\nimport {Connector, coordinator, wasmConnector} from '@uwdata/mosaic-core';\nimport {useEffect, useState} from 'react';\n\nlet mosaicConnector: Connector;\n\n// TODO: Create MosaicSlice and keep the connector in the store\n\n/**\n * Retrieves a Mosaic connector for the DuckDB database.\n *\n * @returns {Promise<MosaicConnector>} The Mosaic connector for the DuckDB database.\n */\nasync function getMosaicConnector(duckDb: DuckDbConnector) {\n if (mosaicConnector) {\n return mosaicConnector;\n }\n if (!isWasmDuckDbConnector(duckDb)) {\n throw new Error('Only WasmDuckDbConnector is currently supported');\n }\n await duckDb.initialize();\n mosaicConnector = await coordinator().databaseConnector(\n wasmConnector({\n // @ts-expect-error - We install a different version of duckdb-wasm\n duckDb: duckDb.getDb(),\n connection: duckDb.getConnection(),\n }),\n );\n return mosaicConnector;\n}\n\n/**\n * Hook to manage the Mosaic connector.\n *\n * @returns {Object} An object containing the Mosaic connector and a loading state.\n */\nexport function useMosaic() {\n const [isLoading, setIsLoading] = useState(true);\n const [connector, setConnector] = useState<Connector>();\n const duckDb = useDuckDb();\n useEffect(() => {\n getMosaicConnector(duckDb)\n .then(setConnector)\n .finally(() => setIsLoading(false));\n }, [duckDb]);\n return {isMosaicLoading: isLoading, mosaicConnector: connector};\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Selection } from '@uwdata/mosaic-core';
|
|
2
2
|
import { Query } from '@uwdata/mosaic-sql';
|
|
3
|
-
|
|
3
|
+
import type { Table as ArrowTable } from 'apache-arrow';
|
|
4
|
+
export type UseMosaicClientOptions = {
|
|
4
5
|
/** Unique id for this client (auto-generated if not provided) */
|
|
5
6
|
id?: string;
|
|
6
7
|
/** Selection name for cross-filtering (will create if doesn't exist) */
|
|
@@ -10,12 +11,12 @@ export type UseMosaicClientOptions<T = unknown> = {
|
|
|
10
11
|
/** Query builder - receives current filter predicate */
|
|
11
12
|
query: (filter: unknown) => ReturnType<typeof Query.from>;
|
|
12
13
|
/** Callback when query results are received */
|
|
13
|
-
queryResult?: (result:
|
|
14
|
+
queryResult?: (result: ArrowTable) => void;
|
|
14
15
|
/** Whether to automatically connect when mosaic is ready */
|
|
15
16
|
enabled?: boolean;
|
|
16
17
|
};
|
|
17
|
-
export declare function useMosaicClient
|
|
18
|
-
data:
|
|
18
|
+
export declare function useMosaicClient(options: UseMosaicClientOptions): {
|
|
19
|
+
data: ArrowTable<any> | null;
|
|
19
20
|
isLoading: boolean;
|
|
20
21
|
client: import("@uwdata/mosaic-core").MosaicClient | null;
|
|
21
22
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMosaicClient.d.ts","sourceRoot":"","sources":["../src/useMosaicClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"useMosaicClient.d.ts","sourceRoot":"","sources":["../src/useMosaicClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AACzC,OAAO,KAAK,EAAC,KAAK,IAAI,UAAU,EAAC,MAAM,cAAc,CAAC;AAMtD,MAAM,MAAM,sBAAsB,GAAG;IACnC,iEAAiE;IACjE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,wDAAwD;IACxD,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,UAAU,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1D,+CAA+C;IAC/C,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB;;;;EAwE9D"}
|