@jbrowse/product-core 2.6.1 → 2.6.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.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/rpcWorker.d.ts +6 -0
- package/dist/rpcWorker.js +74 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/rpcWorker.d.ts +6 -0
- package/esm/rpcWorker.js +67 -0
- package/package.json +7 -6
- package/src/RootModel/BaseRootModel.ts +0 -131
- package/src/RootModel/InternetAccounts.ts +0 -126
- package/src/RootModel/index.ts +0 -2
- package/src/Session/BaseSession.ts +0 -129
- package/src/Session/Connections.ts +0 -145
- package/src/Session/DialogQueue.ts +0 -63
- package/src/Session/DrawerWidgets.ts +0 -222
- package/src/Session/MultipleViews.ts +0 -151
- package/src/Session/ReferenceManagement.ts +0 -134
- package/src/Session/SessionTracks.ts +0 -98
- package/src/Session/Themes.ts +0 -85
- package/src/Session/Tracks.ts +0 -72
- package/src/Session/index.ts +0 -10
- package/src/index.ts +0 -3
- package/src/ui/AboutDialog.tsx +0 -31
- package/src/ui/AboutDialogContents.tsx +0 -88
- package/src/ui/FileInfoPanel.tsx +0 -75
- package/src/ui/index.ts +0 -1
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import PluginManager from '@jbrowse/core/PluginManager'
|
|
2
|
-
import {
|
|
3
|
-
AnyConfigurationModel,
|
|
4
|
-
readConfObject,
|
|
5
|
-
} from '@jbrowse/core/configuration'
|
|
6
|
-
import { IAnyStateTreeNode, Instance, types } from 'mobx-state-tree'
|
|
7
|
-
import { BaseConnectionConfigModel } from '@jbrowse/core/pluggableElementTypes/models/baseConnectionConfig'
|
|
8
|
-
import { BaseConnectionModel } from '@jbrowse/core/pluggableElementTypes/models/BaseConnectionModelFactory'
|
|
9
|
-
|
|
10
|
-
// locals
|
|
11
|
-
import type { BaseRootModelType } from '../RootModel/BaseRootModel'
|
|
12
|
-
import type { SessionWithReferenceManagementType } from './ReferenceManagement'
|
|
13
|
-
import { isBaseSession } from './BaseSession'
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* #stateModel ConnectionManagementSessionMixin
|
|
17
|
-
*/
|
|
18
|
-
export function ConnectionManagementSessionMixin(pluginManager: PluginManager) {
|
|
19
|
-
return types
|
|
20
|
-
.model({
|
|
21
|
-
/**
|
|
22
|
-
* #property
|
|
23
|
-
*/
|
|
24
|
-
connectionInstances: types.array(
|
|
25
|
-
pluginManager.pluggableMstType(
|
|
26
|
-
'connection',
|
|
27
|
-
'stateModel',
|
|
28
|
-
) as BaseConnectionModel,
|
|
29
|
-
),
|
|
30
|
-
})
|
|
31
|
-
.views(self => ({
|
|
32
|
-
/**
|
|
33
|
-
* #getter
|
|
34
|
-
*/
|
|
35
|
-
get connections(): BaseConnectionConfigModel[] {
|
|
36
|
-
const { jbrowse } = self as typeof self & Instance<BaseRootModelType>
|
|
37
|
-
return jbrowse.connections
|
|
38
|
-
},
|
|
39
|
-
}))
|
|
40
|
-
.actions(self => ({
|
|
41
|
-
/**
|
|
42
|
-
* #action
|
|
43
|
-
*/
|
|
44
|
-
makeConnection(
|
|
45
|
-
configuration: AnyConfigurationModel,
|
|
46
|
-
initialSnapshot = {},
|
|
47
|
-
) {
|
|
48
|
-
const type = configuration.type as string
|
|
49
|
-
if (!type) {
|
|
50
|
-
throw new Error('track configuration has no `type` listed')
|
|
51
|
-
}
|
|
52
|
-
const name = readConfObject(configuration, 'name')
|
|
53
|
-
const connectionType = pluginManager.getConnectionType(type)
|
|
54
|
-
if (!connectionType) {
|
|
55
|
-
throw new Error(`unknown connection type ${type}`)
|
|
56
|
-
}
|
|
57
|
-
const length = self.connectionInstances.push({
|
|
58
|
-
...initialSnapshot,
|
|
59
|
-
name,
|
|
60
|
-
// @ts-expect-error unsure why ts doesn't like `type` here, but is
|
|
61
|
-
// needed
|
|
62
|
-
type,
|
|
63
|
-
configuration,
|
|
64
|
-
})
|
|
65
|
-
return self.connectionInstances[length - 1]
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* #action
|
|
70
|
-
*/
|
|
71
|
-
prepareToBreakConnection(configuration: AnyConfigurationModel) {
|
|
72
|
-
const root = self as typeof self &
|
|
73
|
-
Instance<SessionWithReferenceManagementType>
|
|
74
|
-
const callbacksToDeref: Function[] = []
|
|
75
|
-
const derefTypeCount: Record<string, number> = {}
|
|
76
|
-
const name = readConfObject(configuration, 'name')
|
|
77
|
-
const connection = self.connectionInstances.find(c => c.name === name)
|
|
78
|
-
if (!connection) {
|
|
79
|
-
return undefined
|
|
80
|
-
}
|
|
81
|
-
for (const track of connection.tracks) {
|
|
82
|
-
const ref = root.getReferring(track)
|
|
83
|
-
root.removeReferring(ref, track, callbacksToDeref, derefTypeCount)
|
|
84
|
-
}
|
|
85
|
-
return [
|
|
86
|
-
() => {
|
|
87
|
-
callbacksToDeref.forEach(cb => cb())
|
|
88
|
-
this.breakConnection(configuration)
|
|
89
|
-
},
|
|
90
|
-
derefTypeCount,
|
|
91
|
-
]
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* #action
|
|
96
|
-
*/
|
|
97
|
-
breakConnection(configuration: AnyConfigurationModel) {
|
|
98
|
-
const name = readConfObject(configuration, 'name')
|
|
99
|
-
const connection = self.connectionInstances.find(c => c.name === name)
|
|
100
|
-
if (!connection) {
|
|
101
|
-
throw new Error(`no connection found with name ${name}`)
|
|
102
|
-
}
|
|
103
|
-
self.connectionInstances.remove(connection)
|
|
104
|
-
},
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* #action
|
|
108
|
-
*/
|
|
109
|
-
deleteConnection(configuration: AnyConfigurationModel) {
|
|
110
|
-
const { jbrowse } = self as typeof self & Instance<BaseRootModelType>
|
|
111
|
-
return jbrowse.deleteConnectionConf(configuration)
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* #action
|
|
116
|
-
*/
|
|
117
|
-
addConnectionConf(connectionConf: BaseConnectionConfigModel) {
|
|
118
|
-
const { jbrowse } = self as typeof self & Instance<BaseRootModelType>
|
|
119
|
-
return jbrowse.addConnectionConf(connectionConf)
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* #action
|
|
124
|
-
*/
|
|
125
|
-
clearConnections() {
|
|
126
|
-
self.connectionInstances.clear()
|
|
127
|
-
},
|
|
128
|
-
}))
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/** Session mixin MST type for a session that has connections */
|
|
132
|
-
export type SessionWithConnectionsType = ReturnType<
|
|
133
|
-
typeof ConnectionManagementSessionMixin
|
|
134
|
-
>
|
|
135
|
-
|
|
136
|
-
/** Instance of a session that has connections: `connectionInstances`,
|
|
137
|
-
* `makeConnection()`, etc. */
|
|
138
|
-
export type SessionWithConnections = Instance<SessionWithConnectionsType>
|
|
139
|
-
|
|
140
|
-
/** Type guard for SessionWithConnections */
|
|
141
|
-
export function isSessionWithConnections(
|
|
142
|
-
session: IAnyStateTreeNode,
|
|
143
|
-
): session is SessionWithConnections {
|
|
144
|
-
return isBaseSession(session) && 'connectionInstances' in session
|
|
145
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/** MST mixin for managing a queue of dialogs at the level of the session */
|
|
2
|
-
|
|
3
|
-
import PluginManager from '@jbrowse/core/PluginManager'
|
|
4
|
-
import { DialogComponentType } from '@jbrowse/core/util'
|
|
5
|
-
import { IAnyStateTreeNode, Instance, types } from 'mobx-state-tree'
|
|
6
|
-
import { isBaseSession } from './BaseSession'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* #stateModel DialogQueueSessionMixin
|
|
10
|
-
*/
|
|
11
|
-
export function DialogQueueSessionMixin(pluginManager: PluginManager) {
|
|
12
|
-
return types
|
|
13
|
-
.model('DialogQueueSessionMixin', {})
|
|
14
|
-
.volatile(() => ({
|
|
15
|
-
queueOfDialogs: [] as [DialogComponentType, unknown][],
|
|
16
|
-
}))
|
|
17
|
-
.views(self => ({
|
|
18
|
-
/**
|
|
19
|
-
* #getter
|
|
20
|
-
*/
|
|
21
|
-
get DialogComponent() {
|
|
22
|
-
return self.queueOfDialogs[0]?.[0]
|
|
23
|
-
},
|
|
24
|
-
/**
|
|
25
|
-
* #getter
|
|
26
|
-
*/
|
|
27
|
-
get DialogProps() {
|
|
28
|
-
return self.queueOfDialogs[0]?.[1]
|
|
29
|
-
},
|
|
30
|
-
}))
|
|
31
|
-
.actions(self => ({
|
|
32
|
-
/**
|
|
33
|
-
* #action
|
|
34
|
-
*/
|
|
35
|
-
removeActiveDialog() {
|
|
36
|
-
self.queueOfDialogs = self.queueOfDialogs.slice(1)
|
|
37
|
-
},
|
|
38
|
-
/**
|
|
39
|
-
* #action
|
|
40
|
-
*/
|
|
41
|
-
queueDialog(
|
|
42
|
-
cb: (doneCallback: () => void) => [DialogComponentType, unknown],
|
|
43
|
-
) {
|
|
44
|
-
const [component, props] = cb(() => {
|
|
45
|
-
this.removeActiveDialog()
|
|
46
|
-
})
|
|
47
|
-
self.queueOfDialogs = [...self.queueOfDialogs, [component, props]]
|
|
48
|
-
},
|
|
49
|
-
}))
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** Session mixin MST type for a session that has `queueOfDialogs`, etc. */
|
|
53
|
-
export type SessionWithDialogsType = ReturnType<typeof DialogQueueSessionMixin>
|
|
54
|
-
|
|
55
|
-
/** Instance of a session that has dialogs */
|
|
56
|
-
export type SessionWithDialogs = Instance<SessionWithDialogsType>
|
|
57
|
-
|
|
58
|
-
/** Type guard for SessionWithDialogs */
|
|
59
|
-
export function isSessionWithDialogs(
|
|
60
|
-
session: IAnyStateTreeNode,
|
|
61
|
-
): session is SessionWithDialogs {
|
|
62
|
-
return isBaseSession(session) && 'queueOfDialogs' in session
|
|
63
|
-
}
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IAnyStateTreeNode,
|
|
3
|
-
Instance,
|
|
4
|
-
addDisposer,
|
|
5
|
-
isAlive,
|
|
6
|
-
types,
|
|
7
|
-
} from 'mobx-state-tree'
|
|
8
|
-
|
|
9
|
-
import PluginManager from '@jbrowse/core/PluginManager'
|
|
10
|
-
import { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util'
|
|
11
|
-
import { autorun } from 'mobx'
|
|
12
|
-
import {
|
|
13
|
-
AnyConfigurationModel,
|
|
14
|
-
isConfigurationModel,
|
|
15
|
-
} from '@jbrowse/core/configuration'
|
|
16
|
-
import { isBaseSession } from './BaseSession'
|
|
17
|
-
|
|
18
|
-
const minDrawerWidth = 128
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* #stateModel DrawerWidgetSessionMixin
|
|
22
|
-
*/
|
|
23
|
-
export function DrawerWidgetSessionMixin(pluginManager: PluginManager) {
|
|
24
|
-
const widgetStateModelType = pluginManager.pluggableMstType(
|
|
25
|
-
'widget',
|
|
26
|
-
'stateModel',
|
|
27
|
-
)
|
|
28
|
-
type WidgetStateModel = Instance<typeof widgetStateModelType>
|
|
29
|
-
return types
|
|
30
|
-
.model({
|
|
31
|
-
/**
|
|
32
|
-
* #property
|
|
33
|
-
*/
|
|
34
|
-
drawerPosition: types.optional(
|
|
35
|
-
types.string,
|
|
36
|
-
() => localStorageGetItem('drawerPosition') || 'right',
|
|
37
|
-
),
|
|
38
|
-
/**
|
|
39
|
-
* #property
|
|
40
|
-
*/
|
|
41
|
-
drawerWidth: types.optional(
|
|
42
|
-
types.refinement(types.integer, width => width >= minDrawerWidth),
|
|
43
|
-
384,
|
|
44
|
-
),
|
|
45
|
-
/**
|
|
46
|
-
* #property
|
|
47
|
-
*/
|
|
48
|
-
widgets: types.map(widgetStateModelType),
|
|
49
|
-
/**
|
|
50
|
-
* #property
|
|
51
|
-
*/
|
|
52
|
-
activeWidgets: types.map(types.safeReference(widgetStateModelType)),
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* #property
|
|
56
|
-
*/
|
|
57
|
-
minimized: types.optional(types.boolean, false),
|
|
58
|
-
})
|
|
59
|
-
.views(self => ({
|
|
60
|
-
/**
|
|
61
|
-
* #getter
|
|
62
|
-
*/
|
|
63
|
-
get visibleWidget() {
|
|
64
|
-
if (isAlive(self)) {
|
|
65
|
-
// returns most recently added item in active widgets
|
|
66
|
-
return [...self.activeWidgets.values()][self.activeWidgets.size - 1]
|
|
67
|
-
}
|
|
68
|
-
return undefined
|
|
69
|
-
},
|
|
70
|
-
}))
|
|
71
|
-
.actions(self => ({
|
|
72
|
-
/**
|
|
73
|
-
* #action
|
|
74
|
-
*/
|
|
75
|
-
setDrawerPosition(arg: string) {
|
|
76
|
-
self.drawerPosition = arg
|
|
77
|
-
localStorage.setItem('drawerPosition', arg)
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* #action
|
|
82
|
-
*/
|
|
83
|
-
updateDrawerWidth(drawerWidth: number) {
|
|
84
|
-
if (drawerWidth === self.drawerWidth) {
|
|
85
|
-
return self.drawerWidth
|
|
86
|
-
}
|
|
87
|
-
let newDrawerWidth = drawerWidth
|
|
88
|
-
if (newDrawerWidth < minDrawerWidth) {
|
|
89
|
-
newDrawerWidth = minDrawerWidth
|
|
90
|
-
}
|
|
91
|
-
self.drawerWidth = newDrawerWidth
|
|
92
|
-
return newDrawerWidth
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* #action
|
|
97
|
-
*/
|
|
98
|
-
resizeDrawer(distance: number) {
|
|
99
|
-
if (self.drawerPosition === 'left') {
|
|
100
|
-
distance *= -1
|
|
101
|
-
}
|
|
102
|
-
const oldDrawerWidth = self.drawerWidth
|
|
103
|
-
const newDrawerWidth = this.updateDrawerWidth(oldDrawerWidth - distance)
|
|
104
|
-
return oldDrawerWidth - newDrawerWidth
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* #action
|
|
109
|
-
*/
|
|
110
|
-
addWidget(
|
|
111
|
-
typeName: string,
|
|
112
|
-
id: string,
|
|
113
|
-
initialState = {},
|
|
114
|
-
conf?: unknown,
|
|
115
|
-
) {
|
|
116
|
-
const typeDefinition = pluginManager.getElementType('widget', typeName)
|
|
117
|
-
if (!typeDefinition) {
|
|
118
|
-
throw new Error(`unknown widget type ${typeName}`)
|
|
119
|
-
}
|
|
120
|
-
const data = {
|
|
121
|
-
...initialState,
|
|
122
|
-
id,
|
|
123
|
-
type: typeName,
|
|
124
|
-
configuration: conf || { type: typeName },
|
|
125
|
-
}
|
|
126
|
-
self.widgets.set(id, data)
|
|
127
|
-
return self.widgets.get(id)
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* #action
|
|
132
|
-
*/
|
|
133
|
-
showWidget(widget: WidgetStateModel) {
|
|
134
|
-
if (self.activeWidgets.has(widget.id)) {
|
|
135
|
-
self.activeWidgets.delete(widget.id)
|
|
136
|
-
}
|
|
137
|
-
self.activeWidgets.set(widget.id, widget)
|
|
138
|
-
self.minimized = false
|
|
139
|
-
},
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* #action
|
|
143
|
-
*/
|
|
144
|
-
hasWidget(widget: WidgetStateModel) {
|
|
145
|
-
return self.activeWidgets.has(widget.id)
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* #action
|
|
150
|
-
*/
|
|
151
|
-
hideWidget(widget: WidgetStateModel) {
|
|
152
|
-
self.activeWidgets.delete(widget.id)
|
|
153
|
-
},
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* #action
|
|
157
|
-
*/
|
|
158
|
-
minimizeWidgetDrawer() {
|
|
159
|
-
self.minimized = true
|
|
160
|
-
},
|
|
161
|
-
/**
|
|
162
|
-
* #action
|
|
163
|
-
*/
|
|
164
|
-
showWidgetDrawer() {
|
|
165
|
-
self.minimized = false
|
|
166
|
-
},
|
|
167
|
-
/**
|
|
168
|
-
* #action
|
|
169
|
-
*/
|
|
170
|
-
hideAllWidgets() {
|
|
171
|
-
self.activeWidgets.clear()
|
|
172
|
-
},
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* #action
|
|
176
|
-
* opens a configuration editor to configure the given thing,
|
|
177
|
-
* and sets the current task to be configuring it
|
|
178
|
-
* @param configuration -
|
|
179
|
-
*/
|
|
180
|
-
editConfiguration(configuration: AnyConfigurationModel) {
|
|
181
|
-
if (!isConfigurationModel(configuration)) {
|
|
182
|
-
throw new Error(
|
|
183
|
-
'must pass a configuration model to editConfiguration',
|
|
184
|
-
)
|
|
185
|
-
}
|
|
186
|
-
const editor = this.addWidget(
|
|
187
|
-
'ConfigurationEditorWidget',
|
|
188
|
-
'configEditor',
|
|
189
|
-
{ target: configuration },
|
|
190
|
-
)
|
|
191
|
-
this.showWidget(editor)
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
afterAttach() {
|
|
195
|
-
addDisposer(
|
|
196
|
-
self,
|
|
197
|
-
autorun(() => {
|
|
198
|
-
localStorageSetItem('drawerPosition', self.drawerPosition)
|
|
199
|
-
}),
|
|
200
|
-
)
|
|
201
|
-
},
|
|
202
|
-
}))
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/** Session mixin MST type for a session that manages drawer widgets */
|
|
206
|
-
export type SessionWithDrawerWidgetsType = ReturnType<
|
|
207
|
-
typeof DrawerWidgetSessionMixin
|
|
208
|
-
>
|
|
209
|
-
|
|
210
|
-
/** Instance of a session that manages drawer widgets */
|
|
211
|
-
export type SessionWithDrawerWidgets = Instance<SessionWithDrawerWidgetsType>
|
|
212
|
-
|
|
213
|
-
/** Type guard for SessionWithDrawerWidgets */
|
|
214
|
-
export function isSessionWithDrawerWidgets(
|
|
215
|
-
session: IAnyStateTreeNode,
|
|
216
|
-
): session is SessionWithDrawerWidgets {
|
|
217
|
-
return (
|
|
218
|
-
isBaseSession(session) &&
|
|
219
|
-
'widgets' in session &&
|
|
220
|
-
'drawerPosition' in session
|
|
221
|
-
)
|
|
222
|
-
}
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IAnyStateTreeNode,
|
|
3
|
-
Instance,
|
|
4
|
-
getSnapshot,
|
|
5
|
-
types,
|
|
6
|
-
} from 'mobx-state-tree'
|
|
7
|
-
|
|
8
|
-
import PluginManager from '@jbrowse/core/PluginManager'
|
|
9
|
-
import { readConfObject } from '@jbrowse/core/configuration'
|
|
10
|
-
import { Region } from '@jbrowse/core/util'
|
|
11
|
-
import { DrawerWidgetSessionMixin } from './DrawerWidgets'
|
|
12
|
-
import { IBaseViewModel } from '@jbrowse/core/pluggableElementTypes'
|
|
13
|
-
import { IBaseViewModelWithDisplayedRegions } from '@jbrowse/core/pluggableElementTypes/models/BaseViewModel'
|
|
14
|
-
|
|
15
|
-
// locals
|
|
16
|
-
import { BaseSessionModel, isBaseSession } from './BaseSession'
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* #stateModel MultipleViewsSessionMixin
|
|
20
|
-
*/
|
|
21
|
-
export function MultipleViewsSessionMixin(pluginManager: PluginManager) {
|
|
22
|
-
return types
|
|
23
|
-
.compose(
|
|
24
|
-
BaseSessionModel(pluginManager),
|
|
25
|
-
DrawerWidgetSessionMixin(pluginManager),
|
|
26
|
-
)
|
|
27
|
-
.props({
|
|
28
|
-
/**
|
|
29
|
-
* #property
|
|
30
|
-
*/
|
|
31
|
-
views: types.array(pluginManager.pluggableMstType('view', 'stateModel')),
|
|
32
|
-
})
|
|
33
|
-
.actions(self => ({
|
|
34
|
-
/**
|
|
35
|
-
* #action
|
|
36
|
-
*/
|
|
37
|
-
moveViewUp(id: string) {
|
|
38
|
-
const idx = self.views.findIndex(v => v.id === id)
|
|
39
|
-
|
|
40
|
-
if (idx === -1) {
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
if (idx > 0) {
|
|
44
|
-
self.views.splice(idx - 1, 2, self.views[idx], self.views[idx - 1])
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
/**
|
|
48
|
-
* #action
|
|
49
|
-
*/
|
|
50
|
-
moveViewDown(id: string) {
|
|
51
|
-
const idx = self.views.findIndex(v => v.id === id)
|
|
52
|
-
|
|
53
|
-
if (idx === -1) {
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (idx < self.views.length - 1) {
|
|
58
|
-
self.views.splice(idx, 2, self.views[idx + 1], self.views[idx])
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* #action
|
|
64
|
-
*/
|
|
65
|
-
addView(typeName: string, initialState = {}) {
|
|
66
|
-
const typeDefinition = pluginManager.getElementType('view', typeName)
|
|
67
|
-
if (!typeDefinition) {
|
|
68
|
-
throw new Error(`unknown view type ${typeName}`)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const length = self.views.push({
|
|
72
|
-
...initialState,
|
|
73
|
-
type: typeName,
|
|
74
|
-
})
|
|
75
|
-
return self.views[length - 1]
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* #action
|
|
80
|
-
*/
|
|
81
|
-
removeView(view: IBaseViewModel) {
|
|
82
|
-
for (const [, widget] of self.activeWidgets) {
|
|
83
|
-
if (widget.view && widget.view.id === view.id) {
|
|
84
|
-
self.hideWidget(widget)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
self.views.remove(view)
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* #action
|
|
92
|
-
*/
|
|
93
|
-
addLinearGenomeViewOfAssembly(assemblyName: string, initialState = {}) {
|
|
94
|
-
return this.addViewOfAssembly(
|
|
95
|
-
'LinearGenomeView',
|
|
96
|
-
assemblyName,
|
|
97
|
-
initialState,
|
|
98
|
-
)
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* #action
|
|
103
|
-
*/
|
|
104
|
-
addViewOfAssembly(
|
|
105
|
-
viewType: string,
|
|
106
|
-
assemblyName: string,
|
|
107
|
-
initialState: Record<string, unknown> = {},
|
|
108
|
-
) {
|
|
109
|
-
const asm = self.assemblies.find(
|
|
110
|
-
s => readConfObject(s, 'name') === assemblyName,
|
|
111
|
-
)
|
|
112
|
-
if (!asm) {
|
|
113
|
-
throw new Error(
|
|
114
|
-
`Could not add view of assembly "${assemblyName}", assembly name not found`,
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
return this.addView(viewType, {
|
|
118
|
-
...initialState,
|
|
119
|
-
displayRegionsFromAssemblyName: readConfObject(asm, 'name'),
|
|
120
|
-
})
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* #action
|
|
125
|
-
*/
|
|
126
|
-
addViewFromAnotherView(
|
|
127
|
-
viewType: string,
|
|
128
|
-
otherView: IBaseViewModelWithDisplayedRegions,
|
|
129
|
-
initialState: { displayedRegions?: Region[] } = {},
|
|
130
|
-
) {
|
|
131
|
-
const state = { ...initialState }
|
|
132
|
-
state.displayedRegions = getSnapshot(otherView.displayedRegions)
|
|
133
|
-
return this.addView(viewType, state)
|
|
134
|
-
},
|
|
135
|
-
}))
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** Session mixin MST type for a session that manages multiple views */
|
|
139
|
-
export type SessionWithMultipleViewsType = ReturnType<
|
|
140
|
-
typeof MultipleViewsSessionMixin
|
|
141
|
-
>
|
|
142
|
-
|
|
143
|
-
/** Instance of a session with multiple views */
|
|
144
|
-
export type SessionWithMultipleViews = Instance<SessionWithMultipleViewsType>
|
|
145
|
-
|
|
146
|
-
/** Type guard for SessionWithMultipleViews */
|
|
147
|
-
export function isSessionWithMultipleViews(
|
|
148
|
-
session: IAnyStateTreeNode,
|
|
149
|
-
): session is SessionWithMultipleViews {
|
|
150
|
-
return isBaseSession(session) && 'views' in session
|
|
151
|
-
}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/** MST props, views, actions, etc related to managing connections */
|
|
2
|
-
|
|
3
|
-
import PluginManager from '@jbrowse/core/PluginManager'
|
|
4
|
-
import {
|
|
5
|
-
TrackViewModel,
|
|
6
|
-
getContainingView,
|
|
7
|
-
isSessionModelWithWidgets,
|
|
8
|
-
} from '@jbrowse/core/util'
|
|
9
|
-
import {
|
|
10
|
-
IAnyStateTreeNode,
|
|
11
|
-
Instance,
|
|
12
|
-
getMembers,
|
|
13
|
-
getParent,
|
|
14
|
-
getSnapshot,
|
|
15
|
-
getType,
|
|
16
|
-
isModelType,
|
|
17
|
-
isReferenceType,
|
|
18
|
-
types,
|
|
19
|
-
walk,
|
|
20
|
-
} from 'mobx-state-tree'
|
|
21
|
-
|
|
22
|
-
import type { BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes'
|
|
23
|
-
// locals
|
|
24
|
-
import { isBaseSession } from './BaseSession'
|
|
25
|
-
|
|
26
|
-
export interface ReferringNode {
|
|
27
|
-
node: IAnyStateTreeNode
|
|
28
|
-
key: string
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* #stateModel ReferenceManagementSessionMixin
|
|
33
|
-
*/
|
|
34
|
-
export function ReferenceManagementSessionMixin(pluginManager: PluginManager) {
|
|
35
|
-
return types
|
|
36
|
-
.model('ReferenceManagementSessionMixin', {})
|
|
37
|
-
.views(self => ({
|
|
38
|
-
/**
|
|
39
|
-
* #method
|
|
40
|
-
* See if any MST nodes currently have a types.reference to this object.
|
|
41
|
-
*
|
|
42
|
-
* @param object - object
|
|
43
|
-
* @returns An array where the first element is the node referring
|
|
44
|
-
* to the object and the second element is they property name the node is
|
|
45
|
-
* using to refer to the object
|
|
46
|
-
*/
|
|
47
|
-
getReferring(object: IAnyStateTreeNode) {
|
|
48
|
-
const refs: ReferringNode[] = []
|
|
49
|
-
walk(getParent(self), node => {
|
|
50
|
-
if (isModelType(getType(node))) {
|
|
51
|
-
const members = getMembers(node)
|
|
52
|
-
Object.entries(members.properties).forEach(([key, value]) => {
|
|
53
|
-
if (isReferenceType(value) && node[key] === object) {
|
|
54
|
-
refs.push({ node, key })
|
|
55
|
-
}
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
return refs
|
|
60
|
-
},
|
|
61
|
-
}))
|
|
62
|
-
.actions(self => ({
|
|
63
|
-
/**
|
|
64
|
-
* #action
|
|
65
|
-
*/
|
|
66
|
-
removeReferring(
|
|
67
|
-
referring: ReferringNode[],
|
|
68
|
-
track: BaseTrackConfig,
|
|
69
|
-
callbacks: Function[],
|
|
70
|
-
dereferenceTypeCount: Record<string, number>,
|
|
71
|
-
) {
|
|
72
|
-
referring.forEach(({ node }) => {
|
|
73
|
-
let dereferenced = false
|
|
74
|
-
try {
|
|
75
|
-
// If a view is referring to the track config, remove the track
|
|
76
|
-
// from the view
|
|
77
|
-
const type = 'open track(s)'
|
|
78
|
-
const view = getContainingView(node) as TrackViewModel
|
|
79
|
-
callbacks.push(() => view.hideTrack(track.trackId))
|
|
80
|
-
dereferenced = true
|
|
81
|
-
if (!dereferenceTypeCount[type]) {
|
|
82
|
-
dereferenceTypeCount[type] = 0
|
|
83
|
-
}
|
|
84
|
-
dereferenceTypeCount[type] += 1
|
|
85
|
-
} catch (err1) {
|
|
86
|
-
// ignore
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (isSessionModelWithWidgets(self) && self.widgets.has(node.id)) {
|
|
90
|
-
// If a configuration editor widget has the track config
|
|
91
|
-
// open, close the widget
|
|
92
|
-
const type = 'configuration editor widget(s)'
|
|
93
|
-
if (isSessionModelWithWidgets(self)) {
|
|
94
|
-
callbacks.push(() => self.hideWidget(node))
|
|
95
|
-
}
|
|
96
|
-
dereferenced = true
|
|
97
|
-
if (!dereferenceTypeCount[type]) {
|
|
98
|
-
dereferenceTypeCount[type] = 0
|
|
99
|
-
}
|
|
100
|
-
dereferenceTypeCount[type] += 1
|
|
101
|
-
}
|
|
102
|
-
if (!dereferenced) {
|
|
103
|
-
throw new Error(
|
|
104
|
-
`Error when closing this connection, the following node is still referring to a track configuration: ${JSON.stringify(
|
|
105
|
-
getSnapshot(node),
|
|
106
|
-
)}`,
|
|
107
|
-
)
|
|
108
|
-
}
|
|
109
|
-
})
|
|
110
|
-
},
|
|
111
|
-
}))
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** Session mixin MST type for a session that manages multiple views */
|
|
115
|
-
export type SessionWithReferenceManagementType = ReturnType<
|
|
116
|
-
typeof ReferenceManagementSessionMixin
|
|
117
|
-
>
|
|
118
|
-
|
|
119
|
-
/** Instance of a session with MST reference management (`getReferring()`, `removeReferring()`) */
|
|
120
|
-
export type SessionWithReferenceManagement =
|
|
121
|
-
Instance<SessionWithReferenceManagementType>
|
|
122
|
-
|
|
123
|
-
/** Type guard for SessionWithReferenceManagement */
|
|
124
|
-
export function isSessionWithReferenceManagement(
|
|
125
|
-
thing: IAnyStateTreeNode,
|
|
126
|
-
): thing is SessionWithReferenceManagement {
|
|
127
|
-
return (
|
|
128
|
-
isBaseSession(thing) &&
|
|
129
|
-
'getReferring' in thing &&
|
|
130
|
-
typeof thing.getReferring === 'function' &&
|
|
131
|
-
'removeReferring' in thing &&
|
|
132
|
-
typeof thing.removeReferring === 'function'
|
|
133
|
-
)
|
|
134
|
-
}
|