@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.
Files changed (53) hide show
  1. package/esm/RootModel/BaseRootModel.js +2 -1
  2. package/esm/RootModel/PreferencesConfig.d.ts +15 -0
  3. package/esm/RootModel/PreferencesConfig.js +15 -0
  4. package/esm/RootModel/createConfigModel.d.ts +8 -0
  5. package/esm/Session/BaseSession.d.ts +11 -26
  6. package/esm/Session/BaseSession.js +21 -60
  7. package/esm/Session/MultipleViews.d.ts +17 -3
  8. package/esm/Session/MultipleViews.js +45 -5
  9. package/esm/Session/Preferences.d.ts +2 -1
  10. package/esm/Session/Preferences.js +5 -0
  11. package/esm/Session/SessionTracks.d.ts +4 -1
  12. package/esm/Session/SessionTracks.js +8 -0
  13. package/esm/Session/TrackMenu.js +2 -2
  14. package/esm/Session/Tracks.d.ts +4 -5
  15. package/esm/Session/Tracks.js +115 -92
  16. package/esm/Session/developerMode.d.ts +7 -0
  17. package/esm/Session/developerMode.js +43 -0
  18. package/esm/Session/readdedTrackConf.d.ts +8 -0
  19. package/esm/Session/readdedTrackConf.js +25 -0
  20. package/esm/Session/temporaryAssemblyTracks.d.ts +4 -3
  21. package/esm/Session/temporaryAssemblyTracks.js +6 -7
  22. package/esm/controllerTracks.d.ts +3 -3
  23. package/esm/controllerTracks.js +17 -4
  24. package/esm/index.d.ts +2 -2
  25. package/esm/index.js +2 -2
  26. package/esm/loadPlugins.d.ts +1 -1
  27. package/esm/loadPlugins.js +6 -3
  28. package/esm/pruneUnbuildableNodes.js +5 -2
  29. package/esm/rpcWorker.js +5 -4
  30. package/esm/ui/AboutDialogContents.js +2 -1
  31. package/esm/ui/DescriptionPanel.d.ts +3 -0
  32. package/esm/ui/DescriptionPanel.js +24 -0
  33. package/esm/ui/DisplayDefaultsSection.d.ts +7 -20
  34. package/esm/ui/DisplayDefaultsSection.js +9 -47
  35. package/esm/ui/GeneralPreferencesTab.d.ts +14 -0
  36. package/esm/ui/GeneralPreferencesTab.js +27 -0
  37. package/esm/ui/PreferenceCheckbox.d.ts +6 -0
  38. package/esm/ui/PreferenceCheckbox.js +16 -0
  39. package/esm/ui/PreferencesDialog.d.ts +6 -27
  40. package/esm/ui/PreferencesDialog.js +38 -119
  41. package/esm/ui/ViewPreferencesTab.d.ts +12 -0
  42. package/esm/ui/ViewPreferencesTab.js +15 -0
  43. package/esm/ui/descriptionHtml.d.ts +26 -0
  44. package/esm/ui/descriptionHtml.js +66 -0
  45. package/esm/ui/displayDefaultChanges.d.ts +31 -0
  46. package/esm/ui/displayDefaultChanges.js +66 -0
  47. package/esm/ui/preferencesReset.d.ts +18 -0
  48. package/esm/ui/preferencesReset.js +64 -0
  49. package/esm/useEngineLifecycle.d.ts +7 -1
  50. package/esm/useEngineLifecycle.js +24 -2
  51. package/package.json +5 -4
  52. package/esm/scheduleDetachedDestroy.d.ts +0 -18
  53. 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 { useFinalUnmount } from '@jbrowse/core/util/hooks';
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.1",
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.3.1",
30
- "@mui/material": "^9.3.1",
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.1"
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
- }