@issuegraph/viewer 0.1.2 → 0.3.0

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.
package/README.md CHANGED
@@ -5,7 +5,7 @@ Render an [Issuegraph](https://github.com/autnmy/issuegraph) document as a **wor
5
5
  The innermost UI layer, and the whole of its contract:
6
6
 
7
7
  ```
8
- in { issues, edges, order } + a projection choice
8
+ in { issues, edges, order, cycles, host? } + a projection choice
9
9
  out onSelect, onHover
10
10
  never fetching, mutation, auth, persistence, or a host's vocabulary
11
11
  ```
@@ -49,15 +49,44 @@ const document = {
49
49
  slots: [{ rank: 1, lead: '102', members: ['102'], ready: true, holds: [] }],
50
50
  excluded: [{ key: '106', canonical: '105', reason: 'duplicate-of' }],
51
51
  },
52
+ cycles: [],
52
53
  };
53
54
  ```
54
55
 
55
56
  **The order is an input, never something this computes.** `@issuegraph/derive` owns the derivation; a second implementation here would be a mirror whose input space drifts. Everything the viewer draws was given to it — including titles and deep links, because knowing a tracker's URL shape is exactly the knowledge this layer must not carry.
56
57
 
57
- `normalizeDocument` never throws. A hand-built document is untrusted input, so a dangling edge is dropped with a diagnostic rather than taking the render down.
58
+ **So is the cycle answer.** `cycles` is the `blocked-by` cycles the document contains, as the host's reader found them — a host fed by [`@issuegraph/reader`](../reader) passes `Model.cycles` verbatim, and a hand-built document passes `[]`. The graph refusal's `cycle` badge on a component capsule is that answer relayed, never a walk over the edges here: this document carries only the edges it can draw (a `together-with` the order does not group is dropped), so a local walk is a picture of the graph, not the graph, and it disagreed with the reader's on a cycle running through a together unit while both were on one screen. It is required rather than optional because a badge that is simply absent reads as "no cycle"; `[]` says none, and omission is a type error. A member the document does not carry is dropped from the cycle with a diagnostic.
59
+
60
+ `normalizeDocument` never throws on a document of the declared shape. A hand-built document is untrusted input, so a dangling edge is dropped with a diagnostic rather than taking the render down. A missing field is not a document: `order` absent has always thrown, and `cycles` absent throws the same way — a plain-JavaScript host migrating from `0.1.x` adds the field.
58
61
 
59
62
  **A deep link is checked, not just escaped.** `url` is the one field that becomes an executable surface in the DOM, so only `http:`, `https:`, `mailto:` and relative values are linked — a `javascript:` or `data:` value is dropped with a diagnostic. Escaping the attribute would not have stopped it.
60
63
 
64
+ ## The host-facts port
65
+
66
+ Roughly half of what the design draws is not derivable from the graph. The format excludes run state on purpose (SPEC §2, §6.8), so who is working what, how many may run at once, and how fresh the mirror is are facts only the **host** holds. `ViewerDocument.host` is the typed way in, and every field of it is optional: **a host that supplies nothing renders exactly the pure-graph view** — pinned by a test that compares the markup byte for byte.
67
+
68
+ | what the design shows | where it enters | what the viewer does |
69
+ |---|---|---|
70
+ | `6 ranked · 4 ready now · cap 2 · 4 held` | `host.counts` and `host.concurrencyCap` | prints the host's numbers in a summary line; renders nothing when both are absent |
71
+ | `now · <title> · Review · 12m` | `host.running[]` — `{ key, phase, elapsed }` | one NOW row per job above the order (linear) and above the stage (graph), from the issue's own title and identity |
72
+ | `as of 14:32 · 2m ago` · `stale` · refresh | `host.freshness` — `{ asOf, age?, stale?, refresh? }` | the stamp verbatim, `data-stale`, and a `button[data-ig-command="refresh"]` only when a label is supplied |
73
+ | `claimed` · `parked` in the footer | `TrackerHold.label` on a slot's hold | a chip before the hold's sentence, and the words in the footer title |
74
+ | `matched ordered query 1 · label:P0` | `ViewerIssue.provenance` (`matched-query`) | already shipped |
75
+ | `◐ preview-only` | `ViewerIssue.previewOnly` — `{ note }` | a badge and the host's note, one line under provenance |
76
+ | `◆ signals disagree` | `ViewerIssue.disagreement` — `{ used, ignored: { carrier, value } }` | a badge and `ranked by … · … declares ~~value~~`, only the losing value struck |
77
+ | `owner/repo#N ↗` | `ViewerIssue.url` | already shipped |
78
+ | write pending / failed / conflict | `@issuegraph/editor`'s `EdgeOverlay` | the editor's, drawn as overlays; the viewer needs no edit awareness |
79
+
80
+ **The counts are the host's numbers, and the viewer counts nothing.** The document this layer holds may be a window (the editor's rail slices the slots) or a slice (a host showing the next twenty-five), and a count over its slots would state the reader's scroll position as a fact about the order. The host has the whole order; it counts. For the same reason nothing here is a viewer constant — no cap, no clock, no repository name — and every string the host supplies is printed as the host wrote it.
81
+
82
+ **The two hold families are distinct types.** `ViewerHold` is `GraphHold | TrackerHold`, discriminated on `family`. A graph hold — an open `blocked-by`, a serialize peer being worked — renders inline at its would-be rank; a tracker hold — claimed, parked — renders in the footer. Only the tracker arm carries `label`, so a document cannot label a graph hold: the family is the whole of what it is. A `{ family: 'tracker', reason }` written before the label existed still type-checks.
83
+
84
+ **The NOW row is a pointer identity, never a focus one.** The running issue may also hold a slot, and exactly one element per key carries `data-ig-key`. So the row announces itself through `data-ig-group`, like the `together-with` enclosure does: a click selects the issue and `onSelect` fires with its key, a hover reports it, and the keyboard order is untouched. A running job whose key the document does not carry is dropped with a diagnostic, and a running issue is never counted as isolated.
85
+
86
+ **The refresh control is published, not wired.** Refreshing a mirror is fetching, which this layer never does. The button carries `data-ig-command="refresh"` — the same attribute `@issuegraph/editor` reads for its own controls, whose reducer answers a command it does not know by changing nothing — so a host that already listens for the editor's commands hears this one through the same listener. The demo does exactly that.
87
+
88
+ `normalizeDocument` validates the port the way it validates everything else: a cap or a count that is not a non-negative integer is dropped (the counts whole), a running key the document does not carry or names twice is dropped, and a freshness with an empty `asOf` is dropped whole — each with one diagnostic.
89
+
61
90
  ## The three projections
62
91
 
63
92
  | projection | question it answers |
@@ -66,12 +95,14 @@ const document = {
66
95
  | `graph` | what surrounds this issue — the spine with gutters and arcs. Bounded; see below. |
67
96
  | `tree` | where this work came from — the `decomposed-from` hierarchy. |
68
97
 
69
- **Held slots keep their position.** A hold the graph itself imposes renders *inline at the rank the work would have taken*, with `—` for the rank and a dashed station, because "why isn't my P1 running" has to be answerable in place. A hold the runner or tracker imposes is not a fact about the work, earns no rank slot, and collapses into a footer group with duplicates.
98
+ **Held slots keep their position.** A hold the graph itself imposes renders *inline at the rank the work would have taken*, with `—` for the rank and a dashed station, because "why isn't my P1 running" has to be answerable in place. A hold the runner or tracker imposes is not a fact about the work, earns no rank slot, and collapses into a footer group with duplicates. A hold's optional `code` and `subject` — the reader's machine-readable cause and the issue it names — are published as `data-code` and `data-subject` beside `data-family`, and omitted rather than emptied when the host stated neither; the viewer interprets neither and renders `reason` verbatim as before.
70
99
 
71
100
  **The rail sits on the canvas, not above it.** Ranks and readiness stations are HTML — SVG text is not selectable, not reflowable and announces poorly — but they are the labels *for* the spine nodes, so each row is positioned at the coordinates the layout computed for its own node. One stage carries both at the layout's own size, so one SVG unit is one CSS pixel and the two cannot drift; it scrolls rather than shrinking, because shrinking would silently break that alignment.
72
101
 
73
102
  **The graph refuses rather than degrades.** Past 60 nodes it stops drawing and shows connected components as capsules — size, blocking count, cycle flag, chain depth — and past 300 it shows clusters only. Each refusal names the next move. A refusal with a route forward reads as competence; a hairball reads as a bug.
74
103
 
104
+ **A row's badges are budgeted; the order is not.** The linear and tree projections draw every row at any size — that is the promise the refusal routes a reader to — so what they bound is the relationships *per row*: past `ROW_BADGE_BUDGET` (12) a row draws the first twelve in the format's field order, `blocked-by` first, and one `+N more relationships` chip carrying `data-omitted`, its name in its visible text because ARIA prohibits naming a generic span. Nothing is cut silently, and the chip carries no edge identity because it names no single edge; an omitted edge is still selectable, since the drawn-check answers from the document before it consults the markup.
105
+
75
106
  ## The edge grammar
76
107
 
77
108
  Every relationship is separable on **four** channels — dash, terminal marker, glyph, and hue — so removing colour entirely leaves all five distinguishable. That is asserted as a property of the table, not claimed about the rendering.
@@ -94,7 +125,16 @@ So `onSelect` reports **either** an issue key or an edge identity. Distinguish t
94
125
 
95
126
  ## Theming
96
127
 
97
- **Every colour, type and spacing value is a CSS custom property.** The shipped palette is the *default theme*, not the styling — a host retheming it forks nothing.
128
+ **Every colour, type, spacing and surface-treatment value is a CSS custom property.** The shipped palette is the *default theme*, not the styling — a host retheming it forks nothing.
129
+
130
+ The tokens come in **four groups**, and the group decides how the value reaches CSS: `colors` and `type` are emitted verbatim, `metrics` are numbers that gain a `px` unit, and `effects` are emitted verbatim because none of them is a length — a tint is a proportion and an elevation is a whole `box-shadow`. **No tint carries a colour**: it is applied against a colour token that already exists, so retheming a relationship retints its badge. The two elevations are the exception and are deliberately literal — a shadow is dark on a light ground too, so a light theme owns them.
131
+
132
+ ```css
133
+ .ig-badge {
134
+ background: color-mix(in srgb, var(--ig-edge-blocked-by) var(--ig-tint-fill), transparent);
135
+ border-color: color-mix(in srgb, var(--ig-edge-blocked-by) var(--ig-tint-border), transparent);
136
+ }
137
+ ```
98
138
 
99
139
  ```ts
100
140
  import { defaultTheme, extendTheme, renderViewer, viewerStylesheet } from '@issuegraph/viewer';
@@ -128,6 +168,8 @@ That exact theme is the one `acceptance.test.ts` uses, so the example cannot dri
128
168
 
129
169
  **Geometry is theme data too.** `metrics` are numbers, in CSS pixels, and they are what the layout maths reads — so retheming the row height moves the drawing and the stylesheet together rather than only one of them.
130
170
 
171
+ **Adding a token never moves an existing one.** `--ig-row-height` is the *fixed* height of a rail row and keeps that meaning; `--ig-row-min-height` and `--ig-row-padding-block` are the separate vocabulary a content-sized row needs. The same rule holds for the spacing scale and the radius steps, which were added around the values that shipped rather than replacing them.
172
+
131
173
  **The proof that theming is real**: rendering the same document under two themes produces **byte-identical markup** and different styles. If any colour reached the markup, that equality would fail.
132
174
 
133
175
  **CSS ships as a string, not a `.css` file.** An entry that imports CSS cannot be loaded by a bare Node runtime, and a string means no consumer needs a bundler. Install `viewerStylesheet` once and `themeCss(theme)` per theme.
@@ -8,14 +8,27 @@
8
8
  * competence; a hairball reads as a bug.
9
9
  *
10
10
  * Components are undirected — every relationship connects, whatever its
11
- * direction — while the depth and cycle questions are asked of `blocked-by`
12
- * alone, because that is the only field that orders anything.
11
+ * direction — while the depth question is asked of `blocked-by` alone, because
12
+ * that is the only field that orders anything.
13
+ *
14
+ * THE CYCLE QUESTION IS NOT ASKED HERE AT ALL. It is answered by the host —
15
+ * `ViewerDocument.cycles`, the reader's own §6.6 stuck groups — and this module
16
+ * only reads which components those cycles touch. It used to walk the edges for
17
+ * the answer itself, and that walk disagreed with the host's on a cycle running
18
+ * through a together unit: the reader contracts a unit to one vertex and this
19
+ * document does not even carry every together edge, so the two were bound to
20
+ * differ, and both were on one screen. One answer, given, is the rule this
21
+ * package already applies to the order; the cycle badge follows it.
13
22
  */
14
23
  import type { NormalizedDocument } from './document.ts';
15
24
  export interface Cluster {
16
25
  /** Members in the document's own key order, so the output is deterministic. */
17
26
  readonly members: readonly string[];
18
27
  readonly blockedByEdges: number;
28
+ /**
29
+ * Whether the host's `cycles` name any member of this component. The host's
30
+ * answer, relayed — never derived from the edges here.
31
+ */
19
32
  readonly hasCycle: boolean;
20
33
  /** The longest `blocked-by` chain, in edges. `0` when nothing blocks. */
21
34
  readonly chainDepth: number;
@@ -1 +1 @@
1
- {"version":3,"file":"clusters.d.ts","sourceRoot":"","sources":["../src/clusters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,WAAW,OAAO;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAkID,kFAAkF;AAClF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,kBAAkB;AAC5B;;;;;;;GAOG;AACH,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAC1B,SAAS,OAAO,EAAE,CAyCpB"}
1
+ {"version":3,"file":"clusters.d.ts","sourceRoot":"","sources":["../src/clusters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,WAAW,OAAO;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAuID,kFAAkF;AAClF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,kBAAkB;AAC5B;;;;;;;GAOG;AACH,KAAK,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAC1B,SAAS,OAAO,EAAE,CAiDpB"}
package/dist/clusters.js CHANGED
@@ -8,8 +8,17 @@
8
8
  * competence; a hairball reads as a bug.
9
9
  *
10
10
  * Components are undirected — every relationship connects, whatever its
11
- * direction — while the depth and cycle questions are asked of `blocked-by`
12
- * alone, because that is the only field that orders anything.
11
+ * direction — while the depth question is asked of `blocked-by` alone, because
12
+ * that is the only field that orders anything.
13
+ *
14
+ * THE CYCLE QUESTION IS NOT ASKED HERE AT ALL. It is answered by the host —
15
+ * `ViewerDocument.cycles`, the reader's own §6.6 stuck groups — and this module
16
+ * only reads which components those cycles touch. It used to walk the edges for
17
+ * the answer itself, and that walk disagreed with the host's on a cycle running
18
+ * through a together unit: the reader contracts a unit to one vertex and this
19
+ * document does not even carry every together edge, so the two were bound to
20
+ * differ, and both were on one screen. One answer, given, is the rule this
21
+ * package already applies to the order; the cycle badge follows it.
13
22
  */
14
23
  function connectedComponents(document, drawn) {
15
24
  const adjacency = new Map();
@@ -67,19 +76,25 @@ function connectedComponents(document, drawn) {
67
76
  return components;
68
77
  }
69
78
  /**
70
- * The longest `blocked-by` chain inside one component, and whether that
71
- * component contains a cycle.
79
+ * The longest `blocked-by` chain inside one component, in edges.
72
80
  *
73
81
  * A cycle makes "longest chain" undefined, so the walk reports the depth it
74
- * reached over the acyclic part and says a cycle exists rather than looping or
75
- * inventing a number. Both facts are useful to a reader; a hang is not.
82
+ * reached over the acyclic part rather than looping or inventing a number.
83
+ *
84
+ * IT MEETS BACK-EDGES AND PUBLISHES NOTHING ABOUT THEM. Skipping the edge that
85
+ * closes a loop is what makes this walk TERMINATE and its number finite; it is
86
+ * not a cycle answer, and it must not be read as one — whether a component
87
+ * contains a cycle is the host's `cycles`, read in `clustersOf` below. A raw
88
+ * loop this walk steps over (through a closed issue, say) can be one the
89
+ * reader does not report, and a stuck unit the reader does report can be one
90
+ * this walk cannot see. Two answers to one question is the defect this module
91
+ * was rewritten to remove.
76
92
  */
77
- function depthAndCycle(members, blockedBy) {
93
+ function chainDepthOf(members, blockedBy) {
78
94
  const memo = new Map();
79
95
  const onPath = new Set();
80
- let hasCycle = false;
81
96
  // The edges the discovery pass refused to follow, keyed `from\u0000to` so a
82
- // cycle through one member does not suppress that member's other edges.
97
+ // loop through one member does not suppress that member's other edges.
83
98
  const backEdges = new Set();
84
99
  // ITERATIVE, NOT RECURSIVE. This runs on the graph's REFUSAL path, which is
85
100
  // reached precisely because the component is large — so a per-node call frame
@@ -100,12 +115,11 @@ function depthAndCycle(members, blockedBy) {
100
115
  onPath.add(frame.key);
101
116
  for (const next of blockedBy.get(frame.key) ?? []) {
102
117
  if (onPath.has(next)) {
103
- hasCycle = true;
104
- // REMEMBER WHICH EDGE CLOSED THE CYCLE, not just that one did. The
105
- // collecting pass below walks the same adjacency and has no other
106
- // way to tell a back-edge from an ordinary one, so it counted this
107
- // edge against a memo that was never written — `?? 0` — and every
108
- // cycle came out one edge too long. Measured: a two-node cycle
118
+ // REMEMBER WHICH EDGE CLOSED THE LOOP. The collecting pass below
119
+ // walks the same adjacency and has no other way to tell a back-edge
120
+ // from an ordinary one, so it counted this edge against a memo that
121
+ // was never written `?? 0` and every loop came out one edge too
122
+ // long. Measured: a two-node cycle
109
123
  // published `chainDepth: 2` beside its cycle badge when the longest
110
124
  // acyclic chain through it is one edge, and a three-node cycle
111
125
  // published 3 for a chain of two.
@@ -135,7 +149,7 @@ function depthAndCycle(members, blockedBy) {
135
149
  let depth = 0;
136
150
  for (const member of members)
137
151
  depth = Math.max(depth, memo.get(member) ?? 0);
138
- return { depth, hasCycle };
152
+ return depth;
139
153
  }
140
154
  /** Every component the document declares, largest first, then by first member. */
141
155
  export function clustersOf(document,
@@ -158,6 +172,12 @@ drawn) {
158
172
  else
159
173
  existing.push(edge.to);
160
174
  }
175
+ // Every issue the host reports as inside a `blocked-by` cycle. Read off the
176
+ // document, which already narrowed the host's cycles to the keys it carries.
177
+ const stuck = new Set();
178
+ for (const cycle of document.cycles)
179
+ for (const member of cycle)
180
+ stuck.add(member);
161
181
  const clusters = connectedComponents(document, drawn).map((members) => {
162
182
  // SUMMED OFF THE ADJACENCY ABOVE, NOT RE-FILTERED PER COMPONENT. This used to
163
183
  // scan the WHOLE edge array once per component, which is quadratic in exactly
@@ -174,8 +194,11 @@ drawn) {
174
194
  let blockedByEdges = 0;
175
195
  for (const member of members)
176
196
  blockedByEdges += blockedBy.get(member)?.length ?? 0;
177
- const { depth, hasCycle } = depthAndCycle(members, blockedBy);
178
- return { members, blockedByEdges, hasCycle, chainDepth: depth };
197
+ // THE HOST'S ANSWER, LOOKED UP never re-derived. A cycle the reader
198
+ // found touches this component when any member of it is a member here; the
199
+ // set is built once above, so the whole pass stays linear.
200
+ const hasCycle = members.some((member) => stuck.has(member));
201
+ return { members, blockedByEdges, hasCycle, chainDepth: chainDepthOf(members, blockedBy) };
179
202
  });
180
203
  // CODE UNITS, NOT `localeCompare`. This package promises deterministic
181
204
  // rendering, and `localeCompare` without an explicit locale uses the RUNTIME's
@@ -1 +1 @@
1
- {"version":3,"file":"clusters.js","sourceRoot":"","sources":["../src/clusters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAaH,SAAS,mBAAmB,CAC1B,QAA4B,EAC5B,KAAsC;IAEtC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC9C,MAAM,KAAK,GAAG,CAAC,GAAW,EAAY,EAAE;QACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5B,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,UAAU,GAAe,EAAE,CAAC;IAClC,sEAAsE;IACtE,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,SAAS;QAClC,0EAA0E;QAC1E,4EAA4E;QAC5E,uEAAuE;QACvE,2EAA2E;QAC3E,uEAAuE;QACvE,mEAAmE;QACnE,gDAAgD;QAChD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9E,SAAS;QACX,CAAC;QACD,wEAAwE;QACxE,0EAA0E;QAC1E,gDAAgD;QAChD,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;YAAE,SAAS;QAC3D,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpB,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAY,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClB,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC5C,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QACD,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,aAAa,CACpB,OAA0B,EAC1B,SAAiD;IAEjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,4EAA4E;IAC5E,wEAAwE;IACxE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,4EAA4E;IAC5E,8EAA8E;IAC9E,8EAA8E;IAC9E,8EAA8E;IAC9E,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QAC9B,MAAM,KAAK,GAAyC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACtF,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAuC,CAAC;YAC5E,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,KAAK,CAAC,GAAG,EAAE,CAAC;gBACZ,SAAS;YACX,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACpB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACtB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACtB,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;oBAClD,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;wBACrB,QAAQ,GAAG,IAAI,CAAC;wBAChB,mEAAmE;wBACnE,kEAAkE;wBAClE,mEAAmE;wBACnE,kEAAkE;wBAClE,+DAA+D;wBAC/D,oEAAoE;wBACpE,+DAA+D;wBAC/D,kCAAkC;wBAClC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,SAAS,IAAI,EAAE,CAAC,CAAC;wBAC3C,SAAS;oBACX,CAAC;oBACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;wBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;gBAClE,CAAC;gBACD,SAAS;YACX,CAAC;YACD,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;gBAClD,wEAAwE;gBACxE,mEAAmE;gBACnE,wEAAwE;gBACxE,mEAAmE;gBACnE,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,SAAS,IAAI,EAAE,CAAC;oBAAE,SAAS;gBACzD,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACzB,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,UAAU,CACxB,QAA4B;AAC5B;;;;;;;GAOG;AACH,KAA2B;IAE3B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,KAAK,KAAK,YAAY;YAAE,SAAS;QAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,QAAQ,KAAK,SAAS;YAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;;YAC3D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACpE,8EAA8E;QAC9E,8EAA8E;QAC9E,0EAA0E;QAC1E,2EAA2E;QAC3E,6EAA6E;QAC7E,4EAA4E;QAC5E,cAAc;QACd,6EAA6E;QAC7E,4EAA4E;QAC5E,6EAA6E;QAC7E,0EAA0E;QAC1E,sCAAsC;QACtC,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,cAAc,IAAI,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;QACnF,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC9D,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,uEAAuE;IACvE,+EAA+E;IAC/E,yEAAyE;IACzE,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,8DAA8D;IAC9D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC5B,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACtF,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACjC,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"clusters.js","sourceRoot":"","sources":["../src/clusters.ts"],"names":[],"mappings":"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"}
@@ -14,10 +14,12 @@
14
14
  * source. The viewer derives no order, resolves no reference, and reads no
15
15
  * tracker — everything it draws was given to it.
16
16
  *
17
- * `normalizeDocument` is the one entry point. It never throws: a document
18
- * assembled by hand is untrusted input, not a contract, and a renderer that
19
- * dies on a dangling edge is worse than one that draws what it can and says
20
- * what it dropped.
17
+ * `normalizeDocument` is the one entry point. It never throws on a document of
18
+ * the declared shape: a document assembled by hand is untrusted input, not a
19
+ * contract, and a renderer that dies on a dangling edge is worse than one that
20
+ * draws what it can and says what it dropped. A MISSING FIELD IS OUTSIDE THAT
21
+ * PROMISE — `order` absent has always thrown, and `cycles` absent throws the
22
+ * same way — because a document without one is a type error, not a document.
21
23
  */
22
24
  import { type EdgeField } from '@issuegraph/core';
23
25
  /**
@@ -63,11 +65,79 @@ export type HoldFamily =
63
65
  * into a footer group.
64
66
  */
65
67
  | 'tracker';
66
- /** One reason a slot is held, and which family it belongs to. */
67
- export interface ViewerHold {
68
- readonly family: HoldFamily;
68
+ /** What every hold carries, whichever family imposed it. */
69
+ interface HoldBase {
69
70
  /** Human-readable, host-authored. The viewer renders it verbatim. */
70
71
  readonly reason: string;
72
+ /**
73
+ * The machine-readable cause, host-authored like `reason`. A host fed by
74
+ * `@issuegraph/reader` supplies its `ReadinessHold.code`; the viewer
75
+ * publishes whatever it is given as `data-code` and interprets none of it,
76
+ * because the vocabulary is the reader's and this layer restates nothing.
77
+ * OPTIONAL BY DESIGN: a hold the tracker or runner imposes has no reader
78
+ * code, and inventing one would be a second vocabulary.
79
+ */
80
+ readonly code?: string | undefined;
81
+ /**
82
+ * The issue the cause names — the open blocker, the claimed peer, the unready
83
+ * member — when it names one, as the document's own key for it. Published as
84
+ * `data-subject` so a host can turn the sentence into a link or a filter
85
+ * facet; the viewer draws it as text and links nothing (it has no URL shape
86
+ * to link with — see `ViewerIssue.url`).
87
+ */
88
+ readonly subject?: string | undefined;
89
+ }
90
+ /** A hold the graph itself imposes. Drawn inline at the rank the work would have taken. */
91
+ export interface GraphHold extends HoldBase {
92
+ readonly family: 'graph';
93
+ }
94
+ /**
95
+ * A hold the runner or the tracker imposes. Drawn in the footer, with no rank.
96
+ *
97
+ * THE ONE ARM THAT CARRIES A LABEL, and the reason the hold is a union rather
98
+ * than one interface with a family string: the design's footer names each
99
+ * runner hold by ONE WORD — `claimed`, `parked` — beside the sentence, and a
100
+ * graph hold has no such word (its family is the whole of what it is). Putting
101
+ * `label` on both arms would let a document label a graph hold, which nothing
102
+ * draws; narrowing it here makes that a type error rather than a silent drop.
103
+ * OPTIONAL, because a host that supplied `{ family: 'tracker', reason }` before
104
+ * this field existed still does, and still type-checks.
105
+ */
106
+ export interface TrackerHold extends HoldBase {
107
+ readonly family: 'tracker';
108
+ /** The runner's own word for the hold — `claimed`, `parked`. Rendered as a chip before `reason`. */
109
+ readonly label?: string | undefined;
110
+ }
111
+ /**
112
+ * One reason a slot is held, and which family it belongs to. A discriminated
113
+ * union on `family`, so the two families are told apart by the type system
114
+ * and not by a string a call site happens to compare.
115
+ */
116
+ export type ViewerHold = GraphHold | TrackerHold;
117
+ /**
118
+ * A pick-order query the host's engine could not evaluate locally, so the row
119
+ * was ranked some other way. The host says how; the viewer prints the note
120
+ * under a `◐ preview-only` badge and interprets nothing.
121
+ */
122
+ export interface PreviewOnly {
123
+ readonly note: string;
124
+ }
125
+ /**
126
+ * Two ordering signals that disagree about this issue — a mapped label and a
127
+ * frontmatter `priority`, say. WHICH ONE WINS IS THE HOST'S DECISION (the
128
+ * design is explicit that precedence is an owner call, not a default), so the
129
+ * host names the signal it ranked by and the one it set aside; the viewer
130
+ * prints both and strikes only the losing value, so the loser stays legible.
131
+ */
132
+ export interface Disagreement {
133
+ /** The signal the rank came from, as the host spells it: `label:P1 (your mapping)`. */
134
+ readonly used: string;
135
+ readonly ignored: {
136
+ /** Who declared the losing value: `frontmatter`. */
137
+ readonly carrier: string;
138
+ /** The losing value itself, struck through: `priority: 3`. */
139
+ readonly value: string;
140
+ };
71
141
  }
72
142
  /** One issue the document knows about. */
73
143
  export interface ViewerIssue {
@@ -87,6 +157,10 @@ export interface ViewerIssue {
87
157
  readonly priority: number;
88
158
  /** Absent when the host has no provenance to state. */
89
159
  readonly provenance?: RankProvenance | undefined;
160
+ /** Set when the host's engine ranked this row by a fallback. Absent means the query evaluated. */
161
+ readonly previewOnly?: PreviewOnly | undefined;
162
+ /** Set when two host signals disagreed about this row. Absent means they agreed, or there was one. */
163
+ readonly disagreement?: Disagreement | undefined;
90
164
  }
91
165
  /** One relationship, exactly as the format declares it. */
92
166
  export interface ViewerEdge {
@@ -137,11 +211,107 @@ export interface ViewerOrder {
137
211
  readonly slots: readonly ViewerSlot[];
138
212
  readonly excluded: readonly ViewerExclusion[];
139
213
  }
214
+ /**
215
+ * One `blocked-by` cycle, as the host's reader found it: every member key, in
216
+ * whatever order the host supplied. A cycle of one is a self-loop.
217
+ *
218
+ * ONCE NORMALISED IT IS THE MEMBERS THIS DOCUMENT CARRIES, which need not be
219
+ * a closed ring: a document that is a slice of the graph — a window, a focus
220
+ * — keeps the members it draws and drops the rest, exactly as it does for the
221
+ * edges. A cycle is still a stuck group, and a member of one is still stuck.
222
+ */
223
+ export type ViewerCycle = readonly string[];
224
+ /**
225
+ * The host's tally over the WHOLE order — every number a non-negative integer.
226
+ *
227
+ * SUPPLIED, NEVER COUNTED HERE, and the reason is the same one that keeps the
228
+ * order itself an input: the document this layer holds may be a window (the
229
+ * editor's rail slices the slots) or a slice (a host showing the next
230
+ * twenty-five). A count over those slots would state the reader's scroll
231
+ * position as a fact about the order. The host has the whole order; it counts.
232
+ */
233
+ export interface OrderCounts {
234
+ /** Slots that hold a rank. */
235
+ readonly ranked: number;
236
+ /** Slots that may start now — the number the design compares to the cap. */
237
+ readonly readyNow: number;
238
+ /** Slots held, by either family. */
239
+ readonly held: number;
240
+ }
241
+ /** The job the host's runner is working right now. Every string is the host's. */
242
+ export interface RunningJob {
243
+ /** The document's key for the issue being worked. Must be an issue this document carries. */
244
+ readonly key: string;
245
+ /** The runner's phase word: `Review`. */
246
+ readonly phase: string;
247
+ /** How long it has run, as the host formats it: `12m`. */
248
+ readonly elapsed: string;
249
+ }
250
+ /**
251
+ * How fresh the host's mirror is. The viewer has no clock, so every value here
252
+ * is the host's text, formatted by the host.
253
+ */
254
+ export interface Freshness {
255
+ /** The stamp: `14:32`. Empty drops the whole freshness fact with a diagnostic. */
256
+ readonly asOf: string;
257
+ /** Relative age, when the host states it: `2m ago`. */
258
+ readonly age?: string | undefined;
259
+ /** Past the host's threshold. Renders the word `stale` and `data-stale="true"`. */
260
+ readonly stale?: boolean | undefined;
261
+ /**
262
+ * The label of a refresh control. WHEN PRESENT, AND ONLY THEN, the viewer
263
+ * renders a button carrying `data-ig-command="refresh"` and wires nothing to
264
+ * it — refreshing is the host's, so the host listens for the command.
265
+ */
266
+ readonly refresh?: string | undefined;
267
+ }
268
+ /**
269
+ * THE HOST-FACTS PORT: the half of the design the graph cannot derive.
270
+ *
271
+ * The format excludes run state on purpose (SPEC §2, §6.8), so who is working
272
+ * what, how many may run at once, and how fresh the mirror is are facts only
273
+ * the host holds. Every field is optional, and a host that supplies none of
274
+ * them renders exactly the pure-graph view — pinned by test. Nothing here is a
275
+ * viewer constant: no cap, no clock, no repository name.
276
+ */
277
+ export interface HostFacts {
278
+ /** How many ready slots may run at once. A non-negative integer. */
279
+ readonly concurrencyCap?: number | undefined;
280
+ readonly counts?: OrderCounts | undefined;
281
+ readonly running?: readonly RunningJob[] | undefined;
282
+ readonly freshness?: Freshness | undefined;
283
+ }
140
284
  /** Everything the viewer draws. */
141
285
  export interface ViewerDocument {
142
286
  readonly issues: readonly ViewerIssue[];
143
287
  readonly edges: readonly ViewerEdge[];
144
288
  readonly order: ViewerOrder;
289
+ /**
290
+ * The `blocked-by` cycles the document contains, AS THE HOST DERIVED THEM.
291
+ * A host fed by `@issuegraph/reader` passes `Model.cycles` verbatim — the
292
+ * spec's §6.6 stuck groups; a hand-assembled document passes `[]`.
293
+ *
294
+ * REQUIRED, LIKE `order`, AND FOR THE SAME REASON: the viewer derives no
295
+ * cycle, as it derives no order — the edges here are the ones it can draw,
296
+ * not the graph, so a walk over them is a mirror whose input space drifts
297
+ * (see `clusters.ts`). And a badge that is simply absent reads as "no
298
+ * cycle", so an answer a host forgot to pass must not render as one: `[]`
299
+ * says none, and omission is a type error.
300
+ */
301
+ readonly cycles: readonly ViewerCycle[];
302
+ /**
303
+ * What the host knows and the graph does not. OPTIONAL, unlike `order` and
304
+ * `cycles`, because absence here is a complete answer: a host with no runner
305
+ * has no run state to state, and the pure-graph view is what it means.
306
+ */
307
+ readonly host?: HostFacts | undefined;
308
+ }
309
+ /** The host facts after normalisation: `running` always a list, the rest present only when the host stated them. */
310
+ export interface NormalizedHostFacts {
311
+ readonly concurrencyCap?: number | undefined;
312
+ readonly counts?: OrderCounts | undefined;
313
+ readonly running: readonly RunningJob[];
314
+ readonly freshness?: Freshness | undefined;
145
315
  }
146
316
  /**
147
317
  * A normalised document plus an index over it. The index exists so no
@@ -152,6 +322,12 @@ export interface NormalizedDocument {
152
322
  readonly issues: readonly ViewerIssue[];
153
323
  readonly edges: readonly ViewerEdge[];
154
324
  readonly order: ViewerOrder;
325
+ /**
326
+ * The host's cycles, narrowed to the keys this document carries. Every
327
+ * member here is present in `byKey`; a cycle none of whose members are is
328
+ * not here at all.
329
+ */
330
+ readonly cycles: readonly ViewerCycle[];
155
331
  /** Key -> issue. Every edge and slot member below is present here. */
156
332
  readonly byKey: ReadonlyMap<string, ViewerIssue>;
157
333
  /** Key -> the edges touching it, in document order. */
@@ -170,6 +346,8 @@ export interface NormalizedDocument {
170
346
  * provenance when in fact its provenance was not supplied.
171
347
  */
172
348
  readonly outOfSetOrigins: ReadonlyMap<string, string>;
349
+ /** The host facts, validated. Always present; every field but `running` is present only when stated. */
350
+ readonly host: NormalizedHostFacts;
173
351
  }
174
352
  export interface NormalizeResult {
175
353
  readonly document: NormalizedDocument;
@@ -183,8 +361,10 @@ export interface NormalizeResult {
183
361
  /**
184
362
  * Read a document into the shape every projection consumes.
185
363
  *
186
- * Deterministic and total: the same input always produces the same output, and
187
- * no input produces a throw. Call it once per render and pass the result down.
364
+ * Deterministic and total over the declared shape: the same input always
365
+ * produces the same output, and no document produces a throw. Call it once per
366
+ * render and pass the result down.
188
367
  */
189
368
  export declare function normalizeDocument(input: ViewerDocument): NormalizeResult;
369
+ export {};
190
370
  //# sourceMappingURL=document.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}