@jbrowse/core 5.0.0-beta.1 → 5.0.0-beta.3

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 (199) hide show
  1. package/README.md +112 -43
  2. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +2 -3
  3. package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +4 -0
  4. package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +17 -0
  5. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +4 -3
  6. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +2 -2
  7. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +2 -2
  8. package/esm/BaseFeatureWidget/index.d.ts +1 -1
  9. package/esm/BaseFeatureWidget/stateModelFactory.d.ts +8 -1
  10. package/esm/BaseFeatureWidget/stateModelFactory.js +6 -0
  11. package/esm/BaseFeatureWidget/types.d.ts +10 -2
  12. package/esm/PluginLoader.d.ts +1 -0
  13. package/esm/PluginLoader.js +52 -8
  14. package/esm/PluginManager.d.ts +99 -17
  15. package/esm/PluginManager.js +194 -26
  16. package/esm/ReExports/BaseFeatureDetails.js +1 -1
  17. package/esm/ReExports/MuiDataGridReExports.d.ts +1 -0
  18. package/esm/ReExports/MuiDataGridReExports.js +2 -2
  19. package/esm/ReExports/barrelOnlyNames.d.ts +5 -0
  20. package/esm/ReExports/barrelOnlyNames.js +63 -0
  21. package/esm/ReExports/modules.js +31 -109
  22. package/esm/ReExports/publicTracks.d.ts +1 -0
  23. package/esm/ReExports/publicTracks.js +14 -0
  24. package/esm/ReExports/publicUi.d.ts +4 -0
  25. package/esm/ReExports/publicUi.js +33 -0
  26. package/esm/ReExports/publicUtil.d.ts +1 -1
  27. package/esm/ReExports/publicUtil.js +8 -4
  28. package/esm/ReExports/sharedModules.d.ts +96 -0
  29. package/esm/ReExports/sharedModules.js +66 -0
  30. package/esm/ReExports/uiStub.d.ts +2 -0
  31. package/esm/ReExports/uiStub.js +11 -0
  32. package/esm/ReExports/workerModules.d.ts +2 -0
  33. package/esm/ReExports/workerModules.js +15 -0
  34. package/esm/ReExports/workerNamespaceNames.d.ts +11 -0
  35. package/esm/ReExports/workerNamespaceNames.js +281 -0
  36. package/esm/configuration/configurationSchema.d.ts +5 -38
  37. package/esm/configuration/configurationSchema.js +64 -40
  38. package/esm/configuration/index.d.ts +2 -2
  39. package/esm/configuration/index.js +1 -1
  40. package/esm/configuration/promotableDefaults.d.ts +54 -19
  41. package/esm/configuration/promotableDefaults.js +117 -48
  42. package/esm/configuration/promotablePin.d.ts +50 -40
  43. package/esm/configuration/promotableResolve.d.ts +1 -1
  44. package/esm/configuration/promotableResolve.js +1 -1
  45. package/esm/configuration/tabixIndexFields.d.ts +2 -2
  46. package/esm/configuration/tabixIndexFields.js +2 -2
  47. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +12 -0
  48. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +35 -4
  49. package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +41 -0
  50. package/esm/data_adapters/BaseAdapter/featureDensity.js +32 -0
  51. package/esm/data_adapters/BaseAdapter/index.d.ts +2 -1
  52. package/esm/data_adapters/BaseAdapter/index.js +1 -0
  53. package/esm/data_adapters/BaseAdapter/stats.d.ts +33 -1
  54. package/esm/data_adapters/BaseAdapter/stats.js +52 -13
  55. package/esm/data_adapters/BaseAdapter/types.d.ts +3 -8
  56. package/esm/pluggableElementTypes/AdapterType.d.ts +2 -1
  57. package/esm/pluggableElementTypes/AdapterType.js +1 -1
  58. package/esm/pluggableElementTypes/DisplayType.d.ts +4 -12
  59. package/esm/pluggableElementTypes/DisplayType.js +3 -10
  60. package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +27 -0
  61. package/esm/pluggableElementTypes/LazyStateModelElement.js +71 -0
  62. package/esm/pluggableElementTypes/ViewType.d.ts +20 -4
  63. package/esm/pluggableElementTypes/ViewType.js +32 -4
  64. package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
  65. package/esm/pluggableElementTypes/extendElementType.js +9 -5
  66. package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +44 -3
  67. package/esm/pluggableElementTypes/models/BaseDisplayModel.js +75 -2
  68. package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +21 -0
  69. package/esm/pluggableElementTypes/models/BaseTrackModel.js +34 -2
  70. package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +49 -0
  71. package/esm/pluggableElementTypes/models/BaseViewModel.js +28 -0
  72. package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +14 -10
  73. package/esm/pluggableElementTypes/models/assertDisplayContract.js +25 -32
  74. package/esm/pluggableElementTypes/models/baseTrackConfig.js +7 -1
  75. package/esm/rpc/RpcRegistry.d.ts +10 -0
  76. package/esm/rpc/byteBudget.d.ts +9 -0
  77. package/esm/rpc/coreRpcMethods.d.ts +1 -0
  78. package/esm/rpc/coreRpcMethods.js +1 -0
  79. package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +11 -0
  80. package/esm/rpc/methods/CoreGetFeatureDensity.js +22 -0
  81. package/esm/svg/svgReady.d.ts +1 -0
  82. package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
  83. package/esm/ui/CascadingMenu.js +30 -8
  84. package/esm/ui/ErrorMessageStackTraceDialog.js +5 -6
  85. package/esm/ui/ExportSvgDialog.d.ts +1 -1
  86. package/esm/ui/LoadingOverlay.d.ts +14 -0
  87. package/esm/ui/LoadingOverlay.js +1 -1
  88. package/esm/ui/MenuTypes.d.ts +14 -5
  89. package/esm/ui/MenuTypes.js +3 -0
  90. package/esm/ui/PaletteContext.d.ts +11 -4
  91. package/esm/ui/PaletteContext.js +34 -5
  92. package/esm/ui/PinAdornment.js +31 -43
  93. package/esm/ui/ScrollChrome.d.ts +16 -0
  94. package/esm/ui/ScrollChrome.js +12 -0
  95. package/esm/ui/ScrollZoomToggle.d.ts +4 -3
  96. package/esm/ui/ScrollZoomToggle.js +4 -3
  97. package/esm/ui/SizeSliderRow.js +1 -1
  98. package/esm/ui/index.d.ts +3 -3
  99. package/esm/ui/index.js +4 -4
  100. package/esm/ui/launchViewMenu.js +7 -1
  101. package/esm/ui/legendMenuItem.d.ts +10 -16
  102. package/esm/ui/legendMenuItem.js +9 -20
  103. package/esm/ui/makeSizeMenu.js +1 -1
  104. package/esm/ui/menuItemAdornment.d.ts +2 -3
  105. package/esm/ui/menuItemAdornment.js +2 -3
  106. package/esm/ui/menuItems.d.ts +2 -3
  107. package/esm/ui/menuItems.js +1 -2
  108. package/esm/ui/palette.d.ts +11 -11
  109. package/esm/ui/palette.js +11 -11
  110. package/esm/ui/promotablePinCoverage.d.ts +16 -2
  111. package/esm/ui/promotablePinCoverage.js +40 -3
  112. package/esm/ui/theme.js +5 -0
  113. package/esm/ui/toggleMenuItems.d.ts +14 -9
  114. package/esm/ui/toggleMenuItems.js +32 -15
  115. package/esm/util/Base1DUtils.d.ts +4 -2
  116. package/esm/util/Base1DUtils.js +12 -4
  117. package/esm/util/SvgCanvas.js +4 -3
  118. package/esm/util/adapterConfigKey.d.ts +12 -0
  119. package/esm/util/adapterConfigKey.js +14 -0
  120. package/esm/util/adapterMetadata.js +2 -1
  121. package/esm/util/addAndShowTrack.d.ts +1 -1
  122. package/esm/util/addAndShowTrack.js +5 -1
  123. package/esm/util/addTrackFromWidget.js +2 -2
  124. package/esm/util/analytics.js +4 -5
  125. package/esm/util/cacheBudgets.d.ts +22 -19
  126. package/esm/util/cacheBudgets.js +22 -19
  127. package/esm/util/clampToContig.d.ts +17 -0
  128. package/esm/util/clampToContig.js +19 -0
  129. package/esm/util/colorBits.d.ts +2 -1
  130. package/esm/util/colorBits.js +2 -5
  131. package/esm/util/createStopTokenRotation.d.ts +9 -7
  132. package/esm/util/createStopTokenRotation.js +7 -27
  133. package/esm/util/featureTypes.d.ts +24 -0
  134. package/esm/util/featureTypes.js +35 -0
  135. package/esm/util/fetchContext.d.ts +2 -2
  136. package/esm/util/fetchContext.js +2 -2
  137. package/esm/util/fetchPhases.d.ts +10 -10
  138. package/esm/util/hooks.d.ts +8 -0
  139. package/esm/util/hooks.js +27 -0
  140. package/esm/util/index.d.ts +6 -5
  141. package/esm/util/index.js +5 -4
  142. package/esm/util/installFetch.d.ts +71 -34
  143. package/esm/util/installFetch.js +57 -29
  144. package/esm/util/installInitAutorun.d.ts +14 -13
  145. package/esm/util/installInitAutorun.js +17 -17
  146. package/esm/util/installPrerequisiteFetch.d.ts +86 -0
  147. package/esm/util/installPrerequisiteFetch.js +73 -0
  148. package/esm/util/lazyAfterAttach.d.ts +13 -0
  149. package/esm/util/lazyAfterAttach.js +31 -0
  150. package/esm/util/legendCandidates.d.ts +50 -0
  151. package/esm/util/legendCandidates.js +87 -0
  152. package/esm/util/mstUtils.d.ts +12 -1
  153. package/esm/util/mstUtils.js +20 -2
  154. package/esm/util/openFeatureWidget.d.ts +5 -0
  155. package/esm/util/openFeatureWidget.js +1 -0
  156. package/esm/util/openViews.d.ts +16 -0
  157. package/esm/util/openViews.js +22 -0
  158. package/esm/util/parentWalk.d.ts +1 -1
  159. package/esm/util/parentWalk.js +1 -1
  160. package/esm/util/pluginStore.d.ts +1 -0
  161. package/esm/util/pluginStore.js +8 -1
  162. package/esm/util/range.d.ts +13 -9
  163. package/esm/util/range.js +17 -8
  164. package/esm/util/renderToStaticMarkup.js +10 -0
  165. package/esm/util/rxjs.d.ts +16 -0
  166. package/esm/util/rxjs.js +49 -0
  167. package/esm/util/scheduleDetachedDestroy.d.ts +18 -0
  168. package/esm/util/scheduleDetachedDestroy.js +24 -0
  169. package/esm/util/scrollLatch.d.ts +1 -0
  170. package/esm/util/scrollLatch.js +8 -0
  171. package/esm/util/stopToken.d.ts +6 -5
  172. package/esm/util/tabix.d.ts +10 -4
  173. package/esm/util/tabix.js +11 -5
  174. package/esm/util/trackConfigDelta.d.ts +6 -6
  175. package/esm/util/trackConfigDelta.js +3 -3
  176. package/esm/util/tracks.d.ts +48 -0
  177. package/esm/util/tracks.js +192 -66
  178. package/esm/util/types/index.d.ts +58 -10
  179. package/esm/util/types/index.js +3 -0
  180. package/esm/util/unknownSnapshotKeys.d.ts +36 -0
  181. package/esm/util/unknownSnapshotKeys.js +69 -0
  182. package/esm/util/usePanelVirtualScroll.d.ts +6 -2
  183. package/esm/util/usePanelVirtualScroll.js +6 -2
  184. package/esm/util/useRowVirtualScroll.d.ts +1 -1
  185. package/esm/util/useRowVirtualScroll.js +1 -1
  186. package/esm/util/useVirtualScrollWheel.js +11 -1
  187. package/esm/util/viewStatus.d.ts +23 -0
  188. package/esm/util/viewStatus.js +17 -0
  189. package/esm/util/wheelZoom.d.ts +3 -1
  190. package/esm/util/wheelZoom.js +39 -14
  191. package/esm/util/whenViewSettled.d.ts +17 -4
  192. package/esm/util/whenViewSettled.js +19 -6
  193. package/esm/util/withLaunchInput.d.ts +168 -0
  194. package/esm/util/withLaunchInput.js +273 -0
  195. package/package.json +19 -11
  196. package/esm/ui/promotableMenuItems.d.ts +0 -19
  197. package/esm/ui/promotableMenuItems.js +0 -89
  198. package/esm/util/applyInitSettings.d.ts +0 -79
  199. package/esm/util/applyInitSettings.js +0 -91
@@ -26,3 +26,22 @@ export function clampToContig(assembly, region) {
26
26
  ? { ...region, assemblyName: assembly.name, refName, start, end }
27
27
  : undefined;
28
28
  }
29
+ /**
30
+ * `clampToContig` for a refName that may not be on the assembly at all, which
31
+ * is the shape a location nobody requested arrives in — a BAM's `nextRef`, an
32
+ * SA record's contig (REFNAME_NAMESPACES.md). `clampToContig` alone passes an
33
+ * unknown name through with nothing to clamp against, so it cannot tell "past
34
+ * the end of a contig we have" from "a contig we do not have", and both callers
35
+ * need that apart to say which happened.
36
+ */
37
+ export function clampToListedContig(assembly, region) {
38
+ const refName = assembly.getCanonicalRefName2(region.refName);
39
+ const onAssembly = assembly.getRegionForRefName(refName) !== undefined;
40
+ return {
41
+ refName,
42
+ onAssembly,
43
+ region: onAssembly
44
+ ? clampToContig(assembly, { ...region, refName })
45
+ : undefined,
46
+ };
47
+ }
@@ -1,5 +1,7 @@
1
+ import { abgrToCssRgba } from '@jbrowse/render-core/marks/colorFill';
1
2
  import type { Color } from './color-bits/index.ts';
2
3
  import type { Feature } from './simpleFeature.ts';
4
+ export { abgrToCssRgba };
3
5
  export { alpha, blend, darken, formatHEX, formatHEXA, formatRGBA, getAlpha, getBlue, getGreen, getLuminance, getRed, lighten, newColor, parse, toHSLA, toRGBA, } from './color-bits/index.ts';
4
6
  export type { Color } from './color-bits/index.ts';
5
7
  /**
@@ -35,5 +37,4 @@ export declare function abgrRed(c: number): number;
35
37
  export declare function abgrGreen(c: number): number;
36
38
  export declare function abgrBlue(c: number): number;
37
39
  export declare function abgrAlpha(c: number): number;
38
- export declare function abgrToCssRgba(c: number): string;
39
40
  export declare function cssColorToNormalizedRgba(color: string): [number, number, number, number];
@@ -1,5 +1,7 @@
1
+ import { abgrToCssRgba } from '@jbrowse/render-core/marks/colorFill';
1
2
  import { getAlpha, getBlue, getGreen, getRed, newColor, parse, } from './color-bits/index.js';
2
3
  import { namedColorToHex } from './color/cssColorsLevel4.js';
4
+ export { abgrToCssRgba };
3
5
  export { alpha, blend, darken, formatHEX, formatHEXA, formatRGBA, getAlpha, getBlue, getGreen, getLuminance, getRed, lighten, newColor, parse, toHSLA, toRGBA, } from './color-bits/index.js';
4
6
  // Magenta sentinel for invalid input. User-written jexl color callbacks can
5
7
  // legitimately return undefined (e.g. when a feature lacks the field they
@@ -143,7 +145,6 @@ export function normalizedRgbToCss(c) {
143
145
  export function normalizedRgbToCssRgba(c, alpha) {
144
146
  return `rgba(${Math.round(c[0] * 255)},${Math.round(c[1] * 255)},${Math.round(c[2] * 255)},${alpha})`;
145
147
  }
146
- // Set fillStyle from an ABGR-packed u32.
147
148
  export function setAbgrFill(ctx, c) {
148
149
  ctx.fillStyle = abgrToCssRgba(c);
149
150
  }
@@ -165,10 +166,6 @@ export function abgrBlue(c) {
165
166
  export function abgrAlpha(c) {
166
167
  return (c >>> 24) & 0xff;
167
168
  }
168
- // Format an ABGR-packed u32 as a CSS rgba() string.
169
- export function abgrToCssRgba(c) {
170
- return `rgba(${abgrRed(c)},${abgrGreen(c)},${abgrBlue(c)},${abgrAlpha(c) / 255})`;
171
- }
172
169
  export function cssColorToNormalizedRgba(color) {
173
170
  const c = parseCssColor(color);
174
171
  return [
@@ -13,19 +13,20 @@ import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
13
13
  */
14
14
  export type StatusReporter = {
15
15
  /**
16
- * The host's own window, present on any display composing the LGV fetch
17
- * mixins. The rotation reports through it rather than opening a SECOND on
18
- * the same status field — which is what one-window-per-owner exists to
16
+ * The host's own window, present on any display composing `FetchMixin`.
17
+ * The rotation reports through it rather than opening a SECOND on the
18
+ * same status field — which is what one-window-per-owner exists to
19
19
  * prevent.
20
20
  */
21
21
  statusWindow: StatusWindow;
22
22
  setStatusMessage?: never;
23
23
  } | {
24
24
  /**
25
- * The sink for the window the rotation opens for itself. This is the mode
26
- * the displays this helper was written for are in (dotplot, synteny),
27
- * which compose no fetch mixin, along with every
28
- * {@link createStatusChannel} holder.
25
+ * The sink for the window the rotation opens for itself: the mode of a
26
+ * fetch on a host with no window of its own — the prerequisite reads,
27
+ * chord, the breakpoint overlay — along with every
28
+ * {@link createStatusChannel} holder. The comparative displays this
29
+ * helper was written for lend a window now (ADR-105).
29
30
  */
30
31
  setStatusMessage: (status?: RpcStatus) => void;
31
32
  statusWindow?: never;
@@ -110,6 +111,7 @@ export interface ActiveFetch {
110
111
  * passes a {@link createStatusChannel}, which is one volatile instead of two
111
112
  * fields and an action.
112
113
  */
114
+ export type StopTokenRotation = ReturnType<typeof createStopTokenRotation>;
113
115
  export declare function createStopTokenRotation(self: IStateTreeNode, report: StatusReporter): {
114
116
  begin(): ActiveFetch;
115
117
  cancel: () => void;
@@ -28,33 +28,6 @@ export function createStatusChannel() {
28
28
  },
29
29
  };
30
30
  }
31
- /**
32
- * Latest-wins stop-token rotation for a fetch that runs in a bare `autorun`
33
- * rather than through `FetchMixin.runFetch` (which welds the same mechanics to
34
- * `fetchGeneration`, so it's only for viewport-driven LGV fetches). Each
35
- * `begin()` aborts the prior fetch's token and returns a fresh one plus an
36
- * `isCurrent()` guard that captures this run's token — gate every post-await
37
- * write on it and a superseded or torn-down fetch can never clobber fresher
38
- * data. The guard is the return value, so a caller can't forget to compare a
39
- * token by hand.
40
- *
41
- * `end()` in the run's `finally` is the other half, and for the same reason —
42
- * see {@link ActiveFetch.end} for the two things it does together.
43
- *
44
- * Owns the token mechanics and the status channel; the caller keeps its own
45
- * loading/error/commit side-effects. Three holders: `FetchMixin` as a member
46
- * (so `cancelFetch` can reach it), `installFetch` one per installation (every
47
- * other fetch in the tree runs on that skeleton), and the synteny diagonalize
48
- * progress wrapper (`withDiagonalizeProgress`) directly.
49
- *
50
- * `report` is passed rather than read off `self`, so where the status lands is
51
- * the caller's decision and not a shape this imposes. A display passes itself —
52
- * its status fields are part of its own API, and one composing `FetchMixin`
53
- * passes the model-wide window along with them (see `StatusReporter`).
54
- * Anything with one operation to narrate and no status vocabulary of its own
55
- * passes a {@link createStatusChannel}, which is one volatile instead of two
56
- * fields and an action.
57
- */
58
31
  export function createStopTokenRotation(self, report) {
59
32
  let currentStopToken;
60
33
  // The host's window when it has one, so a display composing `FetchMixin` has
@@ -124,6 +97,13 @@ export function createStopTokenRotation(self, report) {
124
97
  statusCallback: stream.statusCallback,
125
98
  end() {
126
99
  ended = true;
100
+ // A completed fetch's token is released here, not only on supersede
101
+ // or cancel — otherwise it pins its AbortSignal controllers (and blob
102
+ // URL) until the next `begin()`, forever for a one-shot fetch that
103
+ // succeeds and never reruns. `stopStopToken` is guarded, so the
104
+ // superseded and cancelled runs that arrive here already-stopped cost
105
+ // nothing.
106
+ stopStopToken(stopToken);
127
107
  if (openStream === stream) {
128
108
  openStream = undefined;
129
109
  }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Classification of a feature from its `type` string alone, for the plugins
3
+ * that decide something about a feature they did not parse. A type is the only
4
+ * thing a display, a menu or a widget can ask about a feature without knowing
5
+ * which adapter produced it, so these live in core rather than beside any one
6
+ * of their callers.
7
+ */
8
+ /**
9
+ * Whether the type names a unit of transcription — a gene, a transcript, or an
10
+ * RNA, including the pseudogene and V(D)J segment spellings. This is the
11
+ * question "does this feature have exons", not "can this feature be spliced":
12
+ * an alignment splices too and is deliberately not gene-like, because a caller
13
+ * that means to launch a protein view or read a CDS would be wrong about it.
14
+ */
15
+ export declare function isGeneLikeType(type: string | undefined): boolean;
16
+ /**
17
+ * Whether the type names a sequence alignment — SO `match` and its subtypes
18
+ * (`cDNA_match`, `EST_match`, `nucleotide_match`, `protein_match`,
19
+ * `translated_nucleotide_match`), whose `match_part` children are the aligned
20
+ * blocks and whose gaps between them are introns when the aligned sequence was
21
+ * a transcript. Separate from `isGeneLikeType` on purpose: an EST alignment is
22
+ * evidence for a gene, not one.
23
+ */
24
+ export declare function isSequenceMatchType(type: string | undefined): boolean;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Classification of a feature from its `type` string alone, for the plugins
3
+ * that decide something about a feature they did not parse. A type is the only
4
+ * thing a display, a menu or a widget can ask about a feature without knowing
5
+ * which adapter produced it, so these live in core rather than beside any one
6
+ * of their callers.
7
+ */
8
+ // Anchored at the end for gene and RNA so 'intergenic_region' is not a gene and
9
+ // 'rnapol_binding_site' is not an RNA. Unanchored for transcript, which SO
10
+ // spells both ways ('transcript', 'pseudogenic_transcript', 'transcript_region').
11
+ const GENE_LIKE_TYPE = /gene(_segment)?$|rna$|transcript/;
12
+ /**
13
+ * Whether the type names a unit of transcription — a gene, a transcript, or an
14
+ * RNA, including the pseudogene and V(D)J segment spellings. This is the
15
+ * question "does this feature have exons", not "can this feature be spliced":
16
+ * an alignment splices too and is deliberately not gene-like, because a caller
17
+ * that means to launch a protein view or read a CDS would be wrong about it.
18
+ */
19
+ export function isGeneLikeType(type) {
20
+ return type !== undefined && GENE_LIKE_TYPE.test(type.toLowerCase());
21
+ }
22
+ // SO `match` and every subtype of it is spelled `<something>_match`, so the
23
+ // suffix is the family. `match_part`, the child, is excluded by the anchor.
24
+ const SEQUENCE_MATCH_TYPE = /(^|_)match$/;
25
+ /**
26
+ * Whether the type names a sequence alignment — SO `match` and its subtypes
27
+ * (`cDNA_match`, `EST_match`, `nucleotide_match`, `protein_match`,
28
+ * `translated_nucleotide_match`), whose `match_part` children are the aligned
29
+ * blocks and whose gaps between them are introns when the aligned sequence was
30
+ * a transcript. Separate from `isGeneLikeType` on purpose: an EST alignment is
31
+ * evidence for a gene, not one.
32
+ */
33
+ export function isSequenceMatchType(type) {
34
+ return type !== undefined && SEQUENCE_MATCH_TYPE.test(type.toLowerCase());
35
+ }
@@ -39,8 +39,8 @@ export interface FetchContext {
39
39
  }
40
40
  /**
41
41
  * Build a {@link FetchContext} over a live fetch's primitives. One
42
- * constructor, so every context — `runFetch`'s, the prerequisite skeleton's —
43
- * carries the same `callRpc` envelope.
42
+ * constructor, so every context — `FetchMixin.runFetch`'s and `runFetchOnce`'s
43
+ * alike — carries the same `callRpc` envelope.
44
44
  *
45
45
  * **`self` has to be somewhere `getRpcSessionId` can find one, which in practice
46
46
  * means a track or something under it.** `rpcSessionId` is declared by
@@ -3,8 +3,8 @@ import { createStatusFanOut } from './progress.js';
3
3
  import { getRpcHost } from './sessionServices.js';
4
4
  /**
5
5
  * Build a {@link FetchContext} over a live fetch's primitives. One
6
- * constructor, so every context — `runFetch`'s, the prerequisite skeleton's —
7
- * carries the same `callRpc` envelope.
6
+ * constructor, so every context — `FetchMixin.runFetch`'s and `runFetchOnce`'s
7
+ * alike — carries the same `callRpc` envelope.
8
8
  *
9
9
  * **`self` has to be somewhere `getRpcSessionId` can find one, which in practice
10
10
  * means a track or something under it.** `rpcSessionId` is declared by
@@ -4,10 +4,10 @@
4
4
  * remembered.
5
5
  *
6
6
  * The shared `installFetch` skeleton takes this shape, and so does the LGV
7
- * global family (`installGlobalFetchAutorun`, over `FetchMixin.runFetch`). It
8
- * was the same contract declared twice, with the same three rules explained
9
- * twice, which is a drift axis over rules whose whole value is being the same
10
- * everywhere.
7
+ * global family (`installGlobalFetchAutorun`, a declaration over that same
8
+ * skeleton). It was the same contract declared twice, with the same three rules
9
+ * explained twice, which is a drift axis over rules whose whole value is being
10
+ * the same everywhere.
11
11
  *
12
12
  * `TCtx` is what a family hands its `run`: a `FetchContext` for most of them, a
13
13
  * `ComparativeFetchContext` (that plus adapter config and refName rename) for
@@ -43,7 +43,7 @@ export interface FetchPhases<TArgs, TResult, TCtx> {
43
43
  * gets a dead Retry button — see there.
44
44
  *
45
45
  * What it must **not** do is move a trigger read of its own under a bail-out.
46
- * See ARCHITECTURE.md §"The global-fetch trigger list must be read
46
+ * See reference/FETCH_SKELETON.md §"The global-fetch trigger list must be read
47
47
  * unconditionally".
48
48
  */
49
49
  prepare: () => TArgs | undefined;
@@ -56,11 +56,11 @@ export interface FetchPhases<TArgs, TResult, TCtx> {
56
56
  * **Nothing it reads is tracked**, so the payload it assembles cannot widen
57
57
  * the autorun's dependency set the way calling `rpcProps()` in the body would.
58
58
  * Being async is not what buys that — `run` is *called* synchronously, so its
59
- * own prefix down to its first `await` runs wherever the caller was. Each
60
- * family arranges it: the global one reaches `run` through
61
- * `FetchMixin.runFetch`, an MST flow and so an action, which MobX runs
62
- * untracked; the comparative one calls its lifecycle inside `untracked`
63
- * because it has no action to hide behind.
59
+ * own prefix down to its first `await` runs wherever the caller was. The
60
+ * `installFetch` skeleton calls it inside `untracked`, which covers the
61
+ * global and comparative families with it; the per-region family reaches its
62
+ * work through `FetchMixin.runFetch`, an MST flow and so an action, which
63
+ * MobX runs untracked.
64
64
  */
65
65
  run: (args: TArgs, ctx: TCtx) => Promise<TResult | undefined>;
66
66
  /**
@@ -20,6 +20,14 @@ export declare function useWidthSetter(view: {
20
20
  * "avoiding recreating the ref contents" pattern.
21
21
  */
22
22
  export declare function useCreateOnce<T>(create: () => T): T;
23
+ /**
24
+ * `useCreateOnce` for an asynchronous factory: returns undefined until
25
+ * `create` resolves, and rethrows a rejection from render. The value can
26
+ * resolve after the component is gone — a caller whose value is expensive to
27
+ * leak should use product-core's `useAsyncEngineLifecycle`, which discards
28
+ * that late arrival.
29
+ */
30
+ export declare function useCreateOnceAsync<T>(create: () => Promise<T>): T | undefined;
23
31
  /**
24
32
  * Run `cleanup` when the component *really* unmounts.
25
33
  *
package/esm/util/hooks.js CHANGED
@@ -112,6 +112,33 @@ export function useCreateOnce(create) {
112
112
  ref.current ??= { value: create() };
113
113
  return ref.current.value;
114
114
  }
115
+ /**
116
+ * `useCreateOnce` for an asynchronous factory: returns undefined until
117
+ * `create` resolves, and rethrows a rejection from render. The value can
118
+ * resolve after the component is gone — a caller whose value is expensive to
119
+ * leak should use product-core's `useAsyncEngineLifecycle`, which discards
120
+ * that late arrival.
121
+ */
122
+ export function useCreateOnceAsync(create) {
123
+ const started = useRef(false);
124
+ const [state, setState] = useState();
125
+ useEffect(() => {
126
+ if (!started.current) {
127
+ started.current = true;
128
+ create().then(value => {
129
+ setState({ value });
130
+ }, (error) => {
131
+ setState({ error });
132
+ });
133
+ }
134
+ // create is read on the first effect only, as in useCreateOnce
135
+ // eslint-disable-next-line @eslint-react/exhaustive-deps
136
+ }, []);
137
+ if (state && 'error' in state) {
138
+ throw state.error;
139
+ }
140
+ return state?.value;
141
+ }
115
142
  /**
116
143
  * Run `cleanup` when the component *really* unmounts.
117
144
  *
@@ -3,7 +3,7 @@ export { capitalizeFirst, pluralize, shorten, shorten2, truncateMiddle, } from '
3
3
  export { formatBytes } from './formatBytes.ts';
4
4
  export { getFillProps, getStrokeProps, stripAlpha } from './svgColorProps.ts';
5
5
  export { fetchAndMaybeUnzip, fetchAndMaybeUnzipText, isGzip, } from './fetchAndMaybeUnzip.ts';
6
- export { type AbstractDisplayModel, type AbstractMenuManager, type AbstractRootModel, type AbstractSessionModel, type AbstractTrackModel, type AbstractViewContainer, type AbstractViewModel, type AnimationMode, type AnyReactComponentType, type AppRootModel, type AssemblyHost, type AssemblyManager, type AugmentedRegion, AuthNeededError, type BasePlugin, type BlobLocation, type ClassReturnedBy, type ConnectionInstance, type DialogComponentType, type DialogHost, type DrawerPosition, type FileHandleLocation, type FileLocation, type InstanceTypeRestrictive, type JBrowsePlugin, type JBrowsePluginVersion, type LocalPathLocation, type NoAssemblyRegion, type NotificationLevel, type NotificationSink, type PaletteHost, type PreBlobLocation, type PreFileHandleLocation, type PreFileLocation, type PreLocalPathLocation, type PreUriLocation, type Region, type RenderingServices, type RpcCaller, type RpcHost, type RootModelWithInternetAccounts, type SelectionContainer, type SessionServices, type SessionWithAddAssembly, type SessionWithAddSessionTrack, type SessionWithPublishTrackConf, type SessionWithConfigEditing, type SessionWithConnectionEditing, type SessionWithConnections, type SessionWithDeleteTrackConf, type SessionWithDrawerWidgets, type SessionWithFocusedViewAndDrawerWidgets, type SessionWithPermanentPlugins, type SessionWithSessionPlugins, type SessionWithShareURL, type SessionWithViewReplacement, type SessionWithWidgets, type SnackAction, type TrackActionView, type TrackCatalog, type TrackContainer, type TrackViewModel, type TypeTestedByPredicate, type UriLocation, type Widget, type WidgetMap, addOrReplaceView, canReplaceView, isAbstractMenuManager, isAppRootModel, isAuthNeededException, isBlobLocation, isDisplayModel, isFileHandleLocation, isLocalPathLocation, isRootModelWithInternetAccounts, isSelectionContainer, isSessionModel, isSessionServices, isSessionModelWithConfigEditing, isSessionModelWithConnectionEditing, isSessionModelWithConnections, isSessionModelWithWidgets, isSessionWithAddAssembly, isSessionWithAddSessionTrack, isSessionWithAddTracks, isSessionWithPublishTrackConf, isSessionWithDeleteTrackConf, isSessionWithPermanentPlugins, isSessionWithSessionPlugins, isSessionWithSessionTracks, isSessionWithShareURL, isSessionWithViewReplacement, isTrackModel, isTrackViewModel, isUriLocation, isViewContainer, isViewModel, } from './types/index.ts';
6
+ export { type AbstractDisplayModel, type AbstractMenuManager, type AbstractRootModel, type AbstractSessionModel, type AbstractTrackModel, type AbstractViewContainer, type AbstractViewModel, type AnimationMode, type AnyReactComponentType, type AppRootModel, type AssemblyHost, type AssemblyManager, type AugmentedRegion, AuthNeededError, type BasePlugin, type BlobLocation, type ClassReturnedBy, type ConnectionInstance, type DialogComponentType, type DialogHost, type DrawerPosition, type FileHandleLocation, type FileLocation, type InstanceTypeRestrictive, type JBrowsePlugin, type JBrowsePluginVersion, type LocalPathLocation, type NoAssemblyRegion, type NotificationLevel, type NotificationSink, type PaletteHost, type PreBlobLocation, type PreFileHandleLocation, type PreFileLocation, type PreLocalPathLocation, type PreUriLocation, type Region, type RenderingServices, type RpcCaller, type RpcHost, type RootModelWithInternetAccounts, type SelectionContainer, type SessionServices, type SessionWithAddAssembly, type SessionWithAddSessionTrack, type SessionWithPublishTrackConf, type SessionWithConfigEditing, type SessionWithConnectionEditing, type SessionWithConnections, type SessionWithDeleteTrackConf, type SessionWithDrawerWidgets, type SessionWithFocusedViewAndDrawerWidgets, type SessionWithPermanentPlugins, type SessionWithSessionPlugins, type SessionWithShareURL, type SessionWithViewReplacement, type SessionWithWidgets, type SnackAction, type TrackActionView, type TrackCatalog, type TrackContainer, type TrackViewModel, type TypeTestedByPredicate, type UriLocation, type Widget, type WidgetMap, addOrReplaceView, canReplaceView, isAbstractMenuManager, isAppRootModel, isAuthNeededException, isBlobLocation, isDisplayModel, isFileHandleLocation, isLocalPathLocation, isRootModelWithInternetAccounts, isSelectionContainer, isSessionModel, isSessionServices, isSessionModelWithConfigEditing, isSessionModelWithConnectionEditing, isSessionModelWithConnections, isSessionModelWithWidgets, isSessionWithAddAssembly, isSessionWithAddSessionTrack, isSessionWithAddTracks, isSessionWithPublishTrackConf, isSessionWithDeleteTrackConf, isSessionWithMultipleViews, isSessionWithPermanentPlugins, isSessionWithSessionPlugins, isSessionWithSessionTracks, isSessionWithShareURL, isSessionWithViewReplacement, isTrackModel, isTrackViewModel, isUriLocation, isViewContainer, isViewModel, } from './types/index.ts';
7
7
  export { type PluginUpdate, type ResolvedPlugin, type StorePluginFailure, type StorePluginResolution, getPluginUpdate, installablePlugins, installedVersionFromUrl, isPluginInstalled, resolvePlugin, resolveStorePluginRefs, resolveStoreRefs, } from './pluginStore.ts';
8
8
  export { type PhaseFailure, type ProgressReporter, type RpcStatus, type StatusCallback, type StatusPhase, type StatusStream, type StatusWindow, type StatusWithProgress, createProgressReporter, createStatusFanOut, createStatusWindow, downloadStatus, progressLabel, statusFraction, statusMessageText, statusProgressLabel, statusReading, statusSource, throttleStatusEmits, updateStatus, withProgress, } from './progress.ts';
9
9
  export { calculateRedispatchRange, doesIntersect2, intersection2, } from './range.ts';
@@ -22,7 +22,7 @@ export { MAX_ZOOM_RATE_PER_MS, SCROLL_ZOOM_FACTOR_DIVISOR, ZOOM_ACTIVE_WINDOW_MS
22
22
  export { avg, clamp, getDisplayStr, getNumberGrouping, max, maxFinite, min, minmax, polarToCartesian, radToDeg, reducePrecision, setNumberGrouping, sum, toLocale, } from './numericUtils.ts';
23
23
  export { type MinimalRegion, bpSpanPx, bpToPx, bytesForRegions, featureSpanPx, getBpDisplayStr, getTickDisplayStr, parseBpString, } from './bpUtils.ts';
24
24
  export { type BasicFeature, gatherOverlaps, mergeIntervals, } from './intervals.ts';
25
- export { clampToContig } from './clampToContig.ts';
25
+ export { clampToContig, clampToListedContig } from './clampToContig.ts';
26
26
  export { animationAllowed } from './animationAllowed.ts';
27
27
  export { springAnimate } from './springAnimate.ts';
28
28
  export { localStorageAvailable, localStorageGetBoolean, localStorageGetItem, localStorageGetJSON, localStorageGetNumber, localStorageGetStringArray, localStorageRemoveItem, localStorageSetBoolean, localStorageSetItem, localStorageSetJSON, localStorageSetNumber, notifyLocalStorageKey, subscribeToLocalStorageKey, } from './localStorage.ts';
@@ -44,9 +44,9 @@ export { downloadPhase, getLocationUri, resolveUri } from './getLocationUri.ts';
44
44
  export { measureGridWidth, resolveSelectedIds } from './dataGridUtils.ts';
45
45
  export { isRpcResult } from './rpc.ts';
46
46
  export { aesDecrypt, aesEncrypt, sha256, sha256Base64, sha256Base64Url, toBase64, toBase64Url, } from './crypto.ts';
47
- export { type FeatureWidgetTypeRef, notifyFeatureDetailsMiss, openFeatureWidget, } from './openFeatureWidget.ts';
47
+ export { type FeatureWidgetTypeRef, type ParentFeatureSummary, notifyFeatureDetailsMiss, openFeatureWidget, } from './openFeatureWidget.ts';
48
48
  export { withFeatureDetails } from './withFeatureDetails.ts';
49
- export { canonicalizeViewRefName, findParentThat, findParentThatIs, getAssemblyHost, getContainingDisplay, getContainingTrack, getContainingView, getEnv, getRenderingServices, getSession, hashCode, objectHash, } from './mstUtils.ts';
49
+ export { canonicalizeViewRefName, findParentThat, findParentThatIs, getAssemblyHost, getContainingDisplay, getContainingTrack, getContainingView, getEnv, getRenderingServices, launchOrReplaceView, getSession, hashCode, objectHash, } from './mstUtils.ts';
50
50
  export { getDialogHost, getNotificationSink, getPaletteHost, getRpcHost, getSessionServices, } from './sessionServices.ts';
51
51
  /**
52
52
  * Convert a browser File (from a drop zone or file input) into a FileLocation:
@@ -56,7 +56,6 @@ export declare function fileToLocation(file: File): FileLocation;
56
56
  export { type Frame, complement, complementTable, defaultStarts, getFrame, revcom, reverse, stitch, } from './seqUtils.ts';
57
57
  export { revlist } from './revlist.ts';
58
58
  export { useCreateOnce, useDebounce, useFinalUnmount, useLocalStorage, useWidthSetter, } from './hooks.ts';
59
- export { renderToStaticMarkup } from './renderToStaticMarkup.ts';
60
59
  export { codonTable, defaultCodonTable, generateCodonTable, } from './geneticCodes.ts';
61
60
  export { IUPAC_MOTIF_REGEX, isPalindromic, iupacToRegex, reverseComplementIupac, } from './iupac.ts';
62
61
  export { type MotifListParse, type MotifParseError, type ParsedMotif, parseMotifList, } from './parseMotifList.ts';
@@ -69,9 +68,11 @@ export { saveAs } from './FileSaver/index.ts';
69
68
  export { type SaveSvgAsImageOptions, saveSvgAsImage, svgHtmlToPngBlob, } from '../svg/saveSvgAsImage.ts';
70
69
  export { type ActiveFetch, type StatusChannel, type StatusReporter, createStatusChannel, createStopTokenRotation, } from './createStopTokenRotation.ts';
71
70
  export { createSharedSetup } from './cachedSetup.ts';
71
+ export { scheduleDetachedDestroy } from './scheduleDetachedDestroy.ts';
72
72
  export { isDataCurrent } from './isDataCurrent.ts';
73
73
  export { handleFetchError, isAbortException, makeAbortError, } from './aborting.ts';
74
74
  export { linkify } from './linkify.ts';
75
+ export { isGeneLikeType, isSequenceMatchType } from './featureTypes.ts';
75
76
  export { locStringsToRegions } from './locStringsToRegions.ts';
76
77
  export type { RefNameSource } from './locStringsToRegions.ts';
77
78
  export { type ParsedLocString, UnknownRefNameError, assembleLocString, assembleLocStringRaw, assembleLocStrings, compareLocStrings, compareLocs, parseLocString, parseLocStringOneBased, stringify, } from './locString.ts';
package/esm/util/index.js CHANGED
@@ -12,7 +12,7 @@ export { capitalizeFirst, pluralize, shorten, shorten2, truncateMiddle, } from '
12
12
  export { formatBytes } from './formatBytes.js';
13
13
  export { getFillProps, getStrokeProps, stripAlpha } from './svgColorProps.js';
14
14
  export { fetchAndMaybeUnzip, fetchAndMaybeUnzipText, isGzip, } from './fetchAndMaybeUnzip.js';
15
- export { AuthNeededError, addOrReplaceView, canReplaceView, isAbstractMenuManager, isAppRootModel, isAuthNeededException, isBlobLocation, isDisplayModel, isFileHandleLocation, isLocalPathLocation, isRootModelWithInternetAccounts, isSelectionContainer, isSessionModel, isSessionServices, isSessionModelWithConfigEditing, isSessionModelWithConnectionEditing, isSessionModelWithConnections, isSessionModelWithWidgets, isSessionWithAddAssembly, isSessionWithAddSessionTrack, isSessionWithAddTracks, isSessionWithPublishTrackConf, isSessionWithDeleteTrackConf, isSessionWithPermanentPlugins, isSessionWithSessionPlugins, isSessionWithSessionTracks, isSessionWithShareURL, isSessionWithViewReplacement, isTrackModel, isTrackViewModel, isUriLocation, isViewContainer, isViewModel, } from './types/index.js';
15
+ export { AuthNeededError, addOrReplaceView, canReplaceView, isAbstractMenuManager, isAppRootModel, isAuthNeededException, isBlobLocation, isDisplayModel, isFileHandleLocation, isLocalPathLocation, isRootModelWithInternetAccounts, isSelectionContainer, isSessionModel, isSessionServices, isSessionModelWithConfigEditing, isSessionModelWithConnectionEditing, isSessionModelWithConnections, isSessionModelWithWidgets, isSessionWithAddAssembly, isSessionWithAddSessionTrack, isSessionWithAddTracks, isSessionWithPublishTrackConf, isSessionWithDeleteTrackConf, isSessionWithMultipleViews, isSessionWithPermanentPlugins, isSessionWithSessionPlugins, isSessionWithSessionTracks, isSessionWithShareURL, isSessionWithViewReplacement, isTrackModel, isTrackViewModel, isUriLocation, isViewContainer, isViewModel, } from './types/index.js';
16
16
  export { getPluginUpdate, installablePlugins, installedVersionFromUrl, isPluginInstalled, resolvePlugin, resolveStorePluginRefs, resolveStoreRefs, } from './pluginStore.js';
17
17
  export { createProgressReporter, createStatusFanOut, createStatusWindow, downloadStatus, progressLabel, statusFraction, statusMessageText, statusProgressLabel, statusReading, statusSource, throttleStatusEmits, updateStatus, withProgress, } from './progress.js';
18
18
  export { calculateRedispatchRange, doesIntersect2, intersection2, } from './range.js';
@@ -29,7 +29,7 @@ export { MAX_ZOOM_RATE_PER_MS, SCROLL_ZOOM_FACTOR_DIVISOR, ZOOM_ACTIVE_WINDOW_MS
29
29
  export { avg, clamp, getDisplayStr, getNumberGrouping, max, maxFinite, min, minmax, polarToCartesian, radToDeg, reducePrecision, setNumberGrouping, sum, toLocale, } from './numericUtils.js';
30
30
  export { bpSpanPx, bpToPx, bytesForRegions, featureSpanPx, getBpDisplayStr, getTickDisplayStr, parseBpString, } from './bpUtils.js';
31
31
  export { gatherOverlaps, mergeIntervals, } from './intervals.js';
32
- export { clampToContig } from './clampToContig.js';
32
+ export { clampToContig, clampToListedContig } from './clampToContig.js';
33
33
  export { animationAllowed } from './animationAllowed.js';
34
34
  export { springAnimate } from './springAnimate.js';
35
35
  export { localStorageAvailable, localStorageGetBoolean, localStorageGetItem, localStorageGetJSON, localStorageGetNumber, localStorageGetStringArray, localStorageRemoveItem, localStorageSetBoolean, localStorageSetItem, localStorageSetJSON, localStorageSetNumber, notifyLocalStorageKey, subscribeToLocalStorageKey, } from './localStorage.js';
@@ -53,7 +53,7 @@ export { isRpcResult } from './rpc.js';
53
53
  export { aesDecrypt, aesEncrypt, sha256, sha256Base64, sha256Base64Url, toBase64, toBase64Url, } from './crypto.js';
54
54
  export { notifyFeatureDetailsMiss, openFeatureWidget, } from './openFeatureWidget.js';
55
55
  export { withFeatureDetails } from './withFeatureDetails.js';
56
- export { canonicalizeViewRefName, findParentThat, findParentThatIs, getAssemblyHost, getContainingDisplay, getContainingTrack, getContainingView, getEnv, getRenderingServices, getSession, hashCode, objectHash, } from './mstUtils.js';
56
+ export { canonicalizeViewRefName, findParentThat, findParentThatIs, getAssemblyHost, getContainingDisplay, getContainingTrack, getContainingView, getEnv, getRenderingServices, launchOrReplaceView, getSession, hashCode, objectHash, } from './mstUtils.js';
57
57
  export { getDialogHost, getNotificationSink, getPaletteHost, getRpcHost, getSessionServices, } from './sessionServices.js';
58
58
  // this is recommended in a later comment in
59
59
  // https://github.com/electron/electron/issues/2288 for detecting electron in a
@@ -91,7 +91,6 @@ export { revlist } from './revlist.js';
91
91
  // without it that is `(0, PR.useLocalStorage) is not a function` when the panel
92
92
  // renders. The implementations never went anywhere -- only these lines did.
93
93
  export { useCreateOnce, useDebounce, useFinalUnmount, useLocalStorage, useWidthSetter, } from './hooks.js';
94
- export { renderToStaticMarkup } from './renderToStaticMarkup.js';
95
94
  export { codonTable, defaultCodonTable, generateCodonTable, } from './geneticCodes.js';
96
95
  export { IUPAC_MOTIF_REGEX, isPalindromic, iupacToRegex, reverseComplementIupac, } from './iupac.js';
97
96
  export { parseMotifList, } from './parseMotifList.js';
@@ -142,9 +141,11 @@ export { createStatusChannel, createStopTokenRotation, } from './createStopToken
142
141
  // through `fetchContext.ts`, which imports this barrel, so exporting it makes
143
142
  // the barrel initialize itself. Import it from `@jbrowse/core/util/installFetch`.
144
143
  export { createSharedSetup } from './cachedSetup.js';
144
+ export { scheduleDetachedDestroy } from './scheduleDetachedDestroy.js';
145
145
  export { isDataCurrent } from './isDataCurrent.js';
146
146
  export { handleFetchError, isAbortException, makeAbortError, } from './aborting.js';
147
147
  export { linkify } from './linkify.js';
148
+ export { isGeneLikeType, isSequenceMatchType } from './featureTypes.js';
148
149
  export { locStringsToRegions } from './locStringsToRegions.js';
149
150
  export { UnknownRefNameError, assembleLocString, assembleLocStringRaw, assembleLocStrings, compareLocStrings, compareLocs, parseLocString, parseLocStringOneBased, stringify, } from './locString.js';
150
151
  export { checkStopToken, checkStopTokenThrottled, createStopToken, createStopTokenChecker, hasSharedArrayBuffer, isStopToken, isStopped, markStopTokenStopped, registerStopTokenBroadcaster, stopStopToken, stopTokenSignal, withStopTokenCheck, withStopTokenSignal, } from './stopToken.js';
@@ -1,6 +1,7 @@
1
- import type { ActiveFetch, StatusReporter } from './createStopTokenRotation.ts';
1
+ import type { ActiveFetch, StatusReporter, StopTokenRotation } from './createStopTokenRotation.ts';
2
2
  import type { FetchContext } from './fetchContext.ts';
3
3
  import type { FetchPhases } from './fetchPhases.ts';
4
+ import type { StopToken } from './stopToken.ts';
4
5
  import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
5
6
  /**
6
7
  * The bookkeeping a family hangs off one fetch, beside the phases. Each of the
@@ -24,11 +25,16 @@ export interface FetchLifecycle {
24
25
  /**
25
26
  * Runs synchronously as the fetch starts, after the rotation has superseded
26
27
  * whatever it replaced: the loading flag (`FetchMixin`'s `activeStopToken`,
27
- * the comparative family's `fetching`), and anything a display blanks
28
+ * through `fetchMixinLifecycle`), and anything a display blanks
28
29
  * because it has no freshness signature to keep stale data honest with
29
30
  * (chord's refName map).
31
+ *
32
+ * Takes the token rather than the whole {@link ActiveFetch}: publishing it is
33
+ * the only thing any implementation does with the fetch, and the guard and
34
+ * the status slot are the skeleton's to hand out — through `ctx`, where a
35
+ * `run` gets them pre-wired.
30
36
  */
31
- onBegin?: (active: ActiveFetch) => void;
37
+ onBegin?: (stopToken: StopToken) => void;
32
38
  /**
33
39
  * Runs in the `finally`, before the rotation's `end()`. `current` is this
34
40
  * run's own guard, already evaluated: a **superseded** run must not clear the
@@ -80,7 +86,7 @@ export interface FetchSkeletonHost extends IStateTreeNode {
80
86
  reloadCounter: number;
81
87
  /**
82
88
  * The states where this host deliberately fetches nothing, read only by the
83
- * dev-only retry check. A decline there is not a dead Retry.
89
+ * retry contract check. A decline there is not a dead Retry.
84
90
  */
85
91
  fetchInert: boolean;
86
92
  /**
@@ -97,19 +103,11 @@ export interface FetchSkeletonHost extends IStateTreeNode {
97
103
  */
98
104
  fetchCanceled?: boolean;
99
105
  }
100
- export interface InstallFetchOptions<TArgs, TResult> extends FetchPhases<TArgs, TResult, FetchContext>, FetchLifecycle {
106
+ interface InstallFetchOptionsBase<TArgs, TResult> extends FetchPhases<TArgs, TResult, FetchContext>, FetchLifecycle {
101
107
  /** autorun name, for the MobX devtools/spy stream */
102
108
  name: string;
103
109
  /** how long to coalesce reruns once the body has started work once */
104
110
  delay: number;
105
- /**
106
- * Where this fetch's status lands. A display passes itself — its status
107
- * fields are part of its own API, and one composing `FetchMixin` lends the
108
- * model-wide window so this fetch takes a slot on the one field beside the
109
- * display's other operations rather than opening a second writer over it.
110
- * Anything with one operation to narrate passes a `createStatusChannel`.
111
- */
112
- report: StatusReporter;
113
111
  /**
114
112
  * An extra skip above `prepare`, reported as `gated` rather than `declined`:
115
113
  * the skeleton decided before the family's own gate was consulted, so it is
@@ -129,7 +127,7 @@ export interface InstallFetchOptions<TArgs, TResult> extends FetchPhases<TArgs,
129
127
  * also be invalidated by `reload()`, or Retry re-runs the body straight into
130
128
  * the same decline and the button is dead. Every layer that has one made
131
129
  * that pairing structural in the end — the global family after arc shipped
132
- * the bug (`GlobalFetchMixin.reload` drops `loadedFetchSignature` in the same
130
+ * the bug (`GlobalFetchMixin.reload` drops `loadedFetchKey` in the same
133
131
  * action as the bump) — and this is that move for the skeleton: a run whose
134
132
  * `reloadCounter` has advanced since the run that last ISSUED a fetch ignores
135
133
  * this gate, so nothing has to remember to clear anything. The multi-way
@@ -148,10 +146,10 @@ export interface InstallFetchOptions<TArgs, TResult> extends FetchPhases<TArgs,
148
146
  */
149
147
  fetchKey?: (args: TArgs) => string;
150
148
  /**
151
- * The key of the data already committed, when the host keeps one — the
152
- * comparative displays stamp `loadedFetchKey`, which their `dataCurrent`
153
- * flag reads too, so a second stamp would be one more thing to disagree with
154
- * it. Omitted, the skeleton stamps its own at commit.
149
+ * The key of the data already committed, when the host keeps one —
150
+ * `KeyedFetchMixin` stamps `loadedFetchKey`, which its `dataCurrent` reads
151
+ * too, so a second stamp would be one more thing to disagree with it.
152
+ * Omitted, the skeleton stamps its own at commit.
155
153
  *
156
154
  * **Either way the stamp is observable**, and the read is tracked. Zoom A→B
157
155
  * issues a fetch for B; zoom back to A before B commits and the re-run
@@ -159,9 +157,23 @@ export interface InstallFetchOptions<TArgs, TResult> extends FetchPhases<TArgs,
159
157
  * write is what wakes the autorun to fetch A again. A closure variable would
160
158
  * leave data B under viewport A until the next input moved.
161
159
  */
162
- committedKey?: () => string | undefined;
160
+ loadedKey?: () => string | undefined;
161
+ /**
162
+ * The predicate form of the freshness gate, for a fetch whose "I have exactly
163
+ * this already" is not string equality: the density tier holds bins over a
164
+ * buffered read and answers a viewport those bins *contain*, which no key can
165
+ * spell. Same rules as `fetchKey` — declined runs report `declined`, and a
166
+ * `reloadCounter` advanced since the last issued fetch overrides it — so the
167
+ * comparison lives here and not in `prepare`, where a reload could not reach
168
+ * it. Runs inside the autorun, so what it reads is tracked: read the
169
+ * committed state off an observable, and the commit that changes the answer
170
+ * wakes the declined run.
171
+ *
172
+ * Either this or `fetchKey`, not both.
173
+ */
174
+ heldAnswers?: (args: TArgs) => boolean;
163
175
  /**
164
- * Install the two dev-only display-contract checks under this name. Omitted
176
+ * Install the two display-contract checks under this name. Omitted
165
177
  * by a **secondary** fetch on a host whose primary foundation already
166
178
  * installed them: `assertDisplayContract` would report the second install as
167
179
  * the double-attach it is built to catch, and a second retry check would
@@ -169,26 +181,51 @@ export interface InstallFetchOptions<TArgs, TResult> extends FetchPhases<TArgs,
169
181
  */
170
182
  contract?: string;
171
183
  }
184
+ /**
185
+ * The rotation half is either/or: `report` says where a rotation this installer
186
+ * creates for itself reports, and `rotation` lends the host's own instead — a
187
+ * display composing `FetchMixin` passes its `fetchRotation`, so `cancelFetch`
188
+ * and `cancelFetchByUser` reach the fetch this installs rather than a second
189
+ * rotation they cannot see. A lent rotation already carries its status window,
190
+ * so `report` would be dead beside it — the same either/or `StatusReporter`
191
+ * itself is a union for.
192
+ */
193
+ export type InstallFetchOptions<TArgs, TResult> = InstallFetchOptionsBase<TArgs, TResult> & ({
194
+ /**
195
+ * Where this fetch's status lands. A display passes itself — its status
196
+ * fields are part of its own API, and one composing `FetchMixin` lends
197
+ * the model-wide window so this fetch takes a slot on the one field
198
+ * beside the display's other operations rather than opening a second
199
+ * writer over it. Anything with one operation to narrate passes a
200
+ * `createStatusChannel`.
201
+ */
202
+ report: StatusReporter;
203
+ rotation?: never;
204
+ } | {
205
+ /** the host's own latest-wins rotation, lent whole — see above */
206
+ rotation: StopTokenRotation;
207
+ report?: never;
208
+ });
172
209
  /**
173
210
  * A whole fetch, installed: the rotation, the leading-edge autorun, the
174
211
  * unconditional trigger reads, the gates, and {@link runFetchOnce} under them.
175
212
  *
176
- * Every fetch in the tree is this shape except one — the prerequisite reads
177
- * (HiC's header, the multi-sample sample list), both comparative displays, the
178
- * circular view's chord fetch, the breakpoint overlay fetch and the multi-way
179
- * synteny display's two DEPENDENT fetches (lane genes, lane links, each gated on
180
- * the key its own commit stamps) all take it. The
181
- * exception is `FetchMixin.runFetch`, the viewport fetch of an LGV display: its
182
- * rotation is a member rather than a closure (so `cancelFetch` can reach it)
183
- * and its trigger list is the per-region or global foundation's, so it holds
184
- * `runFetchOnce` directly and the autorun above it is that foundation's.
213
+ * Every fetch in the tree is this shape except one family — the prerequisite
214
+ * reads (HiC's header, the multi-sample sample list), the two keyed families
215
+ * (`installGlobalFetchAutorun` and `installComparativeFetchAutorun`, which lend
216
+ * `FetchMixin`'s rotation through the `rotation` option so `cancelFetch` and
217
+ * the Cancel button reach the fetch they install), the circular view's chord
218
+ * fetch, the breakpoint overlay fetch and the multi-way synteny display's two
219
+ * DEPENDENT fetches (lane genes, lane links, each gated on the key its own
220
+ * commit stamps) all take it. The
221
+ * exception is the per-region family's `FetchMixin.runFetch`: its trigger is
222
+ * `planRegionFetch`'s autorun and its commits stream per region through
223
+ * `ctx.commitRegion`, so it holds `runFetchOnce` directly and the autorun above
224
+ * it is that foundation's.
185
225
  *
186
226
  * What a caller supplies is exactly what differs between them: which reads wake
187
227
  * it (`prepare`, plus `gate`), what a round trip commits, where the loading
188
228
  * flag lives (`onBegin` / `onEnd`) and where the status goes (`report`).
189
- *
190
- * Returns the rotation's `cancel`, for a family whose model owns the user-facing
191
- * Cancel button: the flag alone is not a cancel — nothing rotates the token, the
192
- * stopped RPC stays current, and it commits over the load the user just stopped.
193
229
  */
194
- export declare function installFetch<TArgs, TResult>(self: FetchSkeletonHost, { name, delay, report, gate, contract, fetchKey, committedKey, prepare, run, commit, setError, onBegin, onEnd, }: InstallFetchOptions<TArgs, TResult>): () => void;
230
+ export declare function installFetch<TArgs, TResult>(self: FetchSkeletonHost, opts: InstallFetchOptions<TArgs, TResult>): void;
231
+ export {};