@vitessce/vit-s 2.0.0-beta.0

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.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/dist/CallbackPublisher.js +68 -0
  3. package/dist/LoadingIndicator.js +27 -0
  4. package/dist/TitleInfo.js +151 -0
  5. package/dist/VitS.js +113 -0
  6. package/dist/Vitessce.integration.test.js +36 -0
  7. package/dist/Vitessce.js +101 -0
  8. package/dist/VitessceGrid.js +55 -0
  9. package/dist/VitessceGrid.test.js +36 -0
  10. package/dist/Warning.js +45 -0
  11. package/dist/classNames.js +8 -0
  12. package/dist/component-registry.js +16 -0
  13. package/dist/data/AbstractLoader.js +35 -0
  14. package/dist/data/AbstractTwoStepLoader.js +7 -0
  15. package/dist/data/LoaderResult.js +7 -0
  16. package/dist/data/index.js +3 -0
  17. package/dist/data/loader-registry.js +15 -0
  18. package/dist/data-hook-utils.js +175 -0
  19. package/dist/data-hooks.js +241 -0
  20. package/dist/errors/AbstractLoaderError.js +13 -0
  21. package/dist/errors/DataSourceFetchError.js +13 -0
  22. package/dist/errors/DatasetNotFoundError.js +17 -0
  23. package/dist/errors/LoaderNotFoundError.js +17 -0
  24. package/dist/errors/LoaderValidationError.js +15 -0
  25. package/dist/errors/OptionsValidationError.js +15 -0
  26. package/dist/errors/index.js +6 -0
  27. package/dist/export-utils.js +70 -0
  28. package/dist/export-utils.test.js +66 -0
  29. package/dist/file-options-schemas-legacy.js +136 -0
  30. package/dist/file-options-schemas-legacy.test.js +126 -0
  31. package/dist/file-options-schemas.js +322 -0
  32. package/dist/file-options-schemas.test.js +23 -0
  33. package/dist/hooks.js +215 -0
  34. package/dist/index.js +18 -0
  35. package/dist/joint-file-types-legacy.js +278 -0
  36. package/dist/joint-file-types-legacy.test.js +400 -0
  37. package/dist/joint-file-types.js +148 -0
  38. package/dist/joint-file-types.test.js +139 -0
  39. package/dist/loader-registry.js +98 -0
  40. package/dist/plugins.js +154 -0
  41. package/dist/plugins.test.fixtures.js +76 -0
  42. package/dist/plugins.test.js +30 -0
  43. package/dist/schemas/PrettyJsonSchema.js +34 -0
  44. package/dist/schemas/config-0.1.0.schema.json +84 -0
  45. package/dist/schemas/config-1.0.0.schema.json +733 -0
  46. package/dist/schemas/config-1.0.1.schema.json +909 -0
  47. package/dist/schemas/config-1.0.10.schema.json +969 -0
  48. package/dist/schemas/config-1.0.11.schema.json +990 -0
  49. package/dist/schemas/config-1.0.12.schema.json +997 -0
  50. package/dist/schemas/config-1.0.13.schema.json +1013 -0
  51. package/dist/schemas/config-1.0.14.schema.json +1048 -0
  52. package/dist/schemas/config-1.0.15.schema.json +1048 -0
  53. package/dist/schemas/config-1.0.15.schema.test.js +22 -0
  54. package/dist/schemas/config-1.0.2.schema.json +910 -0
  55. package/dist/schemas/config-1.0.3.schema.json +910 -0
  56. package/dist/schemas/config-1.0.4.schema.json +949 -0
  57. package/dist/schemas/config-1.0.5.schema.json +949 -0
  58. package/dist/schemas/config-1.0.6.schema.json +949 -0
  59. package/dist/schemas/config-1.0.7.schema.json +949 -0
  60. package/dist/schemas/config-1.0.8.schema.json +965 -0
  61. package/dist/schemas/config-1.0.9.schema.json +965 -0
  62. package/dist/schemas/obsSets.schema.js +195 -0
  63. package/dist/schemas/obsSets.schema.json +194 -0
  64. package/dist/schemas/obsSetsTabular.schema.js +38 -0
  65. package/dist/schemas/obsSetsTabular.schema.json +37 -0
  66. package/dist/schemas/raster.schema.js +120 -0
  67. package/dist/schemas/raster.schema.json +119 -0
  68. package/dist/schemas/schema.test-old.js +50 -0
  69. package/dist/schemas/schema.test.js +46 -0
  70. package/dist/schemas.js +4 -0
  71. package/dist/shared-mui/components.js +35 -0
  72. package/dist/shared-mui/container.js +211 -0
  73. package/dist/shared-mui/styles.js +63 -0
  74. package/dist/shared-plot-options/CellColorEncodingOption.js +18 -0
  75. package/dist/shared-plot-options/OptionSelect.js +12 -0
  76. package/dist/shared-plot-options/OptionsContainer.js +12 -0
  77. package/dist/shared-plot-options/index.js +4 -0
  78. package/dist/shared-plot-options/styles.js +48 -0
  79. package/dist/state/hooks.js +550 -0
  80. package/dist/view-config-upgraders.js +525 -0
  81. package/dist/view-config-utils.js +286 -0
  82. package/dist/view-config-utils.test.fixtures.js +765 -0
  83. package/dist/view-config-utils.test.js +66 -0
  84. package/dist/view-config-versions.js +47 -0
  85. package/dist/vitessce-grid-layout/VitessceGridLayout.js +96 -0
  86. package/dist/vitessce-grid-layout/VitessceGridLayout.test.js +40 -0
  87. package/dist/vitessce-grid-layout/index.js +1 -0
  88. package/dist/vitessce-grid-layout/layout-utils.js +61 -0
  89. package/dist/vitessce-grid-layout/layout-utils.test.js +146 -0
  90. package/dist/vitessce-grid-utils.js +140 -0
  91. package/package.json +43 -0
@@ -0,0 +1,70 @@
1
+ import Bowser from 'bowser';
2
+ import { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from 'lz-string';
3
+ const CURRENT_VERSION = '0.0.1';
4
+ const VITESSCE_CONF_QUERY_STRING = 'vitessce_conf';
5
+ const VERSION_QUERY_STRING = 'vitessce_conf_version';
6
+ const LENGTH_QUERY_STRING = 'vitessce_conf_length';
7
+ function sniffBrowser() {
8
+ const { browser } = Bowser.parse(window.navigator.userAgent);
9
+ return browser.name;
10
+ }
11
+ // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
12
+ const MAX_BROWSER_URL_LENGTHS = {
13
+ Chrome: 32779,
14
+ 'Internet Explorer': 2047,
15
+ Edge: 2047,
16
+ Safari: 65000,
17
+ Firefox: 65000,
18
+ };
19
+ export default class CompressedConfLengthError {
20
+ constructor(message) {
21
+ this.message = message;
22
+ }
23
+ }
24
+ /**
25
+ * Encode a configuration as url params with a version and an lz-compressed conf.
26
+ * @param {Object} params
27
+ * @param {Object} params.conf Previous scope names.
28
+ * @param {function} params.onOverMaximumUrlLength Callback for when new url
29
+ * is over max length for your browser - takes two arguments: { message, willWorkOn }
30
+ * for the error message and the browsers for which the url will work (optional).
31
+ * @returns {string} The new params like
32
+ * vitessce_conf_length=10&vitessce_conf_version=0.0.1&vitessce_conf=fksdfasdfjkl
33
+ */
34
+ export function encodeConfInUrl({ conf, onOverMaximumUrlLength = () => { }, }) {
35
+ const compressedConf = compressToEncodedURIComponent(JSON.stringify(conf));
36
+ const newParams = `${LENGTH_QUERY_STRING}=${compressedConf.length}&${VERSION_QUERY_STRING}=${CURRENT_VERSION}&${VITESSCE_CONF_QUERY_STRING}=${compressedConf}`;
37
+ const browser = sniffBrowser();
38
+ const maxLength = MAX_BROWSER_URL_LENGTHS[browser];
39
+ if (newParams.length > maxLength) {
40
+ const willWorkOn = Object.entries(MAX_BROWSER_URL_LENGTHS)
41
+ .filter(entry => entry[1] > newParams.length)
42
+ .map(entry => entry[0]);
43
+ const message = `Configuration is ${compressedConf.length} characters; max URL for ${browser} is ${maxLength}: it will work on ${willWorkOn.join(', ') || 'no browser'}.`;
44
+ console.error(message);
45
+ onOverMaximumUrlLength({ message, willWorkOn });
46
+ }
47
+ return newParams;
48
+ }
49
+ /**
50
+ * Decode URL params to a Vitessce configuration.
51
+ * The URL params must have version and vitessce_conf params,
52
+ * like vitessce_conf_length=10&vitessce_conf_version=0.0.1&vitessce_conf=fksdfasdfjkl.
53
+ * @param {Object} queryString The URL params,
54
+ * like vitessce_conf_length=10&vitessce_conf_version=0.0.1&vitessce_conf=fksdfasdfjkl.
55
+ * @returns {string} A vitessce configuration.
56
+ */
57
+ export function decodeURLParamsToConf(queryString) {
58
+ const params = new URLSearchParams(queryString.replace('#', '&'));
59
+ const compressedConfString = params.get(VITESSCE_CONF_QUERY_STRING);
60
+ const expectedConfLength = Number(params.get(LENGTH_QUERY_STRING));
61
+ if (expectedConfLength !== compressedConfString.length) {
62
+ throw new CompressedConfLengthError(`Compressed conf length (${compressedConfString.length}) != expected (${expectedConfLength}). URL truncated?`);
63
+ }
64
+ const version = params.get(VERSION_QUERY_STRING);
65
+ if (version === CURRENT_VERSION) {
66
+ const conf = JSON.parse(decompressFromEncodedURIComponent(compressedConfString));
67
+ return conf;
68
+ }
69
+ throw new Error('Unrecognized URL Param Version');
70
+ }
@@ -0,0 +1,66 @@
1
+ import expect from 'expect';
2
+ import { encodeConfInUrl, decodeURLParamsToConf, } from './export-utils';
3
+ const fakeConfig = {
4
+ version: '0.1.0',
5
+ public: false,
6
+ layers: [
7
+ {
8
+ name: 'cells',
9
+ type: 'CELLS',
10
+ fileType: 'cells.json',
11
+ url: 'http://example.com/cells.json',
12
+ },
13
+ ],
14
+ name: 'Just scatterplot',
15
+ staticLayout: [
16
+ {
17
+ component: 'scatterplot',
18
+ props: {
19
+ mapping: 't-SNE',
20
+ view: {
21
+ zoom: 0.75,
22
+ target: [0, 0, 0],
23
+ },
24
+ },
25
+ x: 0,
26
+ y: 0,
27
+ w: 12,
28
+ h: 2,
29
+ },
30
+ ],
31
+ };
32
+ function makeLongString(length) {
33
+ let result = '';
34
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
35
+ const charactersLength = characters.length;
36
+ // eslint-disable-next-line no-plusplus
37
+ for (let i = 0; i < length; i++) {
38
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
39
+ }
40
+ return result;
41
+ }
42
+ describe('src/app/export-utils.js', () => {
43
+ describe('encodeConfInUrl', () => {
44
+ it('encodes a view config for a URL', () => {
45
+ const urlParams1 = encodeConfInUrl({ conf: {} });
46
+ expect(urlParams1).toEqual('vitessce_conf_length=5&vitessce_conf_version=0.0.1&vitessce_conf=N4XyA');
47
+ const urlParams2 = encodeConfInUrl({ conf: fakeConfig });
48
+ expect(urlParams2).toEqual('vitessce_conf_length=327&vitessce_conf_version=0.0.1&vitessce_conf=N4IgbgpgTgzglgewHYgFwgAwDoCMWMgA0IADgK4BGANnAMZoBmAhlTBMVUwJ7QxoDaoJEwC2ENCFoQqrIiAAuXEuPQBhAKIAZTQGU5DOFQgAVJSsnTWWAFYxkcslCoSAFvPklUAei8QAHqIkRli0CCJeUjIwNnYoAL4AusTCYhIAUmQw8gAEMLRM7tBBCPJyWQV0mtwIZKWogpJhJMgQSHUgeQXyRVQlciRQCCR8qKAiTCQkcEgA5hLyALQ6AHLqcmBwEADuaKAAXghhaNgA7ACsxPJMUDMQdfwYhI8YCXFxxH7HxFxfIDuoOAATMQXGhAYk4kA');
49
+ });
50
+ it('Calls onOverMaximumUrlLength for conf too long', () => {
51
+ let browsers;
52
+ // eslint-disable-next-line no-return-assign
53
+ const onOverMaximumUrlLength = ({ willWorkOn }) => browsers = willWorkOn;
54
+ encodeConfInUrl({ conf: { foo: makeLongString(69000) }, onOverMaximumUrlLength });
55
+ expect(browsers).toEqual([]);
56
+ encodeConfInUrl({ conf: { foo: makeLongString(37000) }, onOverMaximumUrlLength });
57
+ expect(browsers).toEqual(['Safari', 'Firefox']);
58
+ });
59
+ it('decodes a view config for a URL', () => {
60
+ const viewConfig1 = decodeURLParamsToConf('vitessce_conf_length=5&vitessce_conf_version=0.0.1&vitessce_conf=N4XyA');
61
+ expect(viewConfig1).toEqual({});
62
+ const viewConfig2 = decodeURLParamsToConf('vitessce_conf_length=327&vitessce_conf_version=0.0.1&vitessce_conf=N4IgbgpgTgzglgewHYgFwgAwDoCMWMgA0IADgK4BGANnAMZoBmAhlTBMVUwJ7QxoDaoJEwC2ENCFoQqrIiAAuXEuPQBhAKIAZTQGU5DOFQgAVJSsnTWWAFYxkcslCoSAFvPklUAei8QAHqIkRli0CCJeUjIwNnYoAL4AusTCYhIAUmQw8gAEMLRM7tBBCPJyWQV0mtwIZKWogpJhJMgQSHUgeQXyRVQlciRQCCR8qKAiTCQkcEgA5hLyALQ6AHLqcmBwEADuaKAAXghhaNgA7ACsxPJMUDMQdfwYhI8YCXFxxH7HxFxfIDuoOAATMQXGhAYk4kA');
63
+ expect(viewConfig2).toEqual(fakeConfig);
64
+ });
65
+ });
66
+ });
@@ -0,0 +1,136 @@
1
+ export const cellsJsonSchema = {
2
+ $schema: 'http://json-schema.org/draft-07/schema#',
3
+ $id: 'https://github.com/vitessce/vitessce/#cells-json-options',
4
+ title: 'cells.json options',
5
+ oneOf: [
6
+ { type: 'null' },
7
+ {
8
+ type: 'object',
9
+ additionalProperties: false,
10
+ required: [],
11
+ properties: {
12
+ obsLabelsTypes: {
13
+ type: 'array',
14
+ items: { type: 'string' },
15
+ },
16
+ embeddingTypes: {
17
+ type: 'array',
18
+ items: { type: 'string' },
19
+ },
20
+ },
21
+ },
22
+ ],
23
+ };
24
+ export const anndataCellsZarrSchema = {
25
+ $schema: 'http://json-schema.org/draft-07/schema#',
26
+ $id: 'https://github.com/vitessce/vitessce/#anndata-cells-zarr-options',
27
+ title: 'anndata-cells.zarr options',
28
+ type: 'object',
29
+ minProperties: 1,
30
+ additionalProperties: false,
31
+ required: [],
32
+ properties: {
33
+ xy: {
34
+ type: 'string',
35
+ description: "The location in the AnnData store of cell centroids, like 'obsm/X_centroids.'",
36
+ },
37
+ poly: {
38
+ type: 'string',
39
+ description: "The location in the AnnData store of cell polygon outlines, like 'obsm/X_polygons.'",
40
+ },
41
+ factors: {
42
+ type: 'array',
43
+ description: "List of locations in the AnnData store of cell sets, like 'obs/louvain'",
44
+ items: {
45
+ type: 'string',
46
+ },
47
+ },
48
+ mappings: {
49
+ patternProperties: {
50
+ '.': {
51
+ type: 'object',
52
+ description: "An object containing key-values for mappings like { UMAP: { key: 'obsm/X_umap', dims: [0, 1] } }.",
53
+ additionalProperties: false,
54
+ required: ['key'],
55
+ properties: {
56
+ key: {
57
+ type: 'string',
58
+ description: "Where to look in the AnnData store for this mapping, like 'obsm/X_umap.'",
59
+ },
60
+ dims: {
61
+ type: 'array',
62
+ description: 'Which indices of the obsm object to take for a scatterplot, allowing for, for example, different PCs from obsm/X_pca',
63
+ minItems: 2,
64
+ maxItems: 2,
65
+ items: { type: 'number' },
66
+ },
67
+ },
68
+ },
69
+ },
70
+ },
71
+ },
72
+ };
73
+ export const anndataCellSetsZarrSchema = {
74
+ $schema: 'http://json-schema.org/draft-07/schema#',
75
+ $id: 'https://github.com/vitessce/vitessce/#anndata-cell-sets-zarr-options',
76
+ title: 'anndata-cell-sets.zarr options',
77
+ type: 'array',
78
+ items: {
79
+ type: 'object',
80
+ additionalProperties: false,
81
+ required: ['groupName', 'setName'],
82
+ properties: {
83
+ groupName: {
84
+ type: 'string',
85
+ description: "The display name for the set, like 'Cell Type' or 'Louvain.'",
86
+ },
87
+ setName: {
88
+ oneOf: [
89
+ {
90
+ type: 'string',
91
+ description: "The location in the AnnData store for the set, like 'obs/louvain' or 'obs/celltype.'",
92
+ },
93
+ {
94
+ type: 'array',
95
+ items: { type: 'string' },
96
+ description: 'An array of locations in the AnnData store for a hierarchy of set names, from coarse to fine levels.',
97
+ },
98
+ ],
99
+ },
100
+ scoreName: {
101
+ oneOf: [
102
+ {
103
+ type: 'string',
104
+ description: "The location in the AnnData store for the set confidence scores, like 'obs/celltype_prediction_score.'",
105
+ },
106
+ ],
107
+ },
108
+ },
109
+ },
110
+ };
111
+ export const anndataExpressionMatrixZarrSchema = {
112
+ $schema: 'http://json-schema.org/draft-07/schema#',
113
+ $id: 'https://github.com/vitessce/vitessce/#anndata-expression-matrix-zarr-options',
114
+ title: 'anndata-expression-matrix.zarr options',
115
+ type: 'object',
116
+ additionalProperties: false,
117
+ required: ['matrix'],
118
+ properties: {
119
+ matrix: {
120
+ type: 'string',
121
+ description: "The location in the AnnData store of the cell x gene matrix, like 'obsm/hvg_subset.' or 'X'",
122
+ },
123
+ geneFilter: {
124
+ type: 'string',
125
+ description: "The location in the AnnData store of a filter for the genes if using a subset of the data, like 'var.highly_variable.' if the matrix comes from 'obsm/hvg_subset.'",
126
+ },
127
+ matrixGeneFilter: {
128
+ type: 'string',
129
+ description: "The location in the AnnData store of a filter for the matrix data (used in heatmap and histogram), like 'var.highly_variable.''",
130
+ },
131
+ geneAlias: {
132
+ type: 'string',
133
+ description: 'The location in the AnnData store of a different list of names for gene list component, other than the `var` index',
134
+ },
135
+ },
136
+ };
@@ -0,0 +1,126 @@
1
+ import { expandExpressionMatrixZarr, expandRasterOmeZarr, expandGenesJson, expandCellsJson, expandCellSetsJson, expandMoleculesJson, expandAnndataCellsZarr, expandAnndataCellSetsZarr, expandAnndataExpressionMatrixZarr, expandClustersJson, } from './joint-file-types-legacy';
2
+ describe('src/app/file-options-schemas-legacy.js', () => {
3
+ describe('Options validation for joint file type expansion functions', () => {
4
+ it('cells.json with extra options fails validation', () => {
5
+ expect(() => expandCellsJson({
6
+ fileType: 'cells.json',
7
+ url: 'http://localhost:8000/cells.json',
8
+ options: {
9
+ badKey: 'test',
10
+ embeddingTypes: ['UMAP', 't-SNE'],
11
+ obsLabelsTypes: ['cluster', 'subcluster'],
12
+ },
13
+ })).toThrow();
14
+ });
15
+ it('molecules.json with any options fails validation', () => {
16
+ expect(() => expandMoleculesJson({
17
+ fileType: 'molecules.json',
18
+ url: 'http://localhost:8000/molecules.json',
19
+ options: {},
20
+ })).toThrow();
21
+ });
22
+ it('expression-matrix.zarr with any options fails validation', () => {
23
+ expect(() => expandExpressionMatrixZarr({
24
+ fileType: 'expression-matrix.zarr',
25
+ url: 'http://localhost:8000/expression-matrix.zarr',
26
+ options: {},
27
+ })).toThrow();
28
+ });
29
+ it('raster.ome-zarr with any options fails validation', () => {
30
+ expect(() => expandRasterOmeZarr({
31
+ fileType: 'raster.ome-zarr',
32
+ url: 'http://localhost:8000/raster.ome-zarr',
33
+ options: {},
34
+ })).toThrow();
35
+ });
36
+ it('cell-sets.json with any options fails validation', () => {
37
+ expect(() => expandCellSetsJson({
38
+ fileType: 'cell-sets.json',
39
+ url: 'http://localhost:8000/cell-sets.json',
40
+ options: {},
41
+ })).toThrow();
42
+ });
43
+ it('clusters.json with any options fails validation', () => {
44
+ expect(() => expandClustersJson({
45
+ fileType: 'clusters.json',
46
+ url: 'http://localhost:8000/clusters.json',
47
+ options: {},
48
+ })).toThrow();
49
+ });
50
+ it('genes.json with any options fails validation', () => {
51
+ expect(() => expandGenesJson({
52
+ fileType: 'genes.json',
53
+ url: 'http://localhost:8000/genes.json',
54
+ options: {},
55
+ })).toThrow();
56
+ });
57
+ it('anndata-cells.zarr with extra options fails validation', () => {
58
+ expect(() => expandAnndataCellsZarr({
59
+ fileType: 'anndata-cells.zarr',
60
+ url: 'http://localhost:8000/anndata-cells.zarr',
61
+ options: {
62
+ poly: 'obsm/poly',
63
+ xy: 'obsm/xy',
64
+ bad: 'bad',
65
+ },
66
+ })).toThrow();
67
+ });
68
+ it('anndata-cells.zarr with invalid options fails validation', () => {
69
+ expect(() => expandAnndataCellsZarr({
70
+ fileType: 'anndata-cells.zarr',
71
+ url: 'http://localhost:8000/anndata-cells.zarr',
72
+ options: {
73
+ poly: 'obsm/poly',
74
+ xy: 'obsm/xy',
75
+ mappings: {
76
+ UMAP: ['bad'],
77
+ },
78
+ },
79
+ })).toThrow();
80
+ });
81
+ it('anndata-cell-sets.zarr with invalid options fails validation', () => {
82
+ expect(() => expandAnndataCellSetsZarr({
83
+ fileType: 'anndata-cell-sets.zarr',
84
+ url: 'http://localhost:8000/anndata-cell-sets.zarr',
85
+ options: {},
86
+ })).toThrow();
87
+ });
88
+ it('anndata-cell-sets.zarr with extra options fails validation', () => {
89
+ expect(() => expandAnndataCellSetsZarr({
90
+ fileType: 'anndata-cell-sets.zarr',
91
+ url: 'http://localhost:8000/anndata-cell-sets.zarr',
92
+ options: [
93
+ {
94
+ groupName: 'Cell Type Annotations',
95
+ setName: 'obs/cell_type',
96
+ scoreName: 'obs/score',
97
+ bad: 'bad',
98
+ },
99
+ ],
100
+ })).toThrow();
101
+ });
102
+ it('anndata-expression-matrix.zarr with invalid options fails validation', () => {
103
+ expect(() => expandAnndataExpressionMatrixZarr({
104
+ fileType: 'anndata-expression-matrix.zarr',
105
+ url: 'http://localhost:8000/anndata-expression-matrix.zarr',
106
+ options: {
107
+ matrix: 'good',
108
+ geneAlias: 1,
109
+ },
110
+ })).toThrow();
111
+ });
112
+ it('anndata-expression-matrix.zarr with extra options fails validation', () => {
113
+ expect(() => expandAnndataExpressionMatrixZarr({
114
+ fileType: 'anndata-expression-matrix.zarr',
115
+ url: 'http://localhost:8000/anndata-expression-matrix.zarr',
116
+ options: {
117
+ matrix: 'good',
118
+ geneAlias: 'good',
119
+ geneFilter: 'good',
120
+ matrixGeneFilter: 'good',
121
+ bad: 'bad',
122
+ },
123
+ })).toThrow();
124
+ });
125
+ });
126
+ });