@drawmotive/textgraph 0.2.1 → 0.2.2-alpha.2
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 +175 -80
- package/docs/api-v1.md +44 -4
- package/docs/images/README.md +28 -0
- package/docs/images/service-flow.png +0 -0
- package/docs/react.md +1 -1
- package/docs/releases.md +34 -16
- package/examples/service-flow.textgraph +6 -0
- package/generated/wasm/DrawMotive.TextGraph.Bridge.wasm +0 -0
- package/generated/wasm/ExCSS.wasm +0 -0
- package/generated/wasm/Graphics.Core.wasm +0 -0
- package/generated/wasm/Grpc.Core.Api.wasm +0 -0
- package/generated/wasm/HarfBuzzSharp.wasm +0 -0
- package/generated/wasm/Math.Core.wasm +0 -0
- package/generated/wasm/Microsoft.Extensions.Logging.Abstractions.wasm +0 -0
- package/generated/wasm/NotoSans-Regular.ttf +0 -0
- package/generated/wasm/Polly.Core.wasm +0 -0
- package/generated/wasm/RBush.wasm +0 -0
- package/generated/wasm/SkiaSharp.wasm +0 -0
- package/generated/wasm/System.Linq.wasm +0 -0
- package/generated/wasm/System.Memory.wasm +0 -0
- package/generated/wasm/System.Private.CoreLib.wasm +0 -0
- package/generated/wasm/System.Runtime.wasm +0 -0
- package/generated/wasm/System.Text.Json.wasm +0 -0
- package/generated/wasm/System.Text.RegularExpressions.wasm +0 -0
- package/generated/wasm/dotnet.boot.js +22 -17
- package/generated/wasm/dotnet.native.js +2 -2
- package/generated/wasm/dotnet.native.wasm +0 -0
- package/generated/wasm/themes.css +25 -12
- package/generated/wasm-manifest.js +44 -37
- package/generated/wasm-manifest.json +44 -37
- package/package.json +15 -3
- package/src/index.d.ts +17 -1
- package/src/index.js +2 -2
- package/src/platform/node.js +17 -1
- package/src/runtime/browser.js +4 -5
- package/src/runtime/dotnet.js +7 -5
- package/src/runtime/font-resources.js +148 -0
- package/src/runtime/language-packs.js +32 -1
- package/src/runtime/render-resources.js +13 -12
- package/src/runtime/rendering.js +3 -2
package/README.md
CHANGED
|
@@ -1,140 +1,235 @@
|
|
|
1
|
-
# TextGraph
|
|
1
|
+
# TextGraph
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Turn text into diagrams in your application.**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Render flowcharts and directed graphs as PNGs in Node.js, browsers, React, and Web
|
|
6
|
+
Workers. TextGraph handles automatic layout and provides source validation and
|
|
7
|
+
rendering diagnostics. The renderer runs where your code runs; no hosted rendering
|
|
8
|
+
API or API key is required.
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
[Documentation](https://textgraph.dev/diagrams/flowcharts) ·
|
|
11
|
+
[Runnable examples](https://github.com/drawmotive/textgraph/tree/main/samples) ·
|
|
12
|
+
[API reference](https://github.com/drawmotive/textgraph/blob/main/docs/api-v1.md)
|
|
13
|
+
|
|
14
|
+
## A few lines. A diagram.
|
|
15
|
+
|
|
16
|
+
```textgraph
|
|
17
|
+
(horizontal)
|
|
18
|
+
browser -> api -> database
|
|
19
|
+
|
|
20
|
+
browser: Browser
|
|
21
|
+
api(fill primary): API Gateway
|
|
22
|
+
database: Database
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
**[Edit this exact diagram in the playground →](https://textgraph.dev/playground#source=%28horizontal%29%0Abrowser%20-%3E%20api%20-%3E%20database%0A%0Abrowser%3A%20Browser%0Aapi%28fill%20primary%29%3A%20API%20Gateway%0Adatabase%3A%20Database%0A)**
|
|
28
|
+
|
|
29
|
+
Actual SDK output from
|
|
30
|
+
[service-flow.textgraph](https://github.com/drawmotive/textgraph/blob/main/examples/service-flow.textgraph).
|
|
31
|
+
Keep source in version control and render again when relationships change.
|
|
32
|
+
TextGraph uses a small, structured language; it does not interpret unrestricted prose.
|
|
33
|
+
|
|
34
|
+
## Choose your workflow
|
|
35
|
+
|
|
36
|
+
| What you want to do | Use | Working example |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| Generate diagrams for documentation, reports, or build jobs | Node.js: write PNG bytes to a file | [Node sample](https://github.com/drawmotive/textgraph/tree/main/samples/node) |
|
|
39
|
+
| Embed live diagrams in dashboards or internal tools | React component and shared provider | [React + Vite sample](https://github.com/drawmotive/textgraph/tree/main/samples/react-vite) |
|
|
40
|
+
| Add editable source and previews to a web app | Browser SDK | [Plain JavaScript sample](https://github.com/drawmotive/textgraph/tree/main/samples/browser) |
|
|
41
|
+
| Keep the UI responsive while rendering larger diagrams | SDK in a module Web Worker | [Worker sample](https://github.com/drawmotive/textgraph/tree/main/samples/worker) |
|
|
42
|
+
| Check syntax and references before rendering | The SDK's `validate()` method | [Validation example](https://github.com/drawmotive/textgraph/blob/main/examples/node.mjs) |
|
|
43
|
+
|
|
44
|
+
For existing documentation, use the
|
|
45
|
+
[Markdown/VitePress plugin](https://textgraph.dev/integrations/markdown) or
|
|
46
|
+
[VS Code Markdown extension](https://textgraph.dev/integrations/vscode).
|
|
47
|
+
|
|
48
|
+
## Install
|
|
9
49
|
|
|
10
50
|
```bash
|
|
11
|
-
npm install @drawmotive/textgraph@0.2.
|
|
51
|
+
npm install @drawmotive/textgraph@0.2.2-alpha.2
|
|
12
52
|
```
|
|
13
53
|
|
|
14
|
-
Requires Node.js 22
|
|
54
|
+
Requires **Node.js 22+** or a modern browser with WebAssembly and Web Crypto.
|
|
55
|
+
Browser applications need HTTPS or localhost. React support is an optional entry
|
|
56
|
+
in this package, compatible with React 18.2+ and 19.
|
|
15
57
|
|
|
16
|
-
|
|
58
|
+
## Render a PNG in Node.js
|
|
17
59
|
|
|
18
|
-
|
|
60
|
+
Save as `render.mjs`, then run `node render.mjs`:
|
|
19
61
|
|
|
20
|
-
```
|
|
62
|
+
```javascript
|
|
21
63
|
import { writeFile } from "node:fs/promises";
|
|
22
|
-
import { initializeTextGraph } from "@drawmotive/textgraph";
|
|
64
|
+
import { initializeTextGraph } from "@drawmotive/textgraph/node";
|
|
23
65
|
|
|
24
66
|
const textgraph = await initializeTextGraph();
|
|
25
|
-
|
|
26
67
|
try {
|
|
27
|
-
const result = await textgraph.renderPng("
|
|
28
|
-
|
|
68
|
+
const result = await textgraph.renderPng("browser -> api -> database");
|
|
29
69
|
if (result.success) {
|
|
30
70
|
await writeFile("diagram.png", result.png);
|
|
71
|
+
console.log("Saved diagram.png");
|
|
31
72
|
} else {
|
|
32
|
-
console.
|
|
73
|
+
console.error(result.diagnostics);
|
|
74
|
+
process.exitCode = 1;
|
|
33
75
|
}
|
|
34
76
|
} finally {
|
|
35
77
|
await textgraph.dispose();
|
|
36
78
|
}
|
|
37
79
|
```
|
|
38
80
|
|
|
39
|
-
|
|
81
|
+
Node reads the included runtime from the installed package. No browser, .NET
|
|
82
|
+
installation, or asset-copy step is needed. Reuse an initialized instance for
|
|
83
|
+
multiple diagrams, then dispose it when the job is finished.
|
|
40
84
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
const result = await textgraph.renderPng("A -> B", {
|
|
45
|
-
scale: 4,
|
|
46
|
-
padding: 24,
|
|
47
|
-
});
|
|
48
|
-
```
|
|
85
|
+
[Complete file-to-PNG sample →](https://github.com/drawmotive/textgraph/tree/main/samples/node)
|
|
49
86
|
|
|
50
|
-
##
|
|
87
|
+
## Add a diagram to React
|
|
51
88
|
|
|
52
|
-
For
|
|
89
|
+
For browser, React, and Worker applications, copy the runtime assets before
|
|
90
|
+
starting development or building:
|
|
53
91
|
|
|
54
92
|
```bash
|
|
55
93
|
npx textgraph-copy-assets public/textgraph/wasm
|
|
56
94
|
```
|
|
57
95
|
|
|
58
|
-
|
|
96
|
+
Then render a component:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { TextGraph, TextGraphProvider } from "@drawmotive/textgraph/react";
|
|
100
|
+
import type { TextGraphInitializeOptions } from "@drawmotive/textgraph";
|
|
101
|
+
|
|
102
|
+
const options: TextGraphInitializeOptions = {
|
|
103
|
+
resolveAsset: (asset) => new URL(`/textgraph/${asset.path}`, location.origin),
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export function Diagram({ source }: { source: string }) {
|
|
107
|
+
return (
|
|
108
|
+
<TextGraphProvider options={options}>
|
|
109
|
+
<TextGraph source={source} alt="Service dependencies" />
|
|
110
|
+
</TextGraphProvider>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Changing `source` updates the image. For several diagrams, put one provider
|
|
116
|
+
around their common parent. Loading states and rendering diagnostics are built in.
|
|
117
|
+
The component renders on the main thread; use the Worker sample for heavier
|
|
118
|
+
interactive workloads.
|
|
119
|
+
|
|
120
|
+
[React + Vite sample →](https://github.com/drawmotive/textgraph/tree/main/samples/react-vite) ·
|
|
121
|
+
[React guide →](https://github.com/drawmotive/textgraph/blob/main/docs/react.md)
|
|
122
|
+
|
|
123
|
+
## Render in a browser
|
|
59
124
|
|
|
60
|
-
|
|
125
|
+
After copying assets as shown above, use this in a bundled browser application:
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
61
128
|
import { initializeTextGraph } from "@drawmotive/textgraph/browser";
|
|
62
129
|
|
|
63
130
|
const textgraph = await initializeTextGraph({
|
|
64
131
|
resolveAsset: (asset) => new URL(`/textgraph/${asset.path}`, location.origin),
|
|
65
132
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
133
|
+
try {
|
|
134
|
+
const result = await textgraph.renderPng("browser -> api -> database", {
|
|
135
|
+
encoding: "base64",
|
|
136
|
+
scale: 2,
|
|
137
|
+
});
|
|
138
|
+
if (result.success) {
|
|
139
|
+
const image = document.createElement("img");
|
|
140
|
+
image.src = `data:image/png;base64,${result.png}`;
|
|
141
|
+
image.alt = "Browser connects to API, which connects to database";
|
|
142
|
+
image.width = result.displayWidth ?? result.width / 2;
|
|
143
|
+
image.height = result.displayHeight ?? result.height / 2;
|
|
144
|
+
image.style.maxWidth = "100%";
|
|
145
|
+
image.style.height = "auto";
|
|
146
|
+
document.body.append(image);
|
|
147
|
+
} else {
|
|
148
|
+
console.error(result.diagnostics);
|
|
149
|
+
}
|
|
150
|
+
} finally {
|
|
151
|
+
await textgraph.dispose();
|
|
81
152
|
}
|
|
82
|
-
|
|
83
|
-
await textgraph.dispose();
|
|
84
153
|
```
|
|
85
154
|
|
|
86
|
-
|
|
155
|
+
For repeated edits, keep the runtime alive and dispose it when the editor closes.
|
|
156
|
+
An async call still computes on its current thread; the Worker sample moves
|
|
157
|
+
rendering off the UI thread.
|
|
87
158
|
|
|
88
|
-
|
|
159
|
+
[Browser example →](https://github.com/drawmotive/textgraph/tree/main/samples/browser) ·
|
|
160
|
+
[Worker example →](https://github.com/drawmotive/textgraph/tree/main/samples/worker)
|
|
89
161
|
|
|
90
|
-
|
|
162
|
+
### Deploy the browser runtime
|
|
91
163
|
|
|
92
|
-
|
|
164
|
+
- Add the asset-copy command to your application's `predev` and `prebuild` scripts.
|
|
165
|
+
- Deploy the complete copied directory: WASM, JavaScript, fonts, themes, and
|
|
166
|
+
licenses. Re-copy after SDK updates; keep SDK and runtime versions matched.
|
|
167
|
+
- The resolver above assumes hosting at `/`. For a subdirectory, use your deployed
|
|
168
|
+
base path; the Vite samples demonstrate `import.meta.env.BASE_URL`.
|
|
93
169
|
|
|
94
|
-
|
|
95
|
-
import { TextGraph, TextGraphProvider } from "@drawmotive/textgraph/react";
|
|
170
|
+
[Asset hosting and CSP →](https://github.com/drawmotive/textgraph/blob/main/docs/api-v1.md#assets-csp-and-offline-operation)
|
|
96
171
|
|
|
97
|
-
|
|
98
|
-
resolveAsset: (asset) => new URL(`/textgraph/${asset.path}`, location.origin),
|
|
99
|
-
};
|
|
172
|
+
## Validation and output options
|
|
100
173
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
174
|
+
On an initialized instance:
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
const validation = await textgraph.validate("browser -> api -> database");
|
|
178
|
+
console.log(validation.valid, validation.diagnostics);
|
|
179
|
+
|
|
180
|
+
const image = await textgraph.renderPng("browser -> api -> database", {
|
|
181
|
+
scale: 2,
|
|
182
|
+
padding: 24,
|
|
183
|
+
maxWidth: 1200,
|
|
184
|
+
});
|
|
108
185
|
```
|
|
109
186
|
|
|
110
|
-
|
|
187
|
+
Validation checks parsing and semantic references; rendering additionally checks
|
|
188
|
+
layout and output. Diagram failures return diagnostics. Operational failures
|
|
189
|
+
reject with `DrawMotiveError`.
|
|
111
190
|
|
|
112
|
-
|
|
191
|
+
PNG output defaults to bytes, scale `1`, padding `10`, and a white background.
|
|
192
|
+
Use higher scale for more pixels and returned display dimensions for web sizing.
|
|
193
|
+
TypeScript declarations are included for every public entry point.
|
|
113
194
|
|
|
114
|
-
|
|
195
|
+
[Full API and options →](https://github.com/drawmotive/textgraph/blob/main/docs/api-v1.md)
|
|
115
196
|
|
|
116
|
-
##
|
|
197
|
+
## Run the examples locally
|
|
117
198
|
|
|
118
|
-
|
|
199
|
+
Samples are complete applications in the public repository and use a local
|
|
200
|
+
package tarball. To try the React sample from a fresh checkout:
|
|
119
201
|
|
|
120
202
|
```bash
|
|
121
|
-
|
|
203
|
+
git clone https://github.com/drawmotive/textgraph.git
|
|
204
|
+
cd textgraph
|
|
205
|
+
node samples/prepare.mjs react-vite
|
|
206
|
+
cd samples/react-vite
|
|
207
|
+
npm run dev
|
|
122
208
|
```
|
|
123
209
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
210
|
+
Vite samples require Node.js **22.12+**. Replace `react-vite` with `browser` or
|
|
211
|
+
`worker` for those samples. The Node sample uses `npm start` instead.
|
|
212
|
+
Preparation packages the checkout and installs sample dependencies; it does not
|
|
213
|
+
publish anything. Samples are not included in the npm package.
|
|
127
214
|
|
|
128
|
-
|
|
129
|
-
const result = await textgraph.renderPng("A: 开始\nB: 完成\nA -> B");
|
|
130
|
-
await textgraph.dispose();
|
|
131
|
-
```
|
|
215
|
+
[Sample setup and deployment →](https://github.com/drawmotive/textgraph/blob/main/samples/README.md)
|
|
132
216
|
|
|
133
|
-
##
|
|
217
|
+
## Current scope
|
|
134
218
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
219
|
+
- **Available:** flowcharts and directed graphs, automatic layout, PNG rendering,
|
|
220
|
+
and source validation.
|
|
221
|
+
- **Not available yet:** mind maps, sequence diagrams, slides, and SVG export.
|
|
222
|
+
- **Fonts:** Noto Sans and Fuzzy Bubbles are included. Custom font descriptors are
|
|
223
|
+
supported; the optional `@drawmotive/textgraph-fonts` package is not published.
|
|
224
|
+
See [font configuration](https://github.com/drawmotive/textgraph/blob/main/docs/api-v1.md#fonts-and-language-packs).
|
|
225
|
+
|
|
226
|
+
## Project links
|
|
227
|
+
|
|
228
|
+
[Language guide](https://textgraph.dev/diagrams/flowcharts) ·
|
|
229
|
+
[Changelog](https://github.com/drawmotive/textgraph/blob/main/CHANGELOG.md) ·
|
|
230
|
+
[Report an issue](https://github.com/drawmotive/textgraph/issues) ·
|
|
231
|
+
[MIT license](https://github.com/drawmotive/textgraph/blob/main/LICENSE)
|
|
232
|
+
|
|
233
|
+
### Try it in a browser
|
|
139
234
|
|
|
140
|
-
|
|
235
|
+
[Open the runnable HTML/JavaScript example](https://textgraph.dev/examples/textgraph/) to edit source, see its PNG and copy the integration code without installing anything. For visual editing, see [the DrawMotive editor](https://textgraph.dev/editor/).
|
package/docs/api-v1.md
CHANGED
|
@@ -40,11 +40,42 @@ After applying `maxWidth`, output is limited to 16,384 pixels per side and 16,77
|
|
|
40
40
|
|
|
41
41
|
## Fonts and language packs
|
|
42
42
|
|
|
43
|
+
Runtimes advertising `textgraph-fonts-v1` prepare actual visible labels before measurement.
|
|
44
|
+
Official Chinese, Japanese and emoji fonts load only when needed, then remain decoded
|
|
45
|
+
until the instance is disposed. Node discovers an installed `@drawmotive/textgraph-fonts`
|
|
46
|
+
package automatically; browser hosts copy its assets and supply their deployed catalog:
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
const runtime = await initializeTextGraph({
|
|
50
|
+
fontAssets: { catalog: new URL("/textgraph/fonts/font-catalog.json", location.origin), fallback: false },
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`fontAssets.catalog` is authoritative: missing or corrupt files fail without silently
|
|
55
|
+
switching versions. With no catalog or language packs, fonts are resolved on demand
|
|
56
|
+
from `https://staging.drawmotive.com/static/font-catalog.json`. Set `fallback: false`
|
|
57
|
+
to prohibit that external access, or supply another catalog URL as `fallback`.
|
|
58
|
+
Installing a local package takes precedence over fallback even in offline mode.
|
|
59
|
+
Use `languagePacks: []` with `fallback: false` to explicitly disable automatic font sources.
|
|
60
|
+
|
|
61
|
+
Catalog fonts carry actual Unicode coverage, language hints, byte sizes and SHA-256.
|
|
62
|
+
They are verified before native installation. Catalog URLs are cached per instance;
|
|
63
|
+
HTTP font URLs include the content hash as a stable `v` parameter. HTTP caching remains
|
|
64
|
+
browser/server-owned; there is no new IndexedDB or Service Worker. Offline operation
|
|
65
|
+
requires the complete runtime and font package on a local filesystem or local server;
|
|
66
|
+
an online page cannot fetch an uncached font after losing network access.
|
|
67
|
+
|
|
68
|
+
`renderPng(source, { language: "ja" })` can disambiguate Han-only labels. Without a hint,
|
|
69
|
+
kana selects Japanese for that label and Han-only labels use Chinese. Grapheme-aware
|
|
70
|
+
emoji selection includes flags, ZWJ sequences, modifiers and keycaps. Font selection
|
|
71
|
+
does not depend on which languages were rendered previously. Unsupported glyphs still
|
|
72
|
+
produce font diagnostics; the font catalog defines coverage, not support for every language.
|
|
73
|
+
|
|
43
74
|
Default rendering includes Noto Sans and Fuzzy Bubbles. Configure additional fonts with `initializeTextGraph({ languagePacks: [...] })`. A `TextGraphLanguagePack` has a non-empty `fonts` array of `{ family, source }` and optional ordered `fallbackFamilies`. Font sources are `URL` objects or non-empty `Uint8Array` values. In Node, use `pathToFileURL()` for filesystem paths; relative asset modules can use `new URL("./font.ttf", import.meta.url)` across platforms.
|
|
44
75
|
|
|
45
|
-
The initializer copies byte arrays, URLs and descriptor arrays before asynchronous work, so later caller mutations cannot change rendering resources. Families must be unique across all packs and bundled defaults. Fallback families must name configured fonts. Descriptor validation performs no font I/O.
|
|
76
|
+
The initializer copies byte arrays, URLs and descriptor arrays before asynchronous work, so later caller mutations cannot change rendering resources. Families must be unique across all packs and bundled defaults. Fallback families must name configured fonts. Descriptor validation performs no font I/O. Legacy descriptors without coverage load on first render; official descriptors carry coverage, languages, bytes and SHA-256 and load on demand. Validate-only use does not read fonts or themes. Font-loading or configuration failures reject with `DrawMotiveError`; a later render can retry.
|
|
46
77
|
|
|
47
|
-
Bundled resource URLs use `resolveAsset`. Language-pack sources use their supplied URL directly and the platform data loader, including custom `fetch` or the network adapter for network URLs. All optional fonts share `@drawmotive/textgraph-fonts`, installed separately. It
|
|
78
|
+
Bundled resource URLs use `resolveAsset`. Language-pack sources use their supplied URL directly and the platform data loader, including custom `fetch` or the network adapter for network URLs. All optional fonts share `@drawmotive/textgraph-fonts`, installed separately. It exports `zhCN`, `ja`, `emoji`, `languagePacks` and `fontCatalogUrl`.
|
|
48
79
|
|
|
49
80
|
## Lifecycle
|
|
50
81
|
|
|
@@ -59,7 +90,7 @@ Existing `loadRuntime`, `readonly` and `mutate` hooks remain for development com
|
|
|
59
90
|
- Node 22 or later: root or `/node`; runtime modules use installed-package `file:` URLs, data uses `node:fs/promises`. HTTP data can use injected fetch, but Node does not import remote HTTP JavaScript. Node `worker_threads` uses `/node`.
|
|
60
91
|
- Browser: `/browser` or browser conditional export. Modern Chromium, Firefox and WebKit with WebAssembly, ESM, fetch, BigInt and Web Crypto are tested. HTTPS or localhost is required for Web Crypto. Exact engine versions are pinned by the Playwright lockfile; historical minimum browser versions are not claimed.
|
|
61
92
|
- Browser module Web Worker: `/worker` inside a host-created Worker; no DOM, window, automatic RPC or Worker pool.
|
|
62
|
-
- React 18.2+ or 19: `/react` provides `TextGraph` and `TextGraphProvider` over the browser runtime. See [React integration](react.md).
|
|
93
|
+
- React 18.2+ or 19: `/react` provides `TextGraph` and `TextGraphProvider` over the browser runtime. See [React integration](react.md).
|
|
63
94
|
|
|
64
95
|
Root condition precedence is worker/browser/node/default. Explicit entries avoid bundler ambiguity. Browser/Worker source graphs exclude Node imports.
|
|
65
96
|
|
|
@@ -71,7 +102,9 @@ Keep this selection scoped to the development command. With it absent, package l
|
|
|
71
102
|
|
|
72
103
|
Defaults resolve relative to the installed module. `resolveAsset(asset, defaultUrl)` may return an absolute URL or URL object for each asset. Deploy the complete `generated/wasm` directory: bundlers must preserve/copy these files and configure the resolver for their deployed location. It covers both JS and data. Instance query parameters isolate mutable .NET ESM state; servers should serve identical module bytes regardless of that query.
|
|
73
104
|
|
|
74
|
-
`fetch` or `adapters.network.fetch` receives data URLs and the applicable initialization or render signal. JS uses dynamic import, which injected fetch cannot intercept. Offline installations must cache the module graph as well as WASM/data at importable URLs, using a Service Worker or local server. No GitHub Releases download is required.
|
|
105
|
+
`fetch` or `adapters.network.fetch` receives data URLs and the applicable initialization or render signal. Independent startup data assets download concurrently; all must pass integrity checks before native startup. JS uses dynamic import, which injected fetch cannot intercept. Offline installations must cache the module graph as well as WASM/data at importable URLs, using a Service Worker or local server. No GitHub Releases download is required.
|
|
106
|
+
|
|
107
|
+
Browser, Worker and Node entry points share this concurrent startup loader. Markdown integrations using the Node entry point inherit it when upgraded to the fixed SDK; their default asset reads are local files. Publishing an SDK version does not update pinned dependencies or previously bundled extensions: consumers must update their dependency and lockfile, then rebuild and redeploy or repackage. The separate `@drawmotive/editor` package uses Blazor's own concurrent loader.
|
|
75
108
|
|
|
76
109
|
Serve WASM as `application/wasm`, JS as `text/javascript`, and provide applicable CORS headers for cross-origin assets. Same-origin CSP: `default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; connect-src 'self'; worker-src 'self'`. No eval, new Function or DOM script injection is used. Cross-origin isolation and SharedArrayBuffer are not required by this single-threaded runtime.
|
|
77
110
|
|
|
@@ -83,6 +116,13 @@ DSL failures resolve with diagnostics. Operational errors reject with `DrawMotiv
|
|
|
83
116
|
|
|
84
117
|
## ABI and versioning
|
|
85
118
|
|
|
119
|
+
The additive `textgraph-fonts-v1` capability adds commands to `Execute`:
|
|
120
|
+
`prepare-fonts` takes `source` and optional `language` and returns visible grapheme
|
|
121
|
+
`fontRuns` with `text`, `language` and `missing`; `install-fonts` atomically appends
|
|
122
|
+
fonts with language metadata; `cancel-prepare` releases interrupted preparation.
|
|
123
|
+
Render commands accept the same language hint. Existing configuration/disposal
|
|
124
|
+
envelopes remain unchanged. The wrapper checks this capability before using a catalog.
|
|
125
|
+
|
|
86
126
|
ABI 1.0.0 retains GetAbiVersion/GetPackageKind/CountParseDiagnostics and adds GetRuntimeInfo(), Validate(source) and Execute(requestJson) on DrawMotive.TextGraph.Bridge.Program. Info returns JSON `{ abiVersion, packageKind, protocolVersion: 1, capabilities }`; Validate returns `{ protocolVersion: 1, valid, diagnostics }`. Wrappers require `textgraph-validate-v1`; PNG rendering additionally requires `textgraph-render-v1` and the manifest `bridge.execute` export. Legacy validation exports remain supported. This is a managed export/JSON protocol, not a raw WASM pointer ABI.
|
|
87
127
|
|
|
88
128
|
`generated/wasm-manifest.json` is authoritative; its ESM projection avoids JSON-module browser assumptions. Shipped schemas describe the manifest, validation response and rendering response. Manifest schema, ABI, protocol and npm versions are separate. Additive exports use capabilities; incompatible wire changes require a new supported version. npm versions and bundled assets are released together. DSL/file-format versions are not frozen by this milestone.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# README preview
|
|
2
|
+
|
|
3
|
+
`service-flow.png` is actual output from the package's bundled renderer, using
|
|
4
|
+
`examples/service-flow.textgraph`. Keep the root README's source block and
|
|
5
|
+
playground link synchronized with that file.
|
|
6
|
+
|
|
7
|
+
Regenerate from the repository root with Node.js 22+:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
node --input-type=module <<'JS'
|
|
11
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { initializeTextGraph } from '@drawmotive/textgraph/node';
|
|
13
|
+
|
|
14
|
+
const textgraph = await initializeTextGraph();
|
|
15
|
+
try {
|
|
16
|
+
const source = await readFile('examples/service-flow.textgraph', 'utf8');
|
|
17
|
+
const result = await textgraph.renderPng(source, { scale: 2, padding: 24 });
|
|
18
|
+
if (!result.success) throw new Error(JSON.stringify(result.diagnostics));
|
|
19
|
+
await writeFile('docs/images/service-flow.png', result.png);
|
|
20
|
+
} finally {
|
|
21
|
+
await textgraph.dispose();
|
|
22
|
+
}
|
|
23
|
+
JS
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The root README uses an absolute GitHub raw URL so the image works on npm as well
|
|
27
|
+
as GitHub. Push the image and source to the public repository before publishing
|
|
28
|
+
the next npm version; npm refreshes its displayed README on publication.
|
|
Binary file
|
package/docs/react.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# React integration
|
|
2
2
|
|
|
3
|
-
The `/react` entry
|
|
3
|
+
The `/react` entry provides a diagram component and shared runtime provider. React is an optional peer dependency (`^18.2.0 || ^19.0.0`); applications without React use the ordinary SDK entries.
|
|
4
4
|
|
|
5
5
|
## Browser assets
|
|
6
6
|
|
package/docs/releases.md
CHANGED
|
@@ -4,17 +4,14 @@ Releases are selected deliberately and published by `.github/workflows/release.y
|
|
|
4
4
|
|
|
5
5
|
## Channels
|
|
6
6
|
|
|
7
|
-
| Version | npm dist-tag |
|
|
7
|
+
| Version | npm dist-tag | Install |
|
|
8
8
|
| --- | --- | --- |
|
|
9
|
-
| `0.
|
|
10
|
-
| `0.2.
|
|
11
|
-
| `0.2.1` (next target) | `latest` after publication | `npm install @drawmotive/textgraph@0.2.1` after publication |
|
|
9
|
+
| `0.2.1` (stable) | `latest` | `npm install @drawmotive/textgraph@0.2.1` |
|
|
10
|
+
| `0.2.2-alpha.2` (preview) | `alpha` | `npm install @drawmotive/textgraph@0.2.2-alpha.2` |
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
Alpha releases update `alpha` and preserve an existing `latest`. npm may assign `latest` on a package’s first publication even when `alpha` is specified.
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
The scripts accept stable SemVer and `X.Y.Z-alpha.N`. Other channels require an explicit release-policy change. The shared optional `@drawmotive/textgraph-fonts` package has its own release lifecycle and is not published by this workflow.
|
|
14
|
+
The scripts accept stable SemVer and `X.Y.Z-alpha.N`. The optional `@drawmotive/textgraph-fonts` package uses the separate fonts workflow described below.
|
|
18
15
|
|
|
19
16
|
## Account setup
|
|
20
17
|
|
|
@@ -36,10 +33,10 @@ Trusted publishing requires npm 11.5.1+ and Node.js 22.14.0+. Publication from a
|
|
|
36
33
|
Native builds belong to the private DrawMotive repository. Commit native source, resource, and bridge changes first, then run there:
|
|
37
34
|
|
|
38
35
|
```bash
|
|
39
|
-
npm run release:textgraph -- 0.2.
|
|
36
|
+
npm run release:textgraph -- 0.2.2-alpha.2
|
|
40
37
|
```
|
|
41
38
|
|
|
42
|
-
This updates the package and lock versions, builds Release assets from the recorded private source commit, generates matching JSON/ESM manifests, updates the root workspace lock, and verifies asset hashes. It does not commit, push, tag, or publish. The `just release-textgraph 0.2.
|
|
39
|
+
This updates the package and lock versions, builds Release assets from the recorded private source commit, generates matching JSON/ESM manifests, updates the root workspace lock, and verifies asset hashes. It does not commit, push, tag, or publish. The `just release-textgraph 0.2.2-alpha.2` alias runs the same command.
|
|
43
40
|
|
|
44
41
|
For a JavaScript-only release reusing already verified native bytes, run in this package:
|
|
45
42
|
|
|
@@ -83,26 +80,47 @@ If npm requires a one-time code, run with `NPM_CONFIG_OTP` set in the local term
|
|
|
83
80
|
After preparation, tests, and review, create the tag on the verified package commit:
|
|
84
81
|
|
|
85
82
|
```bash
|
|
86
|
-
git tag -a textgraph-v0.2.
|
|
87
|
-
git push origin textgraph-v0.2.
|
|
83
|
+
git tag -a textgraph-v0.2.2-alpha.2 -m "Release 0.2.2-alpha.2"
|
|
84
|
+
git push origin textgraph-v0.2.2-alpha.2
|
|
88
85
|
```
|
|
89
86
|
|
|
90
|
-
The release workflow resolves the tag to a commit, runs Node.js and three-browser tests on Ubuntu, packs the tested checkout, and passes the artifact to the `npm` environment for publication. All CI and release jobs use `ubuntu-latest`; the browser suite covers Chromium, Firefox, and WebKit.
|
|
87
|
+
The release workflow resolves the tag to a commit, runs Node.js and three-browser tests on Ubuntu, packs the tested checkout, and passes the artifact to the `npm` environment for publication. All CI and release jobs use `ubuntu-latest`; the browser suite covers Chromium, Firefox, and WebKit. Alpha releases select `alpha`; stable releases select `latest`. Never pass a custom dist-tag to bypass the release policy.
|
|
91
88
|
|
|
92
89
|
## Verify publication and recover
|
|
93
90
|
|
|
94
91
|
```bash
|
|
95
92
|
npm view @drawmotive/textgraph dist-tags --json
|
|
96
|
-
npm view @drawmotive/textgraph@0.2.
|
|
97
|
-
npm install @drawmotive/textgraph@0.2.
|
|
93
|
+
npm view @drawmotive/textgraph@0.2.2-alpha.2 dist.integrity
|
|
94
|
+
npm install @drawmotive/textgraph@0.2.2-alpha.2
|
|
98
95
|
```
|
|
99
96
|
|
|
100
97
|
If a workflow fails before publishing, fix the configuration and rerun the same tag. For a manual dispatch, select the release tag as the workflow ref and supply the same tag as input; dispatching from `main` is rejected so OIDC and provenance identify the correct commit. For example:
|
|
101
98
|
|
|
102
99
|
```bash
|
|
103
|
-
gh workflow run release.yml --ref textgraph-v0.2.
|
|
100
|
+
gh workflow run release.yml --ref textgraph-v0.2.2-alpha.2 -f tag=textgraph-v0.2.2-alpha.2
|
|
104
101
|
```
|
|
105
102
|
|
|
106
103
|
If publication succeeded but a later check failed, the script accepts an identical registry artifact with the correct channel and refuses different bytes at the same version. Keep the original workflow artifact for diagnosing integrity differences.
|
|
107
104
|
|
|
108
105
|
The first alpha owning `latest` is expected and requires no repair. If a later publication unexpectedly changes an existing default, inspect registry state before retrying. Do not unpublish, overwrite versions, or delete tags as a routine recovery step.
|
|
106
|
+
|
|
107
|
+
## Optional fonts package
|
|
108
|
+
|
|
109
|
+
`.github/workflows/release-fonts.yml` publishes `@drawmotive/textgraph-fonts` from tags named `textgraph-fonts-v<VERSION>`. It verifies the coordinated release target, font hashes, Unicode coverage, pinned provenance, original license/notice hashes, offline installation, and publication policy before packing. The package has no native build or SDK dependency.
|
|
110
|
+
|
|
111
|
+
Run these checks from the TextGraph repository after synchronizing the release target and package/lock versions in the parent repository:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm ci --prefix language-packs --workspaces=false
|
|
115
|
+
npm run build --prefix language-packs --workspaces=false
|
|
116
|
+
npm test --prefix language-packs --workspaces=false
|
|
117
|
+
node --test --test-concurrency=1 test/release.test.mjs test/fonts-release.test.mjs
|
|
118
|
+
node scripts/fonts-release.mjs pack
|
|
119
|
+
node scripts/publish-fonts-release.mjs --dry-run
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The exact archive and receipt remain in `language-packs/.release/`; CI retains them as the `textgraph-fonts-npm-release` artifact for 30 days and passes them unchanged to the publish job. Font alpha releases use `alpha`, preserve an existing `latest`, and accept npm assigning `latest` on first publication. A retry verifies the existing version's integrity instead of publishing it again.
|
|
123
|
+
|
|
124
|
+
Allow `textgraph-fonts-v*` tags in the GitHub `npm` environment. For bootstrap, an authorized administrator can set its `NPM_TOKEN` secret to an npm token with permission to create/publish this scoped package. The workflow writes only a token variable reference into a temporary npm configuration; it does not print or retain the credential in the artifact. Once the package exists, configure its trusted publisher with repository `drawmotive/textgraph`, workflow `release-fonts.yml`, and environment `npm`, then remove the bootstrap secret. Without that secret the workflow uses npm trusted publishing with OIDC.
|
|
125
|
+
|
|
126
|
+
After committing and reviewing the release, publish the matching `textgraph-fonts-v<VERSION>` tag. Manual retries must use the same existing tag for both the workflow ref and the `tag` input. Publish the fonts package before refreshing consumer lockfiles; consumers must resolve the actual public registry tarball and integrity.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|