@jbrowse/web-core 2.17.0 → 2.18.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.
@@ -1,167 +1,72 @@
1
1
  import { lazy } from 'react';
2
- import clone from 'clone';
3
- import { getConf, readConfObject, } from '@jbrowse/core/configuration';
4
- import { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util';
5
- import { autorun } from 'mobx';
6
- import { addDisposer, cast, getParent, getSnapshot, types, } from 'mobx-state-tree';
7
- import { DialogQueueSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, } from '@jbrowse/product-core';
8
2
  import { AppFocusMixin, SessionAssembliesMixin, TemporaryAssembliesMixin, } from '@jbrowse/app-core';
3
+ import { getConf, readConfObject } from '@jbrowse/core/configuration';
9
4
  import SnackbarModel from '@jbrowse/core/ui/SnackbarModel';
10
- // icons
11
- import SettingsIcon from '@mui/icons-material/Settings';
12
- import CopyIcon from '@mui/icons-material/FileCopy';
5
+ import { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util';
6
+ import { DialogQueueSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, } from '@jbrowse/product-core';
13
7
  import DeleteIcon from '@mui/icons-material/Delete';
8
+ import CopyIcon from '@mui/icons-material/FileCopy';
14
9
  import InfoIcon from '@mui/icons-material/Info';
15
- // locals
10
+ import SettingsIcon from '@mui/icons-material/Settings';
11
+ import { autorun } from 'mobx';
12
+ import { addDisposer, cast, getParent, getSnapshot, types, } from 'mobx-state-tree';
16
13
  import { WebSessionConnectionsMixin } from '../SessionConnections';
17
- // lazies
18
14
  const AboutDialog = lazy(() => import('./AboutDialog'));
19
- /**
20
- * #stateModel BaseWebSession
21
- * used for "web based" products, including jbrowse-web and react-app
22
- * composed of
23
- * - [ReferenceManagementSessionMixin](../referencemanagementsessionmixin)
24
- * - [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin)
25
- * - [DialogQueueSessionMixin](../dialogqueuesessionmixin)
26
- * - [ThemeManagerSessionMixin](../thememanagersessionmixin)
27
- * - [MultipleViewsSessionMixin](../multipleviewssessionmixin)
28
- * - [SessionTracksManagerSessionMixin](../sessiontracksmanagersessionmixin)
29
- * - [SessionAssembliesMixin](../sessionassembliesmixin)
30
- * - [TemporaryAssembliesMixin](../temporaryassembliesmixin)
31
- * - [WebSessionConnectionsMixin](../websessionconnectionsmixin)
32
- * - [AppFocusMixin](../appfocusmixin)
33
- */
34
15
  export function BaseWebSession({ pluginManager, assemblyConfigSchema, }) {
35
16
  const sessionModel = types
36
17
  .compose('WebCoreSessionModel', types.compose('WebCoreSessionModelGroupA', ReferenceManagementSessionMixin(pluginManager), DrawerWidgetSessionMixin(pluginManager), DialogQueueSessionMixin(pluginManager), ThemeManagerSessionMixin(pluginManager), MultipleViewsSessionMixin(pluginManager)), types.compose('WebCoreSessionModelGroupB', SessionTracksManagerSessionMixin(pluginManager), SessionAssembliesMixin(pluginManager, assemblyConfigSchema), TemporaryAssembliesMixin(pluginManager, assemblyConfigSchema), WebSessionConnectionsMixin(pluginManager), AppFocusMixin(), SnackbarModel()))
37
18
  .props({
38
- /**
39
- * #property
40
- */
41
19
  margin: 0,
42
- /**
43
- * #property
44
- */
45
20
  sessionPlugins: types.array(types.frozen()),
46
21
  })
47
- .volatile(( /* self */) => ({
48
- /**
49
- * #volatile
50
- */
22
+ .volatile(() => ({
51
23
  sessionThemeName: localStorageGetItem('themeName') || 'default',
52
- /**
53
- * #volatile
54
- * this is the current "task" that is being performed in the UI.
55
- * this is usually an object of the form
56
- * `{ taskName: "configure", target: thing_being_configured }`
57
- */
58
24
  task: undefined,
59
25
  }))
60
26
  .views(self => ({
61
- /**
62
- * #getter
63
- */
64
27
  get tracks() {
65
28
  return [...self.sessionTracks, ...self.jbrowse.tracks];
66
29
  },
67
- /**
68
- * #getter
69
- */
70
30
  get root() {
71
31
  return getParent(self);
72
32
  },
73
- /**
74
- * #getter
75
- * list of sessionAssemblies and jbrowse config assemblies, does not
76
- * include temporaryAssemblies. basically the list to be displayed in a
77
- * AssemblySelector dropdown
78
- */
79
33
  get assemblies() {
80
34
  return [...self.jbrowse.assemblies, ...self.sessionAssemblies];
81
35
  },
82
- /**
83
- * #getter
84
- * list of config connections and session connections
85
- */
86
36
  get connections() {
87
37
  return [...self.jbrowse.connections, ...self.sessionConnections];
88
38
  },
89
39
  }))
90
40
  .actions(self => ({
91
- /**
92
- * #action
93
- */
94
41
  setName(str) {
95
42
  self.name = str;
96
43
  },
97
44
  }))
98
45
  .views(self => ({
99
- /**
100
- * #getter
101
- * list of sessionAssemblies and jbrowse config assemblies, does not
102
- * include temporaryAssemblies. basically the list to be displayed in a
103
- * AssemblySelector dropdown
104
- */
105
46
  get assemblyNames() {
106
47
  return self.assemblies.map(f => readConfObject(f, 'name'));
107
48
  },
108
- /**
109
- * #getter
110
- */
111
49
  get version() {
112
50
  return self.root.version;
113
51
  },
114
- /**
115
- * #getter
116
- */
117
52
  get shareURL() {
118
53
  return getConf(self.jbrowse, 'shareURL');
119
54
  },
120
- /**
121
- * #getter
122
- */
123
55
  get textSearchManager() {
124
56
  return self.root.textSearchManager;
125
57
  },
126
- /**
127
- * #getter
128
- */
129
58
  get assemblyManager() {
130
59
  return self.root.assemblyManager;
131
60
  },
132
- /**
133
- * #getter
134
- */
135
- get savedSessions() {
136
- return self.root.savedSessions;
61
+ get savedSessionMetadata() {
62
+ return self.root.savedSessionMetadata;
137
63
  },
138
- /**
139
- * #getter
140
- */
141
64
  get previousAutosaveId() {
142
65
  return self.root.previousAutosaveId;
143
66
  },
144
- /**
145
- * #getter
146
- */
147
- get savedSessionNames() {
148
- return self.root.savedSessionNames;
149
- },
150
- /**
151
- * #getter
152
- */
153
67
  get history() {
154
68
  return self.root.history;
155
69
  },
156
- /**
157
- * #getter
158
- */
159
- get menus() {
160
- return self.root.menus;
161
- },
162
- /**
163
- * #method
164
- */
165
70
  renderProps() {
166
71
  return {
167
72
  theme: self.theme,
@@ -170,15 +75,9 @@ export function BaseWebSession({ pluginManager, assemblyConfigSchema, }) {
170
75
  },
171
76
  }))
172
77
  .actions(self => ({
173
- /**
174
- * #action
175
- */
176
78
  addAssemblyConf(conf) {
177
79
  self.jbrowse.addAssemblyConf(conf);
178
80
  },
179
- /**
180
- * #action
181
- */
182
81
  addSessionPlugin(plugin) {
183
82
  if (self.sessionPlugins.some(p => p.name === plugin.name)) {
184
83
  throw new Error('session plugin cannot be installed twice');
@@ -186,80 +85,48 @@ export function BaseWebSession({ pluginManager, assemblyConfigSchema, }) {
186
85
  self.sessionPlugins.push(plugin);
187
86
  self.root.setPluginsUpdated(true);
188
87
  },
189
- /**
190
- * #action
191
- */
192
88
  removeSessionPlugin(pluginDefinition) {
193
- self.sessionPlugins = cast(self.sessionPlugins.filter(plugin =>
194
- // @ts-expect-error
195
- plugin.url !== pluginDefinition.url ||
196
- // @ts-expect-error
89
+ self.sessionPlugins = cast(self.sessionPlugins.filter(plugin => plugin.url !== pluginDefinition.url ||
197
90
  plugin.umdUrl !== pluginDefinition.umdUrl ||
198
- // @ts-expect-error
199
91
  plugin.cjsUrl !== pluginDefinition.cjsUrl ||
200
- // @ts-expect-error
201
92
  plugin.esmUrl !== pluginDefinition.esmUrl));
202
93
  getParent(self).setPluginsUpdated(true);
203
94
  },
204
- /**
205
- * #action
206
- */
207
95
  addSavedSession(sessionSnapshot) {
208
96
  return self.root.addSavedSession(sessionSnapshot);
209
97
  },
210
- /**
211
- * #action
212
- */
213
- removeSavedSession(sessionSnapshot) {
214
- return self.root.removeSavedSession(sessionSnapshot);
98
+ deleteSavedSession(id) {
99
+ return self.root.deleteSavedSession(id);
100
+ },
101
+ favoriteSavedSession(id) {
102
+ return self.root.favoriteSavedSession(id);
103
+ },
104
+ unfavoriteSavedSession(id) {
105
+ return self.root.unfavoriteSavedSession(id);
215
106
  },
216
- /**
217
- * #action
218
- */
219
107
  renameCurrentSession(sessionName) {
220
108
  return self.root.renameCurrentSession(sessionName);
221
109
  },
222
- /**
223
- * #action
224
- */
225
110
  duplicateCurrentSession() {
226
111
  return self.root.duplicateCurrentSession();
227
112
  },
228
- /**
229
- * #action
230
- */
231
113
  activateSession(sessionName) {
232
114
  return self.root.activateSession(sessionName);
233
115
  },
234
- /**
235
- * #action
236
- */
237
116
  setDefaultSession() {
238
117
  return self.root.setDefaultSession();
239
118
  },
240
- /**
241
- * #action
242
- */
243
119
  saveSessionToLocalStorage() {
244
120
  return self.root.saveSessionToLocalStorage();
245
121
  },
246
- /**
247
- * #action
248
- */
249
122
  loadAutosaveSession() {
250
123
  return self.root.loadAutosaveSession();
251
124
  },
252
- /**
253
- * #action
254
- */
255
125
  setSession(sessionSnapshot) {
256
126
  return self.root.setSession(sessionSnapshot);
257
127
  },
258
128
  }))
259
129
  .actions(self => ({
260
- /**
261
- * #action
262
- */
263
130
  editTrackConfiguration(configuration) {
264
131
  const { adminMode, sessionTracks } = self;
265
132
  if (!adminMode && !sessionTracks.includes(configuration)) {
@@ -269,13 +136,9 @@ export function BaseWebSession({ pluginManager, assemblyConfigSchema, }) {
269
136
  },
270
137
  }))
271
138
  .views(self => ({
272
- /**
273
- * #method
274
- */
275
139
  getTrackActionMenuItems(config) {
276
140
  const { adminMode, sessionTracks } = self;
277
141
  const canEdit = adminMode || sessionTracks.find(t => t.trackId === config.trackId);
278
- // disable if it is a reference sequence track
279
142
  const isRefSeq = config.type === 'ReferenceSequenceTrack';
280
143
  return [
281
144
  {
@@ -284,7 +147,10 @@ export function BaseWebSession({ pluginManager, assemblyConfigSchema, }) {
284
147
  onClick: () => {
285
148
  self.queueDialog(handleClose => [
286
149
  AboutDialog,
287
- { config, handleClose },
150
+ {
151
+ config,
152
+ handleClose,
153
+ },
288
154
  ]);
289
155
  },
290
156
  icon: InfoIcon,
@@ -293,32 +159,31 @@ export function BaseWebSession({ pluginManager, assemblyConfigSchema, }) {
293
159
  label: 'Settings',
294
160
  priority: 1001,
295
161
  disabled: !canEdit,
162
+ icon: SettingsIcon,
296
163
  onClick: () => {
297
164
  self.editTrackConfiguration(config);
298
165
  },
299
- icon: SettingsIcon,
300
166
  },
301
167
  {
302
168
  label: 'Delete track',
303
169
  priority: 1000,
304
170
  disabled: !canEdit || isRefSeq,
305
- onClick: () => self.deleteTrackConf(config),
306
171
  icon: DeleteIcon,
172
+ onClick: () => {
173
+ self.deleteTrackConf(config);
174
+ },
307
175
  },
308
176
  {
309
177
  label: 'Copy track',
310
178
  priority: 999,
311
179
  disabled: isRefSeq,
312
180
  onClick: () => {
313
- const snap = clone(getSnapshot(config));
181
+ const snap = structuredClone(getSnapshot(config));
314
182
  const now = Date.now();
315
183
  snap.trackId += `-${now}`;
316
184
  snap.displays.forEach(display => {
317
185
  display.displayId += `-${now}`;
318
186
  });
319
- // the -sessionTrack suffix to trackId is used as metadata for
320
- // the track selector to store the track in a special category,
321
- // and default category is also cleared
322
187
  if (!self.adminMode) {
323
188
  snap.trackId += '-sessionTrack';
324
189
  snap.category = undefined;
@@ -330,6 +195,9 @@ export function BaseWebSession({ pluginManager, assemblyConfigSchema, }) {
330
195
  },
331
196
  ];
332
197
  },
198
+ menus() {
199
+ return self.root.menus();
200
+ },
333
201
  }))
334
202
  .actions(self => ({
335
203
  afterAttach() {
@@ -341,14 +209,8 @@ export function BaseWebSession({ pluginManager, assemblyConfigSchema, }) {
341
209
  }));
342
210
  const extendedSessionModel = pluginManager.evaluateExtensionPoint('Core-extendSession', sessionModel);
343
211
  return types.snapshotProcessor(extendedSessionModel, {
344
- // @ts-expect-error
345
212
  preProcessor(snapshot) {
346
- // @ts-expect-error
347
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
348
213
  const { connectionInstances, ...rest } = snapshot || {};
349
- // connectionInstances schema changed from object to an array, so any
350
- // old connectionInstances as object is in snapshot, filter it out
351
- // https://github.com/GMOD/jbrowse-components/issues/1903
352
214
  return !Array.isArray(connectionInstances) ? rest : snapshot;
353
215
  },
354
216
  });
@@ -1,10 +1,6 @@
1
- import PluginManager from '@jbrowse/core/PluginManager';
2
- import { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
- import { BaseConnectionConfigModel } from '@jbrowse/core/pluggableElementTypes/models/baseConnectionConfig';
4
- /**
5
- * #stateModel WebSessionConnectionsMixin
6
- * #category session
7
- */
1
+ import type PluginManager from '@jbrowse/core/PluginManager';
2
+ import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
+ import type { BaseConnectionConfigModel } from '@jbrowse/core/pluggableElementTypes/models/baseConnectionConfig';
8
4
  export declare function WebSessionConnectionsMixin(pluginManager: PluginManager): import("mobx-state-tree").IModelType<{
9
5
  connectionInstances: import("mobx-state-tree").IArrayType<import("mobx-state-tree").IModelType<{
10
6
  name: import("mobx-state-tree").ISimpleType<string>;
@@ -51,9 +47,6 @@ export declare function WebSessionConnectionsMixin(pluginManager: PluginManager)
51
47
  clear(): void;
52
48
  }, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
53
49
  } & {
54
- /**
55
- * #property
56
- */
57
50
  sessionConnections: import("mobx-state-tree").IArrayType<import("mobx-state-tree").IAnyModelType>;
58
51
  }, {
59
52
  readonly connections: ({
@@ -1,15 +1,8 @@
1
+ import { ConnectionManagementSessionMixin } from '@jbrowse/product-core';
1
2
  import { types } from 'mobx-state-tree';
2
- import { ConnectionManagementSessionMixin, } from '@jbrowse/product-core';
3
- /**
4
- * #stateModel WebSessionConnectionsMixin
5
- * #category session
6
- */
7
3
  export function WebSessionConnectionsMixin(pluginManager) {
8
4
  return types
9
5
  .compose('SessionConnectionsManagement', ConnectionManagementSessionMixin(pluginManager), types.model({
10
- /**
11
- * #property
12
- */
13
6
  sessionConnections: types.array(pluginManager.pluggableConfigSchemaType('connection')),
14
7
  }))
15
8
  .actions(s => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/web-core",
3
- "version": "2.17.0",
3
+ "version": "2.18.0",
4
4
  "description": "JBrowse 2 code shared between web-app type products",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -42,11 +42,10 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@babel/runtime": "^7.16.3",
45
- "@jbrowse/app-core": "^2.17.0",
46
- "@jbrowse/product-core": "^2.17.0",
45
+ "@jbrowse/app-core": "^2.18.0",
46
+ "@jbrowse/product-core": "^2.18.0",
47
47
  "@mui/icons-material": "^6.0.0",
48
48
  "@mui/material": "^6.0.0",
49
- "clone": "^2.0.0",
50
49
  "copy-to-clipboard": "^3.3.1"
51
50
  },
52
51
  "peerDependencies": {
@@ -61,5 +60,5 @@
61
60
  "publishConfig": {
62
61
  "access": "public"
63
62
  },
64
- "gitHead": "eed30b5e671f8f7823652d7cecc51aa89226de46"
63
+ "gitHead": "c344ea60099cb7e460b77f15808946b24a7eee74"
65
64
  }