@jbrowse/plugin-linear-genome-view 2.4.1 → 2.4.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 (58) hide show
  1. package/dist/BaseLinearDisplay/components/LinearBlocks.d.ts +1 -3
  2. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +8 -43
  3. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  4. package/dist/BaseLinearDisplay/components/TooLargeMessage.d.ts +2 -2
  5. package/dist/BaseLinearDisplay/components/TooLargeMessage.js +4 -8
  6. package/dist/BaseLinearDisplay/components/TooLargeMessage.js.map +1 -1
  7. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +13 -28
  8. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +93 -137
  9. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  10. package/dist/BaseLinearDisplay/models/util.d.ts +4 -0
  11. package/dist/BaseLinearDisplay/models/util.js +33 -1
  12. package/dist/BaseLinearDisplay/models/util.js.map +1 -1
  13. package/dist/LinearBareDisplay/index.js +1 -0
  14. package/dist/LinearBareDisplay/index.js.map +1 -1
  15. package/dist/LinearBareDisplay/model.d.ts +11 -19
  16. package/dist/LinearBasicDisplay/components/SetMaxHeight.d.ts +1 -1
  17. package/dist/LinearBasicDisplay/components/SetMaxHeight.js +2 -5
  18. package/dist/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  19. package/dist/LinearBasicDisplay/index.js +1 -1
  20. package/dist/LinearBasicDisplay/model.d.ts +14 -35
  21. package/dist/LinearBasicDisplay/model.js.map +1 -1
  22. package/dist/LinearGenomeView/components/RefNameAutocomplete.js +11 -17
  23. package/dist/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  24. package/dist/index.d.ts +33 -57
  25. package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +1 -3
  26. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +8 -20
  27. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  28. package/esm/BaseLinearDisplay/components/TooLargeMessage.d.ts +2 -2
  29. package/esm/BaseLinearDisplay/components/TooLargeMessage.js +4 -8
  30. package/esm/BaseLinearDisplay/components/TooLargeMessage.js.map +1 -1
  31. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +13 -28
  32. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js +92 -136
  33. package/esm/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  34. package/esm/BaseLinearDisplay/models/util.d.ts +4 -0
  35. package/esm/BaseLinearDisplay/models/util.js +30 -0
  36. package/esm/BaseLinearDisplay/models/util.js.map +1 -1
  37. package/esm/LinearBareDisplay/index.js +1 -0
  38. package/esm/LinearBareDisplay/index.js.map +1 -1
  39. package/esm/LinearBareDisplay/model.d.ts +11 -19
  40. package/esm/LinearBasicDisplay/components/SetMaxHeight.d.ts +1 -1
  41. package/esm/LinearBasicDisplay/components/SetMaxHeight.js +2 -5
  42. package/esm/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  43. package/esm/LinearBasicDisplay/index.js +1 -1
  44. package/esm/LinearBasicDisplay/model.d.ts +14 -35
  45. package/esm/LinearBasicDisplay/model.js.map +1 -1
  46. package/esm/LinearGenomeView/components/RefNameAutocomplete.js +11 -17
  47. package/esm/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  48. package/esm/index.d.ts +33 -57
  49. package/package.json +2 -2
  50. package/src/BaseLinearDisplay/components/ServerSideRenderedBlockContent.tsx +8 -28
  51. package/src/BaseLinearDisplay/components/TooLargeMessage.tsx +8 -10
  52. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +130 -189
  53. package/src/BaseLinearDisplay/models/util.ts +37 -0
  54. package/src/LinearBareDisplay/index.ts +1 -0
  55. package/src/LinearBasicDisplay/components/SetMaxHeight.tsx +3 -7
  56. package/src/LinearBasicDisplay/index.ts +1 -1
  57. package/src/LinearBasicDisplay/model.ts +1 -1
  58. package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +16 -18
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import React from 'react'
3
+ import { ThemeOptions } from '@mui/material'
3
4
  import { BaseDisplay } from '@jbrowse/core/pluggableElementTypes/models'
4
5
  import { getConf } from '@jbrowse/core/configuration'
5
6
  import { MenuItem } from '@jbrowse/core/ui'
@@ -19,10 +20,7 @@ import { Stats } from '@jbrowse/core/data_adapters/BaseAdapter'
19
20
  import { BaseBlock } from '@jbrowse/core/util/blockTypes'
20
21
  import { Region } from '@jbrowse/core/util/types'
21
22
  import CompositeMap from '@jbrowse/core/util/compositeMap'
22
- import {
23
- getParentRenderProps,
24
- getRpcSessionId,
25
- } from '@jbrowse/core/util/tracks'
23
+ import { getParentRenderProps } from '@jbrowse/core/util/tracks'
26
24
  import { autorun } from 'mobx'
27
25
  import { addDisposer, isAlive, types, Instance } from 'mobx-state-tree'
28
26
 
@@ -34,7 +32,7 @@ import { LinearGenomeViewModel, ExportSvgOptions } from '../../LinearGenomeView'
34
32
  import { Tooltip } from '../components/BaseLinearDisplay'
35
33
  import TooLargeMessage from '../components/TooLargeMessage'
36
34
  import BlockState, { renderBlockData } from './serverSideRenderedBlock'
37
- import { ThemeOptions } from '@mui/material'
35
+ import { getId, getDisplayStr, estimateRegionsStatsPre } from './util'
38
36
 
39
37
  type LGV = LinearGenomeViewModel
40
38
 
@@ -46,26 +44,8 @@ export interface Layout {
46
44
  name: string
47
45
  }
48
46
 
49
- // stabilize clipid under test for snapshot
50
- function getId(id: string, index: number) {
51
- const isJest = typeof jest === 'undefined'
52
- return `clip-${isJest ? id : 'jest'}-${index}`
53
- }
54
-
55
47
  type LayoutRecord = [number, number, number, number]
56
48
 
57
- function getDisplayStr(totalBytes: number) {
58
- let displayBp
59
- if (Math.floor(totalBytes / 1000000) > 0) {
60
- displayBp = `${Number.parseFloat((totalBytes / 1000000).toPrecision(3))} Mb`
61
- } else if (Math.floor(totalBytes / 1000) > 0) {
62
- displayBp = `${Number.parseFloat((totalBytes / 1000).toPrecision(3))} Kb`
63
- } else {
64
- displayBp = `${Math.floor(totalBytes)} bytes`
65
- }
66
- return displayBp
67
- }
68
-
69
49
  const minDisplayHeight = 20
70
50
 
71
51
  /**
@@ -109,8 +89,8 @@ function stateModelFactory() {
109
89
  message: '',
110
90
  featureIdUnderMouse: undefined as undefined | string,
111
91
  contextMenuFeature: undefined as undefined | Feature,
112
- estimatedRegionStatsP: undefined as undefined | Promise<Stats>,
113
- estimatedRegionStats: undefined as undefined | Stats,
92
+ estimatedRegionsStatsP: undefined as undefined | Promise<Stats>,
93
+ estimatedRegionsStats: undefined as undefined | Stats,
114
94
  }))
115
95
  .views(self => ({
116
96
  get height() {
@@ -184,7 +164,7 @@ function stateModelFactory() {
184
164
  get features() {
185
165
  const featureMaps = []
186
166
  for (const block of self.blockState.values()) {
187
- if (block && block.features) {
167
+ if (block?.features) {
188
168
  featureMaps.push(block.features)
189
169
  }
190
170
  }
@@ -202,7 +182,11 @@ function stateModelFactory() {
202
182
  /**
203
183
  * #getter
204
184
  */
205
- getFeatureOverlapping(blockKey: string, x: number, y: number) {
185
+ getFeatureOverlapping(
186
+ blockKey: string,
187
+ x: number,
188
+ y: number,
189
+ ): string | undefined {
206
190
  return self.blockState.get(blockKey)?.layout?.getByCoord(x, y)
207
191
  },
208
192
 
@@ -231,7 +215,7 @@ function stateModelFactory() {
231
215
  * #getter
232
216
  */
233
217
  get currentBytesRequested() {
234
- return self.estimatedRegionStats?.bytes || 0
218
+ return self.estimatedRegionsStats?.bytes || 0
235
219
  },
236
220
 
237
221
  /**
@@ -239,7 +223,7 @@ function stateModelFactory() {
239
223
  */
240
224
  get currentFeatureScreenDensity() {
241
225
  const view = getContainingView(self) as LGV
242
- return (self.estimatedRegionStats?.featureDensity || 0) * view.bpPerPx
226
+ return (self.estimatedRegionsStats?.featureDensity || 0) * view.bpPerPx
243
227
  },
244
228
 
245
229
  /**
@@ -252,7 +236,7 @@ function stateModelFactory() {
252
236
  * #getter
253
237
  */
254
238
  get estimatedStatsReady() {
255
- return !!self.estimatedRegionStats
239
+ return !!self.estimatedRegionsStats || !!self.userBpPerPxLimit
256
240
  },
257
241
 
258
242
  /**
@@ -261,7 +245,7 @@ function stateModelFactory() {
261
245
  get maxAllowableBytes() {
262
246
  return (
263
247
  self.userByteSizeLimit ||
264
- self.estimatedRegionStats?.fetchSizeLimit ||
248
+ self.estimatedRegionsStats?.fetchSizeLimit ||
265
249
  (getConf(self, 'fetchSizeLimit') as number)
266
250
  )
267
251
  },
@@ -273,95 +257,68 @@ function stateModelFactory() {
273
257
  setMessage(message: string) {
274
258
  self.message = message
275
259
  },
276
-
260
+ }))
261
+ .actions(self => ({
277
262
  afterAttach() {
278
263
  // watch the parent's blocks to update our block state when they change,
279
264
  // then we recreate the blocks on our own model (creating and deleting to
280
265
  // match the parent blocks)
281
- const blockWatchDisposer = autorun(() => {
282
- const blocksPresent: { [key: string]: boolean } = {}
283
- const view = getContainingView(self) as LGV
284
- if (view.initialized) {
285
- self.blockDefinitions.contentBlocks.forEach(block => {
286
- blocksPresent[block.key] = true
287
- if (!self.blockState.has(block.key)) {
288
- this.addBlock(block.key, block)
289
- }
290
- })
291
- self.blockState.forEach((_, key) => {
292
- if (!blocksPresent[key]) {
293
- this.deleteBlock(key)
294
- }
295
- })
296
- }
297
- })
298
-
299
- addDisposer(self, blockWatchDisposer)
266
+ addDisposer(
267
+ self,
268
+ autorun(() => {
269
+ const blocksPresent: { [key: string]: boolean } = {}
270
+ const view = getContainingView(self) as LGV
271
+ if (view.initialized) {
272
+ self.blockDefinitions.contentBlocks.forEach(block => {
273
+ blocksPresent[block.key] = true
274
+ if (!self.blockState.has(block.key)) {
275
+ this.addBlock(block.key, block)
276
+ }
277
+ })
278
+ self.blockState.forEach((_, key) => {
279
+ if (!blocksPresent[key]) {
280
+ this.deleteBlock(key)
281
+ }
282
+ })
283
+ }
284
+ }),
285
+ )
300
286
  },
301
287
 
302
288
  /**
303
289
  * #action
304
290
  */
305
- estimateRegionsStats(
306
- regions: Region[],
307
- opts: {
308
- headers?: Record<string, string>
309
- signal?: AbortSignal
310
- filters?: string[]
311
- },
312
- ) {
313
- if (self.estimatedRegionStatsP) {
314
- return self.estimatedRegionStatsP
315
- }
316
-
317
- const { rpcManager } = getSession(self)
318
- const { adapterConfig } = self
319
- if (!adapterConfig) {
320
- // A track extending the base track might not have an adapter config
321
- // e.g. Apollo tracks don't use adapters
322
- return Promise.resolve({})
323
- }
324
- const sessionId = getRpcSessionId(self)
325
-
326
- const params = {
327
- sessionId,
328
- regions,
329
- adapterConfig,
330
- statusCallback: (message: string) => {
331
- if (isAlive(self)) {
332
- this.setMessage(message)
333
- }
334
- },
335
- ...opts,
291
+ async estimateRegionsStats() {
292
+ if (!self.estimatedRegionsStatsP) {
293
+ self.estimatedRegionsStatsP = estimateRegionsStatsPre(self).catch(
294
+ e => {
295
+ this.setRegionsStatsP(undefined)
296
+ throw e
297
+ },
298
+ )
336
299
  }
337
-
338
- self.estimatedRegionStatsP = rpcManager
339
- .call(sessionId, 'CoreEstimateRegionStats', params)
340
- .catch(e => {
341
- this.setRegionStatsP(undefined)
342
- throw e
343
- }) as Promise<Stats>
344
-
345
- return self.estimatedRegionStatsP
300
+ return self.estimatedRegionsStatsP
346
301
  },
302
+
347
303
  /**
348
304
  * #action
349
305
  */
350
- setRegionStatsP(p?: Promise<Stats>) {
351
- self.estimatedRegionStatsP = p
306
+ setRegionsStatsP(arg: any) {
307
+ self.estimatedRegionsStatsP = arg
352
308
  },
309
+
353
310
  /**
354
311
  * #action
355
312
  */
356
- setRegionStats(estimatedRegionStats?: Stats) {
357
- self.estimatedRegionStats = estimatedRegionStats
313
+ setRegionsStats(estimatedRegionsStats?: Stats) {
314
+ self.estimatedRegionsStats = estimatedRegionsStats
358
315
  },
359
316
  /**
360
317
  * #action
361
318
  */
362
- clearRegionStats() {
363
- self.estimatedRegionStatsP = undefined
364
- self.estimatedRegionStats = undefined
319
+ clearRegionsStats() {
320
+ self.estimatedRegionsStatsP = undefined
321
+ self.estimatedRegionsStats = undefined
365
322
  },
366
323
  /**
367
324
  * #action
@@ -390,9 +347,9 @@ function stateModelFactory() {
390
347
  /**
391
348
  * #action
392
349
  */
393
- updateStatsLimit(stats: Stats) {
350
+ updateStatsLimit(stats?: Stats) {
394
351
  const view = getContainingView(self) as LGV
395
- if (stats.bytes) {
352
+ if (stats?.bytes) {
396
353
  self.userByteSizeLimit = stats.bytes
397
354
  } else {
398
355
  self.userBpPerPxLimit = view.bpPerPx
@@ -484,13 +441,11 @@ function stateModelFactory() {
484
441
  if (!self.estimatedStatsReady || view.dynamicBlocks.totalBp < 20_000) {
485
442
  return false
486
443
  }
487
- const bpLimitOrDensity = self.userBpPerPxLimit
488
- ? view.bpPerPx > self.userBpPerPxLimit
489
- : self.currentFeatureScreenDensity > self.maxFeatureScreenDensity
490
-
491
444
  return (
492
445
  self.currentBytesRequested > self.maxAllowableBytes ||
493
- bpLimitOrDensity
446
+ (self.userBpPerPxLimit
447
+ ? view.bpPerPx > self.userBpPerPxLimit
448
+ : self.currentFeatureScreenDensity > self.maxFeatureScreenDensity)
494
449
  )
495
450
  },
496
451
 
@@ -517,7 +472,6 @@ function stateModelFactory() {
517
472
  */
518
473
  async reload() {
519
474
  self.setError()
520
- const aborter = new AbortController()
521
475
  const view = getContainingView(self) as LGV
522
476
 
523
477
  // extra check for contentBlocks.length
@@ -527,84 +481,70 @@ function stateModelFactory() {
527
481
  }
528
482
 
529
483
  try {
530
- self.estimatedRegionStatsP = self.estimateRegionsStats(
531
- view.staticBlocks.contentBlocks,
532
- { signal: aborter.signal },
533
- )
534
- const estimatedRegionStats = await self.estimatedRegionStatsP
484
+ const estimatedRegionsStats = await self.estimateRegionsStats()
535
485
 
536
486
  if (isAlive(self)) {
537
- self.setRegionStats(estimatedRegionStats)
487
+ self.setRegionsStats(estimatedRegionsStats)
538
488
  superReload()
539
- } else {
540
- return
541
489
  }
542
490
  } catch (e) {
543
491
  console.error(e)
544
492
  self.setError(e)
545
493
  }
546
494
  },
547
- afterAttach() {
548
- // this autorun performs stats estimation
549
- //
550
- // the chain of events calls estimateRegionsStats against the data
551
- // adapter which by default uses featureDensity, but can also respond
552
- // with a byte size estimate and fetch size limit (data adapter can
553
- // define what is too much data)
554
- addDisposer(
555
- self,
556
- autorun(
557
- async () => {
558
- try {
559
- const aborter = new AbortController()
560
- const view = getContainingView(self) as LGV
561
-
562
- // extra check for contentBlocks.length
563
- // https://github.com/GMOD/jbrowse-components/issues/2694
564
- if (
565
- !view.initialized ||
566
- !view.staticBlocks.contentBlocks.length
567
- ) {
568
- return
569
- }
570
-
571
- // don't re-estimate featureDensity even if zoom level changes,
572
- // jbrowse1-style assume it's sort of representative
573
- if (self.estimatedRegionStats?.featureDensity !== undefined) {
574
- self.setCurrBpPerPx(view.bpPerPx)
575
- return
576
- }
577
-
578
- // we estimate stats once at a given zoom level
579
- if (view.bpPerPx === self.currBpPerPx) {
580
- return
581
- }
582
-
583
- self.clearRegionStats()
584
- self.setCurrBpPerPx(view.bpPerPx)
585
- const statsP = self.estimateRegionsStats(
586
- view.staticBlocks.contentBlocks,
587
- { signal: aborter.signal },
588
- )
589
- self.setRegionStatsP(statsP)
590
- const estimatedRegionStats = await statsP
591
-
592
- if (isAlive(self)) {
593
- self.setRegionStats(estimatedRegionStats)
594
- }
595
- } catch (e) {
596
- if (!isAbortException(e) && isAlive(self)) {
597
- console.error(e)
598
- self.setError(e)
599
- }
600
- }
601
- },
602
- { delay: 500 },
603
- ),
604
- )
605
- },
606
495
  }
607
496
  })
497
+ .actions(self => ({
498
+ afterAttach() {
499
+ // this autorun performs stats estimation
500
+ //
501
+ // the chain of events calls estimateRegionsStats against the data
502
+ // adapter which by default uses featureDensity, but can also respond
503
+ // with a byte size estimate and fetch size limit (data adapter can
504
+ // define what is too much data)
505
+ addDisposer(
506
+ self,
507
+ autorun(async () => {
508
+ try {
509
+ const view = getContainingView(self) as LGV
510
+
511
+ // extra check for contentBlocks.length
512
+ // https://github.com/GMOD/jbrowse-components/issues/2694
513
+ if (
514
+ !view.initialized ||
515
+ !view.staticBlocks.contentBlocks.length
516
+ ) {
517
+ return
518
+ }
519
+
520
+ // don't re-estimate featureDensity even if zoom level changes,
521
+ // jbrowse1-style assume it's sort of representative
522
+ if (self.estimatedRegionsStats?.featureDensity !== undefined) {
523
+ self.setCurrBpPerPx(view.bpPerPx)
524
+ return
525
+ }
526
+
527
+ // we estimate stats once at a given zoom level
528
+ if (view.bpPerPx === self.currBpPerPx) {
529
+ return
530
+ }
531
+
532
+ self.clearRegionsStats()
533
+ self.setCurrBpPerPx(view.bpPerPx)
534
+ const estimatedRegionsStats = await self.estimateRegionsStats()
535
+ if (isAlive(self)) {
536
+ self.setRegionsStats(estimatedRegionsStats)
537
+ }
538
+ } catch (e) {
539
+ if (!isAbortException(e) && isAlive(self)) {
540
+ console.error(e)
541
+ self.setError(e)
542
+ }
543
+ }
544
+ }),
545
+ )
546
+ },
547
+ }))
608
548
  .views(self => ({
609
549
  /**
610
550
  * #method
@@ -622,8 +562,7 @@ function stateModelFactory() {
622
562
  * react node allows user to force load at current setting
623
563
  */
624
564
  regionCannotBeRendered(_region: Region) {
625
- const { regionTooLarge } = self
626
- return regionTooLarge ? <TooLargeMessage model={self} /> : null
565
+ return self.regionTooLarge ? <TooLargeMessage model={self} /> : null
627
566
  },
628
567
 
629
568
  /**
@@ -636,20 +575,22 @@ function stateModelFactory() {
636
575
  /**
637
576
  * #method
638
577
  */
639
- contextMenuItems() {
640
- return self.contextMenuFeature
641
- ? [
642
- {
643
- label: 'Open feature details',
644
- icon: MenuOpenIcon,
645
- onClick: () => {
646
- if (self.contextMenuFeature) {
647
- self.selectFeature(self.contextMenuFeature)
648
- }
578
+ contextMenuItems(): MenuItem[] {
579
+ return [
580
+ ...(self.contextMenuFeature
581
+ ? [
582
+ {
583
+ label: 'Open feature details',
584
+ icon: MenuOpenIcon,
585
+ onClick: () => {
586
+ if (self.contextMenuFeature) {
587
+ self.selectFeature(self.contextMenuFeature)
588
+ }
589
+ },
649
590
  },
650
- },
651
- ]
652
- : []
591
+ ]
592
+ : []),
593
+ ]
653
594
  },
654
595
  /**
655
596
  * #method
@@ -659,7 +600,7 @@ function stateModelFactory() {
659
600
  return {
660
601
  ...getParentRenderProps(self),
661
602
  notReady:
662
- self.currBpPerPx !== view.bpPerPx || !self.estimatedRegionStats,
603
+ self.currBpPerPx !== view.bpPerPx || !self.estimatedRegionsStats,
663
604
  rpcDriverName: self.rpcDriverName,
664
605
  displayModel: self,
665
606
  onFeatureClick(_: unknown, featureId?: string) {
@@ -1,3 +1,9 @@
1
+ import { Stats } from '@jbrowse/core/data_adapters/BaseAdapter'
2
+ import { getContainingView, getSession } from '@jbrowse/core/util'
3
+ import { getRpcSessionId } from '@jbrowse/core/util/tracks'
4
+ import { IAnyStateTreeNode, isAlive } from 'mobx-state-tree'
5
+ import { LinearGenomeViewModel } from '../../LinearGenomeView'
6
+
1
7
  export interface RenderProps {
2
8
  rendererType: any // eslint-disable-line @typescript-eslint/no-explicit-any
3
9
  renderArgs: { [key: string]: any } // eslint-disable-line @typescript-eslint/no-explicit-any
@@ -22,3 +28,34 @@ export function getDisplayStr(totalBytes: number) {
22
28
  }
23
29
  return displayBp
24
30
  }
31
+
32
+ // stabilize clipid under test for snapshot
33
+ export function getId(id: string, index: number) {
34
+ const isJest = typeof jest === 'undefined'
35
+ return `clip-${isJest ? id : 'jest'}-${index}`
36
+ }
37
+
38
+ export async function estimateRegionsStatsPre(self: IAnyStateTreeNode) {
39
+ const view = getContainingView(self) as LinearGenomeViewModel
40
+ const regions = view.staticBlocks.contentBlocks
41
+
42
+ const { rpcManager } = getSession(self)
43
+ const { adapterConfig } = self
44
+ if (!adapterConfig) {
45
+ // A track extending the base track might not have an adapter config
46
+ // e.g. Apollo tracks don't use adapters
47
+ return {}
48
+ }
49
+ const sessionId = getRpcSessionId(self)
50
+
51
+ return rpcManager.call(sessionId, 'CoreEstimateRegionStats', {
52
+ sessionId,
53
+ regions,
54
+ adapterConfig,
55
+ statusCallback: (message: string) => {
56
+ if (isAlive(self)) {
57
+ self.setMessage(message)
58
+ }
59
+ },
60
+ }) as Promise<Stats>
61
+ }
@@ -12,6 +12,7 @@ export default (pluginManager: PluginManager) => {
12
12
  return new DisplayType({
13
13
  name: 'LinearBareDisplay',
14
14
  configSchema,
15
+ displayName: 'Bare feature display',
15
16
  stateModel: stateModelFactory(configSchema),
16
17
  trackType: 'BasicTrack',
17
18
  viewType: 'LinearGenomeView',
@@ -10,15 +10,11 @@ import {
10
10
  } from '@mui/material'
11
11
  import { makeStyles } from 'tss-react/mui'
12
12
 
13
- const useStyles = makeStyles()(theme => ({
13
+ const useStyles = makeStyles()({
14
14
  root: {
15
15
  width: 500,
16
16
  },
17
-
18
- field: {
19
- margin: theme.spacing(2),
20
- },
21
- }))
17
+ })
22
18
 
23
19
  function SetMaxHeightDlg({
24
20
  model,
@@ -26,7 +22,7 @@ function SetMaxHeightDlg({
26
22
  }: {
27
23
  model: {
28
24
  maxHeight?: number
29
- setMaxHeight: Function
25
+ setMaxHeight: (arg?: number) => void
30
26
  }
31
27
  handleClose: () => void
32
28
  }) {
@@ -11,7 +11,7 @@ export default (pluginManager: PluginManager) => {
11
11
  const config = configSchema(pluginManager)
12
12
  return new DisplayType({
13
13
  name: 'LinearBasicDisplay',
14
- displayName: 'Basic deature display',
14
+ displayName: 'Basic feature display',
15
15
  configSchema: config,
16
16
  stateModel: modelFactory(config),
17
17
  trackType: 'FeatureTrack',
@@ -137,7 +137,7 @@ function stateModelFactory(configSchema: AnyConfigurationSchemaType) {
137
137
  /**
138
138
  * #action
139
139
  */
140
- setMaxHeight(val: number) {
140
+ setMaxHeight(val?: number) {
141
141
  self.trackMaxHeight = val
142
142
  },
143
143
  }))
@@ -30,13 +30,12 @@ export interface Option {
30
30
  function aggregateResults(results: BaseResult[]) {
31
31
  const m: { [key: string]: BaseResult[] } = {}
32
32
 
33
- for (let i = 0; i < results.length; i++) {
34
- const r = results[i]
35
- const d = r.getDisplayString()
36
- if (!m[d]) {
37
- m[d] = []
33
+ for (const result of results) {
34
+ const displayString = result.getDisplayString()
35
+ if (!m[displayString]) {
36
+ m[displayString] = []
38
37
  }
39
- m[d].push(r)
38
+ m[displayString].push(result)
40
39
  }
41
40
  return m
42
41
  }
@@ -63,13 +62,11 @@ function getDeduplicatedResult(results: BaseResult[]) {
63
62
  // because they do not have a matchedObject. the trix search results already
64
63
  // filter so don't need re-filtering
65
64
  function filterOptions(options: Option[], searchQuery: string) {
66
- return options.filter(option => {
67
- const { result } = option
68
- return (
65
+ return options.filter(
66
+ ({ result }) =>
69
67
  result.getLabel().toLowerCase().includes(searchQuery) ||
70
- result.matchedObject
71
- )
72
- })
68
+ result.matchedObject,
69
+ )
73
70
  }
74
71
 
75
72
  function RefNameAutocomplete({
@@ -109,18 +106,17 @@ function RefNameAutocomplete({
109
106
  const assembly = assemblyName ? assemblyManager.get(assemblyName) : undefined
110
107
  const { coarseVisibleLocStrings, hasDisplayedRegions } = model
111
108
 
112
- // eslint-disable-next-line react-hooks/exhaustive-deps
113
- const regions = assembly?.regions || []
109
+ const regions = assembly?.regions
114
110
 
115
111
  const options = useMemo(
116
112
  () =>
117
- regions.map(option => ({
113
+ regions?.map(option => ({
118
114
  result: new RefSequenceResult({
119
115
  refName: option.refName,
120
116
  label: option.refName,
121
117
  matchedAttribute: 'refName',
122
118
  }),
123
- })),
119
+ })) || [],
124
120
  [regions],
125
121
  )
126
122
 
@@ -157,8 +153,10 @@ function RefNameAutocomplete({
157
153
 
158
154
  // heuristic, text width + icon width + 50 accommodates help icon and search
159
155
  // icon
160
- const w = measureText(inputBoxVal, 16) + 50
161
- const width = Math.min(Math.max(w, minWidth), maxWidth)
156
+ const width = Math.min(
157
+ Math.max(measureText(inputBoxVal, 16) + 50, minWidth),
158
+ maxWidth,
159
+ )
162
160
 
163
161
  // notes on implementation:
164
162
  // The selectOnFocus setting helps highlight the field when clicked