@jbrowse/product-core 5.0.0-beta.8 → 5.0.0-beta.9
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 +1 -4
- package/esm/RootModel/HierarchicalConfig.d.ts +21 -47
- package/esm/RootModel/PreferencesConfig.d.ts +18 -49
- package/esm/RootModel/PreferencesConfig.js +2 -3
- package/esm/RootModel/createConfigModel.d.ts +141 -124
- package/esm/RootModel/createConfigModel.js +26 -14
- package/esm/RootModel/menuItems.js +4 -6
- package/esm/Session/BaseSession.d.ts +30 -13
- package/esm/Session/BaseSession.js +50 -16
- package/esm/Session/Connections.d.ts +4 -3
- package/esm/Session/Connections.js +4 -3
- package/esm/Session/DrawerWidgets.d.ts +8 -1
- package/esm/Session/DrawerWidgets.js +19 -7
- package/esm/Session/MultipleViews.d.ts +13 -14
- package/esm/Session/Preferences.d.ts +8 -13
- package/esm/Session/SessionTracks.d.ts +32 -38
- package/esm/Session/SessionTracks.js +52 -115
- package/esm/Session/Themes.d.ts +9 -10
- package/esm/Session/Themes.js +9 -10
- package/esm/Session/TrackMenu.d.ts +1 -26
- package/esm/Session/TrackMenu.js +2 -33
- package/esm/Session/TrackMenuSessionMixin.js +2 -1
- package/esm/Session/Tracks.d.ts +8 -13
- package/esm/Session/copyTrackSnapshot.d.ts +21 -0
- package/esm/Session/copyTrackSnapshot.js +20 -0
- package/esm/Session/hydratedForms.d.ts +16 -0
- package/esm/Session/hydratedForms.js +13 -0
- package/esm/Session/index.d.ts +5 -1
- package/esm/Session/index.js +4 -1
- package/esm/Session/pluginExtraTrackItems.d.ts +11 -0
- package/esm/Session/pluginExtraTrackItems.js +13 -0
- package/esm/controllerTracks.d.ts +13 -8
- package/esm/controllerTracks.js +18 -9
- package/esm/index.d.ts +6 -6
- package/esm/index.js +3 -3
- package/esm/loadPlugins.d.ts +7 -2
- package/esm/loadPlugins.js +6 -2
- package/esm/resolveAssemblies.d.ts +34 -11
- package/esm/resolveAssemblies.js +29 -11
- package/esm/rpcWorker.d.ts +12 -5
- package/esm/rpcWorker.js +1 -1
- package/esm/sessionMigrations/index.d.ts +5 -5
- package/esm/sessionMigrations/index.js +82 -19
- package/esm/sessionUrl.js +1 -1
- package/esm/sessionUtils.d.ts +6 -1
- package/esm/sessionUtils.js +42 -35
- package/esm/ui/AboutDialog.d.ts +10 -2
- package/esm/ui/AboutDialog.js +11 -2
- package/esm/ui/AboutDialogContents.js +3 -21
- package/esm/ui/AppReadyMarker.d.ts +45 -0
- package/esm/ui/AppReadyMarker.js +89 -0
- package/esm/ui/AssemblyInfoPanel.js +4 -10
- package/esm/ui/DescriptionPanel.js +2 -1
- package/esm/ui/FileInfoPanel.js +5 -10
- package/esm/ui/RefNameInfoDialog.js +10 -23
- package/esm/ui/aboutTestUtils.d.ts +140 -0
- package/esm/ui/aboutTestUtils.js +25 -0
- package/esm/ui/descriptionHtml.d.ts +5 -6
- package/esm/ui/descriptionHtml.js +5 -7
- package/esm/ui/index.d.ts +2 -0
- package/esm/ui/index.js +1 -0
- package/esm/ui/util.d.ts +9 -27
- package/esm/ui/util.js +12 -31
- package/package.json +4 -4
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import { readConfObject } from '@jbrowse/core/configuration';
|
|
2
2
|
import { diffTrackConfig, flattenTrackConfigDelta, mergeTrackConfig, } from '@jbrowse/core/util';
|
|
3
3
|
import { expandLooseTrackConfig } from '@jbrowse/core/util/tracks';
|
|
4
|
-
import { applySnapshot, getSnapshot,
|
|
4
|
+
import { applySnapshot, getSnapshot, types } from '@jbrowse/mobx-state-tree';
|
|
5
5
|
import { compareStructural } from 'mobx';
|
|
6
6
|
import { TracksManagerSessionMixin } from './Tracks.js';
|
|
7
|
+
import { hydratedTrackForm } from './hydratedForms.js';
|
|
7
8
|
import { assertNotReaddedDifferently } from './readdedTrackConf.js';
|
|
8
9
|
import { assertTrackConfOutlivesItsAssemblies } from './temporaryAssemblyTracks.js';
|
|
9
|
-
// jbrowse.tracks holds frozen plain objects
|
|
10
|
-
//
|
|
11
|
-
// as plain track configs. Single site for that documented cast — per-node
|
|
12
|
-
// normalization still happens in toPlainConfig.
|
|
10
|
+
// jbrowse.tracks holds frozen plain objects in every product; single site for
|
|
11
|
+
// the cast from its loose frozen type.
|
|
13
12
|
function baseTracks(self) {
|
|
14
13
|
return self.jbrowse.tracks;
|
|
15
14
|
}
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
// always retains the self-identifying trackId, and a base config that omits
|
|
20
|
-
// `displays` diffs against the hydrated snapshot's injected {type, displayId}
|
|
21
|
-
// display stubs to yield `{trackId, displays: [...stubs]}` — nonzero keys but no
|
|
22
|
-
// changed slot. flattenTrackConfigDelta (which drops identity keys and empty
|
|
23
|
-
// display stubs) is the honest test of whether any real setting changed.
|
|
15
|
+
// Not a key count: every delta keeps its trackId, and one can hold nothing but
|
|
16
|
+
// content-free display stubs. A stored delta lights the edited badge, so only a
|
|
17
|
+
// changed slot — a reset included — counts.
|
|
24
18
|
function deltaHasChanges(base, delta) {
|
|
25
19
|
return flattenTrackConfigDelta(base, delta).length > 0;
|
|
26
20
|
}
|
|
@@ -52,42 +46,20 @@ function withoutDelta(deltas, trackId) {
|
|
|
52
46
|
* #stateModel SessionTracksManagerSessionMixin
|
|
53
47
|
*/
|
|
54
48
|
export function SessionTracksManagerSessionMixin(pluginManager) {
|
|
55
|
-
// A
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
// merging across those two forms makes every expanded/injected field read as
|
|
63
|
-
// a user edit — pinning whole adapters and content-free display stubs into
|
|
64
|
-
// deltas, and defeating the delta's purpose (a later admin adapter-URL fix
|
|
65
|
-
// would then be masked by the pinned copy). Normalize a base to the hydrated
|
|
66
|
-
// form by running it through the same track schema, so diff/merge compare
|
|
67
|
-
// like with like and cancel everything untouched. Memoized per frozen-base
|
|
68
|
-
// identity (stable until a jbrowse.tracks write). A base that is already an
|
|
69
|
-
// MST config node (product-core embedded views) is snapshotted directly — it
|
|
70
|
-
// is already in the hydrated form.
|
|
71
|
-
//
|
|
72
|
-
// The isStateTreeNode/getSnapshot casts are load-bearing, don't "simplify"
|
|
73
|
-
// them: our MST fork types `isStateTreeNode`'s parameter as a state-tree node
|
|
74
|
-
// (not `unknown`), so `base` (a plain interface) must widen through `unknown`
|
|
75
|
-
// to be passed, and `getSnapshot` of that returns `unknown`.
|
|
49
|
+
// A base is the raw config-file object — shorthand `uri`, no display stubs —
|
|
50
|
+
// while a working copy's snapshot is hydrated. Diffing or merging across the
|
|
51
|
+
// two reads every expanded field as an edit, pinning whole adapters into the
|
|
52
|
+
// delta, and every member one form has and the other lacks as a reset. So
|
|
53
|
+
// both sides go through the same schema first; a base is memoized per
|
|
54
|
+
// frozen-base identity, which is stable until a jbrowse.tracks write.
|
|
55
|
+
const hydrate = hydratedTrackForm(pluginManager);
|
|
76
56
|
const canonicalBaseCache = new WeakMap();
|
|
77
57
|
function toPlainConfig(base) {
|
|
78
|
-
const node = base;
|
|
79
|
-
if (isStateTreeNode(node)) {
|
|
80
|
-
return getSnapshot(node);
|
|
81
|
-
}
|
|
82
58
|
const cached = canonicalBaseCache.get(base);
|
|
83
59
|
if (cached) {
|
|
84
60
|
return cached;
|
|
85
61
|
}
|
|
86
|
-
const
|
|
87
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- tsc7 sees getSnapshot here as unknown (eslint's TS6 service disagrees; see header note)
|
|
88
|
-
/* oxlint-disable typescript/no-unnecessary-type-assertion */
|
|
89
|
-
const hydrated = getSnapshot(schema.create(base, { pluginManager }));
|
|
90
|
-
/* oxlint-enable typescript/no-unnecessary-type-assertion */
|
|
62
|
+
const hydrated = hydrate(base);
|
|
91
63
|
canonicalBaseCache.set(base, hydrated);
|
|
92
64
|
return hydrated;
|
|
93
65
|
}
|
|
@@ -106,9 +78,10 @@ export function SessionTracksManagerSessionMixin(pluginManager) {
|
|
|
106
78
|
* Per-track config overrides for a non-admin, keyed by trackId, stored as a
|
|
107
79
|
* *delta* against the admin-owned base config (jbrowse.tracks entry) rather
|
|
108
80
|
* than a full copy — so a later admin change to an untouched field still
|
|
109
|
-
* flows through (see trackConfigDelta.ts).
|
|
110
|
-
*
|
|
111
|
-
*
|
|
81
|
+
* flows through (see trackConfigDelta.ts). A `null` member resets a slot
|
|
82
|
+
* the base sets. Frozen (not a typed track array) on purpose: a typed
|
|
83
|
+
* create() would fill defaults, erasing the "unset vs default"
|
|
84
|
+
* distinction the delta merge relies on.
|
|
112
85
|
*
|
|
113
86
|
* `stripDefault` for the reason every other persisted prop beside it has
|
|
114
87
|
* it: without it the empty map is written into every snapshot and every
|
|
@@ -147,10 +120,9 @@ export function SessionTracksManagerSessionMixin(pluginManager) {
|
|
|
147
120
|
// Both keys have stable identity until they actually change: a track's
|
|
148
121
|
// delta only when that track is edited, and the base only on a
|
|
149
122
|
// jbrowse.tracks write. This relies on a base config never mutating in
|
|
150
|
-
// place:
|
|
151
|
-
// updateTrackConf
|
|
152
|
-
//
|
|
153
|
-
// in-place base edit is ever added, key this cache on base content too.
|
|
123
|
+
// place: the frozen array replaces the entry (new identity) on
|
|
124
|
+
// updateTrackConf. If an in-place base edit is ever added, key this cache
|
|
125
|
+
// on base content too.
|
|
154
126
|
const mergeCache = new WeakMap();
|
|
155
127
|
return {
|
|
156
128
|
/**
|
|
@@ -267,13 +239,10 @@ export function SessionTracksManagerSessionMixin(pluginManager) {
|
|
|
267
239
|
// the node identity (existing observers just update); no-op in admin mode
|
|
268
240
|
// or for a track that was never edited (no working copy).
|
|
269
241
|
//
|
|
270
|
-
// Through toPlainConfig like every other read of a base in this file
|
|
271
|
-
//
|
|
272
|
-
//
|
|
273
|
-
//
|
|
274
|
-
// base the two agree, since applySnapshot re-runs the same
|
|
275
|
-
// preProcessSnapshot that toPlainConfig hydrates through, so this only
|
|
276
|
-
// makes that reliance explicit.)
|
|
242
|
+
// Through toPlainConfig like every other read of a base in this file. The
|
|
243
|
+
// raw entry would do the same, since applySnapshot re-runs the
|
|
244
|
+
// preProcessSnapshot toPlainConfig hydrates through; this makes that
|
|
245
|
+
// reliance explicit.
|
|
277
246
|
function revertEditableTrackConfig(trackId) {
|
|
278
247
|
const entry = self.editableTrackConfigs.get(trackId);
|
|
279
248
|
const base = baseTracks(self).find(t => t.trackId === trackId);
|
|
@@ -293,26 +262,16 @@ export function SessionTracksManagerSessionMixin(pluginManager) {
|
|
|
293
262
|
}
|
|
294
263
|
// Single writer for trackConfigDeltas (pass undefined to clear). Clearing
|
|
295
264
|
// also reverts the working copy, which is what makes a Reset visible in an
|
|
296
|
-
// open view
|
|
297
|
-
|
|
298
|
-
// reverting undoes it.
|
|
299
|
-
function writeDelta(trackId, delta, { revertWorkingCopy = true } = {}) {
|
|
265
|
+
// open view.
|
|
266
|
+
function writeDelta(trackId, delta) {
|
|
300
267
|
self.trackConfigDeltas = delta
|
|
301
268
|
? { ...self.trackConfigDeltas, [trackId]: delta }
|
|
302
269
|
: withoutDelta(self.trackConfigDeltas, trackId);
|
|
303
|
-
if (!delta
|
|
270
|
+
if (!delta) {
|
|
304
271
|
revertEditableTrackConfig(trackId);
|
|
305
272
|
}
|
|
306
273
|
stampEditableTrackConfig(trackId);
|
|
307
274
|
}
|
|
308
|
-
// Whether `trackConf` is the working copy's own current state — i.e. this
|
|
309
|
-
// update came from the track's live `setSlot` edits rather than from the
|
|
310
|
-
// config editor's separate temporary node. `syncEditableTrackConfig` below
|
|
311
|
-
// asks the same question the other way round.
|
|
312
|
-
function isWorkingCopyState(trackId, trackConf) {
|
|
313
|
-
const entry = self.editableTrackConfigs.get(trackId);
|
|
314
|
-
return !!entry && compareStructural(getSnapshot(entry.node), trackConf);
|
|
315
|
-
}
|
|
316
275
|
// Push a *programmatic* update (the config editor's Apply, or any
|
|
317
276
|
// updateTrackConfiguration not driven by this node's own live edits) into
|
|
318
277
|
// the working copy. When the node IS the edit source its snapshot already
|
|
@@ -388,31 +347,29 @@ export function SessionTracksManagerSessionMixin(pluginManager) {
|
|
|
388
347
|
* config.json every visitor is served; everyone else's goes to
|
|
389
348
|
* `sessionTracks`.
|
|
390
349
|
*
|
|
391
|
-
* **
|
|
392
|
-
* track means to add it for the whole site.
|
|
393
|
-
* on the user's behalf
|
|
394
|
-
* reconstruction's segment labels
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
* `addSessionTrackConf` above
|
|
350
|
+
* **Call it only from the "Add track" workflows**, where an admin
|
|
351
|
+
* adding a track means to add it for the whole site. For a track a
|
|
352
|
+
* feature creates on the user's behalf (a search result, a computed
|
|
353
|
+
* consensus, a reconstruction's segment labels), one admin click on
|
|
354
|
+
* this publishes it to every visitor, and each later click publishes
|
|
355
|
+
* another copy, because the per-launch trackId prevents deduplication.
|
|
356
|
+
* Use `addSessionTrackConf` above for those.
|
|
398
357
|
*
|
|
399
358
|
* An admin's track still goes to the session when it names an assembly
|
|
400
|
-
* the config.json does not carry
|
|
401
|
-
* genome, a comparative view's synthesized pair. The
|
|
402
|
-
* takes its assembly from the containing view, so an
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
* moved it.
|
|
359
|
+
* the config.json does not carry: a session spec's assembly, a MAF
|
|
360
|
+
* sample's genome, or a comparative view's synthesized pair. The
|
|
361
|
+
* Add-track widget takes its assembly from the containing view, so an
|
|
362
|
+
* admin adding a track in such a view passes a name no visitor can
|
|
363
|
+
* resolve. Publishing it would write an entry the server sends to every
|
|
364
|
+
* visitor and no visitor can draw. Adding it to the session keeps the
|
|
365
|
+
* track usable and writes no dangling entry; a snackbar names the
|
|
366
|
+
* assembly that caused the fallback.
|
|
409
367
|
*
|
|
410
|
-
* **The snackbar names the assembly and not the track**,
|
|
411
|
-
*
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
* of what an admin has to act on anyway.
|
|
368
|
+
* **The snackbar names the assembly and not the track**, so a batch
|
|
369
|
+
* produces one message: `pushSnackbarMessage` dedupes on the exact
|
|
370
|
+
* text, and `BulkAddTracksWorkflow` publishes in a loop. Including the
|
|
371
|
+
* track name would show one snackbar per file to an admin adding
|
|
372
|
+
* thirty. The assembly is all the admin needs to act on.
|
|
416
373
|
*/
|
|
417
374
|
publishTrackConf(trackConf) {
|
|
418
375
|
if (!self.adminMode) {
|
|
@@ -460,11 +417,8 @@ export function SessionTracksManagerSessionMixin(pluginManager) {
|
|
|
460
417
|
: self.sessionTracks.findIndex(t => t.trackId === trackId);
|
|
461
418
|
if (base) {
|
|
462
419
|
const plainBase = toPlainConfig(base);
|
|
463
|
-
const delta = diffTrackConfig(plainBase, trackConf);
|
|
464
|
-
// an edit that nets back to the base
|
|
465
|
-
// any prior override (implicit reset) instead of pinning a
|
|
466
|
-
// content-free delta; skip a no-op write when there's nothing to
|
|
467
|
-
// clear, so the tracks getter doesn't needlessly churn identity
|
|
420
|
+
const delta = diffTrackConfig(plainBase, hydrate(trackConf));
|
|
421
|
+
// an edit that nets back to the base clears any prior override
|
|
468
422
|
if (deltaHasChanges(plainBase, delta)) {
|
|
469
423
|
// Two views showing the same track each run BaseTrackModel's
|
|
470
424
|
// persist reaction against the shared config node, so a single edit
|
|
@@ -480,24 +434,7 @@ export function SessionTracksManagerSessionMixin(pluginManager) {
|
|
|
480
434
|
syncEditableTrackConfig(trackId, trackConf);
|
|
481
435
|
}
|
|
482
436
|
else if (trackId in self.trackConfigDeltas) {
|
|
483
|
-
|
|
484
|
-
// is a reset. `diffTrackConfig` records adds and changes, never
|
|
485
|
-
// deletions (its module note), so *unsetting* a slot the admin
|
|
486
|
-
// base sets diffs to nothing exactly as netting back to the base
|
|
487
|
-
// does — and reverting the working copy then undid the edit ~400ms
|
|
488
|
-
// after the user watched it land. The reachable case is a size
|
|
489
|
-
// row's reset, whose whole job is to unset a slot an admin
|
|
490
|
-
// `config.json` declares.
|
|
491
|
-
//
|
|
492
|
-
// The removal still doesn't survive a reload, which is the
|
|
493
|
-
// tombstone-free delta's documented limitation; what it no longer
|
|
494
|
-
// does is undo itself on screen. Only the working-copy-driven path
|
|
495
|
-
// skips the revert: the config editor edits a separate temporary
|
|
496
|
-
// node, so there the revert is the only thing that moves the open
|
|
497
|
-
// track back to the base.
|
|
498
|
-
writeDelta(trackId, undefined, {
|
|
499
|
-
revertWorkingCopy: !isWorkingCopyState(trackId, trackConf),
|
|
500
|
-
});
|
|
437
|
+
writeDelta(trackId, undefined);
|
|
501
438
|
}
|
|
502
439
|
}
|
|
503
440
|
else if (sessionIdx !== -1) {
|
package/esm/Session/Themes.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
2
|
-
import type { SerializableThemeArgs, ThemeMap } from '@jbrowse/core/ui';
|
|
2
|
+
import type { SerializableThemeArgs, ThemeMap } from '@jbrowse/core/ui/theme';
|
|
3
3
|
import type { IAnyStateTreeNode, Instance } from '@jbrowse/mobx-state-tree';
|
|
4
4
|
import type { ThemeOptions } from '@mui/material';
|
|
5
5
|
/**
|
|
@@ -54,15 +54,14 @@ export declare function ThemeManagerSessionMixin(_pluginManager: PluginManager):
|
|
|
54
54
|
* view's SVG export threads into each display's `renderSvg`, which
|
|
55
55
|
* rebuilds the theme via `createJBrowseTheme` outside React context.
|
|
56
56
|
*
|
|
57
|
-
* The `default` entry is
|
|
58
|
-
* the
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* the distinction this ternary keeps.
|
|
57
|
+
* The `default` entry is merged with the config `theme` slot, because
|
|
58
|
+
* the picker labels it "Default (from config)" and `resolvePalette`
|
|
59
|
+
* merges the preset with the slot for every other consumer. The bare
|
|
60
|
+
* preset would make `view.exportSvg()` drop a host's configured
|
|
61
|
+
* palette: a config setting `primary.main` would draw `#123456` on
|
|
62
|
+
* screen and export the stock `#0D233F`, while the export dialog named
|
|
63
|
+
* the default theme. Every other named theme is a fixed preset that
|
|
64
|
+
* ignores config.
|
|
66
65
|
*/
|
|
67
66
|
getActiveThemeOptions(name?: string): (ThemeOptions & {
|
|
68
67
|
name?: string;
|
package/esm/Session/Themes.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getConf, setConf } from '@jbrowse/core/configuration';
|
|
2
|
-
import { createJBrowseThemeFromArgs, defaultThemes } from '@jbrowse/core/ui';
|
|
3
2
|
import { resolvePalette } from '@jbrowse/core/ui/palette';
|
|
4
3
|
import { resolveStyleTheme } from '@jbrowse/core/ui/styleTheme';
|
|
4
|
+
import { createJBrowseThemeFromArgs, defaultThemes, } from '@jbrowse/core/ui/theme';
|
|
5
5
|
import { localStorageGetItem, localStorageSetItem } from '@jbrowse/core/util';
|
|
6
6
|
import { addDisposer, types } from '@jbrowse/mobx-state-tree';
|
|
7
7
|
import { autorun } from 'mobx';
|
|
@@ -96,15 +96,14 @@ export function ThemeManagerSessionMixin(_pluginManager) {
|
|
|
96
96
|
* view's SVG export threads into each display's `renderSvg`, which
|
|
97
97
|
* rebuilds the theme via `createJBrowseTheme` outside React context.
|
|
98
98
|
*
|
|
99
|
-
* The `default` entry is
|
|
100
|
-
* the
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* the distinction this ternary keeps.
|
|
99
|
+
* The `default` entry is merged with the config `theme` slot, because
|
|
100
|
+
* the picker labels it "Default (from config)" and `resolvePalette`
|
|
101
|
+
* merges the preset with the slot for every other consumer. The bare
|
|
102
|
+
* preset would make `view.exportSvg()` drop a host's configured
|
|
103
|
+
* palette: a config setting `primary.main` would draw `#123456` on
|
|
104
|
+
* screen and export the stock `#0D233F`, while the export dialog named
|
|
105
|
+
* the default theme. Every other named theme is a fixed preset that
|
|
106
|
+
* ignores config.
|
|
108
107
|
*/
|
|
109
108
|
getActiveThemeOptions(name) {
|
|
110
109
|
const all = this.allThemes();
|
|
@@ -4,25 +4,6 @@ import type { BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes';
|
|
|
4
4
|
import type { MenuItem } from '@jbrowse/core/ui';
|
|
5
5
|
import type { DialogComponentType } from '@jbrowse/core/util';
|
|
6
6
|
import type { TrackActionView } from '@jbrowse/core/util/types';
|
|
7
|
-
type TrackCopySnapshot = {
|
|
8
|
-
trackId: string;
|
|
9
|
-
name: string;
|
|
10
|
-
category?: unknown;
|
|
11
|
-
displays?: {
|
|
12
|
-
type: string;
|
|
13
|
-
displayId: string;
|
|
14
|
-
}[];
|
|
15
|
-
} & Record<string, unknown>;
|
|
16
|
-
/**
|
|
17
|
-
* Clone a track config for "Copy track": snapshots the config, appends a unique
|
|
18
|
-
* timestamp suffix to trackId (so it doesn't collide with the original), tags
|
|
19
|
-
* " (copy)" on the name, and regenerates each displayId to the canonical
|
|
20
|
-
* `${trackId}-${type}` form baseTrackConfig auto-injects — keeping them unique
|
|
21
|
-
* (displayId is a types.identifier, so a collision would crash MST).
|
|
22
|
-
*/
|
|
23
|
-
export declare function copyTrackSnapshot(config: BaseTrackConfig, opts: {
|
|
24
|
-
clearCategory: boolean;
|
|
25
|
-
}): TrackCopySnapshot;
|
|
26
7
|
interface TrackActionSession<C> {
|
|
27
8
|
editConfiguration: (config: AnyConfigurationModel | {
|
|
28
9
|
trackId: string;
|
|
@@ -65,18 +46,12 @@ export declare function trackActionItems<C extends {
|
|
|
65
46
|
isSessionOverride?: boolean;
|
|
66
47
|
makeCopy: () => C;
|
|
67
48
|
}): MenuItem[];
|
|
68
|
-
interface SessionWithDialog {
|
|
49
|
+
export interface SessionWithDialog {
|
|
69
50
|
queueDialog: (cb: (done: () => void) => [DialogComponentType, Record<string, unknown>]) => void;
|
|
70
51
|
}
|
|
71
52
|
type TrackConfig = AnyConfigurationModel | Record<string, unknown>;
|
|
72
53
|
/** "About track" menu item, shared by every product's track menu */
|
|
73
54
|
export declare function aboutTrackMenuItem(session: SessionWithDialog, config: TrackConfig): MenuItem;
|
|
74
|
-
/**
|
|
75
|
-
* plugin-contributed per-track items (`Core-extraTrackMenuItems`), surfaced in
|
|
76
|
-
* both the hierarchical selector and the in-view label menu so plugins reach
|
|
77
|
-
* every track menu consistently
|
|
78
|
-
*/
|
|
79
|
-
export declare function pluginExtraTrackItems(pluginManager: PluginManager, session: SessionWithDialog, config: AnyConfigurationModel, view?: TrackActionView): MenuItem[];
|
|
80
55
|
/**
|
|
81
56
|
* flattened track menu (About + raw actions) for the hierarchical track selector
|
|
82
57
|
*/
|
package/esm/Session/TrackMenu.js
CHANGED
|
@@ -1,33 +1,14 @@
|
|
|
1
1
|
import { lazy } from 'react';
|
|
2
2
|
import { InfoIcon } from '@jbrowse/core/ui/Icons';
|
|
3
|
-
import { buildExtraTrackMenuItems } from '@jbrowse/core/ui/buildExtraTrackMenuItems';
|
|
4
3
|
import { namesTemporaryAssembly } from '@jbrowse/core/util';
|
|
5
|
-
import {
|
|
4
|
+
import { types } from '@jbrowse/mobx-state-tree';
|
|
6
5
|
import DeleteIcon from '@mui/icons-material/Delete';
|
|
7
6
|
import CopyIcon from '@mui/icons-material/FileCopy';
|
|
8
7
|
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
|
|
9
8
|
import SettingsIcon from '@mui/icons-material/Settings';
|
|
10
9
|
import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore';
|
|
10
|
+
import { pluginExtraTrackItems } from './pluginExtraTrackItems.js';
|
|
11
11
|
const AboutDialog = lazy(() => import('../ui/AboutDialog.js'));
|
|
12
|
-
/**
|
|
13
|
-
* Clone a track config for "Copy track": snapshots the config, appends a unique
|
|
14
|
-
* timestamp suffix to trackId (so it doesn't collide with the original), tags
|
|
15
|
-
* " (copy)" on the name, and regenerates each displayId to the canonical
|
|
16
|
-
* `${trackId}-${type}` form baseTrackConfig auto-injects — keeping them unique
|
|
17
|
-
* (displayId is a types.identifier, so a collision would crash MST).
|
|
18
|
-
*/
|
|
19
|
-
export function copyTrackSnapshot(config, opts) {
|
|
20
|
-
const snap = structuredClone(isStateTreeNode(config) ? getSnapshot(config) : config);
|
|
21
|
-
snap.trackId += `-${Date.now()}`;
|
|
22
|
-
snap.name += ' (copy)';
|
|
23
|
-
if (opts.clearCategory) {
|
|
24
|
-
snap.category = undefined;
|
|
25
|
-
}
|
|
26
|
-
for (const d of snap.displays ?? []) {
|
|
27
|
-
d.displayId = `${snap.trackId}-${d.type}`;
|
|
28
|
-
}
|
|
29
|
-
return snap;
|
|
30
|
-
}
|
|
31
12
|
/**
|
|
32
13
|
* The shared Settings / Copy / Copy-and-open / Delete track actions. Each
|
|
33
14
|
* product supplies `makeCopy` (its own session-track/category rules) and
|
|
@@ -123,18 +104,6 @@ export function aboutTrackMenuItem(session, config) {
|
|
|
123
104
|
},
|
|
124
105
|
};
|
|
125
106
|
}
|
|
126
|
-
/**
|
|
127
|
-
* plugin-contributed per-track items (`Core-extraTrackMenuItems`), surfaced in
|
|
128
|
-
* both the hierarchical selector and the in-view label menu so plugins reach
|
|
129
|
-
* every track menu consistently
|
|
130
|
-
*/
|
|
131
|
-
export function pluginExtraTrackItems(pluginManager, session, config, view) {
|
|
132
|
-
return buildExtraTrackMenuItems(pluginManager, {
|
|
133
|
-
session: session,
|
|
134
|
-
config,
|
|
135
|
-
view,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
107
|
/**
|
|
139
108
|
* flattened track menu (About + raw actions) for the hierarchical track selector
|
|
140
109
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { types } from '@jbrowse/mobx-state-tree';
|
|
2
2
|
import { asSession } from '../siblingCast.js';
|
|
3
|
-
import { aboutTrackMenuItem,
|
|
3
|
+
import { aboutTrackMenuItem, trackListMenuItems } from './TrackMenu.js';
|
|
4
|
+
import { pluginExtraTrackItems } from './pluginExtraTrackItems.js';
|
|
4
5
|
/**
|
|
5
6
|
* #stateModel TrackMenuSessionMixin
|
|
6
7
|
*
|
package/esm/Session/Tracks.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
8
8
|
id: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<string>, [undefined]>;
|
|
9
9
|
name: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
10
10
|
focusedViewId: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
|
|
11
|
+
highlights: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IType<import("@jbrowse/core/util/highlights").HighlightType, import("@jbrowse/core/util/highlights").HighlightType, import("@jbrowse/core/util/highlights").HighlightType>>, [undefined]>;
|
|
11
12
|
highlightsVisible: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").ISimpleType<boolean>, [undefined]>;
|
|
12
13
|
heldForMissingPlugins: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IType<import("../pruneUnbuildableNodes.ts").HeldNode[] | undefined, import("../pruneUnbuildableNodes.ts").HeldNode[] | undefined, import("../pruneUnbuildableNodes.ts").HeldNode[] | undefined>, [undefined]>;
|
|
13
14
|
}, never>, never>, {
|
|
@@ -509,10 +510,7 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
509
510
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>) | undefined;
|
|
510
511
|
readonly assemblyNamesList: string[];
|
|
511
512
|
readonly configuredAssemblyNames: Set<string>;
|
|
512
|
-
readonly assemblyList:
|
|
513
|
-
setSubschema(slotName: string, data: Record<string, unknown>): any;
|
|
514
|
-
setSlot(slotName: string, value: unknown): void;
|
|
515
|
-
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>)[];
|
|
513
|
+
readonly assemblyList: AnyConfigurationModel[];
|
|
516
514
|
readonly rpcManager: import("@jbrowse/core/rpc/RpcManager").default;
|
|
517
515
|
} & {
|
|
518
516
|
settleAssemblyResolution(assemblyName: string): Promise<void>;
|
|
@@ -1301,10 +1299,7 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1301
1299
|
}, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>>) | undefined;
|
|
1302
1300
|
readonly assemblyNamesList: string[];
|
|
1303
1301
|
readonly configuredAssemblyNames: Set<string>;
|
|
1304
|
-
readonly assemblyList:
|
|
1305
|
-
setSubschema(slotName: string, data: Record<string, unknown>): any;
|
|
1306
|
-
setSlot(slotName: string, value: unknown): void;
|
|
1307
|
-
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>)[];
|
|
1302
|
+
readonly assemblyList: AnyConfigurationModel[];
|
|
1308
1303
|
readonly rpcManager: import("@jbrowse/core/rpc/RpcManager").default;
|
|
1309
1304
|
} & {
|
|
1310
1305
|
settleAssemblyResolution(assemblyName: string): Promise<void>;
|
|
@@ -1604,10 +1599,7 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1604
1599
|
} & {
|
|
1605
1600
|
readonly jbrowse: any;
|
|
1606
1601
|
readonly rpcManager: import("@jbrowse/core/rpc/RpcManager").default;
|
|
1607
|
-
readonly configuration: import("@jbrowse/
|
|
1608
|
-
setSubschema(slotName: string, data: Record<string, unknown>): any;
|
|
1609
|
-
setSlot(slotName: string, value: unknown): void;
|
|
1610
|
-
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>;
|
|
1602
|
+
readonly configuration: import("@jbrowse/core/configuration").ConfigNodeProps<any> & import("@jbrowse/core/configuration").ConfigNodeActions & import("@jbrowse/core/configuration").ConfigNodeBrand<import("@jbrowse/core/configuration").AnyConfigurationSchemaType>;
|
|
1611
1603
|
readonly adminMode: boolean;
|
|
1612
1604
|
readonly textSearchManager: import("@jbrowse/core/TextSearch/TextSearchManager").default;
|
|
1613
1605
|
} & {
|
|
@@ -1628,7 +1620,10 @@ export declare function TracksManagerSessionMixin(pluginManager: PluginManager):
|
|
|
1628
1620
|
clearSelection(): void;
|
|
1629
1621
|
setHovered(thing: unknown): void;
|
|
1630
1622
|
setHighlightsVisible(arg: boolean): void;
|
|
1631
|
-
|
|
1623
|
+
addHighlight(highlight: import("@jbrowse/core/util/highlights").HighlightType): void;
|
|
1624
|
+
removeHighlight(highlight: import("@jbrowse/core/util/highlights").HighlightType): void;
|
|
1625
|
+
updateHighlight(old: import("@jbrowse/core/util/highlights").HighlightType, updates: Partial<import("@jbrowse/core/util/highlights").HighlightType>): void;
|
|
1626
|
+
setHighlights(highlights: import("@jbrowse/core/util/highlights").HighlightType[]): void;
|
|
1632
1627
|
setPreferenceOverride(key: string, value: unknown): void;
|
|
1633
1628
|
clearPreferenceOverrides(): void;
|
|
1634
1629
|
clearPreferenceOverride(key: string): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes';
|
|
2
|
+
type TrackCopySnapshot = {
|
|
3
|
+
trackId: string;
|
|
4
|
+
name: string;
|
|
5
|
+
category?: unknown;
|
|
6
|
+
displays?: {
|
|
7
|
+
type: string;
|
|
8
|
+
displayId: string;
|
|
9
|
+
}[];
|
|
10
|
+
} & Record<string, unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Clone a track config for "Copy track": snapshots the config, appends a unique
|
|
13
|
+
* timestamp suffix to trackId (so it doesn't collide with the original), tags
|
|
14
|
+
* " (copy)" on the name, and regenerates each displayId to the canonical
|
|
15
|
+
* `${trackId}-${type}` form baseTrackConfig auto-injects — keeping them unique
|
|
16
|
+
* (displayId is a types.identifier, so a collision would crash MST).
|
|
17
|
+
*/
|
|
18
|
+
export declare function copyTrackSnapshot(config: BaseTrackConfig, opts: {
|
|
19
|
+
clearCategory: boolean;
|
|
20
|
+
}): TrackCopySnapshot;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getSnapshot, isStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
/**
|
|
3
|
+
* Clone a track config for "Copy track": snapshots the config, appends a unique
|
|
4
|
+
* timestamp suffix to trackId (so it doesn't collide with the original), tags
|
|
5
|
+
* " (copy)" on the name, and regenerates each displayId to the canonical
|
|
6
|
+
* `${trackId}-${type}` form baseTrackConfig auto-injects — keeping them unique
|
|
7
|
+
* (displayId is a types.identifier, so a collision would crash MST).
|
|
8
|
+
*/
|
|
9
|
+
export function copyTrackSnapshot(config, opts) {
|
|
10
|
+
const snap = structuredClone(isStateTreeNode(config) ? getSnapshot(config) : config);
|
|
11
|
+
snap.trackId += `-${Date.now()}`;
|
|
12
|
+
snap.name += ' (copy)';
|
|
13
|
+
if (opts.clearCategory) {
|
|
14
|
+
snap.category = undefined;
|
|
15
|
+
}
|
|
16
|
+
for (const d of snap.displays ?? []) {
|
|
17
|
+
d.displayId = `${snap.trackId}-${d.type}`;
|
|
18
|
+
}
|
|
19
|
+
return snap;
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AssemblySnapshot, TrackSnapshot } from '../sessionUtils.ts';
|
|
2
|
+
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
3
|
+
import type { IAnyType } from '@jbrowse/mobx-state-tree';
|
|
4
|
+
/**
|
|
5
|
+
* A config as its own schema writes it back: shorthand expanded, a stub per
|
|
6
|
+
* compatible display injected, every slot at its default left out. A
|
|
7
|
+
* track-config delta is only exact between two configs in this form, because a
|
|
8
|
+
* member one has and the other lacks then means a reset rather than two
|
|
9
|
+
* spellings of one config.
|
|
10
|
+
*/
|
|
11
|
+
export interface HydratedForms {
|
|
12
|
+
track: (conf: TrackSnapshot) => TrackSnapshot;
|
|
13
|
+
assembly: (conf: AssemblySnapshot) => AssemblySnapshot;
|
|
14
|
+
}
|
|
15
|
+
export declare function hydratedTrackForm(pluginManager: PluginManager): (conf: TrackSnapshot) => TrackSnapshot;
|
|
16
|
+
export declare function hydratedForms(pluginManager: PluginManager, assemblyConfigSchema: IAnyType): HydratedForms;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getSnapshot } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
function snapshotThrough(schema, pluginManager) {
|
|
3
|
+
return (conf) => getSnapshot(schema.create(conf, { pluginManager }));
|
|
4
|
+
}
|
|
5
|
+
export function hydratedTrackForm(pluginManager) {
|
|
6
|
+
return snapshotThrough(pluginManager.pluggableConfigSchemaType('track'), pluginManager);
|
|
7
|
+
}
|
|
8
|
+
export function hydratedForms(pluginManager, assemblyConfigSchema) {
|
|
9
|
+
return {
|
|
10
|
+
track: hydratedTrackForm(pluginManager),
|
|
11
|
+
assembly: snapshotThrough(assemblyConfigSchema, pluginManager),
|
|
12
|
+
};
|
|
13
|
+
}
|
package/esm/Session/index.d.ts
CHANGED
|
@@ -15,8 +15,12 @@ export { BaseSessionModel, isBaseSession, isSession } from './BaseSession.ts';
|
|
|
15
15
|
export type { BaseSession, BaseSessionType } from './BaseSession.ts';
|
|
16
16
|
export { SessionTracksManagerSessionMixin } from './SessionTracks.ts';
|
|
17
17
|
export type { EditableTrackConfig, PlainTrackConfig, SessionWithSessionTracks, SessionWithSessionTracksType, } from './SessionTracks.ts';
|
|
18
|
+
export { hydratedForms } from './hydratedForms.ts';
|
|
19
|
+
export type { HydratedForms } from './hydratedForms.ts';
|
|
18
20
|
export { bakeSessionCascades, getShareableSessionSnapshot, } from './shareableSnapshot.ts';
|
|
19
|
-
export { TrackMenuItemsSessionMixin, aboutTrackMenuItem,
|
|
21
|
+
export { TrackMenuItemsSessionMixin, aboutTrackMenuItem, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './TrackMenu.ts';
|
|
22
|
+
export { copyTrackSnapshot } from './copyTrackSnapshot.ts';
|
|
23
|
+
export { pluginExtraTrackItems } from './pluginExtraTrackItems.ts';
|
|
20
24
|
export { TrackMenuSessionMixin } from './TrackMenuSessionMixin.ts';
|
|
21
25
|
export { finalizeSession } from './finalizeSession.ts';
|
|
22
26
|
export type { AssertSessionModel } from './assertSessionModel.ts';
|
package/esm/Session/index.js
CHANGED
|
@@ -7,7 +7,10 @@ export { MultipleViewsSessionMixin, isSessionWithMultipleViews, } from './Multip
|
|
|
7
7
|
export { PreferencesSessionMixin } from './Preferences.js';
|
|
8
8
|
export { BaseSessionModel, isBaseSession, isSession } from './BaseSession.js';
|
|
9
9
|
export { SessionTracksManagerSessionMixin } from './SessionTracks.js';
|
|
10
|
+
export { hydratedForms } from './hydratedForms.js';
|
|
10
11
|
export { bakeSessionCascades, getShareableSessionSnapshot, } from './shareableSnapshot.js';
|
|
11
|
-
export { TrackMenuItemsSessionMixin, aboutTrackMenuItem,
|
|
12
|
+
export { TrackMenuItemsSessionMixin, aboutTrackMenuItem, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './TrackMenu.js';
|
|
13
|
+
export { copyTrackSnapshot } from './copyTrackSnapshot.js';
|
|
14
|
+
export { pluginExtraTrackItems } from './pluginExtraTrackItems.js';
|
|
12
15
|
export { TrackMenuSessionMixin } from './TrackMenuSessionMixin.js';
|
|
13
16
|
export { finalizeSession } from './finalizeSession.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SessionWithDialog } from './TrackMenu.ts';
|
|
2
|
+
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
3
|
+
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
4
|
+
import type { MenuItem } from '@jbrowse/core/ui';
|
|
5
|
+
import type { TrackActionView } from '@jbrowse/core/util/types';
|
|
6
|
+
/**
|
|
7
|
+
* plugin-contributed per-track items (`Core-extraTrackMenuItems`), surfaced in
|
|
8
|
+
* both the hierarchical selector and the in-view label menu so plugins reach
|
|
9
|
+
* every track menu consistently
|
|
10
|
+
*/
|
|
11
|
+
export declare function pluginExtraTrackItems(pluginManager: PluginManager, session: SessionWithDialog, config: AnyConfigurationModel, view?: TrackActionView): MenuItem[];
|