@jbrowse/plugin-linear-genome-view 2.1.6 → 2.2.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 (109) hide show
  1. package/dist/BaseLinearDisplay/components/LinearBlocks.d.ts +2 -2
  2. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +2 -22
  3. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  4. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +146 -1
  5. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +600 -464
  6. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  7. package/dist/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.js +19 -1
  8. package/dist/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.js.map +1 -1
  9. package/dist/BasicTrack/configSchema.d.ts +3 -0
  10. package/dist/BasicTrack/configSchema.js +18 -0
  11. package/dist/BasicTrack/configSchema.js.map +1 -0
  12. package/dist/BasicTrack/index.d.ts +3 -0
  13. package/dist/BasicTrack/index.js +18 -0
  14. package/dist/BasicTrack/index.js.map +1 -0
  15. package/dist/FeatureTrack/configSchema.d.ts +3 -0
  16. package/dist/FeatureTrack/configSchema.js +21 -0
  17. package/dist/FeatureTrack/configSchema.js.map +1 -0
  18. package/dist/FeatureTrack/index.d.ts +3 -0
  19. package/dist/FeatureTrack/index.js +18 -0
  20. package/dist/FeatureTrack/index.js.map +1 -0
  21. package/dist/LinearBareDisplay/configSchema.d.ts +5 -1
  22. package/dist/LinearBareDisplay/configSchema.js +12 -1
  23. package/dist/LinearBareDisplay/configSchema.js.map +1 -1
  24. package/dist/LinearBareDisplay/model.d.ts +16 -0
  25. package/dist/LinearBareDisplay/model.js +16 -0
  26. package/dist/LinearBareDisplay/model.js.map +1 -1
  27. package/dist/LinearBasicDisplay/configSchema.d.ts +5 -1
  28. package/dist/LinearBasicDisplay/configSchema.js +16 -1
  29. package/dist/LinearBasicDisplay/configSchema.js.map +1 -1
  30. package/dist/LinearBasicDisplay/model.d.ts +77 -6
  31. package/dist/LinearBasicDisplay/model.js +167 -111
  32. package/dist/LinearBasicDisplay/model.js.map +1 -1
  33. package/dist/LinearGenomeView/components/ImportForm.js +34 -28
  34. package/dist/LinearGenomeView/components/ImportForm.js.map +1 -1
  35. package/dist/LinearGenomeView/components/LinearGenomeView.js +1 -21
  36. package/dist/LinearGenomeView/components/LinearGenomeView.js.map +1 -1
  37. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js +7 -5
  38. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js.map +1 -1
  39. package/dist/LinearGenomeView/components/OverviewScaleBar.d.ts +26 -34
  40. package/dist/LinearGenomeView/index.d.ts +189 -15
  41. package/dist/LinearGenomeView/index.js +266 -27
  42. package/dist/LinearGenomeView/index.js.map +1 -1
  43. package/dist/index.d.ts +12 -84
  44. package/dist/index.js +4 -25
  45. package/dist/index.js.map +1 -1
  46. package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +2 -2
  47. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +2 -22
  48. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  49. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +146 -1
  50. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +600 -464
  51. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  52. package/esm/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.js +19 -1
  53. package/esm/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.js.map +1 -1
  54. package/esm/BasicTrack/configSchema.d.ts +3 -0
  55. package/esm/BasicTrack/configSchema.js +16 -0
  56. package/esm/BasicTrack/configSchema.js.map +1 -0
  57. package/esm/BasicTrack/index.d.ts +3 -0
  58. package/esm/BasicTrack/index.js +13 -0
  59. package/esm/BasicTrack/index.js.map +1 -0
  60. package/esm/FeatureTrack/configSchema.d.ts +3 -0
  61. package/esm/FeatureTrack/configSchema.js +19 -0
  62. package/esm/FeatureTrack/configSchema.js.map +1 -0
  63. package/esm/FeatureTrack/index.d.ts +3 -0
  64. package/esm/FeatureTrack/index.js +13 -0
  65. package/esm/FeatureTrack/index.js.map +1 -0
  66. package/esm/LinearBareDisplay/configSchema.d.ts +5 -1
  67. package/esm/LinearBareDisplay/configSchema.js +14 -2
  68. package/esm/LinearBareDisplay/configSchema.js.map +1 -1
  69. package/esm/LinearBareDisplay/model.d.ts +16 -0
  70. package/esm/LinearBareDisplay/model.js +16 -0
  71. package/esm/LinearBareDisplay/model.js.map +1 -1
  72. package/esm/LinearBasicDisplay/configSchema.d.ts +5 -1
  73. package/esm/LinearBasicDisplay/configSchema.js +18 -2
  74. package/esm/LinearBasicDisplay/configSchema.js.map +1 -1
  75. package/esm/LinearBasicDisplay/model.d.ts +77 -6
  76. package/esm/LinearBasicDisplay/model.js +167 -111
  77. package/esm/LinearBasicDisplay/model.js.map +1 -1
  78. package/esm/LinearGenomeView/components/ImportForm.js +36 -30
  79. package/esm/LinearGenomeView/components/ImportForm.js.map +1 -1
  80. package/esm/LinearGenomeView/components/LinearGenomeView.js +2 -22
  81. package/esm/LinearGenomeView/components/LinearGenomeView.js.map +1 -1
  82. package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js +7 -5
  83. package/esm/LinearGenomeView/components/LinearGenomeViewSvg.js.map +1 -1
  84. package/esm/LinearGenomeView/components/OverviewScaleBar.d.ts +26 -34
  85. package/esm/LinearGenomeView/index.d.ts +189 -15
  86. package/esm/LinearGenomeView/index.js +266 -27
  87. package/esm/LinearGenomeView/index.js.map +1 -1
  88. package/esm/index.d.ts +12 -84
  89. package/esm/index.js +4 -25
  90. package/esm/index.js.map +1 -1
  91. package/package.json +2 -2
  92. package/src/BaseLinearDisplay/components/ServerSideRenderedBlockContent.tsx +2 -24
  93. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +695 -555
  94. package/src/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.ts +20 -1
  95. package/src/BasicTrack/configSchema.ts +23 -0
  96. package/src/BasicTrack/index.ts +22 -0
  97. package/src/FeatureTrack/configSchema.ts +27 -0
  98. package/src/FeatureTrack/index.ts +21 -0
  99. package/src/LinearBareDisplay/configSchema.ts +15 -2
  100. package/src/LinearBareDisplay/model.ts +16 -0
  101. package/src/LinearBasicDisplay/configSchema.ts +19 -2
  102. package/src/LinearBasicDisplay/model.ts +63 -11
  103. package/src/LinearGenomeView/components/ImportForm.tsx +79 -63
  104. package/src/LinearGenomeView/components/LinearGenomeView.tsx +2 -26
  105. package/src/LinearGenomeView/components/LinearGenomeViewSvg.tsx +21 -18
  106. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.tsx.snap +204 -204
  107. package/src/LinearGenomeView/index.test.ts +33 -26
  108. package/src/LinearGenomeView/index.tsx +317 -60
  109. package/src/index.ts +6 -46
@@ -70,7 +70,7 @@ function calculateVisibleLocStrings(contentBlocks) {
70
70
  if (!contentBlocks.length) {
71
71
  return '';
72
72
  }
73
- const isSingleAssemblyName = contentBlocks.every(block => block.assemblyName === contentBlocks[0].assemblyName);
73
+ const isSingleAssemblyName = contentBlocks.every(b => b.assemblyName === contentBlocks[0].assemblyName);
74
74
  const locs = contentBlocks.map(block => (0, util_1.assembleLocString)({
75
75
  ...block,
76
76
  start: Math.round(block.start),
@@ -91,30 +91,84 @@ function localStorageGetItem(item) {
91
91
  ? localStorage.getItem(item)
92
92
  : undefined;
93
93
  }
94
+ /**
95
+ * #stateModel LinearGenomeView
96
+ */
94
97
  function stateModelFactory(pluginManager) {
95
98
  return mobx_state_tree_1.types
96
99
  .compose(models_1.BaseViewModel, mobx_state_tree_1.types.model('LinearGenomeView', {
100
+ /**
101
+ * #property
102
+ */
97
103
  id: mst_1.ElementId,
104
+ /**
105
+ * #property
106
+ */
98
107
  type: mobx_state_tree_1.types.literal('LinearGenomeView'),
108
+ /**
109
+ * #property
110
+ * corresponds roughly to the horizontal scroll of the LGV
111
+ */
99
112
  offsetPx: 0,
113
+ /**
114
+ * #property
115
+ * corresponds roughly to the zoom level, base-pairs per pixel
116
+ */
100
117
  bpPerPx: 1,
118
+ /**
119
+ * #property
120
+ * currently displayed regions, can be a single chromosome, arbitrary subsections,
121
+ * or the entire set of chromosomes in the genome, but it not advised to use the
122
+ * entire set of chromosomes if your assembly is very fragmented
123
+ */
101
124
  displayedRegions: mobx_state_tree_1.types.array(mst_1.Region),
102
- // we use an array for the tracks because the tracks are displayed in a
103
- // specific order that we need to keep.
125
+ /**
126
+ * #property
127
+ * array of currently displayed tracks state models instances
128
+ */
104
129
  tracks: mobx_state_tree_1.types.array(pluginManager.pluggableMstType('track', 'stateModel')),
130
+ /**
131
+ * #property
132
+ * array of currently displayed tracks state model's
133
+ */
105
134
  hideHeader: false,
135
+ /**
136
+ * #property
137
+ */
106
138
  hideHeaderOverview: false,
139
+ /**
140
+ * #property
141
+ */
107
142
  hideNoTracksActive: false,
143
+ /**
144
+ * #property
145
+ */
108
146
  trackSelectorType: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.enumeration(['hierarchical']), 'hierarchical'),
147
+ /**
148
+ * #property
149
+ * how to display the track labels, can be "overlapping", "offset", or "hidden"
150
+ */
109
151
  trackLabels: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, () => localStorageGetItem('lgv-trackLabels') || 'overlapping'),
152
+ /**
153
+ * #property
154
+ * show the "center line"
155
+ */
110
156
  showCenterLine: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => {
111
157
  const setting = localStorageGetItem('lgv-showCenterLine');
112
158
  return setting !== undefined && setting !== null ? !!+setting : false;
113
159
  }),
160
+ /**
161
+ * #property
162
+ * show the "cytobands" in the overview scale bar
163
+ */
114
164
  showCytobandsSetting: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => {
115
165
  const setting = localStorageGetItem('lgv-showCytobands');
116
166
  return setting !== undefined && setting !== null ? !!+setting : true;
117
167
  }),
168
+ /**
169
+ * #property
170
+ * show the "gridlines" in the track area
171
+ */
118
172
  showGridlines: true,
119
173
  }))
120
174
  .volatile(() => ({
@@ -137,15 +191,24 @@ function stateModelFactory(pluginManager) {
137
191
  seqDialogDisplayed: false,
138
192
  }))
139
193
  .views(self => ({
194
+ /**
195
+ * #getter
196
+ */
140
197
  get width() {
141
198
  if (self.volatileWidth === undefined) {
142
199
  throw new Error('width undefined, make sure to check for model.initialized');
143
200
  }
144
201
  return self.volatileWidth;
145
202
  },
203
+ /**
204
+ * #getter
205
+ */
146
206
  get interRegionPaddingWidth() {
147
207
  return exports.INTER_REGION_PADDING_WIDTH;
148
208
  },
209
+ /**
210
+ * #getter
211
+ */
149
212
  get assemblyNames() {
150
213
  return [
151
214
  ...new Set(self.displayedRegions.map(region => region.assemblyName)),
@@ -293,33 +356,60 @@ function stateModelFactory(pluginManager) {
293
356
  },
294
357
  }))
295
358
  .actions(self => ({
359
+ /**
360
+ * #action
361
+ */
296
362
  setShowCytobands(flag) {
297
363
  self.showCytobandsSetting = flag;
298
364
  localStorage.setItem('lgv-showCytobands', `${+flag}`);
299
365
  },
366
+ /**
367
+ * #action
368
+ */
300
369
  setWidth(newWidth) {
301
370
  self.volatileWidth = newWidth;
302
371
  },
372
+ /**
373
+ * #action
374
+ */
303
375
  setError(error) {
304
376
  self.volatileError = error;
305
377
  },
378
+ /**
379
+ * #action
380
+ */
306
381
  toggleHeader() {
307
382
  self.hideHeader = !self.hideHeader;
308
383
  },
384
+ /**
385
+ * #action
386
+ */
309
387
  toggleHeaderOverview() {
310
388
  self.hideHeaderOverview = !self.hideHeaderOverview;
311
389
  },
390
+ /**
391
+ * #action
392
+ */
312
393
  toggleNoTracksActive() {
313
394
  self.hideNoTracksActive = !self.hideNoTracksActive;
314
395
  },
396
+ /**
397
+ * #action
398
+ */
315
399
  toggleShowGridlines() {
316
400
  self.showGridlines = !self.showGridlines;
317
401
  },
402
+ /**
403
+ * #action
404
+ */
318
405
  scrollTo(offsetPx) {
319
406
  const newOffsetPx = (0, util_1.clamp)(offsetPx, self.minOffset, self.maxOffset);
320
407
  self.offsetPx = newOffsetPx;
321
408
  return newOffsetPx;
322
409
  },
410
+ /**
411
+ * #action
412
+ */
323
413
  zoomTo(bpPerPx) {
324
414
  const newBpPerPx = (0, util_1.clamp)(bpPerPx, self.minBpPerPx, self.maxBpPerPx);
325
415
  if (newBpPerPx === self.bpPerPx) {
@@ -337,22 +427,37 @@ function stateModelFactory(pluginManager) {
337
427
  viewWidth / 2));
338
428
  return newBpPerPx;
339
429
  },
430
+ /**
431
+ * #action
432
+ * sets offsets used in the get sequence dialog
433
+ */
340
434
  setOffsets(left, right) {
341
- // sets offsets used in the get sequence dialog
342
435
  self.leftOffset = left;
343
436
  self.rightOffset = right;
344
437
  },
438
+ /**
439
+ * #action
440
+ */
345
441
  setSearchResults(results, query) {
346
442
  self.searchResults = results;
347
443
  self.searchQuery = query;
348
444
  },
445
+ /**
446
+ * #action
447
+ */
349
448
  setGetSequenceDialogOpen(open) {
350
449
  self.seqDialogDisplayed = open;
351
450
  },
451
+ /**
452
+ * #action
453
+ */
352
454
  setNewView(bpPerPx, offsetPx) {
353
455
  this.zoomTo(bpPerPx);
354
456
  this.scrollTo(offsetPx);
355
457
  },
458
+ /**
459
+ * #action
460
+ */
356
461
  horizontallyFlip() {
357
462
  self.displayedRegions = (0, mobx_state_tree_1.cast)(self.displayedRegions
358
463
  .slice()
@@ -360,6 +465,9 @@ function stateModelFactory(pluginManager) {
360
465
  .map(region => ({ ...region, reversed: !region.reversed })));
361
466
  this.scrollTo(self.totalBp / self.bpPerPx - self.offsetPx - self.width);
362
467
  },
468
+ /**
469
+ * #action
470
+ */
363
471
  showTrack(trackId, initialSnapshot = {}, displayInitialSnapshot = {}) {
364
472
  const schema = pluginManager.pluggableConfigSchemaType('track');
365
473
  const conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
@@ -404,6 +512,9 @@ function stateModelFactory(pluginManager) {
404
512
  },
405
513
  }))
406
514
  .actions(self => ({
515
+ /**
516
+ * #action
517
+ */
407
518
  moveTrack(movingId, targetId) {
408
519
  const oldIndex = self.tracks.findIndex(track => track.id === movingId);
409
520
  if (oldIndex === -1) {
@@ -417,6 +528,9 @@ function stateModelFactory(pluginManager) {
417
528
  self.tracks.splice(oldIndex, 1);
418
529
  self.tracks.splice(newIndex, 0, track);
419
530
  },
531
+ /**
532
+ * #action
533
+ */
420
534
  closeView() {
421
535
  const parent = (0, util_1.getContainingView)(self);
422
536
  if (parent) {
@@ -430,6 +544,9 @@ function stateModelFactory(pluginManager) {
430
544
  (0, util_1.getSession)(self).removeView(self);
431
545
  }
432
546
  },
547
+ /**
548
+ * #action
549
+ */
433
550
  toggleTrack(trackId) {
434
551
  // if we have any tracks with that configuration, turn them off
435
552
  const hiddenCount = self.hideTrack(trackId);
@@ -438,18 +555,30 @@ function stateModelFactory(pluginManager) {
438
555
  self.showTrack(trackId);
439
556
  }
440
557
  },
558
+ /**
559
+ * #action
560
+ */
441
561
  setTrackLabels(setting) {
442
562
  self.trackLabels = setting;
443
563
  localStorage.setItem('lgv-trackLabels', setting);
444
564
  },
565
+ /**
566
+ * #action
567
+ */
445
568
  toggleCenterLine() {
446
569
  self.showCenterLine = !self.showCenterLine;
447
570
  localStorage.setItem('lgv-showCenterLine', `${+self.showCenterLine}`);
448
571
  },
572
+ /**
573
+ * #action
574
+ */
449
575
  setDisplayedRegions(regions) {
450
576
  self.displayedRegions = (0, mobx_state_tree_1.cast)(regions);
451
577
  self.zoomTo(self.bpPerPx);
452
578
  },
579
+ /**
580
+ * #action
581
+ */
453
582
  activateTrackSelector() {
454
583
  if (self.trackSelectorType === 'hierarchical') {
455
584
  const session = (0, util_1.getSession)(self);
@@ -462,6 +591,7 @@ function stateModelFactory(pluginManager) {
462
591
  throw new Error(`invalid track selector type ${self.trackSelectorType}`);
463
592
  },
464
593
  /**
594
+ * #method
465
595
  * Helper method for the fetchSequence.
466
596
  * Retrieves the corresponding regions that were selected by the rubberband
467
597
  *
@@ -483,38 +613,51 @@ function stateModelFactory(pluginManager) {
483
613
  end: Math.ceil(region.end),
484
614
  }));
485
615
  },
486
- // schedule something to be run after the next time displayedRegions is set
616
+ /**
617
+ * #action
618
+ * schedule something to be run after the next time displayedRegions is set
619
+ */
487
620
  afterDisplayedRegionsSet(cb) {
488
621
  self.afterDisplayedRegionsSetCallbacks.push(cb);
489
622
  },
623
+ /**
624
+ * #action
625
+ */
490
626
  horizontalScroll(distance) {
491
627
  const oldOffsetPx = self.offsetPx;
492
628
  // newOffsetPx is the actual offset after the scroll is clamped
493
629
  const newOffsetPx = self.scrollTo(self.offsetPx + distance);
494
630
  return newOffsetPx - oldOffsetPx;
495
631
  },
632
+ /**
633
+ * #action
634
+ */
496
635
  center() {
497
636
  const centerBp = self.totalBp / 2;
498
637
  const centerPx = centerBp / self.bpPerPx;
499
638
  self.scrollTo(Math.round(centerPx - self.width / 2));
500
639
  },
640
+ /**
641
+ * #action
642
+ */
501
643
  showAllRegions() {
502
644
  self.zoomTo(self.maxBpPerPx);
503
645
  this.center();
504
646
  },
647
+ /**
648
+ * #action
649
+ */
505
650
  showAllRegionsInAssembly(assemblyName) {
506
651
  const session = (0, util_1.getSession)(self);
507
652
  const { assemblyManager } = session;
508
653
  if (!assemblyName) {
509
- const assemblyNames = [
510
- ...new Set(self.displayedRegions.map(region => region.assemblyName)),
511
- ];
512
- if (assemblyNames.length > 1) {
513
- session.notify(`Can't perform this with multiple assemblies currently`);
654
+ const names = new Set(self.displayedRegions.map(r => r.assemblyName));
655
+ if (names.size > 1) {
656
+ session.notify(`Can't perform operation with multiple assemblies currently`);
514
657
  return;
515
658
  }
516
659
  ;
517
- [assemblyName] = assemblyNames;
660
+ [assemblyName] = [...names];
518
661
  }
519
662
  const assembly = assemblyManager.get(assemblyName);
520
663
  if (assembly) {
@@ -526,13 +669,22 @@ function stateModelFactory(pluginManager) {
526
669
  }
527
670
  }
528
671
  },
672
+ /**
673
+ * #action
674
+ */
529
675
  setDraggingTrackId(idx) {
530
676
  self.draggingTrackId = idx;
531
677
  },
678
+ /**
679
+ * #action
680
+ */
532
681
  setScaleFactor(factor) {
533
682
  self.scaleFactor = factor;
534
683
  },
535
- // this "clears the view" and makes the view return to the import form
684
+ /**
685
+ * #action
686
+ * this "clears the view" and makes the view return to the import form
687
+ */
536
688
  clearView() {
537
689
  this.setDisplayedRegions([]);
538
690
  self.tracks.clear();
@@ -542,6 +694,10 @@ function stateModelFactory(pluginManager) {
542
694
  self.scrollTo(0);
543
695
  self.zoomTo(10);
544
696
  },
697
+ /**
698
+ * #action
699
+ * creates an svg export and save using FileSaver
700
+ */
545
701
  async exportSvg(opts = {}) {
546
702
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
547
703
  const html = await (0, LinearGenomeViewSvg_1.renderToSvg)(self, opts);
@@ -551,6 +707,10 @@ function stateModelFactory(pluginManager) {
551
707
  }))
552
708
  .actions(self => {
553
709
  let cancelLastAnimation = () => { };
710
+ /**
711
+ * #action
712
+ * perform animated slide
713
+ */
554
714
  function slide(viewWidths) {
555
715
  const [animate, cancelAnimation] = (0, util_1.springAnimate)(self.offsetPx, self.offsetPx + self.width * viewWidths, self.scrollTo);
556
716
  cancelLastAnimation();
@@ -561,6 +721,10 @@ function stateModelFactory(pluginManager) {
561
721
  })
562
722
  .actions(self => {
563
723
  let cancelLastAnimation = () => { };
724
+ /**
725
+ * #action
726
+ * perform animated zoom
727
+ */
564
728
  function zoom(targetBpPerPx) {
565
729
  self.zoomTo(self.bpPerPx);
566
730
  if (
@@ -582,17 +746,30 @@ function stateModelFactory(pluginManager) {
582
746
  return { zoom };
583
747
  })
584
748
  .views(self => ({
749
+ /**
750
+ * #getter
751
+ */
585
752
  get canShowCytobands() {
586
753
  return self.displayedRegions.length === 1 && this.anyCytobandsExist;
587
754
  },
755
+ /**
756
+ * #getter
757
+ */
588
758
  get showCytobands() {
589
759
  return this.canShowCytobands && self.showCytobandsSetting;
590
760
  },
761
+ /**
762
+ * #getter
763
+ */
591
764
  get anyCytobandsExist() {
592
765
  const { assemblyManager } = (0, util_1.getSession)(self);
593
- const { assemblyNames } = self;
594
- return assemblyNames.some(asm => { var _a, _b; return (_b = (_a = assemblyManager.get(asm)) === null || _a === void 0 ? void 0 : _a.cytobands) === null || _b === void 0 ? void 0 : _b.length; });
766
+ return self.assemblyNames.some(a => { var _a, _b; return (_b = (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.cytobands) === null || _b === void 0 ? void 0 : _b.length; });
595
767
  },
768
+ /**
769
+ * #getter
770
+ * the cytoband is displayed to the right of the chromosome name,
771
+ * and that offset is calculated manually with this method
772
+ */
596
773
  get cytobandOffset() {
597
774
  return this.showCytobands
598
775
  ? (0, util_1.measureText)(self.displayedRegions[0].refName, 12) + 15
@@ -600,6 +777,10 @@ function stateModelFactory(pluginManager) {
600
777
  },
601
778
  }))
602
779
  .views(self => ({
780
+ /**
781
+ * #method
782
+ * return the view menu items
783
+ */
603
784
  menuItems() {
604
785
  const { canShowCytobands, showCytobands } = self;
605
786
  const session = (0, util_1.getSession)(self);
@@ -742,6 +923,15 @@ function stateModelFactory(pluginManager) {
742
923
  let currentlyCalculatedStaticBlocks;
743
924
  let stringifiedCurrentlyCalculatedStaticBlocks = '';
744
925
  return {
926
+ /**
927
+ * #getter
928
+ * static blocks are an important concept jbrowse uses to avoid
929
+ * re-rendering when you scroll to the side. when you horizontally
930
+ * scroll to the right, old blocks to the left may be removed, and
931
+ * new blocks may be instantiated on the right. tracks may use the
932
+ * static blocks to render their data for the region represented by
933
+ * the block
934
+ */
745
935
  get staticBlocks() {
746
936
  const ret = (0, calculateStaticBlocks_1.default)(self);
747
937
  const sret = JSON.stringify(ret);
@@ -751,27 +941,48 @@ function stateModelFactory(pluginManager) {
751
941
  }
752
942
  return currentlyCalculatedStaticBlocks;
753
943
  },
944
+ /**
945
+ * #getter
946
+ * dynamic blocks represent the exact coordinates of the currently
947
+ * visible genome regions on the screen. they are similar to static
948
+ * blocks, but statcic blocks can go offscreen while dynamic blocks
949
+ * represent exactly what is on screen
950
+ */
754
951
  get dynamicBlocks() {
755
952
  return (0, calculateDynamicBlocks_1.default)(self);
756
953
  },
954
+ /**
955
+ * #getter
956
+ * rounded dynamic blocks are dynamic blocks without fractions of bp
957
+ */
757
958
  get roundedDynamicBlocks() {
758
- return this.dynamicBlocks.contentBlocks.map(block => {
759
- return {
760
- ...block,
761
- start: Math.floor(block.start),
762
- end: Math.ceil(block.end),
763
- };
764
- });
959
+ return this.dynamicBlocks.contentBlocks.map(block => ({
960
+ ...block,
961
+ start: Math.floor(block.start),
962
+ end: Math.ceil(block.end),
963
+ }));
765
964
  },
965
+ /**
966
+ * #getter
967
+ * a single "combo-locstring" representing all the regions visible
968
+ * on the screen
969
+ */
766
970
  get visibleLocStrings() {
767
971
  return calculateVisibleLocStrings(this.dynamicBlocks.contentBlocks);
768
972
  },
973
+ /**
974
+ * #getter
975
+ * same as visibleLocStrings, but only updated every 300ms
976
+ */
769
977
  get coarseVisibleLocStrings() {
770
978
  return calculateVisibleLocStrings(self.coarseDynamicBlocks);
771
979
  },
772
980
  };
773
981
  })
774
982
  .actions(self => ({
983
+ /**
984
+ * #action
985
+ */
775
986
  setCoarseDynamicBlocks(blocks) {
776
987
  self.coarseDynamicBlocks = blocks.contentBlocks;
777
988
  self.coarseTotalBp = blocks.totalBp;
@@ -786,6 +997,7 @@ function stateModelFactory(pluginManager) {
786
997
  }))
787
998
  .actions(self => ({
788
999
  /**
1000
+ * #action
789
1001
  * offset is the base-pair-offset in the displayed region, index is the index of the
790
1002
  * displayed region in the linear genome view
791
1003
  *
@@ -795,7 +1007,14 @@ function stateModelFactory(pluginManager) {
795
1007
  moveTo(start, end) {
796
1008
  (0, Base1DUtils_1.moveTo)(self, start, end);
797
1009
  },
798
- navToLocString(locString, optAssemblyName) {
1010
+ /**
1011
+ * #action
1012
+ * navigate to the given locstring
1013
+ *
1014
+ * @param locString - e.g. "chr1:1-100"
1015
+ * @param optAssemblyName - (optional) the assembly name to use when navigating to the locstring
1016
+ */
1017
+ async navToLocString(locString, optAssemblyName) {
799
1018
  const { assemblyNames } = self;
800
1019
  const { assemblyManager } = (0, util_1.getSession)(self);
801
1020
  const { isValidRefName } = assemblyManager;
@@ -805,6 +1024,9 @@ function stateModelFactory(pluginManager) {
805
1024
  .split(/(\s+)/)
806
1025
  .map(f => f.trim())
807
1026
  .filter(f => !!f);
1027
+ if (assemblyName) {
1028
+ await assemblyManager.waitForAssembly(assemblyName);
1029
+ }
808
1030
  // first try interpreting as a whitespace-separated sequence of
809
1031
  // multiple locstrings
810
1032
  try {
@@ -825,9 +1047,9 @@ function stateModelFactory(pluginManager) {
825
1047
  throw e;
826
1048
  }
827
1049
  }
828
- const locations = parsedLocStrings === null || parsedLocStrings === void 0 ? void 0 : parsedLocStrings.map(region => {
1050
+ const locations = await Promise.all(parsedLocStrings === null || parsedLocStrings === void 0 ? void 0 : parsedLocStrings.map(async (region) => {
829
1051
  const asmName = region.assemblyName || assemblyName;
830
- const asm = assemblyManager.get(asmName);
1052
+ const asm = await assemblyManager.waitForAssembly(asmName);
831
1053
  const { refName } = region;
832
1054
  if (!asm) {
833
1055
  throw new Error(`assembly ${asmName} not found`);
@@ -840,7 +1062,7 @@ function stateModelFactory(pluginManager) {
840
1062
  if (!canonicalRefName) {
841
1063
  throw new Error(`Could not find refName ${refName} in ${asm.name}`);
842
1064
  }
843
- const parentRegion = regions.find(region => region.refName === canonicalRefName);
1065
+ const parentRegion = regions.find(r => r.refName === canonicalRefName);
844
1066
  if (!parentRegion) {
845
1067
  throw new Error(`Could not find refName ${refName} in ${asmName}`);
846
1068
  }
@@ -849,7 +1071,7 @@ function stateModelFactory(pluginManager) {
849
1071
  assemblyName: asmName,
850
1072
  parentRegion,
851
1073
  };
852
- });
1074
+ }));
853
1075
  if (locations.length === 1) {
854
1076
  const loc = locations[0];
855
1077
  self.setDisplayedRegions([
@@ -870,6 +1092,7 @@ function stateModelFactory(pluginManager) {
870
1092
  }
871
1093
  },
872
1094
  /**
1095
+ * #action
873
1096
  * Navigate to a location based on its refName and optionally start, end,
874
1097
  * and assemblyName. Can handle if there are multiple displayedRegions
875
1098
  * from same refName. Only navigates to a location if it is entirely
@@ -878,11 +1101,14 @@ function stateModelFactory(pluginManager) {
878
1101
  *
879
1102
  * Throws an error if navigation was unsuccessful
880
1103
  *
881
- * @param location - a proposed location to navigate to
1104
+ * @param query - a proposed location to navigate to
882
1105
  */
883
1106
  navTo(query) {
884
1107
  this.navToMultiple([query]);
885
1108
  },
1109
+ /**
1110
+ * #action
1111
+ */
886
1112
  navToMultiple(locations) {
887
1113
  const firstLocation = locations[0];
888
1114
  let { refName } = firstLocation;
@@ -984,6 +1210,9 @@ function stateModelFactory(pluginManager) {
984
1210
  },
985
1211
  }))
986
1212
  .views(self => ({
1213
+ /**
1214
+ * #method
1215
+ */
987
1216
  rubberBandMenuItems() {
988
1217
  return [
989
1218
  {
@@ -1001,10 +1230,14 @@ function stateModelFactory(pluginManager) {
1001
1230
  },
1002
1231
  ];
1003
1232
  },
1233
+ /**
1234
+ * #method
1235
+ */
1004
1236
  bpToPx({ refName, coord, regionNumber, }) {
1005
1237
  return (0, Base1DUtils_1.bpToPx)({ refName, coord, regionNumber, self });
1006
1238
  },
1007
1239
  /**
1240
+ * #method
1008
1241
  * scrolls the view to center on the given bp. if that is not in any
1009
1242
  * of the displayed regions, does nothing
1010
1243
  * @param coord - basepair at which you want to center the view
@@ -1021,9 +1254,15 @@ function stateModelFactory(pluginManager) {
1021
1254
  self.scrollTo(Math.round(centerPx.offsetPx - self.width / 2));
1022
1255
  }
1023
1256
  },
1257
+ /**
1258
+ * #method
1259
+ */
1024
1260
  pxToBp(px) {
1025
1261
  return (0, Base1DUtils_1.pxToBp)(self, px);
1026
1262
  },
1263
+ /**
1264
+ * #getter
1265
+ */
1027
1266
  get centerLineInfo() {
1028
1267
  return self.displayedRegions.length
1029
1268
  ? this.pxToBp(self.width / 2)