@jbrowse/plugin-linear-genome-view 5.0.0-beta.1 → 5.0.0-beta.11

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 (148) hide show
  1. package/esm/FeatureTrack/configSchema.d.ts +142 -50
  2. package/esm/LaunchLinearGenomeView/index.js +2 -13
  3. package/esm/LinearGenomeView/afterAttach.d.ts +5 -5
  4. package/esm/LinearGenomeView/afterAttach.js +75 -62
  5. package/esm/LinearGenomeView/components/CenterLine.js +5 -3
  6. package/esm/LinearGenomeView/components/CrisprGuidePanel.js +3 -5
  7. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +3 -2
  8. package/esm/LinearGenomeView/components/ExportSvgDialog.js +6 -2
  9. package/esm/LinearGenomeView/components/GetSequenceDialog.js +2 -2
  10. package/esm/LinearGenomeView/components/Header.js +11 -1
  11. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +2 -2
  12. package/esm/LinearGenomeView/components/HeaderPanControls.js +2 -1
  13. package/esm/LinearGenomeView/components/HeaderZoomControls.js +4 -34
  14. package/esm/LinearGenomeView/components/Highlight.js +7 -7
  15. package/esm/LinearGenomeView/components/HighlightBand.d.ts +9 -1
  16. package/esm/LinearGenomeView/components/HighlightBand.js +15 -3
  17. package/esm/LinearGenomeView/components/HighlightChip.d.ts +1 -2
  18. package/esm/LinearGenomeView/components/HighlightChip.js +5 -7
  19. package/esm/LinearGenomeView/components/HoverPositionHighlight.js +3 -3
  20. package/esm/LinearGenomeView/components/ImportForm.js +2 -2
  21. package/esm/LinearGenomeView/components/LinearGenomeView.js +3 -3
  22. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +3 -4
  23. package/esm/LinearGenomeView/components/MiniControls.js +3 -2
  24. package/esm/LinearGenomeView/components/OverviewHighlight.js +3 -3
  25. package/esm/LinearGenomeView/components/OverviewHighlightBand.js +2 -3
  26. package/esm/LinearGenomeView/components/OverviewRubberband.js +20 -45
  27. package/esm/LinearGenomeView/components/OverviewScalebar.js +4 -5
  28. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +5 -3
  29. package/esm/LinearGenomeView/components/PaddingBlocks.d.ts +1 -1
  30. package/esm/LinearGenomeView/components/PaddingBlocks.js +14 -9
  31. package/esm/LinearGenomeView/components/RangeSelectOverlay.js +5 -6
  32. package/esm/LinearGenomeView/components/ResizeAllTracksHandle.d.ts +5 -0
  33. package/esm/LinearGenomeView/components/ResizeAllTracksHandle.js +71 -0
  34. package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -2
  35. package/esm/LinearGenomeView/components/Rubberband.js +3 -2
  36. package/esm/LinearGenomeView/components/SVGHighlightBand.js +2 -3
  37. package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -6
  38. package/esm/LinearGenomeView/components/Scalebar.js +8 -5
  39. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +49 -34
  40. package/esm/LinearGenomeView/components/SearchBox.js +8 -7
  41. package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +2 -1
  42. package/esm/LinearGenomeView/components/SearchResultsDialog.js +2 -2
  43. package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +2 -1
  44. package/esm/LinearGenomeView/components/SearchResultsTable.js +12 -29
  45. package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -4
  46. package/esm/LinearGenomeView/components/TrackContainer.js +63 -9
  47. package/esm/LinearGenomeView/components/TrackLabel.js +10 -3
  48. package/esm/LinearGenomeView/components/TrackLabelButtons.js +2 -2
  49. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +2 -2
  50. package/esm/LinearGenomeView/components/TrackLabelMenu.js +3 -2
  51. package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +4 -1
  52. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +11 -23
  53. package/esm/LinearGenomeView/components/TracksContainer.js +10 -22
  54. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -2
  55. package/esm/LinearGenomeView/components/VerticalGuide.js +3 -16
  56. package/esm/LinearGenomeView/components/ZoomButton.js +6 -1
  57. package/esm/LinearGenomeView/components/ZoomTransform.js +4 -0
  58. package/esm/LinearGenomeView/components/fetchSequence.d.ts +1 -2
  59. package/esm/LinearGenomeView/components/recentLocationsMenu.js +10 -0
  60. package/esm/LinearGenomeView/components/searchModes.d.ts +1 -1
  61. package/esm/LinearGenomeView/components/searchModes.js +1 -1
  62. package/esm/LinearGenomeView/components/useRangeSelect.d.ts +0 -3
  63. package/esm/LinearGenomeView/components/useRangeSelect.js +20 -59
  64. package/esm/LinearGenomeView/components/useSideScroll.d.ts +16 -2
  65. package/esm/LinearGenomeView/components/useSideScroll.js +153 -103
  66. package/esm/LinearGenomeView/components/util.d.ts +4 -0
  67. package/esm/LinearGenomeView/components/util.js +4 -2
  68. package/esm/LinearGenomeView/consts.d.ts +2 -0
  69. package/esm/LinearGenomeView/consts.js +3 -1
  70. package/esm/LinearGenomeView/containingLgv.d.ts +21 -0
  71. package/esm/LinearGenomeView/containingLgv.js +23 -0
  72. package/esm/LinearGenomeView/headerFit.d.ts +4 -2
  73. package/esm/LinearGenomeView/headerFit.js +20 -7
  74. package/esm/LinearGenomeView/index.d.ts +1 -5
  75. package/esm/LinearGenomeView/index.js +10 -7
  76. package/esm/LinearGenomeView/keyboardHandler.d.ts +2 -0
  77. package/esm/LinearGenomeView/keyboardHandler.js +15 -1
  78. package/esm/LinearGenomeView/launchKeys.d.ts +2 -0
  79. package/esm/LinearGenomeView/launchKeys.js +27 -0
  80. package/esm/LinearGenomeView/lazyDialogs.d.ts +2 -4
  81. package/esm/LinearGenomeView/lazyDialogs.js +1 -0
  82. package/esm/LinearGenomeView/linkedViewSync.d.ts +3 -11
  83. package/esm/LinearGenomeView/linkedViewSync.js +27 -43
  84. package/esm/LinearGenomeView/menuItems.d.ts +16 -18
  85. package/esm/LinearGenomeView/menuItems.js +242 -151
  86. package/esm/LinearGenomeView/model.d.ts +2027 -200
  87. package/esm/LinearGenomeView/model.js +560 -395
  88. package/esm/LinearGenomeView/sharedScaleContainer.d.ts +1 -1
  89. package/esm/LinearGenomeView/showRegionsWithUndo.js +7 -1
  90. package/esm/LinearGenomeView/stickyChrome.d.ts +5 -9
  91. package/esm/LinearGenomeView/stickyChrome.js +5 -9
  92. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +4 -4
  93. package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +4 -1
  94. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +8 -21
  95. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +8 -8
  96. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +3 -3
  97. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +7 -11
  98. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +2 -5
  99. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +5 -6
  100. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +9 -10
  101. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +3 -3
  102. package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.d.ts +27 -0
  103. package/esm/LinearGenomeView/svgcomponents/SVGStackedRow.js +12 -0
  104. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +2 -1
  105. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +29 -16
  106. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +4 -4
  107. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +6 -5
  108. package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +1 -1
  109. package/esm/LinearGenomeView/svgcomponents/SVGView.js +1 -1
  110. package/esm/LinearGenomeView/svgcomponents/figureContract.js +14 -14
  111. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +1 -0
  112. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +1 -1
  113. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +50 -68
  114. package/esm/LinearGenomeView/svgcomponents/util.d.ts +20 -8
  115. package/esm/LinearGenomeView/svgcomponents/util.js +50 -29
  116. package/esm/LinearGenomeView/types.d.ts +8 -11
  117. package/esm/LinearGenomeView/util.d.ts +60 -45
  118. package/esm/LinearGenomeView/util.js +131 -160
  119. package/esm/MultiLevelRubberband/MultiLevelRubberband.js +7 -4
  120. package/esm/MultiLevelRubberband/index.d.ts +2 -0
  121. package/esm/MultiLevelRubberband/index.js +2 -0
  122. package/esm/MultiLevelRubberband/menuItems.d.ts +34 -0
  123. package/esm/MultiLevelRubberband/menuItems.js +52 -0
  124. package/esm/MultiLevelRubberband/rowLabel.d.ts +22 -0
  125. package/esm/MultiLevelRubberband/rowLabel.js +27 -0
  126. package/esm/MultiLevelRubberband/types.d.ts +1 -0
  127. package/esm/MultiLevelRubberband/useRangeSelect.d.ts +2 -1
  128. package/esm/MultiLevelRubberband/useRangeSelect.js +31 -47
  129. package/esm/displayKitTests/perRegionTestEnv.d.ts +244 -86
  130. package/esm/displayKitTests/perRegionTestEnv.js +30 -29
  131. package/esm/index.d.ts +15 -85
  132. package/esm/index.js +13 -36
  133. package/esm/searchUtils.d.ts +18 -9
  134. package/esm/searchUtils.js +85 -69
  135. package/esm/shared/RubberbandSpan.js +2 -1
  136. package/esm/shared/coordLabels.d.ts +7 -0
  137. package/esm/shared/coordLabels.js +15 -1
  138. package/esm/shared/useWindowDrag.d.ts +18 -0
  139. package/esm/shared/useWindowDrag.js +45 -0
  140. package/package.json +10 -10
  141. package/esm/LinearGenomeView/FloatingSvgOverlay.d.ts +0 -5
  142. package/esm/LinearGenomeView/FloatingSvgOverlay.js +0 -25
  143. package/esm/LinearGenomeView/initKeys.d.ts +0 -13
  144. package/esm/LinearGenomeView/initKeys.js +0 -104
  145. package/esm/MultiLevelRubberband/VerticalGuide.d.ts +0 -6
  146. package/esm/MultiLevelRubberband/VerticalGuide.js +0 -21
  147. package/esm/lazyPluginExports.d.ts +0 -23
  148. package/esm/lazyPluginExports.js +0 -36
@@ -40,85 +40,177 @@ import type PluginManager from '@jbrowse/core/PluginManager';
40
40
  * }
41
41
  * ```
42
42
  */
43
- declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{}, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
43
+ declare const configSchema: (pluginManager: PluginManager) => import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
44
+ adapter: import("@jbrowse/core/PluginManager").PluggableConfigSchemaType;
45
+ assemblyNames: {
46
+ type: "stringArray";
47
+ } & {
48
+ defaultValue: unknown;
49
+ };
50
+ category: {
51
+ type: "stringArray";
52
+ } & {
53
+ defaultValue: unknown;
54
+ };
55
+ description: {
56
+ type: "string";
57
+ } & {
58
+ defaultValue: string;
59
+ };
60
+ displays: import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/core/PluginManager").PluggableConfigSchemaType>;
61
+ formatAbout: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
62
+ readonly config: {
63
+ type: "frozen";
64
+ } & {
65
+ defaultValue: unknown;
66
+ };
67
+ readonly hideUris: {
68
+ type: "boolean";
69
+ } & {
70
+ defaultValue: boolean;
71
+ };
72
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
73
+ formatDetails: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
74
+ readonly feature: {
75
+ type: "frozen";
76
+ } & {
77
+ defaultValue: unknown;
78
+ };
79
+ readonly subfeatures: {
80
+ type: "frozen";
81
+ } & {
82
+ defaultValue: unknown;
83
+ };
84
+ readonly depth: {
85
+ type: "maybeNumber";
86
+ };
87
+ readonly maxDepth: {
88
+ type: "maybeNumber";
89
+ };
90
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
91
+ metadata: {
92
+ type: "frozen";
93
+ } & {
94
+ defaultValue: unknown;
95
+ };
96
+ name: {
97
+ type: "string";
98
+ } & {
99
+ defaultValue: string;
100
+ };
101
+ textSearching: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
102
+ readonly indexingAttributes: {
103
+ type: "stringArray";
104
+ } & {
105
+ defaultValue: unknown;
106
+ };
107
+ readonly indexingFeatureTypesToExclude: {
108
+ type: "stringArray";
109
+ } & {
110
+ defaultValue: unknown;
111
+ };
112
+ readonly indexingFeatureTypesToInclude: {
113
+ type: "stringArray";
114
+ } & {
115
+ defaultValue: unknown;
116
+ };
117
+ readonly textSearchAdapter: import("@jbrowse/mobx-state-tree").ITypeUnion<any, any, import("@jbrowse/core/configuration").PluggableConfigNode | undefined>;
118
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
119
+ trackId: {
120
+ type: "string";
121
+ } & {
122
+ defaultValue: string;
123
+ };
124
+ type: {
125
+ type: "string";
126
+ } & {
127
+ defaultValue: string;
128
+ };
129
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
44
130
  readonly name: {
45
- readonly description: "descriptive name of the track, falls back to the trackId when unset";
46
- readonly type: "string";
47
- readonly defaultValue: "";
131
+ type: "string";
132
+ } & {
133
+ defaultValue: string;
48
134
  };
49
135
  readonly assemblyNames: {
50
- readonly description: "name of the assembly (or assemblies) track belongs to";
51
- readonly type: "stringArray";
52
- readonly defaultValue: readonly ["assemblyName"];
136
+ type: "stringArray";
137
+ } & {
138
+ defaultValue: unknown;
53
139
  };
54
140
  readonly description: {
55
- readonly description: "a description of the track";
56
- readonly type: "string";
57
- readonly defaultValue: "";
141
+ type: "string";
142
+ } & {
143
+ defaultValue: string;
58
144
  };
59
145
  readonly category: {
60
- readonly description: "the category and sub-categories of a track";
61
- readonly type: "stringArray";
62
- readonly defaultValue: readonly [];
146
+ type: "stringArray";
147
+ } & {
148
+ defaultValue: unknown;
63
149
  };
64
150
  readonly metadata: {
65
- readonly type: "frozen";
66
- readonly description: "anything to add about this track";
67
- readonly defaultValue: {};
151
+ type: "frozen";
152
+ } & {
153
+ defaultValue: unknown;
68
154
  };
69
- readonly adapter: import("@jbrowse/mobx-state-tree").IAnyType;
155
+ readonly adapter: import("@jbrowse/core/PluginManager").PluggableConfigSchemaType;
70
156
  readonly textSearching: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
71
157
  readonly indexingAttributes: {
72
- readonly type: "stringArray";
73
- readonly description: "list of which feature attributes to index for text searching";
74
- readonly defaultValue: readonly ["Name", "ID", "symbol"];
158
+ type: "stringArray";
159
+ } & {
160
+ defaultValue: unknown;
75
161
  };
76
162
  readonly indexingFeatureTypesToExclude: {
77
- readonly type: "stringArray";
78
- readonly description: "list of feature types to exclude in text search index";
79
- readonly defaultValue: readonly ["CDS", "exon"];
163
+ type: "stringArray";
164
+ } & {
165
+ defaultValue: unknown;
80
166
  };
81
167
  readonly indexingFeatureTypesToInclude: {
82
- readonly type: "stringArray";
83
- readonly description: "the only feature types to index; empty means index every type not excluded";
84
- readonly defaultValue: readonly [];
168
+ type: "stringArray";
169
+ } & {
170
+ defaultValue: unknown;
85
171
  };
86
- readonly textSearchAdapter: import("@jbrowse/mobx-state-tree").IAnyType;
87
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
88
- readonly displays: import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/mobx-state-tree").IAnyType>;
172
+ readonly textSearchAdapter: import("@jbrowse/mobx-state-tree").ITypeUnion<any, any, import("@jbrowse/core/configuration").PluggableConfigNode | undefined>;
173
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
174
+ readonly displays: import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/core/PluginManager").PluggableConfigSchemaType>;
89
175
  readonly formatDetails: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
90
176
  readonly feature: {
91
- readonly type: "frozen";
92
- readonly description: "adds extra fields to the feature details";
93
- readonly defaultValue: {};
94
- readonly contextVariable: ["feature"];
177
+ type: "frozen";
178
+ } & {
179
+ defaultValue: unknown;
95
180
  };
96
181
  readonly subfeatures: {
97
- readonly type: "frozen";
98
- readonly description: "adds extra fields to the subfeatures of a feature";
99
- readonly defaultValue: {};
100
- readonly contextVariable: ["feature"];
182
+ type: "frozen";
183
+ } & {
184
+ defaultValue: unknown;
101
185
  };
102
186
  readonly depth: {
103
- readonly type: "maybeNumber";
104
- readonly description: "levels of subfeature the formatDetails.subfeatures callback runs on, default 2";
187
+ type: "maybeNumber";
105
188
  };
106
189
  readonly maxDepth: {
107
- readonly type: "maybeNumber";
108
- readonly description: "hide subfeatures nested deeper than this, default no limit";
190
+ type: "maybeNumber";
109
191
  };
110
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
192
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
111
193
  readonly formatAbout: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
112
194
  readonly config: {
113
- readonly type: "frozen";
114
- readonly description: "formats configuration object in about dialog";
115
- readonly defaultValue: {};
116
- readonly contextVariable: ["config"];
195
+ type: "frozen";
196
+ } & {
197
+ defaultValue: unknown;
117
198
  };
118
199
  readonly hideUris: {
119
- readonly type: "boolean";
120
- readonly defaultValue: false;
200
+ type: "boolean";
201
+ } & {
202
+ defaultValue: boolean;
121
203
  };
122
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined>>;
123
- }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "trackId">>, "trackId">>;
204
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
205
+ type: {
206
+ type: "string";
207
+ } & {
208
+ defaultValue: string;
209
+ };
210
+ trackId: {
211
+ type: "string";
212
+ } & {
213
+ defaultValue: string;
214
+ };
215
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, "trackId", true, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>, "trackId", undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>, any>>;
124
216
  export default configSchema;
@@ -1,22 +1,11 @@
1
- import { linearGenomeViewPropKeys, partitionLaunchKeys, warnUnknownLaunchKeys, } from '../LinearGenomeView/initKeys.js';
2
1
  export default function LaunchLinearGenomeViewF(pluginManager) {
3
2
  /** #extensionPoint LaunchView-LinearGenomeView | async | Programmatically launch a linear genome view */
4
3
  pluginManager.addToExtensionPoint('LaunchView-LinearGenomeView', args => {
5
- const { session, id, ...spec } = args;
4
+ const { session, ...spec } = args;
6
5
  if (!spec.assembly) {
7
6
  throw new Error('No assembly provided when launching linear genome view');
8
7
  }
9
- // Resolution keys go into the one-shot `init` blob afterAttach applies and
10
- // discards; plain props go straight onto the view snapshot, where MST
11
- // restores them natively (and, except for the purely localStorage-backed
12
- // showCenterLine, persist on save). Anything in neither set is a typo — MST
13
- // drops unknown snapshot keys and `init` is a frozen blob, so nothing
14
- // downstream would notice.
15
- const { init, viewProps, unknown } = partitionLaunchKeys(spec, linearGenomeViewPropKeys(pluginManager));
16
- warnUnknownLaunchKeys('LaunchView-LinearGenomeView', unknown);
17
- // A provided id is passed top-level so MST's optional identifier honors it
18
- // (undefined falls back to an auto-generated id).
19
- session.addView('LinearGenomeView', { id, ...viewProps, init });
8
+ session.addView('LinearGenomeView', spec);
20
9
  return args;
21
10
  });
22
11
  }
@@ -1,17 +1,17 @@
1
1
  import type { LinearGenomeViewModel } from './model.ts';
2
2
  import type { InitState } from './types.ts';
3
- import type { AssemblyHost, NotificationSink } from '@jbrowse/core/util';
3
+ import type { AbstractSessionModel, AssemblyHost, NotificationSink } from '@jbrowse/core/util';
4
4
  /**
5
- * Apply an init blob's `highlight` entries to a view, coercing each locstring
6
- * or wire-format object and reporting a bad one without taking out its
7
- * siblings.
5
+ * Add an init blob's `highlight` entries to the session, coercing each
6
+ * locstring or wire-format object and reporting a bad one without taking out
7
+ * its siblings. An entry without an assembly takes the launch's.
8
8
  *
9
9
  * Exported because a LinearSyntenyView row is a LinearGenomeView that does NOT
10
10
  * go through this file's init autorun — the synteny view builds each row's
11
11
  * snapshot and navigates it itself — so the row's own `highlight` had nowhere
12
12
  * to be applied and was dropped in silence.
13
13
  */
14
- export declare function applyInitHighlights(self: LinearGenomeViewModel, session: AssemblyHost & NotificationSink, init: Pick<InitState, 'highlight' | 'assembly'>): void;
14
+ export declare function applyInitHighlights(session: AssemblyHost & NotificationSink & Pick<AbstractSessionModel, 'addHighlight'>, init: Pick<InitState, 'highlight' | 'assembly'>): void;
15
15
  /**
16
16
  * Autorun that handles the init state - navigating to initial location,
17
17
  * showing tracks, etc.
@@ -1,19 +1,10 @@
1
1
  import { getSession, isSessionModelWithWidgets, localStorageSetItem, resolveNamedRegions, } from '@jbrowse/core/util';
2
2
  import { coerceHighlight } from '@jbrowse/core/util/highlights';
3
3
  import { installInitAutorun } from '@jbrowse/core/util/installInitAutorun';
4
- import { normalizeTrackInit } from '@jbrowse/core/util/tracks';
5
- import { addDisposer, getPropertyMembers } from '@jbrowse/mobx-state-tree';
6
- import { autorun, when } from 'mobx';
4
+ import { normalizeTrackInit, warmTrackDisplayGeneric, } from '@jbrowse/core/util/tracks';
5
+ import { addDisposer } from '@jbrowse/mobx-state-tree';
6
+ import { autorun, untracked, when } from 'mobx';
7
7
  import { SearchResultsNotFoundError } from '../searchUtils.js';
8
- import { partitionLaunchKeys, warnUnknownLaunchKeys } from './initKeys.js';
9
- function warnInitKeyProblems(self, init) {
10
- const { viewProps, unknown } = partitionLaunchKeys(init, new Set(Object.keys(getPropertyMembers(self).properties)));
11
- const viewPropKeys = Object.keys(viewProps);
12
- warnUnknownLaunchKeys('LinearGenomeView init', unknown);
13
- if (viewPropKeys.length) {
14
- console.warn(`LinearGenomeView init ignored view prop(s): ${viewPropKeys.join(', ')} — set these on the view alongside init, not inside it`);
15
- }
16
- }
17
8
  // `init` is a frozen blob that often comes from hand-authored JSON, where a
18
9
  // lone entry gets written bare (`tracks: 'genes'`). A string is iterable, so
19
10
  // looping over it directly walked its characters — one track opened per letter.
@@ -30,24 +21,17 @@ async function openTracklist(self, session, superseded) {
30
21
  // activateTrackSelector throws without widget support, which would abort the
31
22
  // rest of init (navigation included) over an optional extra
32
23
  if (isSessionModelWithWidgets(session)) {
33
- // `poppedOut` — the visible widget rendered in a modal, leaving the drawer
34
- // column free — lives on SessionWithDrawerWidgets, whose type guard is
35
- // product-core's, so duck-type it here rather than take an upward
36
- // dependency. A session without the key has no modal to pop out into, so
37
- // false is the right answer for it.
38
- const poppedOut = 'poppedOut' in session && session.poppedOut === true;
39
- // the same line App.tsx draws to decide whether to render the drawer column
40
- // at all. A *minimized* drawer still holds a visibleWidget while taking no
41
- // width, and showWidget un-minimizes it (product-core's DrawerWidgets), so
42
- // `!!visibleWidget` alone reads "already open", skips the wait below, and
43
- // hands navigation the pre-drawer width — the exact thing this is here to
44
- // prevent.
45
- const drawerWasOpen = !!session.visibleWidget && !session.minimized && !poppedOut;
24
+ // `drawerVisible` is the line App.tsx draws to render the drawer column at
25
+ // all: a minimized, popped-out or modal-only widget takes no width. It
26
+ // lives on SessionWithDrawerWidgets, whose type guard is product-core's, so
27
+ // it is duck-typed rather than taken as an upward dependency; a session
28
+ // without it has no drawer column.
29
+ const drawerVisible = () => 'drawerVisible' in session && session.drawerVisible === true;
30
+ const drawerWasVisible = drawerVisible();
46
31
  const widthBefore = self.volatileWidth;
47
32
  self.activateTrackSelector();
48
- // a width change is only coming if the drawer is about to start taking
49
- // space; popped out it never does, so don't sit out the timeout for it
50
- if (!drawerWasOpen && !poppedOut) {
33
+ // a width change is only coming if the drawer just started taking space
34
+ if (!drawerWasVisible && drawerVisible()) {
51
35
  // Bounded so init can't wedge here if the drawer doesn't shrink the view
52
36
  // (e.g. embedded or modal-drawer layouts, where no width change is
53
37
  // coming), and superseded so a re-launch landing mid-wait isn't held
@@ -103,7 +87,11 @@ async function navigateInit(self, session, init) {
103
87
  // navToLocString waits for the assembly itself, and this autorun only
104
88
  // runs once `initialized` confirms init.assembly has loaded regions, so
105
89
  // no explicit waitForAssembly is needed here
106
- await self.navToLocString(init.loc, init.assembly, init.grow);
90
+ // a spec that listed its tracks gets those tracks; one that only named
91
+ // a gene gets the track the gene was found in, as the search box would
92
+ await self.navToLocString(init.loc, init.assembly, init.grow, {
93
+ showHitTrack: init.showHitTrack ?? asArray(init.tracks).length === 0,
94
+ });
107
95
  }
108
96
  else if (init.displayedRegionNames?.length) {
109
97
  // an explicit region list is a navigation request just like `loc`, so it
@@ -134,44 +122,33 @@ async function navigateInit(self, session, init) {
134
122
  }
135
123
  }
136
124
  }
137
- // showTrack funnels through showTrackGeneric, which surfaces any failure
138
- // (unresolved id, bad config, etc) as its own snackbar
139
- function showInitTracks(self, init) {
125
+ // launchTrack funnels through showTrackGeneric, which surfaces any failure
126
+ // (unresolved id, bad config, etc) as its own snackbar, and loads the picked
127
+ // display's state model first when it is registered lazily
128
+ async function showInitTracks(self, init) {
140
129
  for (const t of asArray(init.tracks)) {
141
130
  const { trackId, trackSnapshot, displaySnapshot } = normalizeTrackInit(t);
142
- self.showTrack(trackId, trackSnapshot, displaySnapshot);
143
- }
144
- }
145
- // backfill assemblyName on any session-authored highlights that omitted it so
146
- // downstream code (bookmark widget grid, addBookmark, etc) doesn't have to keep
147
- // falling back
148
- function backfillHighlightAssemblies(self) {
149
- const fallback = self.assemblyNames[0];
150
- if (self.highlight.length && fallback) {
151
- const normalized = self.highlight.map(h => h.assemblyName ? h : { ...h, assemblyName: fallback });
152
- if (normalized.some((h, i) => h !== self.highlight[i])) {
153
- self.setHighlight(normalized);
154
- }
131
+ await self.launchTrack(trackId, trackSnapshot, displaySnapshot);
155
132
  }
156
133
  }
157
134
  /**
158
- * Apply an init blob's `highlight` entries to a view, coercing each locstring
159
- * or wire-format object and reporting a bad one without taking out its
160
- * siblings.
135
+ * Add an init blob's `highlight` entries to the session, coercing each
136
+ * locstring or wire-format object and reporting a bad one without taking out
137
+ * its siblings. An entry without an assembly takes the launch's.
161
138
  *
162
139
  * Exported because a LinearSyntenyView row is a LinearGenomeView that does NOT
163
140
  * go through this file's init autorun — the synteny view builds each row's
164
141
  * snapshot and navigates it itself — so the row's own `highlight` had nowhere
165
142
  * to be applied and was dropped in silence.
166
143
  */
167
- export function applyInitHighlights(self, session, init) {
144
+ export function applyInitHighlights(session, init) {
168
145
  for (const h of asArray(init.highlight)) {
169
146
  // parseLocString throws on an unknown refName or a malformed locstring, and
170
147
  // one bad entry must take out neither its siblings nor the rest of init
171
148
  try {
172
149
  const highlight = coerceHighlight(h, init.assembly, refName => session.assemblyManager.isValidRefName(refName, init.assembly));
173
150
  if (highlight) {
174
- self.addToHighlights(highlight);
151
+ session.addHighlight(highlight);
175
152
  }
176
153
  }
177
154
  catch (e) {
@@ -180,20 +157,24 @@ export function applyInitHighlights(self, session, init) {
180
157
  }
181
158
  }
182
159
  }
183
- async function applyInit(self, init, { superseded }) {
160
+ async function applyInit(self, pending, { superseded }) {
184
161
  const session = getSession(self);
185
- warnInitKeyProblems(self, init);
162
+ // A re-launch of a view already showing an assembly need not restate it:
163
+ // jb.setSession writes `loc` and track entries beside the built state, and
164
+ // the readiness gate resolved the same default before letting this run.
165
+ const init = pending.assembly
166
+ ? pending
167
+ : { ...pending, assembly: self.launchAssemblyName ?? pending.assembly };
186
168
  if (init.tracklist) {
187
169
  await openTracklist(self, session, superseded);
188
170
  }
189
171
  // `superseded`, not a bare isAlive: it subsumes the liveness check (the view
190
172
  // may have been removed while the drawer or the navigation resolved, and
191
173
  // reading or mutating a detached node throws) and also covers the case
192
- // isAlive misses — a newer setInit landed mid-apply, so the rest of *this*
174
+ // isAlive misses — a newer setLaunch landed mid-apply, so the rest of *this*
193
175
  // blob is stale. Finishing it anyway appends its tracks and highlights under
194
- // the one that replaced it, and addToHighlights pushes, so a re-launch of the
195
- // same spec (a StrictMode remount) doubles the bands. The drain loop applies
196
- // the newer init next either way.
176
+ // the one that replaced it. The drain loop applies the newer init next either
177
+ // way.
197
178
  //
198
179
  // Checked after each await rather than once at the top, and as early returns
199
180
  // rather than nesting, so a step added later takes a guard beside it instead
@@ -205,12 +186,44 @@ async function applyInit(self, init, { superseded }) {
205
186
  if (superseded()) {
206
187
  return;
207
188
  }
208
- showInitTracks(self, init);
189
+ await showInitTracks(self, init);
190
+ if (superseded()) {
191
+ return;
192
+ }
209
193
  if (init.nav !== undefined) {
210
194
  self.setHideHeader(!init.nav);
211
195
  }
212
- backfillHighlightAssemblies(self);
213
- applyInitHighlights(self, session, init);
196
+ applyInitHighlights(session, init);
197
+ }
198
+ /**
199
+ * The init autorun below waits for the view's width, which exists only once its
200
+ * component has rendered, and then loads the assembly and launches the tracks
201
+ * one at a time. The assembly and the display code each pending track needs can
202
+ * start loading now, all at once.
203
+ */
204
+ function setupInitWarmup(self) {
205
+ addDisposer(self, autorun(function initWarmupAutorun() {
206
+ const pending = self.pendingLaunch;
207
+ const tracks = asArray(pending?.tracks);
208
+ // eslint-disable-next-line no-restricted-syntax -- EFFECT INPUT: the assembly and track configs only feed the loads started here; the pending launch is the key
209
+ untracked(() => {
210
+ const assembly = pending?.assembly ?? self.launchAssemblyName;
211
+ if (pending && assembly) {
212
+ try {
213
+ getSession(self)
214
+ .assemblyManager.waitForAssembly(assembly)
215
+ .catch(() => { });
216
+ }
217
+ catch {
218
+ // navigation reports an assembly that cannot load
219
+ }
220
+ }
221
+ for (const t of tracks) {
222
+ const { trackId, displaySnapshot } = normalizeTrackInit(t);
223
+ warmTrackDisplayGeneric(self, trackId, displaySnapshot, assembly);
224
+ }
225
+ });
226
+ }, { name: 'LGVInitWarmup' }));
214
227
  }
215
228
  /**
216
229
  * Autorun that handles the init state - navigating to initial location,
@@ -221,9 +234,8 @@ export function setupInitAutorun(self) {
221
234
  name: 'LGVInit',
222
235
  // `init` is what makes hasSomethingToShow / awaitingInitNavigation report
223
236
  // "loading"
224
- // until navigation populates displayedRegions, so the alternative gate
225
- // (clearing `init` up front, the way SpreadsheetView does) would flash the
226
- // import form mid-load.
237
+ // until navigation populates displayedRegions, so clearing `init` up front
238
+ // would flash the import form mid-load.
227
239
  ready: () => self.initialized,
228
240
  // No pre-materialization phase to protect: the view is its own single row,
229
241
  // and `error` already derives a failed init assembly declaratively (via
@@ -271,6 +283,7 @@ function setupLocalStorageAutorun(self) {
271
283
  * Sets up all afterAttach autoruns for the LinearGenomeView
272
284
  */
273
285
  export function doAfterAttach(self) {
286
+ setupInitWarmup(self);
274
287
  setupInitAutorun(self);
275
288
  setupCoarseDynamicBlocksAutorun(self);
276
289
  setupLocalStorageAutorun(self);
@@ -1,4 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { clamp } from '@jbrowse/core/util';
3
+ import { basePaintedAt } from '@jbrowse/core/util/Base1DUtils';
2
4
  import { makeStyles } from '@jbrowse/core/util/tss-react';
3
5
  import CloseIcon from '@mui/icons-material/Close';
4
6
  import { IconButton, Tooltip } from '@mui/material';
@@ -18,6 +20,7 @@ const useStyles = makeStyles()(theme => ({
18
20
  centerLineText: {
19
21
  position: 'absolute',
20
22
  left: 0,
23
+ bottom: 0,
21
24
  display: 'flex',
22
25
  alignItems: 'center',
23
26
  gap: 2,
@@ -31,7 +34,7 @@ const useStyles = makeStyles()(theme => ({
31
34
  },
32
35
  }));
33
36
  const CenterLine = observer(function CenterLine({ model }) {
34
- const { bpPerPx, centerLineInfo, trackHeights, tracks, width } = model;
37
+ const { bpPerPx, centerLineInfo, tracks, width } = model;
35
38
  const { classes } = useStyles();
36
39
  const startingPosition = width / 2;
37
40
  return tracks.length ? (_jsx("div", { "data-testid": "centerline_container", className: classes.centerLineContainer, role: "presentation", style: {
@@ -39,8 +42,7 @@ const CenterLine = observer(function CenterLine({ model }) {
39
42
  width: Math.max(1 / bpPerPx, 1),
40
43
  }, children: centerLineInfo && (_jsxs("div", { "data-testid": "centerline_text", className: classes.centerLineText, role: "presentation", style: {
41
44
  transform: `translateX(${Math.max(1 / bpPerPx, 1) + 5}px)`,
42
- top: trackHeights,
43
- }, children: [centerLineInfo.refName, ":", ' ', Math.max(Math.round(centerLineInfo.offset) + 1, 0).toLocaleString('en-US'), _jsx(Tooltip, { title: "Hide center line", children: _jsx(IconButton, { className: classes.dismiss, onClick: () => {
45
+ }, children: [centerLineInfo.refName, ":", ' ', (clamp(basePaintedAt(centerLineInfo, centerLineInfo.offset), centerLineInfo.start, centerLineInfo.end - 1) + 1).toLocaleString('en-US'), _jsx(Tooltip, { title: "Hide center line", children: _jsx(IconButton, { className: classes.dismiss, onClick: () => {
44
46
  model.setShowCenterLine(false);
45
47
  }, children: _jsx(CloseIcon, { fontSize: "inherit" }) }) })] })) })) : null;
46
48
  });
@@ -64,15 +64,14 @@ const CrisprGuidePanel = observer(function CrisprGuidePanel({ model, handleClose
64
64
  const [pamLocation, setPamLocation] = useState(DEFAULT_PRESET.pamLocation);
65
65
  const [guideLengthStr, setGuideLengthStr] = useState(String(DEFAULT_PRESET.guideLength));
66
66
  const [cutOffsetStr, setCutOffsetStr] = useState(String(DEFAULT_PRESET.cutOffset));
67
- // presets carry this; Custom is treated as a blunt cutter, so the panel does
68
- // not grow a second offset field for a case config can express directly
69
- const [cutOffsetBottom, setCutOffsetBottom] = useState(DEFAULT_PRESET.cutOffsetBottom);
70
67
  const [searchForward, setSearchForward] = useState(true);
71
68
  const [searchReverse, setSearchReverse] = useState(true);
72
69
  const [filterQuality, setFilterQuality] = useState(false);
73
70
  // `Number('')` is 0, so an emptied field would otherwise read as a valid zero
74
71
  const guideLength = toBpCount(guideLengthStr);
75
72
  const cutOffset = toBpCount(cutOffsetStr);
73
+ // Custom is a blunt cutter: config can express a staggered one directly
74
+ const cutOffsetBottom = ENZYME_PRESETS[enzyme]?.cutOffsetBottom ?? cutOffset;
76
75
  // both are bp counts used for fixed-length string slicing, so a fractional
77
76
  // value would silently truncate and skew the placement
78
77
  const guideLengthValid = Number.isInteger(guideLength) && guideLength > 0;
@@ -101,7 +100,6 @@ const CrisprGuidePanel = observer(function CrisprGuidePanel({ model, handleClose
101
100
  setPamLocation(preset.pamLocation);
102
101
  setGuideLengthStr(String(preset.guideLength));
103
102
  setCutOffsetStr(String(preset.cutOffset));
104
- setCutOffsetBottom(preset.cutOffsetBottom);
105
103
  }
106
104
  }
107
105
  function handleSubmit() {
@@ -116,7 +114,7 @@ const CrisprGuidePanel = observer(function CrisprGuidePanel({ model, handleClose
116
114
  guideLength,
117
115
  pamLocation,
118
116
  cutOffset,
119
- cutOffsetBottom: enzyme === 'Custom' ? cutOffset : cutOffsetBottom,
117
+ cutOffsetBottom,
120
118
  searchForward,
121
119
  searchReverse,
122
120
  excludePolyT: filterQuality,
@@ -1,11 +1,12 @@
1
- import type { TrackLabelMode } from '../types.ts';
1
+ import type { TrackLabelMode, ViewTrackLabelMode } from '../types.ts';
2
2
  import type { BaseExportSvgOptions } from '@jbrowse/core/ui';
3
3
  export default function ExportSvgDialog({ model, handleClose, }: {
4
4
  model: {
5
+ effectiveTrackLabels?: ViewTrackLabelMode;
5
6
  exportSvg(opts: BaseExportSvgOptions & {
6
7
  trackLabels: TrackLabelMode;
7
8
  showGridlines: boolean;
8
- }): Promise<void>;
9
+ }): Promise<unknown>;
9
10
  };
10
11
  handleClose: () => void;
11
12
  }): import("react").JSX.Element;
@@ -4,11 +4,15 @@ import { MenuItem, TextField } from '@mui/material';
4
4
  // Shared track-label + gridlines export dialog. Used by LGV, linear-synteny and
5
5
  // breakpoint-split views (their lazyDialogs re-export this).
6
6
  export default function ExportSvgDialog({ model, handleClose, }) {
7
- const [trackLabels, setTrackLabels] = useExportSvgPreference('tracklabels', 'offset');
7
+ // The view's own setting is already an export mode, so a user who has not
8
+ // picked one here gets the figure their screen shows. The key is `-mode`
9
+ // because the modes were once spelled `overlay`/`none`, and a stored one of
10
+ // those would select nothing in the dropdown.
11
+ const [trackLabels, setTrackLabels] = useExportSvgPreference('tracklabels-mode', model.effectiveTrackLabels ?? 'offset');
8
12
  const [showGridlines, setShowGridlines] = useExportSvgPreference('gridlines', false);
9
13
  return (_jsx(BaseExportSvgDialog, { model: model, handleClose: handleClose, exportSvg: opts => model.exportSvg({ ...opts, trackLabels, showGridlines }), checkboxes: _jsx(LabeledCheckbox, { checked: showGridlines, onChange: val => {
10
14
  setShowGridlines(val);
11
15
  }, label: "Show gridlines" }), children: _jsxs(TextField, { select: true, label: "Track label positioning", variant: "outlined", style: { minWidth: 200 }, value: trackLabels, onChange: event => {
12
16
  setTrackLabels(event.target.value);
13
- }, children: [_jsx(MenuItem, { value: "offset", children: "Offset" }), _jsx(MenuItem, { value: "overlay", children: "Overlay" }), _jsx(MenuItem, { value: "left", children: "Left" }), _jsx(MenuItem, { value: "none", children: "None" })] }) }));
17
+ }, children: [_jsx(MenuItem, { value: "offset", children: "Offset" }), _jsx(MenuItem, { value: "overlapping", children: "Overlapping" }), _jsx(MenuItem, { value: "left", children: "Left" }), _jsx(MenuItem, { value: "hidden", children: "Hidden" })] }) }));
14
18
  }
@@ -32,12 +32,12 @@ const GetSequenceDialog = observer(function GetSequenceDialog({ model, regions,
32
32
  // a selection this dialog will happily take is a whole chromosome of
33
33
  // sequence, so both handles are forwarded: closing the dialog stops the
34
34
  // read rather than leaving the worker on it, and the wait is named
35
- async (_name, _locs, stopToken, statusCallback) => {
35
+ async (_name, _locs, signal, statusCallback) => {
36
36
  if (regions.length === 0) {
37
37
  throw new Error('Selected region is out of bounds');
38
38
  }
39
39
  const chunks = await fetchSequence(model, regions, {
40
- stopToken,
40
+ signal,
41
41
  statusCallback,
42
42
  });
43
43
  // validate here (in the async path) so a length mismatch surfaces via the