@jbrowse/product-core 2.6.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 (92) hide show
  1. package/LICENSE +201 -0
  2. package/dist/RootModel/BaseRootModel.d.ts +607 -0
  3. package/dist/RootModel/BaseRootModel.js +101 -0
  4. package/dist/RootModel/InternetAccounts.d.ts +31 -0
  5. package/dist/RootModel/InternetAccounts.js +99 -0
  6. package/dist/RootModel/index.d.ts +2 -0
  7. package/dist/RootModel/index.js +18 -0
  8. package/dist/Session/BaseSession.d.ts +99 -0
  9. package/dist/Session/BaseSession.js +112 -0
  10. package/dist/Session/Connections.d.ts +174 -0
  11. package/dist/Session/Connections.js +113 -0
  12. package/dist/Session/DialogQueue.d.ts +34 -0
  13. package/dist/Session/DialogQueue.js +55 -0
  14. package/dist/Session/DrawerWidgets.d.ts +88 -0
  15. package/dist/Session/DrawerWidgets.js +167 -0
  16. package/dist/Session/MultipleViews.d.ts +1798 -0
  17. package/dist/Session/MultipleViews.js +105 -0
  18. package/dist/Session/ReferenceManagement.d.ts +34 -0
  19. package/dist/Session/ReferenceManagement.js +91 -0
  20. package/dist/Session/SessionTracks.d.ts +1866 -0
  21. package/dist/Session/SessionTracks.js +75 -0
  22. package/dist/Session/Themes.d.ts +38 -0
  23. package/dist/Session/Themes.js +64 -0
  24. package/dist/Session/Tracks.d.ts +1821 -0
  25. package/dist/Session/Tracks.js +51 -0
  26. package/dist/Session/index.d.ts +10 -0
  27. package/dist/Session/index.js +26 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.js +19 -0
  30. package/dist/ui/AboutDialog.d.ts +6 -0
  31. package/dist/ui/AboutDialog.js +20 -0
  32. package/dist/ui/AboutDialogContents.d.ts +5 -0
  33. package/dist/ui/AboutDialogContents.js +70 -0
  34. package/dist/ui/FileInfoPanel.d.ts +5 -0
  35. package/dist/ui/FileInfoPanel.js +76 -0
  36. package/dist/ui/index.d.ts +1 -0
  37. package/dist/ui/index.js +17 -0
  38. package/esm/RootModel/BaseRootModel.d.ts +607 -0
  39. package/esm/RootModel/BaseRootModel.js +93 -0
  40. package/esm/RootModel/InternetAccounts.d.ts +31 -0
  41. package/esm/RootModel/InternetAccounts.js +95 -0
  42. package/esm/RootModel/index.d.ts +2 -0
  43. package/esm/RootModel/index.js +2 -0
  44. package/esm/Session/BaseSession.d.ts +99 -0
  45. package/esm/Session/BaseSession.js +103 -0
  46. package/esm/Session/Connections.d.ts +174 -0
  47. package/esm/Session/Connections.js +108 -0
  48. package/esm/Session/DialogQueue.d.ts +34 -0
  49. package/esm/Session/DialogQueue.js +50 -0
  50. package/esm/Session/DrawerWidgets.d.ts +88 -0
  51. package/esm/Session/DrawerWidgets.js +162 -0
  52. package/esm/Session/MultipleViews.d.ts +1798 -0
  53. package/esm/Session/MultipleViews.js +100 -0
  54. package/esm/Session/ReferenceManagement.d.ts +34 -0
  55. package/esm/Session/ReferenceManagement.js +86 -0
  56. package/esm/Session/SessionTracks.d.ts +1866 -0
  57. package/esm/Session/SessionTracks.js +70 -0
  58. package/esm/Session/Themes.d.ts +38 -0
  59. package/esm/Session/Themes.js +59 -0
  60. package/esm/Session/Tracks.d.ts +1821 -0
  61. package/esm/Session/Tracks.js +46 -0
  62. package/esm/Session/index.d.ts +10 -0
  63. package/esm/Session/index.js +10 -0
  64. package/esm/index.d.ts +3 -0
  65. package/esm/index.js +3 -0
  66. package/esm/ui/AboutDialog.d.ts +6 -0
  67. package/esm/ui/AboutDialog.js +13 -0
  68. package/esm/ui/AboutDialogContents.d.ts +5 -0
  69. package/esm/ui/AboutDialogContents.js +41 -0
  70. package/esm/ui/FileInfoPanel.d.ts +5 -0
  71. package/esm/ui/FileInfoPanel.js +47 -0
  72. package/esm/ui/index.d.ts +1 -0
  73. package/esm/ui/index.js +1 -0
  74. package/package.json +66 -0
  75. package/src/RootModel/BaseRootModel.ts +131 -0
  76. package/src/RootModel/InternetAccounts.ts +126 -0
  77. package/src/RootModel/index.ts +2 -0
  78. package/src/Session/BaseSession.ts +129 -0
  79. package/src/Session/Connections.ts +145 -0
  80. package/src/Session/DialogQueue.ts +63 -0
  81. package/src/Session/DrawerWidgets.ts +222 -0
  82. package/src/Session/MultipleViews.ts +151 -0
  83. package/src/Session/ReferenceManagement.ts +134 -0
  84. package/src/Session/SessionTracks.ts +98 -0
  85. package/src/Session/Themes.ts +85 -0
  86. package/src/Session/Tracks.ts +72 -0
  87. package/src/Session/index.ts +10 -0
  88. package/src/index.ts +3 -0
  89. package/src/ui/AboutDialog.tsx +31 -0
  90. package/src/ui/AboutDialogContents.tsx +88 -0
  91. package/src/ui/FileInfoPanel.tsx +75 -0
  92. package/src/ui/index.ts +1 -0
@@ -0,0 +1,98 @@
1
+ import { IAnyStateTreeNode, Instance, types } from 'mobx-state-tree'
2
+
3
+ import PluginManager from '@jbrowse/core/PluginManager'
4
+ import {
5
+ AnyConfiguration,
6
+ AnyConfigurationModel,
7
+ } from '@jbrowse/core/configuration'
8
+
9
+ // locals
10
+ import { TracksManagerSessionMixin } from './Tracks'
11
+ import { isBaseSession } from './BaseSession'
12
+
13
+ /**
14
+ * #stateModel SessionTracksManagerSessionMixin
15
+ */
16
+ export function SessionTracksManagerSessionMixin(pluginManager: PluginManager) {
17
+ return TracksManagerSessionMixin(pluginManager)
18
+ .named('SessionTracksManagerSessionMixin')
19
+ .props({
20
+ /**
21
+ * #property
22
+ */
23
+ sessionTracks: types.array(
24
+ pluginManager.pluggableConfigSchemaType('track'),
25
+ ),
26
+ })
27
+ .views(self => ({
28
+ /**
29
+ * #getter
30
+ */
31
+ get tracks(): AnyConfigurationModel[] {
32
+ return self.jbrowse.tracks
33
+ },
34
+ }))
35
+ .actions(self => {
36
+ const {
37
+ addTrackConf: superAddTrackConf,
38
+ deleteTrackConf: superDeleteTrackConf,
39
+ } = self
40
+ return {
41
+ /**
42
+ * #action
43
+ */
44
+ addTrackConf(trackConf: AnyConfiguration) {
45
+ if (self.adminMode) {
46
+ return superAddTrackConf(trackConf)
47
+ }
48
+ const { trackId, type } = trackConf as {
49
+ type: string
50
+ trackId: string
51
+ }
52
+ if (!type) {
53
+ throw new Error(`unknown track type ${type}`)
54
+ }
55
+ const track = self.sessionTracks.find(t => t.trackId === trackId)
56
+ if (track) {
57
+ return track
58
+ }
59
+ const length = self.sessionTracks.push(trackConf)
60
+ return self.sessionTracks[length - 1]
61
+ },
62
+
63
+ /**
64
+ * #action
65
+ */
66
+ deleteTrackConf(trackConf: AnyConfigurationModel) {
67
+ // try to delete it in the main config if in admin mode
68
+ const found = superDeleteTrackConf(trackConf)
69
+ if (found) {
70
+ return found
71
+ }
72
+ // if not found or not in admin mode, try to delete it in the
73
+ // sessionTracks
74
+ const { trackId } = trackConf
75
+ const idx = self.sessionTracks.findIndex(t => t.trackId === trackId)
76
+ if (idx === -1) {
77
+ return undefined
78
+ }
79
+ return self.sessionTracks.splice(idx, 1)
80
+ },
81
+ }
82
+ })
83
+ }
84
+
85
+ /** Session mixin MST type for a session that has `sessionTracks` */
86
+ export type SessionWithSessionTracksType = ReturnType<
87
+ typeof SessionTracksManagerSessionMixin
88
+ >
89
+
90
+ /** Instance of a session that has `sessionTracks` */
91
+ export type SessionWithSessionTracks = Instance<SessionWithSessionTracksType>
92
+
93
+ /** Type guard for SessionWithSessionTracks */
94
+ export function isSessionWithSessionTracks(
95
+ thing: IAnyStateTreeNode,
96
+ ): thing is SessionWithSessionTracks {
97
+ return isBaseSession(thing) && 'sessionTracks' in thing
98
+ }
@@ -0,0 +1,85 @@
1
+ import {
2
+ IAnyStateTreeNode,
3
+ Instance,
4
+ addDisposer,
5
+ types,
6
+ } from 'mobx-state-tree'
7
+
8
+ import PluginManager from '@jbrowse/core/PluginManager'
9
+ import { getConf } from '@jbrowse/core/configuration'
10
+ import { createJBrowseTheme, defaultThemes } from '@jbrowse/core/ui'
11
+ import { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util'
12
+ import { ThemeOptions } from '@mui/material'
13
+ import { autorun } from 'mobx'
14
+
15
+ // locals
16
+ import { BaseSession } from './BaseSession'
17
+
18
+ type ThemeMap = { [key: string]: ThemeOptions }
19
+
20
+ /**
21
+ * #stateModel ThemeManagerSessionMixin
22
+ */
23
+ export function ThemeManagerSessionMixin(pluginManager: PluginManager) {
24
+ return types
25
+ .model({})
26
+ .volatile(() => ({
27
+ sessionThemeName: localStorageGetItem('themeName') || 'default',
28
+ }))
29
+ .views(s => ({
30
+ /**
31
+ * #method
32
+ */
33
+ allThemes(): ThemeMap {
34
+ const self = s as typeof s & BaseSession
35
+ const extraThemes = getConf(self.jbrowse, 'extraThemes')
36
+ return { ...defaultThemes, ...extraThemes }
37
+ },
38
+ /**
39
+ * #getter
40
+ */
41
+ get themeName() {
42
+ const { sessionThemeName } = s
43
+ const all = this.allThemes()
44
+ return all[sessionThemeName] ? sessionThemeName : 'default'
45
+ },
46
+ /**
47
+ * #getter
48
+ */
49
+ get theme() {
50
+ const self = s as typeof s & BaseSession
51
+ const configTheme = getConf(self.jbrowse, 'theme')
52
+ const all = this.allThemes()
53
+ return createJBrowseTheme(configTheme, all, this.themeName)
54
+ },
55
+ }))
56
+ .actions(self => ({
57
+ /**
58
+ * #action
59
+ */
60
+ setThemeName(name: string) {
61
+ self.sessionThemeName = name
62
+ },
63
+ afterAttach() {
64
+ addDisposer(
65
+ self,
66
+ autorun(() => {
67
+ localStorageSetItem('themeName', self.themeName)
68
+ }),
69
+ )
70
+ },
71
+ }))
72
+ }
73
+
74
+ /** Session mixin MST type for a session that supports theming */
75
+ export type SessionWithThemesType = ReturnType<typeof ThemeManagerSessionMixin>
76
+
77
+ /** Instance of a session that has theming support */
78
+ export type SessionWithThemes = Instance<SessionWithThemesType>
79
+
80
+ /** Type guard for SessionWithThemes */
81
+ export function isSessionWithThemes(
82
+ session: IAnyStateTreeNode,
83
+ ): session is SessionWithThemes {
84
+ return 'theme' in session
85
+ }
@@ -0,0 +1,72 @@
1
+ import { IAnyStateTreeNode, Instance, types } from 'mobx-state-tree'
2
+
3
+ import PluginManager from '@jbrowse/core/PluginManager'
4
+ import {
5
+ AnyConfiguration,
6
+ AnyConfigurationModel,
7
+ } from '@jbrowse/core/configuration'
8
+ import { BaseSessionModel, isBaseSession } from './BaseSession'
9
+ import { ReferenceManagementSessionMixin } from './ReferenceManagement'
10
+
11
+ /**
12
+ * #stateModel TracksManagerSessionMixin
13
+ * composed of
14
+ * - BaseSessionModel
15
+ * - ReferenceManagementSessionMixin
16
+ */
17
+ export function TracksManagerSessionMixin(pluginManager: PluginManager) {
18
+ return types
19
+ .compose(
20
+ 'TracksManagerSessionMixin',
21
+ BaseSessionModel(pluginManager),
22
+ ReferenceManagementSessionMixin(pluginManager),
23
+ )
24
+ .views(self => ({
25
+ /**
26
+ * #getter
27
+ */
28
+ get tracks(): AnyConfigurationModel[] {
29
+ return self.jbrowse.tracks
30
+ },
31
+ }))
32
+ .actions(self => ({
33
+ /**
34
+ * #action
35
+ */
36
+ addTrackConf(trackConf: AnyConfiguration) {
37
+ return self.jbrowse.addTrackConf(trackConf)
38
+ },
39
+
40
+ /**
41
+ * #action
42
+ */
43
+ deleteTrackConf(trackConf: AnyConfigurationModel) {
44
+ const callbacksToDereferenceTrack: Function[] = []
45
+ const dereferenceTypeCount: Record<string, number> = {}
46
+ const referring = self.getReferring(trackConf)
47
+ self.removeReferring(
48
+ referring,
49
+ trackConf,
50
+ callbacksToDereferenceTrack,
51
+ dereferenceTypeCount,
52
+ )
53
+ callbacksToDereferenceTrack.forEach(cb => cb())
54
+ if (self.adminMode) {
55
+ return self.jbrowse.deleteTrackConf(trackConf)
56
+ }
57
+ },
58
+ }))
59
+ }
60
+
61
+ /** Session mixin MST type for a session that has tracks */
62
+ export type SessionWithTracksType = ReturnType<typeof TracksManagerSessionMixin>
63
+
64
+ /** Instance of a session that has tracks */
65
+ export type SessionWithTracks = Instance<SessionWithTracksType>
66
+
67
+ /** Type guard for SessionWithTracks */
68
+ export function isSessionWithTracks(
69
+ thing: IAnyStateTreeNode,
70
+ ): thing is SessionWithTracks {
71
+ return isBaseSession(thing) && 'tracks' in thing
72
+ }
@@ -0,0 +1,10 @@
1
+ export * from './ReferenceManagement'
2
+ export * from './Connections'
3
+ export * from './DrawerWidgets'
4
+ export * from './DialogQueue'
5
+ export * from './Themes'
6
+ export * from './Tracks'
7
+ export * from './MultipleViews'
8
+ export * from './BaseSession'
9
+ export * from './SessionTracks'
10
+ export * from './BaseSession'
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './RootModel'
2
+ export * from './Session'
3
+ export * from './ui'
@@ -0,0 +1,31 @@
1
+ import React from 'react'
2
+ import { AnyConfigurationModel } from '@jbrowse/core/configuration'
3
+ import Dialog from '@jbrowse/core/ui/Dialog'
4
+ import { getSession, getEnv } from '@jbrowse/core/util'
5
+ import { getTrackName } from '@jbrowse/core/util/tracks'
6
+ import AboutContents from './AboutDialogContents'
7
+
8
+ export function AboutDialog({
9
+ config,
10
+ handleClose,
11
+ }: {
12
+ config: AnyConfigurationModel
13
+ handleClose: () => void
14
+ }) {
15
+ const session = getSession(config)
16
+ const trackName = getTrackName(config, session)
17
+ const { pluginManager } = getEnv(session)
18
+
19
+ const AboutComponent = pluginManager.evaluateExtensionPoint(
20
+ 'Core-replaceAbout',
21
+ AboutContents,
22
+ { session, config },
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ ) as React.FC<any>
25
+
26
+ return (
27
+ <Dialog open onClose={handleClose} title={trackName} maxWidth="xl">
28
+ <AboutComponent config={config} />
29
+ </Dialog>
30
+ )
31
+ }
@@ -0,0 +1,88 @@
1
+ import React, { useState } from 'react'
2
+ import copy from 'copy-to-clipboard'
3
+ import { Button } from '@mui/material'
4
+ import { makeStyles } from 'tss-react/mui'
5
+ import {
6
+ getConf,
7
+ readConfObject,
8
+ AnyConfigurationModel,
9
+ } from '@jbrowse/core/configuration'
10
+ import { getSession, getEnv } from '@jbrowse/core/util'
11
+ import {
12
+ BaseCard,
13
+ Attributes,
14
+ } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
15
+ import FileInfoPanel from './FileInfoPanel'
16
+
17
+ const useStyles = makeStyles()({
18
+ content: {
19
+ minWidth: 800,
20
+ },
21
+ })
22
+
23
+ export default function AboutContents({
24
+ config,
25
+ }: {
26
+ config: AnyConfigurationModel
27
+ }) {
28
+ const [copied, setCopied] = useState(false)
29
+ const conf = readConfObject(config)
30
+ const session = getSession(config)
31
+ const { classes } = useStyles()
32
+
33
+ const hideUris =
34
+ getConf(session, ['formatAbout', 'hideUris']) ||
35
+ readConfObject(config, ['formatAbout', 'hideUris'])
36
+
37
+ const { pluginManager } = getEnv(session)
38
+
39
+ const confPostExt = pluginManager.evaluateExtensionPoint(
40
+ 'Core-customizeAbout',
41
+ {
42
+ config: {
43
+ ...conf,
44
+ ...getConf(session, ['formatAbout', 'config'], { config: conf }),
45
+ ...readConfObject(config, ['formatAbout', 'config'], { config: conf }),
46
+ },
47
+ },
48
+ { session, config },
49
+ ) as Record<string, unknown>
50
+
51
+ const ExtraPanel = pluginManager.evaluateExtensionPoint(
52
+ 'Core-extraAboutPanel',
53
+ null,
54
+ { session, config },
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ ) as { name: string; Component: React.FC<any> }
57
+
58
+ return (
59
+ <div className={classes.content}>
60
+ <BaseCard title="Configuration">
61
+ {!hideUris ? (
62
+ <Button
63
+ variant="contained"
64
+ style={{ float: 'right' }}
65
+ onClick={() => {
66
+ copy(JSON.stringify(conf, null, 2))
67
+ setCopied(true)
68
+ setTimeout(() => setCopied(false), 1000)
69
+ }}
70
+ >
71
+ {copied ? 'Copied to clipboard!' : 'Copy config'}
72
+ </Button>
73
+ ) : null}
74
+ <Attributes
75
+ attributes={confPostExt}
76
+ omit={['displays', 'baseUri', 'refNames', 'formatAbout']}
77
+ hideUris={hideUris}
78
+ />
79
+ </BaseCard>
80
+ {ExtraPanel ? (
81
+ <BaseCard title={ExtraPanel.name}>
82
+ <ExtraPanel.Component config={config} />
83
+ </BaseCard>
84
+ ) : null}
85
+ <FileInfoPanel config={config} />
86
+ </div>
87
+ )
88
+ }
@@ -0,0 +1,75 @@
1
+ import React, { useState, useEffect } from 'react'
2
+ import { Typography } from '@mui/material'
3
+ import {
4
+ readConfObject,
5
+ AnyConfigurationModel,
6
+ } from '@jbrowse/core/configuration'
7
+ import LoadingEllipses from '@jbrowse/core/ui/LoadingEllipses'
8
+ import { getSession } from '@jbrowse/core/util'
9
+ import {
10
+ BaseCard,
11
+ Attributes,
12
+ } from '@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail'
13
+
14
+ type FileInfo = Record<string, unknown> | string
15
+
16
+ export default function FileInfoPanel({
17
+ config,
18
+ }: {
19
+ config: AnyConfigurationModel
20
+ }) {
21
+ const [error, setError] = useState<unknown>()
22
+ const [info, setInfo] = useState<FileInfo>()
23
+ const session = getSession(config)
24
+ const { rpcManager } = session
25
+
26
+ useEffect(() => {
27
+ const aborter = new AbortController()
28
+ const { signal } = aborter
29
+ let cancelled = false
30
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
31
+ ;(async () => {
32
+ try {
33
+ const adapterConfig = readConfObject(config, 'adapter')
34
+ const result = await rpcManager.call(config.trackId, 'CoreGetInfo', {
35
+ adapterConfig,
36
+ signal,
37
+ })
38
+ if (!cancelled) {
39
+ setInfo(result as FileInfo)
40
+ }
41
+ } catch (e) {
42
+ if (!cancelled) {
43
+ console.error(e)
44
+ setError(e)
45
+ }
46
+ }
47
+ })()
48
+
49
+ return () => {
50
+ aborter.abort()
51
+ cancelled = true
52
+ }
53
+ }, [config, rpcManager])
54
+
55
+ const details =
56
+ typeof info === 'string'
57
+ ? {
58
+ header: `<pre>${info
59
+ .replaceAll('<', '&lt;')
60
+ .replaceAll('>', '&gt;')}</pre>`,
61
+ }
62
+ : info || {}
63
+
64
+ return info !== null ? (
65
+ <BaseCard title="File info">
66
+ {error ? (
67
+ <Typography color="error">{`${error}`}</Typography>
68
+ ) : info === undefined ? (
69
+ <LoadingEllipses message="Loading file data" />
70
+ ) : (
71
+ <Attributes attributes={details} />
72
+ )}
73
+ </BaseCard>
74
+ ) : null
75
+ }
@@ -0,0 +1 @@
1
+ export * from './AboutDialog'