mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-02 11:28:12 +08:00
* Added TS. Updated build and linting config. Added types. * [ts-migrate][.] Rename files from JS/JSX to TS/TSX Co-authored-by: ts-migrate <> * [ts-migrate][.] Run TS Migrate Co-authored-by: ts-migrate <> * Corrected files mangled by ts-migrate. * Updated lint config, minor linting. * Re-enabled Husky. * Updated tests and config. * Reverted webpack devtool config. * Removed obsolete snapshots. * Added annotations snap. * Updated tsconfig includes wrt linting. * Removed ts-migrate. Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com>
This commit is contained in:
co-authored by
ts-migrate
Timmy Huang
parent
7328cbdbd5
commit
934cc5c69b
@@ -17,6 +17,28 @@ import { _queryValidate, _queryCacheKey } from "./query";
|
||||
const _dataframeCache = dataframeMemo(128);
|
||||
|
||||
export default class AnnoMatrix {
|
||||
public isView: any;
|
||||
|
||||
public nObs: any;
|
||||
|
||||
public nVar: any;
|
||||
|
||||
public rowIndex: any;
|
||||
|
||||
public schema: any;
|
||||
|
||||
public userFlags: any;
|
||||
|
||||
public viewOf: any;
|
||||
|
||||
protected _cache: any;
|
||||
|
||||
private _pendingLoad: any;
|
||||
|
||||
private _whereCache: any;
|
||||
|
||||
private _gcInfo: any;
|
||||
|
||||
/*
|
||||
Abstract base class for all AnnoMatrix objects. This class provides a proxy
|
||||
to the annotated matrix data authoritatively served by the server/back-end.
|
||||
@@ -54,7 +76,7 @@ export default class AnnoMatrix {
|
||||
return ["obs", "var", "emb", "X"];
|
||||
}
|
||||
|
||||
constructor(schema, nObs, nVar, rowIndex = null) {
|
||||
constructor(schema: any, nObs: any, nVar: any, rowIndex = null) {
|
||||
/*
|
||||
Private constructor - this is an abstract base class. Do not use.
|
||||
*/
|
||||
@@ -83,13 +105,13 @@ export default class AnnoMatrix {
|
||||
this.userFlags = {};
|
||||
|
||||
/*
|
||||
Private instance variables.
|
||||
Private instance variables.
|
||||
|
||||
These are caches - lazily loaded. The only guarantee is that if they
|
||||
are loaded, they will conform to the schema & dimensionality constraints.
|
||||
These are caches - lazily loaded. The only guarantee is that if they
|
||||
are loaded, they will conform to the schema & dimensionality constraints.
|
||||
|
||||
Do NOT use directly - instead, use the fetch() and preload() API.
|
||||
*/
|
||||
Do NOT use directly - instead, use the fetch() and preload() API.
|
||||
*/
|
||||
this._cache = {
|
||||
obs: Dataframe.empty(this.rowIndex),
|
||||
var: Dataframe.empty(this.rowIndex),
|
||||
@@ -109,6 +131,7 @@ export default class AnnoMatrix {
|
||||
/**
|
||||
** Schema helper/accessors
|
||||
**/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
getMatrixColumns(field) {
|
||||
/*
|
||||
Return array of column names in the field. ONLY supported on the
|
||||
@@ -132,6 +155,7 @@ export default class AnnoMatrix {
|
||||
return AnnoMatrix.fields();
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
getColumnSchema(field, col) {
|
||||
/*
|
||||
Return the schema for the field & column ,eg,
|
||||
@@ -144,6 +168,7 @@ export default class AnnoMatrix {
|
||||
return _getColumnSchema(this.schema, field, col);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
getColumnDimensions(field, col) {
|
||||
/*
|
||||
Return the dimensions on this field / column. For most fields, which are 1D,
|
||||
@@ -174,6 +199,7 @@ export default class AnnoMatrix {
|
||||
/**
|
||||
** Load / read interfaces
|
||||
**/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
fetch(field, q) {
|
||||
/*
|
||||
Return the given query on a single matrix field as a single dataframe.
|
||||
@@ -231,6 +257,7 @@ export default class AnnoMatrix {
|
||||
return this._fetch(field, q);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
prefetch(field, q) {
|
||||
/*
|
||||
Start a data fetch & cache fill. Identical to fetch() except it does
|
||||
@@ -261,7 +288,8 @@ export default class AnnoMatrix {
|
||||
** The actual implementation is in the sub-classes, which MUST override these.
|
||||
**/
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
|
||||
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
|
||||
addObsAnnoCategory(col, category) {
|
||||
/*
|
||||
Add a new category value (aka "label") to a writable obs column, and return the new AnnoMatrix.
|
||||
@@ -278,7 +306,8 @@ export default class AnnoMatrix {
|
||||
_subclassResponsibility();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
|
||||
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
|
||||
async removeObsAnnoCategory(col, category, unassignedCategory) {
|
||||
/*
|
||||
Remove a category value from an obs column, reassign any obs having that value
|
||||
@@ -299,7 +328,8 @@ export default class AnnoMatrix {
|
||||
_subclassResponsibility();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
|
||||
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
|
||||
dropObsColumn(col) {
|
||||
/*
|
||||
Drop an entire writable column, eg a user-created obs annotation. Typical use
|
||||
@@ -315,7 +345,8 @@ export default class AnnoMatrix {
|
||||
_subclassResponsibility();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'colSchema' is declared but its value is never rea... Remove this comment to see the full error message
|
||||
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
|
||||
addObsColumn(colSchema, Ctor, value) {
|
||||
/*
|
||||
Add a new writable OBS annotation column, with the caller-specified schema, initial value
|
||||
@@ -344,7 +375,8 @@ export default class AnnoMatrix {
|
||||
_subclassResponsibility();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'oldCol' is declared but its value is never read.
|
||||
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
|
||||
renameObsColumn(oldCol, newCol) {
|
||||
/*
|
||||
Rename the obs column 'oldCol' to have name 'newCol' and returns new AnnoMatrix.
|
||||
@@ -359,7 +391,8 @@ export default class AnnoMatrix {
|
||||
_subclassResponsibility();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
|
||||
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
|
||||
async setObsColumnValues(col, obsLabels, value) {
|
||||
/*
|
||||
Set all obs with label in array 'obsLabels' to have 'value'. Typical use would be
|
||||
@@ -377,7 +410,8 @@ export default class AnnoMatrix {
|
||||
_subclassResponsibility();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read.
|
||||
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
|
||||
async resetObsColumnValues(col, oldValue, newValue) {
|
||||
/*
|
||||
Set by value - all elements in the column with value 'oldValue' are set to 'newValue'.
|
||||
@@ -394,7 +428,8 @@ export default class AnnoMatrix {
|
||||
_subclassResponsibility();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements
|
||||
// @ts-expect-error ts-migrate(6133) FIXME: 'colSchema' is declared but its value is never rea... Remove this comment to see the full error message
|
||||
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements
|
||||
addEmbedding(colSchema) {
|
||||
/*
|
||||
Add a new obs embedding to the AnnoMatrix, with provided schema.
|
||||
@@ -407,28 +442,35 @@ export default class AnnoMatrix {
|
||||
_subclassResponsibility();
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
getCacheKeys(field, query) {
|
||||
/*
|
||||
Return cache keys for columns associated with this query. May return
|
||||
[unknown] if no keys are known (ie, nothing is or was cached).
|
||||
*/
|
||||
Return cache keys for columns associated with this query. May return
|
||||
[unknown] if no keys are known (ie, nothing is or was cached).
|
||||
*/
|
||||
return _whereCacheGet(this._whereCache, this.schema, field, query);
|
||||
}
|
||||
|
||||
/**
|
||||
** Private interfaces below.
|
||||
**/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
_resolveCachedQueries(field, queries) {
|
||||
return queries
|
||||
.map((query) =>
|
||||
_whereCacheGet(this._whereCache, this.schema, field, query).filter(
|
||||
(cacheKey) =>
|
||||
cacheKey !== undefined && this._cache[field].hasCol(cacheKey)
|
||||
return (
|
||||
queries
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'query' implicitly has an 'any' type.
|
||||
.map((query) =>
|
||||
_whereCacheGet(this._whereCache, this.schema, field, query).filter(
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'cacheKey' implicitly has an 'any' type.
|
||||
(cacheKey) =>
|
||||
cacheKey !== undefined && this._cache[field].hasCol(cacheKey)
|
||||
)
|
||||
)
|
||||
)
|
||||
.flat();
|
||||
.flat()
|
||||
);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
async _fetch(field, q) {
|
||||
if (!AnnoMatrix.fields().includes(field)) return undefined;
|
||||
const queries = Array.isArray(q) ? q : [q];
|
||||
@@ -441,6 +483,7 @@ export default class AnnoMatrix {
|
||||
/* find any query not already cached */
|
||||
const uncachedQueries = queries.filter((query) =>
|
||||
_whereCacheGet(this._whereCache, this.schema, field, query).some(
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'cacheKey' implicitly has an 'any' type.
|
||||
(cacheKey) =>
|
||||
cacheKey === undefined || !this._cache[field].hasCol(cacheKey)
|
||||
)
|
||||
@@ -450,8 +493,10 @@ export default class AnnoMatrix {
|
||||
if (uncachedQueries.length > 0) {
|
||||
await Promise.all(
|
||||
uncachedQueries.map((query) =>
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter '_field' implicitly has an 'any' type.
|
||||
this._getPendingLoad(field, query, async (_field, _query) => {
|
||||
/* fetch, then index. _doLoad is subclass interface */
|
||||
// @ts-expect-error ts-migrate(2488) FIXME: Type 'void' must have a '[Symbol.iterator]()' meth... Remove this comment to see the full error message
|
||||
const [whereCacheUpdate, df] = await this._doLoad(_field, _query);
|
||||
this._cache[_field] = this._cache[_field].withColsFrom(df);
|
||||
this._whereCache = _whereCacheMerge(
|
||||
@@ -472,6 +517,7 @@ export default class AnnoMatrix {
|
||||
return response;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
async _getPendingLoad(field, query, fetchFn) {
|
||||
/*
|
||||
Given a query on a field, ensure that we only have a single outstanding
|
||||
@@ -527,19 +573,21 @@ export default class AnnoMatrix {
|
||||
To be effective, the GC callback needs to be invoked from the undo/redo code,
|
||||
as much of the cache is pinned by that data structure.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
_gcField(field, isHot, pinnedColumns) {
|
||||
const maxColumns = isHot ? 256 : 10; // maybe to aggressive?
|
||||
|
||||
const maxColumns = isHot ? 256 : 10;
|
||||
const cache = this._cache[field];
|
||||
if (cache.colIndex.size() < maxColumns) return; // trivial rejection
|
||||
|
||||
const candidates = cache.colIndex
|
||||
.labels()
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
.filter((col) => !pinnedColumns.includes(col));
|
||||
|
||||
const excessCount = candidates.length + pinnedColumns.length - maxColumns;
|
||||
if (excessCount > 0) {
|
||||
const { _gcInfo } = this;
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'a' implicitly has an 'any' type.
|
||||
candidates.sort((a, b) => {
|
||||
let atime = _gcInfo.get(_columnCacheKey(field, a));
|
||||
if (atime === undefined) atime = 0;
|
||||
@@ -558,13 +606,16 @@ export default class AnnoMatrix {
|
||||
// )}]`
|
||||
// );
|
||||
this._cache[field] = toDrop.reduce(
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'df' implicitly has an 'any' type.
|
||||
(df, col) => df.dropCol(col),
|
||||
this._cache[field]
|
||||
);
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
toDrop.forEach((col) => _gcInfo.delete(_columnCacheKey(field, col)));
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
_gcFetchCleanup(field, pinnedColumns) {
|
||||
/*
|
||||
Called during data load/fetch. By definition, this is 'hot', so we
|
||||
@@ -579,6 +630,7 @@ export default class AnnoMatrix {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'hints' implicitly has an 'any' type.
|
||||
_gc(hints) {
|
||||
/*
|
||||
Called from middleware, or elsewhere. isHot is true if we are in the active store,
|
||||
@@ -591,6 +643,7 @@ export default class AnnoMatrix {
|
||||
);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
_gcUpdateStats(field, dataframe) {
|
||||
/*
|
||||
called each time a query is performed, allowing the gc to update any bookkeeping
|
||||
@@ -600,6 +653,7 @@ export default class AnnoMatrix {
|
||||
const cols = dataframe.colIndex.labels();
|
||||
const { _gcInfo } = this;
|
||||
const now = Date.now();
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'c' implicitly has an 'any' type.
|
||||
cols.forEach((c) => {
|
||||
_gcInfo.set(_columnCacheKey(field, c), now);
|
||||
});
|
||||
@@ -617,6 +671,7 @@ export default class AnnoMatrix {
|
||||
|
||||
Do not override _clone();
|
||||
**/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'clone' implicitly has an 'any' type.
|
||||
_cloneDeeper(clone) {
|
||||
clone._cache = _shallowClone(this._cache);
|
||||
clone._gcInfo = new Map();
|
||||
@@ -640,6 +695,7 @@ export default class AnnoMatrix {
|
||||
/*
|
||||
private utility functions below
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
function _columnCacheKey(field, column) {
|
||||
return `${field}/${column}`;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Shallow clone an object, correctly handling prototype
|
||||
*/
|
||||
export default function _shallowClone(orig) {
|
||||
export default function _shallowClone(orig: any) {
|
||||
return Object.assign(Object.create(Object.getPrototypeOf(orig)), orig);
|
||||
}
|
||||
@@ -10,26 +10,31 @@ AnnoMatrix stay in sync:
|
||||
import Crossfilter from "../util/typedCrossfilter";
|
||||
import { _getColumnSchema } from "./schema";
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
function _dimensionNameFromDf(field, df) {
|
||||
const colNames = df.colIndex.labels();
|
||||
return _dimensionName(field, colNames);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
function _dimensionName(field, colNames) {
|
||||
if (!Array.isArray(colNames)) return `${field}/${colNames}`;
|
||||
return `${field}/${colNames.join(":")}`;
|
||||
}
|
||||
|
||||
export default class AnnoMatrixObsCrossfilter {
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
|
||||
constructor(annoMatrix, _obsCrossfilter = null) {
|
||||
this.annoMatrix = annoMatrix;
|
||||
this.obsCrossfilter =
|
||||
(this as any).annoMatrix = annoMatrix;
|
||||
(this as any).obsCrossfilter =
|
||||
_obsCrossfilter || new Crossfilter(annoMatrix._cache.obs);
|
||||
this.obsCrossfilter = this.obsCrossfilter.setData(annoMatrix._cache.obs);
|
||||
(this as any).obsCrossfilter = (this as any).obsCrossfilter.setData(
|
||||
annoMatrix._cache.obs
|
||||
);
|
||||
}
|
||||
|
||||
size() {
|
||||
return this.obsCrossfilter.size();
|
||||
return (this as any).obsCrossfilter.size();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,14 +44,23 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
|
||||
See API documentation in annoMatrix.js.
|
||||
**/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
|
||||
addObsColumn(colSchema, Ctor, value) {
|
||||
const annoMatrix = this.annoMatrix.addObsColumn(colSchema, Ctor, value);
|
||||
const obsCrossfilter = this.obsCrossfilter.setData(annoMatrix._cache.obs);
|
||||
const annoMatrix = (this as any).annoMatrix.addObsColumn(
|
||||
colSchema,
|
||||
Ctor,
|
||||
value
|
||||
);
|
||||
const obsCrossfilter = (this as any).obsCrossfilter.setData(
|
||||
annoMatrix._cache.obs
|
||||
);
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
dropObsColumn(col) {
|
||||
const annoMatrix = this.annoMatrix.dropObsColumn(col);
|
||||
const annoMatrix = (this as any).annoMatrix.dropObsColumn(col);
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
|
||||
let { obsCrossfilter } = this;
|
||||
const dimName = _dimensionName("obs", col);
|
||||
if (obsCrossfilter.hasDimension(dimName)) {
|
||||
@@ -55,10 +69,12 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'oldCol' implicitly has an 'any' type.
|
||||
renameObsColumn(oldCol, newCol) {
|
||||
const annoMatrix = this.annoMatrix.renameObsColumn(oldCol, newCol);
|
||||
const annoMatrix = (this as any).annoMatrix.renameObsColumn(oldCol, newCol);
|
||||
const oldDimName = _dimensionName("obs", oldCol);
|
||||
const newDimName = _dimensionName("obs", newCol);
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
|
||||
let { obsCrossfilter } = this;
|
||||
if (obsCrossfilter.hasDimension(oldDimName)) {
|
||||
obsCrossfilter = obsCrossfilter.renameDimension(oldDimName, newDimName);
|
||||
@@ -66,9 +82,14 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
addObsAnnoCategory(col, category) {
|
||||
const annoMatrix = this.annoMatrix.addObsAnnoCategory(col, category);
|
||||
const annoMatrix = (this as any).annoMatrix.addObsAnnoCategory(
|
||||
col,
|
||||
category
|
||||
);
|
||||
const dimName = _dimensionName("obs", col);
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
|
||||
let { obsCrossfilter } = this;
|
||||
if (obsCrossfilter.hasDimension(dimName)) {
|
||||
obsCrossfilter = obsCrossfilter.delDimension(dimName);
|
||||
@@ -76,13 +97,15 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
async removeObsAnnoCategory(col, category, unassignedCategory) {
|
||||
const annoMatrix = await this.annoMatrix.removeObsAnnoCategory(
|
||||
const annoMatrix = await (this as any).annoMatrix.removeObsAnnoCategory(
|
||||
col,
|
||||
category,
|
||||
unassignedCategory
|
||||
);
|
||||
const dimName = _dimensionName("obs", col);
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
|
||||
let { obsCrossfilter } = this;
|
||||
if (obsCrossfilter.hasDimension(dimName)) {
|
||||
obsCrossfilter = obsCrossfilter.delDimension(dimName);
|
||||
@@ -90,13 +113,15 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
async setObsColumnValues(col, rowLabels, value) {
|
||||
const annoMatrix = await this.annoMatrix.setObsColumnValues(
|
||||
const annoMatrix = await (this as any).annoMatrix.setObsColumnValues(
|
||||
col,
|
||||
rowLabels,
|
||||
value
|
||||
);
|
||||
const dimName = _dimensionName("obs", col);
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
|
||||
let { obsCrossfilter } = this;
|
||||
if (obsCrossfilter.hasDimension(dimName)) {
|
||||
obsCrossfilter = obsCrossfilter.delDimension(dimName);
|
||||
@@ -104,13 +129,15 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
async resetObsColumnValues(col, oldValue, newValue) {
|
||||
const annoMatrix = await this.annoMatrix.resetObsColumnValues(
|
||||
const annoMatrix = await (this as any).annoMatrix.resetObsColumnValues(
|
||||
col,
|
||||
oldValue,
|
||||
newValue
|
||||
);
|
||||
const dimName = _dimensionName("obs", col);
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
|
||||
let { obsCrossfilter } = this;
|
||||
if (obsCrossfilter.hasDimension(dimName)) {
|
||||
obsCrossfilter = obsCrossfilter.delDimension(dimName);
|
||||
@@ -118,9 +145,13 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
|
||||
addEmbedding(colSchema) {
|
||||
const annoMatrix = this.annoMatrix.addEmbedding(colSchema);
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, this.obsCrossfilter);
|
||||
const annoMatrix = (this as any).annoMatrix.addEmbedding(colSchema);
|
||||
return new AnnoMatrixObsCrossfilter(
|
||||
annoMatrix,
|
||||
(this as any).obsCrossfilter
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,11 +159,15 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
* want to stop trackin the selection state, but aren't sure we want to blow the
|
||||
* annomatrix cache.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
dropDimension(field, query) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message
|
||||
const { annoMatrix } = this;
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
|
||||
let { obsCrossfilter } = this;
|
||||
const keys = annoMatrix
|
||||
.getCacheKeys(field, query)
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'k' implicitly has an 'any' type.
|
||||
.filter((k) => k !== undefined);
|
||||
const dimName = _dimensionName(field, keys);
|
||||
if (obsCrossfilter.hasDimension(dimName)) {
|
||||
@@ -146,8 +181,11 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
are just wrappers to lazy create indices.
|
||||
**/
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
async select(field, query, spec) {
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message
|
||||
const { annoMatrix } = this;
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message
|
||||
let { obsCrossfilter } = this;
|
||||
|
||||
if (!annoMatrix?._cache?.[field]) {
|
||||
@@ -180,55 +218,59 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
/*
|
||||
Select all on any dimension in this field.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message
|
||||
const { annoMatrix } = this;
|
||||
const currentDims = this.obsCrossfilter.dimensionNames();
|
||||
const currentDims = (this as any).obsCrossfilter.dimensionNames();
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'xfltr' implicitly has an 'any' type.
|
||||
const obsCrossfilter = currentDims.reduce((xfltr, dim) => {
|
||||
return xfltr.select(dim, { mode: "all" });
|
||||
}, this.obsCrossfilter);
|
||||
}, (this as any).obsCrossfilter);
|
||||
return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter);
|
||||
}
|
||||
|
||||
countSelected() {
|
||||
/* if no data yet indexed in the crossfilter, just say everything is selected */
|
||||
if (this.obsCrossfilter.size() === 0) return this.annoMatrix.nObs;
|
||||
return this.obsCrossfilter.countSelected();
|
||||
if ((this as any).obsCrossfilter.size() === 0)
|
||||
return (this as any).annoMatrix.nObs;
|
||||
return (this as any).obsCrossfilter.countSelected();
|
||||
}
|
||||
|
||||
allSelectedMask() {
|
||||
/* if no data yet indexed in the crossfilter, just say everything is selected */
|
||||
if (
|
||||
this.obsCrossfilter.size() === 0 ||
|
||||
this.obsCrossfilter.dimensionNames().length === 0
|
||||
(this as any).obsCrossfilter.size() === 0 ||
|
||||
(this as any).obsCrossfilter.dimensionNames().length === 0
|
||||
) {
|
||||
/* fake the mask */
|
||||
return new Uint8Array(this.annoMatrix.nObs).fill(1);
|
||||
return new Uint8Array((this as any).annoMatrix.nObs).fill(1);
|
||||
}
|
||||
return this.obsCrossfilter.allSelectedMask();
|
||||
return (this as any).obsCrossfilter.allSelectedMask();
|
||||
}
|
||||
|
||||
allSelectedLabels() {
|
||||
/* if no data yet indexed in the crossfilter, just say everything is selected */
|
||||
if (
|
||||
this.obsCrossfilter.size() === 0 ||
|
||||
this.obsCrossfilter.dimensionNames().length === 0
|
||||
(this as any).obsCrossfilter.size() === 0 ||
|
||||
(this as any).obsCrossfilter.dimensionNames().length === 0
|
||||
) {
|
||||
return this.annoMatrix.rowIndex.labels();
|
||||
return (this as any).annoMatrix.rowIndex.labels();
|
||||
}
|
||||
|
||||
const mask = this.obsCrossfilter.allSelectedMask();
|
||||
const index = this.annoMatrix.rowIndex.isubsetMask(mask);
|
||||
const mask = (this as any).obsCrossfilter.allSelectedMask();
|
||||
const index = (this as any).annoMatrix.rowIndex.isubsetMask(mask);
|
||||
return index.labels();
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'array' implicitly has an 'any' type.
|
||||
fillByIsSelected(array, selectedValue, deselectedValue) {
|
||||
/* if no data yet indexed in the crossfilter, just say everything is selected */
|
||||
if (
|
||||
this.obsCrossfilter.size() === 0 ||
|
||||
this.obsCrossfilter.dimensionNames().length === 0
|
||||
(this as any).obsCrossfilter.size() === 0 ||
|
||||
(this as any).obsCrossfilter.dimensionNames().length === 0
|
||||
) {
|
||||
return array.fill(selectedValue);
|
||||
}
|
||||
return this.obsCrossfilter.fillByIsSelected(
|
||||
return (this as any).obsCrossfilter.fillByIsSelected(
|
||||
array,
|
||||
selectedValue,
|
||||
deselectedValue
|
||||
@@ -239,21 +281,29 @@ export default class AnnoMatrixObsCrossfilter {
|
||||
** Private below
|
||||
**/
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
|
||||
_addObsCrossfilterDimension(annoMatrix, obsCrossfilter, field, df) {
|
||||
if (field === "var") return obsCrossfilter;
|
||||
const dimName = _dimensionNameFromDf(field, df);
|
||||
const dimParams = this._getObsDimensionParams(field, df);
|
||||
obsCrossfilter = obsCrossfilter.setData(annoMatrix._cache.obs);
|
||||
// @ts-expect-error ts-migrate(2488) FIXME: Type 'any[] | undefined' must have a '[Symbol.iter... Remove this comment to see the full error message
|
||||
obsCrossfilter = obsCrossfilter.addDimension(dimName, ...dimParams);
|
||||
return obsCrossfilter;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
_getColumnBaseType(field, col) {
|
||||
/* Look up the primitive type for this field/col */
|
||||
const colSchema = _getColumnSchema(this.annoMatrix.schema, field, col);
|
||||
const colSchema = _getColumnSchema(
|
||||
(this as any).annoMatrix.schema,
|
||||
field,
|
||||
col
|
||||
);
|
||||
return colSchema.type;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
_getObsDimensionParams(field, df) {
|
||||
/* return the crossfilter dimensiontype type and params for this field/dataframe */
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
export { doBinaryRequest, doFetch } from "../util/actionHelpers";
|
||||
|
||||
/* double URI encode - needed for query-param filters */
|
||||
export function _dubEncURIComp(s) {
|
||||
export function _dubEncURIComp(s: any) {
|
||||
return encodeURIComponent(encodeURIComponent(s));
|
||||
}
|
||||
|
||||
/* currently unused, consider deleting */
|
||||
export function _fetchResult(promise) {
|
||||
export function _fetchResult(promise: any) {
|
||||
let _status = "pending";
|
||||
const res = promise.then(
|
||||
(r) => {
|
||||
(r: any) => {
|
||||
_status = "success";
|
||||
return r;
|
||||
},
|
||||
(e) => {
|
||||
(e: any) => {
|
||||
_status = "error";
|
||||
throw e;
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import {
|
||||
const promiseThrottle = new PromiseLimit(5);
|
||||
|
||||
export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
baseURL: any;
|
||||
|
||||
/*
|
||||
AnnoMatrix implementation which proxies to HTTP server using the CXG REST API.
|
||||
Used as the base (non-view) instance.
|
||||
@@ -33,7 +35,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
new AnnoMatrixLoader(serverBaseURL, schema) -> instance
|
||||
|
||||
*/
|
||||
constructor(baseURL, schema) {
|
||||
constructor(baseURL: any, schema: any) {
|
||||
const { nObs, nVar } = schema.dataframe;
|
||||
super(schema, nObs, nVar);
|
||||
|
||||
@@ -48,7 +50,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
/**
|
||||
** Public. API described in base class.
|
||||
**/
|
||||
addObsAnnoCategory(col, category) {
|
||||
addObsAnnoCategory(col: any, category: any) {
|
||||
/*
|
||||
Add a new category (aka label) to the schema for an obs column.
|
||||
*/
|
||||
@@ -60,7 +62,11 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
async removeObsAnnoCategory(col, category, unassignedCategory) {
|
||||
async removeObsAnnoCategory(
|
||||
col: any,
|
||||
category: any,
|
||||
unassignedCategory: any
|
||||
) {
|
||||
/*
|
||||
Remove a single "category" (aka "label") from the data & schema of an obs column.
|
||||
*/
|
||||
@@ -80,7 +86,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
dropObsColumn(col) {
|
||||
dropObsColumn(col: any) {
|
||||
/*
|
||||
drop column from field
|
||||
*/
|
||||
@@ -88,11 +94,12 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
_writableCheck(colSchema); // throws on error
|
||||
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col);
|
||||
newAnnoMatrix._cache.obs = (this as any)._cache.obs.dropCol(col);
|
||||
newAnnoMatrix.schema = removeObsAnnoColumn(this.schema, col);
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
|
||||
addObsColumn(colSchema, Ctor, value) {
|
||||
/*
|
||||
add a column to field, initializing with value. Value may
|
||||
@@ -105,7 +112,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
const colName = colSchema.name;
|
||||
if (
|
||||
_getColumnSchema(this.schema, "obs", colName) ||
|
||||
this._cache.obs.hasCol(colName)
|
||||
(this as any)._cache.obs.hasCol(colName)
|
||||
) {
|
||||
throw new Error("column already exists");
|
||||
}
|
||||
@@ -121,7 +128,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
} else {
|
||||
data = new Ctor(this.nObs).fill(value);
|
||||
}
|
||||
newAnnoMatrix._cache.obs = this._cache.obs.withCol(colName, data);
|
||||
newAnnoMatrix._cache.obs = (this as any)._cache.obs.withCol(colName, data);
|
||||
_normalizeCategoricalSchema(
|
||||
colSchema,
|
||||
newAnnoMatrix._cache.obs.col(colName)
|
||||
@@ -130,15 +137,15 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'oldCol' implicitly has an 'any' type.
|
||||
renameObsColumn(oldCol, newCol) {
|
||||
/*
|
||||
Rename the obs oldColName to newColName. oldCol must be writable.
|
||||
*/
|
||||
const oldColSchema = _getColumnSchema(this.schema, "obs", oldCol);
|
||||
_writableCheck(oldColSchema); // throws on error
|
||||
|
||||
const value = this._cache.obs.hasCol(oldCol)
|
||||
? this._cache.obs.col(oldCol).asArray()
|
||||
_writableCheck(oldColSchema);
|
||||
const value = (this as any)._cache.obs.hasCol(oldCol)
|
||||
? (this as any)._cache.obs.col(oldCol).asArray()
|
||||
: undefined;
|
||||
return this.dropObsColumn(oldCol).addObsColumn(
|
||||
{
|
||||
@@ -150,6 +157,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
async setObsColumnValues(col, rowLabels, value) {
|
||||
/*
|
||||
Set all rows identified by rowLabels to value.
|
||||
@@ -159,11 +167,11 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
|
||||
// ensure that we have the data in cache before we manipulate it
|
||||
await this.fetch("obs", col);
|
||||
if (!this._cache.obs.hasCol(col))
|
||||
if (!(this as any)._cache.obs.hasCol(col))
|
||||
throw new Error("Internal error - user annotation data missing");
|
||||
|
||||
const rowIndices = this.rowIndex.getOffsets(rowLabels);
|
||||
const data = this._cache.obs.col(col).asArray().slice();
|
||||
const data = (this as any)._cache.obs.col(col).asArray().slice();
|
||||
for (let i = 0, len = rowIndices.length; i < len; i += 1) {
|
||||
const idx = rowIndices[i];
|
||||
if (idx === undefined) throw new Error("Unknown row label");
|
||||
@@ -171,7 +179,10 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
}
|
||||
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix._cache.obs = this._cache.obs.replaceColData(col, data);
|
||||
newAnnoMatrix._cache.obs = (this as any)._cache.obs.replaceColData(
|
||||
col,
|
||||
data
|
||||
);
|
||||
const { categories } = colSchema;
|
||||
if (!categories?.includes(value)) {
|
||||
newAnnoMatrix.schema = addObsAnnoCategory(this.schema, col, value);
|
||||
@@ -179,6 +190,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type.
|
||||
async resetObsColumnValues(col, oldValue, newValue) {
|
||||
/*
|
||||
Set all rows with value 'oldValue' to 'newValue'.
|
||||
@@ -192,16 +204,19 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
|
||||
// ensure that we have the data in cache before we manipulate it
|
||||
await this.fetch("obs", col);
|
||||
if (!this._cache.obs.hasCol(col))
|
||||
if (!(this as any)._cache.obs.hasCol(col))
|
||||
throw new Error("Internal error - user annotation data missing");
|
||||
|
||||
const data = this._cache.obs.col(col).asArray().slice();
|
||||
const data = (this as any)._cache.obs.col(col).asArray().slice();
|
||||
for (let i = 0, l = data.length; i < l; i += 1) {
|
||||
if (data[i] === oldValue) data[i] = newValue;
|
||||
}
|
||||
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix._cache.obs = this._cache.obs.replaceColData(col, data);
|
||||
newAnnoMatrix._cache.obs = (this as any)._cache.obs.replaceColData(
|
||||
col,
|
||||
data
|
||||
);
|
||||
const { categories } = colSchema;
|
||||
if (!categories?.includes(newValue)) {
|
||||
newAnnoMatrix.schema = addObsAnnoCategory(this.schema, col, newValue);
|
||||
@@ -209,6 +224,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
|
||||
addEmbedding(colSchema) {
|
||||
/*
|
||||
add new layout to the obs embeddings
|
||||
@@ -226,6 +242,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
/**
|
||||
** Private below
|
||||
**/
|
||||
// @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixLoader' is n... Remove this comment to see the full error message
|
||||
async _doLoad(field, query) {
|
||||
/*
|
||||
_doLoad - evaluates the query against the field. Returns:
|
||||
@@ -280,12 +297,14 @@ export default class AnnoMatrixLoader extends AnnoMatrix {
|
||||
Utility functions below
|
||||
*/
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
|
||||
function _writableCheck(colSchema) {
|
||||
if (!colSchema?.writable) {
|
||||
throw new Error("Unknown or readonly obs column");
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
|
||||
function _writableCategoryTypeCheck(colSchema) {
|
||||
_writableCheck(colSchema);
|
||||
if (colSchema.type !== "categorical") {
|
||||
@@ -293,6 +312,7 @@ function _writableCategoryTypeCheck(colSchema) {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type.
|
||||
function _embLoader(baseURL, _field, query) {
|
||||
_expectSimpleQuery(query);
|
||||
|
||||
@@ -302,6 +322,7 @@ function _embLoader(baseURL, _field, query) {
|
||||
return () => doBinaryRequest(url);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type.
|
||||
function _obsOrVarLoader(baseURL, field, query) {
|
||||
_expectSimpleQuery(query);
|
||||
|
||||
@@ -311,6 +332,7 @@ function _obsOrVarLoader(baseURL, field, query) {
|
||||
return () => doBinaryRequest(url);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type.
|
||||
function _XLoader(baseURL, field, query) {
|
||||
_expectComplexQuery(query);
|
||||
|
||||
@@ -11,7 +11,7 @@ Undoable metareducer and the AnnoMatrix private API. It would be helpful
|
||||
to make the Undoable interface better factored.
|
||||
*/
|
||||
|
||||
const annoMatrixGC = (store) => (next) => (action) => {
|
||||
const annoMatrixGC = (store: any) => (next: any) => (action: any) => {
|
||||
if (_itIsTimeForGC()) {
|
||||
_doGC(store);
|
||||
}
|
||||
@@ -34,7 +34,7 @@ function _itIsTimeForGC() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function _doGC(store) {
|
||||
function _doGC(store: any) {
|
||||
const state = store.getState();
|
||||
|
||||
// these should probably be a function imported from undoable.js, etc, as
|
||||
@@ -43,8 +43,8 @@ function _doGC(store) {
|
||||
const undoableFuture = state["@@undoable/future"];
|
||||
const undoableStack = undoablePast
|
||||
.concat(undoableFuture)
|
||||
.flatMap((snapshot) =>
|
||||
snapshot.filter((v) => v[0] === "annoMatrix").map((v) => v[1])
|
||||
.flatMap((snapshot: any) =>
|
||||
snapshot.filter((v: any) => v[0] === "annoMatrix").map((v: any) => v[1])
|
||||
);
|
||||
const currentAnnoMatrix = state.annoMatrix;
|
||||
|
||||
@@ -53,14 +53,16 @@ function _doGC(store) {
|
||||
as our current gc algo is more aggressive with those not hot.
|
||||
*/
|
||||
const allAnnoMatrices = new Map(
|
||||
undoableStack.map((m) => [m, { isHot: false }])
|
||||
undoableStack.map((m: any) => [m, { isHot: false }])
|
||||
);
|
||||
let am = currentAnnoMatrix;
|
||||
while (am) {
|
||||
allAnnoMatrices.set(am, { isHot: true });
|
||||
am = am.viewOf;
|
||||
}
|
||||
allAnnoMatrices.forEach((hints, annoMatrix) => annoMatrix._gc(hints));
|
||||
allAnnoMatrices.forEach((hints, annoMatrix) =>
|
||||
(annoMatrix as any)._gc(hints)
|
||||
);
|
||||
}
|
||||
|
||||
export default annoMatrixGC;
|
||||
@@ -10,7 +10,7 @@ import { _dubEncURIComp } from "./fetchHelpers";
|
||||
* @param {object | string} query - the query
|
||||
* @returns {object | string} - the normalized query
|
||||
*/
|
||||
export function _queryValidate(query) {
|
||||
export function _queryValidate(query: any) {
|
||||
if (typeof query !== "object") return query;
|
||||
|
||||
if (query.where && query.summarize)
|
||||
@@ -40,11 +40,11 @@ export function _queryValidate(query) {
|
||||
throw new Error("query must specify one of where or summarize");
|
||||
}
|
||||
|
||||
export function _expectSimpleQuery(query) {
|
||||
export function _expectSimpleQuery(query: any) {
|
||||
if (typeof query === "object") throw new Error("expected simple query");
|
||||
}
|
||||
|
||||
export function _expectComplexQuery(query) {
|
||||
export function _expectComplexQuery(query: any) {
|
||||
if (typeof query !== "object") throw new Error("expected complex query");
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ export function _expectComplexQuery(query) {
|
||||
* @param {string|object} query
|
||||
* @returns the key
|
||||
*/
|
||||
export function _queryCacheKey(field, query) {
|
||||
export function _queryCacheKey(field: any, query: any) {
|
||||
if (typeof query === "object") {
|
||||
// complex query
|
||||
if (query.where) {
|
||||
@@ -84,22 +84,22 @@ export function _queryCacheKey(field, query) {
|
||||
return `${field}/${query}`;
|
||||
}
|
||||
|
||||
function _urlEncodeWhereQuery(q) {
|
||||
function _urlEncodeWhereQuery(q: any) {
|
||||
const { field: queryField, column: queryColumn, value: queryValue } = q;
|
||||
return `${_dubEncURIComp(queryField)}:${_dubEncURIComp(
|
||||
queryColumn
|
||||
)}=${_dubEncURIComp(queryValue)}`;
|
||||
}
|
||||
|
||||
function _urlEncodeSummarizeQuery(q) {
|
||||
function _urlEncodeSummarizeQuery(q: any) {
|
||||
const { method, field, column, values } = q;
|
||||
const filter = values
|
||||
.map((value) => _urlEncodeWhereQuery({ field, column, value }))
|
||||
.map((value: any) => _urlEncodeWhereQuery({ field, column, value }))
|
||||
.join("&");
|
||||
return `method=${method}&${filter}`;
|
||||
}
|
||||
|
||||
export function _urlEncodeComplexQuery(q) {
|
||||
export function _urlEncodeComplexQuery(q: any) {
|
||||
if (typeof q === "object") {
|
||||
if (q.where) {
|
||||
return _urlEncodeWhereQuery(q.where);
|
||||
@@ -111,7 +111,7 @@ export function _urlEncodeComplexQuery(q) {
|
||||
throw new Error("Unrecognized complex query type");
|
||||
}
|
||||
|
||||
export function _urlEncodeLabelQuery(colKey, q) {
|
||||
export function _urlEncodeLabelQuery(colKey: any, q: any) {
|
||||
if (!colKey) throw new Error("Unsupported query by name");
|
||||
if (typeof q !== "string") throw new Error("Query must be a simple label.");
|
||||
return `${colKey}=${encodeURIComponent(q)}`;
|
||||
@@ -120,7 +120,7 @@ export function _urlEncodeLabelQuery(colKey, q) {
|
||||
/**
|
||||
* Generate the column key the server will send us for this query.
|
||||
*/
|
||||
export function _hashStringValues(arrayOfString) {
|
||||
export function _hashStringValues(arrayOfString: any) {
|
||||
const hash = sha1(arrayOfString.join(""));
|
||||
return hash;
|
||||
}
|
||||
@@ -4,7 +4,7 @@ Private helper functions related to schema
|
||||
import catLabelSort from "../util/catLabelSort";
|
||||
import { unassignedCategoryLabel } from "../globals";
|
||||
|
||||
export function _getColumnSchema(schema, field, col) {
|
||||
export function _getColumnSchema(schema: any, field: any, col: any) {
|
||||
/* look up the column definition */
|
||||
switch (field) {
|
||||
case "obs":
|
||||
@@ -26,7 +26,7 @@ export function _getColumnSchema(schema, field, col) {
|
||||
}
|
||||
}
|
||||
|
||||
export function _getColumnDimensionNames(schema, field, col) {
|
||||
export function _getColumnDimensionNames(schema: any, field: any, col: any) {
|
||||
/*
|
||||
field/col may be an alias for multiple columns. Currently used to map ND
|
||||
values to 1D dataframe columns for embeddings/layout. Signified by the presence
|
||||
@@ -39,6 +39,7 @@ export function _getColumnDimensionNames(schema, field, col) {
|
||||
return colSchema.dims || [col];
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
|
||||
export function _schemaColumns(schema, field) {
|
||||
switch (field) {
|
||||
case "obs":
|
||||
@@ -52,18 +53,25 @@ export function _schemaColumns(schema, field) {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
|
||||
export function _getWritableColumns(schema, field) {
|
||||
if (field !== "obs") return [];
|
||||
return schema.annotations.obs.columns
|
||||
.filter((v) => v.writable)
|
||||
.map((v) => v.name);
|
||||
return (
|
||||
schema.annotations.obs.columns
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'v' implicitly has an 'any' type.
|
||||
.filter((v) => v.writable)
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'v' implicitly has an 'any' type.
|
||||
.map((v) => v.name)
|
||||
);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type.
|
||||
export function _isContinuousType(schema) {
|
||||
const { type } = schema;
|
||||
return !(type === "string" || type === "boolean" || type === "categorical");
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message
|
||||
export function _normalizeCategoricalSchema(colSchema, col) {
|
||||
const { type, writable } = colSchema;
|
||||
if (
|
||||
@@ -5,7 +5,7 @@ instances of AnnoMatrix, implementing common UI functions.
|
||||
|
||||
import { AnnoMatrixRowSubsetView, AnnoMatrixClipView } from "./views";
|
||||
|
||||
export function isubsetMask(annoMatrix, obsMask) {
|
||||
export function isubsetMask(annoMatrix: any, obsMask: any) {
|
||||
/*
|
||||
Subset annomatrix to contain the rows which have truish value in the mask.
|
||||
Maks length must equal annoMatrix.nObs (row count).
|
||||
@@ -13,6 +13,7 @@ export function isubsetMask(annoMatrix, obsMask) {
|
||||
return isubset(annoMatrix, _maskToList(obsMask));
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
|
||||
export function isubset(annoMatrix, obsOffsets) {
|
||||
/*
|
||||
Subset annomatrix to contain the positions contained in the obsOffsets array
|
||||
@@ -25,6 +26,7 @@ export function isubset(annoMatrix, obsOffsets) {
|
||||
return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
|
||||
export function subset(annoMatrix, obsLabels) {
|
||||
/*
|
||||
subset based on labels
|
||||
@@ -33,6 +35,7 @@ export function subset(annoMatrix, obsLabels) {
|
||||
return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
|
||||
export function subsetByIndex(annoMatrix, obsIndex) {
|
||||
/*
|
||||
subset based upon the new obs index.
|
||||
@@ -40,6 +43,7 @@ export function subsetByIndex(annoMatrix, obsIndex) {
|
||||
return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message
|
||||
export function clip(annoMatrix, qmin, qmax) {
|
||||
/*
|
||||
Create a view that clips all continuous data to the [min, max] range.
|
||||
@@ -53,6 +57,7 @@ export function clip(annoMatrix, qmin, qmax) {
|
||||
Private utility functions below
|
||||
*/
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'mask' implicitly has an 'any' type.
|
||||
function _maskToList(mask) {
|
||||
/* convert masks to lists - method wastes space, but is fast */
|
||||
if (!mask) {
|
||||
@@ -9,21 +9,26 @@ import { _whereCacheCreate } from "./whereCache";
|
||||
import { _isContinuousType, _getColumnSchema } from "./schema";
|
||||
|
||||
class AnnoMatrixView extends AnnoMatrix {
|
||||
constructor(viewOf, rowIndex = null) {
|
||||
constructor(viewOf: any, rowIndex = null) {
|
||||
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
|
||||
const nObs = rowIndex ? rowIndex.size() : viewOf.nObs;
|
||||
super(viewOf.schema, nObs, viewOf.nVar, rowIndex || viewOf.rowIndex);
|
||||
this.viewOf = viewOf;
|
||||
this.isView = true;
|
||||
}
|
||||
|
||||
addObsAnnoCategory(col, category) {
|
||||
addObsAnnoCategory(col: any, category: any) {
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix.viewOf = this.viewOf.addObsAnnoCategory(col, category);
|
||||
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
async removeObsAnnoCategory(col, category, unassignedCategory) {
|
||||
async removeObsAnnoCategory(
|
||||
col: any,
|
||||
category: any,
|
||||
unassignedCategory: any
|
||||
) {
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix.viewOf = await this.viewOf.removeObsAnnoCategory(
|
||||
col,
|
||||
@@ -34,7 +39,7 @@ class AnnoMatrixView extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
dropObsColumn(col) {
|
||||
dropObsColumn(col: any) {
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix.viewOf = this.viewOf.dropObsColumn(col);
|
||||
newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col);
|
||||
@@ -42,21 +47,21 @@ class AnnoMatrixView extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
addObsColumn(colSchema, Ctor, value) {
|
||||
addObsColumn(colSchema: any, Ctor: any, value: any) {
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix.viewOf = this.viewOf.addObsColumn(colSchema, Ctor, value);
|
||||
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
renameObsColumn(oldCol, newCol) {
|
||||
renameObsColumn(oldCol: any, newCol: any) {
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix.viewOf = this.viewOf.renameObsColumn(oldCol, newCol);
|
||||
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
async setObsColumnValues(col, rowLabels, value) {
|
||||
async setObsColumnValues(col: any, rowLabels: any, value: any) {
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix.viewOf = await this.viewOf.setObsColumnValues(
|
||||
col,
|
||||
@@ -68,7 +73,7 @@ class AnnoMatrixView extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
async resetObsColumnValues(col, oldValue, newValue) {
|
||||
async resetObsColumnValues(col: any, oldValue: any, newValue: any) {
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix.viewOf = await this.viewOf.resetObsColumnValues(
|
||||
col,
|
||||
@@ -80,7 +85,7 @@ class AnnoMatrixView extends AnnoMatrix {
|
||||
return newAnnoMatrix;
|
||||
}
|
||||
|
||||
addEmbedding(colSchema) {
|
||||
addEmbedding(colSchema: any) {
|
||||
const newAnnoMatrix = this._clone();
|
||||
newAnnoMatrix.viewOf = this.viewOf.addEmbedding(colSchema);
|
||||
newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema;
|
||||
@@ -92,17 +97,20 @@ class AnnoMatrixMapView extends AnnoMatrixView {
|
||||
/*
|
||||
A view which knows how to transform its data.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type.
|
||||
constructor(viewOf, mapFn) {
|
||||
super(viewOf);
|
||||
this.mapFn = mapFn;
|
||||
(this as any).mapFn = mapFn;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixMapView' is ... Remove this comment to see the full error message
|
||||
async _doLoad(field, query) {
|
||||
const df = await this.viewOf._fetch(field, query);
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colData' implicitly has an 'any' type.
|
||||
const dfMapped = df.mapColumns((colData, colIdx) => {
|
||||
const colLabel = df.colIndex.getLabel(colIdx);
|
||||
const colSchema = _getColumnSchema(this.schema, field, colLabel);
|
||||
return this.mapFn(field, colLabel, colSchema, colData, df);
|
||||
return (this as any).mapFn(field, colLabel, colSchema, colData, df);
|
||||
});
|
||||
const whereCacheUpdate = _whereCacheCreate(
|
||||
field,
|
||||
@@ -117,12 +125,14 @@ export class AnnoMatrixClipView extends AnnoMatrixMapView {
|
||||
/*
|
||||
A view which is a clipped transformation of its parent
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type.
|
||||
constructor(viewOf, qmin, qmax) {
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
super(viewOf, (field, colLabel, colSchema, colData, df) =>
|
||||
_clipAnnoMatrix(field, colLabel, colSchema, colData, df, qmin, qmax)
|
||||
);
|
||||
this.isClipped = true;
|
||||
this.clipRange = [qmin, qmax];
|
||||
(this as any).isClipped = true;
|
||||
(this as any).clipRange = [qmin, qmax];
|
||||
Object.seal(this);
|
||||
}
|
||||
}
|
||||
@@ -131,11 +141,13 @@ export class AnnoMatrixRowSubsetView extends AnnoMatrixView {
|
||||
/*
|
||||
A view which is a subset of total rows.
|
||||
*/
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type.
|
||||
constructor(viewOf, rowIndex) {
|
||||
super(viewOf, rowIndex);
|
||||
Object.seal(this);
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixRowSubsetVie... Remove this comment to see the full error message
|
||||
async _doLoad(field, query) {
|
||||
const df = await this.viewOf._fetch(field, query);
|
||||
|
||||
@@ -158,6 +170,7 @@ export class AnnoMatrixRowSubsetView extends AnnoMatrixView {
|
||||
Utility functions below
|
||||
*/
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
function _clipAnnoMatrix(field, colLabel, colSchema, colData, df, qmin, qmax) {
|
||||
/* only clip obs and var scalar columns */
|
||||
if (field !== "obs" && field !== "X") return colData;
|
||||
@@ -51,7 +51,12 @@ creates a cache entry of:
|
||||
import { _getColumnDimensionNames } from "./schema";
|
||||
import { _hashStringValues } from "./query";
|
||||
|
||||
export function _whereCacheGet(whereCache, schema, field, query) {
|
||||
export function _whereCacheGet(
|
||||
whereCache: any,
|
||||
schema: any,
|
||||
field: any,
|
||||
query: any
|
||||
) {
|
||||
/*
|
||||
query will either be an where query (object) or a column name (string).
|
||||
|
||||
@@ -85,6 +90,7 @@ export function _whereCacheGet(whereCache, schema, field, query) {
|
||||
return _getColumnDimensionNames(schema, field, query) ?? [undefined];
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type.
|
||||
export function _whereCacheCreate(field, query, columnLabels) {
|
||||
/*
|
||||
Create a new whereCache
|
||||
@@ -131,10 +137,11 @@ export function _whereCacheCreate(field, query, columnLabels) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'dst' implicitly has an 'any' type.
|
||||
function __mergeQueries(dst, src) {
|
||||
for (const [queryField, columnMap] of Object.entries(src)) {
|
||||
dst[queryField] = dst[queryField] || new Map();
|
||||
for (const [queryColumn, valueMap] of columnMap) {
|
||||
for (const [queryColumn, valueMap] of columnMap as any) {
|
||||
if (!dst[queryField].has(queryColumn))
|
||||
dst[queryField].set(queryColumn, new Map());
|
||||
for (const [queryValue, columnLabels] of valueMap) {
|
||||
@@ -144,6 +151,7 @@ function __mergeQueries(dst, src) {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'dst' implicitly has an 'any' type.
|
||||
function __whereCacheMerge(dst, src) {
|
||||
/*
|
||||
merge src into dst (modifies dst)
|
||||
@@ -161,6 +169,7 @@ function __whereCacheMerge(dst, src) {
|
||||
dst.summarize = dst.summarize || {};
|
||||
for (const [field, method] of Object.entries(src.summarize)) {
|
||||
dst.summarize[field] = dst.summarize[field] || {};
|
||||
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
|
||||
for (const [methodName, query] of Object.entries(method)) {
|
||||
dst.summarize[field][methodName] =
|
||||
dst.summarize[field][methodName] || {};
|
||||
@@ -171,6 +180,7 @@ function __whereCacheMerge(dst, src) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
// @ts-expect-error ts-migrate(7019) FIXME: Rest parameter 'caches' implicitly has an 'any[]' ... Remove this comment to see the full error message
|
||||
export function _whereCacheMerge(...caches) {
|
||||
return caches.reduce(__whereCacheMerge, {});
|
||||
}
|
||||
Reference in New Issue
Block a user