Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleaner deeptable instantiation pattern #172

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 47 additions & 5 deletions src/Deeptable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,57 @@
// Must come after manifest is set.
this.base_url = baseUrl;
this.root_tile = new Tile(defaultManifest, null, this);
const preProcessRootTile = this.root_tile.preprocessRootTileInfo();

// At instantiation, the deeptable isn't ready; only once this
// async stuff is done can the deeptable be used.
// TODO: Add an async static method as the preferred initialization method.
this.promise = preProcessRootTile.then(async () => {
this.promise = this._makePromise(defaultManifest);
}

/**
* Loads a quadtree created by version 2.0 or great of the quadfeather package (including manifests).
*
* @param tileProxy A tileProxy to use for fetching tiles. Can be used to wrap authentication.
* @param baseUrl The base URL of the quadfeather data.
*
*/
static async fromQuadfeather({
tileProxy,
baseUrl,
plot = null,
}: {
tileProxy?: DS.TileProxy;
baseUrl: string;
plot?: Scatterplot | null;
}) {
let manifest: DS.TileManifest;
if (tileProxy !== undefined) {
throw new Error('Not yet supported');
} else {
manifest = await loadTileManifest(baseUrl + '/manifest.feather');
}

const dt = new Deeptable({
tileProxy,
tileManifest: manifest,
baseUrl,
rootKey: '0/0/0',
plot,
});
await dt.promise;
return dt;
}

/**
* Internal function to ensure
*/
protected _makePromise(
tileManifest: Partial<DS.TileManifest> & { key: string },
): Promise<void> {
return this.root_tile.preprocessRootTileInfo().then(async () => {
const batch = await this.root_tile.get_arrow(null);
const schema = batch.schema;
if (!tileManifest) {
// TODO: Cleaner check that it's a lazy manifest
if (!tileManifest.max_ix) {
this.root_tile.manifest =
await this.root_tile.deriveManifestInfoFromTileMetadata();
}
Expand Down Expand Up @@ -368,7 +410,7 @@
if (dim === undefined) {
continue;
}
dim = (dim as Field<Struct<any>>).type.children.find(

Check failure on line 413 in src/Deeptable.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, TypeScript, and Tests

Unexpected any. Specify a different type
(d) => d.name === sub,
);
}
Expand All @@ -388,7 +430,7 @@
max = JSON.parse(mmax) as T[0];
}
// Can pass min, max as strings for dates.
if (dim.type.typeId === Type.Timestamp) {

Check failure on line 433 in src/Deeptable.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, TypeScript, and Tests

Unsafe member access .typeId on an `any` value
if (typeof min !== 'string' || typeof max !== 'string') {
throw new Error(
'Date field extents in metadata must be passed as strings',
Expand Down Expand Up @@ -1188,7 +1230,7 @@
extent: Rectangle;
};

export async function tileManifest(url: string) {
export async function loadTileManifest(url: string): Promise<TileManifest> {
const data = await fetch(url).then((d) => d.arrayBuffer());
const tb = tableFromIPC(data);
const rows: RowFormatManifest[] = [...tb].map(
Expand Down
6 changes: 5 additions & 1 deletion src/scatterplot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,11 @@
tileProxy,
}: DS.DataSpec): Promise<DS.Deeptable> {
if (source_url !== undefined) {
this._root = Deeptable.from_quadfeather(source_url, this, tileProxy);
this._root = await Deeptable.fromQuadfeather({
baseUrl: source_url,
plot: this,
tileProxy,
});
} else if (arrow_table !== undefined) {
this._root = Deeptable.fromArrowTable(arrow_table, this);
} else if (arrow_buffer !== undefined) {
Expand Down Expand Up @@ -614,7 +618,7 @@
}

get highlit_point_change(): ChangeToHighlitPointFunction['f'] {
return this.handle_highlit_point_change.f.bind(

Check failure on line 621 in src/scatterplot.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, TypeScript, and Tests

Unsafe return of an `any` typed value
this.handle_highlit_point_change,
);
}
Expand Down Expand Up @@ -695,7 +699,7 @@
}
//
const needed_keys = neededFieldsToPlot(prefs.encoding);
this.deeptable.root_tile.require_columns(

Check failure on line 702 in src/scatterplot.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, TypeScript, and Tests

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
[...needed_keys].map((k) => k[0]),
);
// Immediately start loading what we can onto the GPUs, too.
Expand All @@ -713,7 +717,7 @@
*
* @param prefs An API call.
*/
private async unsafe_plotAPI(prefs: DS.APICall): Promise<void> {

Check failure on line 720 in src/scatterplot.ts

View workflow job for this annotation

GitHub Actions / Run ESLint, TypeScript, and Tests

Async method 'unsafe_plotAPI' has no 'await' expression
if (prefs === null) {
return;
}
Expand Down
Loading