@haniffalab/cherita-react 1.4.4 → 1.4.6-dev.2026-01-12.f157a881
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/dist/cjs/components/obsm-list/ObsmList.js +32 -31
- package/dist/cjs/components/var-list/VarItem.js +3 -5
- package/dist/cjs/components/var-list/VarSet.js +4 -6
- package/dist/cjs/context/DatasetContext.js +1 -1
- package/dist/cjs/context/SettingsContext.js +2 -2
- package/dist/cjs/helpers/zarr-helper.js +25 -35
- package/dist/cjs/utils/zarrData.js +6 -6
- package/dist/esm/components/obsm-list/ObsmList.js +33 -32
- package/dist/esm/components/var-list/VarItem.js +4 -6
- package/dist/esm/components/var-list/VarSet.js +5 -7
- package/dist/esm/context/DatasetContext.js +1 -1
- package/dist/esm/context/SettingsContext.js +2 -2
- package/dist/esm/helpers/zarr-helper.js +22 -34
- package/dist/esm/utils/zarrData.js +6 -6
- package/package.json +7 -4
|
@@ -14,11 +14,6 @@ var _requests = require("../../utils/requests");
|
|
|
14
14
|
var _Skeleton = require("../../utils/Skeleton");
|
|
15
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
|
-
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
19
|
-
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
20
|
-
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
21
|
-
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
22
17
|
function ObsmKeysList(_ref) {
|
|
23
18
|
let {
|
|
24
19
|
setHasObsm
|
|
@@ -27,18 +22,11 @@ function ObsmKeysList(_ref) {
|
|
|
27
22
|
const dataset = (0, _DatasetContext.useDataset)();
|
|
28
23
|
const settings = (0, _SettingsContext.useSettings)();
|
|
29
24
|
const dispatch = (0, _SettingsContext.useSettingsDispatch)();
|
|
30
|
-
const [
|
|
25
|
+
const [keysList, setKeysList] = (0, _react.useState)([]);
|
|
31
26
|
const [active, setActive] = (0, _react.useState)(null);
|
|
32
|
-
const
|
|
27
|
+
const params = (0, _react.useMemo)(() => ({
|
|
33
28
|
url: dataset.url
|
|
34
|
-
});
|
|
35
|
-
(0, _react.useEffect)(() => {
|
|
36
|
-
setParams(p => {
|
|
37
|
-
return _objectSpread(_objectSpread({}, p), {}, {
|
|
38
|
-
url: dataset.url
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
}, [dataset.url]);
|
|
29
|
+
}), [dataset.url]);
|
|
42
30
|
const {
|
|
43
31
|
fetchedData,
|
|
44
32
|
isPending,
|
|
@@ -48,17 +36,34 @@ function ObsmKeysList(_ref) {
|
|
|
48
36
|
});
|
|
49
37
|
(0, _react.useEffect)(() => {
|
|
50
38
|
if (!isPending && !serverError) {
|
|
51
|
-
|
|
39
|
+
const obsmKeysArray = Array.isArray(fetchedData) ? fetchedData : [];
|
|
40
|
+
if (obsmKeysArray.length === 0) {
|
|
52
41
|
setHasObsm(false);
|
|
42
|
+
setKeysList([]);
|
|
43
|
+
if (settings.selectedObsm) {
|
|
44
|
+
dispatch({
|
|
45
|
+
type: 'select.obsm',
|
|
46
|
+
obsm: null
|
|
47
|
+
});
|
|
48
|
+
}
|
|
53
49
|
} else {
|
|
54
50
|
setHasObsm(true);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
setKeysList(obsmKeysArray);
|
|
52
|
+
if (settings.selectedObsm) {
|
|
53
|
+
// If selected obsm is not in keys list, reset to null
|
|
54
|
+
if (!_lodash.default.includes(obsmKeysArray, settings.selectedObsm)) {
|
|
55
|
+
dispatch({
|
|
56
|
+
type: 'select.obsm',
|
|
57
|
+
obsm: null
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
setActive(settings.selectedObsm);
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
// Set default obsm if in keys list and not selected
|
|
59
64
|
// Follow DEFAULT_OBSM_KEYS order
|
|
60
65
|
_lodash.default.each(_constants.DEFAULT_OBSM_KEYS, k => {
|
|
61
|
-
const defaultObsm = _lodash.default.find(
|
|
66
|
+
const defaultObsm = _lodash.default.find(obsmKeysArray, item => item.toLowerCase() === k);
|
|
62
67
|
if (defaultObsm) {
|
|
63
68
|
dispatch({
|
|
64
69
|
type: 'select.obsm',
|
|
@@ -69,20 +74,16 @@ function ObsmKeysList(_ref) {
|
|
|
69
74
|
});
|
|
70
75
|
}
|
|
71
76
|
}
|
|
77
|
+
} else if (!isPending && serverError) {
|
|
72
78
|
if (settings.selectedObsm) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
obsm: null
|
|
78
|
-
});
|
|
79
|
-
} else {
|
|
80
|
-
setActive(settings.selectedObsm);
|
|
81
|
-
}
|
|
79
|
+
dispatch({
|
|
80
|
+
type: 'select.obsm',
|
|
81
|
+
obsm: null
|
|
82
|
+
});
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
}, [dispatch, fetchedData, isPending, serverError, setHasObsm, settings.selectedObsm]);
|
|
85
|
-
const obsmList =
|
|
86
|
+
const obsmList = keysList.map(item => {
|
|
86
87
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Dropdown.Item, {
|
|
87
88
|
className: "custom ".concat(active === item && 'active'),
|
|
88
89
|
onClick: () => {
|
|
@@ -165,13 +165,11 @@ function SelectionItem(_ref3) {
|
|
|
165
165
|
selectVar();
|
|
166
166
|
},
|
|
167
167
|
disabled: isNotInData,
|
|
168
|
-
title: isNotInData ? 'Not present in data' : 'Set as color encoding',
|
|
169
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
|
|
168
|
+
title: isNotInData ? 'Not present in data' : isMultiple ? isActive ? 'Remove from plot' : 'Add to plot' : 'Set as color encoding',
|
|
169
|
+
children: [!isMultiple && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
|
|
170
170
|
icon: _freeSolidSvgIcons.faDroplet
|
|
171
171
|
}), isMultiple && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
|
|
172
|
-
icon: _freeSolidSvgIcons.
|
|
173
|
-
size: "xs",
|
|
174
|
-
className: "ps-xs-1"
|
|
172
|
+
icon: _freeSolidSvgIcons.faCheck
|
|
175
173
|
})]
|
|
176
174
|
}, item.matrix_index), showRemove && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
|
|
177
175
|
type: "button",
|
|
@@ -9,10 +9,10 @@ var _freeSolidSvgIcons = require("@fortawesome/free-solid-svg-icons");
|
|
|
9
9
|
var _reactFontawesome = require("@fortawesome/react-fontawesome");
|
|
10
10
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
11
11
|
var _reactBootstrap = require("react-bootstrap");
|
|
12
|
-
var _VarItem = require("./VarItem");
|
|
13
12
|
var _constants = require("../../constants/constants");
|
|
14
13
|
var _SettingsContext = require("../../context/SettingsContext");
|
|
15
14
|
var _SearchBar = require("../search-bar/SearchBar");
|
|
15
|
+
var _VarItem = require("./VarItem");
|
|
16
16
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
17
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
18
|
// @TODO: add button to score genes and plot
|
|
@@ -101,13 +101,11 @@ function SelectionSet(_ref) {
|
|
|
101
101
|
selectSet();
|
|
102
102
|
},
|
|
103
103
|
disabled: !set.vars.length,
|
|
104
|
-
title:
|
|
105
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
|
|
104
|
+
title: !set.vars.length ? 'No variables in set' : isMultiple ? isActive ? 'Remove from plot' : 'Add to plot' : 'Set as color encoding',
|
|
105
|
+
children: [!isMultiple && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
|
|
106
106
|
icon: _freeSolidSvgIcons.faDroplet
|
|
107
107
|
}), isMultiple && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactFontawesome.FontAwesomeIcon, {
|
|
108
|
-
icon: _freeSolidSvgIcons.
|
|
109
|
-
size: "xs",
|
|
110
|
-
className: "ps-xs-1"
|
|
108
|
+
icon: _freeSolidSvgIcons.faCheck
|
|
111
109
|
})]
|
|
112
110
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactBootstrap.Button, {
|
|
113
111
|
type: "button",
|
|
@@ -173,7 +173,7 @@ function SettingsProvider(_ref2) {
|
|
|
173
173
|
|
|
174
174
|
// If the buster is not set or does not match the current package version,
|
|
175
175
|
// reset localSettings to avoid stale data
|
|
176
|
-
if (!buster || buster !== "1.4.
|
|
176
|
+
if (!buster || buster !== "1.4.6-dev.2026-01-12.f157a881") {
|
|
177
177
|
localSettings = {};
|
|
178
178
|
}
|
|
179
179
|
const initSettings = (0, _react.useRef)(initializer({
|
|
@@ -198,7 +198,7 @@ function SettingsProvider(_ref2) {
|
|
|
198
198
|
if (canOverrideSettings && settings) {
|
|
199
199
|
try {
|
|
200
200
|
localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread({
|
|
201
|
-
buster: "1.4.
|
|
201
|
+
buster: "1.4.6-dev.2026-01-12.f157a881" || '0.0.0',
|
|
202
202
|
timestamp: Date.now()
|
|
203
203
|
}, _lodash.default.omit(settings, 'data'))));
|
|
204
204
|
} catch (err) {
|
|
@@ -3,69 +3,60 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.useZarr = exports.useMultipleZarr = exports.ZarrHelper =
|
|
6
|
+
exports.useZarr = exports.useMultipleZarr = exports.ZarrHelper = void 0;
|
|
7
7
|
var _react = require("react");
|
|
8
8
|
var _reactQuery = require("@tanstack/react-query");
|
|
9
|
-
var
|
|
9
|
+
var zarr = _interopRequireWildcard(require("zarrita"));
|
|
10
|
+
var _ndarray = require("@zarrita/ndarray");
|
|
11
|
+
var _ndarrayUnpack = _interopRequireDefault(require("ndarray-unpack"));
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
10
14
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11
15
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
12
16
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
13
17
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
14
18
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
15
|
-
const GET_OPTIONS = exports.GET_OPTIONS = {
|
|
16
|
-
concurrencyLimit: 10,
|
|
17
|
-
// max number of concurrent requests (default 10)
|
|
18
|
-
progressCallback: _ref => {
|
|
19
|
-
let {
|
|
20
|
-
progress,
|
|
21
|
-
queueSize
|
|
22
|
-
} = _ref;
|
|
23
|
-
console.debug("".concat(progress / queueSize * 100, "% complete."));
|
|
24
|
-
} // callback executed after each request
|
|
25
|
-
};
|
|
26
19
|
class ZarrHelper {
|
|
27
20
|
async open(url, path) {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
path: path,
|
|
31
|
-
mode: 'r'
|
|
32
|
-
});
|
|
21
|
+
const root = zarr.root(new zarr.FetchStore(url));
|
|
22
|
+
const z = await zarr.open(root.resolve(path));
|
|
33
23
|
return z;
|
|
34
24
|
}
|
|
35
25
|
}
|
|
36
26
|
exports.ZarrHelper = ZarrHelper;
|
|
37
|
-
const fetchDataFromZarr = async (url, path, s
|
|
27
|
+
const fetchDataFromZarr = async (url, path, s) => {
|
|
38
28
|
try {
|
|
39
29
|
const zarrHelper = new ZarrHelper();
|
|
40
30
|
const z = await zarrHelper.open(url, path);
|
|
41
|
-
const result = await
|
|
42
|
-
|
|
31
|
+
const result = await (0, _ndarray.get)(z, s);
|
|
32
|
+
if (result.dtype === 'bigint64') throw new Error('bigint64 dtype not supported');
|
|
33
|
+
const arr = (0, _ndarrayUnpack.default)(result);
|
|
34
|
+
return arr;
|
|
43
35
|
} catch (error) {
|
|
44
|
-
if (error instanceof
|
|
36
|
+
if (error instanceof zarr.NodeNotFoundError) {
|
|
45
37
|
error.status = 404;
|
|
46
38
|
}
|
|
47
39
|
throw error;
|
|
48
40
|
}
|
|
49
41
|
};
|
|
50
|
-
const useZarr = function (
|
|
42
|
+
const useZarr = function (_ref) {
|
|
51
43
|
let {
|
|
52
44
|
url,
|
|
53
45
|
path,
|
|
54
46
|
s = null
|
|
55
|
-
} =
|
|
56
|
-
let
|
|
57
|
-
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
47
|
+
} = _ref;
|
|
48
|
+
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
58
49
|
const {
|
|
59
50
|
data = null,
|
|
60
51
|
isLoading: isPending = false,
|
|
61
52
|
error: serverError = null
|
|
62
53
|
} = (0, _reactQuery.useQuery)(_objectSpread({
|
|
63
54
|
queryKey: ['zarr', url, path, s],
|
|
64
|
-
queryFn: () => fetchDataFromZarr(url, path, s
|
|
65
|
-
retry: (failureCount,
|
|
55
|
+
queryFn: () => fetchDataFromZarr(url, path, s),
|
|
56
|
+
retry: (failureCount, _ref2) => {
|
|
66
57
|
let {
|
|
67
58
|
error
|
|
68
|
-
} =
|
|
59
|
+
} = _ref2;
|
|
69
60
|
if ([400, 401, 403, 404, 422].includes(error === null || error === void 0 ? void 0 : error.status)) return false;
|
|
70
61
|
return failureCount < 3;
|
|
71
62
|
}
|
|
@@ -86,9 +77,8 @@ const aggregateData = (inputs, data) => {
|
|
|
86
77
|
return dataObject;
|
|
87
78
|
};
|
|
88
79
|
const useMultipleZarr = function (inputs) {
|
|
89
|
-
let
|
|
90
|
-
let
|
|
91
|
-
let agg = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : aggregateData;
|
|
80
|
+
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
81
|
+
let agg = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : aggregateData;
|
|
92
82
|
const combine = (0, _react.useCallback)(results => {
|
|
93
83
|
return {
|
|
94
84
|
data: agg(inputs, results.map(result => result.data)),
|
|
@@ -103,11 +93,11 @@ const useMultipleZarr = function (inputs) {
|
|
|
103
93
|
} = (0, _reactQuery.useQueries)({
|
|
104
94
|
queries: inputs.map(input => _objectSpread({
|
|
105
95
|
queryKey: ['zarr', input.url, input.path, input.s],
|
|
106
|
-
queryFn: () => fetchDataFromZarr(input.url, input.path, input.s
|
|
107
|
-
retry: (failureCount,
|
|
96
|
+
queryFn: () => fetchDataFromZarr(input.url, input.path, input.s),
|
|
97
|
+
retry: (failureCount, _ref3) => {
|
|
108
98
|
let {
|
|
109
99
|
error
|
|
110
|
-
} =
|
|
100
|
+
} = _ref3;
|
|
111
101
|
if ([400, 401, 403, 404, 422].includes(error === null || error === void 0 ? void 0 : error.status)) return false;
|
|
112
102
|
return failureCount < 3;
|
|
113
103
|
}
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.useXData = exports.useObsmData = exports.useObsData = exports.useLabelObsData = void 0;
|
|
7
7
|
var _react = require("react");
|
|
8
8
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
|
-
var
|
|
9
|
+
var _zarrita = require("zarrita");
|
|
10
10
|
var _Resolver = require("./Resolver");
|
|
11
11
|
var _constants = require("../constants/constants");
|
|
12
12
|
var _DatasetContext = require("../context/DatasetContext");
|
|
@@ -22,9 +22,9 @@ const useObsmData = function () {
|
|
|
22
22
|
const obsmParams = (0, _react.useMemo)(() => ({
|
|
23
23
|
url: dataset.url,
|
|
24
24
|
path: 'obsm/' + obsm,
|
|
25
|
-
s: [null, (0,
|
|
25
|
+
s: [null, (0, _zarrita.slice)(null, 2)] // load only [:, :2]
|
|
26
26
|
}), [dataset.url, obsm]);
|
|
27
|
-
return (0, _zarrHelper.useZarr)(obsmParams,
|
|
27
|
+
return (0, _zarrHelper.useZarr)(obsmParams, {
|
|
28
28
|
enabled: !!obsm
|
|
29
29
|
});
|
|
30
30
|
};
|
|
@@ -52,7 +52,7 @@ const useXData = function () {
|
|
|
52
52
|
s: [null, v.matrix_index]
|
|
53
53
|
};
|
|
54
54
|
}), [dataset.url, selectedVar]);
|
|
55
|
-
return (0, _zarrHelper.useMultipleZarr)(xParams,
|
|
55
|
+
return (0, _zarrHelper.useMultipleZarr)(xParams, {
|
|
56
56
|
enabled: !!xParams.length
|
|
57
57
|
}, agg);
|
|
58
58
|
};
|
|
@@ -70,7 +70,7 @@ const useObsData = function () {
|
|
|
70
70
|
path: 'obs/' + ((_obs = obs) === null || _obs === void 0 ? void 0 : _obs.name) + (((_obs2 = obs) === null || _obs2 === void 0 ? void 0 : _obs2.type) === _constants.OBS_TYPES.CATEGORICAL ? '/codes' : '')
|
|
71
71
|
};
|
|
72
72
|
}, [dataset.url, (_obs3 = obs) === null || _obs3 === void 0 ? void 0 : _obs3.name, (_obs4 = obs) === null || _obs4 === void 0 ? void 0 : _obs4.type]);
|
|
73
|
-
return (0, _zarrHelper.useZarr)(obsParams,
|
|
73
|
+
return (0, _zarrHelper.useZarr)(obsParams, {
|
|
74
74
|
enabled: !!obs
|
|
75
75
|
});
|
|
76
76
|
};
|
|
@@ -86,7 +86,7 @@ const useLabelObsData = () => {
|
|
|
86
86
|
key: obs.name
|
|
87
87
|
};
|
|
88
88
|
}), [dataset.url, settings.data.obs, settings.labelObs]);
|
|
89
|
-
return (0, _zarrHelper.useMultipleZarr)(labelObsParams,
|
|
89
|
+
return (0, _zarrHelper.useMultipleZarr)(labelObsParams, {
|
|
90
90
|
enabled: !!labelObsParams.length
|
|
91
91
|
});
|
|
92
92
|
};
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
3
|
-
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
4
|
-
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
5
|
-
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
|
-
import { useEffect, useState } from 'react';
|
|
1
|
+
import { useEffect, useState, useMemo } from 'react';
|
|
7
2
|
import _ from 'lodash';
|
|
8
3
|
import { Button, ButtonGroup, Dropdown, DropdownButton, OverlayTrigger, Tooltip } from 'react-bootstrap';
|
|
9
4
|
import { DEFAULT_OBSM_KEYS } from '../../constants/constants';
|
|
@@ -20,18 +15,11 @@ export function ObsmKeysList(_ref) {
|
|
|
20
15
|
const dataset = useDataset();
|
|
21
16
|
const settings = useSettings();
|
|
22
17
|
const dispatch = useSettingsDispatch();
|
|
23
|
-
const [
|
|
18
|
+
const [keysList, setKeysList] = useState([]);
|
|
24
19
|
const [active, setActive] = useState(null);
|
|
25
|
-
const
|
|
20
|
+
const params = useMemo(() => ({
|
|
26
21
|
url: dataset.url
|
|
27
|
-
});
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
setParams(p => {
|
|
30
|
-
return _objectSpread(_objectSpread({}, p), {}, {
|
|
31
|
-
url: dataset.url
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
}, [dataset.url]);
|
|
22
|
+
}), [dataset.url]);
|
|
35
23
|
const {
|
|
36
24
|
fetchedData,
|
|
37
25
|
isPending,
|
|
@@ -41,17 +29,34 @@ export function ObsmKeysList(_ref) {
|
|
|
41
29
|
});
|
|
42
30
|
useEffect(() => {
|
|
43
31
|
if (!isPending && !serverError) {
|
|
44
|
-
|
|
32
|
+
const obsmKeysArray = Array.isArray(fetchedData) ? fetchedData : [];
|
|
33
|
+
if (obsmKeysArray.length === 0) {
|
|
45
34
|
setHasObsm(false);
|
|
35
|
+
setKeysList([]);
|
|
36
|
+
if (settings.selectedObsm) {
|
|
37
|
+
dispatch({
|
|
38
|
+
type: 'select.obsm',
|
|
39
|
+
obsm: null
|
|
40
|
+
});
|
|
41
|
+
}
|
|
46
42
|
} else {
|
|
47
43
|
setHasObsm(true);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
setKeysList(obsmKeysArray);
|
|
45
|
+
if (settings.selectedObsm) {
|
|
46
|
+
// If selected obsm is not in keys list, reset to null
|
|
47
|
+
if (!_.includes(obsmKeysArray, settings.selectedObsm)) {
|
|
48
|
+
dispatch({
|
|
49
|
+
type: 'select.obsm',
|
|
50
|
+
obsm: null
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
setActive(settings.selectedObsm);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
// Set default obsm if in keys list and not selected
|
|
52
57
|
// Follow DEFAULT_OBSM_KEYS order
|
|
53
58
|
_.each(DEFAULT_OBSM_KEYS, k => {
|
|
54
|
-
const defaultObsm = _.find(
|
|
59
|
+
const defaultObsm = _.find(obsmKeysArray, item => item.toLowerCase() === k);
|
|
55
60
|
if (defaultObsm) {
|
|
56
61
|
dispatch({
|
|
57
62
|
type: 'select.obsm',
|
|
@@ -62,20 +67,16 @@ export function ObsmKeysList(_ref) {
|
|
|
62
67
|
});
|
|
63
68
|
}
|
|
64
69
|
}
|
|
70
|
+
} else if (!isPending && serverError) {
|
|
65
71
|
if (settings.selectedObsm) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
obsm: null
|
|
71
|
-
});
|
|
72
|
-
} else {
|
|
73
|
-
setActive(settings.selectedObsm);
|
|
74
|
-
}
|
|
72
|
+
dispatch({
|
|
73
|
+
type: 'select.obsm',
|
|
74
|
+
obsm: null
|
|
75
|
+
});
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
}, [dispatch, fetchedData, isPending, serverError, setHasObsm, settings.selectedObsm]);
|
|
78
|
-
const obsmList =
|
|
79
|
+
const obsmList = keysList.map(item => {
|
|
79
80
|
return /*#__PURE__*/_jsx(Dropdown.Item, {
|
|
80
81
|
className: "custom ".concat(active === item && 'active'),
|
|
81
82
|
onClick: () => {
|
|
@@ -4,7 +4,7 @@ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object
|
|
|
4
4
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
5
5
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
6
|
import { useEffect, useState } from 'react';
|
|
7
|
-
import {
|
|
7
|
+
import { faCheck, faDroplet, faTrash } from '@fortawesome/free-solid-svg-icons';
|
|
8
8
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
9
9
|
import { MoreVert } from '@mui/icons-material';
|
|
10
10
|
import _ from 'lodash';
|
|
@@ -156,13 +156,11 @@ export function SelectionItem(_ref3) {
|
|
|
156
156
|
selectVar();
|
|
157
157
|
},
|
|
158
158
|
disabled: isNotInData,
|
|
159
|
-
title: isNotInData ? 'Not present in data' : 'Set as color encoding',
|
|
160
|
-
children: [/*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
159
|
+
title: isNotInData ? 'Not present in data' : isMultiple ? isActive ? 'Remove from plot' : 'Add to plot' : 'Set as color encoding',
|
|
160
|
+
children: [!isMultiple && /*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
161
161
|
icon: faDroplet
|
|
162
162
|
}), isMultiple && /*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
163
|
-
icon:
|
|
164
|
-
size: "xs",
|
|
165
|
-
className: "ps-xs-1"
|
|
163
|
+
icon: faCheck
|
|
166
164
|
})]
|
|
167
165
|
}, item.matrix_index), showRemove && /*#__PURE__*/_jsx(Button, {
|
|
168
166
|
type: "button",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import { faChevronDown, faChevronUp, faCircleInfo, faDroplet, faPlus, faTrash } from '@fortawesome/free-solid-svg-icons';
|
|
2
|
+
import { faCheck, faChevronDown, faChevronUp, faCircleInfo, faDroplet, faPlus, faTrash } from '@fortawesome/free-solid-svg-icons';
|
|
3
3
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
4
4
|
import _ from 'lodash';
|
|
5
5
|
import { Button, Collapse, ListGroup, OverlayTrigger, Tooltip } from 'react-bootstrap';
|
|
6
|
-
import { SelectionItem } from './VarItem';
|
|
7
6
|
import { COLOR_ENCODINGS, SELECTION_MODES } from '../../constants/constants';
|
|
8
7
|
import { useSettings, useSettingsDispatch } from '../../context/SettingsContext';
|
|
9
8
|
import { SearchModal } from '../search-bar/SearchBar';
|
|
9
|
+
import { SelectionItem } from './VarItem';
|
|
10
10
|
|
|
11
11
|
// @TODO: add button to score genes and plot
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
@@ -95,13 +95,11 @@ function SelectionSet(_ref) {
|
|
|
95
95
|
selectSet();
|
|
96
96
|
},
|
|
97
97
|
disabled: !set.vars.length,
|
|
98
|
-
title:
|
|
99
|
-
children: [/*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
98
|
+
title: !set.vars.length ? 'No variables in set' : isMultiple ? isActive ? 'Remove from plot' : 'Add to plot' : 'Set as color encoding',
|
|
99
|
+
children: [!isMultiple && /*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
100
100
|
icon: faDroplet
|
|
101
101
|
}), isMultiple && /*#__PURE__*/_jsx(FontAwesomeIcon, {
|
|
102
|
-
icon:
|
|
103
|
-
size: "xs",
|
|
104
|
-
className: "ps-xs-1"
|
|
102
|
+
icon: faCheck
|
|
105
103
|
})]
|
|
106
104
|
}), /*#__PURE__*/_jsx(Button, {
|
|
107
105
|
type: "button",
|
|
@@ -163,7 +163,7 @@ export function SettingsProvider(_ref2) {
|
|
|
163
163
|
|
|
164
164
|
// If the buster is not set or does not match the current package version,
|
|
165
165
|
// reset localSettings to avoid stale data
|
|
166
|
-
if (!buster || buster !== "1.4.
|
|
166
|
+
if (!buster || buster !== "1.4.6-dev.2026-01-12.f157a881") {
|
|
167
167
|
localSettings = {};
|
|
168
168
|
}
|
|
169
169
|
const initSettings = useRef(initializer({
|
|
@@ -188,7 +188,7 @@ export function SettingsProvider(_ref2) {
|
|
|
188
188
|
if (canOverrideSettings && settings) {
|
|
189
189
|
try {
|
|
190
190
|
localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread({
|
|
191
|
-
buster: "1.4.
|
|
191
|
+
buster: "1.4.6-dev.2026-01-12.f157a881" || '0.0.0',
|
|
192
192
|
timestamp: Date.now()
|
|
193
193
|
}, _.omit(settings, 'data'))));
|
|
194
194
|
} catch (err) {
|
|
@@ -5,60 +5,49 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
5
5
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
6
|
import { useCallback } from 'react';
|
|
7
7
|
import { useQueries, useQuery } from '@tanstack/react-query';
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// max number of concurrent requests (default 10)
|
|
12
|
-
progressCallback: _ref => {
|
|
13
|
-
let {
|
|
14
|
-
progress,
|
|
15
|
-
queueSize
|
|
16
|
-
} = _ref;
|
|
17
|
-
console.debug("".concat(progress / queueSize * 100, "% complete."));
|
|
18
|
-
} // callback executed after each request
|
|
19
|
-
};
|
|
8
|
+
import * as zarr from 'zarrita';
|
|
9
|
+
import { get } from '@zarrita/ndarray';
|
|
10
|
+
import unpack from 'ndarray-unpack';
|
|
20
11
|
export class ZarrHelper {
|
|
21
12
|
async open(url, path) {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
path: path,
|
|
25
|
-
mode: 'r'
|
|
26
|
-
});
|
|
13
|
+
const root = zarr.root(new zarr.FetchStore(url));
|
|
14
|
+
const z = await zarr.open(root.resolve(path));
|
|
27
15
|
return z;
|
|
28
16
|
}
|
|
29
17
|
}
|
|
30
|
-
const fetchDataFromZarr = async (url, path, s
|
|
18
|
+
const fetchDataFromZarr = async (url, path, s) => {
|
|
31
19
|
try {
|
|
32
20
|
const zarrHelper = new ZarrHelper();
|
|
33
21
|
const z = await zarrHelper.open(url, path);
|
|
34
|
-
const result = await
|
|
35
|
-
|
|
22
|
+
const result = await get(z, s);
|
|
23
|
+
if (result.dtype === 'bigint64') throw new Error('bigint64 dtype not supported');
|
|
24
|
+
const arr = unpack(result);
|
|
25
|
+
return arr;
|
|
36
26
|
} catch (error) {
|
|
37
|
-
if (error instanceof
|
|
27
|
+
if (error instanceof zarr.NodeNotFoundError) {
|
|
38
28
|
error.status = 404;
|
|
39
29
|
}
|
|
40
30
|
throw error;
|
|
41
31
|
}
|
|
42
32
|
};
|
|
43
|
-
export const useZarr = function (
|
|
33
|
+
export const useZarr = function (_ref) {
|
|
44
34
|
let {
|
|
45
35
|
url,
|
|
46
36
|
path,
|
|
47
37
|
s = null
|
|
48
|
-
} =
|
|
49
|
-
let
|
|
50
|
-
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
38
|
+
} = _ref;
|
|
39
|
+
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
51
40
|
const {
|
|
52
41
|
data = null,
|
|
53
42
|
isLoading: isPending = false,
|
|
54
43
|
error: serverError = null
|
|
55
44
|
} = useQuery(_objectSpread({
|
|
56
45
|
queryKey: ['zarr', url, path, s],
|
|
57
|
-
queryFn: () => fetchDataFromZarr(url, path, s
|
|
58
|
-
retry: (failureCount,
|
|
46
|
+
queryFn: () => fetchDataFromZarr(url, path, s),
|
|
47
|
+
retry: (failureCount, _ref2) => {
|
|
59
48
|
let {
|
|
60
49
|
error
|
|
61
|
-
} =
|
|
50
|
+
} = _ref2;
|
|
62
51
|
if ([400, 401, 403, 404, 422].includes(error === null || error === void 0 ? void 0 : error.status)) return false;
|
|
63
52
|
return failureCount < 3;
|
|
64
53
|
}
|
|
@@ -78,9 +67,8 @@ const aggregateData = (inputs, data) => {
|
|
|
78
67
|
return dataObject;
|
|
79
68
|
};
|
|
80
69
|
export const useMultipleZarr = function (inputs) {
|
|
81
|
-
let
|
|
82
|
-
let
|
|
83
|
-
let agg = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : aggregateData;
|
|
70
|
+
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
71
|
+
let agg = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : aggregateData;
|
|
84
72
|
const combine = useCallback(results => {
|
|
85
73
|
return {
|
|
86
74
|
data: agg(inputs, results.map(result => result.data)),
|
|
@@ -95,11 +83,11 @@ export const useMultipleZarr = function (inputs) {
|
|
|
95
83
|
} = useQueries({
|
|
96
84
|
queries: inputs.map(input => _objectSpread({
|
|
97
85
|
queryKey: ['zarr', input.url, input.path, input.s],
|
|
98
|
-
queryFn: () => fetchDataFromZarr(input.url, input.path, input.s
|
|
99
|
-
retry: (failureCount,
|
|
86
|
+
queryFn: () => fetchDataFromZarr(input.url, input.path, input.s),
|
|
87
|
+
retry: (failureCount, _ref3) => {
|
|
100
88
|
let {
|
|
101
89
|
error
|
|
102
|
-
} =
|
|
90
|
+
} = _ref3;
|
|
103
91
|
if ([400, 401, 403, 404, 422].includes(error === null || error === void 0 ? void 0 : error.status)) return false;
|
|
104
92
|
return failureCount < 3;
|
|
105
93
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import _ from 'lodash';
|
|
3
|
-
import { slice } from '
|
|
3
|
+
import { slice } from 'zarrita';
|
|
4
4
|
import { useSelectedObs, useSelectedVar } from './Resolver';
|
|
5
5
|
import { OBS_TYPES } from '../constants/constants';
|
|
6
6
|
import { useDataset } from '../context/DatasetContext';
|
|
7
7
|
import { useSettings } from '../context/SettingsContext';
|
|
8
|
-
import {
|
|
8
|
+
import { useZarr, useMultipleZarr } from '../helpers/zarr-helper';
|
|
9
9
|
|
|
10
10
|
// @TODO: support specifying slice to load from context
|
|
11
11
|
export const useObsmData = function () {
|
|
@@ -18,7 +18,7 @@ export const useObsmData = function () {
|
|
|
18
18
|
path: 'obsm/' + obsm,
|
|
19
19
|
s: [null, slice(null, 2)] // load only [:, :2]
|
|
20
20
|
}), [dataset.url, obsm]);
|
|
21
|
-
return useZarr(obsmParams,
|
|
21
|
+
return useZarr(obsmParams, {
|
|
22
22
|
enabled: !!obsm
|
|
23
23
|
});
|
|
24
24
|
};
|
|
@@ -45,7 +45,7 @@ export const useXData = function () {
|
|
|
45
45
|
s: [null, v.matrix_index]
|
|
46
46
|
};
|
|
47
47
|
}), [dataset.url, selectedVar]);
|
|
48
|
-
return useMultipleZarr(xParams,
|
|
48
|
+
return useMultipleZarr(xParams, {
|
|
49
49
|
enabled: !!xParams.length
|
|
50
50
|
}, agg);
|
|
51
51
|
};
|
|
@@ -62,7 +62,7 @@ export const useObsData = function () {
|
|
|
62
62
|
path: 'obs/' + ((_obs = obs) === null || _obs === void 0 ? void 0 : _obs.name) + (((_obs2 = obs) === null || _obs2 === void 0 ? void 0 : _obs2.type) === OBS_TYPES.CATEGORICAL ? '/codes' : '')
|
|
63
63
|
};
|
|
64
64
|
}, [dataset.url, (_obs3 = obs) === null || _obs3 === void 0 ? void 0 : _obs3.name, (_obs4 = obs) === null || _obs4 === void 0 ? void 0 : _obs4.type]);
|
|
65
|
-
return useZarr(obsParams,
|
|
65
|
+
return useZarr(obsParams, {
|
|
66
66
|
enabled: !!obs
|
|
67
67
|
});
|
|
68
68
|
};
|
|
@@ -77,7 +77,7 @@ export const useLabelObsData = () => {
|
|
|
77
77
|
key: obs.name
|
|
78
78
|
};
|
|
79
79
|
}), [dataset.url, settings.data.obs, settings.labelObs]);
|
|
80
|
-
return useMultipleZarr(labelObsParams,
|
|
80
|
+
return useMultipleZarr(labelObsParams, {
|
|
81
81
|
enabled: !!labelObsParams.length
|
|
82
82
|
});
|
|
83
83
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haniffalab/cherita-react",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.6-dev.2026-01-12.f157a881",
|
|
4
4
|
"author": "Haniffa Lab",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -42,9 +42,11 @@
|
|
|
42
42
|
"@tanstack/react-virtual": "^3.7.0",
|
|
43
43
|
"@turf/turf": "^7.0.0",
|
|
44
44
|
"@uidotdev/usehooks": "^2.4.1",
|
|
45
|
+
"@zarrita/ndarray": "^0.1.5",
|
|
45
46
|
"bootstrap": "^5.3.3",
|
|
46
47
|
"deck.gl": "8.8.27",
|
|
47
48
|
"jquery": "^3.7.1",
|
|
49
|
+
"ndarray-unpack": "^1.0.0",
|
|
48
50
|
"nebula.gl": "^1.0.4",
|
|
49
51
|
"numbro": "^2.5.0",
|
|
50
52
|
"plotly.js": "^2.23.2",
|
|
@@ -52,7 +54,7 @@
|
|
|
52
54
|
"react-bootstrap": "^2.7.4",
|
|
53
55
|
"react-plotly.js": "^2.6.0",
|
|
54
56
|
"react-scripts": "^5.0.1",
|
|
55
|
-
"
|
|
57
|
+
"zarrita": "^0.5.4"
|
|
56
58
|
},
|
|
57
59
|
"peerDependencies": {
|
|
58
60
|
"react": "^18.2.0",
|
|
@@ -139,5 +141,6 @@
|
|
|
139
141
|
"bugs": {
|
|
140
142
|
"url": "https://github.com/haniffalab/cherita-react/issues"
|
|
141
143
|
},
|
|
142
|
-
"homepage": "https://github.com/haniffalab/cherita-react#readme"
|
|
143
|
-
|
|
144
|
+
"homepage": "https://github.com/haniffalab/cherita-react#readme",
|
|
145
|
+
"prereleaseSha": "f157a88143d77d5a3d69296e84895802f0c39073"
|
|
146
|
+
}
|