@haniffalab/cherita-react 1.4.0-dev.2025-06-09.5492a16c → 1.4.0-dev.2025-06-13.c02f71d0

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.
@@ -5,11 +5,14 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.ObsmKeysList = ObsmKeysList;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
+ var _lodash = _interopRequireDefault(require("lodash"));
8
9
  var _reactBootstrap = require("react-bootstrap");
10
+ var _constants = require("../../constants/constants");
9
11
  var _DatasetContext = require("../../context/DatasetContext");
10
12
  var _SettingsContext = require("../../context/SettingsContext");
11
13
  var _requests = require("../../utils/requests");
12
14
  var _Skeleton = require("../../utils/Skeleton");
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
16
  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); }
14
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; }
15
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; }
@@ -43,13 +46,34 @@ function ObsmKeysList() {
43
46
  (0, _react.useEffect)(() => {
44
47
  if (!isPending && !serverError && fetchedData) {
45
48
  setObsmKeysList(fetchedData);
49
+
50
+ // Set default obsm if in keys list and not selected
51
+ if (!settings.selectedObsm && !!fetchedData.length) {
52
+ // Follow DEFAULT_OBSM_KEYS order
53
+ _lodash.default.each(_constants.DEFAULT_OBSM_KEYS, k => {
54
+ const defaultObsm = _lodash.default.find(fetchedData, item => item.toLowerCase() === k);
55
+ if (defaultObsm) {
56
+ dispatch({
57
+ type: "select.obsm",
58
+ obsm: defaultObsm
59
+ });
60
+ return false; // break
61
+ }
62
+ });
63
+ }
64
+ if (settings.selectedObsm) {
65
+ // If selected obsm is not in keys list, reset to null
66
+ if (!_lodash.default.includes(fetchedData, settings.selectedObsm)) {
67
+ dispatch({
68
+ type: "select.obsm",
69
+ obsm: null
70
+ });
71
+ } else {
72
+ setActive(settings.selectedObsm);
73
+ }
74
+ }
46
75
  }
47
- }, [fetchedData, isPending, serverError]);
48
- (0, _react.useEffect)(() => {
49
- if (settings.selectedObsm) {
50
- setActive(settings.selectedObsm);
51
- }
52
- }, [settings.selectedObsm]);
76
+ }, [dispatch, fetchedData, isPending, serverError, settings.selectedObsm]);
53
77
  const obsmList = obsmKeysList.map(item => {
54
78
  return /*#__PURE__*/_react.default.createElement(_reactBootstrap.Dropdown.Item, {
55
79
  key: item,
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.VIOLIN_MODES = exports.VIOLINPLOT_SCALES = exports.VAR_SORT_ORDER = exports.VAR_SORT = exports.UNSELECTED_POLYGON_FILLCOLOR = exports.SELECTION_MODES = exports.SELECTED_POLYGON_FILLCOLOR = exports.PSEUDOSPATIAL_PLOT_TYPES = exports.PSEUDOSPATIAL_CATEGORICAL_MODES = exports.PLOT_TYPES = exports.PLOTLY_MODEBAR_BUTTONS = exports.OBS_TYPES = exports.MATRIXPLOT_SCALES = exports.LOCAL_STORAGE_KEY = exports.DOTPLOT_SCALES = exports.DEFAULT_OBS_GROUP = exports.COLOR_ENCODINGS = exports.BREAKPOINTS = void 0;
6
+ exports.VIOLIN_MODES = exports.VIOLINPLOT_SCALES = exports.VAR_SORT_ORDER = exports.VAR_SORT = exports.UNSELECTED_POLYGON_FILLCOLOR = exports.SELECTION_MODES = exports.SELECTED_POLYGON_FILLCOLOR = exports.PSEUDOSPATIAL_PLOT_TYPES = exports.PSEUDOSPATIAL_CATEGORICAL_MODES = exports.PLOT_TYPES = exports.PLOTLY_MODEBAR_BUTTONS = exports.OBS_TYPES = exports.MATRIXPLOT_SCALES = exports.LOCAL_STORAGE_KEY = exports.DOTPLOT_SCALES = exports.DEFAULT_OBS_GROUP = exports.DEFAULT_OBSM_KEYS = exports.COLOR_ENCODINGS = exports.BREAKPOINTS = void 0;
7
7
  const LOCAL_STORAGE_KEY = exports.LOCAL_STORAGE_KEY = "CHERITA";
8
8
  const PLOT_TYPES = exports.PLOT_TYPES = {
9
9
  SCATTERPLOT: "scatterplot",
@@ -103,4 +103,7 @@ const PLOTLY_MODEBAR_BUTTONS = exports.PLOTLY_MODEBAR_BUTTONS = ["toImage", "zoo
103
103
  const BREAKPOINTS = exports.BREAKPOINTS = {
104
104
  LG: "(max-width: 991.98px)",
105
105
  XL: "(max-width: 1199.98px)"
106
- };
106
+ };
107
+
108
+ // In order of priority
109
+ const DEFAULT_OBSM_KEYS = exports.DEFAULT_OBSM_KEYS = ["x_umap", "x_tsne", "x_scvi", "x_pca"];
@@ -60,7 +60,7 @@ const persistOptions = {
60
60
  return false;
61
61
  }
62
62
  },
63
- buster: "1.4.0-dev.2025-06-09.5492a16c" || "0.0.0"
63
+ buster: "1.4.0-dev.2025-06-13.c02f71d0" || "0.0.0"
64
64
  // @TODO: add maxAge and api version numbers as buster
65
65
  };
66
66
  const initialDataset = {
@@ -10,6 +10,7 @@ exports.useSettingsDispatch = useSettingsDispatch;
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
  var _lodash = _interopRequireDefault(require("lodash"));
12
12
  var _constants = require("../constants/constants");
13
+ const _excluded = ["buster", "timestamp"];
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
15
  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); }
15
16
  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; }
@@ -17,6 +18,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
17
18
  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; }
18
19
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
19
20
  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); }
21
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
22
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
20
23
  const SettingsContext = exports.SettingsContext = /*#__PURE__*/(0, _react.createContext)(null);
21
24
  const SettingsDispatchContext = exports.SettingsDispatchContext = /*#__PURE__*/(0, _react.createContext)(null);
22
25
 
@@ -128,7 +131,18 @@ function SettingsProvider(_ref2) {
128
131
  const DATASET_STORAGE_KEY = "".concat(_constants.LOCAL_STORAGE_KEY, "-").concat(dataset_url);
129
132
  // Use localStorage directly instead of useLocalStorage due to unnecessary re-renders
130
133
  // https://github.com/uidotdev/usehooks/issues/157
131
- const localSettings = JSON.parse(localStorage.getItem(DATASET_STORAGE_KEY)) || {};
134
+ let _ref3 = JSON.parse(localStorage.getItem(DATASET_STORAGE_KEY)) || {},
135
+ {
136
+ buster,
137
+ timestamp
138
+ } = _ref3,
139
+ localSettings = _objectWithoutProperties(_ref3, _excluded);
140
+
141
+ // If the buster is not set or does not match the current package version,
142
+ // reset localSettings to avoid stale data
143
+ if (!buster || buster !== "1.4.0-dev.2025-06-13.c02f71d0") {
144
+ localSettings = {};
145
+ }
132
146
  const [settings, dispatch] = (0, _react.useReducer)(settingsReducer, {
133
147
  canOverrideSettings,
134
148
  defaultSettings,
@@ -137,7 +151,10 @@ function SettingsProvider(_ref2) {
137
151
  (0, _react.useEffect)(() => {
138
152
  if (canOverrideSettings) {
139
153
  try {
140
- localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(settings));
154
+ localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread({
155
+ buster: "1.4.0-dev.2025-06-13.c02f71d0" || "0.0.0",
156
+ timestamp: Date.now()
157
+ }, settings)));
141
158
  } catch (err) {
142
159
  if (err.code === 22 || err.code === 1014 || err.name === "QuotaExceededError" || err.name === "NS_ERROR_DOM_QUOTA_REACHED") {
143
160
  console.err("Browser storage quota exceeded");
@@ -4,7 +4,9 @@ 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 React, { useEffect, useState } from "react";
7
+ import _ from "lodash";
7
8
  import { Button, ButtonGroup, Dropdown, DropdownButton, OverlayTrigger, Tooltip } from "react-bootstrap";
9
+ import { DEFAULT_OBSM_KEYS } from "../../constants/constants";
8
10
  import { useDataset } from "../../context/DatasetContext";
9
11
  import { useSettings, useSettingsDispatch } from "../../context/SettingsContext";
10
12
  import { useFetch } from "../../utils/requests";
@@ -36,13 +38,34 @@ export function ObsmKeysList() {
36
38
  useEffect(() => {
37
39
  if (!isPending && !serverError && fetchedData) {
38
40
  setObsmKeysList(fetchedData);
41
+
42
+ // Set default obsm if in keys list and not selected
43
+ if (!settings.selectedObsm && !!fetchedData.length) {
44
+ // Follow DEFAULT_OBSM_KEYS order
45
+ _.each(DEFAULT_OBSM_KEYS, k => {
46
+ const defaultObsm = _.find(fetchedData, item => item.toLowerCase() === k);
47
+ if (defaultObsm) {
48
+ dispatch({
49
+ type: "select.obsm",
50
+ obsm: defaultObsm
51
+ });
52
+ return false; // break
53
+ }
54
+ });
55
+ }
56
+ if (settings.selectedObsm) {
57
+ // If selected obsm is not in keys list, reset to null
58
+ if (!_.includes(fetchedData, settings.selectedObsm)) {
59
+ dispatch({
60
+ type: "select.obsm",
61
+ obsm: null
62
+ });
63
+ } else {
64
+ setActive(settings.selectedObsm);
65
+ }
66
+ }
39
67
  }
40
- }, [fetchedData, isPending, serverError]);
41
- useEffect(() => {
42
- if (settings.selectedObsm) {
43
- setActive(settings.selectedObsm);
44
- }
45
- }, [settings.selectedObsm]);
68
+ }, [dispatch, fetchedData, isPending, serverError, settings.selectedObsm]);
46
69
  const obsmList = obsmKeysList.map(item => {
47
70
  return /*#__PURE__*/React.createElement(Dropdown.Item, {
48
71
  key: item,
@@ -97,4 +97,7 @@ export const PLOTLY_MODEBAR_BUTTONS = ["toImage", "zoom2d", "pan2d", "zoomIn2d",
97
97
  export const BREAKPOINTS = {
98
98
  LG: "(max-width: 991.98px)",
99
99
  XL: "(max-width: 1199.98px)"
100
- };
100
+ };
101
+
102
+ // In order of priority
103
+ export const DEFAULT_OBSM_KEYS = ["x_umap", "x_tsne", "x_scvi", "x_pca"];
@@ -50,7 +50,7 @@ const persistOptions = {
50
50
  return false;
51
51
  }
52
52
  },
53
- buster: "1.4.0-dev.2025-06-09.5492a16c" || "0.0.0"
53
+ buster: "1.4.0-dev.2025-06-13.c02f71d0" || "0.0.0"
54
54
  // @TODO: add maxAge and api version numbers as buster
55
55
  };
56
56
  const initialDataset = {
@@ -1,8 +1,11 @@
1
+ const _excluded = ["buster", "timestamp"];
1
2
  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; }
2
3
  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
4
  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
5
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
6
  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); }
7
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
8
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
6
9
  import React, { createContext, useContext, useEffect, useReducer } from "react";
7
10
  import _ from "lodash";
8
11
  import { COLOR_ENCODINGS, DOTPLOT_SCALES, LOCAL_STORAGE_KEY, MATRIXPLOT_SCALES, OBS_TYPES, PSEUDOSPATIAL_CATEGORICAL_MODES, VAR_SORT, VAR_SORT_ORDER, VIOLINPLOT_SCALES } from "../constants/constants";
@@ -117,7 +120,18 @@ export function SettingsProvider(_ref2) {
117
120
  const DATASET_STORAGE_KEY = "".concat(LOCAL_STORAGE_KEY, "-").concat(dataset_url);
118
121
  // Use localStorage directly instead of useLocalStorage due to unnecessary re-renders
119
122
  // https://github.com/uidotdev/usehooks/issues/157
120
- const localSettings = JSON.parse(localStorage.getItem(DATASET_STORAGE_KEY)) || {};
123
+ let _ref3 = JSON.parse(localStorage.getItem(DATASET_STORAGE_KEY)) || {},
124
+ {
125
+ buster,
126
+ timestamp
127
+ } = _ref3,
128
+ localSettings = _objectWithoutProperties(_ref3, _excluded);
129
+
130
+ // If the buster is not set or does not match the current package version,
131
+ // reset localSettings to avoid stale data
132
+ if (!buster || buster !== "1.4.0-dev.2025-06-13.c02f71d0") {
133
+ localSettings = {};
134
+ }
121
135
  const [settings, dispatch] = useReducer(settingsReducer, {
122
136
  canOverrideSettings,
123
137
  defaultSettings,
@@ -126,7 +140,10 @@ export function SettingsProvider(_ref2) {
126
140
  useEffect(() => {
127
141
  if (canOverrideSettings) {
128
142
  try {
129
- localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(settings));
143
+ localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(_objectSpread({
144
+ buster: "1.4.0-dev.2025-06-13.c02f71d0" || "0.0.0",
145
+ timestamp: Date.now()
146
+ }, settings)));
130
147
  } catch (err) {
131
148
  if (err.code === 22 || err.code === 1014 || err.name === "QuotaExceededError" || err.name === "NS_ERROR_DOM_QUOTA_REACHED") {
132
149
  console.err("Browser storage quota exceeded");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haniffalab/cherita-react",
3
- "version": "1.4.0-dev.2025-06-09.5492a16c",
3
+ "version": "1.4.0-dev.2025-06-13.c02f71d0",
4
4
  "author": "Haniffa Lab",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -128,5 +128,5 @@
128
128
  "url": "https://github.com/haniffalab/cherita-react/issues"
129
129
  },
130
130
  "homepage": "https://github.com/haniffalab/cherita-react#readme",
131
- "prereleaseSha": "5492a16cda4208fffd6fd9872eb743223550c084"
131
+ "prereleaseSha": "c02f71d04f2b512fe1f0f8ea3e4813ba5e3927e5"
132
132
  }