@retikz/vanilla 0.3.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/es/builder/coordinate.d.ts +8 -0
- package/dist/es/builder/coordinate.d.ts.map +1 -0
- package/dist/es/builder/coordinate.js +13 -0
- package/dist/es/builder/draw.d.ts +8 -0
- package/dist/es/builder/draw.d.ts.map +1 -0
- package/dist/es/builder/draw.js +14 -0
- package/dist/es/builder/figure.d.ts +21 -0
- package/dist/es/builder/figure.d.ts.map +1 -0
- package/dist/es/builder/figure.js +13 -0
- package/dist/es/builder/isFigure.d.ts +6 -0
- package/dist/es/builder/isFigure.d.ts.map +1 -0
- package/dist/es/builder/isFigure.js +7 -0
- package/dist/es/builder/node.d.ts +9 -0
- package/dist/es/builder/node.d.ts.map +1 -0
- package/dist/es/builder/node.js +20 -0
- package/dist/es/builder/scope.d.ts +23 -0
- package/dist/es/builder/scope.d.ts.map +1 -0
- package/dist/es/builder/scope.js +45 -0
- package/dist/es/builder/types.d.ts +26 -0
- package/dist/es/builder/types.d.ts.map +1 -0
- package/dist/es/figure.d.ts +26 -0
- package/dist/es/figure.d.ts.map +1 -0
- package/dist/es/figure.js +66 -0
- package/dist/es/index.d.ts +20 -0
- package/dist/es/index.d.ts.map +1 -0
- package/dist/es/index.js +8 -0
- package/dist/es/mountSvg.d.ts +10 -0
- package/dist/es/mountSvg.d.ts.map +1 -0
- package/dist/es/mountSvg.js +48 -0
- package/dist/es/renderToSvgString.d.ts +8 -0
- package/dist/es/renderToSvgString.d.ts.map +1 -0
- package/dist/es/renderToSvgString.js +23 -0
- package/dist/es/svgNodeToDom.d.ts +14 -0
- package/dist/es/svgNodeToDom.d.ts.map +1 -0
- package/dist/es/svgNodeToDom.js +26 -0
- package/dist/es/toScene.d.ts +10 -0
- package/dist/es/toScene.d.ts.map +1 -0
- package/dist/es/toScene.js +18 -0
- package/dist/es/types.d.ts +28 -0
- package/dist/es/types.d.ts.map +1 -0
- package/dist/lib/builder/coordinate.cjs +13 -0
- package/dist/lib/builder/coordinate.d.ts +8 -0
- package/dist/lib/builder/coordinate.d.ts.map +1 -0
- package/dist/lib/builder/draw.cjs +14 -0
- package/dist/lib/builder/draw.d.ts +8 -0
- package/dist/lib/builder/draw.d.ts.map +1 -0
- package/dist/lib/builder/figure.cjs +13 -0
- package/dist/lib/builder/figure.d.ts +21 -0
- package/dist/lib/builder/figure.d.ts.map +1 -0
- package/dist/lib/builder/isFigure.cjs +8 -0
- package/dist/lib/builder/isFigure.d.ts +6 -0
- package/dist/lib/builder/isFigure.d.ts.map +1 -0
- package/dist/lib/builder/node.cjs +20 -0
- package/dist/lib/builder/node.d.ts +9 -0
- package/dist/lib/builder/node.d.ts.map +1 -0
- package/dist/lib/builder/scope.cjs +45 -0
- package/dist/lib/builder/scope.d.ts +23 -0
- package/dist/lib/builder/scope.d.ts.map +1 -0
- package/dist/lib/builder/types.d.ts +26 -0
- package/dist/lib/builder/types.d.ts.map +1 -0
- package/dist/lib/figure.cjs +66 -0
- package/dist/lib/figure.d.ts +26 -0
- package/dist/lib/figure.d.ts.map +1 -0
- package/dist/lib/index.cjs +15 -0
- package/dist/lib/index.d.ts +20 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/mountSvg.cjs +48 -0
- package/dist/lib/mountSvg.d.ts +10 -0
- package/dist/lib/mountSvg.d.ts.map +1 -0
- package/dist/lib/renderToSvgString.cjs +23 -0
- package/dist/lib/renderToSvgString.d.ts +8 -0
- package/dist/lib/renderToSvgString.d.ts.map +1 -0
- package/dist/lib/svgNodeToDom.cjs +27 -0
- package/dist/lib/svgNodeToDom.d.ts +14 -0
- package/dist/lib/svgNodeToDom.d.ts.map +1 -0
- package/dist/lib/toScene.cjs +18 -0
- package/dist/lib/toScene.d.ts +10 -0
- package/dist/lib/toScene.d.ts.map +1 -0
- package/dist/lib/types.d.ts +28 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 pionpill
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @retikz/vanilla
|
|
2
|
+
|
|
3
|
+
Framework-free runtime + SSR entry for [retikz](https://pionpill.github.io/retikz/). No JSX, no UI framework — mount a diagram to the DOM, render it to an SVG string on the server, or compose one with an imperative named builder.
|
|
4
|
+
|
|
5
|
+
retikz 的无框架 runtime / SSR 入口:不依赖任何 UI 框架。`renderToSvgString` 走服务端 / 构建期(零 DOM)产 SVG 字符串;`mountSvg` 在浏览器把图形挂到 DOM;命令式 builder(`figure`/`node`/`draw`/`coordinate`/`scope`)让你像 React 一样具名构图、产同一份 IR。组合 `@retikz/render` 内核,不自维护第二套渲染逻辑。
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @retikz/vanilla @retikz/core @retikz/render
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Render IR / Scene
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { renderToSvgString, mountSvg } from '@retikz/vanilla';
|
|
17
|
+
|
|
18
|
+
// server / build time — no DOM
|
|
19
|
+
const svg = renderToSvgString(ir);
|
|
20
|
+
|
|
21
|
+
// browser
|
|
22
|
+
mountSvg(document.querySelector('#diagram'), ir);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Imperative builder
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { figure, node, draw } from '@retikz/vanilla';
|
|
29
|
+
|
|
30
|
+
const fig = figure([
|
|
31
|
+
node('a', { position: [0, 0], text: 'A' }),
|
|
32
|
+
node('b', { position: [120, 0], text: 'B' }),
|
|
33
|
+
draw(['a', 'b'], { arrow: '->' }),
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
const svg = fig.toSvgString(); // also: fig.mount(el) / fig.toCanvas(canvas)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Exports
|
|
40
|
+
|
|
41
|
+
- Runtime: `renderToSvgString`, `mountSvg`
|
|
42
|
+
- Builder: `figure` / `node` / `draw` / `coordinate` / `scope` + the `Figure` view (`.toSvgString` / `.mount` / `.toCanvas`)
|
|
43
|
+
|
|
44
|
+
## Docs
|
|
45
|
+
|
|
46
|
+
<https://pionpill.github.io/retikz/>
|
|
47
|
+
|
|
48
|
+
## License
|
|
49
|
+
|
|
50
|
+
MIT
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Child, CoordinateConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 构造一个 coordinate IR 子节点(具名点占位,不绘制)
|
|
4
|
+
* @description `id` 必要(coordinate 存在意义就是被引用),提为首 positional;`position` 在 config 必填
|
|
5
|
+
* (类型层 `CoordinateConfig` 派生自 `IRCoordinate` 故 position 非可选),缺失在编译期由 schema 报错。
|
|
6
|
+
*/
|
|
7
|
+
export declare const coordinate: (id: string, config: CoordinateConfig) => Child;
|
|
8
|
+
//# sourceMappingURL=coordinate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinate.d.ts","sourceRoot":"","sources":["../../../src/builder/coordinate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,EAAE,QAAQ,gBAAgB,KAAG,KAIhE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/builder/coordinate.ts
|
|
2
|
+
/**
|
|
3
|
+
* 构造一个 coordinate IR 子节点(具名点占位,不绘制)
|
|
4
|
+
* @description `id` 必要(coordinate 存在意义就是被引用),提为首 positional;`position` 在 config 必填
|
|
5
|
+
* (类型层 `CoordinateConfig` 派生自 `IRCoordinate` 故 position 非可选),缺失在编译期由 schema 报错。
|
|
6
|
+
*/
|
|
7
|
+
var coordinate = (id, config) => ({
|
|
8
|
+
type: "coordinate",
|
|
9
|
+
id,
|
|
10
|
+
...config
|
|
11
|
+
});
|
|
12
|
+
//#endregion
|
|
13
|
+
export { coordinate };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Child, DrawConfig, Way } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 构造一个 path IR 子节点
|
|
4
|
+
* @description `way` 经 core `parseWay` 解析成 IRStep 序列(与 React `<Draw way>` 同一解析、同一全集,零漂移);
|
|
5
|
+
* `config` 是 path 级样式(arrow / stroke / dashPattern / fill …),原样并入。
|
|
6
|
+
*/
|
|
7
|
+
export declare const draw: (way: Way, config?: DrawConfig) => Child;
|
|
8
|
+
//# sourceMappingURL=draw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw.d.ts","sourceRoot":"","sources":["../../../src/builder/draw.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAEtD;;;;GAIG;AACH,eAAO,MAAM,IAAI,GAAI,KAAK,GAAG,EAAE,SAAS,UAAU,KAAG,KAInD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { parseWay } from "@retikz/core";
|
|
2
|
+
//#region src/builder/draw.ts
|
|
3
|
+
/**
|
|
4
|
+
* 构造一个 path IR 子节点
|
|
5
|
+
* @description `way` 经 core `parseWay` 解析成 IRStep 序列(与 React `<Draw way>` 同一解析、同一全集,零漂移);
|
|
6
|
+
* `config` 是 path 级样式(arrow / stroke / dashPattern / fill …),原样并入。
|
|
7
|
+
*/
|
|
8
|
+
var draw = (way, config) => ({
|
|
9
|
+
type: "path",
|
|
10
|
+
children: parseWay(way),
|
|
11
|
+
...config
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
export { draw };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Figure } from '../figure';
|
|
2
|
+
import { Child, FigureConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* `figure` 的重载签名
|
|
5
|
+
* @description children-array 形态排在 config 之前——`FigureConfig` 字段全可选,数组也结构上「可赋给」它,
|
|
6
|
+
* 顺序反了会让 `figure([...])` 误匹配 config 重载。
|
|
7
|
+
*/
|
|
8
|
+
type FigureFn = {
|
|
9
|
+
(): Figure;
|
|
10
|
+
(children: Array<Child>): Figure;
|
|
11
|
+
(config: FigureConfig): Figure;
|
|
12
|
+
(config: FigureConfig, children: Array<Child>): Figure;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* 命令式 builder 入口
|
|
16
|
+
* @description 四种调用:`figure()` 空图;`figure(children)` 省略 config 直接传子节点;`figure(config)` 起
|
|
17
|
+
* fluent;`figure(config, children)` hyperscript。都返回同一 `Figure`、`.ir` 一致、可混用。
|
|
18
|
+
*/
|
|
19
|
+
export declare const figure: FigureFn;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=figure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figure.d.ts","sourceRoot":"","sources":["../../../src/builder/figure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,WAAW,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;GAIG;AACH,KAAK,QAAQ,GAAG;IACd,IAAI,MAAM,CAAC;IACX,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;IACjC,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC;IAC/B,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;CACxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,QAMpB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createFigure } from "../figure.js";
|
|
2
|
+
//#region src/builder/figure.ts
|
|
3
|
+
/**
|
|
4
|
+
* 命令式 builder 入口
|
|
5
|
+
* @description 四种调用:`figure()` 空图;`figure(children)` 省略 config 直接传子节点;`figure(config)` 起
|
|
6
|
+
* fluent;`figure(config, children)` hyperscript。都返回同一 `Figure`、`.ir` 一致、可混用。
|
|
7
|
+
*/
|
|
8
|
+
var figure = (configOrChildren, children) => {
|
|
9
|
+
if (Array.isArray(configOrChildren)) return createFigure({}, configOrChildren);
|
|
10
|
+
return createFigure(configOrChildren ?? {}, children ?? []);
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { figure };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Figure } from '../figure';
|
|
2
|
+
/** Figure 品牌标记(Symbol.for 跨包/重复 import 仍同一);标准 mountSvg/renderToSvgString 用它区分 Figure 与 IR/Scene */
|
|
3
|
+
export declare const FIGURE_BRAND: unique symbol;
|
|
4
|
+
/** 运行时判断一个值是不是 Figure(带 brand);纯结构检查、零内部 import → 不与 mountSvg/Figure 形成运行时环 */
|
|
5
|
+
export declare const isFigure: (value: unknown) => value is Figure;
|
|
6
|
+
//# sourceMappingURL=isFigure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isFigure.d.ts","sourceRoot":"","sources":["../../../src/builder/isFigure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,oGAAoG;AACpG,eAAO,MAAM,YAAY,EAAE,OAAO,MAA4C,CAAC;AAE/E,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MACuD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/builder/isFigure.ts
|
|
2
|
+
/** Figure 品牌标记(Symbol.for 跨包/重复 import 仍同一);标准 mountSvg/renderToSvgString 用它区分 Figure 与 IR/Scene */
|
|
3
|
+
var FIGURE_BRAND = Symbol.for("retikz.vanilla.figure");
|
|
4
|
+
/** 运行时判断一个值是不是 Figure(带 brand);纯结构检查、零内部 import → 不与 mountSvg/Figure 形成运行时环 */
|
|
5
|
+
var isFigure = (value) => typeof value === "object" && value !== null && value[FIGURE_BRAND] === true;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { FIGURE_BRAND, isFigure };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Child, NodeConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 构造一个 node IR 子节点
|
|
4
|
+
* @description `node(config)` 匿名;`node(id, config)` 具名(首参为字符串即 id)。单签名联合参数同时接受两种
|
|
5
|
+
* 形态。纯构造 IRNode(`{ type:'node', id?, ...config }`);字段不自列、必填项(如 position)由 core schema
|
|
6
|
+
* 在 compile 期校验,故构造边界用一处断言收口(builder 故意宽松、缺字段不在此拦、交 compileToScene 报错)。
|
|
7
|
+
*/
|
|
8
|
+
export declare const node: (arg1?: string | NodeConfig, arg2?: NodeConfig) => Child;
|
|
9
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/builder/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,IAAI,GAAI,OAAO,MAAM,GAAG,UAAU,EAAE,OAAO,UAAU,KAAG,KAKpE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/builder/node.ts
|
|
2
|
+
/**
|
|
3
|
+
* 构造一个 node IR 子节点
|
|
4
|
+
* @description `node(config)` 匿名;`node(id, config)` 具名(首参为字符串即 id)。单签名联合参数同时接受两种
|
|
5
|
+
* 形态。纯构造 IRNode(`{ type:'node', id?, ...config }`);字段不自列、必填项(如 position)由 core schema
|
|
6
|
+
* 在 compile 期校验,故构造边界用一处断言收口(builder 故意宽松、缺字段不在此拦、交 compileToScene 报错)。
|
|
7
|
+
*/
|
|
8
|
+
var node = (arg1, arg2) => {
|
|
9
|
+
const named = typeof arg1 === "string";
|
|
10
|
+
const config = named ? arg2 : arg1;
|
|
11
|
+
return {
|
|
12
|
+
...named ? {
|
|
13
|
+
type: "node",
|
|
14
|
+
id: arg1
|
|
15
|
+
} : { type: "node" },
|
|
16
|
+
...config
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { node };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { coordinate } from './coordinate';
|
|
2
|
+
import { draw } from './draw';
|
|
3
|
+
import { node } from './node';
|
|
4
|
+
import { Child, ScopeConfig } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* scope 的 fluent 收集器
|
|
7
|
+
* @description `scope(config, build)` 把它交给回调;`.node/.draw/.coordinate/.scope` 把子节点推进内部数组、
|
|
8
|
+
* 链式返回 this。与 hyperscript 数组形态产同一份 children。
|
|
9
|
+
*/
|
|
10
|
+
export type ScopeBuilder = {
|
|
11
|
+
node: (...args: Parameters<typeof node>) => ScopeBuilder;
|
|
12
|
+
draw: (...args: Parameters<typeof draw>) => ScopeBuilder;
|
|
13
|
+
coordinate: (...args: Parameters<typeof coordinate>) => ScopeBuilder;
|
|
14
|
+
scope: (config: ScopeConfig, build: (s: ScopeBuilder) => void) => ScopeBuilder;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* 构造一个 scope IR 子节点(分组容器 + 样式默认 + transforms)
|
|
18
|
+
* @description `config` 与 core `IRScope` / React `<Scope>` 顶层逐字一致——只透传 `transforms`(IRTransform[],
|
|
19
|
+
* 合并顺序 = 数组顺序,首元素最内层)+ 样式默认,**不自造 xshift/yshift 糖**。children 两形态:数组
|
|
20
|
+
* (hyperscript)或回调(fluent,经 ScopeBuilder 收集),单签名联合参数同时接受。
|
|
21
|
+
*/
|
|
22
|
+
export declare const scope: (config: ScopeConfig, arg: Array<Child> | ((s: ScopeBuilder) => void)) => Child;
|
|
23
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/builder/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAElD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,YAAY,CAAC;IACzD,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,YAAY,CAAC;IACzD,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,YAAY,CAAC;IACrE,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,KAAK,YAAY,CAAC;CAChF,CAAC;AAwBF;;;;;GAKG;AACH,eAAO,MAAM,KAAK,GAAI,QAAQ,WAAW,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC,KAAG,KAS5F,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { coordinate } from "./coordinate.js";
|
|
2
|
+
import { draw } from "./draw.js";
|
|
3
|
+
import { node } from "./node.js";
|
|
4
|
+
//#region src/builder/scope.ts
|
|
5
|
+
var createScopeBuilder = (sink) => {
|
|
6
|
+
const self = {
|
|
7
|
+
node(...args) {
|
|
8
|
+
sink.push(node(...args));
|
|
9
|
+
return self;
|
|
10
|
+
},
|
|
11
|
+
draw(...args) {
|
|
12
|
+
sink.push(draw(...args));
|
|
13
|
+
return self;
|
|
14
|
+
},
|
|
15
|
+
coordinate(...args) {
|
|
16
|
+
sink.push(coordinate(...args));
|
|
17
|
+
return self;
|
|
18
|
+
},
|
|
19
|
+
scope(config, build) {
|
|
20
|
+
sink.push(scope(config, build));
|
|
21
|
+
return self;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return self;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* 构造一个 scope IR 子节点(分组容器 + 样式默认 + transforms)
|
|
28
|
+
* @description `config` 与 core `IRScope` / React `<Scope>` 顶层逐字一致——只透传 `transforms`(IRTransform[],
|
|
29
|
+
* 合并顺序 = 数组顺序,首元素最内层)+ 样式默认,**不自造 xshift/yshift 糖**。children 两形态:数组
|
|
30
|
+
* (hyperscript)或回调(fluent,经 ScopeBuilder 收集),单签名联合参数同时接受。
|
|
31
|
+
*/
|
|
32
|
+
var scope = (config, arg) => {
|
|
33
|
+
let children;
|
|
34
|
+
if (typeof arg === "function") {
|
|
35
|
+
children = [];
|
|
36
|
+
arg(createScopeBuilder(children));
|
|
37
|
+
} else children = arg;
|
|
38
|
+
return {
|
|
39
|
+
type: "scope",
|
|
40
|
+
...config,
|
|
41
|
+
children
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
export { scope };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CompileOptions, IRChild, IRCoordinate, IRNode, IRPath, IRScope, IRViewBox, WayDSL } from '@retikz/core';
|
|
2
|
+
/** builder 函数返回的 IR 子节点(node / draw / coordinate / scope 的产物) */
|
|
3
|
+
export type Child = IRChild;
|
|
4
|
+
/** node 的 config:从 IRNode 派生,剔除判别符 type 与提为 positional 的 id */
|
|
5
|
+
export type NodeConfig = Omit<IRNode, 'type' | 'id'>;
|
|
6
|
+
/** draw 的 config:从 IRPath 派生,剔除 type 与由 way 生成的 children(steps) */
|
|
7
|
+
export type DrawConfig = Omit<IRPath, 'type' | 'children'>;
|
|
8
|
+
/** coordinate 的 config:从 IRCoordinate 派生,剔除 type 与 positional 的 id(剩 position 必填) */
|
|
9
|
+
export type CoordinateConfig = Omit<IRCoordinate, 'type' | 'id'>;
|
|
10
|
+
/** scope 的 config:从 IRScope 派生,剔除 type 与单列的 children(含 transforms 等全部样式默认) */
|
|
11
|
+
export type ScopeConfig = Omit<IRScope, 'type' | 'children'>;
|
|
12
|
+
/** draw 的 way:直接复用 core 的 way DSL 全集(id 串 / 坐标 / Cycle / 折角 / 相对 / 曲线 / 弧 …) */
|
|
13
|
+
export type Way = WayDSL;
|
|
14
|
+
/**
|
|
15
|
+
* figure 的 config
|
|
16
|
+
* @description `viewBox` → IR.viewBox(内容坐标系);`width`/`height` → 根 `<svg>` 显示尺寸(adapter 职责);
|
|
17
|
+
* `idPrefix` → SVG 资源 id 前缀;其余(measureText / shapes / arrows / patterns / pathGenerators /
|
|
18
|
+
* padding / precision / nodeDistance / onWarn)派生自 core `CompileOptions`、原样喂 compileToScene。
|
|
19
|
+
*/
|
|
20
|
+
export type FigureConfig = {
|
|
21
|
+
width?: number;
|
|
22
|
+
height?: number;
|
|
23
|
+
viewBox?: IRViewBox;
|
|
24
|
+
idPrefix?: string;
|
|
25
|
+
} & CompileOptions;
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/builder/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,YAAY,EACZ,MAAM,EACN,MAAM,EACN,OAAO,EACP,SAAS,EACT,MAAM,EACP,MAAM,cAAc,CAAC;AAEtB,iEAAiE;AACjE,MAAM,MAAM,KAAK,GAAG,OAAO,CAAC;AAE5B,+DAA+D;AAC/D,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAErD,mEAAmE;AACnE,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC;AAE3D,qFAAqF;AACrF,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAEjE,8EAA8E;AAC9E,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC;AAE7D,gFAAgF;AAChF,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,cAAc,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { IR } from '@retikz/core';
|
|
2
|
+
import { RenderOptions } from '@retikz/render/canvas';
|
|
3
|
+
import { FIGURE_BRAND } from './builder/isFigure';
|
|
4
|
+
import { node } from './builder/node';
|
|
5
|
+
import { ScopeBuilder } from './builder/scope';
|
|
6
|
+
import { Child, CoordinateConfig, DrawConfig, FigureConfig, ScopeConfig, Way } from './builder/types';
|
|
7
|
+
import { MountOptions, RenderToStringOptions, VanillaView } from './types';
|
|
8
|
+
/**
|
|
9
|
+
* 命令式 builder 的装配产物 —— 唯一返回类型
|
|
10
|
+
* @description hyperscript(`figure(config, children)`)与 fluent(`figure(config).node(...)`)都产它、可混用、`.ir` 一致。
|
|
11
|
+
* `.mount`/`.toSvgString`/`.toCanvas` 把 `this.ir`(IR,非 Figure)交底层 renderer;fluent 方法往内部 children 追加、链式返回 this。
|
|
12
|
+
*/
|
|
13
|
+
export type Figure = {
|
|
14
|
+
readonly [FIGURE_BRAND]: true;
|
|
15
|
+
readonly ir: IR;
|
|
16
|
+
mount: (container: Element, options?: MountOptions) => VanillaView;
|
|
17
|
+
toSvgString: (options?: RenderToStringOptions) => string;
|
|
18
|
+
toCanvas: (canvas: HTMLCanvasElement, options?: RenderOptions) => void;
|
|
19
|
+
node: (...args: Parameters<typeof node>) => Figure;
|
|
20
|
+
draw: (way: Way, config?: DrawConfig) => Figure;
|
|
21
|
+
coordinate: (id: string, config: CoordinateConfig) => Figure;
|
|
22
|
+
scope: (config: ScopeConfig, build: (s: ScopeBuilder) => void) => Figure;
|
|
23
|
+
};
|
|
24
|
+
/** figure() 的内部入口:装配 Figure(持 config + children,方法闭包其上) */
|
|
25
|
+
export declare const createFigure: (config: FigureConfig, children: Array<Child>) => Figure;
|
|
26
|
+
//# sourceMappingURL=figure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figure.d.ts","sourceRoot":"","sources":["../../src/figure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAI3G,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEhF;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,WAAW,CAAC;IACnE,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,MAAM,CAAC;IACzD,QAAQ,EAAE,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IACvE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,MAAM,CAAC;IACnD,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,UAAU,KAAK,MAAM,CAAC;IAChD,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAC7D,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,KAAK,MAAM,CAAC;CAC1E,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,YAAY,GAAI,QAAQ,YAAY,EAAE,UAAU,KAAK,CAAC,KAAK,CAAC,KAAG,MAoD3E,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { FIGURE_BRAND } from "./builder/isFigure.js";
|
|
2
|
+
import { toScene } from "./toScene.js";
|
|
3
|
+
import { renderToSvgString } from "./renderToSvgString.js";
|
|
4
|
+
import { mountSvg } from "./mountSvg.js";
|
|
5
|
+
import { coordinate } from "./builder/coordinate.js";
|
|
6
|
+
import { draw } from "./builder/draw.js";
|
|
7
|
+
import { node } from "./builder/node.js";
|
|
8
|
+
import { scope } from "./builder/scope.js";
|
|
9
|
+
import { renderToCanvas } from "@retikz/render/canvas";
|
|
10
|
+
//#region src/figure.ts
|
|
11
|
+
/** figure() 的内部入口:装配 Figure(持 config + children,方法闭包其上) */
|
|
12
|
+
var createFigure = (config, children) => {
|
|
13
|
+
/** call-site options 覆盖 figure 存的 config(call-site wins):viewBox 已并进 ir,其余(width/height/idPrefix + 全套 CompileOptions)全透传 */
|
|
14
|
+
const renderOptions = (callSite) => {
|
|
15
|
+
const merged = {
|
|
16
|
+
...config,
|
|
17
|
+
...callSite
|
|
18
|
+
};
|
|
19
|
+
delete merged.viewBox;
|
|
20
|
+
return merged;
|
|
21
|
+
};
|
|
22
|
+
const fig = {
|
|
23
|
+
[FIGURE_BRAND]: true,
|
|
24
|
+
get ir() {
|
|
25
|
+
return {
|
|
26
|
+
version: 1,
|
|
27
|
+
type: "scene",
|
|
28
|
+
children,
|
|
29
|
+
...config.viewBox ? { viewBox: config.viewBox } : {}
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
mount(container, options) {
|
|
33
|
+
return mountSvg(container, fig.ir, renderOptions(options));
|
|
34
|
+
},
|
|
35
|
+
toSvgString(options) {
|
|
36
|
+
return renderToSvgString(fig.ir, renderOptions(options));
|
|
37
|
+
},
|
|
38
|
+
toCanvas(canvas, options) {
|
|
39
|
+
const compile = { ...config };
|
|
40
|
+
delete compile.viewBox;
|
|
41
|
+
delete compile.idPrefix;
|
|
42
|
+
delete compile.width;
|
|
43
|
+
delete compile.height;
|
|
44
|
+
renderToCanvas(canvas, toScene(fig.ir, compile), options ?? {});
|
|
45
|
+
},
|
|
46
|
+
node(...args) {
|
|
47
|
+
children.push(node(...args));
|
|
48
|
+
return fig;
|
|
49
|
+
},
|
|
50
|
+
draw(way, drawConfig) {
|
|
51
|
+
children.push(draw(way, drawConfig));
|
|
52
|
+
return fig;
|
|
53
|
+
},
|
|
54
|
+
coordinate(id, coordConfig) {
|
|
55
|
+
children.push(coordinate(id, coordConfig));
|
|
56
|
+
return fig;
|
|
57
|
+
},
|
|
58
|
+
scope(scopeConfig, build) {
|
|
59
|
+
children.push(scope(scopeConfig, build));
|
|
60
|
+
return fig;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
return fig;
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { createFigure };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @retikz/vanilla 公开 API —— framework-free runtime / SSR 入口 + 命令式 builder
|
|
3
|
+
*
|
|
4
|
+
* 无框架 / SSR 的 runtime 门面:组合 `@retikz/render/svg`(descriptor / 字符串)与 `@retikz/render/canvas`(后置),
|
|
5
|
+
* 不自维护第二套 Scene→输出内核。`renderToSvgString` 走 SSR(零 DOM);`mountSvg` 走浏览器 DOM 挂载。
|
|
6
|
+
* `figure`/`node`/`draw`/`coordinate`/`scope` 是命令式 builder:用具名图元 + 自定义 shape 构图、产同一份 IR。
|
|
7
|
+
* 模块顶层不触碰任何 DOM 全局——`import` 在纯 Node 下安全。
|
|
8
|
+
*/
|
|
9
|
+
export { renderToSvgString } from './renderToSvgString';
|
|
10
|
+
export { mountSvg } from './mountSvg';
|
|
11
|
+
export { figure } from './builder/figure';
|
|
12
|
+
export { node } from './builder/node';
|
|
13
|
+
export { draw } from './builder/draw';
|
|
14
|
+
export { coordinate } from './builder/coordinate';
|
|
15
|
+
export { scope } from './builder/scope';
|
|
16
|
+
export type { Figure } from './figure';
|
|
17
|
+
export type { ScopeBuilder } from './builder/scope';
|
|
18
|
+
export type { Child, NodeConfig, DrawConfig, CoordinateConfig, ScopeConfig, FigureConfig, Way, } from './builder/types';
|
|
19
|
+
export type { RenderInput, CommonOptions, MountOptions, RenderToStringOptions, VanillaView } from './types';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EACV,KAAK,EACL,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,GAAG,GACJ,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/es/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { renderToSvgString } from "./renderToSvgString.js";
|
|
2
|
+
import { mountSvg } from "./mountSvg.js";
|
|
3
|
+
import { coordinate } from "./builder/coordinate.js";
|
|
4
|
+
import { draw } from "./builder/draw.js";
|
|
5
|
+
import { node } from "./builder/node.js";
|
|
6
|
+
import { scope } from "./builder/scope.js";
|
|
7
|
+
import { figure } from "./builder/figure.js";
|
|
8
|
+
export { coordinate, draw, figure, mountSvg, node, renderToSvgString, scope };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MountOptions, RenderInput, VanillaView } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 把 IR / Scene / Figure 挂成真实 SVG DOM(无框架浏览器 runtime)
|
|
4
|
+
* @description 收 `Figure` 时 delegate 给 `figure.mount`(Figure 自持 config,call-site options 覆盖)。收
|
|
5
|
+
* IR/Scene 时:`toScene`(收 ir 时 compile)→ `buildSvgDocument`(`@retikz/render/svg`)→ 物化进**稳定复用**的 root
|
|
6
|
+
* `<svg>`;`width`/`height` 若给则写回根(`@retikz/render/svg` 只产 viewBox,显示尺寸是 adapter 本分)。`update`
|
|
7
|
+
* 原地重渲染、root 元素 identity 跨 update 不变、不失效。DOM 仅在调用时惰性触碰,`import` 本模块不碰 DOM——守 SSR 导入安全。
|
|
8
|
+
*/
|
|
9
|
+
export declare const mountSvg: (container: Element, input: RenderInput, options?: MountOptions) => VanillaView;
|
|
10
|
+
//# sourceMappingURL=mountSvg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mountSvg.d.ts","sourceRoot":"","sources":["../../src/mountSvg.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAMtE;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,GAAI,WAAW,OAAO,EAAE,OAAO,WAAW,EAAE,UAAS,YAAiB,KAAG,WAwC7F,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { isFigure } from "./builder/isFigure.js";
|
|
2
|
+
import { toScene } from "./toScene.js";
|
|
3
|
+
import { applyAttrs, svgNodeToDom } from "./svgNodeToDom.js";
|
|
4
|
+
import { buildSvgDocument } from "@retikz/render/svg";
|
|
5
|
+
//#region src/mountSvg.ts
|
|
6
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
7
|
+
/** 默认资源 id 前缀(确定性);多实例同页须经 `options.idPrefix` 显式区分 */
|
|
8
|
+
var DEFAULT_ID_PREFIX = "r";
|
|
9
|
+
/**
|
|
10
|
+
* 把 IR / Scene / Figure 挂成真实 SVG DOM(无框架浏览器 runtime)
|
|
11
|
+
* @description 收 `Figure` 时 delegate 给 `figure.mount`(Figure 自持 config,call-site options 覆盖)。收
|
|
12
|
+
* IR/Scene 时:`toScene`(收 ir 时 compile)→ `buildSvgDocument`(`@retikz/render/svg`)→ 物化进**稳定复用**的 root
|
|
13
|
+
* `<svg>`;`width`/`height` 若给则写回根(`@retikz/render/svg` 只产 viewBox,显示尺寸是 adapter 本分)。`update`
|
|
14
|
+
* 原地重渲染、root 元素 identity 跨 update 不变、不失效。DOM 仅在调用时惰性触碰,`import` 本模块不碰 DOM——守 SSR 导入安全。
|
|
15
|
+
*/
|
|
16
|
+
var mountSvg = (container, input, options = {}) => {
|
|
17
|
+
if (isFigure(input)) return input.mount(container, options);
|
|
18
|
+
if (typeof Element === "undefined" || !(container instanceof Element)) throw new Error("mountSvg: container must be a DOM Element.");
|
|
19
|
+
const idPrefix = options.idPrefix ?? DEFAULT_ID_PREFIX;
|
|
20
|
+
const root = document.createElementNS(SVG_NS, "svg");
|
|
21
|
+
const renderInto = (next) => {
|
|
22
|
+
if (isFigure(next)) throw new Error("mountSvg: view.update does not accept a Figure; pass figure.ir instead.");
|
|
23
|
+
const doc = buildSvgDocument(toScene(next, options), { idPrefix });
|
|
24
|
+
while (root.firstChild) root.removeChild(root.firstChild);
|
|
25
|
+
for (const attr of [...root.attributes]) root.removeAttribute(attr.name);
|
|
26
|
+
applyAttrs(root, doc);
|
|
27
|
+
if (options.width !== void 0) root.setAttribute("width", String(options.width));
|
|
28
|
+
if (options.height !== void 0) root.setAttribute("height", String(options.height));
|
|
29
|
+
for (const child of doc.children ?? []) root.appendChild(typeof child === "string" ? document.createTextNode(child) : svgNodeToDom(child));
|
|
30
|
+
};
|
|
31
|
+
renderInto(input);
|
|
32
|
+
container.appendChild(root);
|
|
33
|
+
let disposed = false;
|
|
34
|
+
return {
|
|
35
|
+
root,
|
|
36
|
+
update(next) {
|
|
37
|
+
if (disposed) throw new Error("mountSvg: view already disposed.");
|
|
38
|
+
renderInto(next);
|
|
39
|
+
},
|
|
40
|
+
dispose() {
|
|
41
|
+
if (disposed) return;
|
|
42
|
+
disposed = true;
|
|
43
|
+
root.remove();
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
export { mountSvg };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RenderInput, RenderToStringOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 把 IR / Scene / Figure 渲染成 SVG 字符串(SSR / 构建期)
|
|
4
|
+
* @description 收 `Figure` 时 delegate 给 `figure.toSvgString`。收 IR/Scene 时薄包 `@retikz/render/svg`:`toScene`
|
|
5
|
+
* (ir 缺省走 core fallback measurer、确定性)→ 序列化 → 若给 `width`/`height` 注入根 `<svg>`。零 DOM。
|
|
6
|
+
*/
|
|
7
|
+
export declare const renderToSvgString: (input: RenderInput, options?: RenderToStringOptions) => string;
|
|
8
|
+
//# sourceMappingURL=renderToSvgString.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderToSvgString.d.ts","sourceRoot":"","sources":["../../src/renderToSvgString.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAYlE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,WAAW,EAAE,UAAS,qBAA0B,KAAG,MAI3F,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { isFigure } from "./builder/isFigure.js";
|
|
2
|
+
import { toScene } from "./toScene.js";
|
|
3
|
+
import { renderToSvgString } from "@retikz/render/svg";
|
|
4
|
+
//#region src/renderToSvgString.ts
|
|
5
|
+
/** 默认资源 id 前缀(确定性);多实例同页须经 `options.idPrefix` 显式区分 */
|
|
6
|
+
var DEFAULT_ID_PREFIX = "r";
|
|
7
|
+
/** 把 `width`/`height` 注入到开头的 `<svg` 标签(@retikz/render/svg 只产 viewBox) */
|
|
8
|
+
var injectSize = (svg, width, height) => {
|
|
9
|
+
if (width === void 0 && height === void 0) return svg;
|
|
10
|
+
const attrs = [width !== void 0 ? ` width="${width}"` : "", height !== void 0 ? ` height="${height}"` : ""].join("");
|
|
11
|
+
return svg.replace(/^<svg/, `<svg${attrs}`);
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* 把 IR / Scene / Figure 渲染成 SVG 字符串(SSR / 构建期)
|
|
15
|
+
* @description 收 `Figure` 时 delegate 给 `figure.toSvgString`。收 IR/Scene 时薄包 `@retikz/render/svg`:`toScene`
|
|
16
|
+
* (ir 缺省走 core fallback measurer、确定性)→ 序列化 → 若给 `width`/`height` 注入根 `<svg>`。零 DOM。
|
|
17
|
+
*/
|
|
18
|
+
var renderToSvgString$1 = (input, options = {}) => {
|
|
19
|
+
if (isFigure(input)) return input.toSvgString(options);
|
|
20
|
+
return injectSize(renderToSvgString(toScene(input, options), { idPrefix: options.idPrefix ?? DEFAULT_ID_PREFIX }), options.width, options.height);
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { renderToSvgString$1 as renderToSvgString };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SvgNode } from '@retikz/render/svg';
|
|
2
|
+
/**
|
|
3
|
+
* 把 `SvgNode` 的 attrs / style 写到一个(可复用的)SVG 元素上
|
|
4
|
+
* @description attrs 键是 SVG 真名(呈现属性 kebab / 结构属性规范拼写如 `viewBox`),SVG 命名空间下 `setAttribute`
|
|
5
|
+
* 直用、零名字转换;含 `var()` 的值在 `node.style`(kebab)走 `setProperty`。mountSvg 的 root 复用也用它。
|
|
6
|
+
*/
|
|
7
|
+
export declare const applyAttrs: (el: SVGElement, node: SvgNode) => void;
|
|
8
|
+
/**
|
|
9
|
+
* `SvgNode` descriptor → 真实 SVG DOM(与 react `svgToReact` 同层物化)
|
|
10
|
+
* @description Scene→SvgNode 仍单一留 `@retikz/render/svg`;本函数只把描述树物化成 DOM。仅在**调用时**触 DOM
|
|
11
|
+
* (`document.createElementNS`),模块顶层不碰任何 DOM 全局——守 SSR 导入安全。
|
|
12
|
+
*/
|
|
13
|
+
export declare const svgNodeToDom: (node: SvgNode) => SVGElement;
|
|
14
|
+
//# sourceMappingURL=svgNodeToDom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svgNodeToDom.d.ts","sourceRoot":"","sources":["../../src/svgNodeToDom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAIlD;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,IAAI,UAAU,EAAE,MAAM,OAAO,KAAG,IAS1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,OAAO,KAAG,UAO5C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/svgNodeToDom.ts
|
|
2
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
3
|
+
/**
|
|
4
|
+
* 把 `SvgNode` 的 attrs / style 写到一个(可复用的)SVG 元素上
|
|
5
|
+
* @description attrs 键是 SVG 真名(呈现属性 kebab / 结构属性规范拼写如 `viewBox`),SVG 命名空间下 `setAttribute`
|
|
6
|
+
* 直用、零名字转换;含 `var()` 的值在 `node.style`(kebab)走 `setProperty`。mountSvg 的 root 复用也用它。
|
|
7
|
+
*/
|
|
8
|
+
var applyAttrs = (el, node) => {
|
|
9
|
+
for (const [key, value] of Object.entries(node.attrs)) if (value !== void 0) el.setAttribute(key, String(value));
|
|
10
|
+
if (node.style) {
|
|
11
|
+
for (const [key, value] of Object.entries(node.style)) if (value !== void 0 && value !== null) el.style.setProperty(key, String(value));
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* `SvgNode` descriptor → 真实 SVG DOM(与 react `svgToReact` 同层物化)
|
|
16
|
+
* @description Scene→SvgNode 仍单一留 `@retikz/render/svg`;本函数只把描述树物化成 DOM。仅在**调用时**触 DOM
|
|
17
|
+
* (`document.createElementNS`),模块顶层不碰任何 DOM 全局——守 SSR 导入安全。
|
|
18
|
+
*/
|
|
19
|
+
var svgNodeToDom = (node) => {
|
|
20
|
+
const el = document.createElementNS(SVG_NS, node.tag);
|
|
21
|
+
applyAttrs(el, node);
|
|
22
|
+
for (const child of node.children ?? []) el.appendChild(typeof child === "string" ? document.createTextNode(child) : svgNodeToDom(child));
|
|
23
|
+
return el;
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { applyAttrs, svgNodeToDom };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IR, Scene } from '@retikz/core';
|
|
2
|
+
import { CommonOptions } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* 入参归一成 `Scene`
|
|
5
|
+
* @description 已是 `Scene`(有 `primitives`)直接用;否则当 `IR` 经 `compileToScene` 编译。剥掉 render-only 键
|
|
6
|
+
* (`idPrefix`/`width`/`height`),其余即 core `CompileOptions` 原样透传(`measureText` 缺省时 core 回退
|
|
7
|
+
* `fallbackMeasurer`,Node 下确定可跑)。注:调用方须先把 `Figure` 解成 `ir`,此处只认 `IR | Scene`。
|
|
8
|
+
*/
|
|
9
|
+
export declare const toScene: (input: Scene | IR, options: CommonOptions) => Scene;
|
|
10
|
+
//# sourceMappingURL=toScene.d.ts.map
|