@vitessce/config 3.3.1 → 3.3.3

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/index.js CHANGED
@@ -44,7 +44,9 @@ const FileType$1 = {
44
44
  OBS_SEGMENTATIONS_JSON: "obsSegmentations.json",
45
45
  OBS_SETS_CSV: "obsSets.csv",
46
46
  OBS_SETS_JSON: "obsSets.json",
47
+ // OME-Zarr
47
48
  IMAGE_OME_ZARR: "image.ome-zarr",
49
+ OBS_SEGMENTATIONS_OME_ZARR: "obsSegmentations.ome-zarr",
48
50
  // AnnData
49
51
  OBS_FEATURE_MATRIX_ANNDATA_ZARR: "obsFeatureMatrix.anndata.zarr",
50
52
  OBS_SETS_ANNDATA_ZARR: "obsSets.anndata.zarr",
@@ -645,6 +647,24 @@ function getNextScope(prevScopes) {
645
647
  } while (prevScopes.includes(nextScope));
646
648
  return nextScope;
647
649
  }
650
+ function createPrefixedGetNextScopeNumeric(prefix) {
651
+ return (prevScopes) => {
652
+ let nextScopeInt = 0;
653
+ let nextScopeStr;
654
+ do {
655
+ nextScopeStr = `${prefix}${nextScopeInt}`;
656
+ nextScopeInt += 1;
657
+ } while (prevScopes.includes(nextScopeStr));
658
+ return nextScopeStr;
659
+ };
660
+ }
661
+ function getInitialCoordinationScopePrefix(datasetUid, dataType) {
662
+ return `init_${datasetUid}_${dataType}_`;
663
+ }
664
+ function getInitialCoordinationScopeName(datasetUid, dataType, i = null) {
665
+ const prefix = getInitialCoordinationScopePrefix(datasetUid, dataType);
666
+ return `${prefix}${i === null ? 0 : i}`;
667
+ }
648
668
  let getRandomValues;
649
669
  const rnds8 = new Uint8Array(16);
650
670
  function rng() {
@@ -8990,30 +9010,39 @@ const omeCoordinateTransformations = z.array(z.union([
8990
9010
  scale: z.array(z.number())
8991
9011
  })
8992
9012
  ]));
8993
- z.object({
9013
+ const imageOmeTiffSchema = z.object({
8994
9014
  offsetsUrl: z.string().optional(),
8995
9015
  coordinateTransformations: omeCoordinateTransformations.optional()
8996
9016
  });
9017
+ imageOmeTiffSchema.extend({
9018
+ obsTypesFromChannelNames: z.boolean().optional()
9019
+ });
8997
9020
  const imageOmeZarrSchema = z.object({
8998
9021
  coordinateTransformations: omeCoordinateTransformations.optional()
8999
9022
  });
9000
9023
  imageOmeZarrSchema.extend({
9024
+ obsTypesFromChannelNames: z.boolean().optional()
9025
+ });
9026
+ const imageSpatialdataSchema = imageOmeZarrSchema.extend({
9001
9027
  path: z.string()
9002
9028
  });
9003
- z.object({
9029
+ const obsSegmentationsSpatialdataSchema = z.object({
9030
+ // TODO: should this also extend the imageOmeZarrSchema?
9031
+ // TODO: should this be renamed labelsSpatialdataSchema?
9032
+ // TODO: support obsTypesFromChannelNames?
9004
9033
  path: z.string()
9005
9034
  });
9006
9035
  z.object({
9007
9036
  path: z.string()
9008
9037
  });
9009
- z.object({
9038
+ const obsSpotsSpatialdataSchema = z.object({
9010
9039
  path: z.string(),
9011
9040
  tablePath: z.string().optional().describe("The path to a table which annotates the spots. If available but not specified, the spot identifiers may not be aligned with associated tabular data as expected.")
9012
9041
  });
9013
- annDataObsFeatureMatrix.extend({
9042
+ const obsFeatureMatrixSpatialdataSchema = annDataObsFeatureMatrix.extend({
9014
9043
  region: z.string().describe("The name of a region to use to filter instances (i.e., rows) in the table").optional()
9015
9044
  });
9016
- z.object({
9045
+ const obsSetsSpatialdataSchema = z.object({
9017
9046
  region: z.string().describe("The name of a region to use to filter instances (i.e., rows) in the table").optional(),
9018
9047
  tablePath: z.string().optional().describe("The path to a table which contains the index for the set values."),
9019
9048
  obsSets: annDataObsSets
@@ -9076,6 +9105,19 @@ z.object({
9076
9105
  z.array(annDataConvenienceObsEmbeddingItem)
9077
9106
  ])
9078
9107
  }).partial();
9108
+ z.object({
9109
+ // TODO: should `image` be a special schema
9110
+ // to allow specifying fileUid (like for embeddingType)?
9111
+ image: imageSpatialdataSchema,
9112
+ // TODO: should this be a special schema
9113
+ // to allow specifying fileUid (like for embeddingType)?
9114
+ labels: obsSegmentationsSpatialdataSchema,
9115
+ obsFeatureMatrix: obsFeatureMatrixSpatialdataSchema,
9116
+ obsSpots: obsSpotsSpatialdataSchema,
9117
+ // TODO: obsPoints
9118
+ // TODO: obsLocations
9119
+ obsSets: obsSetsSpatialdataSchema
9120
+ }).partial();
9079
9121
  z.object({
9080
9122
  obsLabelsTypes: z.array(z.string()).optional(),
9081
9123
  embeddingTypes: z.array(z.string()).optional()
@@ -15921,11 +15963,12 @@ class VitessceConfigCoordinationScope {
15921
15963
  * Construct a new coordination scope instance.
15922
15964
  * @param {string} cType The coordination type for this coordination scope.
15923
15965
  * @param {string} cScope The name of the coordination scope.
15966
+ * @param {[any]} cValue Optional. The coordination value of the coordination scope.
15924
15967
  */
15925
- constructor(cType, cScope) {
15968
+ constructor(cType, cScope, cValue = null) {
15926
15969
  this.cType = cType;
15927
15970
  this.cScope = cScope;
15928
- this.cValue = null;
15971
+ this.cValue = cValue;
15929
15972
  }
15930
15973
  /**
15931
15974
  * Set the coordination value of the coordination scope.
@@ -16032,6 +16075,7 @@ class VitessceConfig {
16032
16075
  layout: [],
16033
16076
  initStrategy: "auto"
16034
16077
  };
16078
+ this.getNextScope = getNextScope;
16035
16079
  }
16036
16080
  /**
16037
16081
  * Add a new dataset to the config.
@@ -16045,7 +16089,7 @@ class VitessceConfig {
16045
16089
  addDataset(name = void 0, description = void 0, options = void 0) {
16046
16090
  const { uid } = options || {};
16047
16091
  const prevDatasetUids = this.config.datasets.map((d) => d.dataset.uid);
16048
- const nextUid = uid || getNextScope(prevDatasetUids);
16092
+ const nextUid = uid || this.getNextScope(prevDatasetUids);
16049
16093
  const newDataset = new VitessceConfigDataset(nextUid, name, description);
16050
16094
  this.config.datasets.push(newDataset);
16051
16095
  const [newScope] = this.addCoordination(CoordinationType$1.DATASET);
@@ -16104,7 +16148,7 @@ class VitessceConfig {
16104
16148
  const result = [];
16105
16149
  cTypes.forEach((cType) => {
16106
16150
  const prevScopes = this.config.coordinationSpace[cType] ? Object.keys(this.config.coordinationSpace[cType]) : [];
16107
- const scope = new VitessceConfigCoordinationScope(cType, getNextScope(prevScopes));
16151
+ const scope = new VitessceConfigCoordinationScope(cType, this.getNextScope(prevScopes));
16108
16152
  if (!this.config.coordinationSpace[scope.cType]) {
16109
16153
  this.config.coordinationSpace[scope.cType] = {};
16110
16154
  }
@@ -16122,8 +16166,8 @@ class VitessceConfig {
16122
16166
  const prevMetaScopes = this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES] ? Object.keys(this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES]) : [];
16123
16167
  const prevMetaByScopes = this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES_BY] ? Object.keys(this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES_BY]) : [];
16124
16168
  const metaContainer = new VitessceConfigMetaCoordinationScope(
16125
- getNextScope(prevMetaScopes),
16126
- getNextScope(prevMetaByScopes)
16169
+ this.getNextScope(prevMetaScopes),
16170
+ this.getNextScope(prevMetaByScopes)
16127
16171
  );
16128
16172
  if (!this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES]) {
16129
16173
  this.config.coordinationSpace[CoordinationType$1.META_COORDINATION_SCOPES] = {};
@@ -16151,6 +16195,9 @@ class VitessceConfig {
16151
16195
  addCoordinationByObject(input) {
16152
16196
  const processLevel = (level) => {
16153
16197
  const result = {};
16198
+ if (level === null) {
16199
+ return result;
16200
+ }
16154
16201
  Object.entries(level).forEach(([cType, nextLevelOrInitialValue]) => {
16155
16202
  if (nextLevelOrInitialValue instanceof CoordinationLevel) {
16156
16203
  const nextLevel = nextLevelOrInitialValue.value;
@@ -16225,10 +16272,18 @@ class VitessceConfig {
16225
16272
  * instance, or a `CoordinationLevel` instance.
16226
16273
  * The CL function takes an array of objects as its argument, and returns a CoordinationLevel
16227
16274
  * instance, to support nesting.
16228
- * @param {boolean} meta Should meta-coordination be used? Optional. By default, true.
16275
+ * @param {object|null} options
16276
+ * @param {bool} options.meta Should meta-coordination be used? Optional.
16277
+ * By default, true.
16278
+ * @param {string|null} options.scopePrefix A prefix to add to all
16279
+ * coordination scope names. Optional.
16229
16280
  * @returns {VitessceConfig} This, to allow chaining.
16230
16281
  */
16231
- linkViewsByObject(views, input, meta = true) {
16282
+ linkViewsByObject(views, input, options = null) {
16283
+ const { meta = true, scopePrefix = null } = options || {};
16284
+ if (scopePrefix) {
16285
+ this.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
16286
+ }
16232
16287
  const scopes = this.addCoordinationByObject(input);
16233
16288
  if (meta) {
16234
16289
  const metaScope = this.addMetaCoordination();
@@ -16241,8 +16296,28 @@ class VitessceConfig {
16241
16296
  view.useCoordinationByObject(scopes);
16242
16297
  });
16243
16298
  }
16299
+ if (scopePrefix) {
16300
+ this.getNextScope = getNextScope;
16301
+ }
16244
16302
  return this;
16245
16303
  }
16304
+ /**
16305
+ * Set the value for a coordination scope.
16306
+ * If a coordination object for the coordination type does not yet exist
16307
+ * in the coordination space, it will be created.
16308
+ * @param {string} cType The coordination type.
16309
+ * @param {string} cScope The coordination scope.
16310
+ * @param {any} cValue The initial value for the coordination scope.
16311
+ * @returns {VitessceConfigCoordinationScope} A coordination scope instance.
16312
+ */
16313
+ setCoordinationValue(cType, cScope, cValue) {
16314
+ const scope = new VitessceConfigCoordinationScope(cType, cScope, cValue);
16315
+ if (!this.config.coordinationSpace[scope.cType]) {
16316
+ this.config.coordinationSpace[scope.cType] = {};
16317
+ }
16318
+ this.config.coordinationSpace[scope.cType][scope.cScope] = scope;
16319
+ return scope;
16320
+ }
16246
16321
  /**
16247
16322
  * Set the layout of views.
16248
16323
  * @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A
@@ -16333,6 +16408,22 @@ class VitessceConfig {
16333
16408
  return vc;
16334
16409
  }
16335
16410
  }
16411
+ function getCoordinationSpaceAndScopes(partialCoordinationValues, scopePrefix) {
16412
+ const vc = new VitessceConfig({ schemaVersion: "1.0.16", name: "__dummy__" });
16413
+ vc.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
16414
+ const dataset = vc.addDataset("__dummy__");
16415
+ const v1 = vc.addView(dataset, "__dummy__");
16416
+ vc.linkViewsByObject([v1], partialCoordinationValues, { meta: true });
16417
+ const vcJson = vc.toJSON();
16418
+ const { coordinationSpace } = vcJson;
16419
+ const { coordinationScopes } = vcJson.layout[0];
16420
+ const { coordinationScopesBy } = vcJson.layout[0];
16421
+ return {
16422
+ coordinationSpace,
16423
+ coordinationScopes,
16424
+ coordinationScopesBy
16425
+ };
16426
+ }
16336
16427
  const SINGLE_CELL_WITH_HEATMAP_VIEWS = {
16337
16428
  obsSets: { x: 4, y: 0, w: 4, h: 4 },
16338
16429
  obsSetSizes: { x: 8, y: 0, w: 4, h: 4 },
@@ -16948,7 +17039,10 @@ export {
16948
17039
  HINT_TYPE_TO_FILE_TYPE_MAP,
16949
17040
  VitessceConfig,
16950
17041
  generateConfig,
17042
+ getCoordinationSpaceAndScopes,
16951
17043
  getHintOptions,
17044
+ getInitialCoordinationScopeName,
17045
+ getInitialCoordinationScopePrefix,
16952
17046
  hconcat,
16953
17047
  vconcat
16954
17048
  };
@@ -13,6 +13,11 @@ export function hconcat(...views: (VitessceConfigView | VitessceConfigViewHConca
13
13
  */
14
14
  export function vconcat(...views: (VitessceConfigView | VitessceConfigViewHConcat | VitessceConfigViewVConcat)[]): VitessceConfigViewVConcat;
15
15
  export function CL(value: any): CoordinationLevel;
16
+ export function getCoordinationSpaceAndScopes(partialCoordinationValues: any, scopePrefix: any): {
17
+ coordinationSpace: any;
18
+ coordinationScopes: any;
19
+ coordinationScopesBy: any;
20
+ };
16
21
  /**
17
22
  * Class representing a file within a Vitessce config dataset.
18
23
  */
@@ -162,11 +167,12 @@ export class VitessceConfigCoordinationScope {
162
167
  * Construct a new coordination scope instance.
163
168
  * @param {string} cType The coordination type for this coordination scope.
164
169
  * @param {string} cScope The name of the coordination scope.
170
+ * @param {[any]} cValue Optional. The coordination value of the coordination scope.
165
171
  */
166
- constructor(cType: string, cScope: string);
172
+ constructor(cType: string, cScope: string, cValue?: [any]);
167
173
  cType: string;
168
174
  cScope: string;
169
- cValue: any;
175
+ cValue: [any];
170
176
  /**
171
177
  * Set the coordination value of the coordination scope.
172
178
  * @param {any} cValue The value to set.
@@ -237,6 +243,7 @@ export class VitessceConfig {
237
243
  layout: never[];
238
244
  initStrategy: string;
239
245
  };
246
+ getNextScope: any;
240
247
  /**
241
248
  * Add a new dataset to the config.
242
249
  * @param {string} name A name for the dataset. Optional.
@@ -315,10 +322,24 @@ export class VitessceConfig {
315
322
  * instance, or a `CoordinationLevel` instance.
316
323
  * The CL function takes an array of objects as its argument, and returns a CoordinationLevel
317
324
  * instance, to support nesting.
318
- * @param {boolean} meta Should meta-coordination be used? Optional. By default, true.
325
+ * @param {object|null} options
326
+ * @param {bool} options.meta Should meta-coordination be used? Optional.
327
+ * By default, true.
328
+ * @param {string|null} options.scopePrefix A prefix to add to all
329
+ * coordination scope names. Optional.
319
330
  * @returns {VitessceConfig} This, to allow chaining.
320
331
  */
321
- linkViewsByObject(views: VitessceConfigView[], input: object, meta?: boolean): VitessceConfig;
332
+ linkViewsByObject(views: VitessceConfigView[], input: object, options?: object | null): VitessceConfig;
333
+ /**
334
+ * Set the value for a coordination scope.
335
+ * If a coordination object for the coordination type does not yet exist
336
+ * in the coordination space, it will be created.
337
+ * @param {string} cType The coordination type.
338
+ * @param {string} cScope The coordination scope.
339
+ * @param {any} cValue The initial value for the coordination scope.
340
+ * @returns {VitessceConfigCoordinationScope} A coordination scope instance.
341
+ */
342
+ setCoordinationValue(cType: string, cScope: string, cValue: any): VitessceConfigCoordinationScope;
322
343
  /**
323
344
  * Set the layout of views.
324
345
  * @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A
@@ -1 +1 @@
1
- {"version":3,"file":"VitessceConfig.d.ts","sourceRoot":"","sources":["../src/VitessceConfig.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VitessceConfig.d.ts","sourceRoot":"","sources":["../src/VitessceConfig.js"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
2
  import { CoordinationType } from '@vitessce/constants-internal';
3
- import { fromEntries, getNextScope } from '@vitessce/utils';
3
+ import { fromEntries, getNextScope, createPrefixedGetNextScopeNumeric } from '@vitessce/utils';
4
4
  /**
5
5
  * Class representing a file within a Vitessce config dataset.
6
6
  */
@@ -393,11 +393,12 @@ export class VitessceConfigCoordinationScope {
393
393
  * Construct a new coordination scope instance.
394
394
  * @param {string} cType The coordination type for this coordination scope.
395
395
  * @param {string} cScope The name of the coordination scope.
396
+ * @param {[any]} cValue Optional. The coordination value of the coordination scope.
396
397
  */
397
- constructor(cType, cScope) {
398
+ constructor(cType, cScope, cValue = null) {
398
399
  this.cType = cType;
399
400
  this.cScope = cScope;
400
- this.cValue = null;
401
+ this.cValue = cValue;
401
402
  }
402
403
  /**
403
404
  * Set the coordination value of the coordination scope.
@@ -506,6 +507,7 @@ export class VitessceConfig {
506
507
  layout: [],
507
508
  initStrategy: 'auto',
508
509
  };
510
+ this.getNextScope = getNextScope;
509
511
  }
510
512
  /**
511
513
  * Add a new dataset to the config.
@@ -519,7 +521,7 @@ export class VitessceConfig {
519
521
  addDataset(name = undefined, description = undefined, options = undefined) {
520
522
  const { uid } = options || {};
521
523
  const prevDatasetUids = this.config.datasets.map(d => d.dataset.uid);
522
- const nextUid = (uid || getNextScope(prevDatasetUids));
524
+ const nextUid = (uid || this.getNextScope(prevDatasetUids));
523
525
  const newDataset = new VitessceConfigDataset(nextUid, name, description);
524
526
  this.config.datasets.push(newDataset);
525
527
  const [newScope] = this.addCoordination(CoordinationType.DATASET);
@@ -580,7 +582,7 @@ export class VitessceConfig {
580
582
  const prevScopes = (this.config.coordinationSpace[cType]
581
583
  ? Object.keys(this.config.coordinationSpace[cType])
582
584
  : []);
583
- const scope = new VitessceConfigCoordinationScope(cType, getNextScope(prevScopes));
585
+ const scope = new VitessceConfigCoordinationScope(cType, this.getNextScope(prevScopes));
584
586
  if (!this.config.coordinationSpace[scope.cType]) {
585
587
  this.config.coordinationSpace[scope.cType] = {};
586
588
  }
@@ -601,7 +603,7 @@ export class VitessceConfig {
601
603
  const prevMetaByScopes = (this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES_BY]
602
604
  ? Object.keys(this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES_BY])
603
605
  : []);
604
- const metaContainer = new VitessceConfigMetaCoordinationScope(getNextScope(prevMetaScopes), getNextScope(prevMetaByScopes));
606
+ const metaContainer = new VitessceConfigMetaCoordinationScope(this.getNextScope(prevMetaScopes), this.getNextScope(prevMetaByScopes));
605
607
  if (!this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES]) {
606
608
  this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES] = {};
607
609
  }
@@ -707,6 +709,9 @@ export class VitessceConfig {
707
709
  */
708
710
  const processLevel = (level) => {
709
711
  const result = {};
712
+ if (level === null) {
713
+ return result;
714
+ }
710
715
  Object.entries(level).forEach(([cType, nextLevelOrInitialValue]) => {
711
716
  // Check if value of object is instanceof CoordinationLevel
712
717
  // (otherwise assume it is the coordination value).
@@ -791,10 +796,18 @@ export class VitessceConfig {
791
796
  * instance, or a `CoordinationLevel` instance.
792
797
  * The CL function takes an array of objects as its argument, and returns a CoordinationLevel
793
798
  * instance, to support nesting.
794
- * @param {boolean} meta Should meta-coordination be used? Optional. By default, true.
799
+ * @param {object|null} options
800
+ * @param {bool} options.meta Should meta-coordination be used? Optional.
801
+ * By default, true.
802
+ * @param {string|null} options.scopePrefix A prefix to add to all
803
+ * coordination scope names. Optional.
795
804
  * @returns {VitessceConfig} This, to allow chaining.
796
805
  */
797
- linkViewsByObject(views, input, meta = true) {
806
+ linkViewsByObject(views, input, options = null) {
807
+ const { meta = true, scopePrefix = null } = options || {};
808
+ if (scopePrefix) {
809
+ this.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
810
+ }
798
811
  const scopes = this.addCoordinationByObject(input);
799
812
  if (meta) {
800
813
  const metaScope = this.addMetaCoordination();
@@ -808,8 +821,28 @@ export class VitessceConfig {
808
821
  view.useCoordinationByObject(scopes);
809
822
  });
810
823
  }
824
+ if (scopePrefix) {
825
+ this.getNextScope = getNextScope;
826
+ }
811
827
  return this;
812
828
  }
829
+ /**
830
+ * Set the value for a coordination scope.
831
+ * If a coordination object for the coordination type does not yet exist
832
+ * in the coordination space, it will be created.
833
+ * @param {string} cType The coordination type.
834
+ * @param {string} cScope The coordination scope.
835
+ * @param {any} cValue The initial value for the coordination scope.
836
+ * @returns {VitessceConfigCoordinationScope} A coordination scope instance.
837
+ */
838
+ setCoordinationValue(cType, cScope, cValue) {
839
+ const scope = new VitessceConfigCoordinationScope(cType, cScope, cValue);
840
+ if (!this.config.coordinationSpace[scope.cType]) {
841
+ this.config.coordinationSpace[scope.cType] = {};
842
+ }
843
+ this.config.coordinationSpace[scope.cType][scope.cScope] = scope;
844
+ return scope;
845
+ }
813
846
  /**
814
847
  * Set the layout of views.
815
848
  * @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A
@@ -898,3 +931,21 @@ export class VitessceConfig {
898
931
  return vc;
899
932
  }
900
933
  }
934
+ // For usage during auto-initialization.
935
+ export function getCoordinationSpaceAndScopes(partialCoordinationValues, scopePrefix) {
936
+ const vc = new VitessceConfig({ schemaVersion: '1.0.16', name: '__dummy__' });
937
+ vc.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
938
+ const dataset = vc.addDataset('__dummy__');
939
+ const v1 = vc.addView(dataset, '__dummy__');
940
+ vc.linkViewsByObject([v1], partialCoordinationValues, { meta: true });
941
+ const vcJson = vc.toJSON();
942
+ // TODO: remove the "dataset" coordination type from these objects.
943
+ const { coordinationSpace } = vcJson;
944
+ const { coordinationScopes } = vcJson.layout[0];
945
+ const { coordinationScopesBy } = vcJson.layout[0];
946
+ return {
947
+ coordinationSpace,
948
+ coordinationScopes,
949
+ coordinationScopesBy,
950
+ };
951
+ }
@@ -701,6 +701,111 @@ describe('src/api/VitessceConfig.js', () => {
701
701
  initStrategy: 'auto',
702
702
  });
703
703
  });
704
+ it('can use _meta_ complex coordination with a scope prefix via the linkViewsByObject convenience function', () => {
705
+ const config = new VitessceConfig({
706
+ schemaVersion: '1.0.16',
707
+ name: 'My config',
708
+ });
709
+ const dataset = config.addDataset('My dataset');
710
+ const spatialView = config.addView(dataset, 'spatial');
711
+ const lcView = config.addView(dataset, 'layerController');
712
+ config.linkViewsByObject([spatialView, lcView], {
713
+ spatialImageLayer: CL([
714
+ {
715
+ spatialLayerOpacity: 1,
716
+ spatialImageChannel: CL([
717
+ {
718
+ spatialTargetC: 0,
719
+ spatialChannelColor: [255, 0, 0],
720
+ },
721
+ {
722
+ spatialTargetC: 1,
723
+ spatialChannelColor: [0, 255, 0],
724
+ },
725
+ ]),
726
+ },
727
+ ]),
728
+ }, { scopePrefix: 'SOME_PREFIX_' });
729
+ const configJSON = config.toJSON();
730
+ expect(configJSON).toEqual({
731
+ version: '1.0.16',
732
+ name: 'My config',
733
+ datasets: [
734
+ { uid: 'A', name: 'My dataset', files: [] },
735
+ ],
736
+ coordinationSpace: {
737
+ dataset: { A: 'A' },
738
+ spatialImageLayer: { SOME_PREFIX_0: '__dummy__' },
739
+ spatialLayerOpacity: { SOME_PREFIX_0: 1 },
740
+ spatialImageChannel: {
741
+ SOME_PREFIX_0: '__dummy__',
742
+ SOME_PREFIX_1: '__dummy__',
743
+ },
744
+ spatialTargetC: {
745
+ SOME_PREFIX_0: 0,
746
+ SOME_PREFIX_1: 1,
747
+ },
748
+ spatialChannelColor: {
749
+ SOME_PREFIX_0: [255, 0, 0],
750
+ SOME_PREFIX_1: [0, 255, 0],
751
+ },
752
+ metaCoordinationScopes: {
753
+ SOME_PREFIX_0: {
754
+ spatialImageLayer: ['SOME_PREFIX_0'],
755
+ },
756
+ },
757
+ metaCoordinationScopesBy: {
758
+ SOME_PREFIX_0: {
759
+ spatialImageLayer: {
760
+ spatialLayerOpacity: {
761
+ SOME_PREFIX_0: 'SOME_PREFIX_0',
762
+ },
763
+ spatialImageChannel: {
764
+ SOME_PREFIX_0: ['SOME_PREFIX_0', 'SOME_PREFIX_1'],
765
+ },
766
+ },
767
+ spatialImageChannel: {
768
+ spatialTargetC: {
769
+ SOME_PREFIX_0: 'SOME_PREFIX_0',
770
+ SOME_PREFIX_1: 'SOME_PREFIX_1',
771
+ },
772
+ spatialChannelColor: {
773
+ SOME_PREFIX_0: 'SOME_PREFIX_0',
774
+ SOME_PREFIX_1: 'SOME_PREFIX_1',
775
+ },
776
+ },
777
+ },
778
+ },
779
+ },
780
+ layout: [
781
+ {
782
+ component: 'spatial',
783
+ coordinationScopes: {
784
+ dataset: 'A',
785
+ metaCoordinationScopes: ['SOME_PREFIX_0'],
786
+ metaCoordinationScopesBy: ['SOME_PREFIX_0'],
787
+ },
788
+ x: 0,
789
+ y: 0,
790
+ w: 1,
791
+ h: 1,
792
+ },
793
+ {
794
+ component: 'layerController',
795
+ coordinationScopes: {
796
+ dataset: 'A',
797
+ metaCoordinationScopes: ['SOME_PREFIX_0'],
798
+ metaCoordinationScopesBy: ['SOME_PREFIX_0'],
799
+ },
800
+ x: 0,
801
+ y: 0,
802
+ w: 1,
803
+ h: 1,
804
+ },
805
+ ],
806
+ initStrategy: 'auto',
807
+ });
808
+ });
704
809
  it('can add a coordination scope using the link views convenience function', () => {
705
810
  const config = new VitessceConfig({
706
811
  schemaVersion: '1.0.4',
@@ -1,4 +1,4 @@
1
- export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel } from "./VitessceConfig.js";
1
+ export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel, getCoordinationSpaceAndScopes } from "./VitessceConfig.js";
2
2
  export { generateConfig, getHintOptions } from "./VitessceAutoConfig.js";
3
3
  export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from "./constants.js";
4
4
  //# sourceMappingURL=index.d.ts.map
package/dist-tsc/index.js CHANGED
@@ -1,3 +1,4 @@
1
- export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel } from './VitessceConfig.js';
1
+ export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel, getCoordinationSpaceAndScopes } from './VitessceConfig.js';
2
2
  export { generateConfig, getHintOptions } from './VitessceAutoConfig.js';
3
3
  export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from './constants.js';
4
+ export { getInitialCoordinationScopePrefix, getInitialCoordinationScopeName, } from '@vitessce/utils';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/config",
3
- "version": "3.3.1",
3
+ "version": "3.3.3",
4
4
  "author": "Gehlenborg Lab",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -16,8 +16,8 @@
16
16
  "dist-tsc"
17
17
  ],
18
18
  "dependencies": {
19
- "@vitessce/constants-internal": "3.3.1",
20
- "@vitessce/utils": "3.3.1"
19
+ "@vitessce/constants-internal": "3.3.3",
20
+ "@vitessce/utils": "3.3.3"
21
21
  },
22
22
  "scripts": {
23
23
  "bundle": "pnpm exec vite build -c ../../scripts/vite.config.js",
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
2
  import { CoordinationType } from '@vitessce/constants-internal';
3
- import { fromEntries, getNextScope } from '@vitessce/utils';
3
+ import { fromEntries, getNextScope, createPrefixedGetNextScopeNumeric } from '@vitessce/utils';
4
4
 
5
5
  /**
6
6
  * Class representing a file within a Vitessce config dataset.
@@ -430,11 +430,12 @@ export class VitessceConfigCoordinationScope {
430
430
  * Construct a new coordination scope instance.
431
431
  * @param {string} cType The coordination type for this coordination scope.
432
432
  * @param {string} cScope The name of the coordination scope.
433
+ * @param {[any]} cValue Optional. The coordination value of the coordination scope.
433
434
  */
434
- constructor(cType, cScope) {
435
+ constructor(cType, cScope, cValue = null) {
435
436
  this.cType = cType;
436
437
  this.cScope = cScope;
437
- this.cValue = null;
438
+ this.cValue = cValue;
438
439
  }
439
440
 
440
441
  /**
@@ -555,6 +556,7 @@ export class VitessceConfig {
555
556
  layout: [],
556
557
  initStrategy: 'auto',
557
558
  };
559
+ this.getNextScope = getNextScope;
558
560
  }
559
561
 
560
562
  /**
@@ -569,7 +571,7 @@ export class VitessceConfig {
569
571
  addDataset(name = undefined, description = undefined, options = undefined) {
570
572
  const { uid } = options || {};
571
573
  const prevDatasetUids = this.config.datasets.map(d => d.dataset.uid);
572
- const nextUid = (uid || getNextScope(prevDatasetUids));
574
+ const nextUid = (uid || this.getNextScope(prevDatasetUids));
573
575
  const newDataset = new VitessceConfigDataset(nextUid, name, description);
574
576
  this.config.datasets.push(newDataset);
575
577
  const [newScope] = this.addCoordination(CoordinationType.DATASET);
@@ -641,7 +643,7 @@ export class VitessceConfig {
641
643
  ? Object.keys(this.config.coordinationSpace[cType])
642
644
  : []
643
645
  );
644
- const scope = new VitessceConfigCoordinationScope(cType, getNextScope(prevScopes));
646
+ const scope = new VitessceConfigCoordinationScope(cType, this.getNextScope(prevScopes));
645
647
  if (!this.config.coordinationSpace[scope.cType]) {
646
648
  this.config.coordinationSpace[scope.cType] = {};
647
649
  }
@@ -668,8 +670,8 @@ export class VitessceConfig {
668
670
  : []
669
671
  );
670
672
  const metaContainer = new VitessceConfigMetaCoordinationScope(
671
- getNextScope(prevMetaScopes),
672
- getNextScope(prevMetaByScopes),
673
+ this.getNextScope(prevMetaScopes),
674
+ this.getNextScope(prevMetaByScopes),
673
675
  );
674
676
  if (!this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES]) {
675
677
  this.config.coordinationSpace[CoordinationType.META_COORDINATION_SCOPES] = {};
@@ -777,6 +779,9 @@ export class VitessceConfig {
777
779
  */
778
780
  const processLevel = (level) => {
779
781
  const result = {};
782
+ if (level === null) {
783
+ return result;
784
+ }
780
785
  Object.entries(level).forEach(([cType, nextLevelOrInitialValue]) => {
781
786
  // Check if value of object is instanceof CoordinationLevel
782
787
  // (otherwise assume it is the coordination value).
@@ -859,10 +864,19 @@ export class VitessceConfig {
859
864
  * instance, or a `CoordinationLevel` instance.
860
865
  * The CL function takes an array of objects as its argument, and returns a CoordinationLevel
861
866
  * instance, to support nesting.
862
- * @param {boolean} meta Should meta-coordination be used? Optional. By default, true.
867
+ * @param {object|null} options
868
+ * @param {bool} options.meta Should meta-coordination be used? Optional.
869
+ * By default, true.
870
+ * @param {string|null} options.scopePrefix A prefix to add to all
871
+ * coordination scope names. Optional.
863
872
  * @returns {VitessceConfig} This, to allow chaining.
864
873
  */
865
- linkViewsByObject(views, input, meta = true) {
874
+ linkViewsByObject(views, input, options = null) {
875
+ const { meta = true, scopePrefix = null } = options || {};
876
+
877
+ if (scopePrefix) {
878
+ this.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
879
+ }
866
880
  const scopes = this.addCoordinationByObject(input);
867
881
  if (meta) {
868
882
  const metaScope = this.addMetaCoordination();
@@ -876,9 +890,30 @@ export class VitessceConfig {
876
890
  view.useCoordinationByObject(scopes);
877
891
  });
878
892
  }
893
+ if (scopePrefix) {
894
+ this.getNextScope = getNextScope;
895
+ }
879
896
  return this;
880
897
  }
881
898
 
899
+ /**
900
+ * Set the value for a coordination scope.
901
+ * If a coordination object for the coordination type does not yet exist
902
+ * in the coordination space, it will be created.
903
+ * @param {string} cType The coordination type.
904
+ * @param {string} cScope The coordination scope.
905
+ * @param {any} cValue The initial value for the coordination scope.
906
+ * @returns {VitessceConfigCoordinationScope} A coordination scope instance.
907
+ */
908
+ setCoordinationValue(cType, cScope, cValue) {
909
+ const scope = new VitessceConfigCoordinationScope(cType, cScope, cValue);
910
+ if (!this.config.coordinationSpace[scope.cType]) {
911
+ this.config.coordinationSpace[scope.cType] = {};
912
+ }
913
+ this.config.coordinationSpace[scope.cType][scope.cScope] = scope;
914
+ return scope;
915
+ }
916
+
882
917
  /**
883
918
  * Set the layout of views.
884
919
  * @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A
@@ -973,3 +1008,23 @@ export class VitessceConfig {
973
1008
  return vc;
974
1009
  }
975
1010
  }
1011
+
1012
+ // For usage during auto-initialization.
1013
+ export function getCoordinationSpaceAndScopes(partialCoordinationValues, scopePrefix) {
1014
+ const vc = new VitessceConfig({ schemaVersion: '1.0.16', name: '__dummy__' });
1015
+ vc.getNextScope = createPrefixedGetNextScopeNumeric(scopePrefix);
1016
+ const dataset = vc.addDataset('__dummy__');
1017
+ const v1 = vc.addView(dataset, '__dummy__');
1018
+ vc.linkViewsByObject([v1], partialCoordinationValues, { meta: true });
1019
+ const vcJson = vc.toJSON();
1020
+ // TODO: remove the "dataset" coordination type from these objects.
1021
+ const { coordinationSpace } = vcJson;
1022
+ const { coordinationScopes } = vcJson.layout[0];
1023
+ const { coordinationScopesBy } = vcJson.layout[0];
1024
+
1025
+ return {
1026
+ coordinationSpace,
1027
+ coordinationScopes,
1028
+ coordinationScopesBy,
1029
+ };
1030
+ }
@@ -744,6 +744,116 @@ describe('src/api/VitessceConfig.js', () => {
744
744
  });
745
745
  });
746
746
 
747
+ it('can use _meta_ complex coordination with a scope prefix via the linkViewsByObject convenience function', () => {
748
+ const config = new VitessceConfig({
749
+ schemaVersion: '1.0.16',
750
+ name: 'My config',
751
+ });
752
+ const dataset = config.addDataset('My dataset');
753
+
754
+ const spatialView = config.addView(dataset, 'spatial');
755
+ const lcView = config.addView(dataset, 'layerController');
756
+
757
+ config.linkViewsByObject([spatialView, lcView], {
758
+ spatialImageLayer: CL([
759
+ {
760
+ spatialLayerOpacity: 1,
761
+ spatialImageChannel: CL([
762
+ {
763
+ spatialTargetC: 0,
764
+ spatialChannelColor: [255, 0, 0],
765
+ },
766
+ {
767
+ spatialTargetC: 1,
768
+ spatialChannelColor: [0, 255, 0],
769
+ },
770
+ ]),
771
+ },
772
+ ]),
773
+ }, { scopePrefix: 'SOME_PREFIX_' });
774
+
775
+ const configJSON = config.toJSON();
776
+
777
+ expect(configJSON).toEqual({
778
+ version: '1.0.16',
779
+ name: 'My config',
780
+ datasets: [
781
+ { uid: 'A', name: 'My dataset', files: [] },
782
+ ],
783
+ coordinationSpace: {
784
+ dataset: { A: 'A' },
785
+ spatialImageLayer: { SOME_PREFIX_0: '__dummy__' },
786
+ spatialLayerOpacity: { SOME_PREFIX_0: 1 },
787
+ spatialImageChannel: {
788
+ SOME_PREFIX_0: '__dummy__',
789
+ SOME_PREFIX_1: '__dummy__',
790
+ },
791
+ spatialTargetC: {
792
+ SOME_PREFIX_0: 0,
793
+ SOME_PREFIX_1: 1,
794
+ },
795
+ spatialChannelColor: {
796
+ SOME_PREFIX_0: [255, 0, 0],
797
+ SOME_PREFIX_1: [0, 255, 0],
798
+ },
799
+ metaCoordinationScopes: {
800
+ SOME_PREFIX_0: {
801
+ spatialImageLayer: ['SOME_PREFIX_0'],
802
+ },
803
+ },
804
+ metaCoordinationScopesBy: {
805
+ SOME_PREFIX_0: {
806
+ spatialImageLayer: {
807
+ spatialLayerOpacity: {
808
+ SOME_PREFIX_0: 'SOME_PREFIX_0',
809
+ },
810
+ spatialImageChannel: {
811
+ SOME_PREFIX_0: ['SOME_PREFIX_0', 'SOME_PREFIX_1'],
812
+ },
813
+ },
814
+ spatialImageChannel: {
815
+ spatialTargetC: {
816
+ SOME_PREFIX_0: 'SOME_PREFIX_0',
817
+ SOME_PREFIX_1: 'SOME_PREFIX_1',
818
+ },
819
+ spatialChannelColor: {
820
+ SOME_PREFIX_0: 'SOME_PREFIX_0',
821
+ SOME_PREFIX_1: 'SOME_PREFIX_1',
822
+ },
823
+ },
824
+ },
825
+ },
826
+ },
827
+ layout: [
828
+ {
829
+ component: 'spatial',
830
+ coordinationScopes: {
831
+ dataset: 'A',
832
+ metaCoordinationScopes: ['SOME_PREFIX_0'],
833
+ metaCoordinationScopesBy: ['SOME_PREFIX_0'],
834
+ },
835
+ x: 0,
836
+ y: 0,
837
+ w: 1,
838
+ h: 1,
839
+ },
840
+ {
841
+ component: 'layerController',
842
+ coordinationScopes: {
843
+ dataset: 'A',
844
+ metaCoordinationScopes: ['SOME_PREFIX_0'],
845
+ metaCoordinationScopesBy: ['SOME_PREFIX_0'],
846
+ },
847
+ x: 0,
848
+ y: 0,
849
+ w: 1,
850
+ h: 1,
851
+ },
852
+ ],
853
+ initStrategy: 'auto',
854
+ });
855
+ });
856
+
747
857
  it('can add a coordination scope using the link views convenience function', () => {
748
858
  const config = new VitessceConfig({
749
859
  schemaVersion: '1.0.4',
package/src/index.js CHANGED
@@ -1,3 +1,7 @@
1
- export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel } from './VitessceConfig.js';
1
+ export { VitessceConfig, vconcat, hconcat, CL as CoordinationLevel, getCoordinationSpaceAndScopes } from './VitessceConfig.js';
2
2
  export { generateConfig, getHintOptions } from './VitessceAutoConfig.js';
3
3
  export { HINTS_CONFIG, HINT_TYPE_TO_FILE_TYPE_MAP } from './constants.js';
4
+ export {
5
+ getInitialCoordinationScopePrefix,
6
+ getInitialCoordinationScopeName,
7
+ } from '@vitessce/utils';