@vitessce/config 3.6.3 → 3.6.5

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 (33) hide show
  1. package/dist-tsc/generate-config-anndata.d.ts +8 -0
  2. package/dist-tsc/generate-config-anndata.d.ts.map +1 -0
  3. package/dist-tsc/generate-config-anndata.js +66 -0
  4. package/dist-tsc/generate-config-helpers.d.ts +9 -0
  5. package/dist-tsc/generate-config-helpers.d.ts.map +1 -0
  6. package/dist-tsc/generate-config-helpers.js +17 -0
  7. package/dist-tsc/generate-config-ome.d.ts +4 -0
  8. package/dist-tsc/generate-config-ome.d.ts.map +1 -0
  9. package/dist-tsc/generate-config-ome.js +19 -0
  10. package/dist-tsc/generate-config-spatialdata.d.ts +5 -0
  11. package/dist-tsc/generate-config-spatialdata.d.ts.map +1 -0
  12. package/dist-tsc/generate-config-spatialdata.js +87 -0
  13. package/dist-tsc/generate-config.d.ts +41 -0
  14. package/dist-tsc/generate-config.d.ts.map +1 -0
  15. package/dist-tsc/generate-config.js +241 -0
  16. package/dist-tsc/generate-config.test.d.ts +2 -0
  17. package/dist-tsc/generate-config.test.d.ts.map +1 -0
  18. package/dist-tsc/generate-config.test.js +258 -0
  19. package/dist-tsc/json-fixtures/mouse_liver.anndata.json +274 -0
  20. package/dist-tsc/json-fixtures/mouse_liver.labels.ome.json +50 -0
  21. package/dist-tsc/json-fixtures/mouse_liver.ome.json +50 -0
  22. package/dist-tsc/json-fixtures/mouse_liver.spatialdata.json +374 -0
  23. package/package.json +6 -4
  24. package/src/generate-config-anndata.js +75 -0
  25. package/src/generate-config-helpers.js +19 -0
  26. package/src/generate-config-ome.js +21 -0
  27. package/src/generate-config-spatialdata.js +101 -0
  28. package/src/generate-config.js +265 -0
  29. package/src/generate-config.test.js +274 -0
  30. package/src/json-fixtures/mouse_liver.anndata.json +274 -0
  31. package/src/json-fixtures/mouse_liver.labels.ome.json +50 -0
  32. package/src/json-fixtures/mouse_liver.ome.json +50 -0
  33. package/src/json-fixtures/mouse_liver.spatialdata.json +374 -0
@@ -0,0 +1,8 @@
1
+ export class AnnDataAutoConfig extends AbstractAutoConfig {
2
+ getOptions(): {
3
+ obsEmbedding: never[];
4
+ obsSets: never[];
5
+ };
6
+ }
7
+ import { AbstractAutoConfig } from './generate-config-helpers.js';
8
+ //# sourceMappingURL=generate-config-anndata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-config-anndata.d.ts","sourceRoot":"","sources":["../src/generate-config-anndata.js"],"names":[],"mappings":"AAGA;IACE;;;MAsDC;CAgBF;mCAzEkC,8BAA8B"}
@@ -0,0 +1,66 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import { AbstractAutoConfig } from './generate-config-helpers.js';
3
+ export class AnnDataAutoConfig extends AbstractAutoConfig {
4
+ getOptions() {
5
+ const { zmetadata } = this;
6
+ const options = {
7
+ obsEmbedding: [],
8
+ obsSets: [],
9
+ };
10
+ zmetadata.forEach(({ path, attrs }) => {
11
+ const lowerPath = path.toLowerCase();
12
+ const relPath = path.substring(1);
13
+ // Gene expression matrix.
14
+ if (['/x'].includes(lowerPath)) {
15
+ options.obsFeatureMatrix = {
16
+ path: relPath,
17
+ // TODO: Also check the shape of X.
18
+ // If X is very large, try to initialize initial-filtering properties
19
+ // (will require that /var contains a boolean column however.)
20
+ };
21
+ }
22
+ // Spatial coordinates.
23
+ if (['/obsm/x_spatial', '/obsm/spatial'].includes(lowerPath)) {
24
+ // TODO: use obsSpots instead of obsLocations here?
25
+ options.obsLocations = {
26
+ path: relPath,
27
+ };
28
+ }
29
+ // Embedding arrays.
30
+ if (['/obsm/x_umap', '/obsm/umap'].includes(lowerPath)) {
31
+ options.obsEmbedding.push({ path: relPath, embeddingType: 'UMAP' });
32
+ }
33
+ if (['/obsm/x_tsne', '/obsm/tsne'].includes(lowerPath)) {
34
+ options.obsEmbedding.push({ path: relPath, embeddingType: 't-SNE' });
35
+ }
36
+ if (['/obsm/x_pca', '/obsm/pca'].includes(lowerPath)) {
37
+ options.obsEmbedding.push({ path: relPath, embeddingType: 'PCA' });
38
+ }
39
+ // Cell set columns.
40
+ // TODO: use all categorical/string columns of obs instead of this fixed set?
41
+ const supportedObsSetsPaths = [
42
+ 'cluster', 'clusters', 'subcluster', 'cell_type', 'celltype',
43
+ 'leiden', 'louvain', 'disease', 'organism', 'self_reported_ethnicity',
44
+ 'tissue', 'sex',
45
+ ].map(colname => `/obs/${colname}`);
46
+ if (supportedObsSetsPaths.includes(lowerPath)) {
47
+ const name = relPath.split('/').at(-1);
48
+ options.obsSets.push({ path: relPath, name });
49
+ }
50
+ });
51
+ return options;
52
+ }
53
+ addFiles(vc, dataset) {
54
+ const { url, fileType } = this;
55
+ dataset.addFile({
56
+ url,
57
+ fileType,
58
+ options: this.getOptions(),
59
+ // TODO: coordination values?
60
+ });
61
+ }
62
+ // eslint-disable-next-line class-methods-use-this
63
+ addViews(vc, layoutOption) {
64
+ // TODO
65
+ }
66
+ }
@@ -0,0 +1,9 @@
1
+ export class AbstractAutoConfig {
2
+ constructor(parsedStore: any);
3
+ url: any;
4
+ fileType: any;
5
+ zmetadata: any;
6
+ addFiles(vc: any, dataset: any): void;
7
+ addViews(vc: any, layoutOption: any): void;
8
+ }
9
+ //# sourceMappingURL=generate-config-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-config-helpers.d.ts","sourceRoot":"","sources":["../src/generate-config-helpers.js"],"names":[],"mappings":"AACA;IACE,8BAKC;IAHC,SAAc;IACd,cAAwB;IACxB,eAA0B;IAI5B,sCAEC;IAGD,2CAEC;CACF"}
@@ -0,0 +1,17 @@
1
+ /* eslint-disable no-unused-vars */
2
+ export class AbstractAutoConfig {
3
+ constructor(parsedStore) {
4
+ const { url, fileType, zmetadata } = parsedStore;
5
+ this.url = url;
6
+ this.fileType = fileType;
7
+ this.zmetadata = zmetadata;
8
+ }
9
+ // eslint-disable-next-line class-methods-use-this
10
+ addFiles(vc, dataset) {
11
+ throw new Error('The addFiles() method has not been implemented.');
12
+ }
13
+ // eslint-disable-next-line class-methods-use-this
14
+ addViews(vc, layoutOption) {
15
+ throw new Error('The addViews() method has not been implemented.');
16
+ }
17
+ }
@@ -0,0 +1,4 @@
1
+ export class OmeAutoConfig extends AbstractAutoConfig {
2
+ }
3
+ import { AbstractAutoConfig } from './generate-config-helpers.js';
4
+ //# sourceMappingURL=generate-config-ome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-config-ome.d.ts","sourceRoot":"","sources":["../src/generate-config-ome.js"],"names":[],"mappings":"AAKA;CAeC;mCAnBkC,8BAA8B"}
@@ -0,0 +1,19 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import { AbstractAutoConfig } from './generate-config-helpers.js';
3
+ // TODO: split into separate classes for OME-TIFF and OME-Zarr?
4
+ // TODO: split into separate classes for image and obsSegmentations?
5
+ export class OmeAutoConfig extends AbstractAutoConfig {
6
+ addFiles(vc, dataset) {
7
+ const { url, fileType } = this;
8
+ dataset.addFile({
9
+ url,
10
+ fileType,
11
+ // TODO: options?
12
+ // TODO: coordination values?
13
+ });
14
+ }
15
+ // eslint-disable-next-line class-methods-use-this
16
+ addViews(vc, layoutOption) {
17
+ // TODO
18
+ }
19
+ }
@@ -0,0 +1,5 @@
1
+ export class SpatialDataAutoConfig extends AbstractAutoConfig {
2
+ getOptions(): {};
3
+ }
4
+ import { AbstractAutoConfig } from './generate-config-helpers.js';
5
+ //# sourceMappingURL=generate-config-spatialdata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-config-spatialdata.d.ts","sourceRoot":"","sources":["../src/generate-config-spatialdata.js"],"names":[],"mappings":"AAGA;IACE,iBAgFC;CAgBF;mCAnGkC,8BAA8B"}
@@ -0,0 +1,87 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import { AbstractAutoConfig } from './generate-config-helpers.js';
3
+ export class SpatialDataAutoConfig extends AbstractAutoConfig {
4
+ getOptions() {
5
+ const { zmetadata } = this;
6
+ const options = {};
7
+ const availableElements = zmetadata.filter(({ path }) => {
8
+ const relPath = path.substring(1);
9
+ return relPath.match(/^(tables|table|images|labels|shapes|points)\/([^/]*)$/);
10
+ });
11
+ availableElements.forEach(({ path, attrs }) => {
12
+ const relPath = path.substring(1);
13
+ const firstCoordinateSystem = attrs
14
+ ?.multiscales?.[0]
15
+ ?.coordinateTransformations?.[0]
16
+ ?.output?.name;
17
+ // Handle image elements.
18
+ if (relPath.match(/^(images)\/([^/]*)$/)) {
19
+ options.image = {
20
+ path: relPath,
21
+ coordinateSystem: firstCoordinateSystem,
22
+ // TODO: support a fileUid property in the schema?
23
+ };
24
+ }
25
+ // Handle labels elements.
26
+ if (relPath.match(/^(labels)\/([^/]*)$/)) {
27
+ options.labels = {
28
+ path: relPath,
29
+ coordinateSystem: firstCoordinateSystem,
30
+ // TODO: support a fileUid property in the schema?
31
+ };
32
+ // TODO: check which table annotates these labels.
33
+ }
34
+ // Handle shapes elements.
35
+ if (relPath.match(/^(shapes)\/([^/]*)$/)) {
36
+ // TODO: check if shapes are circles or polygons
37
+ // to determine which Vitessce data type to use.
38
+ options.obsSpots = {
39
+ path: relPath,
40
+ coordinateSystem: firstCoordinateSystem,
41
+ };
42
+ // TODO: check which table annotates these shapes.
43
+ }
44
+ // Handle table elements.
45
+ if (relPath.match(/^(tables|table)\/([^/]*)$/)) {
46
+ // Identify all sub-paths within this table element.
47
+ const tableEls = zmetadata.filter(({ path: subpath }) => subpath.startsWith(path));
48
+ // Check if the table contains an X array.
49
+ const hasX = tableEls.find(el => el.path === `${path}/X`);
50
+ if (hasX) {
51
+ options.obsFeatureMatrix = {
52
+ path: hasX.path.substring(1),
53
+ // region: null,
54
+ };
55
+ }
56
+ // Check if the table contains an obs dataframe.
57
+ const hasObs = tableEls.find(el => el.path === `${path}/obs`);
58
+ if (hasObs) {
59
+ const columnOrder = hasObs.attrs?.['column-order'];
60
+ // Use the columns of this dataframe to configure the obsSets.
61
+ options.obsSets = {
62
+ // region: null,
63
+ tablePath: relPath,
64
+ obsSets: columnOrder.map(c => ({
65
+ path: `${hasObs.path.substring(1)}/${c}`,
66
+ name: c,
67
+ })),
68
+ };
69
+ }
70
+ }
71
+ });
72
+ return options;
73
+ }
74
+ addFiles(vc, dataset) {
75
+ const { url, fileType } = this;
76
+ dataset.addFile({
77
+ url,
78
+ fileType,
79
+ options: this.getOptions(),
80
+ // TODO: coordination values?
81
+ });
82
+ }
83
+ // eslint-disable-next-line class-methods-use-this
84
+ addViews(vc, layoutOption) {
85
+ // TODO
86
+ }
87
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ *
3
+ * @param {string} s A single string, like this
4
+ * `http://example.com/my_zarr.zarr#anndata.zarr;
5
+ * http://example.com/my_tiff.ome.tif`
6
+ * @returns {{ url: string, fileType: string}[]} The URLs with file types.
7
+ */
8
+ export function parseUrls(s: string): {
9
+ url: string;
10
+ fileType: string;
11
+ }[];
12
+ export function parsedUrlToZmetadata(parsedUrl: any): Promise<{
13
+ path: string;
14
+ kind: string;
15
+ attrs: import("zarrita").Attributes;
16
+ }[] | null>;
17
+ /**
18
+ *
19
+ * @param {{ url, fileType, store }[]} parsedUrls
20
+ * @return {string[]} The layoutOptions.
21
+ */
22
+ export function parsedUrlsToLayoutOptions(parsedUrls: {
23
+ url: any;
24
+ fileType: any;
25
+ store: any;
26
+ }[]): string[];
27
+ /**
28
+ *
29
+ * @param {{ url, fileType, store }[]} parsedUrls
30
+ * @param {string|null} layoutOption
31
+ */
32
+ export function generateConfig(parsedUrls: {
33
+ url: any;
34
+ fileType: any;
35
+ store: any;
36
+ }[], layoutOption?: string | null): Promise<{
37
+ config: VitessceConfig;
38
+ stores: any;
39
+ }>;
40
+ import { VitessceConfig } from './VitessceConfig.js';
41
+ //# sourceMappingURL=generate-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-config.d.ts","sourceRoot":"","sources":["../src/generate-config.js"],"names":[],"mappings":"AAgGA;;;;;;GAMG;AACH,6BALW,MAAM,GAGJ;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,EAAE,CAqB9C;AAGD;;;;YAsEC;AAED;;;;GAIG;AACH,sDAHW;IAAE,GAAG,MAAC;IAAC,QAAQ,MAAC;IAAC,KAAK,MAAA;CAAE,EAAE,GACzB,MAAM,EAAE,CAOnB;AAED;;;;GAIG;AACH,2CAHW;IAAE,GAAG,MAAC;IAAC,QAAQ,MAAC;IAAC,KAAK,MAAA;CAAE,EAAE,iBAC1B,MAAM,GAAC,IAAI;;;GAoDrB;+BArQ8B,qBAAqB"}
@@ -0,0 +1,241 @@
1
+ // TODO: ts-check
2
+ import { FileType } from '@vitessce/constants-internal';
3
+ import { withConsolidated, FetchStore, ZipFileStore, open as zarrOpen, root as zarrRoot } from 'zarrita';
4
+ import { VitessceConfig } from './VitessceConfig.js';
5
+ // Classes for different types of objects
6
+ import { AnnDataAutoConfig } from './generate-config-anndata.js';
7
+ import { SpatialDataAutoConfig } from './generate-config-spatialdata.js';
8
+ import { OmeAutoConfig } from './generate-config-ome.js';
9
+ const fileTypeToExtensions = {
10
+ [FileType.IMAGE_OME_TIFF]: ['.ome.tif', '.ome.tiff', '.ome.tf2', '.ome.tf8'],
11
+ [FileType.IMAGE_OME_ZARR]: ['.ome.zarr'],
12
+ [FileType.IMAGE_OME_ZARR_ZIP]: ['.ome.zarr.zip'],
13
+ [FileType.ANNDATA_ZARR]: ['.ad.zarr', '.h5ad.zarr', '.adata.zarr', '.anndata.zarr'],
14
+ [FileType.ANNDATA_ZARR_ZIP]: ['.ad.zarr.zip', '.h5ad.zarr.zip', '.adata.zarr.zip', '.anndata.zarr.zip'],
15
+ // TODO: how to handle h5ad-based AnnData (since needs reference JSON file).
16
+ // Perhaps just assume one H5AD+one JSON (or .ref.json) file correspond to each other?
17
+ [FileType.SPATIALDATA_ZARR]: ['.sd.zarr', '.sdata.zarr', '.spatialdata.zarr'],
18
+ [FileType.SPATIALDATA_ZARR_ZIP]: ['.sd.zarr.zip', '.sdata.zarr.zip', '.spatialdata.zarr.zip'],
19
+ };
20
+ const fileTypeToClass = {
21
+ // OME-TIFF
22
+ [FileType.IMAGE_OME_TIFF]: OmeAutoConfig,
23
+ [FileType.OBS_SEGMENTATIONS_OME_TIFF]: OmeAutoConfig,
24
+ // OME-Zarr
25
+ [FileType.IMAGE_OME_ZARR]: OmeAutoConfig,
26
+ [FileType.IMAGE_OME_ZARR_ZIP]: OmeAutoConfig,
27
+ [FileType.OBS_SEGMENTATIONS_OME_ZARR]: OmeAutoConfig,
28
+ [FileType.OBS_SEGMENTATIONS_OME_ZARR_ZIP]: OmeAutoConfig,
29
+ // AnnData
30
+ [FileType.ANNDATA_ZARR]: AnnDataAutoConfig,
31
+ [FileType.ANNDATA_ZARR_ZIP]: AnnDataAutoConfig,
32
+ // SpatialData
33
+ [FileType.SPATIALDATA_ZARR]: SpatialDataAutoConfig,
34
+ [FileType.SPATIALDATA_ZARR_ZIP]: SpatialDataAutoConfig,
35
+ };
36
+ // This list contains file types that can be mapped to a regular Zarr store
37
+ // (e.g., FetchStore or ZipStore).
38
+ const ZARR_FILETYPES = [
39
+ FileType.ANNDATA_ZARR,
40
+ FileType.ANNDATA_ZARR_ZIP,
41
+ FileType.SPATIALDATA_ZARR,
42
+ FileType.SPATIALDATA_ZARR_ZIP,
43
+ FileType.IMAGE_OME_ZARR,
44
+ FileType.IMAGE_OME_ZARR_ZIP,
45
+ FileType.OBS_SEGMENTATIONS_OME_ZARR,
46
+ FileType.OBS_SEGMENTATIONS_OME_ZARR_ZIP,
47
+ ];
48
+ function urlToFileType(url) {
49
+ const match = Object.entries(fileTypeToExtensions).find(
50
+ // eslint-disable-next-line no-unused-vars
51
+ ([fileType, extensions]) => extensions.some(ext => url.endsWith(ext)));
52
+ if (match) {
53
+ return match[0];
54
+ }
55
+ throw new Error('The file extension contained in the URL did not map to a supported fileType.');
56
+ }
57
+ /**
58
+ *
59
+ * @param {{ fileType, url }} parsedUrl
60
+ * @returns {Readable}
61
+ */
62
+ function getStore(parsedUrl) {
63
+ const { fileType, url } = parsedUrl;
64
+ if (!ZARR_FILETYPES.includes(fileType)) {
65
+ return null;
66
+ }
67
+ return fileType.endsWith('.zip')
68
+ ? ZipFileStore.fromUrl(url)
69
+ : new FetchStore(url);
70
+ }
71
+ /**
72
+ * Ensure that each object { url, fileType, [store] }
73
+ * contains a `store`.
74
+ * @param {object[]} parsedUrls
75
+ * @returns {object[]}
76
+ */
77
+ function ensureStores(parsedUrls) {
78
+ return parsedUrls.map((parsedUrl) => {
79
+ if (parsedUrl.store) {
80
+ return parsedUrl;
81
+ }
82
+ const store = getStore(parsedUrl);
83
+ return {
84
+ ...parsedUrl,
85
+ store,
86
+ };
87
+ });
88
+ }
89
+ /**
90
+ *
91
+ * @param {string} s A single string, like this
92
+ * `http://example.com/my_zarr.zarr#anndata.zarr;
93
+ * http://example.com/my_tiff.ome.tif`
94
+ * @returns {{ url: string, fileType: string}[]} The URLs with file types.
95
+ */
96
+ export function parseUrls(s) {
97
+ const urlsWithHashes = s.split(';');
98
+ return urlsWithHashes.map((urlWithHash) => {
99
+ const parts = urlWithHash.split('#');
100
+ if (parts.length === 1) {
101
+ const [url] = parts;
102
+ return {
103
+ url,
104
+ fileType: urlToFileType(url),
105
+ };
106
+ }
107
+ if (parts.length === 2) {
108
+ const [url, fileType] = parts;
109
+ return {
110
+ url,
111
+ fileType,
112
+ };
113
+ }
114
+ throw new Error('Only expected zero or one # character per URL, but received more.');
115
+ });
116
+ }
117
+ export async function parsedUrlToZmetadata(parsedUrl) {
118
+ const { store: initialStore } = parsedUrl;
119
+ if (!initialStore) {
120
+ return null;
121
+ }
122
+ let store;
123
+ let promises = [];
124
+ try {
125
+ try {
126
+ store = await withConsolidated(initialStore);
127
+ }
128
+ catch {
129
+ // Try again with `zmetadata` rather than `.zmetadata`.
130
+ // Reference: https://github.com/zarr-developers/zarr-python/issues/1121
131
+ store = await withConsolidated(initialStore, { metadataKey: 'zmetadata' });
132
+ }
133
+ // Is consolidated.
134
+ const contents = store.contents();
135
+ promises = contents.map(async (value) => {
136
+ const item = await zarrOpen(zarrRoot(store).resolve(value.path));
137
+ return {
138
+ ...value,
139
+ attrs: item.attrs,
140
+ };
141
+ });
142
+ }
143
+ catch {
144
+ store = initialStore;
145
+ // Is not consolidated.
146
+ const keysToTry = [
147
+ // Note: OME-NGFF metadata is stored in the root attrs.
148
+ '/',
149
+ // AnnData keys
150
+ '/X',
151
+ '/layers',
152
+ '/obs',
153
+ '/var',
154
+ '/obsm',
155
+ '/obsm/spatial',
156
+ '/obsm/X_spatial',
157
+ '/obsm/pca',
158
+ '/obsm/X_pca',
159
+ '/obsm/tsne',
160
+ '/obsm/X_tsne',
161
+ '/obsm/umap',
162
+ '/obsm/X_umap',
163
+ // TODO: second round of getting metadata for
164
+ // columns listed in /obs and /var .attrs['column-order'] ?
165
+ // SpatialData keys
166
+ // Note: For spatialData, we assume the store is always consolidated.
167
+ // TODO: throw error if spatialdata + not consolidated?
168
+ ];
169
+ promises = keysToTry.map(async (k) => {
170
+ try {
171
+ const item = await zarrOpen(zarrRoot(store).resolve(k));
172
+ return {
173
+ path: k,
174
+ kind: item.kind,
175
+ attrs: item.attrs,
176
+ };
177
+ }
178
+ catch {
179
+ return null;
180
+ }
181
+ });
182
+ }
183
+ return (await Promise.all(promises))
184
+ .filter(entry => entry !== null);
185
+ }
186
+ /**
187
+ *
188
+ * @param {{ url, fileType, store }[]} parsedUrls
189
+ * @return {string[]} The layoutOptions.
190
+ */
191
+ export function parsedUrlsToLayoutOptions(parsedUrls) {
192
+ // eslint-disable-next-line no-unused-vars
193
+ const parsedStores = ensureStores(parsedUrls);
194
+ // TODO: implement
195
+ }
196
+ /**
197
+ *
198
+ * @param {{ url, fileType, store }[]} parsedUrls
199
+ * @param {string|null} layoutOption
200
+ */
201
+ export async function generateConfig(parsedUrls, layoutOption = null) {
202
+ // Map each URL to a Zarr store.
203
+ const parsedStores = ensureStores(parsedUrls);
204
+ // Obtain Zarr consolidated_metadata for each store.
205
+ const zmetadataStores = await Promise.all(parsedStores.map(async (parsedStore) => ({
206
+ ...parsedStore,
207
+ zmetadata: await parsedUrlToZmetadata(parsedStore),
208
+ })));
209
+ // Create configuration instance.
210
+ const vc = new VitessceConfig({
211
+ schemaVersion: '1.0.17',
212
+ name: 'Automatically-generated configuration.',
213
+ // TODO: write a description based on what is known
214
+ // (fileType(s) and maybe layoutOption).
215
+ description: 'Populate with a description of this visualization.',
216
+ });
217
+ // Create datasets.
218
+ // TODO: cases in which more than one dataset should be created?
219
+ const dataset = vc.addDataset('Main dataset');
220
+ zmetadataStores.forEach((parsedStore) => {
221
+ const { fileType } = parsedStore;
222
+ const AutoConfigClass = fileTypeToClass[fileType];
223
+ const autoConfig = new AutoConfigClass(parsedStore);
224
+ autoConfig.addFiles(vc, dataset);
225
+ // TODO: add all files, then add all views (in two separate loops)?
226
+ autoConfig.addViews(vc, layoutOption);
227
+ });
228
+ const stores = Object.fromEntries(
229
+ // Here, we use `parsedUrls` rather than `parsedStores`
230
+ // so that we do not provide more stores than intended
231
+ // (i.e., we do not provide stores which were solely created
232
+ // to obtain zmetadata).
233
+ parsedUrls
234
+ .filter(d => d.store)
235
+ .map(d => ([d.url, d.store])));
236
+ // Return both the config and the `stores` url-to-store dict.
237
+ return {
238
+ config: vc,
239
+ stores,
240
+ };
241
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generate-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-config.test.d.ts","sourceRoot":"","sources":["../src/generate-config.test.js"],"names":[],"mappings":""}