@jbrowse/product-core 4.3.0 → 5.0.0-beta.1

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 (133) hide show
  1. package/esm/RootModel/BaseRootModel.d.ts +629 -304
  2. package/esm/RootModel/BaseRootModel.js +138 -14
  3. package/esm/RootModel/HierarchicalConfig.d.ts +57 -21
  4. package/esm/RootModel/HierarchicalConfig.js +36 -0
  5. package/esm/RootModel/InternetAccounts.d.ts +18 -1
  6. package/esm/RootModel/InternetAccounts.js +120 -22
  7. package/esm/RootModel/PreferencesConfig.d.ts +53 -0
  8. package/esm/RootModel/PreferencesConfig.js +61 -0
  9. package/esm/RootModel/createConfigModel.d.ts +232 -0
  10. package/esm/RootModel/createConfigModel.js +56 -0
  11. package/esm/RootModel/index.d.ts +10 -5
  12. package/esm/RootModel/index.js +10 -5
  13. package/esm/RootModel/menuItems.d.ts +24 -0
  14. package/esm/RootModel/menuItems.js +143 -0
  15. package/esm/Session/BaseSession.d.ts +310 -11
  16. package/esm/Session/BaseSession.js +448 -14
  17. package/esm/Session/Connections.d.ts +114 -8
  18. package/esm/Session/Connections.js +195 -74
  19. package/esm/Session/DrawerWidgets.d.ts +115 -12
  20. package/esm/Session/DrawerWidgets.js +161 -42
  21. package/esm/Session/MultipleViews.d.ts +1266 -1128
  22. package/esm/Session/MultipleViews.js +357 -66
  23. package/esm/Session/Preferences.d.ts +1665 -0
  24. package/esm/Session/Preferences.js +54 -0
  25. package/esm/Session/ReferenceManagement.d.ts +28 -3
  26. package/esm/Session/ReferenceManagement.js +56 -41
  27. package/esm/Session/SessionTracks.d.ts +1275 -1138
  28. package/esm/Session/SessionTracks.js +532 -35
  29. package/esm/Session/Themes.d.ts +87 -2
  30. package/esm/Session/Themes.js +156 -23
  31. package/esm/Session/TrackMenu.d.ts +112 -0
  32. package/esm/Session/TrackMenu.js +200 -0
  33. package/esm/Session/TrackMenuSessionMixin.d.ts +27 -0
  34. package/esm/Session/TrackMenuSessionMixin.js +41 -0
  35. package/esm/Session/Tracks.d.ts +1169 -1117
  36. package/esm/Session/Tracks.js +160 -20
  37. package/esm/Session/assertSessionModel.d.ts +21 -0
  38. package/esm/Session/assertSessionModel.js +1 -0
  39. package/esm/Session/finalizeSession.d.ts +16 -0
  40. package/esm/Session/finalizeSession.js +29 -0
  41. package/esm/Session/index.d.ts +22 -10
  42. package/esm/Session/index.js +13 -10
  43. package/esm/Session/shareableSnapshot.d.ts +77 -0
  44. package/esm/Session/shareableSnapshot.js +196 -0
  45. package/esm/Session/temporaryAssemblyTracks.d.ts +23 -0
  46. package/esm/Session/temporaryAssemblyTracks.js +38 -0
  47. package/esm/assertExtends.d.ts +55 -0
  48. package/esm/assertExtends.js +1 -0
  49. package/esm/controllerTracks.d.ts +56 -0
  50. package/esm/controllerTracks.js +77 -0
  51. package/esm/destroyViewState.d.ts +21 -0
  52. package/esm/destroyViewState.js +29 -0
  53. package/esm/index.d.ts +31 -4
  54. package/esm/index.js +31 -4
  55. package/esm/loadPlugins.d.ts +33 -0
  56. package/esm/loadPlugins.js +38 -0
  57. package/esm/localFiles.d.ts +74 -0
  58. package/esm/localFiles.js +156 -0
  59. package/esm/observeSession.d.ts +56 -0
  60. package/esm/observeSession.js +91 -0
  61. package/esm/pluginInput.d.ts +32 -0
  62. package/esm/pluginInput.js +19 -0
  63. package/esm/pruneUnbuildableNodes.d.ts +109 -0
  64. package/esm/pruneUnbuildableNodes.js +568 -0
  65. package/esm/resolveAssemblies.d.ts +44 -0
  66. package/esm/resolveAssemblies.js +55 -0
  67. package/esm/rpcWorker.d.ts +26 -0
  68. package/esm/rpcWorker.js +96 -15
  69. package/esm/scheduleDetachedDestroy.d.ts +18 -0
  70. package/esm/scheduleDetachedDestroy.js +24 -0
  71. package/esm/sessionMigrations/index.d.ts +53 -0
  72. package/esm/sessionMigrations/index.js +432 -0
  73. package/esm/sessionUrl.d.ts +41 -0
  74. package/esm/sessionUrl.js +53 -0
  75. package/esm/sessionUtils.d.ts +69 -0
  76. package/esm/sessionUtils.js +613 -0
  77. package/esm/siblingCast.d.ts +14 -0
  78. package/esm/siblingCast.js +16 -0
  79. package/esm/snapshotUtils.d.ts +8 -0
  80. package/esm/snapshotUtils.js +12 -0
  81. package/esm/ui/AboutDialog.d.ts +3 -6
  82. package/esm/ui/AboutDialog.js +4 -4
  83. package/esm/ui/AboutDialogContents.d.ts +2 -6
  84. package/esm/ui/AboutDialogContents.js +34 -13
  85. package/esm/ui/AssemblyInfoPanel.d.ts +5 -0
  86. package/esm/ui/AssemblyInfoPanel.js +69 -0
  87. package/esm/ui/DisplayDefaultsSection.d.ts +36 -0
  88. package/esm/ui/DisplayDefaultsSection.js +65 -0
  89. package/esm/ui/Drawer.d.ts +21 -0
  90. package/esm/ui/Drawer.js +60 -0
  91. package/esm/ui/DrawerControls.d.ts +5 -0
  92. package/esm/ui/DrawerControls.js +28 -0
  93. package/esm/ui/DrawerHeader.d.ts +6 -0
  94. package/esm/ui/DrawerHeader.js +36 -0
  95. package/esm/ui/DrawerWidget.d.ts +5 -0
  96. package/esm/ui/DrawerWidget.js +12 -0
  97. package/esm/ui/DrawerWidgetSelector.d.ts +5 -0
  98. package/esm/ui/DrawerWidgetSelector.js +40 -0
  99. package/esm/ui/FileInfoPanel.d.ts +3 -6
  100. package/esm/ui/FileInfoPanel.js +35 -26
  101. package/esm/ui/HeaderButtons.d.ts +7 -1
  102. package/esm/ui/HeaderButtons.js +23 -18
  103. package/esm/ui/ModalWidget.d.ts +12 -0
  104. package/esm/ui/ModalWidget.js +33 -0
  105. package/esm/ui/ModalWidgetAppBar.d.ts +8 -0
  106. package/esm/ui/ModalWidgetAppBar.js +9 -0
  107. package/esm/ui/PreferencesDialog.d.ts +56 -0
  108. package/esm/ui/PreferencesDialog.js +145 -0
  109. package/esm/ui/PreferencesResetDialog.d.ts +8 -0
  110. package/esm/ui/PreferencesResetDialog.js +19 -0
  111. package/esm/ui/RefNameAliasesDialog.d.ts +9 -0
  112. package/esm/ui/RefNameAliasesDialog.js +65 -0
  113. package/esm/ui/RefNameInfoDialog.d.ts +3 -6
  114. package/esm/ui/RefNameInfoDialog.js +57 -63
  115. package/esm/ui/WidgetBody.d.ts +18 -0
  116. package/esm/ui/WidgetBody.js +22 -0
  117. package/esm/ui/WidgetHeading.d.ts +7 -0
  118. package/esm/ui/WidgetHeading.js +7 -0
  119. package/esm/ui/drawerLayout.d.ts +18 -0
  120. package/esm/ui/drawerLayout.js +22 -0
  121. package/esm/ui/index.d.ts +13 -1
  122. package/esm/ui/index.js +12 -1
  123. package/esm/ui/util.d.ts +37 -4
  124. package/esm/ui/util.js +35 -38
  125. package/esm/useEngineLifecycle.d.ts +13 -0
  126. package/esm/useEngineLifecycle.js +22 -0
  127. package/package.json +11 -15
  128. package/esm/RootModel/FormatAbout.d.ts +0 -12
  129. package/esm/RootModel/FormatAbout.js +0 -15
  130. package/esm/RootModel/FormatDetails.d.ts +0 -24
  131. package/esm/RootModel/FormatDetails.js +0 -27
  132. package/esm/Session/DialogQueue.d.ts +0 -17
  133. package/esm/Session/DialogQueue.js +0 -31
@@ -0,0 +1,54 @@
1
+ import { localStorageGetItem, localStorageSetItem, setNumberGrouping, } from '@jbrowse/core/util';
2
+ import { freezeDeep } from '@jbrowse/core/util/freezeDeep';
3
+ import { addDisposer, types } from '@jbrowse/mobx-state-tree';
4
+ import { autorun } from 'mobx';
5
+ import { BaseSessionModel } from './BaseSession.js';
6
+ const PREFS_KEY = 'jbrowsePreferences';
7
+ function loadStoredPreferences() {
8
+ const stored = localStorageGetItem(PREFS_KEY);
9
+ let result = {};
10
+ if (stored) {
11
+ try {
12
+ const parsed = JSON.parse(stored);
13
+ if (typeof parsed === 'object' && parsed !== null) {
14
+ result = parsed;
15
+ }
16
+ }
17
+ catch {
18
+ // malformed localStorage value; keep empty defaults
19
+ }
20
+ }
21
+ return result;
22
+ }
23
+ /**
24
+ * #stateModel PreferencesSessionMixin
25
+ *
26
+ * loads and persists user-preference overrides (the BaseSession
27
+ * `preferencesOverrides` volatile) to localStorage. Compose into products that
28
+ * let users edit preferences (web, desktop); embedded sessions omit it and
29
+ * resolve preferences from `configuration.preferences` admin defaults only.
30
+ */
31
+ export function PreferencesSessionMixin(pluginManager) {
32
+ return types
33
+ .compose(BaseSessionModel(pluginManager), types.model({}))
34
+ .actions(self => ({
35
+ afterAttach() {
36
+ // the restore path bypasses `setPreferenceOverride`, so it freezes here
37
+ // too — a promoted default read back from localStorage is shared by
38
+ // reference exactly like a freshly set one
39
+ self.preferencesOverrides.replace(freezeDeep(loadStoredPreferences()));
40
+ // Applied once, here, rather than reactively: the same setting has to
41
+ // hold in the RPC workers (which format tooltip strings from jexl
42
+ // `mouseover` slots) and they only learn it at boot, so a live
43
+ // main-thread update would leave the app formatted two ways at once.
44
+ // The dialog says a reload is needed; this is where the reload lands.
45
+ setNumberGrouping(self.numberGrouping);
46
+ addDisposer(self, autorun(function persistPreferences() {
47
+ // observable.map doesn't JSON-serialize to an object on its own;
48
+ // fromEntries also reads every key so the autorun re-persists on
49
+ // any per-key change
50
+ localStorageSetItem(PREFS_KEY, JSON.stringify(Object.fromEntries(self.preferencesOverrides)));
51
+ }, { name: 'PreferencesOverrides' }));
52
+ },
53
+ }));
54
+ }
@@ -1,15 +1,40 @@
1
+ /** MST props, views, actions, etc related to managing connections */
1
2
  import type PluginManager from '@jbrowse/core/PluginManager';
2
- import type { BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes';
3
3
  import type { IAnyStateTreeNode, Instance } from '@jbrowse/mobx-state-tree';
4
4
  export interface ReferringNode {
5
5
  node: IAnyStateTreeNode;
6
6
  key: string;
7
7
  }
8
+ /**
9
+ * #stateModel ReferenceManagementSessionMixin
10
+ */
8
11
  export declare function ReferenceManagementSessionMixin(_pluginManager: PluginManager): import("@jbrowse/mobx-state-tree").IModelType<{}, {
9
- getReferring(object: IAnyStateTreeNode): ReferringNode[];
12
+ /**
13
+ * #method
14
+ * Walk the tree once and map each requested trackId to the nodes holding a
15
+ * `types.reference` that resolves to it (a view's track entry, a config
16
+ * editor widget). Track configs are matched by trackId, not identity, so a
17
+ * frozen base and its hydrated MST node compare equal.
18
+ */
19
+ getReferringMultiple(trackIds: string[]): Map<string, ReferringNode[]>;
10
20
  } & {
11
- removeReferring(referring: ReferringNode[], track: BaseTrackConfig, callbacks: ((arg: string) => void)[], dereferenceTypeCount: Record<string, number>): void;
21
+ /**
22
+ * #method
23
+ * The nodes currently referring to `trackId` (see getReferringMultiple).
24
+ */
25
+ getReferring(trackId: string): ReferringNode[];
26
+ } & {
27
+ /**
28
+ * #action
29
+ * Remove `trackId` from every view referring to it and close any config
30
+ * editor widget open on it. Runs immediately: the walk that produced
31
+ * `referring` has finished, so mutating those views here is safe.
32
+ */
33
+ dereferenceTrack(trackId: string, referring: ReferringNode[]): void;
12
34
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>;
35
+ /** Session mixin MST type for a session that manages multiple views */
13
36
  export type SessionWithReferenceManagementType = ReturnType<typeof ReferenceManagementSessionMixin>;
37
+ /** Instance of a session with MST reference management (`getReferring()`, `dereferenceTrack()`) */
14
38
  export type SessionWithReferenceManagement = Instance<SessionWithReferenceManagementType>;
39
+ /** Type guard for SessionWithReferenceManagement */
15
40
  export declare function isSessionWithReferenceManagement(thing: IAnyStateTreeNode): thing is SessionWithReferenceManagement;
@@ -1,73 +1,88 @@
1
+ /** MST props, views, actions, etc related to managing connections */
1
2
  import { getContainingView, isSessionModelWithWidgets, } from '@jbrowse/core/util';
2
3
  import { getMembers, getParent, getSnapshot, getType, isModelType, isReferenceType, types, walk, } from '@jbrowse/mobx-state-tree';
3
- import { isBaseSession } from "./BaseSession.js";
4
+ import { isBaseSession } from './BaseSession.js';
5
+ /**
6
+ * #stateModel ReferenceManagementSessionMixin
7
+ */
4
8
  export function ReferenceManagementSessionMixin(_pluginManager) {
5
9
  return types
6
10
  .model('ReferenceManagementSessionMixin', {})
7
11
  .views(self => ({
8
- getReferring(object) {
9
- const refs = [];
10
- const targetTrackId = object.trackId;
12
+ /**
13
+ * #method
14
+ * Walk the tree once and map each requested trackId to the nodes holding a
15
+ * `types.reference` that resolves to it (a view's track entry, a config
16
+ * editor widget). Track configs are matched by trackId, not identity, so a
17
+ * frozen base and its hydrated MST node compare equal.
18
+ */
19
+ getReferringMultiple(trackIds) {
20
+ const ids = new Set(trackIds);
21
+ const result = new Map();
22
+ if (ids.size === 0) {
23
+ return result;
24
+ }
11
25
  walk(getParent(self), node => {
12
26
  if (isModelType(getType(node))) {
13
- const members = getMembers(node);
14
- for (const [key, value] of Object.entries(members.properties)) {
27
+ for (const [key, value] of Object.entries(getMembers(node).properties)) {
15
28
  if (isReferenceType(value)) {
16
- const ref = node[key];
17
- const refTrackId = ref?.trackId;
18
- if (ref === object ||
19
- (targetTrackId && refTrackId && refTrackId === targetTrackId)) {
20
- refs.push({ node, key });
29
+ const id = node[key]?.trackId;
30
+ if (id !== undefined && ids.has(id)) {
31
+ const existing = result.get(id) ?? [];
32
+ existing.push({ node, key });
33
+ result.set(id, existing);
21
34
  }
22
35
  }
23
36
  }
24
37
  }
25
38
  });
26
- return refs;
39
+ return result;
40
+ },
41
+ }))
42
+ .views(self => ({
43
+ /**
44
+ * #method
45
+ * The nodes currently referring to `trackId` (see getReferringMultiple).
46
+ */
47
+ getReferring(trackId) {
48
+ return self.getReferringMultiple([trackId]).get(trackId) ?? [];
27
49
  },
28
50
  }))
29
51
  .actions(self => ({
30
- removeReferring(referring, track, callbacks, dereferenceTypeCount) {
52
+ /**
53
+ * #action
54
+ * Remove `trackId` from every view referring to it and close any config
55
+ * editor widget open on it. Runs immediately: the walk that produced
56
+ * `referring` has finished, so mutating those views here is safe.
57
+ */
58
+ dereferenceTrack(trackId, referring) {
31
59
  for (const { node } of referring) {
32
- let dereferenced = false;
60
+ let view;
33
61
  try {
34
- const type = 'open track(s)';
35
- const view = getContainingView(node);
36
- callbacks.push(() => {
37
- view.hideTrack(track.trackId);
38
- });
39
- dereferenced = true;
40
- if (!dereferenceTypeCount[type]) {
41
- dereferenceTypeCount[type] = 0;
42
- }
43
- dereferenceTypeCount[type] += 1;
62
+ view = getContainingView(node);
44
63
  }
45
- catch (err1) {
64
+ catch {
65
+ // node isn't contained in a view (e.g. it's a widget)
46
66
  }
47
- if (isSessionModelWithWidgets(self) && self.widgets.has(node.id)) {
48
- const type = 'configuration editor widget(s)';
49
- if (isSessionModelWithWidgets(self)) {
50
- callbacks.push(() => {
51
- self.hideWidget(node);
52
- });
53
- }
54
- dereferenced = true;
55
- if (!dereferenceTypeCount[type]) {
56
- dereferenceTypeCount[type] = 0;
57
- }
58
- dereferenceTypeCount[type] += 1;
67
+ const widget = isSessionModelWithWidgets(self) && self.widgets.has(node.id);
68
+ if (view) {
69
+ view.hideTrack(trackId);
70
+ }
71
+ else if (widget) {
72
+ self.hideWidget(node);
59
73
  }
60
- if (!dereferenced) {
61
- throw new Error(`Error when closing this connection, the following node is still referring to a track configuration: ${JSON.stringify(getSnapshot(node))}`);
74
+ else {
75
+ throw new Error(`node still refers to track ${trackId}: ${JSON.stringify(getSnapshot(node))}`);
62
76
  }
63
77
  }
64
78
  },
65
79
  }));
66
80
  }
81
+ /** Type guard for SessionWithReferenceManagement */
67
82
  export function isSessionWithReferenceManagement(thing) {
68
83
  return (isBaseSession(thing) &&
69
84
  'getReferring' in thing &&
70
85
  typeof thing.getReferring === 'function' &&
71
- 'removeReferring' in thing &&
72
- typeof thing.removeReferring === 'function');
86
+ 'dereferenceTrack' in thing &&
87
+ typeof thing.dereferenceTrack === 'function');
73
88
  }