@graphlearning/graphl-flow 0.7.0 → 0.9.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
@@ -3,8 +3,9 @@
3
3
  Declarative architecture diagrams for React. Describe **groups**, **items** and **edges**; the
4
4
  browser lays them out and the engine draws the arrows. Scenes never contain x/y.
5
5
 
6
- > 0.1.0 — seven node types (`group`, `item`, `table`, `code`, `plot`, `tree`, `note`), edges,
6
+ > 0.9.0 — eight node types (`group`, `item`, `table`, `code`, `plot`, `tree`, `note`, `tty`), edges,
7
7
  > two themes, fit-to-frame for 4K recording. Content repos pin a version and upgrade deliberately.
8
+ > Maintainer rules: `CLAUDE.md`; their history: `docs/DECISIONS.md`; workspace: `../CLAUDE.md`.
8
9
 
9
10
  ## Install
10
11
 
@@ -35,6 +36,62 @@ const scene: SceneModel = {
35
36
  </div>
36
37
  ```
37
38
 
39
+ ## Model
40
+
41
+ | Type | Fields |
42
+ |---------|--------|
43
+ | `item` | `id`, `title`, `muted?`, `sub?`, `icon?`, `bullets?`, `stack?`, `chip?`, `tone?`, `span?` |
44
+ | `group` | `id`, `children`, `title?`, `sub?`, `icon?`, `badge?`, `dir?: 'row' \| 'col' \| 'grid'`, `cols?`, `bare?`, `dashed?`, `muted?`, `spread?`, `cell?: number \| true`, `tone?`, `span?` |
45
+ | `table` | `id`, `rows`, `columns?`, `title?`, `tone?`, `span?` — a row is `[cells…]` or `{ cells, id?, tag?, tone? }` |
46
+ | `code` | `id`, `code`, `lang?`, `filename?`, `show?: [from, to][]`, `highlight?: number[]`, `terminal?`, `output?`, `console?`, `cols?`, `tone?`, `span?` |
47
+ | `tty` | `id`, `screen: string[]`, `title?`, `cols?`, `inverse?`, `bold?` (`[row, from, to][]`) — a full-screen program's grid |
48
+ | `plot` | `id`, `x`, `y` (axes: `min`, `max`, `step?`, `label?`, or `labels` for categories), `series`, `title?`, `axes?`, `grid?` |
49
+ | `tree` | `id`, `entries` (`name`, `children?`, `folder?`, `state?: active \| new \| muted`, `note?`, `icon?`), `title?` |
50
+ | `note` | `id`, `text`, `tone?` — a dashed callout of wrapping prose |
51
+ | any node | `minW?`/`minH?` (floors), `maxW?`/`maxH?` (caps), `w?`/`h?` (exact), `fill?`, `span?`, `tone?`; groups also `bare?` |
52
+ | `Edge` | `from`, `to` (a node id; a table row `table.row`; a code line `code.L12`; a tree entry `tree.src/a.py`; a tty row `top.R7`), `label?`, `dashed?`, `bidirectional?` |
53
+ | `Scene` | `nodes`, `edges?`, `title?`, `sub?`, `dir?`, `pulse?` |
54
+
55
+ **Layout.** A group lays its children out as `dir: 'col'` (default), `'row'` (one column per child)
56
+ or `'grid'` (`cols`, default 2). `span: 'all'` gives a child a full row — a rail under columns.
57
+ Siblings in a row stretch to equal height.
58
+
59
+ **Tone** sets what a box means and is inherited by everything inside it:
60
+
61
+ | tone | hue | | tone | hue |
62
+ |---|---|---|---|---|
63
+ | `neutral` | grey | | `serve` | violet |
64
+ | `source` | slate | | `consume` | red |
65
+ | `ingest` | blue | | `infra` | orange |
66
+ | `store` | green | | | |
67
+
68
+ The theme (`dark` | `light`) picks the shade; repos cannot recolour.
69
+
70
+ ## Group and item looks
71
+
72
+ **`dashed: true`** draws a group's frame dashed — a boundary that is a PLACE, not a thing (an AWS
73
+ Region or Availability Zone, as AWS's own diagrams draw them). Only the line style changes, so
74
+ dashing a group never moves anything.
75
+
76
+ **`spread: true`** on a group spaces its children evenly over its full height when the group is
77
+ stretched taller than them (a short column beside a tall one).
78
+
79
+ **`muted: true`** draws an item greyed, or a group as a plain grey outline — a part the system does
80
+ not have yet, at its full size and place (paint only, so muting moves nothing; a muted group does not
81
+ dim its children). An architecture that grows course by course draws its
82
+ whole final shape from the start.
83
+
84
+ **`chip: true`** draws an item as a small framed pill — a thing counted, not described (`Task 1`,
85
+ `Local disk`); chips fill their grid cell, so a row of them lines up.
86
+
87
+ A nested group is a plain card, unless it names its OWN `tone` — then it is a coloured column again
88
+ (the Spark study's four columns, and its green worker nodes inside the orange Worker column).
89
+
90
+ **`stack: true`** puts an item's icon on top with the text centred under it — a card in a column of
91
+ peers (the Business Consumers column).
92
+
93
+ ## Edges
94
+
38
95
  **Edges** connect any two nodes by id — items or groups, at any depth — as right-angle arrows.
39
96
  An edge leaves across the larger gap between the two columns (or rows) it connects, so it stays in
40
97
  the gaps rather than cutting through a neighbour; ends that face each other connect straight. A face with several edges gives each its
@@ -47,14 +104,11 @@ That period is the recorder's loop (`PULSE_S` in `@graphlearning/shell`'s record
47
104
  video has no jump at the join. `pulse: false` on a scene turns it off. `npm run capture` freezes the
48
105
  animation at t = 0, so stills are reproducible.
49
106
 
50
- **`dashed: true`** draws a group's frame dashed — a boundary that is a PLACE, not a thing (an AWS
51
- Region or Availability Zone, as AWS's own diagrams draw them). Only the line style changes, so
52
- dashing a group never moves anything.
107
+ An edge to an id the scene doesn't have logs a console error naming it.
53
108
 
54
- **`spread: true`** on a group spaces its children evenly over its full height when the group is
55
- stretched taller than them (a short column beside a tall one).
109
+ ## Tables and memory
56
110
 
57
- **Tables and memory.** A `table` is a DB schema, a stack frame, a heap object, an array or a hash
111
+ A `table` is a DB schema, a stack frame, a heap object, an array or a hash
58
112
  map's buckets. Every row is addressable as `<table id>.<first cell>` (or `.<id>` when you set one), so
59
113
  a pointer is just an edge: `{ from: 'main.nums', to: 'list' }`. There is no memory node type —
60
114
  stack and heap are groups of tables:
@@ -71,6 +125,8 @@ A row connects through its left or right end only. Lay a pointer's target BESIDE
71
125
  column), not below it — an edge is routed in the gap between two siblings, never around a third.
72
126
  `tag` draws a short pill before a row (`PK`, `FK`, `sp`); `tone` on a row tints it.
73
127
 
128
+ ## Code, consoles and screens
129
+
74
130
  **Code.** `code` takes the source as a (template-literal) string; its common indent is dropped.
75
131
  `lang` is `python | sql | scala | java | js | ts | shell | hcl | ini | nginx | nft | text` — one small highlighter with seven
76
132
  token colours per theme, sharing one keyword set (Java's primitive types, `record`, `sealed` and
@@ -93,10 +149,29 @@ prompt's colours, red for root's `#`; every other row is output, in ink. A comma
93
149
  (default 80) wide wrapped, so the rows after it continue the command, and the command is highlighted
94
150
  whole across the wrap. `show`, `highlight` and `focus` (`con.L12`) work as on code.
95
151
 
152
+ **psql (0.8).** A console also recognises psql's default prompt: `syndica=>` (a new statement),
153
+ `syndica-*>` / `syndica(>` / `syndica'>` (a continued line; `(` and `'` inside brackets or a string),
154
+ `*` a transaction open, `!` a failed one, and `#` a superuser (red, like root). A statement's
155
+ continuation rows are one command, highlighted as SQL across its lines; `\d`, `\q`… draw as psql's
156
+ own commands. Capture with `psql -n` (no readline) in an 80-column pty.
157
+
96
158
  A full-screen program is a **`tty`**: `screen` (its rows), `cols?` (80), `inverse?` and `bold?` runs
97
159
  as `[row, from, to)` — a fixed grid, padded to `cols`, so two captures of `top` are the same box.
98
160
  Its rows are `tty.R<n>`.
99
161
 
162
+ ## Charts
163
+
164
+ A `plot`'s x/y values are DATA in the axes' own units — sample curves in the scene
165
+ file. A series is `line | scatter | area | bar | segment`. Every plot's drawing area is the same
166
+ fixed size, so charts line up across a deck. Series take the next colour of a fixed ramp
167
+ (blue, orange, violet, green) unless given a `tone`. A `segment` is a dashed construction or threshold
168
+ line — muted grey unless toned, solid with `dashed: false`, a vector with `arrow: true`. Bars label
169
+ themselves in a legend; other series label their last point.
170
+
171
+ ## Frames
172
+
173
+ Recipes for whole video frames; each has a study fixture.
174
+
100
175
  **Console frames (0.7).** Two columns, both FIXED: the console (or a `tty` in its slot, same `w`/`h`) |
101
176
  the PICTURE of what it just showed — a `bare` group of the rest of 16:9. No edges between them; ring
102
177
  the console line with `focus`. See `dev/fixtures/studies/console-frame.ts`.
@@ -120,14 +195,7 @@ so keep them narrow. A plot never scales — use `compact: true` (a 420×280 are
120
195
  Don't draw an edge between the IDE's columns: an arrow widens the gap it crosses and moves every
121
196
  pane. Point at code with `highlight` and the narration; edges INSIDE the side pane are fine.
122
197
 
123
- **Charts.** A `plot`'s x/y values are DATA in the axes' own units — sample curves in the scene
124
- file. A series is `line | scatter | area | bar | segment`. Every plot's drawing area is the same
125
- fixed size, so charts line up across a deck. Series take the next colour of a fixed ramp
126
- (blue, orange, violet, green) unless given a `tone`. A `segment` is a dashed construction or threshold
127
- line — muted grey unless toned, solid with `dashed: false`, a vector with `arrow: true`. Bars label
128
- themselves in a legend; other series label their last point.
129
-
130
- An edge to an id the scene doesn't have logs a console error naming it.
198
+ ## Rendering: legibility, focus, fit, recording
131
199
 
132
200
  **Legibility on video.** The fit scales the whole scene to the frame, so what decides how big text
133
201
  looks is how WIDE the scene is for the text it holds — not the font size. Item text wraps at a
@@ -150,38 +218,9 @@ wait on it before recording.
150
218
  `@graphlearning/shell`'s recorders use. In this repo: `npm run capture -- <fixtureId> --theme dark`
151
219
  writes `captures/<id>-<theme>.png`.
152
220
 
153
- ## Model
221
+ ## Icons
154
222
 
155
- | Type | Fields |
156
- |---------|--------|
157
- | `item` | `id`, `title`, `muted?`, `sub?`, `icon?`, `bullets?`, `stack?`, `chip?`, `tone?`, `span?` |
158
- | `group` | `id`, `children`, `title?`, `sub?`, `icon?`, `badge?`, `dir?: 'row' \| 'col' \| 'grid'`, `cols?`, `bare?`, `dashed?`, `muted?`, `spread?`, `cell?: number \| true`, `tone?`, `span?` |
159
- | `table` | `id`, `rows`, `columns?`, `title?`, `tone?`, `span?` — a row is `[cells…]` or `{ cells, id?, tag?, tone? }` |
160
- | `code` | `id`, `code`, `lang?`, `filename?`, `show?: [from, to][]`, `highlight?: number[]`, `terminal?`, `output?`, `console?`, `cols?`, `tone?`, `span?` |
161
- | `tty` | `id`, `screen: string[]`, `title?`, `cols?`, `inverse?`, `bold?` (`[row, from, to][]`) — a full-screen program's grid |
162
- | `plot` | `id`, `x`, `y` (axes: `min`, `max`, `step?`, `label?`, or `labels` for categories), `series`, `title?`, `axes?`, `grid?` |
163
- | `tree` | `id`, `entries` (`name`, `children?`, `folder?`, `state?: active \| new \| muted`, `note?`, `icon?`), `title?` |
164
- | `note` | `id`, `text`, `tone?` — a dashed callout of wrapping prose |
165
- | any node | `minW?`/`minH?` (floors), `maxW?`/`maxH?` (caps), `w?`/`h?` (exact), `fill?`, `span?`, `tone?`; groups also `bare?` |
166
- | `Edge` | `from`, `to` (a node id; a table row `table.row`; a code line `code.L12`; a tree entry `tree.src/a.py`; a tty row `top.R7`), `label?`, `dashed?`, `bidirectional?` |
167
- | `Scene` | `nodes`, `edges?`, `title?`, `sub?`, `dir?`, `pulse?` |
168
-
169
- **Layout.** A group lays its children out as `dir: 'col'` (default), `'row'` (one column per child)
170
- or `'grid'` (`cols`, default 2). `span: 'all'` gives a child a full row — a rail under columns.
171
- Siblings in a row stretch to equal height.
172
-
173
- **Tone** sets what a box means and is inherited by everything inside it:
174
-
175
- | tone | hue | | tone | hue |
176
- |---|---|---|---|---|
177
- | `neutral` | grey | | `serve` | violet |
178
- | `source` | slate | | `consume` | red |
179
- | `ingest` | blue | | `infra` | orange |
180
- | `store` | green | | | |
181
-
182
- The theme (`dark` | `light`) picks the shade; repos cannot recolour.
183
-
184
- **Icons** share one key space across five sets; an unknown key draws no icon. Keys match
223
+ **Icons** share one key space across six sets; an unknown key draws no icon. Keys match
185
224
  `@graphlearning/flow`'s where both have the icon, so scenes port without renaming.
186
225
 
187
226
  | set | drawn in | keys |
@@ -191,18 +230,5 @@ The theme (`dark` | `light`) picks the shade; repos cannot recolour.
191
230
  | AWS service | its own tile | `acm apigateway athena aurora backup budgets cloudformation cloudfront cloudtrail cloudwatch costexplorer dms dynamodb ec2 ecr ecs eks elasticache elb emr eventbridge fargate firehose glue iam identitycenter kinesis kms lakeformation lambda msk mwaa organizations rds redshift route53 s3 sagemaker secretsmanager sns sqs ssm stepfunctions vpc waf xray` |
192
231
  | AWS group mark | its own tile (for a group's `icon`) | `account autoscaling privatesubnet publicsubnet region` |
193
232
  | AWS resource | a single-colour glyph, no tile | `alb bucket container ecsservice ecstask hostedzone iamrole igw message natgateway permissions queue router sts topic vpcendpoint` |
194
- | brand | its own colour (ink if it would vanish) | `airflow almalinux apple arch bash debian docker duckdb fedora flink git github githubactions grafana java junit jupyter kafka kubernetes letsencrypt linux macos maven mongodb nginx pandas postgresql prometheus python redhat rocky snowflakedb spark terraform ubuntu zsh` |
195
-
196
- **`muted: true`** draws an item greyed, or a group as a plain grey outline — a part the system does
197
- not have yet, at its full size and place (paint only, so muting moves nothing; a muted group does not
198
- dim its children). An architecture that grows course by course draws its
199
- whole final shape from the start.
200
-
201
- **`chip: true`** draws an item as a small framed pill — a thing counted, not described (`Task 1`,
202
- `Local disk`); chips fill their grid cell, so a row of them lines up.
203
-
204
- A nested group is a plain card, unless it names its OWN `tone` — then it is a coloured column again
205
- (the Spark study's four columns, and its green worker nodes inside the orange Worker column).
206
-
207
- **`stack: true`** puts an item's icon on top with the text centred under it — a card in a column of
208
- peers (the Business Consumers column).
233
+ | Google Cloud | its own colours (Google Cloud Icons, Apache-2.0) | `bigquery cloudbuild cloudkms cloudlogging cloudmonitoring composer dataflow dataplex dataproc dlp gcpbilling gcpiam gcpproject gcs pubsub secretmanager` |
234
+ | brand | its own colour (ink if it would vanish) | `airflow almalinux apple arch bash debian docker duckdb fedora flink git github gcp githubactions grafana java junit jupyter kafka kubernetes letsencrypt linux looker macos maven mongodb nginx pandas postgresql prometheus python redhat rocky snowflakedb spark terraform ubuntu zsh` |
package/dist/Code.d.ts CHANGED
@@ -15,15 +15,27 @@ type Row = {
15
15
  */
16
16
  export declare function codeRows(node: Code): Row[];
17
17
  export declare const codeLineIds: (node: Code) => string[];
18
- /** A shell prompt, as the three shells the course meets draw it. `sigil` is `$`/`%`, or `#` for root. */
19
- export interface Prompt {
18
+ /**
19
+ * A prompt: a shell's, as the three shells the course meets draw it (`sigil` is `$`/`%`, or `#` for
20
+ * root), or psql's (0.8) default `%/%R%x%# ` — the database, the input state (`=` a new statement,
21
+ * `-` a continued one, `(` `'` `"` inside brackets or quotes), the transaction state (`*` open, `!`
22
+ * failed, `?` unknown) and `>`, or `#` for a superuser.
23
+ */
24
+ export type Prompt = {
25
+ style: 'debian' | 'redhat' | 'zsh';
20
26
  user: string;
21
27
  host: string;
22
28
  cwd: string;
23
29
  sigil: string;
24
- style: 'debian' | 'redhat' | 'zsh';
25
30
  cmd: string;
26
- }
31
+ } | {
32
+ style: 'psql';
33
+ db: string;
34
+ mode: string;
35
+ tx: string;
36
+ sigil: string;
37
+ cmd: string;
38
+ };
27
39
  export declare function parsePrompt(row: string): Prompt | null;
28
40
  type ConsoleRow = {
29
41
  n: number;
@@ -41,8 +53,11 @@ type ConsoleRow = {
41
53
  };
42
54
  /**
43
55
  * Classify a transcript's rows. A prompt row is a command; a command row exactly `cols` wide wrapped,
44
- * so the rows after it continue the command until one is shorter. The command is tokenized WHOLE and
45
- * its tokens cut back into rows, so a string or a path that crosses the wrap keeps its colour.
56
+ * so the rows after it continue the command until one is shorter. psql (0.8) draws a prompt on every
57
+ * line of a statement, so a psql command also takes the continuation-prompt rows after it (`-`, `(`,
58
+ * `'`, `"`) as further LINES. The command is tokenized WHOLE — lines joined by `\n` — and its tokens
59
+ * cut back into rows, so a string crossing a wrap or a line keeps its colour. A shell command is
60
+ * `shell`, a psql one `sql`.
46
61
  */
47
62
  export declare function consoleRows(lines: string[], cols: number): Map<number, ConsoleRow>;
48
63
  export declare function CodeView({ node, style }: {
@@ -0,0 +1,5 @@
1
+ /** Google Cloud product icons in their own colours: 24×24 SVG bodies, keyed as scenes name them. */
2
+ export declare const GCP: Record<string, {
3
+ title: string;
4
+ body: string;
5
+ }>;
@@ -5,5 +5,10 @@ export interface Tok {
5
5
  }
6
6
  export type Lang = 'python' | 'sql' | 'scala' | 'java' | 'js' | 'ts' | 'shell' | 'hcl' | 'ini' | 'nginx' | 'nft' | 'text';
7
7
  export declare function tokenize(src: string, lang: Lang): Tok[];
8
- /** Drop a leading/trailing blank line and the common indent, so scenes can use indented template literals. */
8
+ /**
9
+ * Drop the template literal's first line break, trailing blank lines and the common indent, so scenes
10
+ * can use indented template literals. Only ONE leading blank line goes (0.8): a timeline pane's
11
+ * transcript can START with blank rows — padding that aligns it with the other session — and
12
+ * stripping them all shifted the whole pane up.
13
+ */
9
14
  export declare function dedent(src: string): string[];
package/dist/icons.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { ComponentType, ReactElement } from 'react';
2
2
  import { type LucideIcon } from 'lucide-react';
3
+ import { GCP } from './gcp-icons';
3
4
  /** Generic glyphs, drawn in the node's tone accent. */
4
5
  export declare const LUCIDE: Record<string, LucideIcon>;
5
6
  /** Azure service tiles, in their own colours. The package ships no viewBox; 0 0 18 18 fits all. */
@@ -22,9 +23,9 @@ export declare const BRAND: Record<string, {
22
23
  hex: string;
23
24
  path: string;
24
25
  }>;
26
+ export { GCP };
25
27
  /** `size` is a CSS length — in em, so an icon scales WITH its text and the ratio stays designed. */
26
28
  type Draw = (size: string, surface: string, ink: string) => ReactElement;
27
29
  /** A brand mark under this contrast against the surface draws in ink (Kafka's black on dark). */
28
30
  export declare const BRAND_MIN_CONTRAST = 2.2;
29
31
  export declare const ICONS: Record<string, Draw>;
30
- export {};