@jbrowse/plugin-legacy-jbrowse 1.7.11 → 2.1.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 (92) hide show
  1. package/dist/JBrowse1Connection/configSchema.js +18 -28
  2. package/dist/JBrowse1Connection/configSchema.js.map +1 -0
  3. package/dist/JBrowse1Connection/index.js +10 -22
  4. package/dist/JBrowse1Connection/index.js.map +1 -0
  5. package/dist/JBrowse1Connection/jb1ConfigLoad.js +387 -501
  6. package/dist/JBrowse1Connection/jb1ConfigLoad.js.map +1 -0
  7. package/dist/JBrowse1Connection/jb1ConfigParse.js +414 -435
  8. package/dist/JBrowse1Connection/jb1ConfigParse.js.map +1 -0
  9. package/dist/JBrowse1Connection/jb1ToJb2.js +405 -546
  10. package/dist/JBrowse1Connection/jb1ToJb2.js.map +1 -0
  11. package/dist/JBrowse1Connection/model.js +49 -57
  12. package/dist/JBrowse1Connection/model.js.map +1 -0
  13. package/dist/JBrowse1Connection/types.js +2 -4
  14. package/dist/JBrowse1Connection/types.js.map +1 -0
  15. package/dist/JBrowse1Connection/util.js +123 -130
  16. package/dist/JBrowse1Connection/util.js.map +1 -0
  17. package/dist/JBrowse1TextSeachAdapter/HttpMap.js +181 -326
  18. package/dist/JBrowse1TextSeachAdapter/HttpMap.js.map +1 -0
  19. package/dist/JBrowse1TextSeachAdapter/JBrowse1TextSearchAdapter.js +164 -185
  20. package/dist/JBrowse1TextSeachAdapter/JBrowse1TextSearchAdapter.js.map +1 -0
  21. package/dist/JBrowse1TextSeachAdapter/configSchema.js +20 -33
  22. package/dist/JBrowse1TextSeachAdapter/configSchema.js.map +1 -0
  23. package/dist/JBrowse1TextSeachAdapter/index.js +10 -22
  24. package/dist/JBrowse1TextSeachAdapter/index.js.map +1 -0
  25. package/dist/NCListAdapter/NCListAdapter.js +164 -224
  26. package/dist/NCListAdapter/NCListAdapter.js.map +1 -0
  27. package/dist/NCListAdapter/NCListFeature.js +68 -125
  28. package/dist/NCListAdapter/NCListFeature.js.map +1 -0
  29. package/dist/NCListAdapter/configSchema.js +17 -26
  30. package/dist/NCListAdapter/configSchema.js.map +1 -0
  31. package/dist/NCListAdapter/index.js +8 -14
  32. package/dist/NCListAdapter/index.js.map +1 -0
  33. package/dist/index.js +97 -116
  34. package/dist/index.js.map +1 -0
  35. package/esm/JBrowse1Connection/configSchema.d.ts +2 -0
  36. package/esm/JBrowse1Connection/configSchema.js +18 -0
  37. package/esm/JBrowse1Connection/configSchema.js.map +1 -0
  38. package/esm/JBrowse1Connection/index.d.ts +2 -0
  39. package/esm/JBrowse1Connection/index.js +3 -0
  40. package/esm/JBrowse1Connection/index.js.map +1 -0
  41. package/esm/JBrowse1Connection/jb1ConfigLoad.d.ts +36 -0
  42. package/esm/JBrowse1Connection/jb1ConfigLoad.js +281 -0
  43. package/esm/JBrowse1Connection/jb1ConfigLoad.js.map +1 -0
  44. package/esm/JBrowse1Connection/jb1ConfigParse.d.ts +11 -0
  45. package/esm/JBrowse1Connection/jb1ConfigParse.js +377 -0
  46. package/esm/JBrowse1Connection/jb1ConfigParse.js.map +1 -0
  47. package/esm/JBrowse1Connection/jb1ToJb2.d.ts +49 -0
  48. package/esm/JBrowse1Connection/jb1ToJb2.js +424 -0
  49. package/esm/JBrowse1Connection/jb1ToJb2.js.map +1 -0
  50. package/esm/JBrowse1Connection/model.d.ts +15 -0
  51. package/esm/JBrowse1Connection/model.js +44 -0
  52. package/esm/JBrowse1Connection/model.js.map +1 -0
  53. package/esm/JBrowse1Connection/types.d.ts +91 -0
  54. package/esm/JBrowse1Connection/types.js +2 -0
  55. package/esm/JBrowse1Connection/types.js.map +1 -0
  56. package/esm/JBrowse1Connection/util.d.ts +26 -0
  57. package/esm/JBrowse1Connection/util.js +136 -0
  58. package/esm/JBrowse1Connection/util.js.map +1 -0
  59. package/esm/JBrowse1TextSeachAdapter/HttpMap.d.ts +39 -0
  60. package/esm/JBrowse1TextSeachAdapter/HttpMap.js +89 -0
  61. package/esm/JBrowse1TextSeachAdapter/HttpMap.js.map +1 -0
  62. package/esm/JBrowse1TextSeachAdapter/JBrowse1TextSearchAdapter.d.ts +33 -0
  63. package/esm/JBrowse1TextSeachAdapter/JBrowse1TextSearchAdapter.js +67 -0
  64. package/esm/JBrowse1TextSeachAdapter/JBrowse1TextSearchAdapter.js.map +1 -0
  65. package/esm/JBrowse1TextSeachAdapter/configSchema.d.ts +2 -0
  66. package/esm/JBrowse1TextSeachAdapter/configSchema.js +20 -0
  67. package/esm/JBrowse1TextSeachAdapter/configSchema.js.map +1 -0
  68. package/esm/JBrowse1TextSeachAdapter/index.d.ts +2 -0
  69. package/esm/JBrowse1TextSeachAdapter/index.js +3 -0
  70. package/esm/JBrowse1TextSeachAdapter/index.js.map +1 -0
  71. package/esm/NCListAdapter/NCListAdapter.d.ts +31 -0
  72. package/esm/NCListAdapter/NCListAdapter.js +62 -0
  73. package/esm/NCListAdapter/NCListAdapter.js.map +1 -0
  74. package/esm/NCListAdapter/NCListFeature.d.ts +31 -0
  75. package/esm/NCListAdapter/NCListFeature.js +78 -0
  76. package/esm/NCListAdapter/NCListFeature.js.map +1 -0
  77. package/esm/NCListAdapter/configSchema.d.ts +2 -0
  78. package/esm/NCListAdapter/configSchema.js +16 -0
  79. package/esm/NCListAdapter/configSchema.js.map +1 -0
  80. package/esm/NCListAdapter/index.d.ts +1 -0
  81. package/esm/NCListAdapter/index.js +2 -0
  82. package/esm/NCListAdapter/index.js.map +1 -0
  83. package/esm/index.d.ts +6 -0
  84. package/esm/index.js +50 -0
  85. package/esm/index.js.map +1 -0
  86. package/package.json +17 -8
  87. package/src/NCListAdapter/NCListAdapter.test.ts +24 -16
  88. package/dist/JBrowse1TextSeachAdapter/HttpMap.test.js +0 -118
  89. package/dist/JBrowse1TextSeachAdapter/JBrowse1TextSearchAdapter.test.js +0 -98
  90. package/dist/NCListAdapter/NCListAdapter.test.js +0 -108
  91. package/dist/declare.d.js +0 -1
  92. package/dist/index.test.js +0 -44
@@ -0,0 +1,281 @@
1
+ import { openLocation } from '@jbrowse/core/util/io';
2
+ import { parseJB1Json, parseJB1Conf, regularizeConf } from './jb1ConfigParse';
3
+ import { clone, deepUpdate, fillTemplate } from './util';
4
+ function isUriLocation(location) {
5
+ return location.uri !== undefined;
6
+ }
7
+ function isLocalPathLocation(location) {
8
+ return location.localPath !== undefined;
9
+ }
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, dataRootLocation.length - 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, baseConfigLocation.length - 1);
37
+ }
38
+ let newConfig = {};
39
+ for (const conf of ['jbrowse.conf', 'jbrowse_conf.json']) {
40
+ let fetchedConfig = null;
41
+ try {
42
+ // @ts-ignore
43
+ fetchedConfig = await fetchConfigFile({
44
+ [baseProtocol]: `${baseConfigLocation}/${conf}`,
45
+ });
46
+ }
47
+ catch (error) {
48
+ console.error(`tried to access ${baseConfigLocation}/${conf}, but failed`);
49
+ }
50
+ newConfig = mergeConfigs(newConfig, fetchedConfig) || {};
51
+ }
52
+ if (dataRootReg[protocol]) {
53
+ newConfig.dataRoot = dataRootReg[protocol];
54
+ }
55
+ return createFinalConfig(newConfig);
56
+ }
57
+ const newConfig = regularizeConf(baseConfig, window.location.href);
58
+ if (dataRootReg[protocol]) {
59
+ newConfig.dataRoot = dataRootReg[protocol];
60
+ }
61
+ return createFinalConfig(newConfig);
62
+ }
63
+ export async function createFinalConfig(baseConfig, defaults = configDefaults) {
64
+ const configWithDefaults = deepUpdate(clone(defaults), baseConfig);
65
+ let finalConfig = await loadIncludes(configWithDefaults);
66
+ finalConfig = mergeConfigs(finalConfig, baseConfig) || finalConfig;
67
+ fillTemplates(finalConfig, finalConfig);
68
+ validateConfig(finalConfig);
69
+ return finalConfig;
70
+ }
71
+ export async function fetchConfigFile(location) {
72
+ const result = await openLocation(location).readFile('utf8');
73
+ if (isUriLocation(location)) {
74
+ return parseJb1(result, location.uri);
75
+ }
76
+ if (isLocalPathLocation(location)) {
77
+ return parseJb1(result, location.localPath);
78
+ }
79
+ return parseJb1(result);
80
+ }
81
+ export function parseJb1(config, url = '') {
82
+ if (config.trim().startsWith('{')) {
83
+ return parseJB1Json(config, url);
84
+ }
85
+ return parseJB1Conf(config, url);
86
+ }
87
+ /**
88
+ * Merges config object b into a. Properties in b override those in a.
89
+ */
90
+ function mergeConfigs(a, b) {
91
+ if (b === null) {
92
+ return null;
93
+ }
94
+ if (a === null) {
95
+ a = {};
96
+ }
97
+ for (const prop of Object.keys(b)) {
98
+ if (prop === 'tracks' && prop in a) {
99
+ const aTracks = a[prop] || [];
100
+ const bTracks = b[prop] || [];
101
+ if (Array.isArray(aTracks) && Array.isArray(bTracks)) {
102
+ a[prop] = mergeTrackConfigs(aTracks || [], bTracks || []);
103
+ }
104
+ else {
105
+ throw new Error(`Track config has not been properly regularized: ${aTracks} ${bTracks}`);
106
+ }
107
+ }
108
+ else if (!noRecursiveMerge(prop) &&
109
+ prop in a &&
110
+ // @ts-ignore
111
+ typeof b[prop] === 'object' &&
112
+ // @ts-ignore
113
+ typeof a[prop] === 'object') {
114
+ // @ts-ignore
115
+ a[prop] = deepUpdate(a[prop], b[prop]);
116
+ }
117
+ else if (prop === 'dataRoot') {
118
+ if (a[prop] === undefined ||
119
+ (a[prop] === 'data' && b[prop] !== undefined)) {
120
+ a[prop] = b[prop];
121
+ }
122
+ // @ts-ignore
123
+ }
124
+ else if (a[prop] === undefined || b[prop] !== undefined) {
125
+ // @ts-ignore
126
+ a[prop] = b[prop];
127
+ }
128
+ }
129
+ return a;
130
+ }
131
+ /**
132
+ * Special-case merging of two `tracks` configuration arrays.
133
+ */
134
+ function mergeTrackConfigs(a, b) {
135
+ if (!b.length) {
136
+ return a;
137
+ }
138
+ // index the tracks in `a` by track label
139
+ const aTracks = {};
140
+ a.forEach((t, i) => {
141
+ t.index = i;
142
+ aTracks[t.label] = t;
143
+ });
144
+ b.forEach((bT) => {
145
+ const aT = aTracks[bT.label];
146
+ if (aT) {
147
+ mergeConfigs(aT, bT);
148
+ }
149
+ else {
150
+ a.push(bT);
151
+ }
152
+ });
153
+ return a;
154
+ }
155
+ /**
156
+ * Recursively fetch, parse, and merge all the includes in the given config
157
+ * object. Calls the callback with the resulting configuration when finished.
158
+ * @param inputConfig - Config to load includes into
159
+ */
160
+ async function loadIncludes(inputConfig) {
161
+ inputConfig = clone(inputConfig);
162
+ async function loadRecur(config, upstreamConf) {
163
+ const sourceUrl = config.sourceUrl || config.baseUrl;
164
+ if (!sourceUrl) {
165
+ throw new Error(`Could not determine source URL: ${JSON.stringify(config)}`);
166
+ }
167
+ const newUpstreamConf = mergeConfigs(clone(upstreamConf), config);
168
+ if (!newUpstreamConf) {
169
+ throw new Error('Problem merging configs');
170
+ }
171
+ const includes = fillTemplates(regularizeIncludes(config.include || []), newUpstreamConf);
172
+ delete config.include;
173
+ const loads = includes.map(async (include) => {
174
+ include.cacheBuster = inputConfig.cacheBuster;
175
+ const includedData = await fetchConfigFile({
176
+ uri: new URL(include.url, sourceUrl).href,
177
+ locationType: 'UriLocation',
178
+ });
179
+ return loadRecur(includedData, newUpstreamConf);
180
+ });
181
+ const includedDataObjects = await Promise.all(loads);
182
+ includedDataObjects.forEach((includedData) => {
183
+ config = mergeConfigs(config, includedData) || config;
184
+ });
185
+ return config;
186
+ }
187
+ return loadRecur(inputConfig, {});
188
+ }
189
+ function regularizeIncludes(includes) {
190
+ if (!includes) {
191
+ return [];
192
+ }
193
+ // coerce include to an array
194
+ if (!Array.isArray(includes)) {
195
+ includes = [includes];
196
+ }
197
+ return includes.map((include) => {
198
+ // coerce bare strings in the includes to URLs
199
+ if (typeof include === 'string') {
200
+ include = { url: include };
201
+ }
202
+ // set defaults for format and version
203
+ if (!('format' in include)) {
204
+ include.format = include.url.endsWith('.conf') ? 'conf' : 'JB_json';
205
+ }
206
+ if (include.format === 'JB_json' && !('version' in include)) {
207
+ include.version = 1;
208
+ }
209
+ return include;
210
+ });
211
+ }
212
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unnecessary-type-constraint
213
+ function fillTemplates(subconfig, config) {
214
+ if (!subconfig) {
215
+ return subconfig;
216
+ }
217
+ if (Array.isArray(subconfig)) {
218
+ for (let i = 0; i < subconfig.length; i += 1) {
219
+ subconfig[i] = fillTemplates(subconfig[i], config);
220
+ }
221
+ }
222
+ else if (typeof subconfig === 'object') {
223
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
224
+ const sub = subconfig;
225
+ for (const name of Object.keys(sub)) {
226
+ sub[name] = fillTemplates(sub[name], config);
227
+ }
228
+ }
229
+ else if (typeof subconfig === 'string') {
230
+ // @ts-ignore
231
+ return fillTemplate(subconfig, config);
232
+ }
233
+ return subconfig;
234
+ }
235
+ /**
236
+ * list of config properties that should not be recursively merged
237
+ * @param propName - name of config property
238
+ */
239
+ function noRecursiveMerge(propName) {
240
+ return propName === 'datasets';
241
+ }
242
+ const configDefaults = {
243
+ tracks: [],
244
+ containerID: 'GenomeBrowser',
245
+ dataRoot: 'data',
246
+ show_tracklist: true,
247
+ show_nav: true,
248
+ show_menu: true,
249
+ show_overview: true,
250
+ show_fullviewlink: true,
251
+ update_browser_title: true,
252
+ updateBrowserURL: true,
253
+ refSeqs: '{dataRoot}/seq/refSeqs.json',
254
+ include: ['jbrowse.conf', 'jbrowse_conf.json'],
255
+ nameUrl: '{dataRoot}/names/root.json',
256
+ datasets: {
257
+ _DEFAULT_EXAMPLES: true,
258
+ volvox: { url: '?data=sample_data/json/volvox', name: 'Volvox Example' },
259
+ modencode: {
260
+ url: '?data=sample_data/json/modencode',
261
+ name: 'MODEncode Example',
262
+ },
263
+ yeast: { url: '?data=sample_data/json/yeast', name: 'Yeast Example' },
264
+ },
265
+ highlightSearchedRegions: false,
266
+ highResolutionMode: 'auto',
267
+ };
268
+ /**
269
+ * Examine the loaded and merged configuration for errors. Throws
270
+ * exceptions if it finds anything amiss.
271
+ * @returns nothing meaningful
272
+ */
273
+ function validateConfig(config) {
274
+ if (!config.tracks) {
275
+ config.tracks = [];
276
+ }
277
+ if (!config.baseUrl) {
278
+ throw new Error('Must provide a `baseUrl` in configuration');
279
+ }
280
+ }
281
+ //# sourceMappingURL=jb1ConfigLoad.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jb1ConfigLoad.js","sourceRoot":"","sources":["../../src/JBrowse1Connection/jb1ConfigLoad.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Config } from './types';
2
+ export declare function parseJB1Json(config: Config | string, url: string): Config;
3
+ export declare function parseJB1Conf(config: string, url: string): Config;
4
+ /**
5
+ * Applies defaults and any other necessary tweaks to the loaded configuration.
6
+ * @param conf - the object containing the configuration, which it modifies
7
+ * in-place
8
+ * @param url - URL of the config file
9
+ * @returns the same object it was passed
10
+ */
11
+ export declare function regularizeConf(conf: Config, url: string): Config;
@@ -0,0 +1,377 @@
1
+ /* eslint no-cond-assign: ["error", "except-parens"] */
2
+ import getValue from 'get-value';
3
+ import setValue from 'set-value';
4
+ import { objectHash } from '@jbrowse/core/util';
5
+ import { isSource, isTrack } from './util';
6
+ export function parseJB1Json(config, url) {
7
+ if (typeof config === 'string') {
8
+ let parsedConf;
9
+ try {
10
+ parsedConf = JSON.parse(config);
11
+ }
12
+ catch (error) {
13
+ throw new Error(`${error} when parsing configuration.`);
14
+ }
15
+ return regularizeConf(parsedConf, url);
16
+ }
17
+ return regularizeConf(config, url);
18
+ }
19
+ export function parseJB1Conf(config, url) {
20
+ let parsedConf;
21
+ try {
22
+ parsedConf = parse(config, url);
23
+ }
24
+ catch (error) {
25
+ throw new Error(`${error} when parsing configuration.`);
26
+ }
27
+ return regularizeConf(parsedConf, url);
28
+ }
29
+ function isAlwaysArray(varName) {
30
+ if (varName === 'include') {
31
+ return true;
32
+ }
33
+ return false;
34
+ }
35
+ function parse(text, url) {
36
+ let section = [];
37
+ let keyPath;
38
+ let operation;
39
+ let value;
40
+ const data = { tracks: {} };
41
+ let lineNumber;
42
+ function recordVal() {
43
+ if (value !== undefined) {
44
+ let parsedValue;
45
+ try {
46
+ // parse json
47
+ const match = value.match(/^json:(.+)/i);
48
+ if (match) {
49
+ parsedValue = JSON.parse(match[1]);
50
+ }
51
+ // parse numbers if it looks numeric
52
+ else if (/^[+-]?[\d.,]+([eE][-+]?\d+)?$/.test(value)) {
53
+ parsedValue = parseFloat(value.replace(/,/g, ''));
54
+ }
55
+ else {
56
+ parsedValue = value;
57
+ }
58
+ if (!keyPath) {
59
+ throw new Error(`Error parsing in section ${section.join(' - ')}`);
60
+ }
61
+ const path = section.concat(keyPath).join('.');
62
+ if (operation === '+=') {
63
+ let existing = getValue(data, path);
64
+ if (existing) {
65
+ if (!Array.isArray(existing)) {
66
+ existing = [existing];
67
+ }
68
+ }
69
+ else {
70
+ existing = [];
71
+ }
72
+ existing.push(parsedValue);
73
+ parsedValue = existing;
74
+ }
75
+ if (parsedValue === 'true') {
76
+ parsedValue = true;
77
+ }
78
+ if (parsedValue === 'false') {
79
+ parsedValue = false;
80
+ }
81
+ setValue(data, path, parsedValue);
82
+ }
83
+ catch (e) {
84
+ throw new Error(`syntax error${url ? ` in ${url}` : ''}${lineNumber ? ` at line ${lineNumber - 1}` : ''}`);
85
+ }
86
+ }
87
+ }
88
+ text.split('\n').forEach((textLine, i) => {
89
+ lineNumber = i + 1;
90
+ const line = textLine.replace(/^\s*#.+/, '');
91
+ // new section
92
+ let match;
93
+ if ((match = line.match(/^\s*\[([^\]]+)/))) {
94
+ // new section
95
+ recordVal();
96
+ keyPath = undefined;
97
+ value = undefined;
98
+ section = match[1].trim().split(/\s*\.\s*/);
99
+ if (section.length === 1 && section[0].toLowerCase() === 'general') {
100
+ section = [];
101
+ }
102
+ }
103
+ // new value
104
+ else if ((match = line.match(value === undefined ? /^([^+=]+)(\+?=)(.*)/ : /^(\S[^+=]+)(\+?=)(.*)/))) {
105
+ recordVal();
106
+ keyPath = match[1].trim().split(/\s*\.\s*/);
107
+ [, , operation] = match;
108
+ if (isAlwaysArray(section.concat(keyPath).join('.'))) {
109
+ operation = '+=';
110
+ }
111
+ value = match[3].trim();
112
+ }
113
+ // add to existing array value
114
+ else if (keyPath !== undefined &&
115
+ (match = line.match(/^\s{0,4}\+\s*(.+)/))) {
116
+ recordVal();
117
+ operation = '+=';
118
+ value = match[1].trim();
119
+ }
120
+ // add to existing value
121
+ else if (value !== undefined && (match = line.match(/^\s+(\S.*)/))) {
122
+ value += value.length ? ` ${match[1].trim()}` : match[1].trim();
123
+ }
124
+ // done with last value
125
+ else {
126
+ recordVal();
127
+ keyPath = undefined;
128
+ value = undefined;
129
+ }
130
+ });
131
+ recordVal();
132
+ return data;
133
+ }
134
+ /**
135
+ * Applies defaults and any other necessary tweaks to the loaded configuration.
136
+ * @param conf - the object containing the configuration, which it modifies
137
+ * in-place
138
+ * @param url - URL of the config file
139
+ * @returns the same object it was passed
140
+ */
141
+ export function regularizeConf(conf, url) {
142
+ // if tracks is not an array, convert it to one
143
+ if (conf.tracks && !Array.isArray(conf.tracks)) {
144
+ // if it's a single track config, wrap it in an arrayref
145
+ if (isTrack(conf.tracks)) {
146
+ conf.tracks = [conf.tracks];
147
+ }
148
+ // otherwise, coerce it to an array
149
+ else {
150
+ const tracks = [];
151
+ for (const label of Object.keys(conf.tracks)) {
152
+ const track = conf.tracks[label];
153
+ if (isTrack(track)) {
154
+ tracks.push(track);
155
+ }
156
+ else {
157
+ tracks.push({ label, ...track });
158
+ }
159
+ }
160
+ conf.tracks = tracks;
161
+ }
162
+ }
163
+ // regularize trackMetadata.sources
164
+ const meta = conf.trackMetadata;
165
+ if (meta && meta.sources) {
166
+ // if it's a single source config, wrap it in an arrayref
167
+ if (typeof meta.sources === 'string') {
168
+ meta.sources = [meta.sources];
169
+ }
170
+ if (isSource(meta.sources)) {
171
+ meta.sources = [meta.sources];
172
+ }
173
+ if (!Array.isArray(meta.sources)) {
174
+ const sources = [];
175
+ for (const name of Object.keys(meta.sources)) {
176
+ const source = meta.sources[name];
177
+ if (!('name' in source)) {
178
+ source.name = name;
179
+ }
180
+ sources.push(source);
181
+ }
182
+ meta.sources = sources;
183
+ }
184
+ // coerce any string source defs to be URLs, and try to detect their types
185
+ meta.sources = meta.sources.map((sourceDef) => {
186
+ if (typeof sourceDef === 'string') {
187
+ const newSourceDef = { url: sourceDef };
188
+ const typeMatch = sourceDef.match(/\.(\w+)$/);
189
+ if (typeMatch) {
190
+ newSourceDef.type = typeMatch[1].toLowerCase();
191
+ }
192
+ return newSourceDef;
193
+ }
194
+ return sourceDef;
195
+ });
196
+ }
197
+ conf.sourceUrl = conf.sourceUrl || url;
198
+ if (conf.sourceUrl.startsWith('/')) {
199
+ conf.sourceUrl = new URL(conf.sourceUrl, window.location.href).href;
200
+ }
201
+ conf.baseUrl = conf.baseUrl || new URL('.', conf.sourceUrl).href;
202
+ if (conf.baseUrl.length && !conf.baseUrl.endsWith('/')) {
203
+ conf.baseUrl += '/';
204
+ }
205
+ if (conf.sourceUrl) {
206
+ // set a default baseUrl in each of the track and store confs, and the names
207
+ // conf, if needed
208
+ const addBase = [];
209
+ if (conf.tracks) {
210
+ addBase.push(...conf.tracks);
211
+ }
212
+ if (conf.stores) {
213
+ addBase.push(...Object.values(conf.stores));
214
+ }
215
+ if (conf.names) {
216
+ addBase.push(conf.names);
217
+ }
218
+ addBase.forEach((t) => {
219
+ if (!t.baseUrl) {
220
+ t.baseUrl = conf.baseUrl || '/';
221
+ }
222
+ });
223
+ // resolve the refSeqs and nameUrl if present
224
+ if (conf.refSeqs && typeof conf.refSeqs === 'string') {
225
+ conf.refSeqs = new URL(conf.refSeqs, conf.sourceUrl).href;
226
+ }
227
+ if (conf.nameUrl) {
228
+ conf.nameUrl = new URL(conf.nameUrl, conf.sourceUrl).href;
229
+ }
230
+ }
231
+ conf.stores = conf.stores || {};
232
+ (conf.tracks || []).forEach((trackConfig) => {
233
+ // if there is a `config` subpart, just copy its keys in to the top-level
234
+ // config
235
+ if (trackConfig.config) {
236
+ const c = trackConfig.config;
237
+ delete trackConfig.config;
238
+ trackConfig = { ...c, ...trackConfig };
239
+ }
240
+ // skip if it's a new-style track def
241
+ if (trackConfig.store) {
242
+ return;
243
+ }
244
+ let trackClassName;
245
+ if (trackConfig.type === 'FeatureTrack') {
246
+ trackClassName = 'JBrowse/View/Track/HTMLFeatures';
247
+ }
248
+ else if (trackConfig.type === 'ImageTrack') {
249
+ trackClassName = 'JBrowse/View/Track/FixedImage';
250
+ }
251
+ else if (trackConfig.type === 'ImageTrack.Wiggle') {
252
+ trackClassName = 'JBrowse/View/Track/FixedImage/Wiggle';
253
+ }
254
+ else if (trackConfig.type === 'SequenceTrack') {
255
+ trackClassName = 'JBrowse/View/Track/Sequence';
256
+ }
257
+ else {
258
+ trackClassName = regularizeClass('JBrowse/View/Track', trackConfig.type);
259
+ }
260
+ trackConfig.type = trackClassName;
261
+ synthesizeTrackStoreConfig(conf, trackConfig);
262
+ if (trackConfig.histograms) {
263
+ if (!trackConfig.histograms.baseUrl) {
264
+ trackConfig.histograms.baseUrl = trackConfig.baseUrl;
265
+ }
266
+ synthesizeTrackStoreConfig(conf, trackConfig.histograms);
267
+ }
268
+ });
269
+ return conf;
270
+ }
271
+ /**
272
+ * prefix class name with `root` if it contains no slashes
273
+ * @param root - Prefix root
274
+ * @param className - class name
275
+ */
276
+ function regularizeClass(root, className) {
277
+ if (!className) {
278
+ return '';
279
+ }
280
+ if (!className.includes('/')) {
281
+ className = `${root}/${className}`;
282
+ }
283
+ className = className.replace(/^\//, '');
284
+ return className;
285
+ }
286
+ function guessStoreClass(trackConfig, urlTemplate) {
287
+ if (!trackConfig) {
288
+ return '';
289
+ }
290
+ if (trackConfig.type && trackConfig.type.includes('/FixedImage')) {
291
+ return `JBrowse/Store/TiledImage/Fixed${trackConfig.backendVersion === 0 ? '_v0' : ''}`;
292
+ }
293
+ if (/\.jsonz?$/i.test(urlTemplate)) {
294
+ return `JBrowse/Store/SeqFeature/NCList${trackConfig.backendVersion === 0 ? '_v0' : ''}`;
295
+ }
296
+ if (/\.bam$/i.test(urlTemplate)) {
297
+ return 'JBrowse/Store/SeqFeature/BAM';
298
+ }
299
+ if (/\.cram$/i.test(urlTemplate)) {
300
+ return 'JBrowse/Store/SeqFeature/CRAM';
301
+ }
302
+ if (/\.gff3?$/i.test(urlTemplate)) {
303
+ return 'JBrowse/Store/SeqFeature/GFF3';
304
+ }
305
+ if (/\.bed$/i.test(urlTemplate)) {
306
+ return 'JBrowse/Store/SeqFeature/BED';
307
+ }
308
+ if (/\.vcf.b?gz$/i.test(urlTemplate)) {
309
+ return 'JBrowse/Store/SeqFeature/VCFTabix';
310
+ }
311
+ if (/\.gff3?.b?gz$/i.test(urlTemplate)) {
312
+ return 'JBrowse/Store/SeqFeature/GFF3Tabix';
313
+ }
314
+ if (/\.bed.b?gz$/i.test(urlTemplate)) {
315
+ return 'JBrowse/Store/SeqFeature/BEDTabix';
316
+ }
317
+ if (/\.(bw|bigwig)$/i.test(urlTemplate)) {
318
+ return 'JBrowse/Store/SeqFeature/BigWig';
319
+ }
320
+ if (/\.(bb|bigbed)$/i.test(urlTemplate)) {
321
+ return 'JBrowse/Store/SeqFeature/BigBed';
322
+ }
323
+ if (/\.(fa|fasta)$/i.test(urlTemplate)) {
324
+ return 'JBrowse/Store/SeqFeature/IndexedFasta';
325
+ }
326
+ if (/\.(fa|fasta)\.b?gz$/i.test(urlTemplate)) {
327
+ return 'JBrowse/Store/SeqFeature/BgzipIndexedFasta';
328
+ }
329
+ if (/\.2bit$/i.test(urlTemplate)) {
330
+ return 'JBrowse/Store/SeqFeature/TwoBit';
331
+ }
332
+ if (trackConfig.type && trackConfig.type.endsWith('/Sequence')) {
333
+ return 'JBrowse/Store/Sequence/StaticChunked';
334
+ }
335
+ return '';
336
+ }
337
+ function synthesizeTrackStoreConfig(mainConf, trackConfig) {
338
+ // figure out what data store class to use with the track, applying some
339
+ // defaults if it is not explicit in the configuration
340
+ const { urlTemplate = '' } = trackConfig;
341
+ let storeClass;
342
+ if (trackConfig.storeClass) {
343
+ storeClass = regularizeClass('JBrowse/Store', trackConfig.storeClass);
344
+ }
345
+ else {
346
+ storeClass = guessStoreClass(trackConfig, urlTemplate);
347
+ }
348
+ if (!storeClass) {
349
+ console.warn(`Unable to determine an appropriate data store to use with track '${trackConfig.label}', please explicitly specify a storeClass in the configuration.`);
350
+ return;
351
+ }
352
+ // synthesize a separate store conf
353
+ const storeConf = { ...trackConfig, type: storeClass };
354
+ // if this is the first sequence store we see, and we have no refseqs store
355
+ // defined explicitly, make this the refseqs store.
356
+ if ((storeClass === 'JBrowse/Store/Sequence/StaticChunked' ||
357
+ storeClass === 'JBrowse/Store/Sequence/IndexedFasta' ||
358
+ storeClass === 'JBrowse/Store/SeqFeature/IndexedFasta' ||
359
+ storeClass === 'JBrowse/Store/SeqFeature/BgzipIndexedFasta' ||
360
+ storeClass === 'JBrowse/Store/SeqFeature/TwoBit' ||
361
+ storeClass === 'JBrowse/Store/Sequence/TwoBit' ||
362
+ trackConfig.useAsRefSeqStore) &&
363
+ !(mainConf.stores && mainConf.stores.refseqs)) {
364
+ storeConf.name = 'refseqs';
365
+ }
366
+ else {
367
+ storeConf.name = `store${objectHash(storeConf)}`;
368
+ }
369
+ // record it
370
+ if (!mainConf.stores) {
371
+ mainConf.stores = {};
372
+ }
373
+ mainConf.stores[storeConf.name] = storeConf;
374
+ // connect it to the track conf
375
+ trackConfig.store = storeConf.name;
376
+ }
377
+ //# sourceMappingURL=jb1ConfigParse.js.map