@jbrowse/product-core 4.3.0 → 5.0.0-beta.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/esm/RootModel/BaseRootModel.d.ts +629 -304
- package/esm/RootModel/BaseRootModel.js +139 -14
- package/esm/RootModel/HierarchicalConfig.d.ts +57 -21
- package/esm/RootModel/HierarchicalConfig.js +36 -0
- package/esm/RootModel/InternetAccounts.d.ts +18 -1
- package/esm/RootModel/InternetAccounts.js +120 -22
- package/esm/RootModel/PreferencesConfig.d.ts +68 -0
- package/esm/RootModel/PreferencesConfig.js +76 -0
- package/esm/RootModel/createConfigModel.d.ts +240 -0
- package/esm/RootModel/createConfigModel.js +56 -0
- package/esm/RootModel/index.d.ts +10 -5
- package/esm/RootModel/index.js +10 -5
- package/esm/RootModel/menuItems.d.ts +24 -0
- package/esm/RootModel/menuItems.js +143 -0
- package/esm/Session/BaseSession.d.ts +312 -11
- package/esm/Session/BaseSession.js +458 -14
- package/esm/Session/Connections.d.ts +114 -8
- package/esm/Session/Connections.js +195 -74
- package/esm/Session/DrawerWidgets.d.ts +115 -12
- package/esm/Session/DrawerWidgets.js +161 -42
- package/esm/Session/MultipleViews.d.ts +1281 -1128
- package/esm/Session/MultipleViews.js +396 -64
- package/esm/Session/Preferences.d.ts +1667 -0
- package/esm/Session/Preferences.js +59 -0
- package/esm/Session/ReferenceManagement.d.ts +28 -3
- package/esm/Session/ReferenceManagement.js +56 -41
- package/esm/Session/SessionTracks.d.ts +1277 -1138
- package/esm/Session/SessionTracks.js +540 -35
- package/esm/Session/Themes.d.ts +87 -2
- package/esm/Session/Themes.js +156 -23
- package/esm/Session/TrackMenu.d.ts +112 -0
- package/esm/Session/TrackMenu.js +200 -0
- package/esm/Session/TrackMenuSessionMixin.d.ts +27 -0
- package/esm/Session/TrackMenuSessionMixin.js +41 -0
- package/esm/Session/Tracks.d.ts +1171 -1117
- package/esm/Session/Tracks.js +183 -20
- package/esm/Session/assertSessionModel.d.ts +21 -0
- package/esm/Session/assertSessionModel.js +1 -0
- package/esm/Session/developerMode.d.ts +7 -0
- package/esm/Session/developerMode.js +43 -0
- package/esm/Session/finalizeSession.d.ts +16 -0
- package/esm/Session/finalizeSession.js +29 -0
- package/esm/Session/index.d.ts +22 -10
- package/esm/Session/index.js +13 -10
- package/esm/Session/readdedTrackConf.d.ts +8 -0
- package/esm/Session/readdedTrackConf.js +25 -0
- package/esm/Session/shareableSnapshot.d.ts +77 -0
- package/esm/Session/shareableSnapshot.js +196 -0
- package/esm/Session/temporaryAssemblyTracks.d.ts +24 -0
- package/esm/Session/temporaryAssemblyTracks.js +37 -0
- package/esm/assertExtends.d.ts +55 -0
- package/esm/assertExtends.js +1 -0
- package/esm/controllerTracks.d.ts +56 -0
- package/esm/controllerTracks.js +90 -0
- package/esm/destroyViewState.d.ts +21 -0
- package/esm/destroyViewState.js +29 -0
- package/esm/index.d.ts +31 -4
- package/esm/index.js +31 -4
- package/esm/loadPlugins.d.ts +33 -0
- package/esm/loadPlugins.js +41 -0
- package/esm/localFiles.d.ts +74 -0
- package/esm/localFiles.js +156 -0
- package/esm/observeSession.d.ts +56 -0
- package/esm/observeSession.js +91 -0
- package/esm/pluginInput.d.ts +32 -0
- package/esm/pluginInput.js +19 -0
- package/esm/pruneUnbuildableNodes.d.ts +109 -0
- package/esm/pruneUnbuildableNodes.js +568 -0
- package/esm/resolveAssemblies.d.ts +44 -0
- package/esm/resolveAssemblies.js +55 -0
- package/esm/rpcWorker.d.ts +26 -0
- package/esm/rpcWorker.js +98 -16
- package/esm/scheduleDetachedDestroy.d.ts +18 -0
- package/esm/scheduleDetachedDestroy.js +24 -0
- package/esm/sessionMigrations/index.d.ts +53 -0
- package/esm/sessionMigrations/index.js +432 -0
- package/esm/sessionUrl.d.ts +41 -0
- package/esm/sessionUrl.js +53 -0
- package/esm/sessionUtils.d.ts +69 -0
- package/esm/sessionUtils.js +613 -0
- package/esm/siblingCast.d.ts +14 -0
- package/esm/siblingCast.js +16 -0
- package/esm/snapshotUtils.d.ts +8 -0
- package/esm/snapshotUtils.js +12 -0
- package/esm/ui/AboutDialog.d.ts +3 -6
- package/esm/ui/AboutDialog.js +4 -4
- package/esm/ui/AboutDialogContents.d.ts +2 -6
- package/esm/ui/AboutDialogContents.js +34 -13
- package/esm/ui/AssemblyInfoPanel.d.ts +5 -0
- package/esm/ui/AssemblyInfoPanel.js +69 -0
- package/esm/ui/DisplayDefaultsSection.d.ts +36 -0
- package/esm/ui/DisplayDefaultsSection.js +65 -0
- package/esm/ui/Drawer.d.ts +21 -0
- package/esm/ui/Drawer.js +60 -0
- package/esm/ui/DrawerControls.d.ts +5 -0
- package/esm/ui/DrawerControls.js +28 -0
- package/esm/ui/DrawerHeader.d.ts +6 -0
- package/esm/ui/DrawerHeader.js +36 -0
- package/esm/ui/DrawerWidget.d.ts +5 -0
- package/esm/ui/DrawerWidget.js +12 -0
- package/esm/ui/DrawerWidgetSelector.d.ts +5 -0
- package/esm/ui/DrawerWidgetSelector.js +40 -0
- package/esm/ui/FileInfoPanel.d.ts +3 -6
- package/esm/ui/FileInfoPanel.js +35 -26
- package/esm/ui/HeaderButtons.d.ts +7 -1
- package/esm/ui/HeaderButtons.js +23 -18
- package/esm/ui/ModalWidget.d.ts +12 -0
- package/esm/ui/ModalWidget.js +33 -0
- package/esm/ui/ModalWidgetAppBar.d.ts +8 -0
- package/esm/ui/ModalWidgetAppBar.js +9 -0
- package/esm/ui/PreferencesDialog.d.ts +56 -0
- package/esm/ui/PreferencesDialog.js +145 -0
- package/esm/ui/PreferencesResetDialog.d.ts +8 -0
- package/esm/ui/PreferencesResetDialog.js +19 -0
- package/esm/ui/RefNameAliasesDialog.d.ts +9 -0
- package/esm/ui/RefNameAliasesDialog.js +65 -0
- package/esm/ui/RefNameInfoDialog.d.ts +3 -6
- package/esm/ui/RefNameInfoDialog.js +57 -63
- package/esm/ui/WidgetBody.d.ts +18 -0
- package/esm/ui/WidgetBody.js +22 -0
- package/esm/ui/WidgetHeading.d.ts +7 -0
- package/esm/ui/WidgetHeading.js +7 -0
- package/esm/ui/drawerLayout.d.ts +18 -0
- package/esm/ui/drawerLayout.js +22 -0
- package/esm/ui/index.d.ts +13 -1
- package/esm/ui/index.js +12 -1
- package/esm/ui/util.d.ts +37 -4
- package/esm/ui/util.js +35 -38
- package/esm/useEngineLifecycle.d.ts +19 -0
- package/esm/useEngineLifecycle.js +44 -0
- package/package.json +12 -15
- package/esm/RootModel/FormatAbout.d.ts +0 -12
- package/esm/RootModel/FormatAbout.js +0 -15
- package/esm/RootModel/FormatDetails.d.ts +0 -24
- package/esm/RootModel/FormatDetails.js +0 -27
- package/esm/Session/DialogQueue.d.ts +0 -17
- package/esm/Session/DialogQueue.js +0 -31
|
@@ -2,64 +2,147 @@ import { isConfigurationModel } from '@jbrowse/core/configuration';
|
|
|
2
2
|
import { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util';
|
|
3
3
|
import { addDisposer, getEnv, isAlive, isStateTreeNode, types, } from '@jbrowse/mobx-state-tree';
|
|
4
4
|
import { autorun } from 'mobx';
|
|
5
|
-
import { isBaseSession } from
|
|
5
|
+
import { isBaseSession } from './BaseSession.js';
|
|
6
6
|
const minDrawerWidth = 128;
|
|
7
|
+
const minMainWidth = 150;
|
|
8
|
+
const drawerPositions = ['left', 'right'];
|
|
9
|
+
// localStorage holds whatever a previous version, another tab, or a hand-edit
|
|
10
|
+
// left there, and `drawerPosition` is now an enumeration that throws on a value
|
|
11
|
+
// outside the set.
|
|
12
|
+
function storedDrawerPosition() {
|
|
13
|
+
const stored = localStorageGetItem('drawerPosition');
|
|
14
|
+
return drawerPositions.find(position => position === stored) ?? 'right';
|
|
15
|
+
}
|
|
16
|
+
// The one clamp both resize paths share. `drawerWidth` is a
|
|
17
|
+
// `types.refinement(types.integer, >= minDrawerWidth)`, so the three things this
|
|
18
|
+
// does are load-bearing rather than cosmetic — MST throws on an assignment that
|
|
19
|
+
// misses either bound:
|
|
20
|
+
//
|
|
21
|
+
// - Rounded, because a drag delta is fractional whenever `clientX` is (browser
|
|
22
|
+
// zoom, fractional devicePixelRatio, pen/touch), and ResizeHandle passes that
|
|
23
|
+
// delta straight through.
|
|
24
|
+
// - Bounded by the width the drawer and the main area actually share, which the
|
|
25
|
+
// caller measures. `window.innerWidth` is the default and is right only for a
|
|
26
|
+
// full-window app: an embedded view is whatever box the host gave it, and
|
|
27
|
+
// clamping a 600px embed's drawer against a 1600px window let a drag collapse
|
|
28
|
+
// the view beside it to nothing and overflow the embed.
|
|
29
|
+
// - The minimum applied *last*, because a container narrower than
|
|
30
|
+
// minDrawerWidth + minMainWidth has no width satisfying both bounds. The
|
|
31
|
+
// floor has to win there; the drawer simply crowds the main area.
|
|
32
|
+
function clampDrawerWidth(width, availableWidth) {
|
|
33
|
+
const max = availableWidth - minMainWidth;
|
|
34
|
+
return Math.max(minDrawerWidth, Math.min(Math.round(width), max));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* #stateModel DrawerWidgetSessionMixin
|
|
38
|
+
*/
|
|
7
39
|
export function DrawerWidgetSessionMixin(pluginManager) {
|
|
8
40
|
const widgetStateModelType = pluginManager.pluggableMstType('widget', 'stateModel');
|
|
9
41
|
return types
|
|
10
42
|
.model({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
43
|
+
/**
|
|
44
|
+
* #property
|
|
45
|
+
*/
|
|
46
|
+
drawerPosition: types.optional(types.enumeration('DrawerPosition', [
|
|
47
|
+
...drawerPositions,
|
|
48
|
+
]), storedDrawerPosition),
|
|
49
|
+
/**
|
|
50
|
+
* #property
|
|
51
|
+
*/
|
|
52
|
+
drawerWidth: types.stripDefault(types.refinement(types.integer, width => width >= minDrawerWidth), 384),
|
|
53
|
+
/**
|
|
54
|
+
* #property
|
|
55
|
+
*/
|
|
56
|
+
widgets: types.stripDefault(types.map(widgetStateModelType), {}),
|
|
57
|
+
/**
|
|
58
|
+
* #property
|
|
59
|
+
*/
|
|
60
|
+
activeWidgets: types.stripDefault(types.map(types.safeReference(widgetStateModelType)), {}),
|
|
61
|
+
/**
|
|
62
|
+
* #property
|
|
63
|
+
*/
|
|
64
|
+
minimized: types.stripDefault(types.boolean, false),
|
|
16
65
|
})
|
|
17
66
|
.views(self => ({
|
|
67
|
+
/**
|
|
68
|
+
* #getter
|
|
69
|
+
*/
|
|
70
|
+
// annotated rather than inferred: a widget's state model comes from a
|
|
71
|
+
// plugin, so `pluggableMstType` is `IAnyType` and its Instance is `any` —
|
|
72
|
+
// which silently made this getter, and every read of it off a concrete
|
|
73
|
+
// session, unchecked. `Widget` is the contract `SessionWithWidgets`
|
|
74
|
+
// already declares, so this only brings the concrete model into line with
|
|
75
|
+
// what plugins narrowing to that interface have always seen.
|
|
18
76
|
get visibleWidget() {
|
|
19
77
|
if (isAlive(self)) {
|
|
20
|
-
|
|
78
|
+
// returns most recently added item in active widgets
|
|
79
|
+
return [...self.activeWidgets.values()].at(-1);
|
|
21
80
|
}
|
|
22
81
|
return undefined;
|
|
23
82
|
},
|
|
83
|
+
}))
|
|
84
|
+
.volatile(() => ({
|
|
85
|
+
/**
|
|
86
|
+
* #volatile
|
|
87
|
+
* true while the visible widget is shown in a modal dialog instead of the
|
|
88
|
+
* drawer. Volatile because a restored session that opened straight into a
|
|
89
|
+
* modal, with no drawer behind it, is disorienting
|
|
90
|
+
*/
|
|
91
|
+
poppedOut: false,
|
|
92
|
+
}))
|
|
93
|
+
.views(self => ({
|
|
94
|
+
/**
|
|
95
|
+
* #getter
|
|
96
|
+
* whether the drawer column is on screen: there is something to show, it
|
|
97
|
+
* is not minimized to the FAB, and it is not currently a modal instead.
|
|
98
|
+
*
|
|
99
|
+
* A getter rather than each host's own `&&`, because the hosts drifted --
|
|
100
|
+
* the app shell tested `poppedOut` and the embedded view did not, so the
|
|
101
|
+
* day a popout button reaches the embedded drawer header it would render
|
|
102
|
+
* the modal and the drawer at once.
|
|
103
|
+
*/
|
|
104
|
+
get drawerVisible() {
|
|
105
|
+
return Boolean(self.visibleWidget) && !self.minimized && !self.poppedOut;
|
|
106
|
+
},
|
|
24
107
|
}))
|
|
25
108
|
.actions(self => ({
|
|
109
|
+
/**
|
|
110
|
+
* #action
|
|
111
|
+
*/
|
|
26
112
|
setDrawerPosition(arg) {
|
|
27
113
|
self.drawerPosition = arg;
|
|
28
|
-
localStorage.setItem('drawerPosition', arg);
|
|
29
114
|
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
newDrawerWidth = minDrawerWidth;
|
|
37
|
-
}
|
|
38
|
-
self.drawerWidth = newDrawerWidth;
|
|
39
|
-
return newDrawerWidth;
|
|
115
|
+
/**
|
|
116
|
+
* #action
|
|
117
|
+
*/
|
|
118
|
+
updateDrawerWidth(drawerWidth, availableWidth = window.innerWidth) {
|
|
119
|
+
self.drawerWidth = clampDrawerWidth(drawerWidth, availableWidth);
|
|
120
|
+
return self.drawerWidth;
|
|
40
121
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
122
|
+
/**
|
|
123
|
+
* #action
|
|
124
|
+
*/
|
|
125
|
+
resizeDrawer(distance, availableWidth = window.innerWidth) {
|
|
126
|
+
const signed = self.drawerPosition === 'left' ? -distance : distance;
|
|
45
127
|
const oldDrawerWidth = self.drawerWidth;
|
|
46
|
-
|
|
47
|
-
return oldDrawerWidth -
|
|
128
|
+
self.drawerWidth = clampDrawerWidth(oldDrawerWidth - signed, availableWidth);
|
|
129
|
+
return oldDrawerWidth - self.drawerWidth;
|
|
48
130
|
},
|
|
131
|
+
/**
|
|
132
|
+
* #action
|
|
133
|
+
*/
|
|
49
134
|
addWidget(typeName, id, initialState = {}, conf) {
|
|
50
|
-
|
|
51
|
-
if (!typeDefinition) {
|
|
52
|
-
throw new Error(`unknown widget type ${typeName}`);
|
|
53
|
-
}
|
|
54
|
-
const data = {
|
|
135
|
+
self.widgets.set(id, {
|
|
55
136
|
...initialState,
|
|
56
137
|
id,
|
|
57
138
|
type: typeName,
|
|
58
|
-
configuration: conf
|
|
59
|
-
};
|
|
60
|
-
self.widgets.set(id, data);
|
|
139
|
+
configuration: conf ?? { type: typeName },
|
|
140
|
+
});
|
|
61
141
|
return self.widgets.get(id);
|
|
62
142
|
},
|
|
143
|
+
/**
|
|
144
|
+
* #action
|
|
145
|
+
*/
|
|
63
146
|
showWidget(widget) {
|
|
64
147
|
if (self.activeWidgets.has(widget.id)) {
|
|
65
148
|
self.activeWidgets.delete(widget.id);
|
|
@@ -67,28 +150,62 @@ export function DrawerWidgetSessionMixin(pluginManager) {
|
|
|
67
150
|
self.activeWidgets.set(widget.id, widget);
|
|
68
151
|
self.minimized = false;
|
|
69
152
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
153
|
+
/**
|
|
154
|
+
* #action
|
|
155
|
+
*/
|
|
73
156
|
hideWidget(widget) {
|
|
74
157
|
self.activeWidgets.delete(widget.id);
|
|
158
|
+
if (self.activeWidgets.size === 0) {
|
|
159
|
+
self.poppedOut = false;
|
|
160
|
+
}
|
|
75
161
|
},
|
|
162
|
+
/**
|
|
163
|
+
* #action
|
|
164
|
+
*/
|
|
76
165
|
minimizeWidgetDrawer() {
|
|
77
166
|
self.minimized = true;
|
|
78
167
|
},
|
|
168
|
+
/**
|
|
169
|
+
* #action
|
|
170
|
+
*/
|
|
79
171
|
showWidgetDrawer() {
|
|
80
172
|
self.minimized = false;
|
|
81
173
|
},
|
|
174
|
+
/**
|
|
175
|
+
* #action
|
|
176
|
+
* show the visible widget in a modal dialog, freeing the drawer column
|
|
177
|
+
*/
|
|
178
|
+
popoutWidget() {
|
|
179
|
+
self.poppedOut = true;
|
|
180
|
+
},
|
|
181
|
+
/**
|
|
182
|
+
* #action
|
|
183
|
+
*/
|
|
184
|
+
returnWidgetToDrawer() {
|
|
185
|
+
self.poppedOut = false;
|
|
186
|
+
},
|
|
187
|
+
/**
|
|
188
|
+
* #action
|
|
189
|
+
*/
|
|
82
190
|
hideAllWidgets() {
|
|
83
191
|
self.activeWidgets.clear();
|
|
192
|
+
self.poppedOut = false;
|
|
84
193
|
},
|
|
85
|
-
|
|
194
|
+
/**
|
|
195
|
+
* #action
|
|
196
|
+
* opens a configuration editor to configure the given thing,
|
|
197
|
+
* and sets the current task to be configuring it
|
|
198
|
+
* @param configuration - can be an MST model or a frozen/plain object with trackId
|
|
199
|
+
*/
|
|
200
|
+
editConfiguration(configuration, opts) {
|
|
86
201
|
let targetConfig;
|
|
87
202
|
if (isStateTreeNode(configuration) &&
|
|
88
203
|
isConfigurationModel(configuration)) {
|
|
204
|
+
// Already an MST model (e.g., from track.configuration), use directly
|
|
89
205
|
targetConfig = configuration;
|
|
90
206
|
}
|
|
91
207
|
else if ('trackId' in configuration) {
|
|
208
|
+
// Frozen/plain object - create a temporary MST model for editing
|
|
92
209
|
const trackSchema = pluginManager.pluggableConfigSchemaType('track');
|
|
93
210
|
targetConfig = trackSchema.create(configuration, getEnv(self));
|
|
94
211
|
}
|
|
@@ -96,7 +213,9 @@ export function DrawerWidgetSessionMixin(pluginManager) {
|
|
|
96
213
|
throw new Error('must pass a configuration model or frozen config with trackId to editConfiguration');
|
|
97
214
|
}
|
|
98
215
|
const editor = this.addWidget('ConfigurationEditorWidget', 'configEditor', {});
|
|
216
|
+
// Set target via action since it's now volatile
|
|
99
217
|
editor.setTarget(targetConfig);
|
|
218
|
+
editor.setExpandedDisplayId(opts?.expandedDisplayId);
|
|
100
219
|
this.showWidget(editor);
|
|
101
220
|
},
|
|
102
221
|
afterAttach() {
|
|
@@ -106,20 +225,20 @@ export function DrawerWidgetSessionMixin(pluginManager) {
|
|
|
106
225
|
},
|
|
107
226
|
}))
|
|
108
227
|
.postProcessSnapshot(snap => {
|
|
228
|
+
// drawerPosition is a personal per-browser layout preference, not shared
|
|
229
|
+
// view state: destructure it out so it never lands in the snapshot. It
|
|
230
|
+
// stays localStorage-backed, so each browser keeps its own value.
|
|
231
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
109
232
|
if (!snap) {
|
|
110
233
|
return snap;
|
|
111
234
|
}
|
|
112
|
-
const { drawerPosition,
|
|
235
|
+
const { drawerPosition, ...rest } = snap;
|
|
113
236
|
return {
|
|
114
237
|
...rest,
|
|
115
|
-
...(drawerPosition !== 'right' ? { drawerPosition } : {}),
|
|
116
|
-
...(drawerWidth !== 384 ? { drawerWidth } : {}),
|
|
117
|
-
...(Object.keys(widgets ?? {}).length ? { widgets } : {}),
|
|
118
|
-
...(Object.keys(activeWidgets ?? {}).length ? { activeWidgets } : {}),
|
|
119
|
-
...(minimized ? { minimized } : {}),
|
|
120
238
|
};
|
|
121
239
|
});
|
|
122
240
|
}
|
|
241
|
+
/** Type guard for SessionWithDrawerWidgets */
|
|
123
242
|
export function isSessionWithDrawerWidgets(session) {
|
|
124
243
|
return (isBaseSession(session) &&
|
|
125
244
|
'widgets' in session &&
|