mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-04 08:18: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
@@ -0,0 +1,141 @@
|
||||
import sortBy from "lodash.sortby";
|
||||
/* XXX: cough, cough, ... */
|
||||
import { postNetworkErrorToast } from "../components/framework/toasters";
|
||||
|
||||
/*
|
||||
dispatch an action error to the user. Currently we use
|
||||
async toasts.
|
||||
*/
|
||||
let networkErrorToastKey: any = null;
|
||||
export const dispatchNetworkErrorMessageToUser = (message: any) => {
|
||||
if (!networkErrorToastKey) {
|
||||
networkErrorToastKey = postNetworkErrorToast(message);
|
||||
} else {
|
||||
postNetworkErrorToast(message, networkErrorToastKey);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Catch unexpected errors and make sure we don't lose them!
|
||||
*/
|
||||
export function catchErrorsWrap(fn: any, dispatchToUser = false) {
|
||||
return (dispatch: any, getState: any) => {
|
||||
fn(dispatch, getState).catch((error: any) => {
|
||||
console.error(error);
|
||||
if (dispatchToUser) {
|
||||
dispatchNetworkErrorMessageToUser(error.message);
|
||||
}
|
||||
dispatch({ type: "UNEXPECTED ERROR", error });
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to perform async fetch with some modest error handling
|
||||
* and decoding. Arguments are identical to standard fetch.
|
||||
*/
|
||||
export const doFetch = async (url: any, init = {}) => {
|
||||
try {
|
||||
// add defaults to the fetch init param.
|
||||
init = {
|
||||
method: "get",
|
||||
credentials: "include",
|
||||
...init,
|
||||
};
|
||||
const acceptType = (init as any).headers?.get("Accept");
|
||||
const res = await fetch(url, init);
|
||||
if (
|
||||
res.ok &&
|
||||
// @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
|
||||
(!acceptType || res.headers.get("Content-Type").includes(acceptType))
|
||||
) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// else an error
|
||||
const msg = `Unexpected HTTP response ${res.status}, ${res.statusText}`;
|
||||
dispatchNetworkErrorMessageToUser(msg);
|
||||
throw new Error(msg);
|
||||
} catch (e) {
|
||||
// network error
|
||||
const msg = "Unexpected HTTP error";
|
||||
dispatchNetworkErrorMessageToUser(msg);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Wrapper to perform an async fetch and JSON decode response.
|
||||
*/
|
||||
export const doJsonRequest = async (url: any, init = {}) => {
|
||||
const res = await doFetch(url, {
|
||||
...init,
|
||||
headers: new Headers({ Accept: "application/json" }),
|
||||
});
|
||||
return res.json();
|
||||
};
|
||||
|
||||
/*
|
||||
Wrapper to perform an async fetch for binary data.
|
||||
*/
|
||||
export const doBinaryRequest = async (url: any, init = {}) => {
|
||||
const res = await doFetch(url, {
|
||||
...init,
|
||||
headers: new Headers({ Accept: "application/octet-stream" }),
|
||||
});
|
||||
return res.arrayBuffer();
|
||||
};
|
||||
|
||||
/*
|
||||
This function "packs" filter index lists into the more efficient
|
||||
"range" form specified in the REST 0.2 spec.
|
||||
|
||||
Specifically, it turns an array of indices [0, 1, 2, 10, 11, 14, ...]
|
||||
into a form that encodes runs of consecutive numbers as [min, max].
|
||||
Array may not be sorted, but will only contain uniq values.
|
||||
|
||||
Parameters:
|
||||
indices - input array of numbers (index)
|
||||
minRangeLength - hint, min range length before it is encoded into range format.
|
||||
sorted - boolean hint indicating array is presorted, ascending order
|
||||
|
||||
So [1, 2, 3, 4, 10, 11, 14] -> [ [1, 4], [10, 11], 14]
|
||||
*/
|
||||
export const rangeEncodeIndices = (
|
||||
indices: any,
|
||||
minRangeLength = 3,
|
||||
sorted = false
|
||||
) => {
|
||||
if (indices.length === 0) {
|
||||
return indices;
|
||||
}
|
||||
|
||||
if (!sorted) {
|
||||
indices = sortBy(indices);
|
||||
}
|
||||
|
||||
const result = new Array(indices.length);
|
||||
let resultTail = 0;
|
||||
|
||||
let i = 0;
|
||||
while (i < indices.length) {
|
||||
const begin = indices[i];
|
||||
let current;
|
||||
do {
|
||||
current = indices[i];
|
||||
i += 1;
|
||||
} while (i < indices.length && indices[i] === current + 1);
|
||||
|
||||
if (current - begin + 1 >= minRangeLength) {
|
||||
result[resultTail] = [begin, current];
|
||||
resultTail += 1;
|
||||
} else {
|
||||
for (let j = begin; j <= current; j += 1, resultTail += 1) {
|
||||
result[resultTail] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.length = resultTail;
|
||||
return result;
|
||||
};
|
||||
Reference in New Issue
Block a user