@drawmotive/textgraph 0.2.2-alpha.3 → 0.2.2-alpha.5
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 +21 -3
- package/docs/api-v1.md +14 -2
- package/docs/react.md +7 -0
- package/generated/wasm/DrawMotive.TextGraph.Bridge.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/Polly.Core.wasm +0 -0
- package/generated/wasm/RBush.wasm +0 -0
- package/generated/wasm/SkiaSharp.wasm +0 -0
- package/generated/wasm/System.Collections.Concurrent.wasm +0 -0
- package/generated/wasm/System.Console.wasm +0 -0
- package/generated/wasm/System.IO.Compression.Brotli.wasm +0 -0
- package/generated/wasm/System.IO.Compression.wasm +0 -0
- package/generated/wasm/System.Linq.wasm +0 -0
- package/generated/wasm/System.Net.Http.wasm +0 -0
- package/generated/wasm/System.Private.CoreLib.wasm +0 -0
- package/generated/wasm/System.Runtime.InteropServices.wasm +0 -0
- package/generated/wasm/System.Runtime.Intrinsics.wasm +0 -0
- package/generated/wasm/System.Runtime.wasm +0 -0
- package/generated/wasm/System.Text.Json.wasm +0 -0
- package/generated/wasm/System.Threading.Thread.wasm +0 -0
- package/generated/wasm/dotnet.boot.js +23 -28
- package/generated/wasm/dotnet.native.js +2 -2
- package/generated/wasm/dotnet.native.wasm +0 -0
- package/generated/wasm/themes.css +1 -1
- package/generated/wasm-manifest.js +38 -44
- package/generated/wasm-manifest.json +38 -44
- package/package.json +7 -7
- package/src/index.d.ts +5 -1
- package/src/index.js +8 -2
- package/src/react/index.d.ts +3 -1
- package/src/react/index.js +15 -9
- package/src/runtime/font-cache.js +36 -0
- package/src/runtime/font-resources.js +11 -2
- package/src/runtime/render-resources.js +4 -2
- package/src/runtime/rendering.js +8 -7
- package/generated/wasm/ZstdSharp.wasm +0 -0
package/README.md
CHANGED
|
@@ -51,10 +51,24 @@ For existing documentation, use the
|
|
|
51
51
|
npm install @drawmotive/textgraph@0.2.2-alpha.3
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Supports **Node.js 22** or a modern browser with WebAssembly and Web Crypto.
|
|
55
55
|
Browser applications need HTTPS or localhost. React support is an optional entry
|
|
56
56
|
in this package, compatible with React 18.2+ and 19.
|
|
57
57
|
|
|
58
|
+
## Supported environments
|
|
59
|
+
|
|
60
|
+
| Layer | Supported environment | Verification boundary |
|
|
61
|
+
| --- | --- | --- |
|
|
62
|
+
| Node runtime and package tools | Node.js 22; npm 10 | Vite samples require Node 22.12+ on the 22 line |
|
|
63
|
+
| Desktop build and Node rendering | Linux, Windows, macOS | CI targets all three systems with Node 22 |
|
|
64
|
+
| Browser, React and module Worker rendering | Current Chromium, Firefox and WebKit engines | Playwright tests the SDK and samples on Linux; WebKit is not a Safari device certification |
|
|
65
|
+
| React entry | React 18.2+ in the 18 line, or React 19 | React is an optional peer dependency |
|
|
66
|
+
|
|
67
|
+
The standalone audit on 2026-10-01 ran Linux x64 with Node 22.23.2 and npm
|
|
68
|
+
10.9.8. The support and CI targets above do not claim that Windows, macOS
|
|
69
|
+
or every browser was executed in that audit. Browser hosts must provide
|
|
70
|
+
WebAssembly, JavaScript modules, Web Crypto and a secure origin.
|
|
71
|
+
|
|
58
72
|
## Render a PNG in Node.js
|
|
59
73
|
|
|
60
74
|
Save as `render.mjs`, then run `node render.mjs`:
|
|
@@ -232,8 +246,8 @@ publish anything. Samples are not included in the npm package.
|
|
|
232
246
|
- **Available:** flowcharts and directed graphs, automatic layout, PNG and SVG rendering,
|
|
233
247
|
and source validation.
|
|
234
248
|
- **Not available yet:** mind maps, sequence diagrams, and slides.
|
|
235
|
-
- **Fonts:** Noto Sans and Fuzzy Bubbles are included. Custom font descriptors
|
|
236
|
-
|
|
249
|
+
- **Fonts:** Noto Sans and Fuzzy Bubbles are included. Custom font descriptors and
|
|
250
|
+
the optional published `@drawmotive/textgraph-fonts@0.2.2-alpha.2` package are supported.
|
|
237
251
|
See [font configuration](https://github.com/drawmotive/textgraph/blob/main/docs/api-v1.md#fonts-and-language-packs).
|
|
238
252
|
|
|
239
253
|
## Project links
|
|
@@ -243,6 +257,10 @@ publish anything. Samples are not included in the npm package.
|
|
|
243
257
|
[Report an issue](https://github.com/drawmotive/textgraph/issues) ·
|
|
244
258
|
[MIT license](https://github.com/drawmotive/textgraph/blob/main/LICENSE)
|
|
245
259
|
|
|
260
|
+
For public checkout commands and pull requests, see [Contributing](CONTRIBUTING.md).
|
|
261
|
+
Redistribution notices are indexed in [NOTICE](NOTICE).
|
|
262
|
+
For vulnerability reports, see [Security reporting](SECURITY.md).
|
|
263
|
+
|
|
246
264
|
### Try it in a browser
|
|
247
265
|
|
|
248
266
|
[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
|
@@ -75,11 +75,23 @@ Use `languagePacks: []` with `fallback: false` to explicitly disable automatic f
|
|
|
75
75
|
|
|
76
76
|
Catalog fonts carry actual Unicode coverage, language hints, byte sizes and SHA-256.
|
|
77
77
|
They are verified before native installation. Catalog URLs are cached per instance;
|
|
78
|
-
HTTP font URLs include the content hash as a stable `v` parameter.
|
|
79
|
-
|
|
78
|
+
HTTP font URLs include the content hash as a stable `v` parameter. The SDK automatically
|
|
79
|
+
stores verified bundled and optional font bytes in browser/Worker Cache Storage
|
|
80
|
+
(`textgraph-fonts-v1`) and reuses them across instances and page reloads, independent
|
|
81
|
+
of server cache headers. Cached bytes are verified again before use; damaged entries
|
|
82
|
+
are replaced from the configured source. Storage denial or quota errors fall back
|
|
83
|
+
to normal loading. Local files and descriptors without hashes are not persisted. Offline operation
|
|
80
84
|
requires the complete runtime and font package on a local filesystem or local server;
|
|
81
85
|
an online page cannot fetch an uncached font after losing network access.
|
|
82
86
|
|
|
87
|
+
For interactive previews, pass `onPreview` to `renderPng` or `renderSvg`. When visible
|
|
88
|
+
labels need optional fonts, the callback receives a provisional successful image
|
|
89
|
+
using installed fonts before catalog/font downloads. Display it with a font-loading
|
|
90
|
+
notice; missing glyphs or different text geometry can appear temporarily. The returned
|
|
91
|
+
promise still resolves to the final output after fonts are installed and layout is
|
|
92
|
+
recomputed. Calls without the callback retain final-output semantics. Font-loading
|
|
93
|
+
failures reject so the host can keep the provisional image and offer a retry.
|
|
94
|
+
|
|
83
95
|
`renderPng(source, { language: "ja" })` and `renderSvg(source, { language: "ja" })` can disambiguate Han-only labels. Without a hint,
|
|
84
96
|
kana selects Japanese for that label and Han-only labels use Chinese. Grapheme-aware
|
|
85
97
|
emoji selection includes flags, ZWJ sequences, modifiers and keycaps. Font selection
|
package/docs/react.md
CHANGED
|
@@ -38,10 +38,17 @@ Use your deployed base path instead of `/` for subdirectory hosting. The [React/
|
|
|
38
38
|
| `alt` | Image description; defaults to `TextGraph diagram`. |
|
|
39
39
|
| `renderOptions` | Defaults to `scale: 1`; `padding` and `maxWidth` use SDK defaults. Set `scale: 2` explicitly for higher raster density. |
|
|
40
40
|
| `loading` | React content shown with `role="status"`; defaults to `Rendering diagram…`. |
|
|
41
|
+
| `fontsLoading` | Content shown beside the provisional image while optional fonts load; defaults to `Fonts are still loading…`. |
|
|
41
42
|
| Other image attributes | Passed to the successful `<img>`, including `className`, `style`, `width`, and `height`. |
|
|
42
43
|
|
|
43
44
|
The component owns `src`, encoding, and cancellation. While new input renders, old images are replaced by loading content. A stale result cannot replace newer input. DSL diagnostics and operational failures appear as escaped text with `role="alert"`; corrected input renders again. Changing only `alt` or image styles does not rerun layout.
|
|
44
45
|
|
|
46
|
+
When optional fonts are needed, the component displays a provisional image first,
|
|
47
|
+
shows `fontsLoading`, and replaces the image after loading and measuring the fonts.
|
|
48
|
+
If loading fails, the preview remains beside the error. The SDK automatically caches
|
|
49
|
+
verified font bytes across instances and reloads in browser Cache Storage; no host
|
|
50
|
+
cache setup is required.
|
|
51
|
+
|
|
45
52
|
Images use the render result's logical `displayWidth` and `displayHeight`, so increasing `scale` adds pixels without enlarging the diagram. `maxWidth` limits raster pixels rather than CSS width. Styles default to `maxWidth: '100%'` and `height: 'auto'`; supplied styles merge over these defaults, and explicit image dimensions override the logical dimensions.
|
|
46
53
|
|
|
47
54
|
Older runtimes omit display dimensions. The component then divides raster dimensions by the requested scale; this preserves logical size unless `maxWidth` has lowered the effective density. Deploy matching updated runtime assets for accurate sizing in that case. PNG DPI metadata does not control CSS size.
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const config = /*json-start*/{
|
|
2
2
|
"mainAssemblyName": "DrawMotive.TextGraph.Bridge.dll",
|
|
3
3
|
"resources": {
|
|
4
|
-
"hash": "sha256-
|
|
4
|
+
"hash": "sha256-NkSXf6BaW3IAk8E3aIFzyrGG28CgnWT4/WC1onNX/Z0=",
|
|
5
5
|
"jsModuleNative": [
|
|
6
6
|
{
|
|
7
7
|
"name": "dotnet.native.js"
|
|
@@ -15,7 +15,7 @@ export const config = /*json-start*/{
|
|
|
15
15
|
"wasmNative": [
|
|
16
16
|
{
|
|
17
17
|
"name": "dotnet.native.wasm",
|
|
18
|
-
"hash": "sha256-
|
|
18
|
+
"hash": "sha256-Tqb9aNQTpsiBcpNevNGjnyxzrpZE0n77Sx4Rcn4UFhc="
|
|
19
19
|
}
|
|
20
20
|
],
|
|
21
21
|
"coreAssembly": [
|
|
@@ -27,7 +27,7 @@ export const config = /*json-start*/{
|
|
|
27
27
|
{
|
|
28
28
|
"virtualPath": "System.Private.CoreLib.wasm",
|
|
29
29
|
"name": "System.Private.CoreLib.wasm",
|
|
30
|
-
"hash": "sha256-
|
|
30
|
+
"hash": "sha256-Iaa0Sf9pQ/5qOAIAghx8wjz/9jodVQVYvksdfYoyQo8="
|
|
31
31
|
}
|
|
32
32
|
],
|
|
33
33
|
"assembly": [
|
|
@@ -39,12 +39,12 @@ export const config = /*json-start*/{
|
|
|
39
39
|
{
|
|
40
40
|
"virtualPath": "Grpc.Core.Api.wasm",
|
|
41
41
|
"name": "Grpc.Core.Api.wasm",
|
|
42
|
-
"hash": "sha256-
|
|
42
|
+
"hash": "sha256-X6Xe6EsTbgz2wWCfm/jWGDbHliLWTyZ4/q8tq0mEXuA="
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
"virtualPath": "HarfBuzzSharp.wasm",
|
|
46
46
|
"name": "HarfBuzzSharp.wasm",
|
|
47
|
-
"hash": "sha256-
|
|
47
|
+
"hash": "sha256-ANRkrpepe+vbsz6PkjgjWbgkW2W68G7iYG9gU7qx+zs="
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
"virtualPath": "MagicOnion.Abstractions.wasm",
|
|
@@ -109,7 +109,7 @@ export const config = /*json-start*/{
|
|
|
109
109
|
{
|
|
110
110
|
"virtualPath": "Microsoft.Extensions.Logging.Abstractions.wasm",
|
|
111
111
|
"name": "Microsoft.Extensions.Logging.Abstractions.wasm",
|
|
112
|
-
"hash": "sha256-
|
|
112
|
+
"hash": "sha256-20141PpUKEltX8UAUL75vqQKTz7O4t65bVFpNxnVtq0="
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
"virtualPath": "Microsoft.Extensions.Options.wasm",
|
|
@@ -139,7 +139,7 @@ export const config = /*json-start*/{
|
|
|
139
139
|
{
|
|
140
140
|
"virtualPath": "Polly.Core.wasm",
|
|
141
141
|
"name": "Polly.Core.wasm",
|
|
142
|
-
"hash": "sha256-
|
|
142
|
+
"hash": "sha256-dXCCNoxEuqdFCoVDH1ZfKecXtEldfinkUKjwj18RqKE="
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
"virtualPath": "R3.wasm",
|
|
@@ -154,7 +154,7 @@ export const config = /*json-start*/{
|
|
|
154
154
|
{
|
|
155
155
|
"virtualPath": "SkiaSharp.wasm",
|
|
156
156
|
"name": "SkiaSharp.wasm",
|
|
157
|
-
"hash": "sha256-
|
|
157
|
+
"hash": "sha256-bRa2qn2QJTeC0dSx2LmKFUS1lm/ZeqoaJ31c24l8NtI="
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
160
|
"virtualPath": "SkiaSharp.HarfBuzz.wasm",
|
|
@@ -166,35 +166,30 @@ export const config = /*json-start*/{
|
|
|
166
166
|
"name": "Stateless.wasm",
|
|
167
167
|
"hash": "sha256-EWplLf93o2pQw4CGMvCTYO234EMwTX1tSqc2xJ8JbCw="
|
|
168
168
|
},
|
|
169
|
-
{
|
|
170
|
-
"virtualPath": "ZstdSharp.wasm",
|
|
171
|
-
"name": "ZstdSharp.wasm",
|
|
172
|
-
"hash": "sha256-KR3cAHwB6xsvw0WXeCcP8OnTHPehbTBzJ5VbX5vlOVU="
|
|
173
|
-
},
|
|
174
169
|
{
|
|
175
170
|
"virtualPath": "Graphics.Core.wasm",
|
|
176
171
|
"name": "Graphics.Core.wasm",
|
|
177
|
-
"hash": "sha256-
|
|
172
|
+
"hash": "sha256-RkBXYEmkqaTS5u4oaD9LgCGW9BeM6Yx6y7Faf0anA0A="
|
|
178
173
|
},
|
|
179
174
|
{
|
|
180
175
|
"virtualPath": "Math.Core.wasm",
|
|
181
176
|
"name": "Math.Core.wasm",
|
|
182
|
-
"hash": "sha256-
|
|
177
|
+
"hash": "sha256-pdy4LK0A0uhbm44JzBQPm/7P1SQ1cZNhcvycGoJBxsk="
|
|
183
178
|
},
|
|
184
179
|
{
|
|
185
180
|
"virtualPath": "RBush.wasm",
|
|
186
181
|
"name": "RBush.wasm",
|
|
187
|
-
"hash": "sha256-
|
|
182
|
+
"hash": "sha256-hB+961dw2Pyftv3Lyp+nlvtuEj0yUB5d/Fzby23Rq2k="
|
|
188
183
|
},
|
|
189
184
|
{
|
|
190
185
|
"virtualPath": "DrawMotive.TextGraph.Bridge.wasm",
|
|
191
186
|
"name": "DrawMotive.TextGraph.Bridge.wasm",
|
|
192
|
-
"hash": "sha256-
|
|
187
|
+
"hash": "sha256-FPqTWFElDDiTkAPoR5NrVyDpUDK4hTEj5naELw5Y21c="
|
|
193
188
|
},
|
|
194
189
|
{
|
|
195
190
|
"virtualPath": "System.Collections.Concurrent.wasm",
|
|
196
191
|
"name": "System.Collections.Concurrent.wasm",
|
|
197
|
-
"hash": "sha256-
|
|
192
|
+
"hash": "sha256-Jeoyh28M8wBA9+BQ0e4ANv2Jq6ITNW88s/DsalFTOII="
|
|
198
193
|
},
|
|
199
194
|
{
|
|
200
195
|
"virtualPath": "System.Collections.Immutable.wasm",
|
|
@@ -239,7 +234,7 @@ export const config = /*json-start*/{
|
|
|
239
234
|
{
|
|
240
235
|
"virtualPath": "System.Console.wasm",
|
|
241
236
|
"name": "System.Console.wasm",
|
|
242
|
-
"hash": "sha256-
|
|
237
|
+
"hash": "sha256-wWvOkB7Asdsz3ljcee0YzCbdSqWCXg1y/VElLjmc4IA="
|
|
243
238
|
},
|
|
244
239
|
{
|
|
245
240
|
"virtualPath": "System.Diagnostics.StackTrace.wasm",
|
|
@@ -254,12 +249,12 @@ export const config = /*json-start*/{
|
|
|
254
249
|
{
|
|
255
250
|
"virtualPath": "System.IO.Compression.Brotli.wasm",
|
|
256
251
|
"name": "System.IO.Compression.Brotli.wasm",
|
|
257
|
-
"hash": "sha256-
|
|
252
|
+
"hash": "sha256-DcPCQCYlBqXrd+tiArKhLDeuqXNSS6lnKVwPOoQ9NZg="
|
|
258
253
|
},
|
|
259
254
|
{
|
|
260
255
|
"virtualPath": "System.IO.Compression.wasm",
|
|
261
256
|
"name": "System.IO.Compression.wasm",
|
|
262
|
-
"hash": "sha256-
|
|
257
|
+
"hash": "sha256-smvpD00XQvKdSiwuc7hnhCoRz2Nk9VsSTg7MQ9QDipY="
|
|
263
258
|
},
|
|
264
259
|
{
|
|
265
260
|
"virtualPath": "System.IO.Pipelines.wasm",
|
|
@@ -274,7 +269,7 @@ export const config = /*json-start*/{
|
|
|
274
269
|
{
|
|
275
270
|
"virtualPath": "System.Linq.wasm",
|
|
276
271
|
"name": "System.Linq.wasm",
|
|
277
|
-
"hash": "sha256-
|
|
272
|
+
"hash": "sha256-fuRhzw+pO117bLAf4pgfy9YBNt5KfAQ9s+2VhePWmsU="
|
|
278
273
|
},
|
|
279
274
|
{
|
|
280
275
|
"virtualPath": "System.Memory.wasm",
|
|
@@ -284,7 +279,7 @@ export const config = /*json-start*/{
|
|
|
284
279
|
{
|
|
285
280
|
"virtualPath": "System.Net.Http.wasm",
|
|
286
281
|
"name": "System.Net.Http.wasm",
|
|
287
|
-
"hash": "sha256-
|
|
282
|
+
"hash": "sha256-ARrgegBDSux9EF+zqRrsot7EbG1Q9fVGFdJPdHm/r54="
|
|
288
283
|
},
|
|
289
284
|
{
|
|
290
285
|
"virtualPath": "System.Net.Primitives.wasm",
|
|
@@ -334,12 +329,12 @@ export const config = /*json-start*/{
|
|
|
334
329
|
{
|
|
335
330
|
"virtualPath": "System.Runtime.InteropServices.wasm",
|
|
336
331
|
"name": "System.Runtime.InteropServices.wasm",
|
|
337
|
-
"hash": "sha256-
|
|
332
|
+
"hash": "sha256-Q+92Kf8z4HWVuCYT5hM1wtDe4wQSltcDE8cvVbCH8fU="
|
|
338
333
|
},
|
|
339
334
|
{
|
|
340
335
|
"virtualPath": "System.Runtime.Intrinsics.wasm",
|
|
341
336
|
"name": "System.Runtime.Intrinsics.wasm",
|
|
342
|
-
"hash": "sha256-
|
|
337
|
+
"hash": "sha256-Amor9SnGJljEQGEHCbNnu8SJdtb2TN+4vW5fSBgwcMc="
|
|
343
338
|
},
|
|
344
339
|
{
|
|
345
340
|
"virtualPath": "System.Runtime.Loader.wasm",
|
|
@@ -359,7 +354,7 @@ export const config = /*json-start*/{
|
|
|
359
354
|
{
|
|
360
355
|
"virtualPath": "System.Runtime.wasm",
|
|
361
356
|
"name": "System.Runtime.wasm",
|
|
362
|
-
"hash": "sha256-
|
|
357
|
+
"hash": "sha256-f0aumL0L3t2Dj97l3TzNxbOS4K9q93bDGqeAdICfb/A="
|
|
363
358
|
},
|
|
364
359
|
{
|
|
365
360
|
"virtualPath": "System.Security.Cryptography.wasm",
|
|
@@ -379,7 +374,7 @@ export const config = /*json-start*/{
|
|
|
379
374
|
{
|
|
380
375
|
"virtualPath": "System.Text.Json.wasm",
|
|
381
376
|
"name": "System.Text.Json.wasm",
|
|
382
|
-
"hash": "sha256-
|
|
377
|
+
"hash": "sha256-VDv7svOvBBRLoEC3jt8c/LiVS4CCJyY8vXuy2/npWGg="
|
|
383
378
|
},
|
|
384
379
|
{
|
|
385
380
|
"virtualPath": "System.Text.RegularExpressions.wasm",
|
|
@@ -394,7 +389,7 @@ export const config = /*json-start*/{
|
|
|
394
389
|
{
|
|
395
390
|
"virtualPath": "System.Threading.Thread.wasm",
|
|
396
391
|
"name": "System.Threading.Thread.wasm",
|
|
397
|
-
"hash": "sha256-
|
|
392
|
+
"hash": "sha256-xmNkGMgtSroWqZ6CxqqzoILHxIWocNCS8InItRUqIUE="
|
|
398
393
|
},
|
|
399
394
|
{
|
|
400
395
|
"virtualPath": "System.Threading.ThreadPool.wasm",
|
|
@@ -30,11 +30,11 @@ Module['ready'] = new Promise((resolve, reject) => {
|
|
|
30
30
|
|
|
31
31
|
// --pre-jses are emitted after the Module integration code, so that they can
|
|
32
32
|
// refer to Module (if they choose; they can also define Module)
|
|
33
|
-
// include: /home/
|
|
33
|
+
// include: /home/mason/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.browser-wasm/10.0.12/runtimes/browser-wasm/native/src/es6/dotnet.es6.pre.js
|
|
34
34
|
if (_nativeModuleLoaded) throw new Error("Native module already loaded");
|
|
35
35
|
_nativeModuleLoaded = true;
|
|
36
36
|
createDotnetRuntime = Module = moduleArg(Module);
|
|
37
|
-
// end include: /home/
|
|
37
|
+
// end include: /home/mason/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.browser-wasm/10.0.12/runtimes/browser-wasm/native/src/es6/dotnet.es6.pre.js
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
// Sometimes an existing Module object exists with properties
|
|
Binary file
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
--textgraph-edge-label-self-loop-padding: 8px;
|
|
86
86
|
--textgraph-edge-label-center-nudge-limit: 12px;
|
|
87
87
|
--textgraph-edge-label-font-size: medium;
|
|
88
|
-
--textgraph-edge-label-padding:
|
|
88
|
+
--textgraph-edge-label-padding: 3px 6px;
|
|
89
89
|
--textgraph-edge-label-opacity: 0.88;
|
|
90
90
|
--textgraph-preview-export-padding: 48px;
|
|
91
91
|
--textgraph-preview-group-corner-radius: 4px;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "@drawmotive/textgraph",
|
|
4
|
-
"packageVersion": "0.2.2-alpha.
|
|
4
|
+
"packageVersion": "0.2.2-alpha.5",
|
|
5
5
|
"abiVersion": "1.0.0",
|
|
6
6
|
"protocolVersion": 1,
|
|
7
7
|
"runtimeModule": "wasm/dotnet.js",
|
|
@@ -27,7 +27,7 @@ export default {
|
|
|
27
27
|
},
|
|
28
28
|
"targetFramework": "net10.0",
|
|
29
29
|
"privateSource": {
|
|
30
|
-
"commit": "
|
|
30
|
+
"commit": "f7627ef2646772503fb3d8165ee312d4f411566c",
|
|
31
31
|
"project": "DrawMotive.TextGraph.Bridge"
|
|
32
32
|
},
|
|
33
33
|
"entryAssembly": "wasm/DrawMotive.TextGraph.Bridge.wasm",
|
|
@@ -52,7 +52,7 @@ export default {
|
|
|
52
52
|
"path": "wasm/DrawMotive.TextGraph.Bridge.wasm",
|
|
53
53
|
"mediaType": "application/wasm",
|
|
54
54
|
"bytes": 87317,
|
|
55
|
-
"sha256": "
|
|
55
|
+
"sha256": "14fa935851250c38939003e847936b5720e95032b8853123e676842f0e58db57"
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"path": "wasm/ExCSS.wasm",
|
|
@@ -75,20 +75,20 @@ export default {
|
|
|
75
75
|
{
|
|
76
76
|
"path": "wasm/Graphics.Core.wasm",
|
|
77
77
|
"mediaType": "application/wasm",
|
|
78
|
-
"bytes":
|
|
79
|
-
"sha256": "
|
|
78
|
+
"bytes": 4040985,
|
|
79
|
+
"sha256": "4640576049a4a9a4d2e6ee28683f4b802196f4178ce98c7acbb15a7f46a70340"
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"path": "wasm/Grpc.Core.Api.wasm",
|
|
83
83
|
"mediaType": "application/wasm",
|
|
84
84
|
"bytes": 7957,
|
|
85
|
-
"sha256": "
|
|
85
|
+
"sha256": "5fa5dee84b136e0cf6c1609f9bf8d61836c79622d64f2678feaf2dab49845ee0"
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
"path": "wasm/HarfBuzzSharp.wasm",
|
|
89
89
|
"mediaType": "application/wasm",
|
|
90
90
|
"bytes": 30485,
|
|
91
|
-
"sha256": "
|
|
91
|
+
"sha256": "00d464ae97a97bebdbb33e8f92382359b8245b65baf06ee2606f6053bab1fb3b"
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
"path": "wasm/MagicOnion.Abstractions.wasm",
|
|
@@ -118,7 +118,7 @@ export default {
|
|
|
118
118
|
"path": "wasm/Math.Core.wasm",
|
|
119
119
|
"mediaType": "application/wasm",
|
|
120
120
|
"bytes": 3241241,
|
|
121
|
-
"sha256": "
|
|
121
|
+
"sha256": "a5dcb82cad00d2e85b9b8e09cc140f9bfecfd5243571936172fc9c1a8241c6c9"
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
"path": "wasm/MemoryPack.Core.wasm",
|
|
@@ -166,7 +166,7 @@ export default {
|
|
|
166
166
|
"path": "wasm/Microsoft.Extensions.Logging.Abstractions.wasm",
|
|
167
167
|
"mediaType": "application/wasm",
|
|
168
168
|
"bytes": 19221,
|
|
169
|
-
"sha256": "
|
|
169
|
+
"sha256": "db4d78d4fa5428496d5fc50050bef9bea40a4f3ecee2deb96d51693719d5b6ad"
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
172
|
"path": "wasm/Microsoft.Extensions.Logging.wasm",
|
|
@@ -214,7 +214,7 @@ export default {
|
|
|
214
214
|
"path": "wasm/Polly.Core.wasm",
|
|
215
215
|
"mediaType": "application/wasm",
|
|
216
216
|
"bytes": 62741,
|
|
217
|
-
"sha256": "
|
|
217
|
+
"sha256": "757082368c44baa7450a85431f565f29e717b4495d7e29e450a8f08f5f11a8a1"
|
|
218
218
|
},
|
|
219
219
|
{
|
|
220
220
|
"path": "wasm/Polly.wasm",
|
|
@@ -238,7 +238,7 @@ export default {
|
|
|
238
238
|
"path": "wasm/RBush.wasm",
|
|
239
239
|
"mediaType": "application/wasm",
|
|
240
240
|
"bytes": 24341,
|
|
241
|
-
"sha256": "
|
|
241
|
+
"sha256": "841fbdeb5770d8fc9fb6fdcbca9fa796fb6e123d32501e5dfc5cdbcb6dd1ab69"
|
|
242
242
|
},
|
|
243
243
|
{
|
|
244
244
|
"path": "wasm/SkiaSharp.HarfBuzz.wasm",
|
|
@@ -249,8 +249,8 @@ export default {
|
|
|
249
249
|
{
|
|
250
250
|
"path": "wasm/SkiaSharp.wasm",
|
|
251
251
|
"mediaType": "application/wasm",
|
|
252
|
-
"bytes":
|
|
253
|
-
"sha256": "
|
|
252
|
+
"bytes": 102677,
|
|
253
|
+
"sha256": "6d16b6aa7d90253782d1d4b1d8b98a1544b5966fd97aaa1a277d5cdb897c36d2"
|
|
254
254
|
},
|
|
255
255
|
{
|
|
256
256
|
"path": "wasm/Stateless.wasm",
|
|
@@ -261,8 +261,8 @@ export default {
|
|
|
261
261
|
{
|
|
262
262
|
"path": "wasm/System.Collections.Concurrent.wasm",
|
|
263
263
|
"mediaType": "application/wasm",
|
|
264
|
-
"bytes":
|
|
265
|
-
"sha256": "
|
|
264
|
+
"bytes": 36117,
|
|
265
|
+
"sha256": "25ea32876f0cf30040f7e050d1ee0036fd89aba213356f3cb3f0ec6a51533882"
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
268
|
"path": "wasm/System.Collections.Immutable.wasm",
|
|
@@ -316,7 +316,7 @@ export default {
|
|
|
316
316
|
"path": "wasm/System.Console.wasm",
|
|
317
317
|
"mediaType": "application/wasm",
|
|
318
318
|
"bytes": 15125,
|
|
319
|
-
"sha256": "
|
|
319
|
+
"sha256": "c16bce901ec0b1db33de58dc79ed18cc26dd4aa5825e0d72fd51252e399ce080"
|
|
320
320
|
},
|
|
321
321
|
{
|
|
322
322
|
"path": "wasm/System.Diagnostics.StackTrace.wasm",
|
|
@@ -333,14 +333,14 @@ export default {
|
|
|
333
333
|
{
|
|
334
334
|
"path": "wasm/System.IO.Compression.Brotli.wasm",
|
|
335
335
|
"mediaType": "application/wasm",
|
|
336
|
-
"bytes":
|
|
337
|
-
"sha256": "
|
|
336
|
+
"bytes": 6933,
|
|
337
|
+
"sha256": "0dc3c240262506a5eb77eb6202b2a12c37aea973524ba967295c0f3a843d3598"
|
|
338
338
|
},
|
|
339
339
|
{
|
|
340
340
|
"path": "wasm/System.IO.Compression.wasm",
|
|
341
341
|
"mediaType": "application/wasm",
|
|
342
342
|
"bytes": 13077,
|
|
343
|
-
"sha256": "
|
|
343
|
+
"sha256": "b26be90f4d1742f29d4a2c2e73b867842a11cf6364f55b124e0ecc43d4038a96"
|
|
344
344
|
},
|
|
345
345
|
{
|
|
346
346
|
"path": "wasm/System.IO.Pipelines.wasm",
|
|
@@ -357,8 +357,8 @@ export default {
|
|
|
357
357
|
{
|
|
358
358
|
"path": "wasm/System.Linq.wasm",
|
|
359
359
|
"mediaType": "application/wasm",
|
|
360
|
-
"bytes":
|
|
361
|
-
"sha256": "
|
|
360
|
+
"bytes": 104213,
|
|
361
|
+
"sha256": "7ee461cf0fa93b5d7b6cb01fe2981fcbd60136de4a7c043db3ed9585e3d69ac5"
|
|
362
362
|
},
|
|
363
363
|
{
|
|
364
364
|
"path": "wasm/System.Memory.wasm",
|
|
@@ -370,7 +370,7 @@ export default {
|
|
|
370
370
|
"path": "wasm/System.Net.Http.wasm",
|
|
371
371
|
"mediaType": "application/wasm",
|
|
372
372
|
"bytes": 142101,
|
|
373
|
-
"sha256": "
|
|
373
|
+
"sha256": "011ae07a00434aec7d105fb3a91aeca2dec46c6d50f5f54615d24f7479bfaf9e"
|
|
374
374
|
},
|
|
375
375
|
{
|
|
376
376
|
"path": "wasm/System.Net.Primitives.wasm",
|
|
@@ -393,8 +393,8 @@ export default {
|
|
|
393
393
|
{
|
|
394
394
|
"path": "wasm/System.Private.CoreLib.wasm",
|
|
395
395
|
"mediaType": "application/wasm",
|
|
396
|
-
"bytes":
|
|
397
|
-
"sha256": "
|
|
396
|
+
"bytes": 2173721,
|
|
397
|
+
"sha256": "21a6b449ff6943fe6a380200821c7cc23cfff63a1d550558be4b1d7d8a32428f"
|
|
398
398
|
},
|
|
399
399
|
{
|
|
400
400
|
"path": "wasm/System.Private.Uri.wasm",
|
|
@@ -442,13 +442,13 @@ export default {
|
|
|
442
442
|
"path": "wasm/System.Runtime.InteropServices.wasm",
|
|
443
443
|
"mediaType": "application/wasm",
|
|
444
444
|
"bytes": 8981,
|
|
445
|
-
"sha256": "
|
|
445
|
+
"sha256": "43ef7629ff33e07595b82613e61335c2d0dee3041296d70313c72f55b087f1f5"
|
|
446
446
|
},
|
|
447
447
|
{
|
|
448
448
|
"path": "wasm/System.Runtime.Intrinsics.wasm",
|
|
449
449
|
"mediaType": "application/wasm",
|
|
450
|
-
"bytes":
|
|
451
|
-
"sha256": "
|
|
450
|
+
"bytes": 4885,
|
|
451
|
+
"sha256": "026a2bf529c62658c440610709b367bbc48976d6f64cdfb8bd6e5f48183070c7"
|
|
452
452
|
},
|
|
453
453
|
{
|
|
454
454
|
"path": "wasm/System.Runtime.Loader.wasm",
|
|
@@ -472,7 +472,7 @@ export default {
|
|
|
472
472
|
"path": "wasm/System.Runtime.wasm",
|
|
473
473
|
"mediaType": "application/wasm",
|
|
474
474
|
"bytes": 16661,
|
|
475
|
-
"sha256": "
|
|
475
|
+
"sha256": "7f46ae98bd0bdedd838fdee5dd3ccdc5b392e0af6af776c31aa78074809f6ff0"
|
|
476
476
|
},
|
|
477
477
|
{
|
|
478
478
|
"path": "wasm/System.Security.Cryptography.wasm",
|
|
@@ -496,7 +496,7 @@ export default {
|
|
|
496
496
|
"path": "wasm/System.Text.Json.wasm",
|
|
497
497
|
"mediaType": "application/wasm",
|
|
498
498
|
"bytes": 251669,
|
|
499
|
-
"sha256": "
|
|
499
|
+
"sha256": "543bfbb2f3af04144ba040b78edf1cfcb8954b808227263cbd7bb2dbf9e95868"
|
|
500
500
|
},
|
|
501
501
|
{
|
|
502
502
|
"path": "wasm/System.Text.RegularExpressions.wasm",
|
|
@@ -514,7 +514,7 @@ export default {
|
|
|
514
514
|
"path": "wasm/System.Threading.Thread.wasm",
|
|
515
515
|
"mediaType": "application/wasm",
|
|
516
516
|
"bytes": 4885,
|
|
517
|
-
"sha256": "
|
|
517
|
+
"sha256": "c6636418c82d4aba16a99e82c6aab3a082c7c485a870d092f089c8b5152a2141"
|
|
518
518
|
},
|
|
519
519
|
{
|
|
520
520
|
"path": "wasm/System.Threading.ThreadPool.wasm",
|
|
@@ -546,17 +546,11 @@ export default {
|
|
|
546
546
|
"bytes": 4885,
|
|
547
547
|
"sha256": "bcf126d8aaa05eaaee1b09f3ef5f224a0983a01f089a0ee21f71733b9edbd118"
|
|
548
548
|
},
|
|
549
|
-
{
|
|
550
|
-
"path": "wasm/ZstdSharp.wasm",
|
|
551
|
-
"mediaType": "application/wasm",
|
|
552
|
-
"bytes": 396565,
|
|
553
|
-
"sha256": "291ddc007c01eb1b2fc3459778270ff0e9d31cf7a16d307327955b5f9be53955"
|
|
554
|
-
},
|
|
555
549
|
{
|
|
556
550
|
"path": "wasm/dotnet.boot.js",
|
|
557
551
|
"mediaType": "text/javascript",
|
|
558
|
-
"bytes":
|
|
559
|
-
"sha256": "
|
|
552
|
+
"bytes": 17861,
|
|
553
|
+
"sha256": "693025847f303f2ec3bf731150746f4a6e9c28a53418d8b5ee4100beb55ece60"
|
|
560
554
|
},
|
|
561
555
|
{
|
|
562
556
|
"path": "wasm/dotnet.js",
|
|
@@ -567,14 +561,14 @@ export default {
|
|
|
567
561
|
{
|
|
568
562
|
"path": "wasm/dotnet.native.js",
|
|
569
563
|
"mediaType": "text/javascript",
|
|
570
|
-
"bytes":
|
|
571
|
-
"sha256": "
|
|
564
|
+
"bytes": 248697,
|
|
565
|
+
"sha256": "432e3ef8049930253ad4580757a750b831660de5206e350d2c4b98236ecee763"
|
|
572
566
|
},
|
|
573
567
|
{
|
|
574
568
|
"path": "wasm/dotnet.native.wasm",
|
|
575
569
|
"mediaType": "application/wasm",
|
|
576
|
-
"bytes":
|
|
577
|
-
"sha256": "
|
|
570
|
+
"bytes": 6306756,
|
|
571
|
+
"sha256": "4ea6fd68d413a6c88172935ebcd1a39f2c73ae9644d27efb4b1e11727e141617"
|
|
578
572
|
},
|
|
579
573
|
{
|
|
580
574
|
"path": "wasm/dotnet.runtime.js",
|
|
@@ -597,8 +591,8 @@ export default {
|
|
|
597
591
|
{
|
|
598
592
|
"path": "wasm/themes.css",
|
|
599
593
|
"mediaType": "text/css",
|
|
600
|
-
"bytes":
|
|
601
|
-
"sha256": "
|
|
594
|
+
"bytes": 3795,
|
|
595
|
+
"sha256": "2a4e25471c5fbb29bd9639bc97311e1dea941ecd7f9cf9d720f18626811ff057"
|
|
602
596
|
}
|
|
603
597
|
]
|
|
604
598
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"packageName": "@drawmotive/textgraph",
|
|
4
|
-
"packageVersion": "0.2.2-alpha.
|
|
4
|
+
"packageVersion": "0.2.2-alpha.5",
|
|
5
5
|
"abiVersion": "1.0.0",
|
|
6
6
|
"protocolVersion": 1,
|
|
7
7
|
"runtimeModule": "wasm/dotnet.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"targetFramework": "net10.0",
|
|
29
29
|
"privateSource": {
|
|
30
|
-
"commit": "
|
|
30
|
+
"commit": "f7627ef2646772503fb3d8165ee312d4f411566c",
|
|
31
31
|
"project": "DrawMotive.TextGraph.Bridge"
|
|
32
32
|
},
|
|
33
33
|
"entryAssembly": "wasm/DrawMotive.TextGraph.Bridge.wasm",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"path": "wasm/DrawMotive.TextGraph.Bridge.wasm",
|
|
53
53
|
"mediaType": "application/wasm",
|
|
54
54
|
"bytes": 87317,
|
|
55
|
-
"sha256": "
|
|
55
|
+
"sha256": "14fa935851250c38939003e847936b5720e95032b8853123e676842f0e58db57"
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"path": "wasm/ExCSS.wasm",
|
|
@@ -75,20 +75,20 @@
|
|
|
75
75
|
{
|
|
76
76
|
"path": "wasm/Graphics.Core.wasm",
|
|
77
77
|
"mediaType": "application/wasm",
|
|
78
|
-
"bytes":
|
|
79
|
-
"sha256": "
|
|
78
|
+
"bytes": 4040985,
|
|
79
|
+
"sha256": "4640576049a4a9a4d2e6ee28683f4b802196f4178ce98c7acbb15a7f46a70340"
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"path": "wasm/Grpc.Core.Api.wasm",
|
|
83
83
|
"mediaType": "application/wasm",
|
|
84
84
|
"bytes": 7957,
|
|
85
|
-
"sha256": "
|
|
85
|
+
"sha256": "5fa5dee84b136e0cf6c1609f9bf8d61836c79622d64f2678feaf2dab49845ee0"
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
88
|
"path": "wasm/HarfBuzzSharp.wasm",
|
|
89
89
|
"mediaType": "application/wasm",
|
|
90
90
|
"bytes": 30485,
|
|
91
|
-
"sha256": "
|
|
91
|
+
"sha256": "00d464ae97a97bebdbb33e8f92382359b8245b65baf06ee2606f6053bab1fb3b"
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
"path": "wasm/MagicOnion.Abstractions.wasm",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"path": "wasm/Math.Core.wasm",
|
|
119
119
|
"mediaType": "application/wasm",
|
|
120
120
|
"bytes": 3241241,
|
|
121
|
-
"sha256": "
|
|
121
|
+
"sha256": "a5dcb82cad00d2e85b9b8e09cc140f9bfecfd5243571936172fc9c1a8241c6c9"
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
"path": "wasm/MemoryPack.Core.wasm",
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
"path": "wasm/Microsoft.Extensions.Logging.Abstractions.wasm",
|
|
167
167
|
"mediaType": "application/wasm",
|
|
168
168
|
"bytes": 19221,
|
|
169
|
-
"sha256": "
|
|
169
|
+
"sha256": "db4d78d4fa5428496d5fc50050bef9bea40a4f3ecee2deb96d51693719d5b6ad"
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
172
|
"path": "wasm/Microsoft.Extensions.Logging.wasm",
|
|
@@ -214,7 +214,7 @@
|
|
|
214
214
|
"path": "wasm/Polly.Core.wasm",
|
|
215
215
|
"mediaType": "application/wasm",
|
|
216
216
|
"bytes": 62741,
|
|
217
|
-
"sha256": "
|
|
217
|
+
"sha256": "757082368c44baa7450a85431f565f29e717b4495d7e29e450a8f08f5f11a8a1"
|
|
218
218
|
},
|
|
219
219
|
{
|
|
220
220
|
"path": "wasm/Polly.wasm",
|
|
@@ -238,7 +238,7 @@
|
|
|
238
238
|
"path": "wasm/RBush.wasm",
|
|
239
239
|
"mediaType": "application/wasm",
|
|
240
240
|
"bytes": 24341,
|
|
241
|
-
"sha256": "
|
|
241
|
+
"sha256": "841fbdeb5770d8fc9fb6fdcbca9fa796fb6e123d32501e5dfc5cdbcb6dd1ab69"
|
|
242
242
|
},
|
|
243
243
|
{
|
|
244
244
|
"path": "wasm/SkiaSharp.HarfBuzz.wasm",
|
|
@@ -249,8 +249,8 @@
|
|
|
249
249
|
{
|
|
250
250
|
"path": "wasm/SkiaSharp.wasm",
|
|
251
251
|
"mediaType": "application/wasm",
|
|
252
|
-
"bytes":
|
|
253
|
-
"sha256": "
|
|
252
|
+
"bytes": 102677,
|
|
253
|
+
"sha256": "6d16b6aa7d90253782d1d4b1d8b98a1544b5966fd97aaa1a277d5cdb897c36d2"
|
|
254
254
|
},
|
|
255
255
|
{
|
|
256
256
|
"path": "wasm/Stateless.wasm",
|
|
@@ -261,8 +261,8 @@
|
|
|
261
261
|
{
|
|
262
262
|
"path": "wasm/System.Collections.Concurrent.wasm",
|
|
263
263
|
"mediaType": "application/wasm",
|
|
264
|
-
"bytes":
|
|
265
|
-
"sha256": "
|
|
264
|
+
"bytes": 36117,
|
|
265
|
+
"sha256": "25ea32876f0cf30040f7e050d1ee0036fd89aba213356f3cb3f0ec6a51533882"
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
268
|
"path": "wasm/System.Collections.Immutable.wasm",
|
|
@@ -316,7 +316,7 @@
|
|
|
316
316
|
"path": "wasm/System.Console.wasm",
|
|
317
317
|
"mediaType": "application/wasm",
|
|
318
318
|
"bytes": 15125,
|
|
319
|
-
"sha256": "
|
|
319
|
+
"sha256": "c16bce901ec0b1db33de58dc79ed18cc26dd4aa5825e0d72fd51252e399ce080"
|
|
320
320
|
},
|
|
321
321
|
{
|
|
322
322
|
"path": "wasm/System.Diagnostics.StackTrace.wasm",
|
|
@@ -333,14 +333,14 @@
|
|
|
333
333
|
{
|
|
334
334
|
"path": "wasm/System.IO.Compression.Brotli.wasm",
|
|
335
335
|
"mediaType": "application/wasm",
|
|
336
|
-
"bytes":
|
|
337
|
-
"sha256": "
|
|
336
|
+
"bytes": 6933,
|
|
337
|
+
"sha256": "0dc3c240262506a5eb77eb6202b2a12c37aea973524ba967295c0f3a843d3598"
|
|
338
338
|
},
|
|
339
339
|
{
|
|
340
340
|
"path": "wasm/System.IO.Compression.wasm",
|
|
341
341
|
"mediaType": "application/wasm",
|
|
342
342
|
"bytes": 13077,
|
|
343
|
-
"sha256": "
|
|
343
|
+
"sha256": "b26be90f4d1742f29d4a2c2e73b867842a11cf6364f55b124e0ecc43d4038a96"
|
|
344
344
|
},
|
|
345
345
|
{
|
|
346
346
|
"path": "wasm/System.IO.Pipelines.wasm",
|
|
@@ -357,8 +357,8 @@
|
|
|
357
357
|
{
|
|
358
358
|
"path": "wasm/System.Linq.wasm",
|
|
359
359
|
"mediaType": "application/wasm",
|
|
360
|
-
"bytes":
|
|
361
|
-
"sha256": "
|
|
360
|
+
"bytes": 104213,
|
|
361
|
+
"sha256": "7ee461cf0fa93b5d7b6cb01fe2981fcbd60136de4a7c043db3ed9585e3d69ac5"
|
|
362
362
|
},
|
|
363
363
|
{
|
|
364
364
|
"path": "wasm/System.Memory.wasm",
|
|
@@ -370,7 +370,7 @@
|
|
|
370
370
|
"path": "wasm/System.Net.Http.wasm",
|
|
371
371
|
"mediaType": "application/wasm",
|
|
372
372
|
"bytes": 142101,
|
|
373
|
-
"sha256": "
|
|
373
|
+
"sha256": "011ae07a00434aec7d105fb3a91aeca2dec46c6d50f5f54615d24f7479bfaf9e"
|
|
374
374
|
},
|
|
375
375
|
{
|
|
376
376
|
"path": "wasm/System.Net.Primitives.wasm",
|
|
@@ -393,8 +393,8 @@
|
|
|
393
393
|
{
|
|
394
394
|
"path": "wasm/System.Private.CoreLib.wasm",
|
|
395
395
|
"mediaType": "application/wasm",
|
|
396
|
-
"bytes":
|
|
397
|
-
"sha256": "
|
|
396
|
+
"bytes": 2173721,
|
|
397
|
+
"sha256": "21a6b449ff6943fe6a380200821c7cc23cfff63a1d550558be4b1d7d8a32428f"
|
|
398
398
|
},
|
|
399
399
|
{
|
|
400
400
|
"path": "wasm/System.Private.Uri.wasm",
|
|
@@ -442,13 +442,13 @@
|
|
|
442
442
|
"path": "wasm/System.Runtime.InteropServices.wasm",
|
|
443
443
|
"mediaType": "application/wasm",
|
|
444
444
|
"bytes": 8981,
|
|
445
|
-
"sha256": "
|
|
445
|
+
"sha256": "43ef7629ff33e07595b82613e61335c2d0dee3041296d70313c72f55b087f1f5"
|
|
446
446
|
},
|
|
447
447
|
{
|
|
448
448
|
"path": "wasm/System.Runtime.Intrinsics.wasm",
|
|
449
449
|
"mediaType": "application/wasm",
|
|
450
|
-
"bytes":
|
|
451
|
-
"sha256": "
|
|
450
|
+
"bytes": 4885,
|
|
451
|
+
"sha256": "026a2bf529c62658c440610709b367bbc48976d6f64cdfb8bd6e5f48183070c7"
|
|
452
452
|
},
|
|
453
453
|
{
|
|
454
454
|
"path": "wasm/System.Runtime.Loader.wasm",
|
|
@@ -472,7 +472,7 @@
|
|
|
472
472
|
"path": "wasm/System.Runtime.wasm",
|
|
473
473
|
"mediaType": "application/wasm",
|
|
474
474
|
"bytes": 16661,
|
|
475
|
-
"sha256": "
|
|
475
|
+
"sha256": "7f46ae98bd0bdedd838fdee5dd3ccdc5b392e0af6af776c31aa78074809f6ff0"
|
|
476
476
|
},
|
|
477
477
|
{
|
|
478
478
|
"path": "wasm/System.Security.Cryptography.wasm",
|
|
@@ -496,7 +496,7 @@
|
|
|
496
496
|
"path": "wasm/System.Text.Json.wasm",
|
|
497
497
|
"mediaType": "application/wasm",
|
|
498
498
|
"bytes": 251669,
|
|
499
|
-
"sha256": "
|
|
499
|
+
"sha256": "543bfbb2f3af04144ba040b78edf1cfcb8954b808227263cbd7bb2dbf9e95868"
|
|
500
500
|
},
|
|
501
501
|
{
|
|
502
502
|
"path": "wasm/System.Text.RegularExpressions.wasm",
|
|
@@ -514,7 +514,7 @@
|
|
|
514
514
|
"path": "wasm/System.Threading.Thread.wasm",
|
|
515
515
|
"mediaType": "application/wasm",
|
|
516
516
|
"bytes": 4885,
|
|
517
|
-
"sha256": "
|
|
517
|
+
"sha256": "c6636418c82d4aba16a99e82c6aab3a082c7c485a870d092f089c8b5152a2141"
|
|
518
518
|
},
|
|
519
519
|
{
|
|
520
520
|
"path": "wasm/System.Threading.ThreadPool.wasm",
|
|
@@ -546,17 +546,11 @@
|
|
|
546
546
|
"bytes": 4885,
|
|
547
547
|
"sha256": "bcf126d8aaa05eaaee1b09f3ef5f224a0983a01f089a0ee21f71733b9edbd118"
|
|
548
548
|
},
|
|
549
|
-
{
|
|
550
|
-
"path": "wasm/ZstdSharp.wasm",
|
|
551
|
-
"mediaType": "application/wasm",
|
|
552
|
-
"bytes": 396565,
|
|
553
|
-
"sha256": "291ddc007c01eb1b2fc3459778270ff0e9d31cf7a16d307327955b5f9be53955"
|
|
554
|
-
},
|
|
555
549
|
{
|
|
556
550
|
"path": "wasm/dotnet.boot.js",
|
|
557
551
|
"mediaType": "text/javascript",
|
|
558
|
-
"bytes":
|
|
559
|
-
"sha256": "
|
|
552
|
+
"bytes": 17861,
|
|
553
|
+
"sha256": "693025847f303f2ec3bf731150746f4a6e9c28a53418d8b5ee4100beb55ece60"
|
|
560
554
|
},
|
|
561
555
|
{
|
|
562
556
|
"path": "wasm/dotnet.js",
|
|
@@ -567,14 +561,14 @@
|
|
|
567
561
|
{
|
|
568
562
|
"path": "wasm/dotnet.native.js",
|
|
569
563
|
"mediaType": "text/javascript",
|
|
570
|
-
"bytes":
|
|
571
|
-
"sha256": "
|
|
564
|
+
"bytes": 248697,
|
|
565
|
+
"sha256": "432e3ef8049930253ad4580757a750b831660de5206e350d2c4b98236ecee763"
|
|
572
566
|
},
|
|
573
567
|
{
|
|
574
568
|
"path": "wasm/dotnet.native.wasm",
|
|
575
569
|
"mediaType": "application/wasm",
|
|
576
|
-
"bytes":
|
|
577
|
-
"sha256": "
|
|
570
|
+
"bytes": 6306756,
|
|
571
|
+
"sha256": "4ea6fd68d413a6c88172935ebcd1a39f2c73ae9644d27efb4b1e11727e141617"
|
|
578
572
|
},
|
|
579
573
|
{
|
|
580
574
|
"path": "wasm/dotnet.runtime.js",
|
|
@@ -597,8 +591,8 @@
|
|
|
597
591
|
{
|
|
598
592
|
"path": "wasm/themes.css",
|
|
599
593
|
"mediaType": "text/css",
|
|
600
|
-
"bytes":
|
|
601
|
-
"sha256": "
|
|
594
|
+
"bytes": 3795,
|
|
595
|
+
"sha256": "2a4e25471c5fbb29bd9639bc97311e1dea941ecd7f9cf9d720f18626811ff057"
|
|
602
596
|
}
|
|
603
597
|
]
|
|
604
598
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drawmotive/textgraph",
|
|
3
|
-
"version": "0.2.2-alpha.
|
|
3
|
+
"version": "0.2.2-alpha.5",
|
|
4
4
|
"description": "Render TextGraph flowcharts and directed graphs as PNG images in Node.js, browsers, React, and Web Workers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"textgraph",
|
|
@@ -81,15 +81,15 @@
|
|
|
81
81
|
"node": ">=22"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
|
-
"@playwright/test": "1.
|
|
84
|
+
"@playwright/test": "1.63.0",
|
|
85
85
|
"ajv": "8.20.0",
|
|
86
86
|
"pngjs": "7.0.0",
|
|
87
87
|
"typescript": "^7.0.2",
|
|
88
|
-
"react": "^19.
|
|
89
|
-
"react-dom": "^19.
|
|
90
|
-
"@types/react": "^19.
|
|
91
|
-
"@types/react-dom": "^19.
|
|
92
|
-
"jsdom": "^
|
|
88
|
+
"react": "^19.3.0",
|
|
89
|
+
"react-dom": "^19.3.0",
|
|
90
|
+
"@types/react": "^19.3.0",
|
|
91
|
+
"@types/react-dom": "^19.3.0",
|
|
92
|
+
"jsdom": "^30.1.2"
|
|
93
93
|
},
|
|
94
94
|
"publishConfig": {
|
|
95
95
|
"access": "public",
|
package/src/index.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ export interface TextGraphRuntime {
|
|
|
65
65
|
readonly abiVersion: string;
|
|
66
66
|
readonly capabilities?: readonly string[];
|
|
67
67
|
validate?(source: string): string | Promise<string>;
|
|
68
|
-
execute?(requestJson: string, context?: { signal?: AbortSignal }): string | Promise<string>;
|
|
68
|
+
execute?(requestJson: string, context?: { signal?: AbortSignal; onPreview?(responseJson: string): void }): string | Promise<string>;
|
|
69
69
|
dispose?(): void | Promise<void>;
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -127,6 +127,8 @@ export interface TextGraphLanguagePack {
|
|
|
127
127
|
export type TextGraphPngEncoding = 'bytes' | 'base64';
|
|
128
128
|
|
|
129
129
|
export interface TextGraphRenderPngOptions<Encoding extends TextGraphPngEncoding = TextGraphPngEncoding> {
|
|
130
|
+
/** Receives a provisional image before optional fonts load; the promise returns the final image. */
|
|
131
|
+
onPreview?(result: Extract<TextGraphRenderPngResult<Encoding extends 'base64' ? string : Uint8Array>, { success: true }>): void;
|
|
130
132
|
/** Optional language hint for ambiguous Han text, e.g. ja or zh-CN. */
|
|
131
133
|
language?: string;
|
|
132
134
|
/** Defaults to bytes. Base64 contains no data-URL prefix. */
|
|
@@ -149,6 +151,8 @@ export type TextGraphRenderPngResult<Png extends Uint8Array | string = Uint8Arra
|
|
|
149
151
|
|
|
150
152
|
/** Vector export uses logical diagram units and requires textgraph-render-svg-v1. */
|
|
151
153
|
export interface TextGraphRenderSvgOptions {
|
|
154
|
+
/** Receives a provisional vector before optional fonts load; the promise returns the final vector. */
|
|
155
|
+
onPreview?(result: Extract<TextGraphRenderSvgResult, { success: true }>): void;
|
|
152
156
|
/** Optional language hint for ambiguous Han text, e.g. ja or zh-CN. */
|
|
153
157
|
language?: string;
|
|
154
158
|
/** Non-negative padding in diagram units. Defaults to 10. */
|
package/src/index.js
CHANGED
|
@@ -38,13 +38,19 @@ export async function initializeTextGraph(options = {}) {
|
|
|
38
38
|
// Every export format uses the same operation queue and resource-preparing executor.
|
|
39
39
|
const render = async (source, callOptions, normalize, decode, capability, format) => {
|
|
40
40
|
if (instance.state !== 'ready') throw new DrawMotiveError('INSTANCE_DISPOSED', 'The runtime instance is disposing or disposed');
|
|
41
|
-
const { request, encoding, signal } = normalize(source, callOptions);
|
|
41
|
+
const { request, encoding, signal, onPreview } = normalize(source, callOptions);
|
|
42
42
|
throwIfAborted(signal);
|
|
43
43
|
if (typeof runtime.execute !== 'function' || !capabilities.includes(capability)) throw new DrawMotiveError('UNSUPPORTED_CAPABILITY', `Runtime does not support ${format} rendering`);
|
|
44
44
|
return instance.mutate(async () => {
|
|
45
45
|
throwIfAborted(signal);
|
|
46
46
|
let response;
|
|
47
|
-
|
|
47
|
+
const context = { signal };
|
|
48
|
+
if (onPreview) context.onPreview = json => {
|
|
49
|
+
throwIfAborted(signal);
|
|
50
|
+
const preview = decode(json, encoding);
|
|
51
|
+
if (preview.success) onPreview(preview);
|
|
52
|
+
};
|
|
53
|
+
try { response = await runtime.execute(JSON.stringify(request), context); }
|
|
48
54
|
catch (cause) {
|
|
49
55
|
throwIfAborted(signal);
|
|
50
56
|
if (cause instanceof DrawMotiveError || cause?.name === 'AbortError') throw cause;
|
package/src/react/index.d.ts
CHANGED
|
@@ -12,8 +12,10 @@ export interface TextGraphProps extends Omit<ImgHTMLAttributes<HTMLImageElement>
|
|
|
12
12
|
source: string;
|
|
13
13
|
alt?: string;
|
|
14
14
|
/** Defaults to scale 1; the image displays at logical size. */
|
|
15
|
-
renderOptions?: Omit<TextGraphRenderPngOptions, 'encoding' | 'signal'>;
|
|
15
|
+
renderOptions?: Omit<TextGraphRenderPngOptions, 'encoding' | 'signal' | 'onPreview'>;
|
|
16
16
|
loading?: ReactNode;
|
|
17
|
+
/** Shown beside the provisional image until optional fonts finish loading. */
|
|
18
|
+
fontsLoading?: ReactNode;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
export declare function TextGraphProvider(props: TextGraphProviderProps): ReactElement;
|
package/src/react/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { createContext, createElement, useContext, useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { Fragment, createContext, createElement, useContext, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import { createRuntimeResource } from './runtime.js';
|
|
5
5
|
|
|
6
6
|
const RuntimeContext = createContext(null);
|
|
@@ -15,12 +15,12 @@ export function TextGraphProvider({ options = defaultOptions, children }) {
|
|
|
15
15
|
|
|
16
16
|
/** Renders DSL as an image; only the latest committed input may publish a result. */
|
|
17
17
|
export function TextGraph({ source, alt = 'TextGraph diagram', renderOptions = defaultOptions,
|
|
18
|
-
loading = 'Rendering diagram…', style, ...imageProps }) {
|
|
18
|
+
loading = 'Rendering diagram…', fontsLoading = 'Fonts are still loading…', style, ...imageProps }) {
|
|
19
19
|
const shared = useContext(RuntimeContext);
|
|
20
20
|
const resource = useMemo(() => shared ?? createRuntimeResource(defaultOptions), [shared]);
|
|
21
|
-
const { scale = 1, padding, maxWidth } = renderOptions;
|
|
22
|
-
const request = useMemo(() => ({ source, scale, padding, maxWidth, resource }),
|
|
23
|
-
[source, scale, padding, maxWidth, resource]);
|
|
21
|
+
const { scale = 1, padding, maxWidth, language } = renderOptions;
|
|
22
|
+
const request = useMemo(() => ({ source, scale, padding, maxWidth, language, resource }),
|
|
23
|
+
[source, scale, padding, maxWidth, language, resource]);
|
|
24
24
|
const [state, setState] = useState(null);
|
|
25
25
|
|
|
26
26
|
useEffect(() => {
|
|
@@ -30,13 +30,16 @@ export function TextGraph({ source, alt = 'TextGraph diagram', renderOptions = d
|
|
|
30
30
|
try {
|
|
31
31
|
const runtime = await resource.get();
|
|
32
32
|
if (controller.signal.aborted) return;
|
|
33
|
-
const result = await runtime.renderPng(source, { scale, padding, maxWidth, encoding: 'base64', signal: controller.signal
|
|
33
|
+
const result = await runtime.renderPng(source, { scale, padding, maxWidth, language, encoding: 'base64', signal: controller.signal,
|
|
34
|
+
onPreview: result => { if (!controller.signal.aborted) setState({ request, result, fontsLoading: true }); },
|
|
35
|
+
});
|
|
34
36
|
if (!controller.signal.aborted) setState({ request, result });
|
|
35
37
|
} catch (error) {
|
|
36
38
|
if (!controller.signal.aborted) {
|
|
37
39
|
// Host loaders may reject arbitrary values, including null. Keep the
|
|
38
40
|
// failure branch explicit so reporting an error cannot break React render.
|
|
39
|
-
setState({ request,
|
|
41
|
+
setState(previous => ({ request, result: previous?.request === request ? previous.result : undefined,
|
|
42
|
+
error: error instanceof Error ? error : new Error(String(error ?? 'Could not render diagram')) }));
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
})();
|
|
@@ -46,14 +49,17 @@ export function TextGraph({ source, alt = 'TextGraph diagram', renderOptions = d
|
|
|
46
49
|
// State is keyed by the whole request so old images disappear immediately,
|
|
47
50
|
// even before passive effects clean up the previous asynchronous render.
|
|
48
51
|
if (state?.request !== request) return createElement('span', { role: 'status' }, loading);
|
|
49
|
-
if (
|
|
52
|
+
if (!state.result?.success) {
|
|
50
53
|
const message = state.error?.message ?? state.result.diagnostics.map(item => item.message).join('\n');
|
|
51
54
|
return createElement('span', { role: 'alert' }, message || 'Could not render diagram');
|
|
52
55
|
}
|
|
53
56
|
const result = state.result;
|
|
54
57
|
// Density improves sharpness without enlarging the diagram. Native dimensions
|
|
55
58
|
// also preserve logical size when maxWidth lowers the actual render density.
|
|
56
|
-
|
|
59
|
+
const image = createElement('img', { width: result.displayWidth ?? result.width / scale, height: result.displayHeight ?? result.height / scale, ...imageProps,
|
|
57
60
|
style: { maxWidth: '100%', ...(imageProps.height == null ? { height: 'auto' } : {}), ...style },
|
|
58
61
|
src: `data:image/png;base64,${result.png}`, alt });
|
|
62
|
+
if (state.error) return createElement(Fragment, null, image, createElement('span', { role: 'alert' }, state.error.message));
|
|
63
|
+
if (state.fontsLoading) return createElement(Fragment, null, image, createElement('span', { role: 'status' }, fontsLoading));
|
|
64
|
+
return image;
|
|
59
65
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { readVerifiedAsset } from './integrity.js';
|
|
2
|
+
import { throwIfAborted } from './lifecycle.js';
|
|
3
|
+
|
|
4
|
+
const cacheName = 'textgraph-fonts-v1';
|
|
5
|
+
|
|
6
|
+
/** HTTP fonts are immutable by content hash. Cache verified bytes in browsers
|
|
7
|
+
* and Workers without requiring host headers or a service worker; local files
|
|
8
|
+
* stay authoritative. Storage is optional and cannot turn valid I/O into failure. */
|
|
9
|
+
export async function readVerifiedFontAsset(item, options, readAsset) {
|
|
10
|
+
if (!['http:', 'https:'].includes(item.url?.protocol)) return readVerifiedAsset(item, options, readAsset);
|
|
11
|
+
const url = new URL(item.url);
|
|
12
|
+
url.searchParams.set('v', item.asset.sha256);
|
|
13
|
+
const versioned = { ...item, url };
|
|
14
|
+
let cache;
|
|
15
|
+
try { cache = await globalThis.caches?.open(cacheName); } catch { /* Private contexts may deny storage. */ }
|
|
16
|
+
throwIfAborted(options.signal);
|
|
17
|
+
let cached;
|
|
18
|
+
try { cached = await cache?.match(url.href); } catch { /* Read from the configured source instead. */ }
|
|
19
|
+
throwIfAborted(options.signal);
|
|
20
|
+
if (cached) {
|
|
21
|
+
try {
|
|
22
|
+
const bytes = await readVerifiedAsset(versioned, options, async () => cached);
|
|
23
|
+
throwIfAborted(options.signal);
|
|
24
|
+
return bytes;
|
|
25
|
+
} catch {
|
|
26
|
+
throwIfAborted(options.signal);
|
|
27
|
+
// A damaged entry grants no authority: evict and verify the original source.
|
|
28
|
+
try { await cache.delete(url.href); } catch { /* A new download can still succeed. */ }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const bytes = await readVerifiedAsset(versioned, options, readAsset);
|
|
32
|
+
throwIfAborted(options.signal);
|
|
33
|
+
try { await cache?.put(url.href, new Response(bytes, { headers: { 'Content-Type': 'font/ttf' } })); } catch { /* Quota and storage failures are non-fatal. */ }
|
|
34
|
+
throwIfAborted(options.signal);
|
|
35
|
+
return bytes;
|
|
36
|
+
}
|
|
@@ -2,7 +2,7 @@ import { DrawMotiveError } from './errors.js';
|
|
|
2
2
|
import { normalizeFontMetadata } from './language-packs.js';
|
|
3
3
|
import { decodeDiagnostics } from './validation.js';
|
|
4
4
|
import { decodeConfiguration } from './rendering.js';
|
|
5
|
-
import {
|
|
5
|
+
import { readVerifiedFontAsset } from './font-cache.js';
|
|
6
6
|
import { throwIfAborted } from './lifecycle.js';
|
|
7
7
|
|
|
8
8
|
export const fontCapability = 'textgraph-fonts-v1';
|
|
@@ -102,6 +102,7 @@ export function createFontPreparation({ options, readAsset, execute }) {
|
|
|
102
102
|
const loading = { ...options, signal: context.signal };
|
|
103
103
|
const attempted = new Set();
|
|
104
104
|
let consumed = false;
|
|
105
|
+
let previewed = false;
|
|
105
106
|
try {
|
|
106
107
|
while (true) {
|
|
107
108
|
throwIfAborted(context.signal);
|
|
@@ -110,6 +111,14 @@ export function createFontPreparation({ options, readAsset, execute }) {
|
|
|
110
111
|
if (!prepared.success) return JSON.stringify({ protocolVersion: 1, success: false, diagnostics: prepared.diagnostics });
|
|
111
112
|
const missing = prepared.fontRuns.filter(run => run.missing && run.language);
|
|
112
113
|
if (!missing.length) break;
|
|
114
|
+
// Native can render with its installed fallback fonts. Publish that image
|
|
115
|
+
// before optional I/O; final measurement still runs after installation.
|
|
116
|
+
if (context.onPreview && !previewed) {
|
|
117
|
+
const preview = await execute(request);
|
|
118
|
+
throwIfAborted(context.signal);
|
|
119
|
+
context.onPreview(preview);
|
|
120
|
+
previewed = true;
|
|
121
|
+
}
|
|
113
122
|
const selected = new Set();
|
|
114
123
|
let available = explicit;
|
|
115
124
|
for (const run of missing) {
|
|
@@ -126,7 +135,7 @@ export function createFontPreparation({ options, readAsset, execute }) {
|
|
|
126
135
|
for (const font of selected) {
|
|
127
136
|
attempted.add(font.family);
|
|
128
137
|
throwIfAborted(context.signal);
|
|
129
|
-
const bytes = await
|
|
138
|
+
const bytes = await readVerifiedFontAsset({ asset: { path: `font:${font.family}`, bytes: font.bytes, sha256: font.sha256, mediaType: 'font/ttf' }, url: font.source }, loading,
|
|
130
139
|
font.source instanceof Uint8Array ? async () => new Response(font.source) : readAsset);
|
|
131
140
|
throwIfAborted(context.signal);
|
|
132
141
|
fonts.push({ family: font.family, data: fontBase64(bytes), languages: font.languages });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRuntimeAssetPlan } from './shared.js';
|
|
2
2
|
import { readVerifiedAsset } from './integrity.js';
|
|
3
|
+
import { readVerifiedFontAsset } from './font-cache.js';
|
|
3
4
|
import { decodeConfiguration } from './rendering.js';
|
|
4
5
|
import { throwIfAborted } from './lifecycle.js';
|
|
5
6
|
import { createFontPreparation, fontBase64 as base64, fontCapability } from './font-resources.js';
|
|
@@ -18,9 +19,10 @@ export function createRenderingExecutor({ manifest, options, readAsset, execute
|
|
|
18
19
|
const selected = new Set([manifest.rendering.theme, ...manifest.rendering.fonts.map(font => font.asset)]);
|
|
19
20
|
const plan = createRuntimeAssetPlan({ manifest: { assets: manifest.assets.filter(asset => selected.has(asset.path)) }, moduleUrl: import.meta.url, resolveAsset: options.resolveAsset });
|
|
20
21
|
const byPath = new Map(plan.map(item => [item.asset.path, item]));
|
|
22
|
+
const fontPaths = new Set(manifest.rendering.fonts.map(font => font.asset));
|
|
21
23
|
const load = async path => {
|
|
22
24
|
throwIfAborted(context.signal);
|
|
23
|
-
const bytes = await readVerifiedAsset(byPath.get(path), loadingOptions, readAsset);
|
|
25
|
+
const bytes = await (fontPaths.has(path) ? readVerifiedFontAsset : readVerifiedAsset)(byPath.get(path), loadingOptions, readAsset);
|
|
24
26
|
throwIfAborted(context.signal);
|
|
25
27
|
return bytes;
|
|
26
28
|
};
|
|
@@ -34,7 +36,7 @@ export function createRenderingExecutor({ manifest, options, readAsset, execute
|
|
|
34
36
|
throwIfAborted(context.signal);
|
|
35
37
|
const item = { asset: { path: `font:${font.family}`, mediaType: 'font/ttf', bytes: font.bytes, sha256: font.sha256 }, url: font.source };
|
|
36
38
|
const bytes = font.coverage
|
|
37
|
-
? await
|
|
39
|
+
? await readVerifiedFontAsset(item, loadingOptions, font.source instanceof Uint8Array ? async () => new Response(font.source) : readAsset)
|
|
38
40
|
: font.source instanceof Uint8Array ? font.source : new Uint8Array(await (await readAsset(item, loadingOptions)).arrayBuffer());
|
|
39
41
|
throwIfAborted(context.signal);
|
|
40
42
|
fonts.push({ family: font.family, data: base64(bytes), ...(font.languages ? { languages: font.languages } : {}) });
|
package/src/runtime/rendering.js
CHANGED
|
@@ -7,30 +7,31 @@ const invalid = message => { throw new DrawMotiveError('INVALID_ARGUMENT', messa
|
|
|
7
7
|
/** Both export formats share source, logical padding, language and cancellation semantics. */
|
|
8
8
|
function normalizeCommonOptions(source, options) {
|
|
9
9
|
if (typeof source !== 'string' || !options || typeof options !== 'object' || Array.isArray(options)) invalid('Rendering requires a source string and options object');
|
|
10
|
-
const { padding = 10, signal, language } = options;
|
|
10
|
+
const { padding = 10, signal, language, onPreview } = options;
|
|
11
|
+
if (onPreview !== undefined && typeof onPreview !== 'function') invalid('onPreview must be a function');
|
|
11
12
|
if (language !== undefined && (typeof language !== 'string' || !/^[a-z]{2,8}(?:-[A-Za-z0-9]+)*$/.test(language))) invalid('language must be a language tag');
|
|
12
13
|
// The native geometry contract uses float32; reject values lost at that boundary.
|
|
13
14
|
if (!Number.isFinite(padding) || !Number.isFinite(Math.fround(padding)) || padding < 0) invalid('padding must be non-negative and representable as a finite float32');
|
|
14
15
|
validateSignal(signal);
|
|
15
|
-
return { padding, signal, request: { protocolVersion: 1, operation: 'render', source, ...(language === undefined ? {} : { language }) } };
|
|
16
|
+
return { padding, signal, onPreview, request: { protocolVersion: 1, operation: 'render', source, ...(language === undefined ? {} : { language }) } };
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/** Normalize export settings before queuing; native receives only the render contract. */
|
|
19
20
|
export function normalizeRenderOptions(source, options) {
|
|
20
|
-
const { padding, signal, request } = normalizeCommonOptions(source, options);
|
|
21
|
+
const { padding, signal, onPreview, request } = normalizeCommonOptions(source, options);
|
|
21
22
|
const { encoding = 'bytes', scale = 1, maxWidth } = options;
|
|
22
23
|
if (!['bytes', 'base64'].includes(encoding)) invalid('encoding must be bytes or base64');
|
|
23
24
|
// The native geometry contract uses float32; reject values lost at that boundary.
|
|
24
25
|
if (!Number.isFinite(scale) || !Number.isFinite(Math.fround(scale)) || Math.fround(scale) <= 0) invalid('scale must be positive and representable as a finite float32');
|
|
25
26
|
if (maxWidth !== undefined && (!Number.isSafeInteger(maxWidth) || maxWidth <= 0)) invalid('maxWidth must be a positive integer');
|
|
26
|
-
return { encoding, signal, request: { ...request, export: { format: 'png', scale, padding, ...(maxWidth === undefined ? {} : { maxWidth }) } } };
|
|
27
|
+
return { encoding, signal, onPreview, request: { ...request, export: { format: 'png', scale, padding, ...(maxWidth === undefined ? {} : { maxWidth }) } } };
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
/** SVG accepts only logical export settings; PNG density and encoding have no vector meaning. */
|
|
30
31
|
export function normalizeSvgOptions(source, options) {
|
|
31
|
-
const { padding, signal, request } = normalizeCommonOptions(source, options);
|
|
32
|
-
if (Reflect.ownKeys(options).some(key => !['padding', 'language', 'signal'].includes(key))) invalid('Unknown SVG rendering option');
|
|
33
|
-
return { signal, request: { ...request, export: { format: 'svg', padding } } };
|
|
32
|
+
const { padding, signal, onPreview, request } = normalizeCommonOptions(source, options);
|
|
33
|
+
if (Reflect.ownKeys(options).some(key => !['padding', 'language', 'signal', 'onPreview'].includes(key))) invalid('Unknown SVG rendering option');
|
|
34
|
+
return { signal, onPreview, request: { ...request, export: { format: 'svg', padding } } };
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
/** Accept canonical base64 only; platform atob implementations otherwise tolerate corruption. */
|
|
Binary file
|