DotplotDisplay
Auto-generated @jbrowse/mobx-state-tree API for the current JBrowse release — see pluggable elements for concepts. Provided by the dotplot-view plugin. View source.
The configuration slots for this model are documented on its config schema page.
Members a composed model contributes are listed here too, so these tables are the whole surface.
Properties
| Member | Description | Defined by |
|---|---|---|
typetype: types.literal('DotplotDisplay') | DotplotDisplay | |
configurationconfiguration: ConfigurationReference(configSchema) | DotplotDisplay | |
idid: ElementId | BaseDisplay |
Volatiles
| Member | Description | Defined by |
|---|---|---|
rpcDatarpcData: undefined as DotplotRpcData | undefined | RPC-computed feature data | DotplotDisplay |
instanceDatainstanceData: undefined as DotplotInstanceData | undefined | GPU-instance positions produced from rpcData, self-describing via embedded bpPerPx, with no colors in them. Rebuilt only when the data or the zoom changes; the palette is joined on top by the geometry getter. | DotplotDisplay |
fetchWarningsfetchWarnings: [] as ComparativeWarning[] | What the last completed fetch had to say about itself, written with the data it describes (see setRpcData). | DotplotDisplay |
hoveredSegmentIdxhoveredSegmentIdx: -1 | Index into instanceData's per-SEGMENT arrays of the line the pointer is nearest, or -1.The segment rather than the feature, even though the tooltip and the highlight are both about the feature: the feature index derives from this one ( hoveredFeatureIdx below), and the CIGAR operator under the cursor derives from nothing else — a CIGAR-detailed alignment is a staircase of segments and the pointer is on one step of it. Same choice LinearSyntenyDisplay.hoveredInstanceIdx makes, where getFeature does the translating.It addresses instanceData, so it is dropped by BOTH writers of that — a zoom rebuilds the geometry without refetching. | DotplotDisplay |
errorerror: undefined as unknown | BaseDisplay | |
statusMessagestatusMessage: undefined as string | undefined | BaseDisplay | |
statusProgressstatusProgress: undefined as number | undefined | determinate progress fraction [0,1] for the current status, or undefined when the in-flight phase is indeterminate. Set alongside statusMessage by setStatusMessage; a display that never shows a bar simply leaves it undefined. | BaseDisplay |
assembliesSwappedassembliesSwapped: false | Set once at view load by a refName-comparison check, independent of the per-render fetch, so it never re-fires or misfires on zoom. Surfaces through each display's warnings. | ComparativeFetchMixin |
loadedFetchKeyloadedFetchKey: undefined as FetchKey | undefined | currentFetchKey as it stood when the held data was committed — the loaded half of the freshness compare. Written only by commitFetchResult, so a display cannot stamp data it did not fetch, and cleared by reload for the overlay's sake rather than the refetch's (the skeleton's reload epoch is what overrides its gate). The data itself stays display-owned: arc keeps stale arcs on screen under the loading overlay, HiC the stale matrix, synteny the stale ribbons. | KeyedFetchMixin |
activeSignalactiveSignal: undefined as AbortSignal | undefined | signal of the in-flight fetch, or undefined when idle | FetchMixin |
fetchGenerationfetchGeneration: 0 | bumps at every fetch end; autoruns read it to re-evaluate, and it doubles as the staleness epoch inside runFetch | FetchMixin |
reloadCounterreloadCounter: 0 | Bumped by reload() and read unconditionally by the fetch autoruns, so a user retry re-runs the body even where nothing else moved — after an error every other fetch input is unchanged. It is also the half that survives a reload() override that forgets to invalidate, which is the dead Retry button makeRetryContractCheck reports. Declared here because this is the one mixin every fetch foundation composes, the same argument that put fetchInert below; the comparative family carried its own until ADR-105. | FetchMixin |
statusWindowstatusWindow: createStatusWindow(writeStatus(self)) | This display's status field, and the only thing that writes it: one throttle window, one slot per concurrent operation, so N parallel per-region fetches thin to one stream between them rather than N and a second operation cannot end the first one's label (ADR-081). Lent whole to createAbortRotation by a display that also runs a bare-autorun fetch — see StatusReporter. | FetchMixin |
fetchCanceledfetchCanceled: false | true after the user explicitly cancels a load (the loading overlay's cancel button → cancelFetchByUser). A durable, blocking state — unlike cancelFetch, it does not retrigger the fetch autoruns — so the load stays stopped until the user retries (reload) or the viewport changes. Any new fetch clears it (runFetch resets it at the start). | FetchMixin |
| fetchRotation | The latest-wins machine this mixin is a wrapper around, and not a second one: createAbortRotation owns abort rotation, the isCurrent guard, the status slot and the supersede-versus-end rule (ADR-080, ADR-081), for every fetch in the codebase that has one. runFetch adds the observable bookkeeping a display needs on top — isLoading, error, fetchGeneration, fetchCanceled — and nothing else.It was two implementations of that machine until 2026-08-20, which is how they came to disagree about whether a completed fetch releases its signal. A display's primary fetch is this wrapper; a second concurrent fetch on the same node holds a rotation of its own, which is why the primitive is the thing that exists and this is the thing built on it (ADR-054 §1, the one section ADR-105 keeps). It is lent this display's statusWindow, so the fetch takes a slot on the one field rather than opening a second window over it — the whole point of StatusReporter. | FetchMixin |
lodTierInfolodTierInfo: undefined as LodTierInfo | undefined | LodTierInfoMixin |
Getters
| Member | Description | Defined by |
|---|---|---|
viewDotplotViewModel | The plot this display draws into. One getter rather than a getContainingView cast per reader, the same way LinearSyntenyDisplay.view answers it.This names the view type even though the view names this display back ( dotplotDisplays). That mutual reference resolves only because both model types are declared as interface … extends Instance<…> rather than type … = Instance<…> — see ADR-055. | DotplotDisplay |
displayKeynumber | Stable slot on the view-shared backend. Hashed from the node id, not taken from the track's index, so hiding or reordering a sibling can't hand this display another's buffer. | DotplotDisplay |
fetchLandedboolean | ComparativeFetchMixin's hook: a fetch has completed (data is present, even if it mapped zero features). Not a feature-count test — an empty-but-finished fetch has landed, otherwise an empty plot spins the loading overlay forever. | DotplotDisplay |
hasDrawableboolean | ComparativeFetchMixin's hook, answered with the instance geometry rather than fetchLanded or the geometry computed: svgReady is polled outside any reactive context, and a geometry read there recolors every segment per poll. | DotplotDisplay |
computedColorsUint32Array<ArrayBufferLike> | undefined | Main-thread-computed per-segment colors — the gpuProps half of the rpcProps/gpuProps split. A colorBy change recomputes this alone, without re-walking a single CIGAR. Opacity is NOT read here. It rides the shader's alpha uniform (and drawDotplotInstances' param) off DotplotView.dotplotRenderState, so the slider is a redraw, not a recolor — the same split synteny makes. Baking it in made every drag frame recompute this array, re-pack every instance and re-upload the buffer. | DotplotDisplay |
paintedChromosomeOrderreadonly string[] | undefined | The chromosome order the chromosome-painting modes color by: the refNames of whichever axis' assembly colorBy names, in the assembly's own order. Undefined for every other mode, and while the assembly is still loading — the color function falls back to its hash there.It has to come from the assembly rather than from the features, because a color must not change with which chromosomes happen to be in view. The dotplot twin of LinearSyntenyDisplay.paintedChromosomeOrder, off the two axes instead of two stacked levels: 'query' is the horizontal axis (the feature's own refName lane) and 'target' the vertical (the mate's). 'reference' is a stacked-view mode with no dotplot meaning, and the shared color function falls it back to query — with no order, since naming an axis for it would be inventing an answer. | DotplotDisplay |
colorByFieldstring | The field the plot paints by. | DotplotDisplay |
trackColorstring | This track's slot in the plot's palette, used by the track field. Assigned by the view, not locally: pinning a color on one track shifts which automatic slots its siblings can take. | DotplotDisplay |
trackIdstring | DotplotDisplay | |
| geometry | Instance positions joined with the computed colors: what the backends upload and what SVG export draws. The view's upload autorun reads this, so a palette change re-uploads without rebuilding geometry. | DotplotDisplay |
hoveredFeatureIdxnumber | Index into rpcData's per-FEATURE arrays of the alignment the pointer is over, or -1. Derived rather than stored, so it cannot disagree with hoveredSegmentIdx about which alignment that is.Not instanceFeatureIdx[i] ?? i: an out-of-range segment index reads undefined there, and falling back to the raw index would answer with a different feature rather than with nothing. Same reasoning as LinearSyntenyDisplay.getFeature. | DotplotDisplay |
tooltipLinesstring[] | undefined | The hovered feature's tooltip, as lines, or undefined when nothing is hovered. The dotplot twin of LinearSyntenyDisplay.tooltipLines; both feed ComparativeTooltip, which renders lines as text nodes — see getDotplotTooltipLines. | DotplotDisplay |
hoveredFeatureHighlightDotplotHoverHighlight | undefined | The hovered feature redrawn over the canvas: an SVG path of its segments in plot px, plus its own packed color as CSS. The hover shading is entirely this getter; neither renderer draws it. Synteny boosts alpha and darkens rgb per fragment from a hoveredFeatureId uniform, which costs an instance lane, a uniform, a hand-written Canvas2D twin of the same arithmetic, and a broken color run in drawDotplotInstances' batcher. Restroking one feature — a handful of segments — over the shared canvas needs none of that, and is backend-agnostic by construction: it draws the same over the GPU canvas and the Canvas2D fallback because it never asks which one painted. renderSvg deliberately does not draw it — an off-screen export has no pointer, and a transient hover has no business in a figure.The cue is opacity + width, not hue: the plot's own alpha slider routinely sits at 0.2, so restroking opaque and a few px wider is exactly synteny's "the hovered one goes solid". Nothing here picks a highlight color, because every hue is already in use — category10 paints the chromosome modes, and red/blue/black are the strand and default schemes.Recomputes on pan (through plotTransform's viewBpH/viewBpV), so the highlight stays on its feature, and only while something is hovered. plotTransform rather than dotplotRenderState, which carries alpha and lineWidth too — an opacity drag would rebuild this path once a frame for a value it does not read. | DotplotDisplay |
fetchRegionsRegion[] | The h-axis fetch window: the visible content blocks expanded by the shared pan buffer and snapped outward to a buffer-sized grid, so a pan within the buffer neither refetches nor exposes an unfetched strip, and zoomed out it collapses to the whole displayed region. The v axis is deliberately not scoped: the fetch is one-dimensional (h regions in, every mate out), so a vertical pan needs no data the h window didn't already bring, and must never trigger a refetch. Unlike synteny, nothing culls this window again in the worker — executeDotplotFeaturesAndPositions maps every feature it is handed — so the window's only job is to be a superset of what's on screen. | DotplotDisplay |
viewSignaturestring | KeyedFetchMixin's hook, this display's half of currentFetchKey: the fetch-input signature (see fetchKey.ts) for the view's current state. The mixin appends the settings and adapter axes. Reactive: recomputes when either axis's zoom or displayed-region order/orientation changes, or when a pan carries the h axis into a new snapped fetch window. As a computed it only notifies when the string itself changes, which is what lets the fetch autorun track it and stay quiet through sub-buffer pans. | DotplotDisplay |
lodTierLodTier | The detail tier this plot's fetch asks the adapter for. Resolved here on the main thread, not adapter-side from bpPerPx, so it is part of currentFetchKey — see resolveLodTier. Both axes feed it: CIGAR detail is worth drawing when a block is wide on either one, so dropping to the no-CIGAR tier is only safe once both are past the threshold. The tier the adapter will serve once lodTierInfo has landed: a file with no coarse tier is 'fine' at any zoom, and the threshold is clamped up to the file's --coarse bound. | DotplotDisplay |
displayPhaseDisplayStatusPhase | The display's own mutually-exclusive state, the way every LGV display publishes one — so AppReadyMarker counts this display's fetch, and the app stops reporting itself ready over a plot that is still working. Ranked by comparativeDisplayPhase, off the shared canvas's surfaceReadiness and this display's own fetch state.DisplayStatusPhase, not DisplayPhase: the view owns the rendering backend, so this display can never be the one to report a backend failure. | DotplotDisplay |
warningsComparativeWarning[] | Per-render fetch warnings, plus the load-time reversed-assembly hint. | DotplotDisplay |
parentTrackAbstractTrackModel | BaseDisplay | |
RenderingComponentFC<…> | BaseDisplay | |
| DisplayBlurb | BaseDisplay | |
adapterConfigRecord<string, unknown> | BaseDisplay | |
isMinimizedboolean | Returns true if the parent track is minimized. Used to skip expensive operations like autoruns when track is not visible. | BaseDisplay |
hoveredFeatureunknown | Overridable hook (default undefined): what the pointer is currently over, for readers outside the display. LinearGenomeViewContainer publishes it to session.hovered, the view-wide "what is the user pointing at" channel a plugin can subscribe to.Declared here because a cross-display consumer can only read a name the base declares — the same reason FetchMixin.fetchInert is a hook rather than a getter each display invents. The container used to read featureUnderMouse, which only the wiggle, alignments and Manhattan families spelled that way — canvas said hoveredFeature, variants hoveredGenotype — so the channel carried a hover from a third of the display types and nothing said which. It also asked only displays[0] of each track.unknown because the payload genuinely differs — a read, a wiggle bin, a SNP, a genotype cell — and session.hovered is typed to match ("can be anything; code that wants to deal with this should examine it"). Narrow it in the override. | BaseDisplay |
featureNounstring | Overridable hook (default 'feature'): the SINGULAR word for one of the things this display draws, as a menu row or a chip says it — "Hide this read", "Showing 3 variants".Declared here for the same reason as hoveredFeature above: it is read across the display boundary, by chrome that has no idea which display it is drawing for (SoloSelectionChip, alignments' group-label overlay), and a name only the base declares is a name every such consumer can rely on. Two displays declared it independently and one of those declarations WAS this default.A control keeps the generic word; content takes this one. "Variant height" reads as a different setting from "Feature height" when it is the same one, so the shared menus stay on "feature" however the display answers here, and the noun varies where it names what the user is looking at — "Showing 3 variants", "Hide this read". A display drawing something the generic word already fits is right to leave this alone. Distinct from the per-hit noun a context menu takes off the clicked item's own type ("mRNA", "gene"); that names one annotation, this names what the track holds. The hit noun falls back to this. | BaseDisplay |
featureWidgetType{ type: string; id: string; } | The widget openFeatureWidget opens for one of this display's features. Displays may override it. The default is the generic feature widget, for displays drawing plain features.Displays whose features are a specific kind (a read, a variant, a synteny block) override it, including the id: two displays naming one id share the drawer panel, which suits two displays showing the same kind of feature. | BaseDisplay |
loadingboolean | First load, nothing on screen yet: drives the full striped overlay. Deliberately not && isLoading, which would blink the overlay off during the pre-fetch debounce gap. Excludes error so error UI and loading UI never show at once, and fetchInert so a display that will never fetch rests instead of spinning on data that is not coming. | ComparativeFetchMixin |
refetchingboolean | A fetch is running over a stale plot still on screen (zoom, reorder, pan past the buffer): drives a corner indicator rather than the full overlay, so a viewport change does not mask what is drawn. | ComparativeFetchMixin |
svgReadyboolean | Off-screen SVG export gate, the shared computeSvgReady policy every display runs. Neither comparative display has a regionTooLarge state (LOD gates the fetch, not region size). fetchInert is the extra terminal, so an export cannot hang on data the autorun will never fetch, and fetchCanceled is terminal for the same reason: durable until Retry, and an export presses nothing. The data half waits out an in-flight same-key retry (!refetching) and a stale plot (dataCurrent). | ComparativeFetchMixin |
dataSupersededboolean | Overridable hook (default false): the held data answers the key, but this display knows it is not what the screen will settle on — a dependent fetch of its own is still out, or a fetch input it writes itself has moved. The same hook MultiRegionDisplayMixin declares, for the same reason: the key compare is structurally blind to anything the display fetches outside its primary fetch, and an export sampling svgReady in that window paints the half-filled frame.A term of dataCurrent and NOT of the skeleton's freshness gate, so it holds the export and never re-runs the primary fetch. It fails hung, not stale: a value that latches true parks awaitSvgReady on its backstop, so state only what a later commit is guaranteed to clear. | KeyedFetchMixin |
currentFetchKeyFetchKey | undefined | Key of the fetch the current view, settings and adapter call for. The fetch skeleton's freshness key: captured at issue, compared against the stamp above, and written to it at commit. Its identity survives a recomputation onto equal content, so the idle compare is ===. | KeyedFetchMixin |
dataCurrentboolean | The shared freshness answer every foundation gives: data has been committed (loadedFetchKey is only ever written beside it), it was fetched for the current view and settings, and the display is not about to supersede it itself. A pan inside the loaded blocks stays current; a block entering, a tier step, a settings change or a reload() moves one side of the compare. What the fetch autorun gates on is the same compare inside installFetch, not this getter — the skeleton owns it so a reload can override it. This one is for the readers outside the fetch, the export gate above all. The per-region twin is isCacheValid: what decides a refetch, and deliberately not the whole freshness answer. | KeyedFetchMixin |
isLoadingboolean | true while a fetch is active | FetchMixin |
isLoadingOrCanceledboolean | isLoading widened to cover a user-canceled load: what a hover gate wants, since neither state has a frame on screen that a hit describes. Not a phase input — computeActivityPhase reads the two apart, because a cancel is finished (canceled) where a fetch is not (loading). | FetchMixin |
fetchInertboolean | Overridable hook (default false): the states where this display deliberately never fetches, so it holds no data and none is coming. Sequence sets it past base resolution ("Zoom in to see sequence"); LD sets it with the triangle toggled off. One hook has three readers. A display that gains such a state declares it once, which covers the reader it would otherwise forget, always the one outside the display: - the phase ( computeActivityPhase), which otherwise parks a scrim over the placeholder, or a canceled overlay once Cancel is clicked; - the SVG export (computeSvgReady's extraTerminal), whose awaitSvgReady is an unbounded when, so one such display hangs the whole view's export; - the retry contract check (makeRetryContractCheck), which would otherwise report a dead Retry on a display correctly declining to load anything.fetchInert replaces three hooks: loadingSuppressed, svgReadyExtraTerminal on each of the two foundations, and fetchInert on the comparative family, which had already collapsed them. Both LGV displays that override it returned one expression for all three, and the global family hard-coded one of the three to false for a while, so LD could express only half its state. All three fetch families declare it here since the comparative one composed this mixin (ADR-105), so the retry check reads one field everywhere. ADR-082.A hook rather than a displayPhase override, because overriding the getter means restating the whole loading condition. Sequence held a verbatim copy of the other terms that way, and a copy misses any term added to the condition later.fetchInert lives here because this is the one mixin all three display foundations compose. Same argument, one level down, that put rendersCanvas on RenderLifecycleMixin beside canvasDrawn. | FetchMixin |
awaitingPrerequisiteboolean | Overridable hook (default false), read only by the retry contract check (makeRetryContractCheck): "this run declined because a prerequisite fetch in another autorun has not landed, and its arrival wakes this one again". It defers the retry verdict to that later run rather than waiving it, so a display cannot spend its retry on a decline it called preliminary.Two displays set it, one per fetch foundation, so it lives beside fetchInert rather than on either: HiC's contacts fetch declines until CoreGetInfo lands, and MultiSampleVariantBaseModel's fetchNeeded declines until sourcesBase does. Both have a reload() that wakes the prerequisite's autorun as well as their own.It has to be strictly narrower than the gate it explains. One that restates the gate's negation makes every decline a deferred one. No run is then ever judged, which exempts the display from the check. HiC does this deliberately, because its gate and its prerequisite are one condition; what covers its retry instead is LinearHicDisplay/infoFetchFailure.test.ts.Not for a display deliberately not fetching at all — that is fetchInert above, which the loading scrim and the export read too. | FetchMixin |
awaitingDependentDataboolean | Overridable hook (default false), read by computeActivityPhase: a load this display depends on beyond its primary fetch has not landed for the first time, so the frame the primary fetch calls current is still missing something. Multi-way synteny sets it until its lane genes and lane links first arrive, so an export or a capture never lands between the ortholog fetch and the gene models that fill the lanes.A hook rather than a displayPhase override, for the reason fetchInert is one: that display carried the override, restating the foundation's two arguments verbatim to append one term, and a copy like that misses any term added to the foundation later.Not dataSuperseded, which holds the export through every later refetch too: a display saying this wants the scrim on the first landing only, since later lane fetches redraw over lanes already on screen. | FetchMixin |
settingsFetchInputsunknown | The settings axis every fetch family invalidates on: this display's rpcProps() payload and its adapter config, as one value compared structurally. The per-region family watches it from SettingsInvalidate and stamps it on each region, the keyed families fold it into currentFetchKey, and the byte gate measures under it — one getter, so no two can come to invalidate on different axes.undefined inside the payload is a real state and a class instance compares by its own fields, which a serialized key could not say; makeSettingsFetchInputs has why. | FetchMixin |
Methods
| Member | Description | Defined by |
|---|---|---|
| renderSvg | DotplotDisplay | |
| renderingProps | props passed to the renderer's React "Rendering" component. these are client-side only and never sent to the worker. includes displayModel and callbacks | BaseDisplay |
() => MenuItem[] | BaseDisplay |
Actions
| Member | Description | Defined by |
|---|---|---|
setRpcData(data: DotplotRpcData, warnings: ComparativeWarning[]) => void | Commits a fetch result and the warnings it raised, tagged with the key it was fetched for. One action, not three: the warnings describe this result, so writing them separately let a failed refetch leave the last result's warnings standing over data they no longer describe, and each extra action is another round of the view's warning/upload observers per RPC completion. Same reason LinearSyntenyDisplay.setRpcData takes its feature and instance data together.The loading flags are deliberately NOT touched here: this runs as installComparativeFetchAutorun's commit, whose finally clears isLoading and the status line under the same staleness guard.setError is not overridden either: the two callers that set one (the fetch skeleton's catch, afterAttach's) already log it, so the override this display used to carry printed every fetch failure twice — and had to special-case undefined because the skeleton clears the error through the same setter before every fetch. | DotplotDisplay |
setInstanceData(data: DotplotInstanceData | undefined) => void | DotplotDisplay | |
setHoveredSegmentIdx(idx: number) => void | Written by the view's setHoveredFeature, which points the whole plot's hover at one hit — never per display from a component, so the N writes land in one MobX batch. | DotplotDisplay |
setStatusMessage(status?: RpcStatus | undefined) => void | BaseDisplay | |
setError(error?: unknown) => void | BaseDisplay | |
clearHoveredFeature() => void | Overridable hook (default no-op): drop whatever hoveredFeature reports. The writing twin of that getter, and what installClearHoverOnViewportChange calls.A display that STORES its hover owes an override; one that derives it from the live pointer (MAF, Hi-C, LD) owes nothing, and the default costs it nothing. Declared here so the clear can be installed for every display rather than remembered per display — forgetting it is the failure ARCHITECTURE.md's stored-hover section is about, and it used to be six closures at six call sites, which is six chances to omit one. | BaseDisplay |
reload() => void | base display reload does nothing, see specialized displays for details | BaseDisplay |
| applyDisplaySettings | Apply a set of display settings to the live display, and report which were applied. Each key runs through the display config schema's preProcessSnapshot (shorthand expansions and legacy-key migrations, as showTrackGeneric applies to a session spec's inline track keys), then writes the matching config slot. A key naming a sub-schema (facet, color) replaces the whole object, its string shorthand lifted by that schema, and null clears it. Keys that are not slots come back in unapplied as { key, reason }, so a caller can tell a misspelling from a key that has an action instead of a slot.allowSetters also routes a non-slot key to a single-argument action named set<Key>. It is off by default because session specs, share links and embeds pass untyped JSON here, and a default fallback would let them call internal setters (setError, setScrollTop, ...) and call multi-argument setters with one argument. A caller that wants a specific action can call it directly.A key whose write threw is reported in failed. Only failed means the caller passed a bad value. unapplied needs the caller's own context to read: showTrackGeneric spreads the same settings into the display's snapshot, so a declared prop (resolution) has already landed by the time it reports here, while the restyle path spreads nothing and every entry there did nothing.A per-key error does not abort the remaining keys. A caller mid- showTrack has already pushed the track, and one rejected value should not leave it half-configured. | BaseDisplay |
setAssembliesSwapped(arg: boolean) => void | ComparativeFetchMixin | |
commitFetchResult(commit: () => void, key: FetchKey) => void | The commit half of a keyed fetch: run the display's own store in the same transaction as the key stamp, so no observer can see fresh data under a stale key or the reverse. As the only writer of loadedFetchKey, this action makes dataCurrent derivable, because a display cannot commit without stamping. | KeyedFetchMixin |
stopActiveFetch() => void | Abort the in-flight fetch (if any) and retire its slot. The shared preamble of both cancel paths; the difference between them is only what they do to fetchCanceled / fetchGeneration afterward. | FetchMixin |
openStatusStream(isCurrent: () => boolean) => StatusStream | Open one operation's slot on the display's status field: an RPC statusCallback throttled through the display-wide window and guarded so a callback that fires after the node is torn down (RPCs resolve their status stream asynchronously) is a safe no-op, plus the clear that retires the slot when the operation ends.Every operation on the display opens one, and the two come back together because an operation that never retires keeps reporting status for a phase that is over. The viewport fetch ( runFetch), the clustering run and a lent createAbortRotation are three of them on one field; before ADR-081 each blanked the field outright and the last one to finish overwrote the status of the other two.isCurrent is required and has no "node is alive" default, because a live node is not enough: a superseded fetch is on a live node, and its late status repainting the overlay of the fetch that replaced it is the failure this guards. runFetch passes !isStale(), and every display gets that through ctx.statusCallback unasked; a caller outside a fetch (the clustering autorun) passes its own run's flag. Defaulting to isAlive made the loose answer the easy one and five displays took it.runFetch's own slot is opened by the rotation; this is for an operation outside any fetch, the tree sidebar's clustering run. | FetchMixin |
cancelFetch() => void | cancel any in-flight fetch and bump fetchGeneration (always bumps, so callers can retrigger fetch autoruns even when nothing was in flight). This is the internal reset clearAllRpcData runs — it clears any user-cancel flag so the retrigger actually re-fetches. | FetchMixin |
cancelFetchByUser() => void | User-initiated cancel from the loading overlay. Stops the in-flight fetch and lands in a durable fetchCanceled state. Unlike cancelFetch, it does NOT bump fetchGeneration — so the fetch autoruns don't immediately restart the load. The user retries via reload (the overlay's retry button), or it clears on the next viewport change. | FetchMixin |
beforeDestroy() => void | Abort an in-flight fetch on teardown. Without this, a display destroyed mid-fetch (track/view closed while loading) never signals the worker to abort the now-useless work, and its in-flight HTTP reads keep downloading. MST auto-chains lifecycle hooks, so a composing display can still define its own beforeDestroy. | FetchMixin |
beginFetch(signal: AbortSignal) => void | The onBegin half of a fetch's bookkeeping: publish the in-flight signal (isLoading) and clear the durable user-cancel — a load starting is the single clear point that covers every retrigger path (reload, viewport change, settings invalidate). An action of its own for the same reason endFetch is: installFetch's lifecycle callbacks run outside any MST flow this mixin owns. | FetchMixin |
endFetch(current: boolean) => void | The finally half of runFetch's bookkeeping, an action of its own because runFetchOnce's finally resumes on a microtask the flow does not own — a direct volatile write there is outside the action context, which is the one thing hoisting the sequence into a shared function costs. The stale branch is a superseded fetch, which must not clear the loading flag the run that replaced it just set. | FetchMixin |
runFetch(work: (ctx: FetchContext) => Promise<void>) => Promise<void> | Run a cancel-safe fetch (cancels any prior). The work callback gets a FetchContext with a signal to forward to the RPC and an isStale() check to short-circuit commits once the user has moved on. The MST-flow wrapper over the shared runFetchOnce sequence, and only the wrapper: the begin/clear/run/commit/error/end order, and the rules that keep a superseded run from writing back, are the same function every other fetch in the tree runs. What this adds is the observable bookkeeping a display needs — isLoading through activeSignal, fetchGeneration, the user-cancel clear — and the flow itself, which is an action, so work's synchronous prefix runs untracked wherever a fetch autorun calls this. | FetchMixin |
setLodTierInfo(info: LodTierInfo | undefined) => void | LodTierInfoMixin |