What the library draws on a node's rim for its pivots: one badge per pivot that
declared a potential, one badge for all of them, or nothing. Set it through
pivotRimBadge in the graph options, or here to change it later.
Assigning marks every node dirty, the way setPotential does for one — the rim
redraws on the next render, so call graph.renderer.update() if nothing else is
about to.
How many pivots are registered — what the Pivot rail mode's gating reads.
Every registered pivot, in registration order.
How many pivots apply to one node — what the 'summary' rim badge counts when
nothing was declared for it.
Memoised, because the rim asks this for every node on every render and the
answer is one appliesTo call per registered pivot: at a hundred providers and
a thousand nodes, asking each time is a hundred thousand calls a frame. The memo
is dropped whenever the registry or the graph's nodes change, so a predicate
reading anything else can go stale — acceptable for a hint on the rim, and the
panel is always the exact answer.
The cached summary for exactly this question, if there is one. Lets a surface paint a number it already knows without asking again.
Abort in-flight provider calls: one pivot's or every pivot's, and optionally only one kind.
The kind is what lets leaving a surface stop the questions it was asking without
cancelling the work it commissioned — a fetch already has a candidate set of its
own and a pane showing it, so abandoning that silently would throw away results
nobody asked to lose.
OptionalpivotId: stringOptionalkind: "summarize" | "fetch"Cancel a fetch in flight. The candidate set goes with it; nothing is staged.
The candidates staged for one pivot, if any.
Drop a staged set without rejecting anything. Closing a pane is not a verdict: whatever was never rejected is offered again on the next run.
Drop a waiting re-run and carry on with what is on show. Nothing is rejected: the next run offers those candidates again.
What applies to this origin. An empty origin yields the origin-less pivots — search, import, staging — and nothing else, because a selection-driven pivot with no selection has nothing to run on.
A pivot that applies to only part of the origin is in: a selection mixing a domain and an IP offers the domain-only providers too, and each is run against the nodes it kept.
Commit the marked candidates of one staged set.
Purely additive: an id already on canvas is skipped, never overwritten, and
removal only ever happens through graph.history or graph.removeBySource.
The whole batch goes through onBeforeIngest once, and lands as one
dataBatchChanged.
Drop cached summaries: all of them, one pivot's, or only those asked about particular nodes. The library caches because a multi-selection summary is an aggregate nothing can decompose, but only the consumer knows when their backend changed.
OptionalpivotId: stringOptionalnodes: Node[]Mark or unmark a candidate for ingest. Deliberately silent: with hundreds of rows, re-rendering the pane on every tick loses the analyst's place, so the caller updates the row it just changed.
Mark every landable candidate — what "select all" resolves to.
Subscribe to pivot state changes — the registry, a summary, the staged candidates, the run stack. Returns a disposer.
Register a pivot. Returns a disposer; calling it twice is a no-op. A duplicate id is skipped with a warning, as everywhere else in the library.
Reject candidates explicitly. Remembered for the session, keyed per pivot: a candidate rejected under one pivot is still offered by another, which asks about it in a different analytic context.
How many candidates have been rejected for this pivot this session.
The rejected candidate ids for this pivot — what the pane reveals on demand.
The rejections themselves, rows and all, newest last. What a surface listing them shows: an id names nothing once the run that carried it is gone.
Reject everything still untriaged in this set — how triaging 1,800 down to 12 and dismissing the rest stays one gesture.
Run a pivot: gate the advertised count against its cap, fetch, then either land
the results (autoIngest) or stage them for triage.
Resolves at the hand-off — a staged run does not wait on the analyst. The
outcome's runId is the id the resulting ingest is recorded under, so it is
the handle for graph.history.undo.
Write ingested runs back out to the systems their pivots speak to: one run, or every savable run with something still unsaved.
The library contributes the bookkeeping, not the transport — which elements a run created, which of them have been written, and what a retry should carry. The write itself is PivotDefinition.save's, and a pivot that declares none is skipped entirely rather than counted as failing.
Runs go one at a time: a backend being written to is not helped by six parallel batches, and a sequential pass makes the report exact.
Optionaltarget: stringA run id for one run, a pivot id for every unsaved run of that pivot, or nothing for all of them.
Promote a waiting re-run: its candidates become the set on show, and the marks on the one it replaces go with it. A no-op while the re-run is still fetching — swapping in a set with nothing in it yet would be the silent discard this whole mechanism exists to avoid.
Every staged candidate set — one per pivot that has been run and not yet cleared.
Ask a pivot what is out there. Serves a cached answer without touching the provider, and supersedes any summarize already in flight for the same pivot.
Resolves undefined when the call was superseded or cancelled — nothing to
render, and never an error. A provider that throws rejects, so a surface can
show the failure and offer a retry.
Unregister a pivot, dropping its cached summaries and its staged candidates.
Take a rejection back. Reaches the session memory whether or not the candidate is still staged — a rejection from an earlier run suppresses the row rather than showing it, and taking it back is the only way that row is ever offered again.
Take every rejection this pivot holds back. The way out of a Reject all remaining that went too far, which one-by-one restoring is not.
Savable runs with elements still on canvas and not yet written.
What a Save would send — across every savable run, or one pivot's.
OptionalpivotId: stringAbsolute ceiling on what one fetch may stage. A provider that returns more is
refused — nothing is staged, nothing is truncated, and the analyst is told
the number. It is about memory for candidate objects, not the table, which
virtualises. Override it through pivotCandidateCeiling in the graph options.
Whether a node a run created and has not written back carries a
pvt-node-unsaved class. Set it through pivotMarkUnsaved in the graph
options, or here to change it later.
How many new candidates a one-click pivot lands without triage. The number is
about the canvas rather than the clicking: undo takes an ingest back but not the
layout the simulation made around it, so the limit is roughly what a graph can
absorb and still be the graph the analyst was reading. Override it through
pivotQuickIngestLimit in the graph options.
The pivot runtime: the registry, the two provider calls with their cancellation and cache, the narrowing gate, the candidate sets awaiting triage, and ingest with its provenance. Taking a run back is
graph.history's job, alongside every other thing the analyst can reverse.It holds no UI. Everything here is drivable from the console — a pivot with
autoIngest: trueis end to end without a single pane — and the triage pane and the Pivot rail mode are readers of this state, not owners of it.Reached as Graph.pivots.