@retikz/core 0.3.0-alpha.2 → 0.3.0-alpha.4

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.
Files changed (214) hide show
  1. package/README.md +41 -41
  2. package/dist/es/compile/anchor-cache.d.ts +5 -3
  3. package/dist/es/compile/anchor-cache.d.ts.map +1 -1
  4. package/dist/es/compile/anchor-cache.js +14 -10
  5. package/dist/es/compile/boundary.d.ts +19 -0
  6. package/dist/es/compile/boundary.d.ts.map +1 -0
  7. package/dist/es/compile/boundary.js +64 -0
  8. package/dist/es/compile/compile.d.ts.map +1 -1
  9. package/dist/es/compile/compile.js +15 -2
  10. package/dist/es/compile/node.d.ts +24 -8
  11. package/dist/es/compile/node.d.ts.map +1 -1
  12. package/dist/es/compile/node.js +106 -17
  13. package/dist/es/compile/path/anchor.d.ts.map +1 -1
  14. package/dist/es/compile/path/anchor.js +7 -6
  15. package/dist/es/compile/path/index.d.ts.map +1 -1
  16. package/dist/es/compile/path/index.js +7 -3
  17. package/dist/es/compile/path/relative.js +1 -1
  18. package/dist/es/compile/scope.d.ts.map +1 -1
  19. package/dist/es/compile/scope.js +2 -1
  20. package/dist/es/geometry/arc.d.ts +14 -0
  21. package/dist/es/geometry/arc.d.ts.map +1 -1
  22. package/dist/es/geometry/arc.js +65 -9
  23. package/dist/es/geometry/index.d.ts +1 -0
  24. package/dist/es/geometry/index.d.ts.map +1 -1
  25. package/dist/es/geometry/rect.d.ts +2 -2
  26. package/dist/es/geometry/rect.d.ts.map +1 -1
  27. package/dist/es/geometry/rect.js +3 -3
  28. package/dist/es/geometry/roundedContour.d.ts +88 -0
  29. package/dist/es/geometry/roundedContour.d.ts.map +1 -0
  30. package/dist/es/geometry/roundedContour.js +417 -0
  31. package/dist/es/index.d.ts +6 -5
  32. package/dist/es/index.d.ts.map +1 -1
  33. package/dist/es/index.js +9 -6
  34. package/dist/es/ir/boundary.d.ts +25 -0
  35. package/dist/es/ir/boundary.d.ts.map +1 -0
  36. package/dist/es/ir/boundary.js +14 -0
  37. package/dist/es/ir/index.d.ts +2 -0
  38. package/dist/es/ir/index.d.ts.map +1 -1
  39. package/dist/es/ir/node.d.ts +43 -7
  40. package/dist/es/ir/node.d.ts.map +1 -1
  41. package/dist/es/ir/node.js +8 -3
  42. package/dist/es/ir/path/arrow.d.ts +12 -12
  43. package/dist/es/ir/path/path.d.ts +493 -147
  44. package/dist/es/ir/path/path.d.ts.map +1 -1
  45. package/dist/es/ir/path/path.js +3 -0
  46. package/dist/es/ir/path/step.d.ts +674 -154
  47. package/dist/es/ir/path/step.d.ts.map +1 -1
  48. package/dist/es/ir/path/step.js +2 -2
  49. package/dist/es/ir/path/target.d.ts +43 -8
  50. package/dist/es/ir/path/target.d.ts.map +1 -1
  51. package/dist/es/ir/path/target.js +4 -5
  52. package/dist/es/ir/scope.d.ts +851 -234
  53. package/dist/es/ir/scope.d.ts.map +1 -1
  54. package/dist/es/ir/scope.js +6 -2
  55. package/dist/es/ir/shape.d.ts +14 -0
  56. package/dist/es/ir/shape.d.ts.map +1 -0
  57. package/dist/es/ir/shape.js +9 -0
  58. package/dist/es/parsers/parseNodeTarget.d.ts.map +1 -1
  59. package/dist/es/parsers/parseNodeTarget.js +4 -2
  60. package/dist/es/primitive/ellipse.d.ts +5 -0
  61. package/dist/es/primitive/ellipse.d.ts.map +1 -1
  62. package/dist/es/primitive/group.d.ts +5 -0
  63. package/dist/es/primitive/group.d.ts.map +1 -1
  64. package/dist/es/primitive/path.d.ts +5 -0
  65. package/dist/es/primitive/path.d.ts.map +1 -1
  66. package/dist/es/primitive/rect.d.ts +5 -0
  67. package/dist/es/primitive/rect.d.ts.map +1 -1
  68. package/dist/es/primitive/text.d.ts +5 -0
  69. package/dist/es/primitive/text.d.ts.map +1 -1
  70. package/dist/es/shapes/_contour.d.ts +19 -0
  71. package/dist/es/shapes/_contour.d.ts.map +1 -0
  72. package/dist/es/shapes/_contour.js +60 -0
  73. package/dist/es/shapes/_shared.d.ts +54 -0
  74. package/dist/es/shapes/_shared.d.ts.map +1 -1
  75. package/dist/es/shapes/_shared.js +68 -1
  76. package/dist/es/shapes/arc.d.ts +8 -0
  77. package/dist/es/shapes/arc.d.ts.map +1 -0
  78. package/dist/es/shapes/arc.js +104 -0
  79. package/dist/es/shapes/define.d.ts +13 -0
  80. package/dist/es/shapes/define.d.ts.map +1 -0
  81. package/dist/es/shapes/define.js +13 -0
  82. package/dist/es/shapes/ellipse.d.ts +5 -4
  83. package/dist/es/shapes/ellipse.d.ts.map +1 -1
  84. package/dist/es/shapes/ellipse.js +15 -7
  85. package/dist/es/shapes/index.d.ts +9 -6
  86. package/dist/es/shapes/index.d.ts.map +1 -1
  87. package/dist/es/shapes/index.js +10 -5
  88. package/dist/es/shapes/polygon.d.ts +13 -0
  89. package/dist/es/shapes/polygon.d.ts.map +1 -0
  90. package/dist/es/shapes/polygon.js +104 -0
  91. package/dist/es/shapes/rectangle.d.ts +7 -5
  92. package/dist/es/shapes/rectangle.d.ts.map +1 -1
  93. package/dist/es/shapes/rectangle.js +37 -8
  94. package/dist/es/shapes/sector.d.ts +9 -0
  95. package/dist/es/shapes/sector.d.ts.map +1 -0
  96. package/dist/es/shapes/sector.js +143 -0
  97. package/dist/es/shapes/star.d.ts +15 -0
  98. package/dist/es/shapes/star.d.ts.map +1 -0
  99. package/dist/es/shapes/star.js +113 -0
  100. package/dist/es/shapes/types.d.ts +47 -14
  101. package/dist/es/shapes/types.d.ts.map +1 -1
  102. package/dist/lib/compile/anchor-cache.cjs +14 -10
  103. package/dist/lib/compile/anchor-cache.d.ts +5 -3
  104. package/dist/lib/compile/anchor-cache.d.ts.map +1 -1
  105. package/dist/lib/compile/boundary.cjs +65 -0
  106. package/dist/lib/compile/boundary.d.ts +19 -0
  107. package/dist/lib/compile/boundary.d.ts.map +1 -0
  108. package/dist/lib/compile/compile.cjs +15 -2
  109. package/dist/lib/compile/compile.d.ts.map +1 -1
  110. package/dist/lib/compile/node.cjs +106 -17
  111. package/dist/lib/compile/node.d.ts +24 -8
  112. package/dist/lib/compile/node.d.ts.map +1 -1
  113. package/dist/lib/compile/path/anchor.cjs +7 -6
  114. package/dist/lib/compile/path/anchor.d.ts.map +1 -1
  115. package/dist/lib/compile/path/index.cjs +7 -3
  116. package/dist/lib/compile/path/index.d.ts.map +1 -1
  117. package/dist/lib/compile/path/relative.cjs +1 -1
  118. package/dist/lib/compile/scope.cjs +2 -1
  119. package/dist/lib/compile/scope.d.ts.map +1 -1
  120. package/dist/lib/geometry/arc.cjs +66 -8
  121. package/dist/lib/geometry/arc.d.ts +14 -0
  122. package/dist/lib/geometry/arc.d.ts.map +1 -1
  123. package/dist/lib/geometry/index.d.ts +1 -0
  124. package/dist/lib/geometry/index.d.ts.map +1 -1
  125. package/dist/lib/geometry/rect.cjs +3 -3
  126. package/dist/lib/geometry/rect.d.ts +2 -2
  127. package/dist/lib/geometry/rect.d.ts.map +1 -1
  128. package/dist/lib/geometry/roundedContour.cjs +418 -0
  129. package/dist/lib/geometry/roundedContour.d.ts +88 -0
  130. package/dist/lib/geometry/roundedContour.d.ts.map +1 -0
  131. package/dist/lib/index.cjs +14 -7
  132. package/dist/lib/index.d.ts +6 -5
  133. package/dist/lib/index.d.ts.map +1 -1
  134. package/dist/lib/ir/boundary.cjs +15 -0
  135. package/dist/lib/ir/boundary.d.ts +25 -0
  136. package/dist/lib/ir/boundary.d.ts.map +1 -0
  137. package/dist/lib/ir/index.d.ts +2 -0
  138. package/dist/lib/ir/index.d.ts.map +1 -1
  139. package/dist/lib/ir/node.cjs +8 -3
  140. package/dist/lib/ir/node.d.ts +43 -7
  141. package/dist/lib/ir/node.d.ts.map +1 -1
  142. package/dist/lib/ir/path/arrow.d.ts +12 -12
  143. package/dist/lib/ir/path/path.cjs +3 -0
  144. package/dist/lib/ir/path/path.d.ts +493 -147
  145. package/dist/lib/ir/path/path.d.ts.map +1 -1
  146. package/dist/lib/ir/path/step.cjs +2 -2
  147. package/dist/lib/ir/path/step.d.ts +674 -154
  148. package/dist/lib/ir/path/step.d.ts.map +1 -1
  149. package/dist/lib/ir/path/target.cjs +4 -5
  150. package/dist/lib/ir/path/target.d.ts +43 -8
  151. package/dist/lib/ir/path/target.d.ts.map +1 -1
  152. package/dist/lib/ir/scope.cjs +6 -2
  153. package/dist/lib/ir/scope.d.ts +851 -234
  154. package/dist/lib/ir/scope.d.ts.map +1 -1
  155. package/dist/lib/ir/shape.cjs +9 -0
  156. package/dist/lib/ir/shape.d.ts +14 -0
  157. package/dist/lib/ir/shape.d.ts.map +1 -0
  158. package/dist/lib/parsers/parseNodeTarget.cjs +4 -2
  159. package/dist/lib/parsers/parseNodeTarget.d.ts.map +1 -1
  160. package/dist/lib/primitive/ellipse.d.ts +5 -0
  161. package/dist/lib/primitive/ellipse.d.ts.map +1 -1
  162. package/dist/lib/primitive/group.d.ts +5 -0
  163. package/dist/lib/primitive/group.d.ts.map +1 -1
  164. package/dist/lib/primitive/path.d.ts +5 -0
  165. package/dist/lib/primitive/path.d.ts.map +1 -1
  166. package/dist/lib/primitive/rect.d.ts +5 -0
  167. package/dist/lib/primitive/rect.d.ts.map +1 -1
  168. package/dist/lib/primitive/text.d.ts +5 -0
  169. package/dist/lib/primitive/text.d.ts.map +1 -1
  170. package/dist/lib/shapes/_contour.cjs +61 -0
  171. package/dist/lib/shapes/_contour.d.ts +19 -0
  172. package/dist/lib/shapes/_contour.d.ts.map +1 -0
  173. package/dist/lib/shapes/_shared.cjs +70 -0
  174. package/dist/lib/shapes/_shared.d.ts +54 -0
  175. package/dist/lib/shapes/_shared.d.ts.map +1 -1
  176. package/dist/lib/shapes/arc.cjs +104 -0
  177. package/dist/lib/shapes/arc.d.ts +8 -0
  178. package/dist/lib/shapes/arc.d.ts.map +1 -0
  179. package/dist/lib/shapes/define.cjs +13 -0
  180. package/dist/lib/shapes/define.d.ts +13 -0
  181. package/dist/lib/shapes/define.d.ts.map +1 -0
  182. package/dist/lib/shapes/ellipse.cjs +15 -7
  183. package/dist/lib/shapes/ellipse.d.ts +5 -4
  184. package/dist/lib/shapes/ellipse.d.ts.map +1 -1
  185. package/dist/lib/shapes/index.cjs +12 -6
  186. package/dist/lib/shapes/index.d.ts +9 -6
  187. package/dist/lib/shapes/index.d.ts.map +1 -1
  188. package/dist/lib/shapes/polygon.cjs +104 -0
  189. package/dist/lib/shapes/polygon.d.ts +13 -0
  190. package/dist/lib/shapes/polygon.d.ts.map +1 -0
  191. package/dist/lib/shapes/rectangle.cjs +37 -8
  192. package/dist/lib/shapes/rectangle.d.ts +7 -5
  193. package/dist/lib/shapes/rectangle.d.ts.map +1 -1
  194. package/dist/lib/shapes/sector.cjs +143 -0
  195. package/dist/lib/shapes/sector.d.ts +9 -0
  196. package/dist/lib/shapes/sector.d.ts.map +1 -0
  197. package/dist/lib/shapes/star.cjs +113 -0
  198. package/dist/lib/shapes/star.d.ts +15 -0
  199. package/dist/lib/shapes/star.d.ts.map +1 -0
  200. package/dist/lib/shapes/types.d.ts +47 -14
  201. package/dist/lib/shapes/types.d.ts.map +1 -1
  202. package/package.json +2 -2
  203. package/dist/es/shapes/circle.d.ts +0 -8
  204. package/dist/es/shapes/circle.d.ts.map +0 -1
  205. package/dist/es/shapes/circle.js +0 -34
  206. package/dist/es/shapes/diamond.d.ts +0 -8
  207. package/dist/es/shapes/diamond.d.ts.map +0 -1
  208. package/dist/es/shapes/diamond.js +0 -66
  209. package/dist/lib/shapes/circle.cjs +0 -34
  210. package/dist/lib/shapes/circle.d.ts +0 -8
  211. package/dist/lib/shapes/circle.d.ts.map +0 -1
  212. package/dist/lib/shapes/diamond.cjs +0 -66
  213. package/dist/lib/shapes/diamond.d.ts +0 -8
  214. package/dist/lib/shapes/diamond.d.ts.map +0 -1
@@ -0,0 +1,113 @@
1
+ import { localToWorld } from "../geometry/_transform.js";
2
+ import { defineShape } from "./define.js";
3
+ import { boundaryFromContour, contourCommands } from "../geometry/roundedContour.js";
4
+ import { contourToPathCommands, verticesToSegments } from "./_contour.js";
5
+ import { z } from "zod";
6
+ //#region src/shapes/star.ts
7
+ var DEG_TO_RAD = Math.PI / 180;
8
+ /**
9
+ * 计算 star 单一真源几何
10
+ * @description 局部系以中心为原点:顶点 k 角 = (rotate ?? 0) + k·(180/points) − 90,半径偶 outer / 奇 inner,
11
+ * point = [r·cosθ, r·sinθ](0°=+x,90°=+y screen y-down)。−90 基准使默认第一尖角朝上(−y)。
12
+ * AABB 半轴 = 各顶点 |x| / |y| 的最大值(对称 → 中心即原点)。
13
+ */
14
+ var starGeometry = (params) => {
15
+ const { points, innerRadius, outerRadius } = params;
16
+ const rotate = params.rotate ?? 0;
17
+ const step = 180 / points;
18
+ const vertices = [];
19
+ let maxAbsX = 0;
20
+ let maxAbsY = 0;
21
+ for (let k = 0; k < 2 * points; k++) {
22
+ const angle = (rotate + k * step - 90) * DEG_TO_RAD;
23
+ const radius = k % 2 === 0 ? outerRadius : innerRadius;
24
+ const x = radius * Math.cos(angle);
25
+ const y = radius * Math.sin(angle);
26
+ vertices.push([x, y]);
27
+ if (Math.abs(x) > maxAbsX) maxAbsX = Math.abs(x);
28
+ if (Math.abs(y) > maxAbsY) maxAbsY = Math.abs(y);
29
+ }
30
+ return {
31
+ vertices,
32
+ aabbHalfAxes: {
33
+ halfWidth: maxAbsX,
34
+ halfHeight: maxAbsY
35
+ }
36
+ };
37
+ };
38
+ /** 局部顶点(中心为原点)→ 世界系(经 rect 旋转 / 平移) */
39
+ var toWorld = (rect, local) => localToWorld(rect, local);
40
+ /**
41
+ * 世界系顶点环(局部 2×points 顶点逐个经 rect 投世界)
42
+ * @description emit 收轴对齐 rect(rotate=0)、boundaryPoint 收带 rotate 的 rect,二者共用此构造;
43
+ * 绕向 = starGeometry 顶点顺序(偶尖 / 奇凹交替),供 verticesToSegments → rounded-contour 模块倒角。
44
+ */
45
+ var worldVertices = (rect, geo) => geo.vertices.map((v) => toWorld(rect, v));
46
+ /**
47
+ * star 注册项:星形(外径尖角 / 内径凹角交替的 2×points 顶点闭合多边形)
48
+ * @description params-半径驱动的纯几何形状(像 sector,尺寸由 outerRadius 定、忽略文本内框):四何函数共用
49
+ * `starGeometry`(单一真源)。circumscribe 返回含全部尖角的精确 AABB 半轴(随 rotate 变,不随 cornerRadius 变);
50
+ * 星形关于中心对称 → AABB 中心 = 星形中心 = node position,无需 circumscribeOffset。emit / boundaryPoint 把
51
+ * `2×points` 顶点环构造成折线段,委托 rounded-contour 模块:cornerRadius 省略 / 0 出原尖角轮廓、>0 在每个顶点
52
+ * 插逐角夹紧的 fillet 弧——凸尖与凹角(notch)由模块按接缝转向叉积统一处理(凹角弧 sweep 反向、圆心在凸侧),
53
+ * emit 与 boundaryPoint 共用同一份 fillet 结果。emit 收轴对齐 rect(旋转由外层 group 施加)、boundaryPoint
54
+ * 收带 rotate 的 rect 且 rayOrigin = 星形几何中心(关于中心对称,AABB 中心 = 形心 = node position)。
55
+ * anchor 含 center / tip-N(第 N 尖角)/ notch-N(第 N 凹角)——恒在原尖角 / 凹角逻辑顶点,不随 cornerRadius 移;
56
+ * self-rotate(params.rotate)与 Node.rotate 叠加。scaleParams 只缩 inner/outerRadius / cornerRadius(长度)、
57
+ * 不缩 points(计数)/ rotate(角度)。
58
+ */
59
+ var star = defineShape({
60
+ paramsSchema: z.strictObject({
61
+ points: z.number().int().min(3).describe("Number of star points (>= 3)."),
62
+ innerRadius: z.number().finite().positive().describe("Inner (notch) radius in user units."),
63
+ outerRadius: z.number().finite().positive().describe("Outer (tip) radius in user units; must be > innerRadius."),
64
+ rotate: z.number().finite().optional().describe("Shape self-rotation in degrees; default 0 = first tip points up (screen -y / top); positive rotates clockwise (screen). Composes with Node.rotate."),
65
+ cornerRadius: z.number().finite().nonnegative().optional().describe("Corner radius in user units; 0 / omitted = sharp corners. Clamped per corner to the largest non-self-intersecting fillet.")
66
+ }).refine((p) => p.outerRadius > p.innerRadius, { message: "outerRadius must be greater than innerRadius" }),
67
+ circumscribe: (_hw, _hh, params) => starGeometry(params).aabbHalfAxes,
68
+ boundaryPoint: (rect, toward, params) => {
69
+ const segments = verticesToSegments(worldVertices(rect, starGeometry(params)));
70
+ const center = toWorld(rect, [0, 0]);
71
+ return boundaryFromContour(segments, params.cornerRadius, center, toward) ?? center;
72
+ },
73
+ anchor: (rect, name, params) => {
74
+ const geo = starGeometry(params);
75
+ if (name === "center") return toWorld(rect, [0, 0]);
76
+ const tip = /^tip-(\d+)$/.exec(name);
77
+ if (tip) {
78
+ const index = 2 * Number(tip[1]);
79
+ if (index >= geo.vertices.length) return void 0;
80
+ return toWorld(rect, geo.vertices[index]);
81
+ }
82
+ const notch = /^notch-(\d+)$/.exec(name);
83
+ if (notch) {
84
+ const index = 2 * Number(notch[1]) + 1;
85
+ if (index >= geo.vertices.length) return void 0;
86
+ return toWorld(rect, geo.vertices[index]);
87
+ }
88
+ },
89
+ *emit(rect, style, round, params) {
90
+ yield {
91
+ type: "path",
92
+ commands: contourToPathCommands(contourCommands(verticesToSegments(worldVertices(rect, starGeometry(params))), params.cornerRadius), round),
93
+ fill: style.fill ?? "transparent",
94
+ fillOpacity: style.fillOpacity,
95
+ stroke: style.stroke ?? "currentColor",
96
+ strokeOpacity: style.strokeOpacity,
97
+ strokeWidth: style.strokeWidth ?? 1,
98
+ dashPattern: style.dashPattern,
99
+ opacity: style.opacity
100
+ };
101
+ },
102
+ scaleParams: (params, sx, sy) => {
103
+ const factor = Math.sqrt(sx * sy);
104
+ return {
105
+ ...params,
106
+ innerRadius: params.innerRadius * factor,
107
+ outerRadius: params.outerRadius * factor,
108
+ ...params.cornerRadius === void 0 ? {} : { cornerRadius: params.cornerRadius * factor }
109
+ };
110
+ }
111
+ });
112
+ //#endregion
113
+ export { star };
@@ -1,5 +1,7 @@
1
+ import { z } from 'zod';
1
2
  import { Position } from '../geometry/point';
2
3
  import { Rect } from '../geometry/rect';
4
+ import { IRJsonObject } from '../ir/json';
3
5
  import { PaintValue, ScenePrimitive } from '../primitive';
4
6
  /**
5
7
  * emit 需要的视觉样式子集
@@ -13,38 +15,69 @@ export type ShapeStyle = {
13
15
  strokeOpacity?: number;
14
16
  strokeWidth?: number;
15
17
  dashPattern?: Array<number>;
16
- roundedCorners?: number;
18
+ cornerRadius?: number;
17
19
  opacity?: number;
18
20
  };
19
21
  /**
20
- * 一个 shape 的可注册定义:外接 / 边界 / anchor / emit 四件事
21
- * @description plain object(factory 友好:`createPolygonShape(6)` 这类普通函数返回它即可);含函数、
22
- * **不进 IR**,走 `CompileOptions.shapes` 运行时注入。内置 4 shape 也是注册项(无内置特权)。
22
+ * 一个 shape 的参数化可注册定义(定义点 typed 形态)
23
+ * @description plain object(factory 友好:`createPolygonShape(6)` 这类普通函数返回它即可);含函数与
24
+ * `paramsSchema`,**不进 IR**,走 `CompileOptions.shapes` 运行时注入。内置 4 shape 也是注册项(无内置特权)。
25
+ * 每个计算函数末位收 per-instance `params`(类型由 `paramsSchema.parse` 在编译期保证),无参形状用
26
+ * `z.strictObject({})` 并忽略 `params`。
27
+ *
28
+ * - `paramsSchema`:类型约束输出 JSON-safe(`z.ZodType<TParams>`)。这是类型层约束,不是运行时唯一保证——
29
+ * compile 在 `paramsSchema.parse(params)` 之后还会对结果跑一次 `JsonObjectSchema.parse`,拦下宽松
30
+ * schema 放过的非 JSON 输出(function / undefined 等)。
23
31
  *
24
32
  * 坐标语义两套,第三方最易写错:
25
33
  * - `boundaryPoint` / `anchor` 收**带 `rotate` 的 Rect**——用 re-export 的 `worldToLocal` / `localToWorld` 写局部系几何。
26
34
  * - `emit` 收**轴对齐 Rect(rotate=0)**——旋转由编译器在外层 `GroupPrim` 统一施加。
27
35
  */
28
- export type ShapeDefinition = {
36
+ export type ShapeDefinitionInput<TParams extends IRJsonObject> = {
37
+ /** params 的 zod schema;类型约束输出 JSON-safe(运行时双 parse 才是真正护栏,见编译期桥接) */
38
+ paramsSchema: z.ZodType<TParams>;
29
39
  /**
30
- * 外接:内容半轴(text + padding)→ 外接框半轴。
31
- * @description rectangle: identity;circle: √(hw²+hh²) 两轴相等;ellipse: ×√2;diamond: ×2。
40
+ * 外接:内容半轴(text + padding)+ params → 外接框半轴。
41
+ * @description 必返回**包含完整 shape 的精确 AABB 半轴**(compile 的 viewBox / scope bbox 只累积该 AABB
42
+ * 四角)。rectangle: identity;circle: √(hw²+hh²) 两轴相等;ellipse: ×√2;diamond: ×2;参数化形状据 params 算。
32
43
  */
33
- circumscribe: (innerHalfWidth: number, innerHalfHeight: number) => {
44
+ circumscribe: (innerHalfWidth: number, innerHalfHeight: number, params: TParams) => {
34
45
  halfWidth: number;
35
46
  halfHeight: number;
36
47
  };
37
- /** 中心 → toward 射线 ∩ 边界(rect 带 rotate)。 */
38
- boundaryPoint: (rect: Rect, toward: Position) => Position;
48
+ /**
49
+ * AABB 中心相对 node `position` 的偏移(可选;缺省 `[0, 0]` = AABB 中心即 position)。
50
+ * @description 多数 shape 的视觉 AABB 以 position 为中心(rectangle / ellipse / diamond);但 sector 等
51
+ * 形状的语义锚点(圆心 apex)才是 position,其外接 AABB 中心偏在一侧——此 hook 让 compile 把
52
+ * `rect.center` 放到 `position + offset`,使 bbox / viewBox 罩住完整形状、anchor 以 AABB 中心 rect 计算时
53
+ * apex 落回 position。返回**未旋转**局部偏移(compile 在施加 node rotate 前用于定位 rect 中心)。
54
+ */
55
+ circumscribeOffset?: (params: TParams) => Position;
56
+ /** 中心 → toward 射线 ∩ 边界(rect 带 rotate);params 喂参数化边界。 */
57
+ boundaryPoint: (rect: Rect, toward: Position, params: TParams) => Position;
39
58
  /** 命名 anchor 世界坐标;shape 不认识的名字返回 `undefined`(调用方据此抛清晰错误)。 */
40
- anchor: (rect: Rect, name: string) => Position | undefined;
59
+ anchor: (rect: Rect, name: string, params: TParams) => Position | undefined;
41
60
  /**
42
61
  * 边上比例点:side 真实边界从约定起点起 t∈[0,1] 处(轴对齐空间求出后由 layout 投回世界系)。
43
62
  * @description 可选——内置 4 shape 必实现,不实现的 shape 收到 `{ side, t }` 时编译期(resolveEdgePoint)抛明确错。
44
63
  * 与 `anchor` 同坐标语义:收**带 rotate 的 Rect**,自行用 worldToLocal/localToWorld 处理旋转。
45
64
  */
46
- edgePoint?: (rect: Rect, side: 'north' | 'south' | 'east' | 'west', t: number) => Position;
47
- /** 视觉 primitive,**轴对齐空间**(rotate 由编译器外层 GroupPrim 统一施加)。 */
48
- emit: (rect: Rect, style: ShapeStyle, round: (n: number) => number) => Iterable<ScenePrimitive>;
65
+ edgePoint?: (rect: Rect, side: 'north' | 'south' | 'east' | 'west', t: number, params: TParams) => Position;
66
+ /** 视觉 primitive,**轴对齐空间**(rotate 由编译器外层 GroupPrim 统一施加);params 喂参数化几何。 */
67
+ emit: (rect: Rect, style: ShapeStyle, round: (n: number) => number, params: TParams) => Iterable<ScenePrimitive>;
68
+ /**
69
+ * node scale 作用于 params 的方式(可选)。
70
+ * @description 给定原始 params 与水平 / 垂直缩放因子 `sx` / `sy`,返回缩放后的 params。
71
+ * 缺省时编译器沿用默认行为——深度缩放 params 里所有数值叶子(uniform 几何均值因子)。
72
+ * 适用于 params 含「非长度」语义字段(如角度)的形状:sector / arc 只缩半径、不缩角度,
73
+ * 通过本 hook 把 startAngle / endAngle 排除在缩放外。不缩放任何 params 的形状不必实现。
74
+ */
75
+ scaleParams?: (params: TParams, sx: number, sy: number) => TParams;
49
76
  };
77
+ /**
78
+ * shape 定义的擦除形态:registry 存这个
79
+ * @description 所有函数收 `IRJsonObject`(实际类型由 `paramsSchema.parse` 在编译期保证);registry 同构
80
+ * `Record<string, ShapeDefinition>`、不泛型化(避免逆变 / 落 any)。定义点用 `defineShape<TParams>` 拿类型安全。
81
+ */
82
+ export type ShapeDefinition = ShapeDefinitionInput<IRJsonObject>;
50
83
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/shapes/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,YAAY,EAAE,CACZ,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,KACpB;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,0CAA0C;IAC1C,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,KAAK,QAAQ,CAAC;IAC1D,6DAA6D;IAC7D,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,KAAK,QAAQ,GAAG,SAAS,CAAC;IAC3D;;;;OAIG;IACH,SAAS,CAAC,EAAE,CACV,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,EACzC,CAAC,EAAE,MAAM,KACN,QAAQ,CAAC;IACd,4DAA4D;IAC5D,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,KAAK,QAAQ,CAAC,cAAc,CAAC,CAAC;CACjG,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/shapes/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,oBAAoB,CAAC,OAAO,SAAS,YAAY,IAAI;IAC/D,qEAAqE;IACrE,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC;;;;OAIG;IACH,YAAY,EAAE,CACZ,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,OAAO,KACZ;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,QAAQ,CAAC;IACnD,wDAAwD;IACxD,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,KAAK,QAAQ,CAAC;IAC3E,6DAA6D;IAC7D,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,QAAQ,GAAG,SAAS,CAAC;IAC5E;;;;OAIG;IACH,SAAS,CAAC,EAAE,CACV,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,EACzC,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,OAAO,KACZ,QAAQ,CAAC;IACd,0EAA0E;IAC1E,IAAI,EAAE,CACJ,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,EAC5B,MAAM,EAAE,OAAO,KACZ,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC9B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;CACpE,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC"}
@@ -1,3 +1,4 @@
1
+ const require_boundary = require("./boundary.cjs");
1
2
  const require_node = require("./node.cjs");
2
3
  //#region src/compile/anchor-cache.ts
3
4
  /**
@@ -9,32 +10,35 @@ var cache = /* @__PURE__ */ new WeakMap();
9
10
  var ANGLE_RE = /^-?\d+(\.\d+)?$/;
10
11
  /**
11
12
  * 把 anchorName 解析到对应 shape 的 anchor / boundaryPoint 上
12
- * @description 数字字符串走 angleBoundaryOf;其余按 RectAnchor 走 anchorOf
13
+ * @description 数字字符串走 angleBoundaryOf;其余按 RectAnchor 走 anchorOf;boundary 透传给两者
13
14
  */
14
- var computeAnchor = (layout, anchorName) => {
15
- if (ANGLE_RE.test(anchorName)) return positionToIR(require_node.angleBoundaryOf(layout, Number(anchorName)));
16
- return positionToIR(require_node.anchorOf(layout, anchorName));
15
+ var computeAnchor = (layout, anchorName, boundary) => {
16
+ if (ANGLE_RE.test(anchorName)) return positionToIR(require_node.angleBoundaryOf(layout, Number(anchorName), boundary));
17
+ return positionToIR(require_node.anchorOf(layout, anchorName, boundary));
17
18
  };
18
19
  /** geometry Position(含 readonly 形态)转 IRPosition 元组(IRPosition === [number, number]) */
19
20
  var positionToIR = (p) => [p[0], p[1]];
20
21
  /**
21
22
  * 取节点 anchor 的全局坐标,带 per-layout 缓存
22
23
  * @description name 接受 RectAnchor 关键字(如 `'north'` / `'south-west'`)或数字角度字符串(如 `'30'` / `'-45'`);
23
- * 同一 (layout, name) 第二次起返回首调用结果的**同一引用**——上游可用 `===` 判定 cache 命中
24
+ * boundary 指定连接面(默认 `'shape'`,即节点自身视觉轮廓);不同 boundary 产生独立缓存条目,互不串扰;
25
+ * 同一 (layout, name, boundary) 组合第二次起返回首调用结果的**同一引用**——上游可用 `===` 判定 cache 命中
24
26
  * @param layout 已 Pass 1 完成的 NodeLayout(rect 已是全局坐标)
25
27
  * @param anchorName 关键字或数字角度字符串
28
+ * @param boundary 连接面,缺省为 `'shape'`(视觉轮廓)
26
29
  * @returns 全局坐标系下的 IRPosition `[x, y]`
27
30
  */
28
- var resolveAnchor = (layout, anchorName) => {
31
+ var resolveAnchor = (layout, anchorName, boundary = "shape") => {
29
32
  let layoutCache = cache.get(layout);
30
33
  if (!layoutCache) {
31
34
  layoutCache = /* @__PURE__ */ new Map();
32
35
  cache.set(layout, layoutCache);
33
36
  }
34
- const cached = layoutCache.get(anchorName);
37
+ const key = `${require_boundary.boundaryKey(boundary)} ${anchorName}`;
38
+ const cached = layoutCache.get(key);
35
39
  if (cached !== void 0) return cached;
36
- const result = computeAnchor(layout, anchorName);
37
- layoutCache.set(anchorName, result);
40
+ const result = computeAnchor(layout, anchorName, boundary);
41
+ layoutCache.set(key, result);
38
42
  return result;
39
43
  };
40
44
  /**
@@ -57,7 +61,7 @@ var resolveEdgePoint = (layout, side, t) => {
57
61
  const key = `${side}:${t}`;
58
62
  const cached = layoutCache.get(key);
59
63
  if (cached !== void 0) return cached;
60
- const result = positionToIR(edgePoint(layout.rect, side, t));
64
+ const result = positionToIR(edgePoint(layout.rect, side, t, layout.shapeParams ?? {}));
61
65
  layoutCache.set(key, result);
62
66
  return result;
63
67
  };
@@ -1,15 +1,17 @@
1
1
  import { Side } from '../geometry/_edge';
2
- import { IRPosition } from '../ir';
2
+ import { IRBoundary, IRPosition } from '../ir';
3
3
  import { NodeLayout } from './node';
4
4
  /**
5
5
  * 取节点 anchor 的全局坐标,带 per-layout 缓存
6
6
  * @description name 接受 RectAnchor 关键字(如 `'north'` / `'south-west'`)或数字角度字符串(如 `'30'` / `'-45'`);
7
- * 同一 (layout, name) 第二次起返回首调用结果的**同一引用**——上游可用 `===` 判定 cache 命中
7
+ * boundary 指定连接面(默认 `'shape'`,即节点自身视觉轮廓);不同 boundary 产生独立缓存条目,互不串扰;
8
+ * 同一 (layout, name, boundary) 组合第二次起返回首调用结果的**同一引用**——上游可用 `===` 判定 cache 命中
8
9
  * @param layout 已 Pass 1 完成的 NodeLayout(rect 已是全局坐标)
9
10
  * @param anchorName 关键字或数字角度字符串
11
+ * @param boundary 连接面,缺省为 `'shape'`(视觉轮廓)
10
12
  * @returns 全局坐标系下的 IRPosition `[x, y]`
11
13
  */
12
- export declare const resolveAnchor: (layout: NodeLayout, anchorName: string) => IRPosition;
14
+ export declare const resolveAnchor: (layout: NodeLayout, anchorName: string, boundary?: IRBoundary | undefined) => IRPosition;
13
15
  /**
14
16
  * 取节点边上比例点 `{ side, t }` 的全局坐标,带 per-layout 缓存
15
17
  * @description 走 `layout.shapeDef.edgePoint`——shape 未实现(如自定义 shape)抛"does not support side anchors";
@@ -1 +1 @@
1
- {"version":3,"file":"anchor-cache.d.ts","sourceRoot":"","sources":["../../../src/compile/anchor-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AA4BzC;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,UAAU,EAClB,YAAY,MAAM,KACjB,UAWF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,UAAU,EAClB,MAAM,IAAI,EACV,GAAG,MAAM,KACR,UAuBF,CAAC"}
1
+ {"version":3,"file":"anchor-cache.d.ts","sourceRoot":"","sources":["../../../src/compile/anchor-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAiCzC;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,UAAU,EAClB,YAAY,MAAM,EAClB,WAAU,UAAU,GAAG,SAAmB,KACzC,UAYF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,UAAU,EAClB,MAAM,IAAI,EACV,GAAG,MAAM,KACR,UAuBF,CAAC"}
@@ -0,0 +1,65 @@
1
+ const require_ellipse = require("../shapes/ellipse.cjs");
2
+ const require_rectangle = require("../shapes/rectangle.cjs");
3
+ //#region src/compile/boundary.ts
4
+ /** 保留字:连接面 = 节点自身视觉形状 */
5
+ var SELF = "shape";
6
+ /** 保留字:真圆(半径 = AABB 较长半轴) */
7
+ var CIRCLE = "circle";
8
+ /** 把 rect 收成边长 = max(width, height) 的正方(中心 / rotate 不变)——circle 连接面用 */
9
+ var squareToMax = (rect) => {
10
+ const side = Math.max(rect.width, rect.height);
11
+ return {
12
+ x: rect.x,
13
+ y: rect.y,
14
+ width: side,
15
+ height: side,
16
+ rotate: rect.rotate
17
+ };
18
+ };
19
+ /**
20
+ * 把连接面取值解析为「计算 boundaryPoint / anchor 所需的 def + rect + params」
21
+ * @description layout-neutral:borrowed/builtin 一律喂目标节点的视觉 AABB rect,绝不调其 circumscribe。
22
+ * 保留字 'shape' → 视觉 def 原样;'circle' → ellipse def + squared-to-max rect;
23
+ * 保留字 'rectangle' / 'ellipse' → 对应内置 def + 视觉 AABB;其余 → registry 查表。
24
+ * 保留字优先于 registry 同名 shape。
25
+ */
26
+ var resolveBoundary = (boundary, visualDef, visualRect, visualParams, registry) => {
27
+ if (boundary === void 0 || boundary === SELF) return {
28
+ def: visualDef,
29
+ rect: visualRect,
30
+ params: visualParams
31
+ };
32
+ if (boundary === CIRCLE) return {
33
+ def: require_ellipse.ellipse,
34
+ rect: squareToMax(visualRect),
35
+ params: {}
36
+ };
37
+ if (boundary === "rectangle") return {
38
+ def: require_rectangle.rectangle,
39
+ rect: visualRect,
40
+ params: {}
41
+ };
42
+ if (boundary === "ellipse") return {
43
+ def: require_ellipse.ellipse,
44
+ rect: visualRect,
45
+ params: {}
46
+ };
47
+ const type = typeof boundary === "string" ? boundary : boundary.type;
48
+ const rawParams = typeof boundary === "string" ? {} : boundary.params ?? {};
49
+ const def = Object.prototype.hasOwnProperty.call(registry, type) ? registry[type] : void 0;
50
+ if (!def) throw new Error(`Unknown connection surface '${type}'; reserved: shape/circle, registered: ${Object.keys(registry).sort().join(", ")}`);
51
+ return {
52
+ def,
53
+ rect: visualRect,
54
+ params: def.paramsSchema.parse(rawParams)
55
+ };
56
+ };
57
+ /** 连接面的稳定字符串判别(anchor cache key 用) */
58
+ var boundaryKey = (boundary) => {
59
+ if (boundary === void 0) return SELF;
60
+ if (typeof boundary === "string") return boundary;
61
+ return `${boundary.type}:${JSON.stringify(boundary.params ?? {})}`;
62
+ };
63
+ //#endregion
64
+ exports.boundaryKey = boundaryKey;
65
+ exports.resolveBoundary = resolveBoundary;
@@ -0,0 +1,19 @@
1
+ import { Rect } from '../geometry/rect';
2
+ import { IRBoundary } from '../ir';
3
+ import { IRJsonObject } from '../ir/json';
4
+ import { ShapeDefinition } from '../shapes';
5
+ /**
6
+ * 把连接面取值解析为「计算 boundaryPoint / anchor 所需的 def + rect + params」
7
+ * @description layout-neutral:borrowed/builtin 一律喂目标节点的视觉 AABB rect,绝不调其 circumscribe。
8
+ * 保留字 'shape' → 视觉 def 原样;'circle' → ellipse def + squared-to-max rect;
9
+ * 保留字 'rectangle' / 'ellipse' → 对应内置 def + 视觉 AABB;其余 → registry 查表。
10
+ * 保留字优先于 registry 同名 shape。
11
+ */
12
+ export declare const resolveBoundary: (boundary: IRBoundary | undefined, visualDef: ShapeDefinition, visualRect: Rect, visualParams: IRJsonObject, registry: Record<string, ShapeDefinition>) => {
13
+ def: ShapeDefinition;
14
+ rect: Rect;
15
+ params: IRJsonObject;
16
+ };
17
+ /** 连接面的稳定字符串判别(anchor cache key 用) */
18
+ export declare const boundaryKey: (boundary: IRBoundary | undefined) => string;
19
+ //# sourceMappingURL=boundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../../src/compile/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAcjD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,UAAU,GAAG,SAAS,EAChC,WAAW,eAAe,EAC1B,YAAY,IAAI,EAChB,cAAc,YAAY,EAC1B,UAAU,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,KACxC;IAAE,GAAG,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAuB1D,CAAC;AAEF,sCAAsC;AACtC,eAAO,MAAM,WAAW,GAAI,UAAU,UAAU,GAAG,SAAS,KAAG,MAI9D,CAAC"}
@@ -38,7 +38,8 @@ var zeroSizeRectAt = (id, [cx, cy]) => ({
38
38
  textHeight: 0,
39
39
  align: "middle",
40
40
  lineHeight: 0,
41
- fontSize: 0
41
+ fontSize: 0,
42
+ shapes: require_index.BUILTIN_SHAPES
42
43
  });
43
44
  /**
44
45
  * 把 coordinate 注册成 0×0 NodeLayout
@@ -77,6 +78,16 @@ var viewBoxToLayout = (vb, round) => {
77
78
  };
78
79
  };
79
80
  /**
81
+ * 自动算 layout 的 finite 守卫:四值非全 finite 即抛清晰错(LLM 可读),不泄漏进 Scene
82
+ * @description computeLayout 由 `center ± halfWidth` 等运算聚合——极端 shape 几何(如 outerRadius:1e308
83
+ * 半轴 finite 但 center+halfWidth 溢出 Infinity)会让运算结果脏。schema 的 `.finite()` 只守单字段输入,
84
+ * 守不住聚合后的溢出;此处复用 viewBoxToLayout 同款 finite 关口,是自动 layout 进 Scene 前的唯一兜底。
85
+ */
86
+ var assertFiniteLayout = (layout) => {
87
+ if (!Number.isFinite(layout.x) || !Number.isFinite(layout.y) || !Number.isFinite(layout.width) || !Number.isFinite(layout.height)) throw new Error(`Node layout produced non-finite bounds (x=${String(layout.x)}, y=${String(layout.y)}, width=${String(layout.width)}, height=${String(layout.height)}); check shape geometry (e.g. extreme radius).`);
88
+ return layout;
89
+ };
90
+ /**
80
91
  * 默认 warn dispatcher:dev 模式 console.warn、生产静默
81
92
  * @description 用户传 onWarn 时使用用户的;不传走此 fallback
82
93
  */
@@ -304,6 +315,8 @@ var compileToScene = (ir, options = {}) => {
304
315
  type: "group",
305
316
  children: stableSortByZIndex(sealSink(innerSink))
306
317
  };
318
+ if (child.id !== void 0) group.id = child.id;
319
+ if (child.meta !== void 0) group.meta = child.meta;
307
320
  if (hasOwnTransforms) group.transforms = [...ownTransforms];
308
321
  if (child.clip !== void 0) group.clipRef = clip.resolve(child.clip);
309
322
  sink.push(group);
@@ -338,7 +351,7 @@ var compileToScene = (ir, options = {}) => {
338
351
  const resources = [...paint.resources(), ...clip.resources()];
339
352
  return {
340
353
  primitives: stableSortByZIndex(sealSink(primitives)),
341
- layout: loweredIr.viewBox !== void 0 ? viewBoxToLayout(loweredIr.viewBox, round) : require_layout.computeLayout(allPoints, layoutPadding, round),
354
+ layout: loweredIr.viewBox !== void 0 ? viewBoxToLayout(loweredIr.viewBox, round) : assertFiniteLayout(require_layout.computeLayout(allPoints, layoutPadding, round)),
342
355
  ...resources.length > 0 ? { resources } : {}
343
356
  };
344
357
  };
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/compile/compile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAwC,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAa,KAAK,EAA6B,MAAM,cAAc,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAwBzD,OAAO,EAAE,KAAK,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AA4CrE,uEAAuE;AACvE,MAAM,MAAM,cAAc,GAAG;IAC3B;;;OAGG;IACH,IAAI,EACA,2BAA2B,GAC3B,gBAAgB,GAChB,0BAA0B,GAC1B,wBAAwB,GACxB,yBAAyB,GACzB,sBAAsB,GACtB,8BAA8B,GAC9B,oBAAoB,GACpB,mBAAmB,GACnB,yBAAyB,GACzB,yBAAyB,GACzB,2BAA2B,GAC3B,0BAA0B,GAC1B,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAClB,iBAAiB;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,2BAA2B;AAC3B,MAAM,MAAM,cAAc,GAAG;IAC3B,oCAAoC;IACpC,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3C;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACxC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AA+HF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,IAAI,EAAE,EAAE,UAAS,cAAmB,KAAG,KAiWrE,CAAC"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/compile/compile.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAwC,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAa,KAAK,EAA6B,MAAM,cAAc,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAwBzD,OAAO,EAAE,KAAK,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AA6CrE,uEAAuE;AACvE,MAAM,MAAM,cAAc,GAAG;IAC3B;;;OAGG;IACH,IAAI,EACA,2BAA2B,GAC3B,gBAAgB,GAChB,0BAA0B,GAC1B,wBAAwB,GACxB,yBAAyB,GACzB,sBAAsB,GACtB,8BAA8B,GAC9B,oBAAoB,GACpB,mBAAmB,GACnB,yBAAyB,GACzB,yBAAyB,GACzB,2BAA2B,GAC3B,0BAA0B,GAC1B,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAClB,iBAAiB;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,2BAA2B;AAC3B,MAAM,MAAM,cAAc,GAAG;IAC3B,oCAAoC;IACpC,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC3C;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACxC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAwJF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,IAAI,EAAE,EAAE,UAAS,cAAmB,KAAG,KAqWrE,CAAC"}