@jbrowse/app-core 4.3.0 → 5.0.0-beta.10

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 (165) hide show
  1. package/esm/AppSession/AppRootModel.d.ts +30 -0
  2. package/esm/AppSession/AppRootModel.js +1 -0
  3. package/esm/AppSession/AppSessionMixin.d.ts +1324 -0
  4. package/esm/AppSession/AppSessionMixin.js +62 -0
  5. package/esm/AppSession/index.d.ts +2 -0
  6. package/esm/AppSession/index.js +1 -0
  7. package/esm/Assemblies/AssembliesMixin.d.ts +294 -0
  8. package/esm/Assemblies/AssembliesMixin.js +154 -0
  9. package/esm/Assemblies/index.d.ts +1 -2
  10. package/esm/Assemblies/index.js +1 -2
  11. package/esm/HistoryManagement/index.d.ts +11 -0
  12. package/esm/HistoryManagement/index.js +43 -10
  13. package/esm/JBrowseConfig/RootConfiguration.d.ts +123 -78
  14. package/esm/JBrowseConfig/RootConfiguration.js +79 -7
  15. package/esm/JBrowseConfig/defaultShareUrl.d.ts +1 -0
  16. package/esm/JBrowseConfig/defaultShareUrl.js +5 -0
  17. package/esm/JBrowseConfig/index.d.ts +175 -84
  18. package/esm/JBrowseConfig/index.js +64 -2
  19. package/esm/JBrowseModel/index.d.ts +175 -97
  20. package/esm/JBrowseModel/index.js +132 -31
  21. package/esm/JbApi/index.d.ts +2 -0
  22. package/esm/JbApi/index.js +1 -0
  23. package/esm/JbApi/jbApi.d.ts +2767 -0
  24. package/esm/JbApi/jbApi.js +1383 -0
  25. package/esm/RootMenu/index.d.ts +69 -3
  26. package/esm/RootMenu/index.js +96 -61
  27. package/esm/SessionSpec/index.d.ts +6 -0
  28. package/esm/SessionSpec/index.js +3 -0
  29. package/esm/SessionSpec/lgvUrlInit.d.ts +79 -0
  30. package/esm/SessionSpec/lgvUrlInit.js +161 -0
  31. package/esm/SessionSpec/loadSessionSpec.d.ts +75 -0
  32. package/esm/SessionSpec/loadSessionSpec.js +473 -0
  33. package/esm/SessionSpec/parseSessionSpecUrl.d.ts +7 -0
  34. package/esm/SessionSpec/parseSessionSpecUrl.js +181 -0
  35. package/esm/SessionSpec/types.d.ts +37 -0
  36. package/esm/SessionSpec/types.js +1 -0
  37. package/esm/WorkspaceLayout/LayoutRenderer.d.ts +24 -0
  38. package/esm/WorkspaceLayout/LayoutRenderer.js +185 -0
  39. package/esm/WorkspaceLayout/PanelView.d.ts +13 -0
  40. package/esm/WorkspaceLayout/PanelView.js +99 -0
  41. package/esm/WorkspaceLayout/TabStrip.d.ts +14 -0
  42. package/esm/WorkspaceLayout/TabStrip.js +226 -0
  43. package/esm/WorkspaceLayout/WorkspaceContainer.d.ts +16 -0
  44. package/esm/WorkspaceLayout/WorkspaceContainer.js +107 -0
  45. package/esm/WorkspaceLayout/WorkspacePanelActions.d.ts +24 -0
  46. package/esm/WorkspaceLayout/WorkspacePanelActions.js +120 -0
  47. package/esm/WorkspaceLayout/WorkspaceTab.d.ts +27 -0
  48. package/esm/WorkspaceLayout/WorkspaceTab.js +105 -0
  49. package/esm/WorkspaceLayout/dockviewTheme.d.ts +69 -0
  50. package/esm/WorkspaceLayout/dockviewTheme.js +82 -0
  51. package/esm/WorkspaceLayout/dropZone.d.ts +105 -0
  52. package/esm/WorkspaceLayout/dropZone.js +113 -0
  53. package/esm/WorkspaceLayout/index.d.ts +8 -0
  54. package/esm/WorkspaceLayout/index.js +4 -0
  55. package/esm/WorkspaceLayout/model.d.ts +260 -0
  56. package/esm/WorkspaceLayout/model.js +586 -0
  57. package/esm/WorkspaceLayout/panelChrome.d.ts +19 -0
  58. package/esm/WorkspaceLayout/panelChrome.js +4 -0
  59. package/esm/WorkspaceLayout/spec.d.ts +88 -0
  60. package/esm/WorkspaceLayout/spec.js +226 -0
  61. package/esm/WorkspaceLayout/splitter.d.ts +25 -0
  62. package/esm/WorkspaceLayout/splitter.js +37 -0
  63. package/esm/WorkspaceLayout/tree.d.ts +158 -0
  64. package/esm/WorkspaceLayout/tree.js +379 -0
  65. package/esm/WorkspaceLayout/useLayoutDrag.d.ts +34 -0
  66. package/esm/WorkspaceLayout/useLayoutDrag.js +232 -0
  67. package/esm/index.d.ts +18 -9
  68. package/esm/index.js +16 -9
  69. package/esm/menus.d.ts +55 -68
  70. package/esm/menus.js +117 -86
  71. package/esm/queryParams.d.ts +9 -0
  72. package/esm/queryParams.js +93 -0
  73. package/esm/sessionModelFactory.d.ts +18 -0
  74. package/esm/sessionModelFactory.js +1 -0
  75. package/esm/ui/App/App.d.ts +3 -14
  76. package/esm/ui/App/App.js +39 -19
  77. package/esm/ui/App/AppFab.d.ts +12 -3
  78. package/esm/ui/App/AppFab.js +15 -8
  79. package/esm/ui/App/AppToolbar.d.ts +2 -14
  80. package/esm/ui/App/AppToolbar.js +45 -31
  81. package/esm/ui/App/ClassicViewsContainer.d.ts +4 -10
  82. package/esm/ui/App/ClassicViewsContainer.js +9 -8
  83. package/esm/ui/App/DialogQueue.d.ts +17 -1
  84. package/esm/ui/App/DialogQueue.js +30 -1
  85. package/esm/ui/App/Drawer.d.ts +1 -1
  86. package/esm/ui/App/Drawer.js +10 -39
  87. package/esm/ui/App/DrawerHeader.d.ts +2 -3
  88. package/esm/ui/App/DrawerHeader.js +24 -11
  89. package/esm/ui/App/DrawerHeaderHelpButton.d.ts +1 -1
  90. package/esm/ui/App/DrawerHeaderHelpButton.js +3 -3
  91. package/esm/ui/App/DrawerHeaderHelpDialog.d.ts +2 -2
  92. package/esm/ui/App/DrawerHeaderHelpDialog.js +3 -4
  93. package/esm/ui/App/DrawerWidget.d.ts +1 -1
  94. package/esm/ui/App/DrawerWidget.js +9 -21
  95. package/esm/ui/App/JBrowseTabMenu.d.ts +2 -3
  96. package/esm/ui/App/JBrowseTabMenu.js +24 -5
  97. package/esm/ui/App/ThemeModeButton.d.ts +12 -0
  98. package/esm/ui/App/ThemeModeButton.js +34 -0
  99. package/esm/ui/App/ViewButtons.d.ts +2 -4
  100. package/esm/ui/App/ViewButtons.js +15 -3
  101. package/esm/ui/App/ViewContainer.d.ts +3 -2
  102. package/esm/ui/App/ViewContainer.js +128 -24
  103. package/esm/ui/App/ViewContainerTitle.d.ts +1 -1
  104. package/esm/ui/App/ViewContainerTitle.js +21 -11
  105. package/esm/ui/App/ViewErrorFallback.d.ts +18 -0
  106. package/esm/ui/App/ViewErrorFallback.js +42 -0
  107. package/esm/ui/App/ViewHeader.d.ts +3 -4
  108. package/esm/ui/App/ViewHeader.js +28 -17
  109. package/esm/ui/App/ViewLauncher.d.ts +2 -8
  110. package/esm/ui/App/ViewLauncher.js +7 -5
  111. package/esm/ui/App/ViewMenu.d.ts +3 -5
  112. package/esm/ui/App/ViewMenu.js +87 -92
  113. package/esm/ui/App/ViewStack.d.ts +7 -0
  114. package/esm/ui/App/ViewStack.js +48 -0
  115. package/esm/ui/App/ViewWrapper.d.ts +15 -1
  116. package/esm/ui/App/ViewWrapper.js +26 -10
  117. package/esm/ui/App/ViewsContainer.d.ts +4 -11
  118. package/esm/ui/App/ViewsContainer.js +6 -9
  119. package/esm/ui/App/index.d.ts +2 -1
  120. package/esm/ui/App/index.js +3 -2
  121. package/esm/ui/App/lazyChunk.d.ts +13 -0
  122. package/esm/ui/App/lazyChunk.js +91 -0
  123. package/esm/ui/App/lazyParts.d.ts +32 -0
  124. package/esm/ui/App/lazyParts.js +8 -0
  125. package/esm/ui/App/preloadAppShell.d.ts +14 -0
  126. package/esm/ui/App/preloadAppShell.js +41 -0
  127. package/esm/ui/App/types.d.ts +17 -3
  128. package/esm/ui/App/types.js +1 -1
  129. package/esm/ui/App/useViewVisibility.d.ts +35 -0
  130. package/esm/ui/App/useViewVisibility.js +88 -0
  131. package/esm/ui/App/viewTitle.d.ts +12 -0
  132. package/esm/ui/App/viewTitle.js +17 -0
  133. package/esm/ui/index.d.ts +1 -1
  134. package/esm/ui/index.js +1 -1
  135. package/package.json +12 -17
  136. package/esm/AppFocus/index.d.ts +0 -5
  137. package/esm/AppFocus/index.js +0 -12
  138. package/esm/Assemblies/SessionAssembliesMixin.d.ts +0 -92
  139. package/esm/Assemblies/SessionAssembliesMixin.js +0 -53
  140. package/esm/Assemblies/TemporaryAssembliesMixin.d.ts +0 -10
  141. package/esm/Assemblies/TemporaryAssembliesMixin.js +0 -37
  142. package/esm/DockviewLayout/index.d.ts +0 -35
  143. package/esm/DockviewLayout/index.js +0 -111
  144. package/esm/ui/App/DockviewContext.d.ts +0 -22
  145. package/esm/ui/App/DockviewContext.js +0 -29
  146. package/esm/ui/App/DockviewLeftHeaderActions.d.ts +0 -2
  147. package/esm/ui/App/DockviewLeftHeaderActions.js +0 -58
  148. package/esm/ui/App/DockviewRightHeaderActions.d.ts +0 -2
  149. package/esm/ui/App/DockviewRightHeaderActions.js +0 -100
  150. package/esm/ui/App/DrawerControls.d.ts +0 -5
  151. package/esm/ui/App/DrawerControls.js +0 -25
  152. package/esm/ui/App/DrawerWidgetSelector.d.ts +0 -5
  153. package/esm/ui/App/DrawerWidgetSelector.js +0 -47
  154. package/esm/ui/App/JBrowseViewPanel.d.ts +0 -8
  155. package/esm/ui/App/JBrowseViewPanel.js +0 -40
  156. package/esm/ui/App/JBrowseViewTab.d.ts +0 -8
  157. package/esm/ui/App/JBrowseViewTab.js +0 -97
  158. package/esm/ui/App/ModalWidget.d.ts +0 -6
  159. package/esm/ui/App/ModalWidget.js +0 -48
  160. package/esm/ui/App/TiledViewsContainer.d.ts +0 -6
  161. package/esm/ui/App/TiledViewsContainer.js +0 -366
  162. package/esm/ui/App/copyView.d.ts +0 -1
  163. package/esm/ui/App/copyView.js +0 -29
  164. package/esm/ui/App/dockviewUtils.d.ts +0 -46
  165. package/esm/ui/App/dockviewUtils.js +0 -55
@@ -1,13 +1,79 @@
1
- import type { Menu, MenuAction } from '../menus.ts';
2
- import type { MenuItem } from '@jbrowse/core/ui/Menu';
1
+ import type { MenuAction } from '../menus.ts';
2
+ import type { MenuItem } from '@jbrowse/core/ui/menuItems';
3
+ /**
4
+ * #stateModel RootAppMenuMixin
5
+ */
3
6
  export declare function RootAppMenuMixin(): import("@jbrowse/mobx-state-tree").IModelType<{}, {
4
7
  mutableMenuActions: MenuAction[];
5
8
  } & {
6
- setMenus(newMenus: Menu[]): void;
9
+ /**
10
+ * #action
11
+ * Add a top-level menu, if the app bar does not already have one with
12
+ * this name.
13
+ *
14
+ * @param menuName - Name of the menu to add.
15
+ */
7
16
  appendMenu(menuName: string): void;
17
+ /**
18
+ * #action
19
+ * Insert a top-level menu, if the app bar does not already have one
20
+ * with this name.
21
+ *
22
+ * @param menuName - Name of the menu to insert.
23
+ *
24
+ * @param position - Position to insert menu. If negative, counts from the
25
+ * end, e.g. `insertMenu('My Menu', -1)` will insert the menu as the
26
+ * second-to-last one.
27
+ */
8
28
  insertMenu(menuName: string, position: number): void;
29
+ /**
30
+ * #action
31
+ * Add a menu item to a top-level menu, creating the menu if it does not
32
+ * exist.
33
+ *
34
+ * @param menuName - Name of the top-level menu to append to.
35
+ *
36
+ * @param menuItem - Menu item to append.
37
+ */
9
38
  appendToMenu(menuName: string, menuItem: MenuItem): void;
39
+ /**
40
+ * #action
41
+ * Insert a menu item into a top-level menu, creating the menu if it
42
+ * does not exist.
43
+ *
44
+ * @param menuName - Name of the top-level menu to insert into
45
+ *
46
+ * @param menuItem - Menu item to insert
47
+ *
48
+ * @param position - Position to insert menu item. If negative, counts
49
+ * from the end, e.g. `insertInMenu('My Menu', item, -1)` will insert the
50
+ * item as the second-to-last one.
51
+ */
10
52
  insertInMenu(menuName: string, menuItem: MenuItem, position: number): void;
53
+ /**
54
+ * #action
55
+ * Add a menu item to a sub-menu, creating any part of the path that
56
+ * does not exist.
57
+ *
58
+ * @param menuPath - Path to the sub-menu to add to, starting with the
59
+ * top-level menu (e.g. `['File', 'Insert']`).
60
+ *
61
+ * @param menuItem - Menu item to append.
62
+ */
11
63
  appendToSubMenu(menuPath: string[], menuItem: MenuItem): void;
64
+ /**
65
+ * #action
66
+ * Insert a menu item into a sub-menu, creating any part of the path
67
+ * that does not exist.
68
+ *
69
+ * @param menuPath - Path to the sub-menu to add to, starting with the
70
+ * top-level menu (e.g. `['File', 'Insert']`).
71
+ *
72
+ * @param menuItem - Menu item to insert.
73
+ *
74
+ * @param position - Position to insert menu item. If negative, counts
75
+ * from the end, e.g. `insertInSubMenu(path, item, -1)` will insert the
76
+ * item as the second-to-last one.
77
+ */
12
78
  insertInSubMenu(menuPath: string[], menuItem: MenuItem, position: number): void;
13
79
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, import("@jbrowse/mobx-state-tree")._NotCustomized>;
@@ -1,71 +1,106 @@
1
1
  import { types } from '@jbrowse/mobx-state-tree';
2
+ /**
3
+ * #stateModel RootAppMenuMixin
4
+ */
2
5
  export function RootAppMenuMixin() {
3
6
  return types
4
7
  .model({})
5
8
  .volatile(() => ({
9
+ // array reference is replaced (not mutated) so MobX observers detect the change
6
10
  mutableMenuActions: [],
7
11
  }))
8
- .actions(self => ({
9
- setMenus(newMenus) {
10
- self.mutableMenuActions = [
11
- ...self.mutableMenuActions,
12
- { type: 'setMenus', newMenus },
13
- ];
14
- },
15
- appendMenu(menuName) {
16
- self.mutableMenuActions = [
17
- ...self.mutableMenuActions,
18
- { type: 'appendMenu', menuName },
19
- ];
20
- },
21
- insertMenu(menuName, position) {
22
- self.mutableMenuActions = [
23
- ...self.mutableMenuActions,
24
- {
25
- type: 'insertMenu',
26
- menuName,
27
- position,
28
- },
29
- ];
30
- },
31
- appendToMenu(menuName, menuItem) {
32
- self.mutableMenuActions = [
33
- ...self.mutableMenuActions,
34
- {
35
- type: 'appendToMenu',
36
- menuName,
37
- menuItem,
38
- },
39
- ];
40
- },
41
- insertInMenu(menuName, menuItem, position) {
42
- self.mutableMenuActions.push({
43
- type: 'insertInMenu',
44
- menuName,
45
- menuItem,
46
- position,
47
- });
48
- },
49
- appendToSubMenu(menuPath, menuItem) {
50
- self.mutableMenuActions = [
51
- ...self.mutableMenuActions,
52
- {
53
- type: 'appendToSubMenu',
54
- menuPath,
55
- menuItem,
56
- },
57
- ];
58
- },
59
- insertInSubMenu(menuPath, menuItem, position) {
60
- self.mutableMenuActions = [
61
- ...self.mutableMenuActions,
62
- {
63
- type: 'insertInSubMenu',
64
- menuPath,
12
+ .actions(self => {
13
+ function pushAction(action) {
14
+ self.mutableMenuActions = [...self.mutableMenuActions, action];
15
+ }
16
+ return {
17
+ /**
18
+ * #action
19
+ * Add a top-level menu, if the app bar does not already have one with
20
+ * this name.
21
+ *
22
+ * @param menuName - Name of the menu to add.
23
+ */
24
+ appendMenu(menuName) {
25
+ pushAction({ type: 'addMenu', menuName });
26
+ },
27
+ /**
28
+ * #action
29
+ * Insert a top-level menu, if the app bar does not already have one
30
+ * with this name.
31
+ *
32
+ * @param menuName - Name of the menu to insert.
33
+ *
34
+ * @param position - Position to insert menu. If negative, counts from the
35
+ * end, e.g. `insertMenu('My Menu', -1)` will insert the menu as the
36
+ * second-to-last one.
37
+ */
38
+ insertMenu(menuName, position) {
39
+ pushAction({ type: 'addMenu', menuName, position });
40
+ },
41
+ /**
42
+ * #action
43
+ * Add a menu item to a top-level menu, creating the menu if it does not
44
+ * exist.
45
+ *
46
+ * @param menuName - Name of the top-level menu to append to.
47
+ *
48
+ * @param menuItem - Menu item to append.
49
+ */
50
+ appendToMenu(menuName, menuItem) {
51
+ pushAction({ type: 'addItem', menuPath: [menuName], menuItem });
52
+ },
53
+ /**
54
+ * #action
55
+ * Insert a menu item into a top-level menu, creating the menu if it
56
+ * does not exist.
57
+ *
58
+ * @param menuName - Name of the top-level menu to insert into
59
+ *
60
+ * @param menuItem - Menu item to insert
61
+ *
62
+ * @param position - Position to insert menu item. If negative, counts
63
+ * from the end, e.g. `insertInMenu('My Menu', item, -1)` will insert the
64
+ * item as the second-to-last one.
65
+ */
66
+ insertInMenu(menuName, menuItem, position) {
67
+ pushAction({
68
+ type: 'addItem',
69
+ menuPath: [menuName],
65
70
  menuItem,
66
71
  position,
67
- },
68
- ];
69
- },
70
- }));
72
+ });
73
+ },
74
+ /**
75
+ * #action
76
+ * Add a menu item to a sub-menu, creating any part of the path that
77
+ * does not exist.
78
+ *
79
+ * @param menuPath - Path to the sub-menu to add to, starting with the
80
+ * top-level menu (e.g. `['File', 'Insert']`).
81
+ *
82
+ * @param menuItem - Menu item to append.
83
+ */
84
+ appendToSubMenu(menuPath, menuItem) {
85
+ pushAction({ type: 'addItem', menuPath, menuItem });
86
+ },
87
+ /**
88
+ * #action
89
+ * Insert a menu item into a sub-menu, creating any part of the path
90
+ * that does not exist.
91
+ *
92
+ * @param menuPath - Path to the sub-menu to add to, starting with the
93
+ * top-level menu (e.g. `['File', 'Insert']`).
94
+ *
95
+ * @param menuItem - Menu item to insert.
96
+ *
97
+ * @param position - Position to insert menu item. If negative, counts
98
+ * from the end, e.g. `insertInSubMenu(path, item, -1)` will insert the
99
+ * item as the second-to-last one.
100
+ */
101
+ insertInSubMenu(menuPath, menuItem, position) {
102
+ pushAction({ type: 'addItem', menuPath, menuItem, position });
103
+ },
104
+ };
105
+ });
71
106
  }
@@ -0,0 +1,6 @@
1
+ export { buildLgvInit, buildLgvInitFromParams, hubConnectionSpec, readHubUrlParam, readNavParam, readTracklistParam, shortHubLabel, splitHighlights, } from './lgvUrlInit.ts';
2
+ export { addSessionTracks, launchSpecView, launchableSpecView, loadSessionSpec, viewTypeProblem, } from './loadSessionSpec.ts';
3
+ export { parseSessionSpecUrl } from './parseSessionSpecUrl.ts';
4
+ export type { LgvUrlInit } from './lgvUrlInit.ts';
5
+ export type { ParsedSessionSpec } from './parseSessionSpecUrl.ts';
6
+ export type { LayoutNode, ViewSpec } from './types.ts';
@@ -0,0 +1,3 @@
1
+ export { buildLgvInit, buildLgvInitFromParams, hubConnectionSpec, readHubUrlParam, readNavParam, readTracklistParam, shortHubLabel, splitHighlights, } from './lgvUrlInit.js';
2
+ export { addSessionTracks, launchSpecView, launchableSpecView, loadSessionSpec, viewTypeProblem, } from './loadSessionSpec.js';
3
+ export { parseSessionSpecUrl } from './parseSessionSpecUrl.js';
@@ -0,0 +1,79 @@
1
+ export interface LgvUrlInit {
2
+ loc?: string;
3
+ assembly?: string;
4
+ tracks?: string[];
5
+ tracklist?: boolean;
6
+ nav?: boolean;
7
+ highlight?: string[];
8
+ displayedRegionNames?: string[];
9
+ }
10
+ export declare function splitHighlights(str: string): string[];
11
+ /**
12
+ * `&tracklist=` — only the literal `true` turns the track selector on.
13
+ *
14
+ * Absent stays absent rather than collapsing into the param's default:
15
+ * buildLgvInit's result is layered over a defaultSession's own pending init, so
16
+ * a `false` synthesized here would overwrite what that session set.
17
+ */
18
+ export declare function readTracklistParam(value: string | undefined): boolean | undefined;
19
+ /**
20
+ * `&nav=` — anything but the literal `false` leaves the navigation bar on.
21
+ *
22
+ * The opposite default to tracklist above, and deliberately so: the nav bar is
23
+ * on unless a link turns it off, the track selector is off unless a link turns
24
+ * it on. Absent stays absent for the same reason as tracklist.
25
+ */
26
+ export declare function readNavParam(value: string | undefined): boolean | undefined;
27
+ /**
28
+ * Normalizes already-decoded shorthand values into an LGV init.
29
+ *
30
+ * A param the URL omits is left off the result rather than set to undefined:
31
+ * jbrowse-web's applyDefaultSessionViewInit merges this over the view's own
32
+ * pending init, and a present-but-undefined key there would erase what the
33
+ * defaultSession set.
34
+ */
35
+ export declare function buildLgvInit(args: {
36
+ loc?: string;
37
+ tracks?: string;
38
+ assembly?: string;
39
+ tracklist?: boolean;
40
+ nav?: boolean;
41
+ highlight?: string;
42
+ regions?: string;
43
+ }): LgvUrlInit;
44
+ /**
45
+ * `&hubURL=` — a comma-separated list of hub.txt urls.
46
+ *
47
+ * Empty entries are dropped, so `&hubURL=` and `&hubURL=,,` are no hubs at all
48
+ * rather than a list of blanks. jbrowse-web learned that the hard way: a
49
+ * present-but-empty param is still truthy, which routed the load to a hub
50
+ * builder with no url to connect to and produced a session with nothing in it
51
+ * and no diagnostic.
52
+ */
53
+ export declare function readHubUrlParam(value: string | undefined): string[];
54
+ /**
55
+ * A short, readable label for a hub connection, before its hub.txt has been
56
+ * read: the second-to-last path segment, which for `…/myHub/hub.txt` is the
57
+ * hub's own directory. Beats showing the whole url in a track-selector category
58
+ * header.
59
+ */
60
+ export declare function shortHubLabel(url: string): string;
61
+ /**
62
+ * The `sessionConnections` entry for a hub url — the spec vocabulary for "attach
63
+ * this track hub", which loadSessionSpec registers before it launches any view.
64
+ */
65
+ export declare function hubConnectionSpec(url: string): {
66
+ type: string;
67
+ connectionId: string;
68
+ name: string;
69
+ hubTxtLocation: {
70
+ uri: string;
71
+ locationType: string;
72
+ };
73
+ };
74
+ /**
75
+ * The same init, read straight off a link's params. jbrowse-web decodes these
76
+ * into its loader's own properties first (they have to survive an HMR reload),
77
+ * so it calls buildLgvInit above; a caller holding a whole URL wants this.
78
+ */
79
+ export declare function buildLgvInitFromParams(params: URLSearchParams): LgvUrlInit;
@@ -0,0 +1,161 @@
1
+ import { parseRegionNames } from '@jbrowse/core/util';
2
+ // split a space-separated &highlight= URL param into individual highlights.
3
+ // spaces inside a JSON object ({...}) are not treated as delimiters, so a
4
+ // highlight like {"refName":"chr1","start":1,"end":2,"label":"my region"}
5
+ // survives intact alongside plain loc strings
6
+ export function splitHighlights(str) {
7
+ const out = [];
8
+ let depth = 0;
9
+ let cur = '';
10
+ for (const ch of str) {
11
+ if (ch === '{') {
12
+ depth++;
13
+ }
14
+ if (ch === '}') {
15
+ depth = Math.max(0, depth - 1);
16
+ }
17
+ if (ch === ' ' && depth === 0) {
18
+ if (cur) {
19
+ out.push(cur);
20
+ }
21
+ cur = '';
22
+ }
23
+ else {
24
+ cur += ch;
25
+ }
26
+ }
27
+ if (cur) {
28
+ out.push(cur);
29
+ }
30
+ return out;
31
+ }
32
+ /**
33
+ * `&tracklist=` — only the literal `true` turns the track selector on.
34
+ *
35
+ * Absent stays absent rather than collapsing into the param's default:
36
+ * buildLgvInit's result is layered over a defaultSession's own pending init, so
37
+ * a `false` synthesized here would overwrite what that session set.
38
+ */
39
+ export function readTracklistParam(value) {
40
+ return value === undefined ? undefined : value === 'true';
41
+ }
42
+ /**
43
+ * `&nav=` — anything but the literal `false` leaves the navigation bar on.
44
+ *
45
+ * The opposite default to tracklist above, and deliberately so: the nav bar is
46
+ * on unless a link turns it off, the track selector is off unless a link turns
47
+ * it on. Absent stays absent for the same reason as tracklist.
48
+ */
49
+ export function readNavParam(value) {
50
+ return value === undefined ? undefined : value !== 'false';
51
+ }
52
+ /**
53
+ * Normalizes already-decoded shorthand values into an LGV init.
54
+ *
55
+ * A param the URL omits is left off the result rather than set to undefined:
56
+ * jbrowse-web's applyDefaultSessionViewInit merges this over the view's own
57
+ * pending init, and a present-but-undefined key there would erase what the
58
+ * defaultSession set.
59
+ */
60
+ export function buildLgvInit(args) {
61
+ const { loc, tracks, assembly, tracklist, nav, highlight, regions } = args;
62
+ const init = {};
63
+ if (loc !== undefined) {
64
+ init.loc = loc;
65
+ }
66
+ if (assembly !== undefined) {
67
+ init.assembly = assembly;
68
+ }
69
+ // empty entries dropped, like `regions`: `&tracks=a,` asked for no track
70
+ // named ''
71
+ const trackIds = tracks?.split(',').filter(Boolean);
72
+ if (trackIds?.length) {
73
+ init.tracks = trackIds;
74
+ }
75
+ if (tracklist !== undefined) {
76
+ init.tracklist = tracklist;
77
+ }
78
+ if (nav !== undefined) {
79
+ init.nav = nav;
80
+ }
81
+ if (highlight !== undefined) {
82
+ init.highlight = splitHighlights(highlight);
83
+ }
84
+ if (regions !== undefined) {
85
+ // restrict a whole-genome view (no loc) to these named chromosomes, in
86
+ // order; resolved through assembly aliases in afterAttach's showNamedRegions
87
+ //
88
+ // Through core's parser, the same one the import forms' chromosome boxes
89
+ // use, rather than a bare split: this is one syntax with one meaning, and
90
+ // the second reading of it dropped `chr2` from `&regions=chr1,%20chr2`
91
+ // without a word. Empty entries go with it — a present-but-empty
92
+ // `&regions=` is still truthy, and the list of one empty name it used to
93
+ // produce reported itself as having matched nothing. Same trap as
94
+ // readHubUrlParam below.
95
+ const names = parseRegionNames(regions);
96
+ if (names.length) {
97
+ init.displayedRegionNames = names;
98
+ }
99
+ }
100
+ return init;
101
+ }
102
+ /**
103
+ * `&hubURL=` — a comma-separated list of hub.txt urls.
104
+ *
105
+ * Empty entries are dropped, so `&hubURL=` and `&hubURL=,,` are no hubs at all
106
+ * rather than a list of blanks. jbrowse-web learned that the hard way: a
107
+ * present-but-empty param is still truthy, which routed the load to a hub
108
+ * builder with no url to connect to and produced a session with nothing in it
109
+ * and no diagnostic.
110
+ */
111
+ export function readHubUrlParam(value) {
112
+ return value?.split(',').filter(Boolean) ?? [];
113
+ }
114
+ /**
115
+ * A short, readable label for a hub connection, before its hub.txt has been
116
+ * read: the second-to-last path segment, which for `…/myHub/hub.txt` is the
117
+ * hub's own directory. Beats showing the whole url in a track-selector category
118
+ * header.
119
+ */
120
+ export function shortHubLabel(url) {
121
+ try {
122
+ const segments = new URL(url).pathname.split('/').filter(Boolean);
123
+ return segments.at(-2) ?? segments.at(-1) ?? url;
124
+ }
125
+ catch {
126
+ return url;
127
+ }
128
+ }
129
+ /**
130
+ * The `sessionConnections` entry for a hub url — the spec vocabulary for "attach
131
+ * this track hub", which loadSessionSpec registers before it launches any view.
132
+ */
133
+ export function hubConnectionSpec(url) {
134
+ return {
135
+ type: 'UCSCTrackHubConnection',
136
+ connectionId: url,
137
+ name: shortHubLabel(url),
138
+ hubTxtLocation: { uri: url, locationType: 'UriLocation' },
139
+ };
140
+ }
141
+ // URLSearchParams.get returns null for an absent param, and every reader here
142
+ // distinguishes absent from present-and-empty
143
+ function read(params, key) {
144
+ return params.get(key) ?? undefined;
145
+ }
146
+ /**
147
+ * The same init, read straight off a link's params. jbrowse-web decodes these
148
+ * into its loader's own properties first (they have to survive an HMR reload),
149
+ * so it calls buildLgvInit above; a caller holding a whole URL wants this.
150
+ */
151
+ export function buildLgvInitFromParams(params) {
152
+ return buildLgvInit({
153
+ loc: read(params, 'loc'),
154
+ assembly: read(params, 'assembly'),
155
+ tracks: read(params, 'tracks'),
156
+ tracklist: readTracklistParam(read(params, 'tracklist')),
157
+ nav: readNavParam(read(params, 'nav')),
158
+ highlight: read(params, 'highlight'),
159
+ regions: read(params, 'regions'),
160
+ });
161
+ }
@@ -0,0 +1,75 @@
1
+ import type { LayoutNode, ViewSpec } from './types.ts';
2
+ import type PluginManager from '@jbrowse/core/PluginManager';
3
+ import type { AbstractSessionModel } from '@jbrowse/core/util';
4
+ /**
5
+ * Register `&sessionTracks=` / a spec's `sessionTracks` into a session.
6
+ *
7
+ * Exported because the hub launch needs it too and must not reimplement it.
8
+ *
9
+ * A track that fails to register does not cost the caller the rest of them —
10
+ * same reasoning as the per-connection and per-view try/catch around it, one
11
+ * layer down.
12
+ */
13
+ export declare function addSessionTracks(session: AbstractSessionModel | undefined, tracks: Record<string, unknown>[]): void;
14
+ /**
15
+ * Why one view type cannot launch from a spec here, or nothing. Two causes,
16
+ * two messages: the type is unknown at all (a typo, or a plugin that was not
17
+ * loaded), or it exists but nothing taught it how to launch from a spec, which
18
+ * only the view's plugin can fix.
19
+ */
20
+ export declare function viewTypeProblem(pluginManager: PluginManager, type: string): string | undefined;
21
+ /**
22
+ * A spec view entry as its launcher takes it, and what its type does not take.
23
+ *
24
+ * The same classification a view snapshot gets, run here because a spec never
25
+ * becomes one: `LaunchView-<type>` takes these keys as arguments, so
26
+ * `withLaunchInput`'s partition never sees them and nothing names a typo.
27
+ * `{type: 'LinearGenomeView', asembly: 'volvox'}` reported only the launcher's
28
+ * downstream "No assembly provided", on the one surface written by hand with no
29
+ * compiler and no editor behind it.
30
+ *
31
+ * A view type that registers no launch keys classifies nothing: its launcher's
32
+ * vocabulary is undeclared, so every argument would read as a typo. A lazily
33
+ * registered type declares its properties on a state model that is not loaded
34
+ * yet, so it is loaded first — the launch would have loaded it anyway.
35
+ */
36
+ export declare function launchableSpecView(pluginManager: PluginManager, spec: ViewSpec): Promise<{
37
+ view: ViewSpec;
38
+ problem?: string;
39
+ }>;
40
+ /**
41
+ * Launch one spec view into the session through its `LaunchView-<type>`
42
+ * extension point, the same door `loadSessionSpec` uses for each of its views
43
+ * — so `jb.addView` and a spec agree on what a view entry means, a
44
+ * ProteinView's `connectedView` included.
45
+ *
46
+ * Strict so a launch handler that throws (missing/invalid assembly, unresolved
47
+ * track, ...) is returned as a failure instead of being swallowed by the plain
48
+ * extension-point runner, which would leave a silent empty session. A handler
49
+ * that legitimately no-ops returns normally and is unaffected.
50
+ *
51
+ * `created` is EVERY view the launch added, in creation order: a connected
52
+ * ProteinView creates its genome view and then itself. `view` is the entry's
53
+ * own, the one of the spec's type, which is where `displayName` goes — it used
54
+ * to land on the genome view a ProteinView opened first, and the structure came
55
+ * up "Untitled view". `type` is the dispatch key, not a setting: forwarding it
56
+ * would land in the view's launch blob and trip the "ignored unknown key(s):
57
+ * type" warning meant to catch typos.
58
+ */
59
+ export declare function launchSpecView(session: AbstractSessionModel | undefined, pluginManager: PluginManager, spec: ViewSpec): Promise<{
60
+ created: import("@jbrowse/core/util").AbstractViewModel[];
61
+ view: import("@jbrowse/core/util").AbstractViewModel | undefined;
62
+ failure?: {
63
+ message: string;
64
+ cause: unknown;
65
+ } | undefined;
66
+ }>;
67
+ export interface SessionSpec {
68
+ views: ViewSpec[];
69
+ sessionAssemblies?: Record<string, unknown>[];
70
+ sessionConnections?: Record<string, unknown>[];
71
+ sessionTracks?: Record<string, unknown>[];
72
+ layout?: LayoutNode;
73
+ sessionName?: string;
74
+ }
75
+ export declare function loadSessionSpec(spec: SessionSpec, pluginManager: PluginManager): Promise<void>;