@jbrowse/product-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 (157) hide show
  1. package/esm/RootModel/BaseRootModel.d.ts +514 -323
  2. package/esm/RootModel/BaseRootModel.js +141 -14
  3. package/esm/RootModel/HierarchicalConfig.d.ts +30 -20
  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 +37 -0
  8. package/esm/RootModel/PreferencesConfig.js +75 -0
  9. package/esm/RootModel/createConfigModel.d.ts +257 -0
  10. package/esm/RootModel/createConfigModel.js +77 -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 +141 -0
  15. package/esm/Session/BaseSession.d.ts +285 -11
  16. package/esm/Session/BaseSession.js +383 -15
  17. package/esm/Session/Connections.d.ts +115 -8
  18. package/esm/Session/Connections.js +196 -74
  19. package/esm/Session/DrawerWidgets.d.ts +145 -13
  20. package/esm/Session/DrawerWidgets.js +219 -49
  21. package/esm/Session/MultipleViews.d.ts +1067 -1177
  22. package/esm/Session/MultipleViews.js +395 -64
  23. package/esm/Session/Preferences.d.ts +1389 -0
  24. package/esm/Session/Preferences.js +58 -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 +1101 -1180
  28. package/esm/Session/SessionTracks.js +584 -34
  29. package/esm/Session/Themes.d.ts +136 -2
  30. package/esm/Session/Themes.js +267 -21
  31. package/esm/Session/TrackMenu.d.ts +88 -0
  32. package/esm/Session/TrackMenu.js +175 -0
  33. package/esm/Session/TrackMenuSessionMixin.d.ts +27 -0
  34. package/esm/Session/TrackMenuSessionMixin.js +42 -0
  35. package/esm/Session/Tracks.d.ts +945 -1159
  36. package/esm/Session/Tracks.js +229 -30
  37. package/esm/Session/assertSessionModel.d.ts +21 -0
  38. package/esm/Session/assertSessionModel.js +1 -0
  39. package/esm/Session/copyTrackSnapshot.d.ts +21 -0
  40. package/esm/Session/copyTrackSnapshot.js +20 -0
  41. package/esm/Session/developerMode.d.ts +7 -0
  42. package/esm/Session/developerMode.js +43 -0
  43. package/esm/Session/finalizeSession.d.ts +15 -0
  44. package/esm/Session/finalizeSession.js +28 -0
  45. package/esm/Session/hydratedForms.d.ts +16 -0
  46. package/esm/Session/hydratedForms.js +13 -0
  47. package/esm/Session/index.d.ts +27 -10
  48. package/esm/Session/index.js +16 -10
  49. package/esm/Session/pluginExtraTrackItems.d.ts +11 -0
  50. package/esm/Session/pluginExtraTrackItems.js +13 -0
  51. package/esm/Session/readdedTrackConf.d.ts +8 -0
  52. package/esm/Session/readdedTrackConf.js +24 -0
  53. package/esm/Session/shareableSnapshot.d.ts +23 -0
  54. package/esm/Session/shareableSnapshot.js +66 -0
  55. package/esm/Session/temporaryAssemblyTracks.d.ts +24 -0
  56. package/esm/Session/temporaryAssemblyTracks.js +37 -0
  57. package/esm/assertExtends.d.ts +55 -0
  58. package/esm/assertExtends.js +1 -0
  59. package/esm/controllerTracks.d.ts +76 -0
  60. package/esm/controllerTracks.js +125 -0
  61. package/esm/destroyViewState.d.ts +21 -0
  62. package/esm/destroyViewState.js +29 -0
  63. package/esm/embeddedController.d.ts +57 -0
  64. package/esm/embeddedController.js +100 -0
  65. package/esm/index.d.ts +32 -4
  66. package/esm/index.js +31 -4
  67. package/esm/loadPlugins.d.ts +38 -0
  68. package/esm/loadPlugins.js +45 -0
  69. package/esm/localFiles.d.ts +74 -0
  70. package/esm/localFiles.js +156 -0
  71. package/esm/observeSession.d.ts +55 -0
  72. package/esm/observeSession.js +90 -0
  73. package/esm/parallelChunkLoading.d.ts +30 -0
  74. package/esm/parallelChunkLoading.js +71 -0
  75. package/esm/pluginInput.d.ts +32 -0
  76. package/esm/pluginInput.js +19 -0
  77. package/esm/pruneUnbuildableNodes.d.ts +109 -0
  78. package/esm/pruneUnbuildableNodes.js +562 -0
  79. package/esm/resolveAssemblies.d.ts +68 -0
  80. package/esm/resolveAssemblies.js +77 -0
  81. package/esm/rpcWorker.d.ts +36 -4
  82. package/esm/rpcWorker.js +126 -20
  83. package/esm/sessionMigrations/index.d.ts +15 -0
  84. package/esm/sessionMigrations/index.js +178 -0
  85. package/esm/sessionUrl.d.ts +40 -0
  86. package/esm/sessionUrl.js +66 -0
  87. package/esm/sessionUtils.d.ts +74 -0
  88. package/esm/sessionUtils.js +599 -0
  89. package/esm/siblingCast.d.ts +14 -0
  90. package/esm/siblingCast.js +16 -0
  91. package/esm/snapshotUtils.d.ts +8 -0
  92. package/esm/snapshotUtils.js +12 -0
  93. package/esm/ui/AboutDialog.d.ts +8 -3
  94. package/esm/ui/AboutDialog.js +14 -5
  95. package/esm/ui/AboutDialogContents.d.ts +2 -6
  96. package/esm/ui/AboutDialogContents.js +13 -17
  97. package/esm/ui/AssemblyInfoPanel.d.ts +5 -0
  98. package/esm/ui/AssemblyInfoPanel.js +63 -0
  99. package/esm/ui/DescriptionPanel.d.ts +3 -0
  100. package/esm/ui/DescriptionPanel.js +25 -0
  101. package/esm/ui/Drawer.d.ts +21 -0
  102. package/esm/ui/Drawer.js +60 -0
  103. package/esm/ui/DrawerControls.d.ts +5 -0
  104. package/esm/ui/DrawerControls.js +28 -0
  105. package/esm/ui/DrawerHeader.d.ts +6 -0
  106. package/esm/ui/DrawerHeader.js +36 -0
  107. package/esm/ui/DrawerWidget.d.ts +5 -0
  108. package/esm/ui/DrawerWidget.js +12 -0
  109. package/esm/ui/DrawerWidgetSelector.d.ts +5 -0
  110. package/esm/ui/DrawerWidgetSelector.js +40 -0
  111. package/esm/ui/FileInfoPanel.d.ts +3 -6
  112. package/esm/ui/FileInfoPanel.js +36 -26
  113. package/esm/ui/GeneralPreferencesTab.d.ts +17 -0
  114. package/esm/ui/GeneralPreferencesTab.js +34 -0
  115. package/esm/ui/HeaderButtons.d.ts +2 -1
  116. package/esm/ui/HeaderButtons.js +15 -17
  117. package/esm/ui/ModalWidget.d.ts +13 -0
  118. package/esm/ui/ModalWidget.js +48 -0
  119. package/esm/ui/ModalWidgetAppBar.d.ts +8 -0
  120. package/esm/ui/ModalWidgetAppBar.js +9 -0
  121. package/esm/ui/PreferenceCheckbox.d.ts +6 -0
  122. package/esm/ui/PreferenceCheckbox.js +16 -0
  123. package/esm/ui/PreferencesDialog.d.ts +34 -0
  124. package/esm/ui/PreferencesDialog.js +55 -0
  125. package/esm/ui/PreferencesResetDialog.d.ts +8 -0
  126. package/esm/ui/PreferencesResetDialog.js +19 -0
  127. package/esm/ui/RefNameAliasesDialog.d.ts +9 -0
  128. package/esm/ui/RefNameAliasesDialog.js +65 -0
  129. package/esm/ui/RefNameInfoDialog.d.ts +3 -6
  130. package/esm/ui/RefNameInfoDialog.js +45 -63
  131. package/esm/ui/ViewPreferencesTab.d.ts +12 -0
  132. package/esm/ui/ViewPreferencesTab.js +15 -0
  133. package/esm/ui/WidgetBody.d.ts +18 -0
  134. package/esm/ui/WidgetBody.js +22 -0
  135. package/esm/ui/WidgetHeading.d.ts +7 -0
  136. package/esm/ui/WidgetHeading.js +7 -0
  137. package/esm/ui/aboutTestUtils.d.ts +140 -0
  138. package/esm/ui/aboutTestUtils.js +25 -0
  139. package/esm/ui/descriptionHtml.d.ts +25 -0
  140. package/esm/ui/descriptionHtml.js +64 -0
  141. package/esm/ui/drawerLayout.d.ts +18 -0
  142. package/esm/ui/drawerLayout.js +22 -0
  143. package/esm/ui/index.d.ts +15 -1
  144. package/esm/ui/index.js +13 -1
  145. package/esm/ui/preferencesReset.d.ts +18 -0
  146. package/esm/ui/preferencesReset.js +69 -0
  147. package/esm/ui/util.d.ts +22 -7
  148. package/esm/ui/util.js +19 -41
  149. package/esm/useEngineLifecycle.d.ts +19 -0
  150. package/esm/useEngineLifecycle.js +44 -0
  151. package/package.json +15 -18
  152. package/esm/RootModel/FormatAbout.d.ts +0 -12
  153. package/esm/RootModel/FormatAbout.js +0 -15
  154. package/esm/RootModel/FormatDetails.d.ts +0 -24
  155. package/esm/RootModel/FormatDetails.js +0 -27
  156. package/esm/Session/DialogQueue.d.ts +0 -17
  157. package/esm/Session/DialogQueue.js +0 -31
@@ -0,0 +1,140 @@
1
+ import PluginManager from '@jbrowse/core/PluginManager';
2
+ import type { SnapshotIn } from '@jbrowse/mobx-state-tree';
3
+ export declare const aboutTestPluginManager: PluginManager;
4
+ export declare const TestTrackConf: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
5
+ readonly name: {
6
+ type: "string";
7
+ } & {
8
+ defaultValue: string;
9
+ };
10
+ readonly assemblyNames: {
11
+ type: "stringArray";
12
+ } & {
13
+ defaultValue: unknown;
14
+ };
15
+ readonly adapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
16
+ readonly type: {
17
+ type: "string";
18
+ } & {
19
+ defaultValue: string;
20
+ };
21
+ readonly bamLocation: {
22
+ type: "fileLocation";
23
+ } & {
24
+ defaultValue: unknown;
25
+ };
26
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
27
+ readonly metadata: {
28
+ type: "frozen";
29
+ } & {
30
+ defaultValue: unknown;
31
+ };
32
+ readonly formatAbout: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
33
+ readonly config: {
34
+ type: "frozen";
35
+ } & {
36
+ defaultValue: unknown;
37
+ };
38
+ readonly hideUris: {
39
+ type: "boolean";
40
+ } & {
41
+ defaultValue: boolean;
42
+ };
43
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
44
+ trackId: {
45
+ type: "string";
46
+ } & {
47
+ defaultValue: string;
48
+ };
49
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "trackId", undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
50
+ export declare function makeTrackConf(snapshot: SnapshotIn<typeof TestTrackConf>): import("@jbrowse/core/configuration").ConfigNodeProps<{
51
+ readonly name: {
52
+ type: "string";
53
+ } & {
54
+ defaultValue: string;
55
+ };
56
+ readonly assemblyNames: {
57
+ type: "stringArray";
58
+ } & {
59
+ defaultValue: unknown;
60
+ };
61
+ readonly adapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
62
+ readonly type: {
63
+ type: "string";
64
+ } & {
65
+ defaultValue: string;
66
+ };
67
+ readonly bamLocation: {
68
+ type: "fileLocation";
69
+ } & {
70
+ defaultValue: unknown;
71
+ };
72
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
73
+ readonly metadata: {
74
+ type: "frozen";
75
+ } & {
76
+ defaultValue: unknown;
77
+ };
78
+ readonly formatAbout: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
79
+ readonly config: {
80
+ type: "frozen";
81
+ } & {
82
+ defaultValue: unknown;
83
+ };
84
+ readonly hideUris: {
85
+ type: "boolean";
86
+ } & {
87
+ defaultValue: boolean;
88
+ };
89
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
90
+ trackId: {
91
+ type: "string";
92
+ } & {
93
+ defaultValue: string;
94
+ };
95
+ }> & import("@jbrowse/core/configuration").ConfigNodeActions & import("@jbrowse/core/configuration").ConfigNodeBrand<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
96
+ readonly name: {
97
+ type: "string";
98
+ } & {
99
+ defaultValue: string;
100
+ };
101
+ readonly assemblyNames: {
102
+ type: "stringArray";
103
+ } & {
104
+ defaultValue: unknown;
105
+ };
106
+ readonly adapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
107
+ readonly type: {
108
+ type: "string";
109
+ } & {
110
+ defaultValue: string;
111
+ };
112
+ readonly bamLocation: {
113
+ type: "fileLocation";
114
+ } & {
115
+ defaultValue: unknown;
116
+ };
117
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
118
+ readonly metadata: {
119
+ type: "frozen";
120
+ } & {
121
+ defaultValue: unknown;
122
+ };
123
+ readonly formatAbout: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
124
+ readonly config: {
125
+ type: "frozen";
126
+ } & {
127
+ defaultValue: unknown;
128
+ };
129
+ readonly hideUris: {
130
+ type: "boolean";
131
+ } & {
132
+ defaultValue: boolean;
133
+ };
134
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
135
+ trackId: {
136
+ type: "string";
137
+ } & {
138
+ defaultValue: string;
139
+ };
140
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "trackId", undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>>;
@@ -0,0 +1,25 @@
1
+ import PluginManager from '@jbrowse/core/PluginManager';
2
+ import { ConfigurationSchema, FormatAboutConfigSchemaFactory, } from '@jbrowse/core/configuration';
3
+ // a real PluginManager provides the jexl instance a callback slot evaluates with
4
+ export const aboutTestPluginManager = new PluginManager([]).createPluggableElements();
5
+ aboutTestPluginManager.configure();
6
+ // the slots the About dialog reads off a track config, without registering a
7
+ // track type to get them
8
+ export const TestTrackConf = ConfigurationSchema('TestTrack', {
9
+ name: { type: 'string', defaultValue: '' },
10
+ assemblyNames: { type: 'stringArray', defaultValue: [] },
11
+ adapter: ConfigurationSchema('TestAdapter', {
12
+ type: { type: 'string', defaultValue: 'TestAdapter' },
13
+ bamLocation: {
14
+ type: 'fileLocation',
15
+ defaultValue: { uri: '', locationType: 'UriLocation' },
16
+ },
17
+ }),
18
+ metadata: { type: 'frozen', defaultValue: {} },
19
+ formatAbout: FormatAboutConfigSchemaFactory(),
20
+ }, { explicitIdentifier: 'trackId' });
21
+ export function makeTrackConf(snapshot) {
22
+ return TestTrackConf.create(snapshot, {
23
+ pluginManager: aboutTestPluginManager,
24
+ });
25
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The URL of a track's prose description page in its `metadata`, as a UCSC
3
+ * track hub supplies it, and undefined for anything that is not an http(s) url
4
+ * — the value reaches `openLocation` and an anchor's href, so a `javascript:`
5
+ * or `file://` one does not become one here.
6
+ *
7
+ * Four spellings: `UCSCTrackHubConnection` spreads the trackDb stanza across
8
+ * `metadata`, the bulk converter behind genomes.jbrowse.org nests it under
9
+ * `metadata.ucsc` (~50,700 configs at permanent URLs), and the stanza key is
10
+ * `html` for a track and `htmlPath` for an assembly. Both producers write an
11
+ * escaped anchor rather than a bare url, so the href comes back through a parse
12
+ * rather than a regex.
13
+ */
14
+ export declare function getDescriptionHtmlUrl(metadata: unknown): string | undefined;
15
+ /**
16
+ * A fetched description page as markup for `SanitizedHTML`: links and images
17
+ * resolved against the page they came from rather than the JBrowse origin, and
18
+ * `<form>` dropped, which the sanitizer keeps and which in a document off a
19
+ * third-party origin is a credential prompt wearing the app's own chrome.
20
+ *
21
+ * Parsing rather than string-rewriting is what makes taking `body` handle the
22
+ * pages that are whole documents in the same pass. The parse is inert — no
23
+ * scripts run, no images load — and the sanitizer still sees everything after.
24
+ */
25
+ export declare function rebaseDescriptionHtml(html: string, baseUrl: string): string;
@@ -0,0 +1,64 @@
1
+ function isRecord(value) {
2
+ return typeof value === 'object' && value !== null;
3
+ }
4
+ function descriptionUrl(value) {
5
+ const href = new DOMParser()
6
+ .parseFromString(value, 'text/html')
7
+ .querySelector('a[href]')
8
+ ?.getAttribute('href');
9
+ const candidate = typeof href === 'string' ? href : value.trim();
10
+ return /^https?:\/\//i.test(candidate) ? candidate : undefined;
11
+ }
12
+ /**
13
+ * The URL of a track's prose description page in its `metadata`, as a UCSC
14
+ * track hub supplies it, and undefined for anything that is not an http(s) url
15
+ * — the value reaches `openLocation` and an anchor's href, so a `javascript:`
16
+ * or `file://` one does not become one here.
17
+ *
18
+ * Four spellings: `UCSCTrackHubConnection` spreads the trackDb stanza across
19
+ * `metadata`, the bulk converter behind genomes.jbrowse.org nests it under
20
+ * `metadata.ucsc` (~50,700 configs at permanent URLs), and the stanza key is
21
+ * `html` for a track and `htmlPath` for an assembly. Both producers write an
22
+ * escaped anchor rather than a bare url, so the href comes back through a parse
23
+ * rather than a regex.
24
+ */
25
+ export function getDescriptionHtmlUrl(metadata) {
26
+ return [metadata, isRecord(metadata) ? metadata.ucsc : undefined]
27
+ .flatMap(record => (isRecord(record) ? [record.html, record.htmlPath] : []))
28
+ .filter(candidate => typeof candidate === 'string')
29
+ .map(candidate => descriptionUrl(candidate))
30
+ .find(url => url !== undefined);
31
+ }
32
+ function absolute(value, baseUrl) {
33
+ try {
34
+ return new URL(value, baseUrl).href;
35
+ }
36
+ catch {
37
+ return value;
38
+ }
39
+ }
40
+ /**
41
+ * A fetched description page as markup for `SanitizedHTML`: links and images
42
+ * resolved against the page they came from rather than the JBrowse origin, and
43
+ * `<form>` dropped, which the sanitizer keeps and which in a document off a
44
+ * third-party origin is a credential prompt wearing the app's own chrome.
45
+ *
46
+ * Parsing rather than string-rewriting is what makes taking `body` handle the
47
+ * pages that are whole documents in the same pass. The parse is inert — no
48
+ * scripts run, no images load — and the sanitizer still sees everything after.
49
+ */
50
+ export function rebaseDescriptionHtml(html, baseUrl) {
51
+ const doc = new DOMParser().parseFromString(html, 'text/html');
52
+ for (const form of doc.querySelectorAll('form')) {
53
+ form.remove();
54
+ }
55
+ for (const el of doc.querySelectorAll('[href], [src]')) {
56
+ for (const attribute of ['href', 'src']) {
57
+ const value = el.getAttribute(attribute);
58
+ if (value) {
59
+ el.setAttribute(attribute, absolute(value, baseUrl));
60
+ }
61
+ }
62
+ }
63
+ return doc.body.innerHTML;
64
+ }
@@ -0,0 +1,18 @@
1
+ import type { DrawerPosition } from '@jbrowse/core/util/types';
2
+ /**
3
+ * CSS `grid-template-columns` for a main content area with an optional drawer
4
+ * widget on the left or right. Shared by the app shell (`App.tsx`) and the
5
+ * embedded views so the drawer positioning stays identical across products.
6
+ *
7
+ * The `[main]`/`[drawer]` line names are the whole interface: a host renders
8
+ * the main container and the drawer once each, in any order, and each takes
9
+ * its column by name. Placing them by DOM order instead means the host has to
10
+ * render the drawer twice — once on each side, under opposite conditions — and
11
+ * any other in-flow child auto-placed between them lands in a column meant for
12
+ * one of the two.
13
+ */
14
+ export declare function drawerGridTemplateColumns({ drawerVisible, drawerPosition, drawerWidth, }: {
15
+ drawerVisible: boolean;
16
+ drawerPosition: DrawerPosition;
17
+ drawerWidth: number;
18
+ }): string;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * CSS `grid-template-columns` for a main content area with an optional drawer
3
+ * widget on the left or right. Shared by the app shell (`App.tsx`) and the
4
+ * embedded views so the drawer positioning stays identical across products.
5
+ *
6
+ * The `[main]`/`[drawer]` line names are the whole interface: a host renders
7
+ * the main container and the drawer once each, in any order, and each takes
8
+ * its column by name. Placing them by DOM order instead means the host has to
9
+ * render the drawer twice — once on each side, under opposite conditions — and
10
+ * any other in-flow child auto-placed between them lands in a column meant for
11
+ * one of the two.
12
+ */
13
+ export function drawerGridTemplateColumns({ drawerVisible, drawerPosition, drawerWidth, }) {
14
+ const main = '[main] minmax(0, 1fr)';
15
+ if (drawerVisible) {
16
+ const drawer = `[drawer] ${drawerWidth}px`;
17
+ return drawerPosition === 'right'
18
+ ? `${main} ${drawer}`
19
+ : `${drawer} ${main}`;
20
+ }
21
+ return main;
22
+ }
package/esm/ui/index.d.ts CHANGED
@@ -1 +1,15 @@
1
- export * from './AboutDialog.tsx';
1
+ export { default as AppReadyMarker } from '@jbrowse/core/ui/AppReadyMarker';
2
+ export { default as AboutDialog } from './AboutDialog.tsx';
3
+ export type { AboutPanelProps } from './util.ts';
4
+ export { default as Drawer } from './Drawer.tsx';
5
+ export { default as DrawerControls } from './DrawerControls.tsx';
6
+ export { default as DrawerHeader } from './DrawerHeader.tsx';
7
+ export { default as DrawerWidget } from './DrawerWidget.tsx';
8
+ export { default as DrawerWidgetSelector } from './DrawerWidgetSelector.tsx';
9
+ export { drawerGridTemplateColumns } from './drawerLayout.ts';
10
+ export { default as ModalWidget } from './ModalWidget.tsx';
11
+ export { default as ModalWidgetAppBar } from './ModalWidgetAppBar.tsx';
12
+ export { default as PreferencesDialog } from './PreferencesDialog.tsx';
13
+ export type { PreferencesDialogSession, PreferencesPanelDescriptor, } from './PreferencesDialog.tsx';
14
+ export { default as WidgetBody } from './WidgetBody.tsx';
15
+ export { default as WidgetHeading } from './WidgetHeading.tsx';
package/esm/ui/index.js CHANGED
@@ -1 +1,13 @@
1
- export * from "./AboutDialog.js";
1
+ export { default as AppReadyMarker } from '@jbrowse/core/ui/AppReadyMarker';
2
+ export { default as AboutDialog } from './AboutDialog.js';
3
+ export { default as Drawer } from './Drawer.js';
4
+ export { default as DrawerControls } from './DrawerControls.js';
5
+ export { default as DrawerHeader } from './DrawerHeader.js';
6
+ export { default as DrawerWidget } from './DrawerWidget.js';
7
+ export { default as DrawerWidgetSelector } from './DrawerWidgetSelector.js';
8
+ export { drawerGridTemplateColumns } from './drawerLayout.js';
9
+ export { default as ModalWidget } from './ModalWidget.js';
10
+ export { default as ModalWidgetAppBar } from './ModalWidgetAppBar.js';
11
+ export { default as PreferencesDialog } from './PreferencesDialog.js';
12
+ export { default as WidgetBody } from './WidgetBody.js';
13
+ export { default as WidgetHeading } from './WidgetHeading.js';
@@ -0,0 +1,18 @@
1
+ import type { TrackConfigChange } from '@jbrowse/core/util';
2
+ export interface ResettablePreferencesSession {
3
+ themeName?: string;
4
+ setThemeName: (arg: string) => void;
5
+ themeMode: 'light' | 'dark' | 'system';
6
+ setThemeMode: (arg: 'light' | 'dark' | 'system') => 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): TrackConfigChange[];
17
+ export declare function resetAllPreferences(session: ResettablePreferencesSession): void;
18
+ export declare function resetPreferenceChange(session: ResettablePreferencesSession, change: TrackConfigChange): void;
@@ -0,0 +1,69 @@
1
+ const NON_MAP_PREFERENCES = [
2
+ {
3
+ head: 'theme',
4
+ change: s => s.themeName && s.themeName !== 'default'
5
+ ? { path: ['theme'], from: 'default', to: s.themeName }
6
+ : undefined,
7
+ reset: s => {
8
+ s.setThemeName('default');
9
+ },
10
+ },
11
+ {
12
+ head: 'themeMode',
13
+ change: s => s.themeMode === 'light'
14
+ ? undefined
15
+ : { path: ['themeMode'], from: 'light', to: s.themeMode },
16
+ reset: s => {
17
+ s.setThemeMode('light');
18
+ },
19
+ },
20
+ {
21
+ head: 'stickyViewHeaders',
22
+ change: s => s.stickyViewHeaders
23
+ ? undefined
24
+ : { path: ['stickyViewHeaders'], from: true, to: false },
25
+ reset: s => {
26
+ s.setStickyViewHeaders(true);
27
+ },
28
+ },
29
+ {
30
+ head: 'useWorkspaces',
31
+ change: s => s.effectiveUseWorkspaces === s.defaultUseWorkspaces
32
+ ? undefined
33
+ : {
34
+ path: ['useWorkspaces'],
35
+ from: s.defaultUseWorkspaces,
36
+ to: s.effectiveUseWorkspaces,
37
+ },
38
+ reset: s => {
39
+ s.resetUseWorkspaces();
40
+ },
41
+ },
42
+ ];
43
+ const NON_MAP_HEADS = new Set(NON_MAP_PREFERENCES.map(p => p.head));
44
+ // Everything "Reset to defaults" reverts, as rows: the scalar overrides in the
45
+ // preference map, and the preferences held outside it.
46
+ export function collectPreferenceChanges(session) {
47
+ return [
48
+ ...session
49
+ .getPreferenceChanges()
50
+ .filter(c => !NON_MAP_HEADS.has(c.path[0])),
51
+ ...NON_MAP_PREFERENCES.map(p => p.change(session)).filter(c => c !== undefined),
52
+ ];
53
+ }
54
+ export function resetAllPreferences(session) {
55
+ session.clearPreferenceOverrides();
56
+ for (const p of NON_MAP_PREFERENCES) {
57
+ p.reset(session);
58
+ }
59
+ }
60
+ export function resetPreferenceChange(session, change) {
61
+ const [head] = change.path;
62
+ const pref = NON_MAP_PREFERENCES.find(p => p.head === head);
63
+ if (pref) {
64
+ pref.reset(session);
65
+ }
66
+ else if (head) {
67
+ session.clearPreferenceOverride(head);
68
+ }
69
+ }
package/esm/ui/util.d.ts CHANGED
@@ -1,15 +1,30 @@
1
- import type PluginManager from '@jbrowse/core/PluginManager';
2
1
  import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
2
  import type { AbstractSessionModel } from '@jbrowse/core/util';
4
- export declare function removeAttr(obj: Record<string, unknown>, attr: string): Record<string, unknown>;
5
- export declare function readConf(config: AnyConfigurationModel | Record<string, unknown>, slotPath?: string | string[]): any;
6
- export declare function generateDisplayableConfig({ config, session, pluginManager, }: {
7
- config: AnyConfigurationModel | Record<string, unknown>;
3
+ export interface AboutPanelProps {
4
+ session: AbstractSessionModel;
5
+ /** the track's config, hydrated by the dialog before any panel sees it */
6
+ config: AnyConfigurationModel;
7
+ }
8
+ declare module '@jbrowse/core/PluginManager' {
9
+ interface ExtensionPointRegistry {
10
+ 'Core-extraAboutPanel': ComponentList<AboutPanelProps>;
11
+ /** #extensionPoint Core-replaceAbout | sync | Replace or wrap a track's About dialog body */
12
+ 'Core-replaceAbout': ComponentSlot<AboutPanelProps>;
13
+ }
14
+ }
15
+ /**
16
+ * What a track's About dialog shows: the config with the session's and the
17
+ * track's `formatAbout` callbacks merged over it, plus the resolved `hideUris`.
18
+ * The two slots fold differently on purpose: `config` is a merge the track can
19
+ * win key-by-key, `hideUris` an OR a track cannot turn back off.
20
+ */
21
+ export declare function getAboutDialogConfig({ config, session, }: {
22
+ config: AnyConfigurationModel;
8
23
  session: AbstractSessionModel;
9
- pluginManager: PluginManager;
10
24
  }): {
11
25
  config: {
12
- metadata?: Record<string, unknown>;
13
26
  [key: string]: unknown;
27
+ metadata?: Record<string, unknown>;
14
28
  };
29
+ hideUris: boolean;
15
30
  };
package/esm/ui/util.js CHANGED
@@ -1,42 +1,20 @@
1
- import { getConf, readConfObject } from '@jbrowse/core/configuration';
2
- import { getSnapshot, isStateTreeNode } from '@jbrowse/mobx-state-tree';
3
- export function removeAttr(obj, attr) {
4
- for (const prop in obj) {
5
- if (prop === attr) {
6
- delete obj[prop];
7
- }
8
- else if (typeof obj[prop] === 'object') {
9
- removeAttr(obj[prop], attr);
10
- }
11
- }
12
- return obj;
13
- }
14
- export function readConf(config, slotPath) {
15
- if (isStateTreeNode(config)) {
16
- return slotPath
17
- ? readConfObject(config, slotPath)
18
- : getSnapshot(config);
19
- }
20
- if (!slotPath) {
21
- return config;
22
- }
23
- if (typeof slotPath === 'string') {
24
- return config[slotPath];
25
- }
26
- let result = config;
27
- for (const key of slotPath) {
28
- result = result?.[key];
29
- }
30
- return result;
31
- }
32
- export function generateDisplayableConfig({ config, session, pluginManager, }) {
33
- const conf = isStateTreeNode(config) ? readConfObject(config) : config;
34
- const formatAboutConfig = readConf(config, ['formatAbout', 'config']) || {};
35
- return pluginManager.evaluateExtensionPoint('Core-customizeAbout', {
36
- config: {
37
- ...conf,
38
- ...getConf(session, ['formatAbout', 'config'], { config: conf }),
39
- ...formatAboutConfig,
40
- },
41
- }, { session, config });
1
+ import { getConf, mergeFormatCallbacks, readConfObject, } from '@jbrowse/core/configuration';
2
+ // #endregion
3
+ /**
4
+ * What a track's About dialog shows: the config with the session's and the
5
+ * track's `formatAbout` callbacks merged over it, plus the resolved `hideUris`.
6
+ * The two slots fold differently on purpose: `config` is a merge the track can
7
+ * win key-by-key, `hideUris` an OR a track cannot turn back off.
8
+ */
9
+ export function getAboutDialogConfig({ config, session, }) {
10
+ const conf = readConfObject(config);
11
+ const shown = {
12
+ ...conf,
13
+ ...mergeFormatCallbacks(getConf(session, ['formatAbout', 'config'], { config: conf }), readConfObject(config, ['formatAbout', 'config'], { config: conf })),
14
+ };
15
+ return {
16
+ config: shown,
17
+ hideUris: Boolean(getConf(session, ['formatAbout', 'hideUris']) ||
18
+ readConfObject(config, ['formatAbout', 'hideUris'])),
19
+ };
42
20
  }
@@ -0,0 +1,19 @@
1
+ import type { EmbeddedRoot } from './destroyViewState.ts';
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;
9
+ /**
10
+ * Destroy an engine when its component really unmounts — terminating its RPC
11
+ * worker threads and stopping its autoruns.
12
+ *
13
+ * The lifecycle rule is {@link useFinalUnmount}'s, including why the obvious
14
+ * `useEffect(() => () => destroyViewState(state), [state])` is wrong under
15
+ * StrictMode; this only names what gets torn down. Pair it with
16
+ * `useCreateOnce`, since the engine has to be the same one for the component's
17
+ * whole life.
18
+ */
19
+ export declare function useDestroyOnUnmount(viewState: EmbeddedRoot): void;
@@ -0,0 +1,44 @@
1
+ import { useRef } from 'react';
2
+ import { useCreateOnceAsync, useFinalUnmount } from '@jbrowse/core/util/hooks';
3
+ import { destroyViewState } from './destroyViewState.js';
4
+ // `useCreateOnce` is core's, and is re-exported rather than wrapped: an engine
5
+ // is only the most expensive thing StrictMode's double-invoked state
6
+ // initializer can build twice, not the only one. The faceted track selector's
7
+ // MST model hit the same trap in a plugin, which cannot reach this package.
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
+ }
30
+ /**
31
+ * Destroy an engine when its component really unmounts — terminating its RPC
32
+ * worker threads and stopping its autoruns.
33
+ *
34
+ * The lifecycle rule is {@link useFinalUnmount}'s, including why the obvious
35
+ * `useEffect(() => () => destroyViewState(state), [state])` is wrong under
36
+ * StrictMode; this only names what gets torn down. Pair it with
37
+ * `useCreateOnce`, since the engine has to be the same one for the component's
38
+ * whole life.
39
+ */
40
+ export function useDestroyOnUnmount(viewState) {
41
+ useFinalUnmount(() => {
42
+ destroyViewState(viewState);
43
+ });
44
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/product-core",
3
- "version": "4.3.0",
3
+ "version": "5.0.0-beta.10",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "JBrowse 2 code shared between products but not used by plugins",
@@ -21,37 +21,34 @@
21
21
  },
22
22
  "author": "JBrowse Team",
23
23
  "main": "esm/index.js",
24
+ "exports": {
25
+ ".": "./esm/index.js"
26
+ },
24
27
  "files": [
25
28
  "esm"
26
29
  ],
27
30
  "dependencies": {
28
- "@jbrowse/mobx-state-tree": "^5.6.0",
29
- "@mui/material": "^7.3.11",
30
- "copy-to-clipboard": "^3.3.3",
31
- "librpc-web-mod": "^2.1.1",
32
- "mobx": "^6.15.3",
33
- "mobx-react": "^9.2.1",
34
- "@jbrowse/core": "^4.3.0"
31
+ "@jbrowse/mobx-state-tree": "^6.6.1",
32
+ "@mui/icons-material": "^9.4.0",
33
+ "@mui/material": "^9.4.0",
34
+ "mobx": "^7.0.5",
35
+ "mobx-react": "^10.0.2",
36
+ "@jbrowse/core": "^5.0.0-beta.10",
37
+ "@jbrowse/render-core": "^5.0.0-beta.10"
35
38
  },
36
39
  "peerDependencies": {
37
- "react": ">=18.0.0",
38
- "react-dom": ">=18.0.0"
40
+ "react": ">=19.0.0",
41
+ "react-dom": ">=19.0.0"
39
42
  },
40
43
  "publishConfig": {
41
44
  "access": "public"
42
45
  },
43
46
  "scripts": {
44
- "build:esm": "tsc -p tsconfig.build.esm.json",
47
+ "build:esm": "node ../../node_modules/typescript7/bin/tsc --build tsconfig.build.esm.json",
45
48
  "build": "pnpm build:esm",
46
49
  "test": "cd ../..; jest --passWithNoTests packages/product-core",
47
50
  "clean": "rimraf esm *.tsbuildinfo",
48
51
  "prebuild": "pnpm clean"
49
52
  },
50
- "types": "esm/index.d.ts",
51
- "exports": {
52
- ".": {
53
- "types": "./esm/index.d.ts",
54
- "import": "./esm/index.js"
55
- }
56
- }
53
+ "types": "esm/index.d.ts"
57
54
  }