Skip to content

Commit e58e6b6

Browse files
authored
feat: Upgrade to Mosaic v0.11 (#56)
1 parent d85b8fc commit e58e6b6

15 files changed

+556
-330
lines changed

deno.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
"@js-temporal/polyfill": "npm:@js-temporal/polyfill@~0.4.4",
2525
"@lukeed/uuid": "npm:@lukeed/uuid@^2.0.1",
2626
"@preact/signals-core": "npm:@preact/signals-core@^1.8.0",
27-
"@uwdata/mosaic-core": "npm:@uwdata/mosaic-core@~0.10.0",
28-
"@uwdata/mosaic-plot": "npm:@uwdata/mosaic-plot@~0.10.0",
29-
"@uwdata/mosaic-sql": "npm:@uwdata/mosaic-sql@~0.10.0",
30-
"apache-arrow": "npm:apache-arrow@^17.0.0",
27+
"@uwdata/flechette": "npm:@uwdata/flechette@^1.1.0",
28+
"@uwdata/mosaic-core": "npm:@uwdata/mosaic-core@~0.11.0",
29+
"@uwdata/mosaic-plot": "npm:@uwdata/mosaic-plot@~0.11.0",
30+
"@uwdata/mosaic-sql": "npm:@uwdata/mosaic-sql@~0.11.0",
3131
"d3": "npm:d3@^7.9.0",
3232
"htl": "npm:htl@~0.3.1"
3333
},

deno.lock

+182-74
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/clients/DataTable.ts

+22-21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as arrow from "apache-arrow";
1+
import * as flech from "@uwdata/flechette";
22
// @ts-types="../deps/mosaic-core.d.ts"
33
import {
44
type Coordinator,
@@ -24,12 +24,13 @@ import { StatusBar } from "./StatusBar.ts";
2424

2525
interface DataTableOptions {
2626
table: string;
27-
schema: arrow.Schema;
27+
schema: flech.Schema;
2828
height?: number;
2929
}
3030

3131
// TODO: more
3232
type ColumnSummaryClient = Histogram | ValueCounts;
33+
type TableRow = Record<string, unknown>;
3334

3435
/**
3536
* Create a DataTable client.
@@ -67,7 +68,7 @@ export async function datatable(
6768

6869
export class DataTable extends MosaicClient {
6970
/** source of the data */
70-
#meta: { table: string; schema: arrow.Schema };
71+
#meta: { table: string; schema: flech.Schema };
7172
/** for the component */
7273
#root: HTMLElement = document.createElement("div");
7374
/** shadow root for the component */
@@ -97,8 +98,8 @@ export class DataTable extends MosaicClient {
9798
/** the formatter for the data table entries */
9899
#format: Record<string, (value: unknown) => string>;
99100

100-
/** @type {AsyncBatchReader<arrow.StructRowProxy> | null} */
101-
#reader: AsyncBatchReader<arrow.StructRowProxy> | null = null;
101+
/** @type {AsyncBatchReader<flech.StructRowProxy> | null} */
102+
#reader: AsyncBatchReader<TableRow> | null = null;
102103

103104
#sql = signal(undefined as string | undefined);
104105

@@ -199,7 +200,7 @@ export class DataTable extends MosaicClient {
199200
* A Mosiac lifecycle function called with arrow results from `query`.
200201
* Must be synchronous, and return `this`.
201202
*/
202-
queryResult(table: arrow.Table): this {
203+
queryResult(table: flech.Table): this {
203204
if (!this.#pendingInternalRequest) {
204205
// data is not from an internal request, so reset table
205206
this.#reader = new AsyncBatchReader(() => {
@@ -362,7 +363,7 @@ export class DataTable extends MosaicClient {
362363
}
363364
}
364365

365-
#appendRow(d: arrow.StructRowProxy, i: number) {
366+
#appendRow(d: TableRow, i: number) {
366367
let itr = this.#templateRow?.cloneNode(true);
367368
assert(itr, "Must have a data row");
368369
let td = itr.childNodes[0] as HTMLTableCellElement;
@@ -389,7 +390,7 @@ const TRUNCATE = /** @type {const} */ ({
389390
});
390391

391392
function thcol(
392-
field: arrow.Field,
393+
field: flech.Field,
393394
minWidth: number,
394395
vis?: ColumnSummaryClient,
395396
) {
@@ -502,7 +503,7 @@ function thcol(
502503
/**
503504
* Return a formatter for each field in the schema
504505
*/
505-
function formatof(schema: arrow.Schema) {
506+
function formatof(schema: flech.Schema) {
506507
const format: Record<string, (value: unknown) => string> = Object.create(
507508
null,
508509
);
@@ -515,20 +516,20 @@ function formatof(schema: arrow.Schema) {
515516
/**
516517
* Return a class type of each field in the schema.
517518
*/
518-
function classof(schema: arrow.Schema): Record<string, "number" | "date"> {
519+
function classof(schema: flech.Schema): Record<string, "number" | "date"> {
519520
const classes: Record<string, "number" | "date"> = Object.create(null);
520521
for (const field of schema.fields) {
521-
if (
522-
arrow.DataType.isInt(field.type) ||
523-
arrow.DataType.isFloat(field.type)
524-
) {
525-
classes[field.name] = "number";
526-
}
527-
if (
528-
arrow.DataType.isDate(field.type) ||
529-
arrow.DataType.isTimestamp(field.type)
530-
) {
531-
classes[field.name] = "date";
522+
switch (field.type.typeId) {
523+
case flech.Type.Int:
524+
case flech.Type.Float:
525+
classes[field.name] = "number";
526+
break;
527+
case flech.Type.Date:
528+
case flech.Type.Timestamp:
529+
classes[field.name] = "date";
530+
break;
531+
default:
532+
break;
532533
}
533534
}
534535
return classes;

lib/clients/Histogram.ts

+7-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
// @ts-types="../deps/mosaic-sql.d.ts";
1010
import { count, Query, type SQLExpression } from "@uwdata/mosaic-sql";
1111
import * as mplot from "@uwdata/mosaic-plot";
12-
import type * as arrow from "apache-arrow";
12+
import type * as flech from "@uwdata/flechette";
1313

1414
import { CrossfilterHistogramPlot } from "../utils/CrossfilterHistogramPlot.ts";
1515

@@ -21,7 +21,7 @@ interface HistogramOptions {
2121
/** The table to query. */
2222
table: string;
2323
/** An arrow Field containing the column info to use for the histogram. */
24-
field: arrow.Field;
24+
field: flech.Field;
2525
/** The column to use for the histogram. */
2626
column: string;
2727
/** The type of the column. Must be "number" or "date". */
@@ -30,14 +30,14 @@ interface HistogramOptions {
3030
filterBy: Selection;
3131
}
3232

33-
type BinTable = arrow.Table<{ x1: arrow.Int; x2: arrow.Int; y: arrow.Int }>;
33+
type BinTable = flech.Table;
3434

3535
/** Represents a Cross-filtered Histogram */
3636
export class Histogram extends MosaicClient implements Mark {
3737
#source: {
3838
table: string;
3939
column: string;
40-
field: arrow.Field;
40+
field: flech.Field;
4141
type: "number" | "date";
4242
};
4343
#el: HTMLElement = document.createElement("div");
@@ -102,11 +102,9 @@ export class Histogram extends MosaicClient implements Mark {
102102
* Provide query result data to the mark.
103103
*/
104104
queryResult(data: BinTable) {
105-
let bins = Array.from(data, (d) => ({
106-
x0: d.x1,
107-
x1: d.x2,
108-
length: d.y,
109-
}));
105+
let bins: Array<{ x0: number; x1: number; length: number }> = data
106+
.toArray()
107+
.map((d) => ({ x0: d.x1, x1: d.x2, length: d.y }));
110108
let nullCount = 0;
111109
let nullBinIndex = bins.findIndex((b) => b.x0 == null);
112110
if (nullBinIndex >= 0) {

lib/clients/StatusBar.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type * as arrow from "apache-arrow";
1+
import * as flech from "@uwdata/flechette";
22
// @ts-types="../deps/mosaic-core.d.ts"
33
import {
44
type Interactor,
@@ -7,6 +7,7 @@ import {
77
} from "@uwdata/mosaic-core";
88
// @ts-types="../deps/mosaic-sql.d.ts"
99
import { count, Query } from "@uwdata/mosaic-sql";
10+
import { assert } from "../utils/assert.ts";
1011

1112
interface StatusBarOptions {
1213
table: string;
@@ -66,7 +67,13 @@ export class StatusBar extends MosaicClient {
6667
return query;
6768
}
6869

69-
queryResult(table: arrow.Table<{ count: arrow.Int }>) {
70+
queryResult(table: flech.Table) {
71+
assert(
72+
table.schema.fields.find((f) => f.name === "count")?.type.typeId ===
73+
flech.Type.Int,
74+
"Expected count field to be an integer",
75+
);
76+
7077
let count = Number(table.get(0)?.count ?? 0);
7178
if (!this.#totalRows) {
7279
// we need to know the total number of rows to display

lib/clients/ValueCounts.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
type SQLExpression,
1010
sum,
1111
} from "@uwdata/mosaic-sql";
12-
import type * as arrow from "apache-arrow";
12+
import type * as flech from "@uwdata/flechette";
1313
import { effect } from "@preact/signals-core";
1414

1515
import { ValueCountsPlot } from "../utils/ValueCountsPlot.ts";
@@ -19,17 +19,17 @@ interface UniqueValuesOptions {
1919
/** The table to query. */
2020
table: string;
2121
/** An arrow Field containing the column info to use for the histogram. */
22-
field: arrow.Field;
22+
field: flech.Field;
2323
/** A mosaic selection to filter the data. */
2424
filterBy: Selection;
2525
}
2626

27-
type CountTable = arrow.Table<{ key: arrow.Utf8; total: arrow.Int }>;
27+
type CountTable = flech.Table;
2828

2929
export class ValueCounts extends MosaicClient {
3030
#table: string;
3131
#column: string;
32-
#field: arrow.Field;
32+
#field: flech.Field;
3333
#el: HTMLElement = document.createElement("div");
3434
#plot: ReturnType<typeof ValueCountsPlot> | undefined;
3535

lib/demo.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/// <reference types="npm:vite/client" />
2+
// @ts-types="./deps/mosaic-core.d.ts";
23
import * as mc from "@uwdata/mosaic-core";
34
import * as msql from "@uwdata/mosaic-sql";
45

lib/deps/mosaic-core.d.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @ts-types="./mosaic-sql.d.ts";
22
import type { Query, SQLExpression } from "@uwdata/mosaic-sql";
3-
import type * as arrow from "apache-arrow";
3+
import type * as flechette from "@uwdata/flechette";
44

55
export interface Interactor<T = unknown> {
66
reset(): void;
@@ -113,7 +113,7 @@ export class MosaicClient {
113113
query(filter?: Array<unknown>): Query;
114114
/** Called before the coordinator submitting a query to inform the client */
115115
queryPending(): this;
116-
queryResult(data: arrow.Table): this;
116+
queryResult(data: flechette.Table): this;
117117
queryError(error: unknown): this;
118118
requestQuery(query: Query): void;
119119
requestUpdate(query: Query): void;
@@ -124,7 +124,7 @@ export type ConnectorQuery = { type: "arrow" | "json"; sql: string };
124124
export interface Connector {
125125
query(
126126
query: ConnectorQuery,
127-
): Promise<arrow.Table | Record<string, unknown>>;
127+
): Promise<flechette.Table | Record<string, unknown>>;
128128
}
129129

130130
export class Coordinator {
@@ -134,8 +134,11 @@ export class Coordinator {
134134
prefetch(query: Query): void;
135135
logger(impl?: unknown): Logger;
136136
databaseConnector(connector: Connector): void;
137-
query(query: Query): Promise<arrow.Table>;
137+
query(query: Query): Promise<flechette.Table>;
138138
clear(): void;
139+
dataCubeIndexer: {
140+
schema: string | undefined;
141+
};
139142
}
140143

141144
type Logger = typeof console & {

lib/utils/AsyncBatchReader.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ import { assert } from "./assert.ts";
2222
*/
2323
export class AsyncBatchReader<T> {
2424
/** the iterable batches to read */
25-
#batches: Array<{ data: Iterator<T>; last: boolean }> = [];
25+
#batches: Array<{ data: Generator<T>; last: boolean }> = [];
2626
/** the index of the current row */
2727
#index: number = 0;
2828
/** resolves a promise for when the next batch is available */
2929
#resolve: (() => void) | null = null;
3030
/** the current batch */
31-
#current: { data: Iterator<T>; last: boolean } | null = null;
31+
#current: { data: Generator<T>; last: boolean } | null = null;
3232
/** A function to request more data. */
3333
#requestNextBatch: () => void;
3434
/**
@@ -50,7 +50,7 @@ export class AsyncBatchReader<T> {
5050
* @param options
5151
* @param options.last - whether this is the last batch
5252
*/
53-
enqueueBatch(batch: Iterator<T>, { last }: { last: boolean }) {
53+
enqueueBatch(batch: Generator<T>, { last }: { last: boolean }) {
5454
this.#batches.push({ data: batch, last });
5555
if (this.#resolve) {
5656
this.#resolve();

lib/utils/CrossfilterHistogramPlot.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as d3 from "d3";
44
import { assert } from "../utils/assert.ts";
55
import { tickFormatterForBins } from "./tick-formatter-for-bins.ts";
66
import type { Bin, Scale } from "../types.ts";
7-
import type * as arrow from "apache-arrow";
7+
import type * as flech from "@uwdata/flechette";
88
import { formatDataType, percentFormatter } from "./formatting.ts";
99

1010
interface HistogramOptions {
@@ -29,7 +29,7 @@ interface HistogramOptions {
2929
*/
3030
export function CrossfilterHistogramPlot(
3131
bins: Array<Bin>,
32-
field: arrow.Field,
32+
field: flech.Field,
3333
{
3434
type = "number",
3535
width = 125,

lib/utils/ValueCountsPlot.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import { effect, signal } from "@preact/signals-core";
2-
import type * as arrow from "apache-arrow";
2+
import type * as flech from "@uwdata/flechette";
33
// @ts-types="npm:@types/d3"
44
import * as d3 from "d3";
55
import { assert } from "./assert.ts";
66
import { formatDataType, percentFormatter } from "./formatting.ts";
77

8-
type CountTableData = arrow.Table<{
9-
key: arrow.Utf8;
10-
total: arrow.Int;
11-
}>;
8+
type CountTableData = flech.Table;
129

1310
interface ValueCountsPlot {
1411
width?: number;
@@ -24,7 +21,7 @@ interface ValueCountsPlot {
2421

2522
export function ValueCountsPlot(
2623
data: CountTableData,
27-
field: arrow.Field,
24+
field: flech.Field,
2825
{
2926
width = 125,
3027
height = 30,
@@ -178,9 +175,11 @@ function createBar(opts: {
178175
}
179176

180177
function prepareData(data: CountTableData) {
181-
let arr: Array<{ key: string; total: number }> = data
178+
let arr = data
182179
.toArray()
183-
.toSorted((a, b) => b.total - a.total);
180+
.toSorted((a, b) => b.total - a.total) as Array<
181+
{ key: string; total: number }
182+
>;
184183
let total = arr.reduce((acc, d) => acc + d.total, 0);
185184
return {
186185
bins: arr.filter((d) =>

0 commit comments

Comments
 (0)