@jbrowse/product-core 5.0.0-beta.1 → 5.0.0-beta.3
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.js +2 -1
- package/esm/RootModel/PreferencesConfig.d.ts +15 -0
- package/esm/RootModel/PreferencesConfig.js +15 -0
- package/esm/RootModel/createConfigModel.d.ts +8 -0
- package/esm/Session/BaseSession.d.ts +11 -26
- package/esm/Session/BaseSession.js +21 -60
- package/esm/Session/MultipleViews.d.ts +17 -3
- package/esm/Session/MultipleViews.js +45 -5
- package/esm/Session/Preferences.d.ts +2 -1
- package/esm/Session/Preferences.js +5 -0
- package/esm/Session/SessionTracks.d.ts +4 -1
- package/esm/Session/SessionTracks.js +8 -0
- package/esm/Session/TrackMenu.js +2 -2
- package/esm/Session/Tracks.d.ts +4 -5
- package/esm/Session/Tracks.js +115 -92
- package/esm/Session/developerMode.d.ts +7 -0
- package/esm/Session/developerMode.js +43 -0
- package/esm/Session/readdedTrackConf.d.ts +8 -0
- package/esm/Session/readdedTrackConf.js +25 -0
- package/esm/Session/temporaryAssemblyTracks.d.ts +4 -3
- package/esm/Session/temporaryAssemblyTracks.js +6 -7
- package/esm/controllerTracks.d.ts +3 -3
- package/esm/controllerTracks.js +17 -4
- package/esm/index.d.ts +2 -2
- package/esm/index.js +2 -2
- package/esm/loadPlugins.d.ts +1 -1
- package/esm/loadPlugins.js +6 -3
- package/esm/pruneUnbuildableNodes.js +5 -2
- package/esm/rpcWorker.js +5 -4
- package/esm/ui/AboutDialogContents.js +2 -1
- package/esm/ui/DescriptionPanel.d.ts +3 -0
- package/esm/ui/DescriptionPanel.js +24 -0
- package/esm/ui/DisplayDefaultsSection.d.ts +7 -20
- package/esm/ui/DisplayDefaultsSection.js +9 -47
- package/esm/ui/GeneralPreferencesTab.d.ts +14 -0
- package/esm/ui/GeneralPreferencesTab.js +27 -0
- package/esm/ui/PreferenceCheckbox.d.ts +6 -0
- package/esm/ui/PreferenceCheckbox.js +16 -0
- package/esm/ui/PreferencesDialog.d.ts +6 -27
- package/esm/ui/PreferencesDialog.js +38 -119
- package/esm/ui/ViewPreferencesTab.d.ts +12 -0
- package/esm/ui/ViewPreferencesTab.js +15 -0
- package/esm/ui/descriptionHtml.d.ts +26 -0
- package/esm/ui/descriptionHtml.js +66 -0
- package/esm/ui/displayDefaultChanges.d.ts +31 -0
- package/esm/ui/displayDefaultChanges.js +66 -0
- package/esm/ui/preferencesReset.d.ts +18 -0
- package/esm/ui/preferencesReset.js +64 -0
- package/esm/useEngineLifecycle.d.ts +7 -1
- package/esm/useEngineLifecycle.js +24 -2
- package/package.json +5 -4
- package/esm/scheduleDetachedDestroy.d.ts +0 -18
- package/esm/scheduleDetachedDestroy.js +0 -24
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DisplayDefaultsSession } from './displayDefaultChanges.ts';
|
|
2
|
+
import type PluginManager from '@jbrowse/core/PluginManager';
|
|
3
|
+
import type { TrackConfigChange } from '@jbrowse/core/util';
|
|
4
|
+
export interface ResettablePreferencesSession extends DisplayDefaultsSession {
|
|
5
|
+
themeName?: string;
|
|
6
|
+
setThemeName: (arg: string) => void;
|
|
7
|
+
stickyViewHeaders: boolean;
|
|
8
|
+
setStickyViewHeaders: (sticky: boolean) => void;
|
|
9
|
+
effectiveUseWorkspaces: boolean;
|
|
10
|
+
defaultUseWorkspaces: boolean;
|
|
11
|
+
resetUseWorkspaces: () => void;
|
|
12
|
+
clearPreferenceOverrides: () => void;
|
|
13
|
+
clearPreferenceOverride: (key: string) => void;
|
|
14
|
+
getPreferenceChanges: () => TrackConfigChange[];
|
|
15
|
+
}
|
|
16
|
+
export declare function collectPreferenceChanges(session: ResettablePreferencesSession, pluginManager: PluginManager): TrackConfigChange[];
|
|
17
|
+
export declare function resetAllPreferences(session: ResettablePreferencesSession): void;
|
|
18
|
+
export declare function resetPreferenceChange(session: ResettablePreferencesSession, change: TrackConfigChange): void;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { displayDefaultChanges, resetDisplayDefault, } from './displayDefaultChanges.js';
|
|
2
|
+
const NON_MAP_PREFERENCES = [
|
|
3
|
+
{
|
|
4
|
+
head: 'theme',
|
|
5
|
+
change: s => s.themeName && s.themeName !== 'default'
|
|
6
|
+
? { path: ['theme'], from: 'default', to: s.themeName }
|
|
7
|
+
: undefined,
|
|
8
|
+
reset: s => {
|
|
9
|
+
s.setThemeName('default');
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
head: 'stickyViewHeaders',
|
|
14
|
+
change: s => s.stickyViewHeaders
|
|
15
|
+
? undefined
|
|
16
|
+
: { path: ['stickyViewHeaders'], from: true, to: false },
|
|
17
|
+
reset: s => {
|
|
18
|
+
s.setStickyViewHeaders(true);
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
head: 'useWorkspaces',
|
|
23
|
+
change: s => s.effectiveUseWorkspaces === s.defaultUseWorkspaces
|
|
24
|
+
? undefined
|
|
25
|
+
: {
|
|
26
|
+
path: ['useWorkspaces'],
|
|
27
|
+
from: s.defaultUseWorkspaces,
|
|
28
|
+
to: s.effectiveUseWorkspaces,
|
|
29
|
+
},
|
|
30
|
+
reset: s => {
|
|
31
|
+
s.resetUseWorkspaces();
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
const NON_MAP_HEADS = new Set(NON_MAP_PREFERENCES.map(p => p.head));
|
|
36
|
+
// Everything "Reset to defaults" reverts, as rows: the scalar overrides in the
|
|
37
|
+
// preference map, the promoted display-type defaults (same map, listed through
|
|
38
|
+
// the builder the Display defaults section uses so both surfaces read alike),
|
|
39
|
+
// and the preferences held outside the map.
|
|
40
|
+
export function collectPreferenceChanges(session, pluginManager) {
|
|
41
|
+
return [
|
|
42
|
+
...session
|
|
43
|
+
.getPreferenceChanges()
|
|
44
|
+
.filter(c => !NON_MAP_HEADS.has(c.path[0])),
|
|
45
|
+
...displayDefaultChanges(session, pluginManager),
|
|
46
|
+
...NON_MAP_PREFERENCES.map(p => p.change(session)).filter(c => c !== undefined),
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
export function resetAllPreferences(session) {
|
|
50
|
+
session.clearPreferenceOverrides();
|
|
51
|
+
for (const p of NON_MAP_PREFERENCES) {
|
|
52
|
+
p.reset(session);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function resetPreferenceChange(session, change) {
|
|
56
|
+
const [head] = change.path;
|
|
57
|
+
const pref = NON_MAP_PREFERENCES.find(p => p.head === head);
|
|
58
|
+
if (pref) {
|
|
59
|
+
pref.reset(session);
|
|
60
|
+
}
|
|
61
|
+
else if (!resetDisplayDefault(session, change) && head) {
|
|
62
|
+
session.clearPreferenceOverride(head);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { EmbeddedRoot } from './destroyViewState.ts';
|
|
2
|
-
export { useCreateOnce } from '@jbrowse/core/util/hooks';
|
|
2
|
+
export { useCreateOnce, useCreateOnceAsync } from '@jbrowse/core/util/hooks';
|
|
3
|
+
/**
|
|
4
|
+
* Async `useCreateOnce` + `useDestroyOnUnmount`: undefined until the engine is
|
|
5
|
+
* ready. An engine resolving after the final unmount is destroyed on arrival
|
|
6
|
+
* instead of orphaning its worker pool and autoruns.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useAsyncEngineLifecycle<T extends EmbeddedRoot>(create: () => Promise<T>): T | undefined;
|
|
3
9
|
/**
|
|
4
10
|
* Destroy an engine when its component really unmounts — terminating its RPC
|
|
5
11
|
* worker threads and stopping its autoruns.
|
|
@@ -1,10 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import { useCreateOnceAsync, useFinalUnmount } from '@jbrowse/core/util/hooks';
|
|
2
3
|
import { destroyViewState } from './destroyViewState.js';
|
|
3
4
|
// `useCreateOnce` is core's, and is re-exported rather than wrapped: an engine
|
|
4
5
|
// is only the most expensive thing StrictMode's double-invoked state
|
|
5
6
|
// initializer can build twice, not the only one. The faceted track selector's
|
|
6
7
|
// MST model hit the same trap in a plugin, which cannot reach this package.
|
|
7
|
-
export { useCreateOnce } from '@jbrowse/core/util/hooks';
|
|
8
|
+
export { useCreateOnce, useCreateOnceAsync } from '@jbrowse/core/util/hooks';
|
|
9
|
+
/**
|
|
10
|
+
* Async `useCreateOnce` + `useDestroyOnUnmount`: undefined until the engine is
|
|
11
|
+
* ready. An engine resolving after the final unmount is destroyed on arrival
|
|
12
|
+
* instead of orphaning its worker pool and autoruns.
|
|
13
|
+
*/
|
|
14
|
+
export function useAsyncEngineLifecycle(create) {
|
|
15
|
+
const unmounted = useRef(false);
|
|
16
|
+
const engine = useCreateOnceAsync(() => create().then(built => {
|
|
17
|
+
if (unmounted.current) {
|
|
18
|
+
destroyViewState(built);
|
|
19
|
+
}
|
|
20
|
+
return built;
|
|
21
|
+
}));
|
|
22
|
+
useFinalUnmount(() => {
|
|
23
|
+
unmounted.current = true;
|
|
24
|
+
if (engine) {
|
|
25
|
+
destroyViewState(engine);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return engine;
|
|
29
|
+
}
|
|
8
30
|
/**
|
|
9
31
|
* Destroy an engine when its component really unmounts — terminating its RPC
|
|
10
32
|
* worker threads and stopping its autoruns.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/product-core",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "JBrowse 2 code shared between products but not used by plugins",
|
|
@@ -26,11 +26,12 @@
|
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@jbrowse/mobx-state-tree": "^6.5.1",
|
|
29
|
-
"@mui/icons-material": "^9.
|
|
30
|
-
"@mui/material": "^9.
|
|
29
|
+
"@mui/icons-material": "^9.4.0",
|
|
30
|
+
"@mui/material": "^9.4.0",
|
|
31
31
|
"mobx": "^7.0.3",
|
|
32
32
|
"mobx-react": "^10.0.2",
|
|
33
|
-
"@jbrowse/core": "^5.0.0-beta.
|
|
33
|
+
"@jbrowse/core": "^5.0.0-beta.3",
|
|
34
|
+
"@jbrowse/render-core": "^5.0.0-beta.3"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"react": ">=19.0.0",
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { IAnyStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
2
|
-
/**
|
|
3
|
-
* Free a tree an action has already let go of — a superseded session, a view
|
|
4
|
-
* taken out of one, a superseded rootModel the React host has detached.
|
|
5
|
-
*
|
|
6
|
-
* A task rather than a microtask: the wait is for React to unmount the
|
|
7
|
-
* components rendering it, which happens on the re-render that the action's own
|
|
8
|
-
* reactions schedule. Deferring is acceptable here, and is not elsewhere,
|
|
9
|
-
* because the node stays alive and detached until it fires — a late read gets a
|
|
10
|
-
* live tree nobody is rendering. ADR-069.
|
|
11
|
-
*
|
|
12
|
-
* The destroy itself is not optional. `beforeDestroy` is a plugin-facing
|
|
13
|
-
* contract (jbrowse-plugin-apollo aborts its in-flight fetches there) and core's
|
|
14
|
-
* `BaseTrackModel` releases the `rpcSessionId` claim that lets
|
|
15
|
-
* `CoreFreeResources` evict a parsed adapter from the worker — so detaching and
|
|
16
|
-
* forgetting would trade a console warning for an unbounded leak.
|
|
17
|
-
*/
|
|
18
|
-
export declare function scheduleDetachedDestroy(node: IAnyStateTreeNode): void;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { destroy, isAlive } from '@jbrowse/mobx-state-tree';
|
|
2
|
-
/**
|
|
3
|
-
* Free a tree an action has already let go of — a superseded session, a view
|
|
4
|
-
* taken out of one, a superseded rootModel the React host has detached.
|
|
5
|
-
*
|
|
6
|
-
* A task rather than a microtask: the wait is for React to unmount the
|
|
7
|
-
* components rendering it, which happens on the re-render that the action's own
|
|
8
|
-
* reactions schedule. Deferring is acceptable here, and is not elsewhere,
|
|
9
|
-
* because the node stays alive and detached until it fires — a late read gets a
|
|
10
|
-
* live tree nobody is rendering. ADR-069.
|
|
11
|
-
*
|
|
12
|
-
* The destroy itself is not optional. `beforeDestroy` is a plugin-facing
|
|
13
|
-
* contract (jbrowse-plugin-apollo aborts its in-flight fetches there) and core's
|
|
14
|
-
* `BaseTrackModel` releases the `rpcSessionId` claim that lets
|
|
15
|
-
* `CoreFreeResources` evict a parsed adapter from the worker — so detaching and
|
|
16
|
-
* forgetting would trade a console warning for an unbounded leak.
|
|
17
|
-
*/
|
|
18
|
-
export function scheduleDetachedDestroy(node) {
|
|
19
|
-
setTimeout(() => {
|
|
20
|
-
if (isAlive(node)) {
|
|
21
|
-
destroy(node);
|
|
22
|
-
}
|
|
23
|
-
}, 0);
|
|
24
|
-
}
|