@genome-spy/app 0.75.0 → 0.76.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 (66) hide show
  1. package/dist/AbortablePromiseCache-beUIcZcW.js +96 -0
  2. package/dist/agentApi-CzdacisO.js +25226 -0
  3. package/dist/agentApi.es.js +9460 -0
  4. package/dist/agentShared.es.js +4742 -0
  5. package/dist/{blosc-oa0DlI6G.js → blosc-BX4BJ8sR.js} +1 -1
  6. package/dist/componentStyles-CIXoKEp0.js +2182 -0
  7. package/dist/dialog.es.js +377 -0
  8. package/dist/{esm-n0auOe11.js → esm-BH0wx5y-.js} +1 -1
  9. package/dist/esm-BLfLaJtE.js +121 -0
  10. package/dist/{esm-D-WfYOx7.js → esm-BWsx1OJ2.js} +25 -25
  11. package/dist/{browser-Dvlo92rx.js → esm-BY4T8YoD.js} +38 -22
  12. package/dist/esm-CZvS2Ldm.js +155 -0
  13. package/dist/esm-CdIesJ1z.js +461 -0
  14. package/dist/{esm-DCCYNvaz.js → esm-Cr7pLUfG.js} +50 -50
  15. package/dist/esm-D-y0Ce1M.js +573 -0
  16. package/dist/esm-DHOMWRoL.js +1426 -0
  17. package/dist/{esm-Cmo4qEPr.js → esm-DJUb6vy0.js} +5 -5
  18. package/dist/esm-DPS6pYKF.js +1248 -0
  19. package/dist/esm-DRZ5LLNH.js +142 -0
  20. package/dist/esm-DjF6pKy5.js +369 -0
  21. package/dist/esm-PDPkTR1_.js +1015 -0
  22. package/dist/esm-s_SlArJ8.js +298 -0
  23. package/dist/index.es.js +7874 -28936
  24. package/dist/index.js +1127 -729
  25. package/dist/lit-ymUSmGBw.js +510 -0
  26. package/dist/{lz4-jZ0zyLBa.js → lz4-BSYl80V8.js} +1 -1
  27. package/dist/parquetRead-m8-8_SpH.js +1609 -0
  28. package/dist/schema.json +445 -85
  29. package/dist/style.css +1 -1
  30. package/dist/viewUtils-C5htqZCm.js +14147 -0
  31. package/dist/{zstd-C6ksIG9r.js → zstd-BAfRM3IH.js} +1 -1
  32. package/package.json +30 -5
  33. package/src/agentApi/index.d.ts +123 -0
  34. package/src/agentShared/index.d.ts +97 -0
  35. package/src/agentShared/types.d.ts +8 -0
  36. package/src/appTypes.d.ts +75 -0
  37. package/src/bookmark/databaseSchema.d.ts +33 -0
  38. package/src/charts/boxplotTypes.d.ts +15 -0
  39. package/src/charts/sampleAttributePlotTypes.d.ts +149 -0
  40. package/src/coreSpecAugmentation.d.ts +29 -0
  41. package/src/dialog/index.d.ts +5 -0
  42. package/src/embedTypes.d.ts +9 -0
  43. package/src/index.d.ts +16 -0
  44. package/src/sampleView/sampleViewTypes.d.ts +174 -0
  45. package/src/sampleView/state/payloadTypes.d.ts +400 -0
  46. package/src/sampleView/state/sampleState.d.ts +76 -0
  47. package/src/sampleView/types.d.ts +125 -0
  48. package/src/spec/appSpec.d.ts +54 -0
  49. package/src/spec/sampleView.d.ts +487 -0
  50. package/src/spec/view.d.ts +124 -0
  51. package/src/state/paramProvenanceTypes.d.ts +215 -0
  52. package/src/state/selectionExpansionTypes.d.ts +77 -0
  53. package/src/state.d.ts +97 -0
  54. package/src/types/lz-string.d.ts +24 -0
  55. package/src/types/vega-loader.d.ts +1 -0
  56. package/src/utils/colorScaleSummary.d.ts +15 -0
  57. package/src/utils/statistics/fieldSummary.d.ts +49 -0
  58. package/src/vite-env.d.ts +6 -0
  59. package/LICENSE +0 -21
  60. /package/dist/{AbortablePromiseCache-3gHJdF3E.js → AbortablePromiseCache-BDH1cqFl.js} +0 -0
  61. /package/dist/{chunk-INHXZS53-fPMmEwMt.js → chunk-INHXZS53-DwEV9sMh.js} +0 -0
  62. /package/dist/{esm-BygJiwh0.js → esm-BL9SNSnj.js} +0 -0
  63. /package/dist/{esm-B8-vSu-c.js → esm-BwW--bVV.js} +0 -0
  64. /package/dist/{esm-CGX-qz1d.js → esm-Bz_92nH0.js} +0 -0
  65. /package/dist/{esm-CuMSzCHy.js → esm-D2_c7lXY.js} +0 -0
  66. /package/dist/{parquetRead-CJe1UPsz.js → parquetRead-BuEN-6yG.js} +0 -0
@@ -0,0 +1,174 @@
1
+ import { SampleHierarchy } from "./state/sampleSlice.js";
2
+ import { Group } from "./state/sampleState.js";
3
+ import { LocSize } from "@genome-spy/core/view/layout/flexLayout.js";
4
+ import { ChromosomalLocus } from "@genome-spy/core/spec/genome.js";
5
+ import { Scalar } from "@genome-spy/core/spec/channel.js";
6
+ import { ComplexDomain, NumericDomain } from "@genome-spy/core/spec/scale.js";
7
+ import { AggregationSpec, Interval } from "./types.js";
8
+ import ViewContext from "@genome-spy/core/types/viewContext.js";
9
+ import type {
10
+ ParamSelector,
11
+ ViewSelector,
12
+ } from "@genome-spy/core/view/viewUtilTypes.d.ts";
13
+
14
+ export type { ParamSelector, ViewSelector };
15
+
16
+ /**
17
+ * View reference used in SampleView actions. Legacy values may be a view name
18
+ * string, but selectors are the unambiguous, bookmark-friendly form.
19
+ */
20
+ export type ViewRef = string | ViewSelector;
21
+
22
+ export interface KeyAndLocation<T> {
23
+ key: T;
24
+ locSize: LocSize;
25
+ }
26
+
27
+ export type GroupLocation = KeyAndLocation<Group[]>;
28
+ export type SampleLocation = KeyAndLocation<string>;
29
+
30
+ export interface GroupDetails {
31
+ index: number;
32
+ group: Group;
33
+ depth: number;
34
+ n: number;
35
+ }
36
+
37
+ export type HierarchicalGroupLocation = KeyAndLocation<GroupDetails>;
38
+
39
+ export type InterpolatedLocationMaker = <K, T extends KeyAndLocation<K>>(
40
+ fitted: T[],
41
+ scrollable: T[]
42
+ ) => T[];
43
+
44
+ export interface Locations {
45
+ groups: HierarchicalGroupLocation[];
46
+ samples: SampleLocation[];
47
+ summaries: GroupLocation[];
48
+ }
49
+
50
+ export interface LocationContext {
51
+ getSampleHierarchy: () => SampleHierarchy;
52
+ getHeight: () => number;
53
+ getSummaryHeight: () => number;
54
+ onLocationUpdate: (arg: { sampleHeight: number }) => void;
55
+ viewContext: ViewContext;
56
+ isStickySummaries: () => boolean;
57
+ }
58
+
59
+ export interface BaseSpecifier {
60
+ /**
61
+ * A unique view reference. Legacy values may be a view name string.
62
+ */
63
+ view: ViewRef;
64
+
65
+ /**
66
+ * Attribute or field name used by the specifier.
67
+ */
68
+ field: string;
69
+
70
+ /**
71
+ * The x-scale domain that was visible when the action was triggered.
72
+ */
73
+ domainAtActionTime?: NumericDomain | ComplexDomain;
74
+ }
75
+
76
+ /**
77
+ * Specifier that points to a single locus or scalar coordinate.
78
+ */
79
+ export interface LocusSpecifier extends BaseSpecifier {
80
+ /**
81
+ * Coordinate on the `x` axis. May be a number of locus on a chromosome.
82
+ * Alternatively, a scalar if a categorical scale is used.
83
+ */
84
+ locus: Scalar | ChromosomalLocus;
85
+ }
86
+
87
+ /**
88
+ * Interval that will be resolved from a selection parameter.
89
+ */
90
+ export interface SelectionIntervalSource {
91
+ type: "selection";
92
+ selector: ParamSelector;
93
+ }
94
+
95
+ /**
96
+ * Literal interval or selection-backed interval reference.
97
+ */
98
+ export type IntervalReference = Interval | SelectionIntervalSource;
99
+
100
+ /**
101
+ * Interval plus the container key used by some helper functions.
102
+ */
103
+ export type IntervalCarrier = { interval: IntervalReference };
104
+
105
+ /**
106
+ * Predicate applied to raw view features before interval aggregation.
107
+ */
108
+ export type FeatureFilter =
109
+ | {
110
+ /** Feature field to test. */
111
+ field: string;
112
+
113
+ /** Retain features where the field is exactly this value. */
114
+ operator: "eq";
115
+
116
+ /** Matched value. */
117
+ value: Scalar | null;
118
+ }
119
+ | {
120
+ /** Feature field to test. */
121
+ field: string;
122
+
123
+ /** Retain features where the field is one of the listed values. */
124
+ operator: "in";
125
+
126
+ /** Matched values. */
127
+ values: (Scalar | null)[];
128
+ }
129
+ | {
130
+ /** Feature field to test. */
131
+ field: string;
132
+
133
+ /** Numeric comparison operator. */
134
+ operator: "lt" | "lte" | "gt" | "gte";
135
+
136
+ /** Numeric threshold. */
137
+ value: number;
138
+ };
139
+
140
+ /**
141
+ * Specifier that summarizes a field over an interval.
142
+ */
143
+ export interface IntervalSpecifier extends BaseSpecifier {
144
+ /** Literal interval or a selection source resolved at action execution time */
145
+ interval: IntervalReference;
146
+
147
+ /** Predicate applied to raw features before aggregation. */
148
+ featureFilter?: FeatureFilter;
149
+
150
+ /** Aggregation operation to apply over the interval */
151
+ aggregation: AggregationSpec;
152
+ }
153
+
154
+ /**
155
+ * Supported view-backed attribute specifiers used by the sample collection
156
+ * actions.
157
+ */
158
+ export type ViewAttributeSpecifier = LocusSpecifier | IntervalSpecifier;
159
+
160
+ /**
161
+ * @param {ViewAttributeSpecifier} specifier
162
+ * @returns {specifier is IntervalSpecifier}
163
+ */
164
+ export function isIntervalSpecifier(
165
+ specifier: ViewAttributeSpecifier
166
+ ): specifier is IntervalSpecifier;
167
+
168
+ export function isLiteralInterval(
169
+ interval: IntervalReference
170
+ ): interval is Interval;
171
+
172
+ export function isIntervalSource(
173
+ interval: IntervalReference
174
+ ): interval is SelectionIntervalSource;
@@ -0,0 +1,400 @@
1
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
2
+ /*
3
+ * Many payload types are empty interfaces that extend PayloadWithAttribute.
4
+ * They are semantically distinct types for FSA actions but don't add new properties.
5
+ * Using interfaces keeps them consistent with other payload types in this file.
6
+ */
7
+
8
+ import { Scalar } from "@genome-spy/core/spec/channel.js";
9
+ import { Sample } from "./sampleState.js";
10
+ import { AggregationSpec, AttributeIdentifier, Interval } from "../types.js";
11
+ import { SampleAttributeDef } from "@genome-spy/app/spec/sampleView.js";
12
+
13
+ /*
14
+ * This file defines the payload types for actions that modify sample view state.
15
+ * The actions conform to the Flux Standard Action (FSA) pattern,
16
+ * where the payload is contained in the `payload` property of the action object.
17
+ * See [FSA](https://github.com/redux-utilities/flux-standard-action?tab=readme-ov-file#example)
18
+ *
19
+ * Some utility types related to sample view state are also defined here.
20
+
21
+ * Note: There are two types of paths:
22
+ * 1. Metadata attribute paths, which identify attributes in the metadata hierarchy.
23
+ * 2. Sample group paths, which identify groups in the sample grouping hierarchy.
24
+
25
+ * These are both represented as string arrays, but they refer to different hierarchies.
26
+ */
27
+
28
+ /**
29
+ * An identifier or name for a sample attribute.
30
+ *
31
+ * As the identifiers may represent paths in a hierarchy, they are strings
32
+ * where path segments are separated by a forward slash ('/').
33
+ * Separators in path segments are always escaped to avoid ambiguity.
34
+ */
35
+ export type AttributeName = string;
36
+
37
+ /**
38
+ * Columnar metadata representation
39
+ * Keys are attribute names, values are arrays of attribute values
40
+ * for each sample, in the same order as the samples array.
41
+ *
42
+ * Columnar format is more efficient for storage in bookmarked actions.
43
+ */
44
+ export interface ColumnarMetadata {
45
+ /**
46
+ * Sample ids for the rows in this payload.
47
+ *
48
+ * Every other column must follow this same order.
49
+ */
50
+ sample: string[];
51
+
52
+ /**
53
+ * Metadata columns keyed by attribute name.
54
+ */
55
+ [key: AttributeName]: Scalar[];
56
+ }
57
+
58
+ export interface SetSamples {
59
+ /**
60
+ * Samples to install as the current collection.
61
+ *
62
+ * Each sample must have a unique `id`.
63
+ */
64
+ samples: Sample[];
65
+ }
66
+
67
+ export interface SetMetadata {
68
+ /**
69
+ * Metadata encoded in columnar form, aligned to the sample order.
70
+ */
71
+ columnarMetadata: ColumnarMetadata;
72
+
73
+ /**
74
+ * Optional attribute definitions for the incoming metadata columns.
75
+ *
76
+ * Use this to preserve attribute types, titles, scales, or other metadata
77
+ * settings instead of relying on inference.
78
+ */
79
+ attributeDefs?: Record<AttributeName, SampleAttributeDef>;
80
+
81
+ /**
82
+ * Whether to replace the current metadata set.
83
+ *
84
+ * If `true`, only the provided columns remain. If omitted or `false`, the
85
+ * provided columns are merged into the existing metadata.
86
+ */
87
+ replace?: boolean;
88
+ }
89
+
90
+ export interface DeriveMetadata extends PayloadWithAttribute {
91
+ /**
92
+ * Name of the derived metadata column.
93
+ *
94
+ * This becomes the leaf attribute name written into metadata. Prefer a
95
+ * short user-facing name.
96
+ */
97
+ name: string;
98
+
99
+ /**
100
+ * Optional metadata group path for the derived column.
101
+ *
102
+ * When provided, the resulting attribute is written under
103
+ * `groupPath/name`.
104
+ */
105
+ groupPath?: string;
106
+
107
+ /**
108
+ * If omitted, derived metadata may inherit an authored source scale when
109
+ * the aggregation preserves the source value domain. Use `null` to force
110
+ * automatic scale inference without inheritance.
111
+ */
112
+ scale?: SampleAttributeDef["scale"] | null;
113
+ }
114
+
115
+ export interface AddMetadataFromSource {
116
+ /**
117
+ * Configured metadata source to read from.
118
+ *
119
+ * Omit this only when exactly one source is available.
120
+ */
121
+ sourceId?: string;
122
+
123
+ /**
124
+ * Column ids to import from the selected source.
125
+ */
126
+ columnIds: string[];
127
+
128
+ /**
129
+ * Optional metadata group path override for the imported columns.
130
+ */
131
+ groupPath?: string;
132
+
133
+ /**
134
+ * Whether to replace the current metadata set.
135
+ *
136
+ * If `true`, only the imported columns remain. If omitted or `false`, the
137
+ * imported columns are merged into the existing metadata.
138
+ */
139
+ replace?: boolean;
140
+
141
+ /**
142
+ * @hidden
143
+ */
144
+ _augmented?: {
145
+ metadata: SetMetadata;
146
+ };
147
+ }
148
+
149
+ export type ThresholdOperator = "lt" | "lte";
150
+
151
+ export type ComparisonOperatorType = "lt" | "lte" | "eq" | "gte" | "gt";
152
+
153
+ /**
154
+ * Exact categorical value used by nominal sample filters.
155
+ */
156
+ export type NominalFilterValue = Scalar | null;
157
+
158
+ /**
159
+ * Numeric threshold used when partitioning or filtering quantitative values.
160
+ */
161
+ export interface Threshold {
162
+ /**
163
+ * Upper-bound comparison used for the interval ending at this threshold.
164
+ *
165
+ * `lt` makes the upper endpoint exclusive (`<`). `lte` makes the upper
166
+ * endpoint inclusive (`<=`).
167
+ */
168
+ operator: ThresholdOperator;
169
+
170
+ /**
171
+ * Numeric threshold value.
172
+ */
173
+ operand: number;
174
+ }
175
+
176
+ export interface IntervalAggregation {
177
+ interval: Interval;
178
+ aggregation: AggregationSpec;
179
+ }
180
+
181
+ /**
182
+ * @hidden
183
+ */
184
+ export interface AugmentedAttribute {
185
+ /** Values accessed just prior to dispatching the action to reducers */
186
+ values: Record<string, any>;
187
+ /** Domain of the accessed attribute, if needed */
188
+ domain?: Scalar[];
189
+ /** Derived metadata payload computed prior to dispatch */
190
+ metadata?: SetMetadata;
191
+ /** Condition values for actions that compare two attributes */
192
+ conditionValues?: Record<string, any>;
193
+ }
194
+
195
+ export interface QuantitativeAttributeCondition {
196
+ /**
197
+ * Quantitative attribute tested within each category.
198
+ */
199
+ attribute: AttributeIdentifier;
200
+
201
+ /**
202
+ * Comparison applied as `attributeValue operator operand`.
203
+ */
204
+ operator: ComparisonOperatorType;
205
+
206
+ /**
207
+ * Numeric value on the right-hand side of the comparison.
208
+ */
209
+ operand: number;
210
+ }
211
+
212
+ export interface CategoricalAttributeCondition {
213
+ /**
214
+ * Categorical or ordinal attribute tested within each category.
215
+ */
216
+ attribute: AttributeIdentifier;
217
+
218
+ /**
219
+ * Membership test applied as `attributeValue in values`.
220
+ */
221
+ operator: "in";
222
+
223
+ /**
224
+ * Attribute values that satisfy the condition.
225
+ */
226
+ values: Scalar[];
227
+
228
+ /**
229
+ * Requirement for selected values within each retained category.
230
+ *
231
+ * `any` retains a category when at least one sample has one of the selected
232
+ * values. `all` requires every selected value to occur in at least one
233
+ * sample in the category.
234
+ *
235
+ * __Default value:__ `"any"`
236
+ */
237
+ required?: "any" | "all";
238
+ }
239
+
240
+ export type AttributeCondition =
241
+ | QuantitativeAttributeCondition
242
+ | CategoricalAttributeCondition;
243
+
244
+ /**
245
+ * Payloads that reference an abstract attribute include this interface.
246
+ * As some of the attributes reside outside the redux store, their values
247
+ * are accessed just prior to dispatching the action to reducers and
248
+ * stored in `_augmented` here for later use.
249
+ */
250
+ export interface PayloadWithAttribute {
251
+ /**
252
+ * Attribute operated on by the action.
253
+ *
254
+ * Its current values are resolved before the reducer runs and then used by
255
+ * sorting, filtering, grouping, or metadata derivation.
256
+ */
257
+ attribute: AttributeIdentifier;
258
+
259
+ /**
260
+ * @hidden
261
+ */
262
+ _augmented?: AugmentedAttribute;
263
+ }
264
+
265
+ /**
266
+ * Payload for sorting samples in descending order by an attribute.
267
+ */
268
+ export interface SortBy extends PayloadWithAttribute {}
269
+
270
+ /**
271
+ * Payload for retaining the first sample of each distinct category.
272
+ */
273
+ export interface RetainFirstOfEach extends PayloadWithAttribute {}
274
+
275
+ export interface RetainFirstNCategories extends PayloadWithAttribute {
276
+ /**
277
+ * Maximum number of distinct categories to retain.
278
+ *
279
+ * Categories are taken in first-seen order within each current group.
280
+ *
281
+ * @minimum 1
282
+ */
283
+ n: number;
284
+ }
285
+
286
+ /**
287
+ * Payload for removing samples whose attribute value is `undefined` or `null`.
288
+ */
289
+ export interface RemoveUndefined extends PayloadWithAttribute {}
290
+
291
+ /**
292
+ * Payload for grouping by a categorical or ordinal attribute.
293
+ */
294
+ export interface GroupByNominal extends PayloadWithAttribute {}
295
+
296
+ /**
297
+ * Payload for grouping a quantitative attribute into quartiles.
298
+ */
299
+ export interface GroupToQuartiles extends PayloadWithAttribute {}
300
+
301
+ export interface GroupByThresholds extends PayloadWithAttribute {
302
+ /**
303
+ * Thresholds used to stratify the samples.
304
+ *
305
+ * Supply these in ascending operand order. Adjacent thresholds define the
306
+ * output intervals.
307
+ */
308
+ thresholds: [Threshold, ...Threshold[]];
309
+
310
+ /**
311
+ * Optional display titles for the generated groups.
312
+ *
313
+ * When provided, the array must contain one title for each output interval:
314
+ * exactly `thresholds.length + 1` titles. Titles are ordered from the
315
+ * lowest interval to the highest interval, matching the ascending threshold
316
+ * order. For thresholds `[10, 20]`, titles correspond to values below `10`,
317
+ * values from `10` to `20`, and values above `20`.
318
+ *
319
+ * Titles must be non-empty and unique. The original interval labels are
320
+ * still preserved for each group.
321
+ */
322
+ groupTitles?: string[];
323
+ }
324
+
325
+ export interface RemoveGroup {
326
+ /**
327
+ * Group names from outermost to innermost, excluding the implicit ROOT.
328
+ */
329
+ path: string[];
330
+ }
331
+
332
+ /**
333
+ * Payload for filtering samples by comparing a quantitative attribute
334
+ * against a numeric operand.
335
+ */
336
+ export interface FilterByQuantitative extends PayloadWithAttribute {
337
+ /**
338
+ * Comparison applied as `attributeValue operator operand`.
339
+ */
340
+ operator: ComparisonOperatorType;
341
+
342
+ /**
343
+ * Numeric value on the right-hand side of the comparison.
344
+ */
345
+ operand: number;
346
+ }
347
+
348
+ export interface RetainCategoriesByAttribute extends PayloadWithAttribute {
349
+ /**
350
+ * Categorical attribute whose categories are retained.
351
+ *
352
+ * All samples with a retained category value are kept.
353
+ */
354
+ attribute: AttributeIdentifier;
355
+
356
+ /**
357
+ * Per-sample condition used to decide which values of `attribute` are retained.
358
+ *
359
+ * A value of `attribute` is retained when at least one sample with that value
360
+ * satisfies this condition. All samples with retained `attribute` values are
361
+ * kept.
362
+ */
363
+ condition: AttributeCondition;
364
+ }
365
+
366
+ export interface FilterByNominal extends PayloadWithAttribute {
367
+ /**
368
+ * Attribute values matched by exact equality.
369
+ */
370
+ values: NominalFilterValue[];
371
+
372
+ /**
373
+ * Whether to remove matching samples instead of retaining them.
374
+ *
375
+ * If omitted or `false`, only matching samples are kept.
376
+ */
377
+ remove?: boolean;
378
+ }
379
+
380
+ export interface RetainMatched extends PayloadWithAttribute {
381
+ /**
382
+ * Attribute whose values must be present in every current non-empty group.
383
+ */
384
+ attribute: AttributeIdentifier;
385
+ }
386
+
387
+ /**
388
+ * Which categories belong to which group.
389
+ */
390
+ export type CustomGroups = Record<string, Scalar[]>;
391
+
392
+ export interface GroupCustom extends PayloadWithAttribute {
393
+ /**
394
+ * Mapping from output group name to attribute values assigned to that group.
395
+ *
396
+ * Samples whose value is not listed in any group are omitted from the
397
+ * grouped result.
398
+ */
399
+ groups: CustomGroups;
400
+ }
@@ -0,0 +1,76 @@
1
+ import { scalar } from "@genome-spy/core/utils/domainArray.js";
2
+ import { SampleAttributeDef } from "@genome-spy/app/spec/sampleView.js";
3
+ import { AttributeIdentifier } from "../types.js";
4
+ import { PayloadAction } from "@reduxjs/toolkit";
5
+
6
+ export type SampleId = string;
7
+
8
+ /**
9
+ * Sample metadata
10
+ */
11
+ export interface Sample {
12
+ id: SampleId;
13
+
14
+ displayName: string;
15
+
16
+ /** For internal use. Identifies the sample facet efficiently. */
17
+ indexNumber: number;
18
+ }
19
+
20
+ export type Metadatum = Record<string, scalar>;
21
+ export type Metadata = Record<SampleId, Metadatum>;
22
+
23
+ export interface BaseGroup {
24
+ /** e.g., an attribute value that forms a group. Used as a key when identifying subgroups. */
25
+ name: string;
26
+
27
+ /** A descriptive title for the group. May contain quantile intervals, etc. */
28
+ title: string;
29
+
30
+ /** Original generated title for derived groups, such as threshold intervals. */
31
+ generatedTitle?: string;
32
+ }
33
+
34
+ export interface SampleGroup extends BaseGroup {
35
+ samples: SampleId[];
36
+ }
37
+
38
+ export interface GroupGroup extends BaseGroup {
39
+ groups: Group[];
40
+ }
41
+
42
+ export type Group = SampleGroup | GroupGroup;
43
+
44
+ export interface GroupMetadata {
45
+ /** e.g., an attribute that is used for partitioning */
46
+ attribute: AttributeIdentifier;
47
+ }
48
+
49
+ export interface SampleMetadata {
50
+ /** SampleIds as keys, attributes as values */
51
+ entities: Metadata;
52
+ /** Names of all available metadata attributes */
53
+ attributeNames: string[];
54
+ /** A definition for each attribute or attribute group */
55
+ attributeDefs?: Record<string, SampleAttributeDef>;
56
+ }
57
+
58
+ export interface SampleHierarchy {
59
+ /** All known samples that are available for use */
60
+ sampleData: {
61
+ ids: SampleId[];
62
+ entities: Record<SampleId, Sample>;
63
+ };
64
+
65
+ /** Metadata for samples. It's ok to have some samples missing. */
66
+ sampleMetadata: SampleMetadata;
67
+
68
+ /** Metadata for each hierarchy level. Does not include the root. */
69
+ groupMetadata: GroupMetadata[];
70
+
71
+ /** The root of the hierarchy */
72
+ rootGroup: Group;
73
+
74
+ // TODO: Extract this into a separate interface
75
+ lastAction?: PayloadAction;
76
+ }