flowink 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FlowInk contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICE.md ADDED
@@ -0,0 +1,17 @@
1
+ # Third-party notices
2
+
3
+ FlowInk's own source is licensed under MIT.
4
+
5
+ The flowchart grammar, portions of parsing/semantic processing, and upstream
6
+ compatibility fixtures derive from Mermaid 12.0.0 (MIT), tag `mermaid@12.0.0`,
7
+ commit `98a0945418c76238f15df2afaddbba4272656c3b`.
8
+ Source: https://github.com/mermaid-js/mermaid/tree/mermaid%4012.0.0
9
+ The upstream license and grammar provenance are included in `vendor/mermaid`.
10
+ The parser is generated at build time by Jison (MIT).
11
+
12
+ Runtime dependencies retain their own licenses; they are installed separately
13
+ and not relicensed by FlowInk. In particular, elkjs is distributed under
14
+ `EPL-2.0 OR GPL-3.0-or-later`; its license is included in the installed elkjs
15
+ package. See https://github.com/kieler/elkjs/blob/master/LICENSE.md.
16
+
17
+ Graph::Easy is a visual reference. FlowInk contains no Graph::Easy code.
package/README.md ADDED
@@ -0,0 +1,301 @@
1
+ <div align="center">
2
+
3
+ # FlowInk
4
+
5
+ **Mermaid flowcharts, rendered as text.**
6
+
7
+ ASCII and Unicode diagrams for Node.js and the browser.
8
+
9
+ [![npm version](https://img.shields.io/npm/v/flowink)](https://www.npmjs.com/package/flowink)
10
+ [![JavaScript ESM](https://img.shields.io/badge/JavaScript-ESM-f7df1e?logo=javascript&logoColor=111111)](#quick-start)
11
+ [![Mermaid 12.0.0](https://img.shields.io/badge/Mermaid-12.0.0-ff3670)](#compatibility)
12
+ [![Node.js 22.12+](https://img.shields.io/badge/Node.js-%E2%89%A522.12-339933?logo=nodedotjs&logoColor=white)](#development)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue)](LICENSE)
14
+
15
+ [Quick start](#quick-start) · [Examples](#examples) · [API](#api) · [Compatibility](#compatibility) · [Development](#development)
16
+
17
+ </div>
18
+
19
+ <!-- example:hero:start -->
20
+ ```text
21
+ +---------+ +------------+
22
+ | Mermaid |->| Plain text |
23
+ +---------+ +------------+
24
+ ```
25
+ <!-- example:hero:end -->
26
+
27
+ ## Why FlowInk?
28
+
29
+ - **Keep your Mermaid source.** Uses the official flowchart grammar pinned to Mermaid 12.0.0.
30
+ - **Choose your alphabet.** ASCII by default, Unicode when you want box-drawing characters.
31
+ - **Keep the graph intact.** Branches, cycles, parallel edges, self-loops, and nested subgraphs.
32
+ - **Keep the details.** Chinese text, multiline labels, and plain-text Markdown/HTML content; styles and interactions stay in the parsed data.
33
+ - **Use JavaScript.** ESM API, JSDoc-derived TypeScript declarations, and no runtime DOM or external executable requirement.
34
+
35
+ ## Quick start
36
+
37
+ Requires **Node.js 22.12+**. Install from npm:
38
+
39
+ ```sh
40
+ npm install flowink
41
+ ```
42
+
43
+ Create `demo.mjs` in your project:
44
+
45
+ ```js
46
+ import { parse, render } from 'flowink';
47
+
48
+ const source = `flowchart LR
49
+ A[Mermaid] --> B[Plain text]
50
+ `;
51
+
52
+ console.log(await render(source));
53
+ console.log(await render(source, { charset: 'unicode' }));
54
+
55
+ const graph = parse(source);
56
+ console.log(graph.nodes, graph.edges);
57
+ ```
58
+
59
+ ```sh
60
+ node demo.mjs
61
+ ```
62
+
63
+ Browser applications can import `flowink` through their usual bundler.
64
+
65
+ ## Examples
66
+
67
+ Each output below is generated by `render()` from the accompanying source. The inputs are also available in [`examples/`](examples).
68
+
69
+ ### 1. A decision with two outcomes
70
+
71
+ <!-- example:decision:start -->
72
+ **Mermaid source**
73
+
74
+ ```text
75
+ flowchart TB
76
+ A[Start] --> B{Ready?}
77
+ B -->|yes| C[Ship]
78
+ B -->|no| D[Wait]
79
+ ```
80
+
81
+ **Unicode output** · `render(source, { charset: 'unicode' })`
82
+
83
+ ```text
84
+ ┌────────┐
85
+ │ Start │
86
+ └────────┘
87
+ ┌─┘
88
+
89
+ ╱────────╲
90
+ │ │
91
+ ◁ Ready? ▷
92
+ │ │
93
+ ╲────────╱
94
+ ┌┘ │
95
+ │ └─────┐
96
+ │ no │
97
+ yes │ │
98
+ │ │
99
+ │ │
100
+ ▼ ▼
101
+ ┌───────┐┌───────┐
102
+ │ Ship ││ Wait │
103
+ └───────┘└───────┘
104
+ ```
105
+ <!-- example:decision:end -->
106
+
107
+ ### 2. Chinese and multiline labels
108
+
109
+ Drawing characters and label text are independent: ASCII mode also preserves Chinese and other Unicode labels. Use a monospace font with suitable CJK and emoji support.
110
+
111
+ <!-- example:chinese:start -->
112
+ **Mermaid source**
113
+
114
+ ```text
115
+ flowchart LR
116
+ A["開始"] -->|確認| B["完成<br/>下一步"]
117
+ ```
118
+
119
+ **Unicode output** · `render(source, { charset: 'unicode' })`
120
+
121
+ ```text
122
+ 確認
123
+ ┌──────┐ ┌────────┐
124
+ │ 開始 │────────▶│ 完成 │
125
+ │ │ │ 下一步 │
126
+ └──────┘ └────────┘
127
+ ```
128
+ <!-- example:chinese:end -->
129
+
130
+ <details>
131
+ <summary><strong>3. A cycle — follow the return edge</strong></summary>
132
+
133
+ <!-- example:cycle:start -->
134
+ **Mermaid source**
135
+
136
+ ```text
137
+ flowchart TB
138
+ A[Plan] --> B[Build] --> C[Review] --> A
139
+ ```
140
+
141
+ **ASCII output** · `render(source, { charset: 'ascii' })`
142
+
143
+ ```text
144
+ +-------+
145
+ | Plan |
146
+ +-------+
147
+ ++ ^
148
+ | +----+
149
+ v |
150
+ +-------+ |
151
+ | Build | |
152
+ +-------+ |
153
+ ++ |
154
+ | |
155
+ v +----+
156
+ +--------+
157
+ | Review |
158
+ +--------+
159
+ ```
160
+ <!-- example:cycle:end -->
161
+
162
+ </details>
163
+
164
+ <details>
165
+ <summary><strong>4. A subgraph with an outgoing connection</strong></summary>
166
+
167
+ <!-- example:subgraph:start -->
168
+ **Mermaid source**
169
+
170
+ ```text
171
+ flowchart TB
172
+ subgraph Build
173
+ A[Parse] --> B[Layout]
174
+ end
175
+ B --> C[Text]
176
+ ```
177
+
178
+ **ASCII output** · `render(source, { charset: 'ascii' })`
179
+
180
+ ```text
181
+ +------------+
182
+ | Build |
183
+ | +--------+ |
184
+ | | Parse | |
185
+ | +--------+ |
186
+ | +-+ |
187
+ | v |
188
+ | +--------+ |
189
+ | | Layout | |
190
+ | +--------+ |
191
+ | | |
192
+ +-----|------+
193
+ |
194
+ |
195
+ v
196
+ +------+
197
+ | Text |
198
+ +------+
199
+ ```
200
+ <!-- example:subgraph:end -->
201
+
202
+ </details>
203
+
204
+ ## API
205
+
206
+ ### `render(source, options?) → Promise<string>`
207
+
208
+ ```js
209
+ const ascii = await render(source);
210
+ const unicode = await render(source, { charset: 'unicode' });
211
+ ```
212
+
213
+ | Option | Values | Default |
214
+ | --- | --- | --- |
215
+ | `charset` | `'ascii'`, `'unicode'` | `'ascii'` |
216
+
217
+ Output has no trailing spaces or trailing newline. There is no fixed total width, and labels are not truncated. Dense diagrams may expand to preserve wire spacing and readable label placement.
218
+
219
+ ### `parse(source) → FlowGraph`
220
+
221
+ Returns an independent, serializable graph, retaining the exact original input.
222
+
223
+ | Field | Contents |
224
+ | --- | --- |
225
+ | `source` | Original Mermaid source |
226
+ | `direction` | Normalized flow direction |
227
+ | `nodes` | IDs, labels, label types, shapes, parents, styles, classes, metadata |
228
+ | `edges` | IDs, endpoints, labels, arrows, stroke, length, styles, classes, metadata |
229
+ | `subgraphs` | IDs, titles, membership, hierarchy, local directions, metadata |
230
+ | `classes` | Named style definitions |
231
+ | `metadata` | Frontmatter, directives, accessibility information, and other non-drawing data |
232
+
233
+ ### Errors
234
+
235
+ ```js
236
+ import { FlowInkError, render } from 'flowink';
237
+
238
+ try {
239
+ console.log(await render(source));
240
+ } catch (error) {
241
+ if (error instanceof FlowInkError) {
242
+ console.error(error.code, error.message);
243
+ if (error.line !== undefined) {
244
+ console.error(`Line ${error.line}, column ${error.column}`);
245
+ }
246
+ } else {
247
+ throw error;
248
+ }
249
+ }
250
+ ```
251
+
252
+ Located syntax errors use one-based lines and columns in the original source. Layout failures are reported explicitly; a successful render must not silently omit an edge.
253
+
254
+ ## Compatibility
255
+
256
+ **The baseline is Mermaid 12.0.0**, tag `mermaid@12.0.0`, commit [`98a0945`](https://github.com/mermaid-js/mermaid/tree/98a0945418c76238f15df2afaddbba4272656c3b). The official Jison grammar is vendored unchanged and generated into JavaScript during the build. See [grammar provenance](vendor/mermaid/README.md).
257
+
258
+ ```text
259
+ Mermaid source → parser + graph model → ELK layout → character grid → text
260
+ ```
261
+
262
+ | Feature | Text representation |
263
+ | --- | --- |
264
+ | Flowchart/graph syntax, chained links, multi-node links, edge IDs | Parsed using the pinned upstream grammar |
265
+ | Branches, cycles, parallel edges, self-loops | Orthogonal routes with separate endpoints and collision checks |
266
+ | Nested subgraphs and cross-boundary edges | Containers with Mermaid's direction inheritance behavior |
267
+ | Common node shapes | Text approximations |
268
+ | Other shapes, images, icons | Shape annotations or text placeholders |
269
+ | HTML and Markdown labels | Plain text, preserving line breaks and entities |
270
+ | Colors, CSS, animation, links, callbacks | Retained as data; callbacks are not executed and images are not fetched |
271
+ | Invisible edges | Influence layout without visible strokes |
272
+
273
+ FlowInk uses its own text layout rather than Mermaid SVG coordinates. Nonjoining crossings use `#` in ASCII and `╳` in Unicode, distinct from corners and junctions. Alignment follows character display widths; fonts and terminals can differ in their Unicode width conventions.
274
+
275
+ Compatibility covers this version's **flowcharts**, not other Mermaid diagram types or future releases. The first version supplies the package API; a CLI and editor UI are outside its current scope.
276
+
277
+ ## Development
278
+
279
+ ```sh
280
+ git clone https://github.com/william1010121/flowink.git
281
+ cd flowink
282
+ npm ci
283
+ npm run build
284
+ npm test
285
+ npm run test:types
286
+ npm run test:package
287
+ ```
288
+
289
+ ### Verification
290
+
291
+ The suite covers **435 upstream fixtures**, including complete static inputs and bounded arrow, length, keyword, and character matrices. It also checks graph geometry, labels, Unicode widths, error locations, and repeated/concurrent calls.
292
+
293
+ - **Parser comparison:** upstream cases use Mermaid's raw parser and FlowDB; preprocessing cases use Mermaid's public API. [Fixture provenance and exclusions](test/fixtures/upstream/README.md).
294
+ - **Package installation:** `test:package` checks archive contents and installs the tarball in a temporary directory outside the project.
295
+ - **Browser execution:** `npm run test:browser:build` generates `.cache/browser-smoke/index.html`. Serve that directory over HTTP and open the page to compare five diagrams in both charsets against Node.js output. Results are available in `window.__flowinkSmoke`.
296
+
297
+ Fixtures are checked in, so tests do not download upstream source on each run. Mermaid itself is a development-only oracle dependency. Rendering is asynchronous but still uses CPU; applications can run large layouts in their own worker.
298
+
299
+ ## License
300
+
301
+ FlowInk's own code is [MIT](LICENSE). Mermaid-derived files retain their MIT attribution. Runtime dependencies retain their own licenses, including elkjs's `EPL-2.0 OR GPL-3.0-or-later`. See [third-party notices](NOTICE.md).
@@ -0,0 +1,13 @@
1
+ /** An input or layout error. Locations refer to the original Mermaid source. */
2
+ export class FlowInkError extends Error {
3
+ /** @param {string} message @param {{code?:string,line?:number,column?:number,cause?:unknown}} [options] */
4
+ constructor(message: string, options?: {
5
+ code?: string;
6
+ line?: number;
7
+ column?: number;
8
+ cause?: unknown;
9
+ });
10
+ code: string;
11
+ line: number;
12
+ column: number;
13
+ }
@@ -0,0 +1,14 @@
1
+ /** @typedef {import('./types.js').FlowGraph} FlowGraph */
2
+ /** @typedef {import('./types.js').RenderOptions} RenderOptions */
3
+ /**
4
+ * Render a Mermaid 12.0.0 flowchart as a plain text diagram.
5
+ * @param {string} source Mermaid flowchart source.
6
+ * @param {RenderOptions} [options]
7
+ * @returns {Promise<string>}
8
+ */
9
+ export function render(source: string, options?: RenderOptions): Promise<string>;
10
+ export type FlowGraph = import("./types.js").FlowGraph;
11
+ export type RenderOptions = import("./types.js").RenderOptions;
12
+ import { parse } from './parse.js';
13
+ import { FlowInkError } from './errors.js';
14
+ export { parse, FlowInkError };