@jbrowse/plugin-linear-genome-view 5.0.0-beta.19 → 5.0.0-beta.20

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 (47) hide show
  1. package/esm/LinearGenomeView/afterAttach.d.ts +17 -0
  2. package/esm/LinearGenomeView/afterAttach.js +71 -43
  3. package/esm/LinearGenomeView/components/CenterLine.js +6 -3
  4. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +2 -3
  5. package/esm/LinearGenomeView/components/ExportSvgDialog.js +12 -3
  6. package/esm/LinearGenomeView/components/Header.js +1 -1
  7. package/esm/LinearGenomeView/components/HeaderZoomControls.js +3 -2
  8. package/esm/LinearGenomeView/components/HighlightBand.js +7 -7
  9. package/esm/LinearGenomeView/components/ImportForm.js +3 -3
  10. package/esm/LinearGenomeView/components/MiniControls.js +1 -1
  11. package/esm/LinearGenomeView/components/OverviewRubberband.js +5 -3
  12. package/esm/LinearGenomeView/components/ResizeAllTracksHandle.js +7 -4
  13. package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -1
  14. package/esm/LinearGenomeView/components/SVGHighlightBand.js +15 -3
  15. package/esm/LinearGenomeView/components/SearchBox.js +3 -2
  16. package/esm/LinearGenomeView/components/SearchResultsTable.js +2 -2
  17. package/esm/LinearGenomeView/components/TrackContainer.js +1 -1
  18. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +2 -3
  19. package/esm/LinearGenomeView/components/fetchSequence.js +15 -7
  20. package/esm/LinearGenomeView/components/useRangeSelect.js +5 -2
  21. package/esm/LinearGenomeView/menuItems.js +5 -5
  22. package/esm/LinearGenomeView/model.d.ts +52 -40
  23. package/esm/LinearGenomeView/model.js +71 -50
  24. package/esm/LinearGenomeView/rExport/exportLinearView.d.ts +4 -0
  25. package/esm/LinearGenomeView/rExport/exportLinearView.js +26 -6
  26. package/esm/LinearGenomeView/rExport/rScript.d.ts +19 -9
  27. package/esm/LinearGenomeView/rExport/rScript.js +91 -53
  28. package/esm/LinearGenomeView/showRegionsWithUndo.js +5 -3
  29. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.d.ts +3 -1
  30. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +2 -2
  31. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +3 -1
  32. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +2 -2
  33. package/esm/LinearGenomeView/svgcomponents/SVGView.js +15 -1
  34. package/esm/LinearGenomeView/svgcomponents/util.d.ts +1 -0
  35. package/esm/LinearGenomeView/types.d.ts +6 -0
  36. package/esm/LinearGenomeView/types.js +0 -1
  37. package/esm/LinearGenomeView/util.js +9 -9
  38. package/esm/MultiLevelRubberband/useRangeSelect.js +14 -12
  39. package/esm/TrackModifiers/index.d.ts +4 -1
  40. package/esm/TrackModifiers/index.js +26 -7
  41. package/esm/displayKitTests/perRegionTestEnv.d.ts +2 -0
  42. package/esm/index.d.ts +2 -2
  43. package/esm/index.js +1 -1
  44. package/esm/searchUtils.d.ts +1 -3
  45. package/esm/searchUtils.js +33 -44
  46. package/esm/shared/useWindowDrag.js +11 -9
  47. package/package.json +7 -7
@@ -12,12 +12,15 @@ const MAX_REFNAME_HITS = 10;
12
12
  // shared dispatch used by SearchBox.onSelect and the LGV ImportForm submit:
13
13
  // route a chosen result to a direct nav, a multi-result dialog, or a generic
14
14
  // locstring/refname resolution
15
+ // Resolves whether the view moved: a hit that raised the picker, or a glob
16
+ // refused as too wide, did not.
15
17
  export async function navigateToSelectedOption({ option, model, assemblyName, }) {
16
18
  if (option.hasLocation()) {
17
19
  await navToOption({ option, model, assemblyName });
20
+ return true;
18
21
  }
19
22
  else if (option.results?.length) {
20
- await showSearchResults({
23
+ return showSearchResults({
21
24
  results: option.results,
22
25
  query: option.getLabel(),
23
26
  model,
@@ -25,7 +28,7 @@ export async function navigateToSelectedOption({ option, model, assemblyName, })
25
28
  });
26
29
  }
27
30
  else {
28
- await handleSelectedRegion({
31
+ return handleSelectedRegion({
29
32
  input: option.getLabel(),
30
33
  assemblyName,
31
34
  model,
@@ -159,9 +162,9 @@ export function notifySearchFailure(session, e) {
159
162
  console.error(e);
160
163
  session.notify(e instanceof SearchResultsNotFoundError ? e.message : `${e}`, 'warning');
161
164
  }
162
- // if input is a known ref or locstring, navigate directly;
163
- // otherwise search and: pop a dialog for multiple results, navigate for one,
164
- // or fall back to treating input as a locstring
165
+ // if input parses as one or more locstrings, navigate directly; otherwise
166
+ // search and: pop a dialog for multiple results, navigate for one, or report
167
+ // the miss
165
168
  //
166
169
  // Returns whether the view actually moved. Three branches deliberately do not
167
170
  // navigate — a glob too wide to open, a multi-hit search whose hits disagree
@@ -178,16 +181,11 @@ export async function handleSelectedRegion({ input, model, assemblyName, grow, s
178
181
  const assembly = await assemblyManager
179
182
  .waitForAssembly(assemblyName)
180
183
  .catch(() => undefined);
181
- // the same predicate navToLocstrings hands parseLocStrings, so a locstring
182
- // that passes here is one the parse below will accept
184
+ await Promise.all(assembliesNamedIn(input).map(name => assemblyManager.requireAssembly(name)));
183
185
  const isRef = (ref) => !!assembly && assemblyManager.isValidRefName(ref, assemblyName);
184
- // navigate treating input as one or more whitespace-separated locstrings
185
- const navToLocstrings = () => model.navToLocations(parseLocStrings(input, assemblyName, (ref, asm) => assemblyManager.isValidRefName(ref, asm)), assemblyName, grow);
186
- if (input
187
- .split(/\s+/)
188
- .filter(Boolean)
189
- .every(entry => checkRef(entry, isRef))) {
190
- await navToLocstrings();
186
+ const parsed = parseOrError(() => parseLocStrings(input, assemblyName, (ref, asm) => assemblyManager.isValidRefName(ref, asm)));
187
+ if (parsed.locations) {
188
+ await model.navToLocations(parsed.locations, assemblyName, grow);
191
189
  return true;
192
190
  }
193
191
  else if (input.includes('*') && !!assembly) {
@@ -273,34 +271,30 @@ export async function handleSelectedRegion({ input, model, assemblyName, grow, s
273
271
  return true;
274
272
  }
275
273
  else {
276
- // no search hits: still try to resolve the input as a locstring (bare
277
- // refname, "ref start end" triplet, etc). If that also can't find a
278
- // refname and the input names no sequence and no coordinate — a gene
279
- // name, or a phrase like "breast cancer" — reframe the unknown-ref error
280
- // as a name miss; keep the specific ref error for coordinate-shaped input
281
- try {
282
- await navToLocstrings();
283
- return true;
284
- }
285
- catch (e) {
286
- const isPlainName = !input.includes(':') &&
287
- input
288
- .trim()
289
- .split(/\s+/)
290
- .every(token => !isRef(token) && !/^\d[\d,]*$/.test(token));
291
- if (e instanceof UnknownRefNameError && isPlainName) {
292
- throw nameNotFound(input, assemblyName, found);
293
- }
294
- else {
295
- throw e;
296
- }
297
- }
274
+ // no search hits and no locstring either. An input naming no sequence
275
+ // and no coordinate — a gene name, or a phrase like "breast cancer" — is
276
+ // reported as a name miss; coordinate-shaped input keeps its ref error
277
+ const isPlainName = !input.includes(':') &&
278
+ input
279
+ .trim()
280
+ .split(/\s+/)
281
+ .every(token => !isRef(token) && !/^\d[\d,]*$/.test(token));
282
+ throw parsed.error instanceof UnknownRefNameError && isPlainName
283
+ ? nameNotFound(input, assemblyName, found)
284
+ : parsed.error;
298
285
  }
299
286
  }
300
287
  }
301
- export function checkRef(str, isRef) {
302
- const [ref, rest] = splitLast(str, ':');
303
- return isRef(str) || (isRef(ref) && /^\d/.test(rest));
288
+ function parseOrError(parse) {
289
+ try {
290
+ return { locations: parse() };
291
+ }
292
+ catch (error) {
293
+ return { error };
294
+ }
295
+ }
296
+ function assembliesNamedIn(input) {
297
+ return [...input.matchAll(/(?:^|\s)\{([^}]+)\}/g)].map(([, name]) => name);
304
298
  }
305
299
  async function searchNames({ queryString, searchType, assemblyName, textSearchManager, assembly, signal, }) {
306
300
  const report = await textSearchManager?.searchIndexes({
@@ -378,8 +372,3 @@ function searchRefNames(assembly, queryString, searchType) {
378
372
  weak: hits.filter(h => h.tier === 'substring').map(h => h.result),
379
373
  };
380
374
  }
381
- // splits on the last instance of a character
382
- export function splitLast(str, split) {
383
- const i = str.lastIndexOf(split);
384
- return i === -1 ? [str, ''] : [str.slice(0, i), str.slice(i + 1)];
385
- }
@@ -18,15 +18,17 @@ export function useWindowDrag(ref, startX, handlers) {
18
18
  const mouseMove = (event) => {
19
19
  onMove(event.clientX - left);
20
20
  };
21
- const mouseUp = ({ clientX, clientY }) => {
22
- const endX = clientX - left;
23
- onEnd({
24
- startX,
25
- endX,
26
- isClick: Math.abs(endX - startX) <= 3,
27
- clientX,
28
- clientY,
29
- });
21
+ const mouseUp = ({ button, clientX, clientY }) => {
22
+ if (button === 0) {
23
+ const endX = clientX - left;
24
+ onEnd({
25
+ startX,
26
+ endX,
27
+ isClick: Math.abs(endX - startX) <= 3,
28
+ clientX,
29
+ clientY,
30
+ });
31
+ }
30
32
  };
31
33
  const keyDown = (event) => {
32
34
  if (event.key === 'Escape') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-linear-genome-view",
3
- "version": "5.0.0-beta.19",
3
+ "version": "5.0.0-beta.20",
4
4
  "type": "module",
5
5
  "description": "JBrowse 2 linear genome view",
6
6
  "keywords": [
@@ -26,11 +26,11 @@
26
26
  "@mui/material": "^9.5.0",
27
27
  "mobx": "^7.1.3",
28
28
  "mobx-react": "^10.0.3",
29
- "@jbrowse/core": "^5.0.0-beta.19",
30
- "@jbrowse/display-kit": "^5.0.0-beta.19",
31
- "@jbrowse/launch-args": "^5.0.0-beta.19",
32
- "@jbrowse/display-ui": "^5.0.0-beta.19",
33
- "@jbrowse/render-core": "^5.0.0-beta.19"
29
+ "@jbrowse/core": "^5.0.0-beta.20",
30
+ "@jbrowse/display-ui": "^5.0.0-beta.20",
31
+ "@jbrowse/display-kit": "^5.0.0-beta.20",
32
+ "@jbrowse/render-core": "^5.0.0-beta.20",
33
+ "@jbrowse/launch-args": "^5.0.0-beta.20"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "react": ">=19.0.0",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "sideEffects": false,
43
43
  "devDependencies": {
44
- "@jbrowse/display-test-utils": "^5.0.0-beta.19"
44
+ "@jbrowse/display-test-utils": "^5.0.0-beta.20"
45
45
  },
46
46
  "scripts": {
47
47
  "prebuild": "pnpm clean",