@jbrowse/plugin-legacy-jbrowse 4.2.1 → 5.0.0-beta.1

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 (36) hide show
  1. package/esm/JBrowse1Connection/configSchema.d.ts +42 -18
  2. package/esm/JBrowse1Connection/configSchema.js +29 -3
  3. package/esm/JBrowse1Connection/get-value.d.ts +1 -10
  4. package/esm/JBrowse1Connection/get-value.js +9 -82
  5. package/esm/JBrowse1Connection/index.js +2 -2
  6. package/esm/JBrowse1Connection/jb1ConfigLoad.d.ts +9 -36
  7. package/esm/JBrowse1Connection/jb1ConfigLoad.js +72 -241
  8. package/esm/JBrowse1Connection/jb1ConfigParse.d.ts +6 -3
  9. package/esm/JBrowse1Connection/jb1ConfigParse.js +25 -250
  10. package/esm/JBrowse1Connection/jb1ToJb2.d.ts +8 -3
  11. package/esm/JBrowse1Connection/jb1ToJb2.js +124 -368
  12. package/esm/JBrowse1Connection/model.d.ts +57 -50
  13. package/esm/JBrowse1Connection/model.js +23 -9
  14. package/esm/JBrowse1Connection/set-value.d.ts +1 -0
  15. package/esm/JBrowse1Connection/set-value.js +14 -0
  16. package/esm/JBrowse1Connection/types.d.ts +4 -57
  17. package/esm/JBrowse1Connection/util.d.ts +13 -8
  18. package/esm/JBrowse1Connection/util.js +15 -80
  19. package/esm/JBrowse1TextSearchAdapter/HttpMap.d.ts +34 -7
  20. package/esm/JBrowse1TextSearchAdapter/HttpMap.js +49 -24
  21. package/esm/JBrowse1TextSearchAdapter/JBrowse1TextSearchAdapter.d.ts +5 -5
  22. package/esm/JBrowse1TextSearchAdapter/JBrowse1TextSearchAdapter.js +21 -22
  23. package/esm/JBrowse1TextSearchAdapter/configSchema.d.ts +42 -14
  24. package/esm/JBrowse1TextSearchAdapter/configSchema.js +31 -1
  25. package/esm/JBrowse1TextSearchAdapter/index.js +2 -2
  26. package/esm/NCListAdapter/NCListAdapter.d.ts +11 -1
  27. package/esm/NCListAdapter/NCListAdapter.js +12 -3
  28. package/esm/NCListAdapter/NCListFeature.d.ts +34 -3
  29. package/esm/NCListAdapter/NCListFeature.js +22 -8
  30. package/esm/NCListAdapter/configSchema.d.ts +35 -9
  31. package/esm/NCListAdapter/configSchema.js +26 -1
  32. package/esm/NCListAdapter/index.js +2 -2
  33. package/esm/index.js +3 -5
  34. package/package.json +9 -12
  35. package/esm/GuessNCList/index.d.ts +0 -2
  36. package/esm/GuessNCList/index.js +0 -15
@@ -1,27 +1,51 @@
1
+ /**
2
+ * #config JBrowse1Connection
3
+ *
4
+ * #example
5
+ * An entry in the config's `connections`, pointing at a JBrowse 1 data
6
+ * directory — the one holding `trackList.json` and `seq/`. Its tracks are
7
+ * translated to JBrowse 2 equivalents on connect, which is the path for serving
8
+ * an existing JBrowse 1 instance's data without re-processing it.
9
+ * ```js
10
+ * {
11
+ * type: 'JBrowse1Connection',
12
+ * connectionId: 'jbrowse1_example',
13
+ * name: 'Legacy JBrowse 1 data',
14
+ * assemblyNames: ['hg19'],
15
+ * dataDirLocation: { uri: 'https://example.com/jbrowse1/data/' },
16
+ * }
17
+ * ```
18
+ */
1
19
  declare const JBrowse1Connection: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
- dataDirLocation: {
3
- type: string;
4
- defaultValue: {
5
- uri: string;
6
- locationType: string;
20
+ /**
21
+ * #slot
22
+ */
23
+ readonly dataDirLocation: {
24
+ readonly type: "fileLocation";
25
+ readonly defaultValue: {
26
+ readonly uri: "https://mysite.com/jbrowse/data/";
27
+ readonly locationType: "UriLocation";
7
28
  };
8
- description: string;
29
+ readonly description: "the location of the JBrowse 1 data directory, often something like https://mysite.com/jbrowse/data/";
9
30
  };
10
- assemblyNames: {
11
- description: string;
12
- type: string;
13
- defaultValue: never[];
31
+ /**
32
+ * #slot
33
+ */
34
+ readonly assemblyNames: {
35
+ readonly description: "name of the assembly the connection belongs to, should be a single entry";
36
+ readonly type: "stringArray";
37
+ readonly defaultValue: readonly [];
14
38
  };
15
39
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
16
- name: {
17
- type: string;
18
- defaultValue: string;
19
- description: string;
40
+ readonly name: {
41
+ readonly type: "string";
42
+ readonly defaultValue: "nameOfConnection";
43
+ readonly description: "a unique name for this connection";
20
44
  };
21
- assemblyNames: {
22
- type: string;
23
- defaultValue: never[];
24
- description: string;
45
+ readonly assemblyNames: {
46
+ readonly type: "stringArray";
47
+ readonly defaultValue: readonly [];
48
+ readonly description: "optional list of names of assemblies in this connection";
25
49
  };
26
50
  }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "connectionId">>, undefined>>;
27
51
  export default JBrowse1Connection;
@@ -1,21 +1,47 @@
1
1
  import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
2
  import { baseConnectionConfig } from '@jbrowse/core/pluggableElementTypes/models';
3
- function x() { }
3
+ /**
4
+ * #config JBrowse1Connection
5
+ *
6
+ * #example
7
+ * An entry in the config's `connections`, pointing at a JBrowse 1 data
8
+ * directory — the one holding `trackList.json` and `seq/`. Its tracks are
9
+ * translated to JBrowse 2 equivalents on connect, which is the path for serving
10
+ * an existing JBrowse 1 instance's data without re-processing it.
11
+ * ```js
12
+ * {
13
+ * type: 'JBrowse1Connection',
14
+ * connectionId: 'jbrowse1_example',
15
+ * name: 'Legacy JBrowse 1 data',
16
+ * assemblyNames: ['hg19'],
17
+ * dataDirLocation: { uri: 'https://example.com/jbrowse1/data/' },
18
+ * }
19
+ * ```
20
+ */
4
21
  const JBrowse1Connection = ConfigurationSchema('JBrowse1Connection', {
22
+ /**
23
+ * #slot
24
+ */
5
25
  dataDirLocation: {
6
26
  type: 'fileLocation',
7
27
  defaultValue: {
8
- uri: 'http://mysite.com/jbrowse/data/',
28
+ uri: 'https://mysite.com/jbrowse/data/',
9
29
  locationType: 'UriLocation',
10
30
  },
11
- description: 'the location of the JBrowse 1 data directory, often something like http://mysite.com/jbrowse/data/',
31
+ description: 'the location of the JBrowse 1 data directory, often something like https://mysite.com/jbrowse/data/',
12
32
  },
33
+ /**
34
+ * #slot
35
+ */
13
36
  assemblyNames: {
14
37
  description: 'name of the assembly the connection belongs to, should be a single entry',
15
38
  type: 'stringArray',
16
39
  defaultValue: [],
17
40
  },
18
41
  }, {
42
+ /**
43
+ * #baseConfiguration
44
+ */
19
45
  baseConfiguration: baseConnectionConfig,
20
46
  });
21
47
  export default JBrowse1Connection;
@@ -1,10 +1 @@
1
- export interface Options {
2
- default?: unknown;
3
- separator?: string;
4
- joinChar?: string;
5
- join?: (segs: string[]) => string;
6
- split?: (path: string) => string[];
7
- isValid?: (key: string, target: {}) => boolean;
8
- }
9
- declare const getValue: (target: unknown, path: string | number | string[], options?: Options) => unknown;
10
- export default getValue;
1
+ export default function getValue(target: Record<string, unknown>, path: string): unknown;
@@ -1,84 +1,11 @@
1
- const isObject = v => v !== null && typeof v === 'object';
2
- const join = (segs, joinChar, options) => {
3
- if (typeof options.join === 'function') {
4
- return options.join(segs);
5
- }
6
- return segs[0] + joinChar + segs[1];
7
- };
8
- const split = (path, splitChar, options) => {
9
- if (typeof options.split === 'function') {
10
- return options.split(path);
11
- }
12
- return path.split(splitChar);
13
- };
14
- const isValid = (key, target = {}, options) => {
15
- if (typeof options?.isValid === 'function') {
16
- return options.isValid(key, target);
17
- }
18
- return true;
19
- };
20
- const isValidObject = (v) => {
21
- return isObject(v) || typeof v === 'function';
22
- };
23
- const getValue = (target, path, options = {}) => {
24
- if (!isObject(options)) {
25
- options = { default: options };
26
- }
27
- if (!isValidObject(target)) {
28
- return options.default !== undefined ? options.default : target;
29
- }
30
- if (typeof path === 'number') {
31
- path = String(path);
32
- }
33
- const pathIsArray = Array.isArray(path);
34
- const pathIsString = typeof path === 'string';
35
- const splitChar = options.separator || '.';
36
- const joinChar = options.joinChar || (typeof splitChar === 'string' ? splitChar : '.');
37
- if (!pathIsString && !pathIsArray) {
38
- return target;
39
- }
40
- if (target[path] !== undefined) {
41
- return isValid(path, target, options) ? target[path] : options.default;
42
- }
43
- const segs = pathIsArray ? path : split(path, splitChar, options);
44
- const len = segs.length;
45
- let idx = 0;
46
- do {
47
- let prop = segs[idx];
48
- if (typeof prop !== 'string') {
49
- prop = String(prop);
50
- }
51
- while (prop.endsWith('\\')) {
52
- prop = join([prop.slice(0, -1), segs[++idx] || ''], joinChar, options);
53
- }
54
- if (target[prop] !== undefined) {
55
- if (!isValid(prop, target, options)) {
56
- return options.default;
57
- }
58
- target = target[prop];
59
- }
60
- else {
61
- let hasProp = false;
62
- let n = idx + 1;
63
- while (n < len) {
64
- prop = join([prop, segs[n++]], joinChar, options);
65
- if ((hasProp = target[prop] !== undefined)) {
66
- if (!isValid(prop, target, options)) {
67
- return options.default;
68
- }
69
- target = target[prop];
70
- idx = n - 1;
71
- break;
72
- }
73
- }
74
- if (!hasProp) {
75
- return options.default;
76
- }
1
+ // minimal nested getter, mirroring ./set-value.ts
2
+ export default function getValue(target, path) {
3
+ let value = target;
4
+ for (const seg of path.split('.')) {
5
+ if (typeof value !== 'object' || value === null) {
6
+ return undefined;
77
7
  }
78
- } while (++idx < len && isValidObject(target));
79
- if (idx === len) {
80
- return target;
8
+ value = value[seg];
81
9
  }
82
- return options.default;
83
- };
84
- export default getValue;
10
+ return value;
11
+ }
@@ -1,6 +1,6 @@
1
1
  import ConnectionType from '@jbrowse/core/pluggableElementTypes/ConnectionType';
2
- import configSchema from "./configSchema.js";
3
- import modelFactory from "./model.js";
2
+ import configSchema from './configSchema.js';
3
+ import modelFactory from './model.js';
4
4
  export default function JBrowse1ConnectionF(pluginManager) {
5
5
  pluginManager.addConnectionType(() => new ConnectionType({
6
6
  name: 'JBrowse1Connection',
@@ -1,36 +1,9 @@
1
- import type { Config, JBLocation } from './types.ts';
2
- export declare function fetchJb1(dataRoot?: JBLocation, baseConfig?: Config, baseConfigRoot?: JBLocation): Promise<Config>;
3
- export declare function createFinalConfig(baseConfig: Config, defaults?: {
4
- tracks: never[];
5
- containerID: string;
6
- dataRoot: string;
7
- show_tracklist: boolean;
8
- show_nav: boolean;
9
- show_menu: boolean;
10
- show_overview: boolean;
11
- show_fullviewlink: boolean;
12
- update_browser_title: boolean;
13
- updateBrowserURL: boolean;
14
- refSeqs: string;
15
- include: string[];
16
- nameUrl: string;
17
- datasets: {
18
- _DEFAULT_EXAMPLES: boolean;
19
- volvox: {
20
- url: string;
21
- name: string;
22
- };
23
- modencode: {
24
- url: string;
25
- name: string;
26
- };
27
- yeast: {
28
- url: string;
29
- name: string;
30
- };
31
- };
32
- highlightSearchedRegions: boolean;
33
- highResolutionMode: string;
34
- }): Promise<Config>;
35
- export declare function fetchConfigFile(location: JBLocation): Promise<Config>;
36
- export declare function parseJb1(config: string, url?: string): Config;
1
+ import type { Config } from './types.ts';
2
+ import type { FileLocation } from '@jbrowse/core/util/types';
3
+ /**
4
+ * Read the track list out of a JBrowse 1 data directory. Only the tracks and
5
+ * the data root survive: the rest of a JBrowse 1 config — display defaults,
6
+ * `refSeqs`, `nameUrl`, the synthesized `stores` — describes the JBrowse 1
7
+ * browser, which is not the thing being configured here.
8
+ */
9
+ export declare function fetchJb1(dataDir: FileLocation): Promise<Config>;
@@ -1,247 +1,78 @@
1
1
  import { openLocation } from '@jbrowse/core/util/io';
2
- import { parseJB1Conf, parseJB1Json, regularizeConf } from "./jb1ConfigParse.js";
3
- import { deepUpdate, fillTemplate } from "./util.js";
4
- function isUriLocation(location) {
5
- return location.uri !== undefined;
2
+ import { parseJb1 } from './jb1ConfigParse.js';
3
+ import { fillTemplate, isTrack } from './util.js';
4
+ // JBrowse 1 kept a data directory's track list in either or both of these, so
5
+ // a missing one is normal rather than an error
6
+ const TRACK_LISTS = ['trackList.json', 'tracks.conf'];
7
+ /**
8
+ * Read the track list out of a JBrowse 1 data directory. Only the tracks and
9
+ * the data root survive: the rest of a JBrowse 1 config — display defaults,
10
+ * `refSeqs`, `nameUrl`, the synthesized `stores` — describes the JBrowse 1
11
+ * browser, which is not the thing being configured here.
12
+ */
13
+ export async function fetchJb1(dataDir) {
14
+ const dataRoot = locationPath(dataDir).replace(/\/$/, '');
15
+ const tracks = [];
16
+ const seen = new Set();
17
+ async function read(path) {
18
+ if (seen.has(path)) {
19
+ return;
20
+ }
21
+ seen.add(path);
22
+ const config = await readConfig(dataDir, path);
23
+ if (!config) {
24
+ return;
25
+ }
26
+ tracks.push(...regularizeTracks(config.tracks, { dataRoot }));
27
+ const dir = path.replace(/\/[^/]*$/, '');
28
+ for (const include of [config.include ?? []].flat()) {
29
+ await read(/^\w[\w+.-]*:/.test(include) ? include : `${dir}/${include}`);
30
+ }
31
+ }
32
+ for (const name of TRACK_LISTS) {
33
+ await read(`${dataRoot}/${name}`);
34
+ }
35
+ return { dataRoot, tracks };
6
36
  }
7
- function isLocalPathLocation(location) {
8
- return location.localPath !== undefined;
37
+ function locationPath(location) {
38
+ return 'uri' in location
39
+ ? location.uri
40
+ : 'localPath' in location
41
+ ? location.localPath
42
+ : '';
9
43
  }
10
- export async function fetchJb1(dataRoot = { uri: '', locationType: 'UriLocation' }, baseConfig = {
11
- include: ['{dataRoot}/trackList.json', '{dataRoot}/tracks.conf'],
12
- }, baseConfigRoot = { uri: '', locationType: 'UriLocation' }) {
13
- const protocol = 'uri' in dataRoot ? 'uri' : 'localPath';
14
- const dataRootReg = JSON.parse(JSON.stringify(dataRoot));
15
- let dataRootLocation = '';
16
- if (isUriLocation(dataRoot)) {
17
- dataRootLocation = dataRoot.uri;
18
- }
19
- if (isLocalPathLocation(dataRoot)) {
20
- dataRootLocation = dataRoot.localPath;
21
- }
22
- if (dataRootLocation.endsWith('/')) {
23
- dataRootReg[protocol] = dataRootLocation.slice(0, -1);
24
- }
25
- if ((isUriLocation(baseConfigRoot) && baseConfigRoot.uri) ||
26
- (isLocalPathLocation(baseConfigRoot) && baseConfigRoot.localPath)) {
27
- const baseProtocol = 'uri' in baseConfigRoot ? 'uri' : 'localPath';
28
- let baseConfigLocation = '';
29
- if (isUriLocation(baseConfigRoot)) {
30
- baseConfigLocation = baseConfigRoot.uri;
31
- }
32
- if (isLocalPathLocation(baseConfigRoot)) {
33
- baseConfigLocation = baseConfigRoot.localPath;
34
- }
35
- if (baseConfigLocation.endsWith('/')) {
36
- baseConfigLocation = baseConfigLocation.slice(0, -1);
37
- }
38
- let newConfig = {};
39
- for (const conf of ['jbrowse.conf', 'jbrowse_conf.json']) {
40
- let fetchedConfig = null;
41
- try {
42
- fetchedConfig = await fetchConfigFile({
43
- [baseProtocol]: `${baseConfigLocation}/${conf}`,
44
- });
45
- }
46
- catch (error) {
47
- console.error(`tried to access ${baseConfigLocation}/${conf}, but failed`);
48
- }
49
- newConfig = mergeConfigs(newConfig, fetchedConfig) || {};
50
- }
51
- if (dataRootReg[protocol]) {
52
- newConfig.dataRoot = dataRootReg[protocol];
53
- }
54
- return createFinalConfig(newConfig);
55
- }
56
- const newConfig = regularizeConf(baseConfig, window.location.href);
57
- if (dataRootReg[protocol]) {
58
- newConfig.dataRoot = dataRootReg[protocol];
59
- }
60
- return createFinalConfig(newConfig);
61
- }
62
- export async function createFinalConfig(baseConfig, defaults = configDefaults) {
63
- const configWithDefaults = deepUpdate(structuredClone(defaults), baseConfig);
64
- let finalConfig = await loadIncludes(configWithDefaults);
65
- finalConfig = mergeConfigs(finalConfig, baseConfig) || finalConfig;
66
- fillTemplates(finalConfig, finalConfig);
67
- validateConfig(finalConfig);
68
- return finalConfig;
69
- }
70
- export async function fetchConfigFile(location) {
71
- const result = await openLocation(location).readFile('utf8');
72
- if (isUriLocation(location)) {
73
- return parseJb1(result, location.uri);
74
- }
75
- if (isLocalPathLocation(location)) {
76
- return parseJb1(result, location.localPath);
77
- }
78
- return parseJb1(result);
79
- }
80
- export function parseJb1(config, url = '') {
81
- if (config.trim().startsWith('{')) {
82
- return parseJB1Json(config, url);
83
- }
84
- return parseJB1Conf(config, url);
44
+ async function readConfig(dataDir, path) {
45
+ const location = 'localPath' in dataDir
46
+ ? { localPath: path, locationType: 'LocalPathLocation' }
47
+ : { uri: path, locationType: 'UriLocation' };
48
+ let text;
49
+ try {
50
+ text = await openLocation(location).readFile('utf8');
51
+ }
52
+ catch {
53
+ return undefined;
54
+ }
55
+ return parseJb1(text, path);
85
56
  }
86
- function mergeConfigs(a, b) {
87
- if (b === null) {
88
- return null;
89
- }
90
- if (a === null) {
91
- a = {};
92
- }
93
- for (const prop of Object.keys(b)) {
94
- if (prop === 'tracks' && prop in a) {
95
- const aTracks = a[prop] || [];
96
- const bTracks = b[prop] || [];
97
- if (Array.isArray(aTracks) && Array.isArray(bTracks)) {
98
- a[prop] = mergeTrackConfigs(aTracks, bTracks);
99
- }
100
- else {
101
- throw new Error(`Track config has not been properly regularized: ${aTracks} ${bTracks}`);
102
- }
103
- }
104
- else if (!noRecursiveMerge(prop) &&
105
- prop in a &&
106
- typeof b[prop] === 'object' &&
107
- typeof a[prop] === 'object') {
108
- a[prop] = deepUpdate(a[prop], b[prop]);
109
- }
110
- else if (prop === 'dataRoot') {
111
- if (a[prop] === undefined ||
112
- (a[prop] === 'data' && b[prop] !== undefined)) {
113
- a[prop] = b[prop];
114
- }
115
- }
116
- else if (a[prop] === undefined || b[prop] !== undefined) {
117
- a[prop] = b[prop];
118
- }
119
- }
120
- return a;
121
- }
122
- function mergeTrackConfigs(a, b) {
123
- if (!b.length) {
124
- return a;
125
- }
126
- const aTracks = {};
127
- for (const [i, t] of a.entries()) {
128
- t.index = i;
129
- aTracks[t.label] = t;
130
- }
131
- for (const bT of b) {
132
- const aT = aTracks[bT.label];
133
- if (aT) {
134
- mergeConfigs(aT, bT);
135
- }
136
- else {
137
- a.push(bT);
138
- }
139
- }
140
- return a;
141
- }
142
- async function loadIncludes(inputConfig) {
143
- inputConfig = structuredClone(inputConfig);
144
- async function loadRecur(config, upstreamConf) {
145
- const sourceUrl = config.sourceUrl || config.baseUrl;
146
- if (!sourceUrl) {
147
- throw new Error(`Could not determine source URL: ${JSON.stringify(config)}`);
148
- }
149
- const newUpstreamConf = mergeConfigs(structuredClone(upstreamConf), config);
150
- if (!newUpstreamConf) {
151
- throw new Error('Problem merging configs');
152
- }
153
- const includes = fillTemplates(regularizeIncludes(config.include || []), newUpstreamConf);
154
- config.include = undefined;
155
- const loads = includes.map(async (include) => {
156
- include.cacheBuster = inputConfig.cacheBuster;
157
- const includedData = await fetchConfigFile({
158
- uri: new URL(include.url, sourceUrl).href,
159
- locationType: 'UriLocation',
160
- });
161
- return loadRecur(includedData, newUpstreamConf);
162
- });
163
- const includedDataObjects = await Promise.all(loads);
164
- for (const includedData of includedDataObjects) {
165
- config = mergeConfigs(config, includedData) || config;
166
- }
167
- return config;
168
- }
169
- return loadRecur(inputConfig, {});
170
- }
171
- function regularizeIncludes(includes) {
172
- if (!includes) {
173
- return [];
174
- }
175
- if (!Array.isArray(includes)) {
176
- includes = [includes];
177
- }
178
- return includes.map((include) => {
179
- if (typeof include === 'string') {
180
- include = { url: include };
181
- }
182
- if (!('format' in include)) {
183
- include.format = include.url.endsWith('.conf') ? 'conf' : 'JB_json';
184
- }
185
- if (include.format === 'JB_json' && !('version' in include)) {
186
- include.version = 1;
187
- }
188
- return include;
57
+ /**
58
+ * JBrowse 1 accepted `tracks` as an array, as a single track, or as an object
59
+ * keyed by label; let a track hold its settings in a `config` subobject; and
60
+ * let any string value interpolate `{dataRoot}`.
61
+ */
62
+ function regularizeTracks(tracks, fillWith) {
63
+ const list = Array.isArray(tracks)
64
+ ? tracks
65
+ : !tracks
66
+ ? []
67
+ : isTrack(tracks)
68
+ ? [tracks]
69
+ : Object.entries(tracks).map(([label, track]) => ({ label, ...track }));
70
+ return list.map(track => {
71
+ const { config, ...rest } = track;
72
+ const flat = { ...config, ...rest };
73
+ return Object.fromEntries(Object.entries(flat).map(([key, value]) => [
74
+ key,
75
+ typeof value === 'string' ? fillTemplate(value, fillWith) : value,
76
+ ]));
189
77
  });
190
78
  }
191
- function fillTemplates(subconfig, config) {
192
- if (!subconfig) {
193
- return subconfig;
194
- }
195
- if (Array.isArray(subconfig)) {
196
- for (let i = 0; i < subconfig.length; i += 1) {
197
- subconfig[i] = fillTemplates(subconfig[i], config);
198
- }
199
- }
200
- else if (typeof subconfig === 'object') {
201
- const sub = subconfig;
202
- for (const name of Object.keys(sub)) {
203
- sub[name] = fillTemplates(sub[name], config);
204
- }
205
- }
206
- else if (typeof subconfig === 'string') {
207
- return fillTemplate(subconfig, config);
208
- }
209
- return subconfig;
210
- }
211
- function noRecursiveMerge(propName) {
212
- return propName === 'datasets';
213
- }
214
- const configDefaults = {
215
- tracks: [],
216
- containerID: 'GenomeBrowser',
217
- dataRoot: 'data',
218
- show_tracklist: true,
219
- show_nav: true,
220
- show_menu: true,
221
- show_overview: true,
222
- show_fullviewlink: true,
223
- update_browser_title: true,
224
- updateBrowserURL: true,
225
- refSeqs: '{dataRoot}/seq/refSeqs.json',
226
- include: ['jbrowse.conf', 'jbrowse_conf.json'],
227
- nameUrl: '{dataRoot}/names/root.json',
228
- datasets: {
229
- _DEFAULT_EXAMPLES: true,
230
- volvox: { url: '?data=sample_data/json/volvox', name: 'Volvox Example' },
231
- modencode: {
232
- url: '?data=sample_data/json/modencode',
233
- name: 'MODEncode Example',
234
- },
235
- yeast: { url: '?data=sample_data/json/yeast', name: 'Yeast Example' },
236
- },
237
- highlightSearchedRegions: false,
238
- highResolutionMode: 'auto',
239
- };
240
- function validateConfig(config) {
241
- if (!config.tracks) {
242
- config.tracks = [];
243
- }
244
- if (!config.baseUrl) {
245
- throw new Error('Must provide a `baseUrl` in configuration');
246
- }
247
- }
@@ -1,4 +1,7 @@
1
1
  import type { Config } from './types.ts';
2
- export declare function parseJB1Json(config: Config | string, url: string): Config;
3
- export declare function parseJB1Conf(config: string, url: string): Config;
4
- export declare function regularizeConf(conf: Config, url: string): Config;
2
+ /**
3
+ * Parse a JBrowse 1 config file. A `trackList.json` is JSON; a `tracks.conf`
4
+ * is JBrowse 1's own INI-like format, whose `[section.subsection]` headers and
5
+ * `key.subkey = value` lines both address a dotted path.
6
+ */
7
+ export declare function parseJb1(text: string, url?: string): Config;