@jbrowse/plugin-config 4.3.0 → 5.0.0-beta.2

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 (72) hide show
  1. package/esm/ConfigurationEditorWidget/components/AddNewField.d.ts +4 -0
  2. package/esm/ConfigurationEditorWidget/components/AddNewField.js +28 -0
  3. package/esm/ConfigurationEditorWidget/components/BooleanEditor.d.ts +4 -2
  4. package/esm/ConfigurationEditorWidget/components/BooleanEditor.js +19 -4
  5. package/esm/ConfigurationEditorWidget/components/CallbackEditor.d.ts +4 -2
  6. package/esm/ConfigurationEditorWidget/components/CallbackEditor.js +24 -42
  7. package/esm/ConfigurationEditorWidget/components/ColorEditor.d.ts +3 -11
  8. package/esm/ConfigurationEditorWidget/components/ColorEditor.js +28 -20
  9. package/esm/ConfigurationEditorWidget/components/ConfigurationEditor.d.ts +2 -3
  10. package/esm/ConfigurationEditorWidget/components/ConfigurationEditor.js +108 -17
  11. package/esm/ConfigurationEditorWidget/components/ConfigurationTextField.d.ts +1 -1
  12. package/esm/ConfigurationEditorWidget/components/ConfigurationTextField.js +10 -2
  13. package/esm/ConfigurationEditorWidget/components/HeadingComponent.d.ts +1 -1
  14. package/esm/ConfigurationEditorWidget/components/IntegerEditor.d.ts +10 -0
  15. package/esm/ConfigurationEditorWidget/components/IntegerEditor.js +9 -0
  16. package/esm/ConfigurationEditorWidget/components/JsonEditor.d.ts +3 -1
  17. package/esm/ConfigurationEditorWidget/components/JsonEditor.js +27 -40
  18. package/esm/ConfigurationEditorWidget/components/MapEntryCard.d.ts +8 -0
  19. package/esm/ConfigurationEditorWidget/components/MapEntryCard.js +23 -0
  20. package/esm/ConfigurationEditorWidget/components/MapSlotEditor.d.ts +8 -0
  21. package/esm/ConfigurationEditorWidget/components/MapSlotEditor.js +18 -0
  22. package/esm/ConfigurationEditorWidget/components/NumberEditor.d.ts +6 -4
  23. package/esm/ConfigurationEditorWidget/components/NumberEditor.js +24 -15
  24. package/esm/ConfigurationEditorWidget/components/NumberMapEditor.d.ts +4 -4
  25. package/esm/ConfigurationEditorWidget/components/NumberMapEditor.js +7 -31
  26. package/esm/ConfigurationEditorWidget/components/SlotEditor.d.ts +4 -5
  27. package/esm/ConfigurationEditorWidget/components/SlotEditor.js +83 -48
  28. package/esm/ConfigurationEditorWidget/components/StringArrayEditor.d.ts +3 -4
  29. package/esm/ConfigurationEditorWidget/components/StringArrayEditor.js +11 -24
  30. package/esm/ConfigurationEditorWidget/components/StringArrayMapEditor.d.ts +3 -6
  31. package/esm/ConfigurationEditorWidget/components/StringArrayMapEditor.js +14 -39
  32. package/esm/ConfigurationEditorWidget/components/TypeSelector.d.ts +1 -1
  33. package/esm/ConfigurationEditorWidget/components/TypeSelector.js +2 -2
  34. package/esm/ConfigurationEditorWidget/components/singularSlotName.d.ts +13 -0
  35. package/esm/ConfigurationEditorWidget/components/singularSlotName.js +23 -0
  36. package/esm/ConfigurationEditorWidget/components/useSlotEditorStyles.d.ts +2 -2
  37. package/esm/ConfigurationEditorWidget/components/useSlotEditorStyles.js +6 -1
  38. package/esm/ConfigurationEditorWidget/index.js +3 -3
  39. package/esm/ConfigurationEditorWidget/model.d.ts +8 -1
  40. package/esm/ConfigurationEditorWidget/model.js +40 -1
  41. package/esm/FromConfigAdapter/FromConfigAdapter.d.ts +6 -1
  42. package/esm/FromConfigAdapter/FromConfigAdapter.js +31 -1
  43. package/esm/FromConfigAdapter/configSchema.d.ts +36 -3
  44. package/esm/FromConfigAdapter/configSchema.js +34 -2
  45. package/esm/FromConfigAdapter/index.js +2 -2
  46. package/esm/FromConfigRegionsAdapter/FromConfigRegionsAdapter.d.ts +8 -0
  47. package/esm/FromConfigRegionsAdapter/FromConfigRegionsAdapter.js +10 -25
  48. package/esm/FromConfigRegionsAdapter/configSchema.d.ts +42 -3
  49. package/esm/FromConfigRegionsAdapter/configSchema.js +39 -2
  50. package/esm/FromConfigRegionsAdapter/index.js +2 -2
  51. package/esm/FromConfigSequenceAdapter/FromConfigSequenceAdapter.d.ts +15 -2
  52. package/esm/FromConfigSequenceAdapter/FromConfigSequenceAdapter.js +32 -40
  53. package/esm/FromConfigSequenceAdapter/configSchema.d.ts +41 -3
  54. package/esm/FromConfigSequenceAdapter/configSchema.js +38 -2
  55. package/esm/FromConfigSequenceAdapter/index.js +2 -2
  56. package/esm/NcbiSequenceReportAliasAdapter/NcbiSequenceReportAliasAdapter.d.ts +5 -4
  57. package/esm/NcbiSequenceReportAliasAdapter/NcbiSequenceReportAliasAdapter.js +28 -24
  58. package/esm/NcbiSequenceReportAliasAdapter/configSchema.d.ts +77 -9
  59. package/esm/NcbiSequenceReportAliasAdapter/configSchema.js +79 -12
  60. package/esm/NcbiSequenceReportAliasAdapter/index.js +3 -2
  61. package/esm/RefNameAliasAdapter/RefNameAliasAdapter.d.ts +4 -3
  62. package/esm/RefNameAliasAdapter/RefNameAliasAdapter.js +22 -28
  63. package/esm/RefNameAliasAdapter/configSchema.d.ts +87 -12
  64. package/esm/RefNameAliasAdapter/configSchema.js +86 -12
  65. package/esm/RefNameAliasAdapter/index.js +3 -2
  66. package/esm/aliasUtils.d.ts +4 -0
  67. package/esm/aliasUtils.js +26 -0
  68. package/esm/index.d.ts +2 -2
  69. package/esm/index.js +7 -7
  70. package/esm/normalizeUriSnapshot.d.ts +1 -0
  71. package/esm/normalizeUriSnapshot.js +13 -0
  72. package/package.json +11 -15
@@ -1,11 +1,18 @@
1
1
  import type PluginManager from '@jbrowse/core/PluginManager';
2
2
  import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
+ /**
4
+ * #stateModel ConfigurationEditorWidget
5
+ * Widget for editing a config model's slots in a form: holds the target
6
+ * configuration and debounce-saves edits back to the session.
7
+ */
3
8
  export default function stateModelFactory(_pluginManager: PluginManager): import("@jbrowse/mobx-state-tree").IModelType<{
4
9
  id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
5
- type: import("@jbrowse/mobx-state-tree").ISimpleType<"ConfigurationEditorWidget">;
10
+ type: import("@jbrowse/mobx-state-tree").ILiteralType<"ConfigurationEditorWidget">;
6
11
  }, {
7
12
  target: AnyConfigurationModel | undefined;
13
+ expandedDisplayId: string | undefined;
8
14
  } & {
9
15
  setTarget(newTarget: AnyConfigurationModel | undefined): void;
16
+ setExpandedDisplayId(displayId: string | undefined): void;
10
17
  afterCreate(): void;
11
18
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>;
@@ -2,6 +2,11 @@ import { getSession } from '@jbrowse/core/util';
2
2
  import { ElementId } from '@jbrowse/core/util/types/mst';
3
3
  import { addDisposer, getSnapshot, types } from '@jbrowse/mobx-state-tree';
4
4
  import { autorun } from 'mobx';
5
+ /**
6
+ * #stateModel ConfigurationEditorWidget
7
+ * Widget for editing a config model's slots in a form: holds the target
8
+ * configuration and debounce-saves edits back to the session.
9
+ */
5
10
  export default function stateModelFactory(_pluginManager) {
6
11
  return types
7
12
  .model('ConfigurationEditorWidget', {
@@ -9,24 +14,58 @@ export default function stateModelFactory(_pluginManager) {
9
14
  type: types.literal('ConfigurationEditorWidget'),
10
15
  })
11
16
  .volatile(() => ({
17
+ // Target is stored as volatile since it doesn't need to be serialized.
18
+ // The target is an MST model from track.configuration (which creates
19
+ // an MST model from frozen config via ConfigurationReference).
12
20
  target: undefined,
21
+ // displayId of the display active in the view this editor was opened
22
+ // from; its config accordion expands by default while the track's other
23
+ // (incompatible/inactive) displays start collapsed
24
+ expandedDisplayId: undefined,
13
25
  }))
14
26
  .actions(self => ({
15
27
  setTarget(newTarget) {
16
28
  self.target = newTarget;
17
29
  },
30
+ setExpandedDisplayId(displayId) {
31
+ self.expandedDisplayId = displayId;
32
+ },
18
33
  afterCreate() {
19
34
  let timeout;
35
+ // Auto-save configuration changes with 400ms debounce. The autorun
36
+ // reacts to any changes in the target configuration model and persists
37
+ // them back to the session after a short delay via
38
+ // updateTrackConfiguration, which routes admin edits to the jbrowse
39
+ // config in place and everyone else's to a shareable per-track delta
40
+ // (trackConfigDeltas) against the admin base. It keys off trackId; in
41
+ // practice the widget is only opened on track configs. A config with no
42
+ // trackId (assembly/connection) degrades gracefully: updateTrackConfiguration
43
+ // finds no base/session/connection home and the edit just applies to the
44
+ // live MST node in memory for this session.
45
+ //
46
+ // BaseTrackModel's afterAttach runs a sibling debounced save (a reaction
47
+ // on the same config node) for direct setSlot quick-edits on a *shown*
48
+ // track. Both intentionally coexist: this widget also handles an unshown
49
+ // track edited from the selector, which has no BaseTrackModel. When both
50
+ // fire they compute an identical delta, deduped in updateTrackConfiguration
51
+ // — don't drop one to "simplify".
20
52
  addDisposer(self, autorun(() => {
21
53
  if (self.target) {
54
+ // track configs (the practical case) carry a trackId; a
55
+ // trackId-less snapshot degrades to an in-memory edit (see above)
22
56
  const snapshot = getSnapshot(self.target);
23
57
  clearTimeout(timeout);
24
58
  timeout = setTimeout(() => {
25
59
  const session = getSession(self);
26
- session.jbrowse.updateTrackConf(snapshot);
60
+ session.updateTrackConfiguration(snapshot);
27
61
  }, 400);
28
62
  }
29
63
  }));
64
+ // ensure a pending debounced save can't fire after disposal, where
65
+ // getSession(self) would throw on the now-detached node
66
+ addDisposer(self, () => {
67
+ clearTimeout(timeout);
68
+ });
30
69
  },
31
70
  }));
32
71
  }
@@ -4,6 +4,11 @@ import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
4
4
  import type { getSubAdapterType } from '@jbrowse/core/data_adapters/dataAdapterCache';
5
5
  import type { Feature, SimpleFeatureSerialized } from '@jbrowse/core/util/simpleFeature';
6
6
  import type { NoAssemblyRegion } from '@jbrowse/core/util/types';
7
+ export declare function mergeFeaturesToRegions(features: Map<string, Feature[]>): {
8
+ refName: string;
9
+ start: number;
10
+ end: number;
11
+ }[];
7
12
  export declare function makeFeatures(fdata: SimpleFeatureSerialized[]): Map<string, Feature[]>;
8
13
  export default class FromConfigAdapter extends BaseFeatureDataAdapter {
9
14
  protected features: Map<string, Feature[]>;
@@ -11,7 +16,7 @@ export default class FromConfigAdapter extends BaseFeatureDataAdapter {
11
16
  getRefNames(): Promise<string[]>;
12
17
  getRefNameAliases(): Promise<{
13
18
  refName: string;
14
- aliases: any;
19
+ aliases: unknown;
15
20
  }[]>;
16
21
  getFeatures(region: NoAssemblyRegion): import("rxjs").Observable<Feature>;
17
22
  }
@@ -2,6 +2,35 @@ import { readConfObject } from '@jbrowse/core/configuration';
2
2
  import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
3
3
  import { ObservableCreate } from '@jbrowse/core/util/rxjs';
4
4
  import SimpleFeature from '@jbrowse/core/util/simpleFeature';
5
+ export function mergeFeaturesToRegions(features) {
6
+ const regions = [];
7
+ for (const [refName, feats] of features) {
8
+ let currentRegion;
9
+ for (const feature of feats) {
10
+ if (currentRegion &&
11
+ currentRegion.end >= feature.get('start') &&
12
+ currentRegion.start <= feature.get('end')) {
13
+ // take the max: a fully-contained feature (smaller end) must not
14
+ // shrink the merged region
15
+ currentRegion.end = Math.max(currentRegion.end, feature.get('end'));
16
+ }
17
+ else {
18
+ if (currentRegion) {
19
+ regions.push(currentRegion);
20
+ }
21
+ currentRegion = {
22
+ refName,
23
+ start: feature.get('start'),
24
+ end: feature.get('end'),
25
+ };
26
+ }
27
+ }
28
+ if (currentRegion) {
29
+ regions.push(currentRegion);
30
+ }
31
+ }
32
+ return regions;
33
+ }
5
34
  export function makeFeatures(fdata) {
6
35
  const features = new Map();
7
36
  for (const entry of fdata) {
@@ -14,6 +43,7 @@ export function makeFeatures(fdata) {
14
43
  }
15
44
  bucket.push(f);
16
45
  }
46
+ // sort the features on each reference sequence by start coordinate
17
47
  for (const refFeatures of features.values()) {
18
48
  refFeatures.sort((a, b) => a.get('start') - b.get('start'));
19
49
  }
@@ -38,7 +68,7 @@ export default class FromConfigAdapter extends BaseFeatureDataAdapter {
38
68
  getFeatures(region) {
39
69
  const { refName, start, end } = region;
40
70
  return ObservableCreate(async (observer) => {
41
- const features = this.features.get(refName) || [];
71
+ const features = this.features.get(refName) ?? [];
42
72
  for (const f of features) {
43
73
  if (f.get('end') > start && f.get('start') < end) {
44
74
  observer.next(f);
@@ -1,7 +1,40 @@
1
+ /**
2
+ * #config FromConfigAdapter
3
+ * #trackType FeatureTrack
4
+ * #fileFormat inline | Inline features | Features written straight into config.json
5
+ * supplies features inline in the config instead of reading a file, useful for
6
+ * small feature sets added via a URL or session spec
7
+ *
8
+ * #example
9
+ * ```js
10
+ * {
11
+ * type: 'FromConfigAdapter',
12
+ * features: [
13
+ * { uniqueId: 'f1', refName: 'ctgA', start: 100, end: 200, name: 'feature1' },
14
+ * ],
15
+ * }
16
+ * ```
17
+ */
1
18
  declare const configSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
- features: {
3
- type: string;
4
- defaultValue: never[];
19
+ /**
20
+ * #slot
21
+ * stable identifier used as the adapter cache key; avoids hashing the
22
+ * (potentially large) features array. optional — falls back to hash.
23
+ */
24
+ readonly adapterId: {
25
+ readonly type: "string";
26
+ readonly defaultValue: "";
27
+ };
28
+ /**
29
+ * #slot
30
+ * the features themselves, as an array of plain objects. Each needs a
31
+ * `uniqueId`, `refName`, `start` and `end` (0-based half-open); anything
32
+ * else — `name`, `type`, `score`, `strand`, nested `subfeatures` — is
33
+ * carried through onto the feature as-is.
34
+ */
35
+ readonly features: {
36
+ readonly type: "frozen";
37
+ readonly defaultValue: readonly [];
5
38
  };
6
39
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
7
40
  export default configSchema;
@@ -1,9 +1,41 @@
1
1
  import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
- function x() { }
2
+ /**
3
+ * #config FromConfigAdapter
4
+ * #trackType FeatureTrack
5
+ * #fileFormat inline | Inline features | Features written straight into config.json
6
+ * supplies features inline in the config instead of reading a file, useful for
7
+ * small feature sets added via a URL or session spec
8
+ *
9
+ * #example
10
+ * ```js
11
+ * {
12
+ * type: 'FromConfigAdapter',
13
+ * features: [
14
+ * { uniqueId: 'f1', refName: 'ctgA', start: 100, end: 200, name: 'feature1' },
15
+ * ],
16
+ * }
17
+ * ```
18
+ */
3
19
  const configSchema = ConfigurationSchema('FromConfigAdapter', {
20
+ /**
21
+ * #slot
22
+ * stable identifier used as the adapter cache key; avoids hashing the
23
+ * (potentially large) features array. optional — falls back to hash.
24
+ */
25
+ adapterId: {
26
+ type: 'string',
27
+ defaultValue: '',
28
+ },
29
+ /**
30
+ * #slot
31
+ * the features themselves, as an array of plain objects. Each needs a
32
+ * `uniqueId`, `refName`, `start` and `end` (0-based half-open); anything
33
+ * else — `name`, `type`, `score`, `strand`, nested `subfeatures` — is
34
+ * carried through onto the feature as-is.
35
+ */
4
36
  features: {
5
37
  type: 'frozen',
6
38
  defaultValue: [],
7
39
  },
8
- }, { explicitlyTyped: true, implicitIdentifier: 'adapterId' });
40
+ }, { explicitlyTyped: true });
9
41
  export default configSchema;
@@ -1,10 +1,10 @@
1
1
  import { AdapterType } from '@jbrowse/core/pluggableElementTypes';
2
- import configSchema from "./configSchema.js";
2
+ import configSchema from './configSchema.js';
3
3
  export default function FromConfigAdapterF(pluginManager) {
4
4
  pluginManager.addAdapterType(() => new AdapterType({
5
5
  name: 'FromConfigAdapter',
6
6
  configSchema,
7
- getAdapterClass: () => import("./FromConfigAdapter.js").then(r => r.default),
7
+ getAdapterClass: () => import('./FromConfigAdapter.js').then(r => r.default),
8
8
  adapterMetadata: {
9
9
  hiddenFromGUI: true,
10
10
  },
@@ -3,9 +3,17 @@ import type PluginManager from '@jbrowse/core/PluginManager';
3
3
  import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
4
4
  import type { RegionsAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
5
5
  import type { getSubAdapterType } from '@jbrowse/core/data_adapters/dataAdapterCache';
6
+ /**
7
+ * Adapter that just returns the features defined in its `features` configuration
8
+ * key, like:
9
+ * `"features": [ { "refName": "ctgA", "start":1, "end":20 }, ... ]`
10
+ */
6
11
  export default class FromConfigRegionsAdapter extends BaseAdapter implements RegionsAdapter {
7
12
  private features;
8
13
  constructor(config: AnyConfigurationModel, getSubAdapter?: getSubAdapterType, pluginManager?: PluginManager);
14
+ /**
15
+ * Get refName, start, and end for all features after collapsing any overlaps
16
+ */
9
17
  getRegions(): Promise<{
10
18
  refName: string;
11
19
  start: number;
@@ -1,6 +1,11 @@
1
1
  import { readConfObject } from '@jbrowse/core/configuration';
2
2
  import { BaseAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
3
- import { makeFeatures } from "../FromConfigAdapter/FromConfigAdapter.js";
3
+ import { makeFeatures, mergeFeaturesToRegions, } from '../FromConfigAdapter/FromConfigAdapter.js';
4
+ /**
5
+ * Adapter that just returns the features defined in its `features` configuration
6
+ * key, like:
7
+ * `"features": [ { "refName": "ctgA", "start":1, "end":20 }, ... ]`
8
+ */
4
9
  export default class FromConfigRegionsAdapter extends BaseAdapter {
5
10
  features;
6
11
  constructor(config, getSubAdapter, pluginManager) {
@@ -8,31 +13,11 @@ export default class FromConfigRegionsAdapter extends BaseAdapter {
8
13
  const f = readConfObject(config, 'features');
9
14
  this.features = makeFeatures(f);
10
15
  }
16
+ /**
17
+ * Get refName, start, and end for all features after collapsing any overlaps
18
+ */
11
19
  async getRegions() {
12
- const regions = [];
13
- for (const [refName, features] of this.features) {
14
- let currentRegion;
15
- for (const feature of features) {
16
- if (currentRegion &&
17
- currentRegion.end >= feature.get('start') &&
18
- currentRegion.start <= feature.get('end')) {
19
- currentRegion.end = feature.get('end');
20
- }
21
- else {
22
- if (currentRegion) {
23
- regions.push(currentRegion);
24
- }
25
- currentRegion = {
26
- refName,
27
- start: feature.get('start'),
28
- end: feature.get('end'),
29
- };
30
- }
31
- }
32
- if (currentRegion) {
33
- regions.push(currentRegion);
34
- }
35
- }
20
+ const regions = mergeFeaturesToRegions(this.features);
36
21
  regions.sort((a, b) => a.refName.localeCompare(b.refName));
37
22
  return regions;
38
23
  }
@@ -1,7 +1,46 @@
1
+ /**
2
+ * #config FromConfigRegionsAdapter
3
+ * #trackType ReferenceSequenceTrack
4
+ * #fileFormat inline | Inline regions | refNames and sizes only, no sequence
5
+ * used for specifying refNames+sizes of an assembly
6
+ *
7
+ * #example
8
+ * Supplies refNames+sizes with no sequence, as the adapter of an assembly's
9
+ * `sequence` (a `ReferenceSequenceTrack`):
10
+ * ```js
11
+ * {
12
+ * type: 'ReferenceSequenceTrack',
13
+ * trackId: 'my_refseq',
14
+ * adapter: {
15
+ * type: 'FromConfigRegionsAdapter',
16
+ * features: [
17
+ * { uniqueId: 'ctgA', refName: 'ctgA', start: 0, end: 50000 },
18
+ * { uniqueId: 'ctgB', refName: 'ctgB', start: 0, end: 6079 },
19
+ * ],
20
+ * },
21
+ * }
22
+ * ```
23
+ */
1
24
  declare const regionsConfigSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
- features: {
3
- type: string;
4
- defaultValue: never[];
25
+ /**
26
+ * #slot
27
+ * stable identifier used as the adapter cache key; avoids hashing the
28
+ * (potentially large) features array. optional — falls back to hash.
29
+ */
30
+ readonly adapterId: {
31
+ readonly type: "string";
32
+ readonly defaultValue: "";
33
+ };
34
+ /**
35
+ * #slot
36
+ * one entry per reference sequence, each with a `uniqueId`, `refName`,
37
+ * `start: 0` and `end` set to that sequence's length. This is what defines
38
+ * the assembly's reference names and sizes; no bases are supplied, so
39
+ * base-level views are empty.
40
+ */
41
+ readonly features: {
42
+ readonly type: "frozen";
43
+ readonly defaultValue: readonly [];
5
44
  };
6
45
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
7
46
  export default regionsConfigSchema;
@@ -1,12 +1,49 @@
1
1
  import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
- function x() { }
2
+ /**
3
+ * #config FromConfigRegionsAdapter
4
+ * #trackType ReferenceSequenceTrack
5
+ * #fileFormat inline | Inline regions | refNames and sizes only, no sequence
6
+ * used for specifying refNames+sizes of an assembly
7
+ *
8
+ * #example
9
+ * Supplies refNames+sizes with no sequence, as the adapter of an assembly's
10
+ * `sequence` (a `ReferenceSequenceTrack`):
11
+ * ```js
12
+ * {
13
+ * type: 'ReferenceSequenceTrack',
14
+ * trackId: 'my_refseq',
15
+ * adapter: {
16
+ * type: 'FromConfigRegionsAdapter',
17
+ * features: [
18
+ * { uniqueId: 'ctgA', refName: 'ctgA', start: 0, end: 50000 },
19
+ * { uniqueId: 'ctgB', refName: 'ctgB', start: 0, end: 6079 },
20
+ * ],
21
+ * },
22
+ * }
23
+ * ```
24
+ */
3
25
  const regionsConfigSchema = ConfigurationSchema('FromConfigRegionsAdapter', {
26
+ /**
27
+ * #slot
28
+ * stable identifier used as the adapter cache key; avoids hashing the
29
+ * (potentially large) features array. optional — falls back to hash.
30
+ */
31
+ adapterId: {
32
+ type: 'string',
33
+ defaultValue: '',
34
+ },
35
+ /**
36
+ * #slot
37
+ * one entry per reference sequence, each with a `uniqueId`, `refName`,
38
+ * `start: 0` and `end` set to that sequence's length. This is what defines
39
+ * the assembly's reference names and sizes; no bases are supplied, so
40
+ * base-level views are empty.
41
+ */
4
42
  features: {
5
43
  type: 'frozen',
6
44
  defaultValue: [],
7
45
  },
8
46
  }, {
9
47
  explicitlyTyped: true,
10
- implicitIdentifier: 'adapterId',
11
48
  });
12
49
  export default regionsConfigSchema;
@@ -1,10 +1,10 @@
1
1
  import { AdapterType } from '@jbrowse/core/pluggableElementTypes';
2
- import configSchema from "./configSchema.js";
2
+ import configSchema from './configSchema.js';
3
3
  export default function FromConfigRegionsAdapterF(pluginManager) {
4
4
  pluginManager.addAdapterType(() => new AdapterType({
5
5
  name: 'FromConfigRegionsAdapter',
6
6
  configSchema,
7
- getAdapterClass: () => import("./FromConfigRegionsAdapter.js").then(r => r.default),
7
+ getAdapterClass: () => import('./FromConfigRegionsAdapter.js').then(r => r.default),
8
8
  adapterMetadata: {
9
9
  hiddenFromGUI: true,
10
10
  },
@@ -1,12 +1,25 @@
1
1
  import FromConfigAdapter from '../FromConfigAdapter/FromConfigAdapter.ts';
2
- import type { RegionsAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
2
+ import type { BaseOptions, RegionsAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
3
3
  import type { Feature } from '@jbrowse/core/util/simpleFeature';
4
4
  import type { NoAssemblyRegion } from '@jbrowse/core/util/types';
5
5
  export default class FromConfigSequenceAdapter extends FromConfigAdapter implements RegionsAdapter {
6
+ /**
7
+ * Fetch features for a certain region
8
+ * @param region - Region
9
+ * @returns Observable of Feature objects in the region
10
+ */
6
11
  getFeatures(region: NoAssemblyRegion): import("rxjs").Observable<Feature>;
7
12
  getRegions(): Promise<{
13
+ refName: string;
8
14
  start: number;
9
15
  end: number;
10
- refName: string;
11
16
  }[]>;
17
+ /**
18
+ * `BaseSequenceAdapter`'s default, which this cannot inherit — it extends
19
+ * `FromConfigAdapter` — and which anything resolving a sequence SUB-adapter
20
+ * requires by name: `getSequenceSubAdapter` checks for the method and refuses
21
+ * an adapter without it, so a GC content track over a from-config assembly
22
+ * failed with "provides no sequence".
23
+ */
24
+ getSequence(region: NoAssemblyRegion, opts?: BaseOptions): Promise<string | undefined>;
12
25
  }
@@ -1,50 +1,42 @@
1
1
  import { ObservableCreate } from '@jbrowse/core/util/rxjs';
2
2
  import SimpleFeature from '@jbrowse/core/util/simpleFeature';
3
- import { firstValueFrom } from 'rxjs';
4
- import { toArray } from 'rxjs/operators';
5
- import FromConfigAdapter from "../FromConfigAdapter/FromConfigAdapter.js";
3
+ import FromConfigAdapter, { mergeFeaturesToRegions, } from '../FromConfigAdapter/FromConfigAdapter.js';
6
4
  export default class FromConfigSequenceAdapter extends FromConfigAdapter {
5
+ /**
6
+ * Fetch features for a certain region
7
+ * @param region - Region
8
+ * @returns Observable of Feature objects in the region
9
+ */
7
10
  getFeatures(region) {
8
- return ObservableCreate(async (observer) => {
9
- const feats = await firstValueFrom(super.getFeatures(region).pipe(toArray()));
10
- const feat = feats[0];
11
- observer.next(new SimpleFeature({
12
- ...feat.toJSON(),
13
- uniqueId: `${feat.id()}:${region.start}-${region.end}`,
14
- end: region.end,
15
- start: region.start,
16
- seq: feat
17
- .get('seq')
18
- .slice(Math.max(region.start - feat.get('start'), 0), Math.max(region.end - feat.get('start'), 0)),
19
- }));
11
+ const { refName, start, end } = region;
12
+ return ObservableCreate(observer => {
13
+ const feats = this.features.get(refName) ?? [];
14
+ const feat = feats.find(f => f.get('end') > start && f.get('start') < end);
15
+ if (feat) {
16
+ const featStart = feat.get('start');
17
+ observer.next(new SimpleFeature({
18
+ ...feat.toJSON(),
19
+ uniqueId: `${feat.id()}:${start}-${end}`,
20
+ start,
21
+ end,
22
+ seq: feat.get('seq').slice(Math.max(start - featStart, 0), Math.max(end - featStart, 0)),
23
+ }));
24
+ }
20
25
  observer.complete();
21
26
  });
22
27
  }
23
28
  async getRegions() {
24
- const regions = [];
25
- for (const [refName, features] of this.features) {
26
- let currentRegion;
27
- for (const feature of features) {
28
- if (currentRegion &&
29
- currentRegion.end >= feature.get('start') &&
30
- currentRegion.start <= feature.get('end')) {
31
- currentRegion.end = feature.get('end');
32
- }
33
- else {
34
- if (currentRegion) {
35
- regions.push(currentRegion);
36
- }
37
- currentRegion = {
38
- refName,
39
- start: feature.get('start'),
40
- end: feature.get('end'),
41
- };
42
- }
43
- }
44
- if (currentRegion) {
45
- regions.push(currentRegion);
46
- }
47
- }
48
- return regions;
29
+ return mergeFeaturesToRegions(this.features);
30
+ }
31
+ /**
32
+ * `BaseSequenceAdapter`'s default, which this cannot inherit — it extends
33
+ * `FromConfigAdapter` — and which anything resolving a sequence SUB-adapter
34
+ * requires by name: `getSequenceSubAdapter` checks for the method and refuses
35
+ * an adapter without it, so a GC content track over a from-config assembly
36
+ * failed with "provides no sequence".
37
+ */
38
+ async getSequence(region, opts) {
39
+ const features = await this.getFeaturesArray({ ...region, assemblyName: '' }, opts);
40
+ return features[0]?.get('seq');
49
41
  }
50
42
  }
@@ -1,7 +1,45 @@
1
+ /**
2
+ * #config FromConfigSequenceAdapter
3
+ * #trackType ReferenceSequenceTrack
4
+ * #fileFormat inline | Inline sequence | Each feature's `seq` holds the bases for its region
5
+ * supplies reference sequence inline in the config; each feature's `seq` holds
6
+ * the bases for its region
7
+ *
8
+ * #example
9
+ * Used as the adapter of an assembly's `sequence` (a `ReferenceSequenceTrack`):
10
+ * ```js
11
+ * {
12
+ * type: 'ReferenceSequenceTrack',
13
+ * trackId: 'my_refseq',
14
+ * adapter: {
15
+ * type: 'FromConfigSequenceAdapter',
16
+ * features: [
17
+ * { uniqueId: 'ctgA', refName: 'ctgA', start: 0, end: 10, seq: 'ATGCATGCAT' },
18
+ * ],
19
+ * },
20
+ * }
21
+ * ```
22
+ */
1
23
  declare const sequenceConfigSchema: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
- features: {
3
- type: string;
4
- defaultValue: never[];
24
+ /**
25
+ * #slot
26
+ * stable identifier used as the adapter cache key; avoids hashing the
27
+ * (potentially large) features array. optional — falls back to hash.
28
+ */
29
+ readonly adapterId: {
30
+ readonly type: "string";
31
+ readonly defaultValue: "";
32
+ };
33
+ /**
34
+ * #slot
35
+ * one entry per reference sequence, each with a `uniqueId`, `refName`,
36
+ * `start`, `end`, and a `seq` string holding the bases for that span. The
37
+ * bases live in the config, so this is for small sequences — a plasmid, a
38
+ * test contig — not a genome.
39
+ */
40
+ readonly features: {
41
+ readonly type: "frozen";
42
+ readonly defaultValue: readonly [];
5
43
  };
6
44
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
7
45
  export default sequenceConfigSchema;