/
createModel.ts
156 lines (152 loc) · 4.42 KB
/
createModel.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import React from 'react'
import assemblyManagerFactory, {
assemblyConfigSchemaFactory,
} from '@jbrowse/core/assemblyManager'
import { PluginConstructor } from '@jbrowse/core/Plugin'
import PluginManager from '@jbrowse/core/PluginManager'
import RpcManager from '@jbrowse/core/rpc/RpcManager'
import TextSearchManager from '@jbrowse/core/TextSearch/TextSearchManager'
import { UriLocation } from '@jbrowse/core/util'
import { cast, getSnapshot, Instance, SnapshotIn, types } from 'mobx-state-tree'
import corePlugins from '../corePlugins'
import createConfigModel from './createConfigModel'
import createSessionModel from './createSessionModel'
import { version } from '../version'
/**
* #stateModel JBrowseReactCircularGenomeViewRootModel
*/
export default function createModel(
runtimePlugins: PluginConstructor[],
makeWorkerInstance: () => Worker = () => {
throw new Error('no makeWorkerInstance supplied')
},
hydrateFn?: (
container: Element | Document,
initialChildren: React.ReactNode,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) => any,
createRootFn?: (elt: Element | DocumentFragment) => {
render: (node: React.ReactElement) => unknown
},
) {
const pluginManager = new PluginManager(
[...corePlugins, ...runtimePlugins].map(P => new P()),
)
pluginManager.createPluggableElements()
const Session = createSessionModel(pluginManager)
const assemblyConfigSchema = assemblyConfigSchemaFactory(pluginManager)
const assemblyManagerType = assemblyManagerFactory(
assemblyConfigSchema,
pluginManager,
)
const rootModel = types
.model('ReactCircularGenomeView', {
/**
* #property
*/
config: createConfigModel(pluginManager, assemblyConfigSchema),
/**
* #property
*/
session: Session,
/**
* #property
*/
assemblyManager: types.optional(assemblyManagerType, {}),
/**
* #property
*/
internetAccounts: types.array(
pluginManager.pluggableMstType('internet account', 'stateModel'),
),
})
.volatile(() => ({
error: undefined as unknown,
adminMode: false,
version,
}))
.actions(self => ({
/**
* #action
*/
setSession(sessionSnapshot: SnapshotIn<typeof Session>) {
self.session = cast(sessionSnapshot)
},
/**
* #action
*/
renameCurrentSession(sessionName: string) {
if (self.session) {
const snapshot = JSON.parse(JSON.stringify(getSnapshot(self.session)))
snapshot.name = sessionName
this.setSession(snapshot)
}
},
/**
* #action
*/
setError(error: unknown) {
self.error = error
},
/**
* #action
*/
addInternetAccount(
internetAccount: SnapshotIn<(typeof self.internetAccounts)[0]>,
) {
self.internetAccounts.push(internetAccount)
},
/**
* #action
*/
findAppropriateInternetAccount(location: UriLocation) {
// find the existing account selected from menu
const selectedId = location.internetAccountId
if (selectedId) {
const selectedAccount = self.internetAccounts.find(account => {
return account.internetAccountId === selectedId
})
if (selectedAccount) {
return selectedAccount
}
}
// if no existing account or not found, try to find working account
for (const account of self.internetAccounts) {
const handleResult = account.handlesLocation(location)
if (handleResult) {
return account
}
}
// no available internet accounts
return null
},
}))
.views(self => ({
/**
* #getter
*/
get jbrowse() {
return self.config
},
/**
* #getter
*/
get pluginManager() {
return pluginManager
},
}))
.volatile(self => ({
rpcManager: new RpcManager(pluginManager, self.config.configuration.rpc, {
WebWorkerRpcDriver: {
makeWorkerInstance,
},
MainThreadRpcDriver: {},
}),
hydrateFn,
createRootFn,
textSearchManager: new TextSearchManager(pluginManager),
}))
return { model: rootModel, pluginManager }
}
export type ViewStateModel = ReturnType<typeof createModel>['model']
export type ViewModel = Instance<ViewStateModel>