@jbrowse/wiggle-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.
@@ -10,7 +10,7 @@ export interface ScoreScaleHost {
10
10
  /**
11
11
  * #stateModel ScoreScaleMixin
12
12
  * #category display
13
- * #crossCuttingMixin Score axis. Nothing — the config slots. Brings `scaleType` / `autoscaleType` / `minScore` / `maxScore` / `*Bound` / `numStdDev` and their setters, i.e. the whole `ScoreScaleModel` interface the shared score menu and `SetMinMaxDialog` consume
13
+ * #crossCuttingMixin Score axis. Nothing — the config slots. Brings `scaleType` / `autoscaleType` / `minScore` / `maxScore` / `manual*` / `*Bound` / `hasManualScoreBounds` / `numStdDev` and their setters, i.e. the whole `ScoreScaleModel` interface the shared score menu and `SetMinMaxDialog` consume
14
14
  *
15
15
  * The score axis every quantitative display shares: which scale, how to
16
16
  * autoscale it, and the manual min/max bounds. This is the runtime half of
@@ -26,10 +26,17 @@ export interface ScoreScaleHost {
26
26
  * — the alignments coverage band shares this axis but none of the rest.
27
27
  *
28
28
  * `minScore`/`maxScore` are the **raw** slot values with their
29
- * `Number.MIN_VALUE`/`Number.MAX_VALUE` "unset" sentinels intact, because that
30
- * is what the dialog round-trips; `minScoreBound`/`maxScoreBound` are the
31
- * resolved bounds, where `undefined` means "autoscale this end". Every consumer
32
- * that computes a domain reads the `*Bound` pair.
29
+ * `Number.MIN_VALUE`/`Number.MAX_VALUE` "unset" sentinels intact, and nothing
30
+ * outside this file should want them: `manualMinScore`/`manualMaxScore` are the
31
+ * same answer with the sentinel resolved to `undefined`, which is what the
32
+ * dialog round-trips and what the menu captions itself with;
33
+ * `minScoreBound`/`maxScoreBound` are the resolved bounds, where `undefined`
34
+ * means "autoscale this end". Every consumer that computes a domain reads the
35
+ * `*Bound` pair.
36
+ *
37
+ * Whether a bound is *configured* is a third question, and `hasManualScoreBounds`
38
+ * is the only getter that answers it — the resolved pair cannot, since
39
+ * `defaultScoreDomain` is exactly the hook that turns an unset end into a number.
33
40
  */
34
41
  export declare function ScoreScaleMixin(): import("@jbrowse/mobx-state-tree").IModelType<{}, {
35
42
  /**
@@ -75,6 +82,16 @@ export declare function ScoreScaleMixin(): import("@jbrowse/mobx-state-tree").IM
75
82
  * checked before this is consulted.
76
83
  */
77
84
  readonly defaultScoreDomain: [number | undefined, number | undefined];
85
+ /**
86
+ * #getter
87
+ * The lower bound the config really sets, `undefined` at the sentinel.
88
+ */
89
+ readonly manualMinScore: number | undefined;
90
+ /**
91
+ * #getter
92
+ * The upper bound the config really sets, `undefined` at the sentinel.
93
+ */
94
+ readonly manualMaxScore: number | undefined;
78
95
  /**
79
96
  * #getter
80
97
  * Resolved lower bound; `undefined` means autoscale this end.
@@ -85,6 +102,16 @@ export declare function ScoreScaleMixin(): import("@jbrowse/mobx-state-tree").IM
85
102
  * Resolved upper bound; `undefined` means autoscale this end.
86
103
  */
87
104
  readonly maxScoreBound: number | undefined;
105
+ /**
106
+ * #getter
107
+ * Whether the user has pinned either end, which is a different question
108
+ * from whether either end resolved to a number: `defaultScoreDomain` fills
109
+ * the sentinels in, so a GC content track answers yes to the second with
110
+ * nothing configured. The score menu asks this one — it gates the "Clear
111
+ * manual min/max" row, and a Clear that writes the sentinels already
112
+ * there is a row that does nothing and never goes away.
113
+ */
114
+ readonly hasManualScoreBounds: boolean;
88
115
  } & {
89
116
  /**
90
117
  * #action
@@ -8,7 +8,7 @@ const confNode = (self) => self;
8
8
  /**
9
9
  * #stateModel ScoreScaleMixin
10
10
  * #category display
11
- * #crossCuttingMixin Score axis. Nothing — the config slots. Brings `scaleType` / `autoscaleType` / `minScore` / `maxScore` / `*Bound` / `numStdDev` and their setters, i.e. the whole `ScoreScaleModel` interface the shared score menu and `SetMinMaxDialog` consume
11
+ * #crossCuttingMixin Score axis. Nothing — the config slots. Brings `scaleType` / `autoscaleType` / `minScore` / `maxScore` / `manual*` / `*Bound` / `hasManualScoreBounds` / `numStdDev` and their setters, i.e. the whole `ScoreScaleModel` interface the shared score menu and `SetMinMaxDialog` consume
12
12
  *
13
13
  * The score axis every quantitative display shares: which scale, how to
14
14
  * autoscale it, and the manual min/max bounds. This is the runtime half of
@@ -24,10 +24,17 @@ const confNode = (self) => self;
24
24
  * — the alignments coverage band shares this axis but none of the rest.
25
25
  *
26
26
  * `minScore`/`maxScore` are the **raw** slot values with their
27
- * `Number.MIN_VALUE`/`Number.MAX_VALUE` "unset" sentinels intact, because that
28
- * is what the dialog round-trips; `minScoreBound`/`maxScoreBound` are the
29
- * resolved bounds, where `undefined` means "autoscale this end". Every consumer
30
- * that computes a domain reads the `*Bound` pair.
27
+ * `Number.MIN_VALUE`/`Number.MAX_VALUE` "unset" sentinels intact, and nothing
28
+ * outside this file should want them: `manualMinScore`/`manualMaxScore` are the
29
+ * same answer with the sentinel resolved to `undefined`, which is what the
30
+ * dialog round-trips and what the menu captions itself with;
31
+ * `minScoreBound`/`maxScoreBound` are the resolved bounds, where `undefined`
32
+ * means "autoscale this end". Every consumer that computes a domain reads the
33
+ * `*Bound` pair.
34
+ *
35
+ * Whether a bound is *configured* is a third question, and `hasManualScoreBounds`
36
+ * is the only getter that answers it — the resolved pair cannot, since
37
+ * `defaultScoreDomain` is exactly the hook that turns an unset end into a number.
31
38
  */
32
39
  export function ScoreScaleMixin() {
33
40
  return types
@@ -88,23 +95,45 @@ export function ScoreScaleMixin() {
88
95
  get defaultScoreDomain() {
89
96
  return [undefined, undefined];
90
97
  },
98
+ /**
99
+ * #getter
100
+ * The lower bound the config really sets, `undefined` at the sentinel.
101
+ */
102
+ get manualMinScore() {
103
+ return this.minScore === Number.MIN_VALUE ? undefined : this.minScore;
104
+ },
105
+ /**
106
+ * #getter
107
+ * The upper bound the config really sets, `undefined` at the sentinel.
108
+ */
109
+ get manualMaxScore() {
110
+ return this.maxScore === Number.MAX_VALUE ? undefined : this.maxScore;
111
+ },
91
112
  /**
92
113
  * #getter
93
114
  * Resolved lower bound; `undefined` means autoscale this end.
94
115
  */
95
116
  get minScoreBound() {
96
- return this.minScore === Number.MIN_VALUE
97
- ? this.defaultScoreDomain[0]
98
- : this.minScore;
117
+ return this.manualMinScore ?? this.defaultScoreDomain[0];
99
118
  },
100
119
  /**
101
120
  * #getter
102
121
  * Resolved upper bound; `undefined` means autoscale this end.
103
122
  */
104
123
  get maxScoreBound() {
105
- return this.maxScore === Number.MAX_VALUE
106
- ? this.defaultScoreDomain[1]
107
- : this.maxScore;
124
+ return this.manualMaxScore ?? this.defaultScoreDomain[1];
125
+ },
126
+ /**
127
+ * #getter
128
+ * Whether the user has pinned either end, which is a different question
129
+ * from whether either end resolved to a number: `defaultScoreDomain` fills
130
+ * the sentinels in, so a GC content track answers yes to the second with
131
+ * nothing configured. The score menu asks this one — it gates the "Clear
132
+ * manual min/max" row, and a Clear that writes the sentinels already
133
+ * there is a row that does nothing and never goes away.
134
+ */
135
+ get hasManualScoreBounds() {
136
+ return (this.manualMinScore !== undefined || this.manualMaxScore !== undefined);
108
137
  },
109
138
  }))
110
139
  .actions(self => ({
@@ -1,7 +1,7 @@
1
1
  declare const _default: (props: {
2
2
  model: {
3
- minScore: number;
4
- maxScore: number;
3
+ manualMinScore: number | undefined;
4
+ manualMaxScore: number | undefined;
5
5
  scaleType: string;
6
6
  setMinScore: (arg?: number) => void;
7
7
  setMaxScore: (arg?: number) => void;
@@ -3,11 +3,15 @@ import { useState } from 'react';
3
3
  import { NumberTextField, SubmitDialog } from '@jbrowse/core/ui';
4
4
  import { Typography } from '@mui/material';
5
5
  import { observer } from 'mobx-react';
6
+ // The two fields open on what the config really pins, which is the mixin's
7
+ // `manual*` pair rather than the raw slots — the sentinel comparison is one
8
+ // answer per end and lives there. Submitting `undefined` writes the sentinel
9
+ // back, so an emptied field is how autoscale resumes.
6
10
  export default observer(function SetMinMaxDialog(props) {
7
11
  const { model, handleClose } = props;
8
- const { minScore, maxScore, scaleType } = model;
9
- const [min, setMin] = useState(minScore === Number.MIN_VALUE ? undefined : minScore);
10
- const [max, setMax] = useState(maxScore === Number.MAX_VALUE ? undefined : maxScore);
12
+ const { manualMinScore, manualMaxScore, scaleType } = model;
13
+ const [min, setMin] = useState(manualMinScore);
14
+ const [max, setMax] = useState(manualMaxScore);
11
15
  const rangeOk = min === undefined || max === undefined || max > min;
12
16
  const logOk = !(scaleType === 'log' && min !== undefined && min <= 0);
13
17
  return (_jsxs(SubmitDialog, { open: true, title: "Set min/max score for track", submitDisabled: !rangeOk || !logOk, onCancel: handleClose, onSubmit: () => {
@@ -0,0 +1,27 @@
1
+ import type { YScaleTicks } from './yScaleTicks.ts';
2
+ /**
3
+ * A left-oriented Y-axis in the shared gutter, at a band's top-left corner on
4
+ * screen. Every stacked band that carries one — the alignments coverage band,
5
+ * MAF's coverage and conservation bands — draws it through this, and its export
6
+ * emits `SvgYScaleGutter` with the same spine placement, so the on-screen and
7
+ * exported axes cannot drift apart.
8
+ *
9
+ * `left` is the gutter's own left edge; the spine is placed inside the gutter
10
+ * from there, so a caller positioning the box does not also offset the spine.
11
+ */
12
+ export default function YScaleGutter({ top, left, height, ticks, }: {
13
+ top: number;
14
+ left?: number;
15
+ height: number;
16
+ ticks: YScaleTicks;
17
+ }): import("react").JSX.Element;
18
+ /**
19
+ * The gutter's `<g>` on its own, for a caller that already owns an `<svg>` —
20
+ * the SVG export, whose bands are positioned by the enclosing document. `left`
21
+ * is the gutter's left edge in that document.
22
+ */
23
+ export declare function SvgYScaleGutter({ left, y, ticks, }: {
24
+ left?: number;
25
+ y: number;
26
+ ticks: YScaleTicks;
27
+ }): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import YScaleBar from './YScaleBar.js';
3
+ import { AXIS_GUTTER_WIDTH_PX, leftAxisSpineX } from './yScaleTicks.js';
4
+ /**
5
+ * A left-oriented Y-axis in the shared gutter, at a band's top-left corner on
6
+ * screen. Every stacked band that carries one — the alignments coverage band,
7
+ * MAF's coverage and conservation bands — draws it through this, and its export
8
+ * emits `SvgYScaleGutter` with the same spine placement, so the on-screen and
9
+ * exported axes cannot drift apart.
10
+ *
11
+ * `left` is the gutter's own left edge; the spine is placed inside the gutter
12
+ * from there, so a caller positioning the box does not also offset the spine.
13
+ */
14
+ export default function YScaleGutter({ top, left = 0, height, ticks, }) {
15
+ return (_jsx("svg", { style: {
16
+ position: 'absolute',
17
+ top,
18
+ left,
19
+ pointerEvents: 'none',
20
+ height,
21
+ width: AXIS_GUTTER_WIDTH_PX,
22
+ }, children: _jsx(SvgYScaleGutter, { y: 0, ticks: ticks }) }));
23
+ }
24
+ /**
25
+ * The gutter's `<g>` on its own, for a caller that already owns an `<svg>` —
26
+ * the SVG export, whose bands are positioned by the enclosing document. `left`
27
+ * is the gutter's left edge in that document.
28
+ */
29
+ export function SvgYScaleGutter({ left = 0, y, ticks, }) {
30
+ return (_jsx("g", { transform: `translate(${leftAxisSpineX(left)}, ${y})`, children: _jsx(YScaleBar, { ticks: ticks, orientation: "left" }) }));
31
+ }
package/esm/autoscale.js CHANGED
@@ -116,16 +116,27 @@ export function computeScoreStats(summaryScoreMode, datasets) {
116
116
  !overlaps(featurePositions[i * 2], featurePositions[i * 2 + 1], visStart, visEnd)) {
117
117
  continue;
118
118
  }
119
- min = Math.min(min, minScores[i]);
120
- max = Math.max(max, maxScores[i]);
119
+ // Non-finite scores are skipped rather than folded in: a wig file may
120
+ // carry a NaN, and one of them poisons min/max and mean alike, collapsing
121
+ // the whole domain to the [0, 1] stub the callers fall back to.
122
+ const lo = minScores[i];
123
+ if (Number.isFinite(lo)) {
124
+ min = Math.min(min, lo);
125
+ }
126
+ const hi = maxScores[i];
127
+ if (Number.isFinite(hi)) {
128
+ max = Math.max(max, hi);
129
+ }
121
130
  // Mean/stddev always use featureScores (the average) regardless of
122
131
  // summaryScoreMode; min/max for the domain bounds come from the mode-
123
132
  // selected arrays above. Intentional: sd-based autoscale centers on the
124
133
  // average-value distribution even in whiskers/min/max summary modes.
125
134
  const avg = featureScores[i];
126
- sum += avg;
127
- sumSq += avg * avg;
128
- count++;
135
+ if (Number.isFinite(avg)) {
136
+ sum += avg;
137
+ sumSq += avg * avg;
138
+ count++;
139
+ }
129
140
  }
130
141
  }
131
142
  if (count === 0 || !Number.isFinite(min) || !Number.isFinite(max)) {
package/esm/index.d.ts CHANGED
@@ -27,6 +27,7 @@ export { makeAutoscaleTypeSubMenu, makeCrossHatchItem, makeScaleTypeSubMenu, mak
27
27
  export type { ScoreScaleModel } from './scoreMenuItems.ts';
28
28
  export { ScoreScaleMixin } from './ScoreScaleMixin.ts';
29
29
  export { default as YScaleBar } from './YScaleBar.tsx';
30
+ export { SvgYScaleGutter, default as YScaleGutter } from './YScaleGutter.tsx';
30
31
  export { default as YScaleBarOverlay } from './YScaleBarOverlay.tsx';
31
32
  export { MIN_FILL_WIDTH_PX, NO_PREV_START, RENDERING_TYPE_DENSITY, RENDERING_TYPE_LINE, RENDERING_TYPE_LINE_CENTER, RENDERING_TYPE_SCATTER, RENDERING_TYPE_XYPLOT, } from './renderingBackendTypes.ts';
32
33
  export type { SourceRenderData, WiggleGPURenderState, WiggleRenderingBackend, WiggleRenderingType, } from './renderingBackendTypes.ts';
package/esm/index.js CHANGED
@@ -19,6 +19,7 @@ export { DEFAULT_AUTOSCALE_OPTIONS } from './autoscale.js';
19
19
  export { makeAutoscaleTypeSubMenu, makeCrossHatchItem, makeScaleTypeSubMenu, makeScoreSubMenu, makeSetMinMaxScoreItem, } from './scoreMenuItems.js';
20
20
  export { ScoreScaleMixin } from './ScoreScaleMixin.js';
21
21
  export { default as YScaleBar } from './YScaleBar.js';
22
+ export { SvgYScaleGutter, default as YScaleGutter } from './YScaleGutter.js';
22
23
  export { default as YScaleBarOverlay } from './YScaleBarOverlay.js';
23
24
  export { MIN_FILL_WIDTH_PX, NO_PREV_START, RENDERING_TYPE_DENSITY, RENDERING_TYPE_LINE, RENDERING_TYPE_LINE_CENTER, RENDERING_TYPE_SCATTER, RENDERING_TYPE_XYPLOT, } from './renderingBackendTypes.js';
24
25
  export {} from './displayModel.js';
@@ -1,3 +1,3 @@
1
- import type { Ctx2D } from '@jbrowse/core/util/paintLayer';
1
+ import type { MarkContext2D } from '@jbrowse/render-core/marks';
2
2
  export declare const SMALL_POINT_MAX_DIAMETER_PX = 3;
3
- export declare function appendPointMarker(ctx: Ctx2D, cx: number, y: number, diameter: number): void;
3
+ export declare function appendPointMarker(ctx: MarkContext2D, cx: number, y: number, diameter: number): void;
@@ -1,27 +1,18 @@
1
- import { crispSquareTopLeftPx } from '@jbrowse/render-core/shaders/pointGlyph';
1
+ import { appendGlyph } from '@jbrowse/render-core/marks/glyphPaint';
2
2
  import { SMALL_POINT_MAX_DIAMETER } from '@jbrowse/render-core/shaders/pointGlyphConsts';
3
+ import { GLYPH_DISC } from '@jbrowse/render-core/shaders/pointMarkConsts';
3
4
  // At/below a 3px diameter an antialiased disc reads as a blurry blob, so scatter
4
5
  // points draw as a crisp filled square below this threshold and an AA disc
5
6
  // above it. The value comes from pointGlyph.slang via `//! export-consts`, so
6
7
  // the two backends can't disagree about where the square/disc split is; the
7
8
  // alias keeps this module's long-standing public name.
8
9
  export const SMALL_POINT_MAX_DIAMETER_PX = SMALL_POINT_MAX_DIAMETER;
9
- // Append one scatter point marker to the current path, centered on (cx, y): a
10
- // crisp filled square at/below SMALL_POINT_MAX_DIAMETER_PX, else an antialiased
11
- // disc. Shared by the wiggle scatter and GWAS Manhattan Canvas2D paths so the
12
- // square/disc threshold can't drift between them or from the shader. The caller
13
- // owns ctx.beginPath()/ctx.fill() so many markers batch into one fill.
10
+ // Append one scatter point marker to the current path, centered on (cx, y): the
11
+ // `point` shape's disc glyph, which is a crisp filled square at/below
12
+ // SMALL_POINT_MAX_DIAMETER_PX and an antialiased disc above it. Wiggle's
13
+ // scatter mode draws only that one glyph, so this is the shape's painter
14
+ // reached at a name that predates it. The caller owns
15
+ // ctx.beginPath()/ctx.fill() so many markers batch into one fill.
14
16
  export function appendPointMarker(ctx, cx, y, diameter) {
15
- const radius = diameter / 2;
16
- if (diameter <= SMALL_POINT_MAX_DIAMETER_PX) {
17
- // Snap the top-left to the pixel grid (round-half-up) so the crisp square's
18
- // fill lands on whole pixels instead of AA-blurring across columns/rows.
19
- // `crispSquareTopLeftPx` is generated from pointGlyph.slang (adr-051), so
20
- // this is the shader's snap rather than a re-derivation of it.
21
- ctx.rect(crispSquareTopLeftPx(cx, diameter), crispSquareTopLeftPx(y, diameter), diameter, diameter);
22
- }
23
- else {
24
- ctx.moveTo(cx + radius, y);
25
- ctx.arc(cx, y, radius, 0, Math.PI * 2);
26
- }
17
+ appendGlyph(ctx, GLYPH_DISC, cx, y, diameter);
27
18
  }
@@ -3,10 +3,11 @@ import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
3
3
  export interface ScoreScaleModel extends IStateTreeNode {
4
4
  scaleType: string;
5
5
  autoscaleType: string;
6
- minScore: number;
7
- maxScore: number;
6
+ manualMinScore: number | undefined;
7
+ manualMaxScore: number | undefined;
8
8
  minScoreBound: number | undefined;
9
9
  maxScoreBound: number | undefined;
10
+ hasManualScoreBounds: boolean;
10
11
  setScaleType: (v: string) => void;
11
12
  setAutoscale: (v?: string) => void;
12
13
  setMinScore: (n?: number) => void;
@@ -29,21 +29,19 @@ export function makeAutoscaleTypeSubMenu(self, options = DEFAULT_AUTOSCALE_OPTIO
29
29
  }),
30
30
  };
31
31
  }
32
- // The model resolves the Number.MIN_VALUE / MAX_VALUE "unset, fall back to
33
- // autoscale" sentinel into minScoreBound/maxScoreBound (undefined = autoscale).
34
- // Surfacing them lets the menu show that a manual range is in force — otherwise
35
- // an autoscale-type radio still reads as checked while a fixed bound silently
36
- // overrides it.
37
- function resolveScoreBounds(self) {
38
- const min = self.minScoreBound;
39
- const max = self.maxScoreBound;
40
- return { min, max, hasManual: min !== undefined || max !== undefined };
41
- }
32
+ // Showing the range in the label is how the menu says a fixed bound is in force
33
+ // — otherwise an autoscale-type radio still reads as checked while a manual
34
+ // bound silently overrides it. So it is the PINNED pair that is shown, with
35
+ // `auto` for the end nobody pinned. A display overriding `defaultScoreDomain`
36
+ // resolves both ends to numbers with nothing configured: asking the resolved
37
+ // pair captioned every GC content track "(0 – 1)", and once one end was really
38
+ // set it printed the other end's default beside it, in the one place the user
39
+ // looks to find out what they have pinned.
42
40
  export function makeSetMinMaxScoreItem(self) {
43
- const { min, max, hasManual } = resolveScoreBounds(self);
41
+ const { manualMinScore, manualMaxScore } = self;
44
42
  return {
45
- label: hasManual
46
- ? `Set min/max score (${min ?? 'auto'} – ${max ?? 'auto'})...`
43
+ label: self.hasManualScoreBounds
44
+ ? `Set min/max score (${manualMinScore ?? 'auto'} – ${manualMaxScore ?? 'auto'})...`
47
45
  : 'Set min/max score...',
48
46
  onClick: () => {
49
47
  getDialogHost(self).queueDialog(handleClose => [
@@ -95,9 +93,7 @@ export function makeScoreSubMenu(self, opts = {}) {
95
93
  ...(scaleType ? [makeScaleTypeSubMenu(self)] : []),
96
94
  ...(autoscale ? [makeAutoscaleTypeSubMenu(self, autoscaleOptions)] : []),
97
95
  makeSetMinMaxScoreItem(self),
98
- ...(resolveScoreBounds(self).hasManual
99
- ? [makeClearMinMaxScoreItem(self)]
100
- : []),
96
+ ...(self.hasManualScoreBounds ? [makeClearMinMaxScoreItem(self)] : []),
101
97
  ...trailingItems,
102
98
  ],
103
99
  };
@@ -12,7 +12,7 @@
12
12
  // per-result Set would list a shared buffer twice.
13
13
  //
14
14
  // Aliasing the adapter's own arrays here as well, rather than copying them, is
15
- // costed and declined in agent-docs/reference/REJECTED_IDEAS.md: it retains 20
15
+ // costed and declined in agent-docs/architecture-decision-records/: it retains 20
16
16
  // bytes a feature on the main thread where copying retains 12.
17
17
  export function collectWiggleTransferables(results) {
18
18
  const buffers = new Set();
@@ -17,7 +17,7 @@ export interface VisibleEntry<T> {
17
17
  * `coarseDynamicBlocks`: over the empty initial coarse list every walker below
18
18
  * yields no entries, and no entries is not a stale domain but the caller's
19
19
  * `[0, 1]` fallback — a bigwig line track drew blank and a density track solid.
20
- * ARCHITECTURE.md, "Every fetch autorun runs on the leading edge".
20
+ * reference/FETCH_SKELETON.md, "Every fetch autorun runs on the leading edge".
21
21
  */
22
22
  export interface SettledBlocksView {
23
23
  initialized: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/wiggle-core",
3
- "version": "5.0.0-beta.1",
3
+ "version": "5.0.0-beta.3",
4
4
  "type": "module",
5
5
  "description": "Shared scale and autoscale utilities for wiggle and coverage displays",
6
6
  "keywords": [
@@ -29,12 +29,12 @@
29
29
  ],
30
30
  "dependencies": {
31
31
  "@jbrowse/mobx-state-tree": "^6.5.1",
32
- "@mui/icons-material": "^9.3.1",
33
- "@mui/material": "^9.3.1",
32
+ "@mui/icons-material": "^9.4.0",
33
+ "@mui/material": "^9.4.0",
34
34
  "mobx-react": "^10.0.2",
35
- "@jbrowse/display-kit": "^5.0.0-beta.1",
36
- "@jbrowse/core": "^5.0.0-beta.1",
37
- "@jbrowse/render-core": "^5.0.0-beta.1"
35
+ "@jbrowse/core": "^5.0.0-beta.3",
36
+ "@jbrowse/render-core": "^5.0.0-beta.3",
37
+ "@jbrowse/display-kit": "^5.0.0-beta.3"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "react": ">=19.0.0"