@neta-art/cohub 8.24.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dist/board/animation.d.ts +57 -181
  2. package/dist/board/animation.js +374 -220
  3. package/dist/board/core/arrow-geometry.d.ts +33 -18
  4. package/dist/board/core/arrow-geometry.js +283 -52
  5. package/dist/board/core/draw-geometry.d.ts +22 -36
  6. package/dist/board/core/draw-geometry.js +148 -85
  7. package/dist/board/core/export-assets.d.ts +3 -6
  8. package/dist/board/core/export-assets.js +0 -2
  9. package/dist/board/core/export-plan.d.ts +12 -63
  10. package/dist/board/core/export-plan.js +55 -94
  11. package/dist/board/core/palette.d.ts +4 -21
  12. package/dist/board/core/palette.js +8 -13
  13. package/dist/board/core/scene.d.ts +33 -0
  14. package/dist/board/core/scene.js +302 -0
  15. package/dist/board/core/shape-definition.d.ts +12 -24
  16. package/dist/board/core/shape-definition.js +0 -19
  17. package/dist/board/core/shape-types.d.ts +6 -120
  18. package/dist/board/core/shape-types.js +5 -5
  19. package/dist/board/core/text-metrics.d.ts +8 -11
  20. package/dist/board/core/text-metrics.js +5 -34
  21. package/dist/board/core/tool-styles.d.ts +6 -16
  22. package/dist/board/core/tool-styles.js +17 -25
  23. package/dist/board/export/index.d.ts +10 -17
  24. package/dist/board/export/index.js +22 -21
  25. package/dist/board/export/scene.d.ts +10 -16
  26. package/dist/board/export/scene.js +17 -30
  27. package/dist/board/geometry.d.ts +27 -56
  28. package/dist/board/geometry.js +7 -67
  29. package/dist/board/headless/index.d.ts +6 -27
  30. package/dist/board/headless/index.js +4 -19
  31. package/dist/board/headless/sketch.d.ts +19 -0
  32. package/dist/board/headless/sketch.js +146 -0
  33. package/dist/board/image-key.d.ts +2 -12
  34. package/dist/board/image-key.js +3 -13
  35. package/dist/board/index.d.ts +18 -20
  36. package/dist/board/index.js +17 -17
  37. package/dist/board/media-playback.d.ts +3 -6
  38. package/dist/board/media-playback.js +6 -6
  39. package/dist/board/presets.d.ts +150 -0
  40. package/dist/board/presets.js +226 -0
  41. package/dist/board/render/board-background.d.ts +5 -3
  42. package/dist/board/render/board-background.js +8 -7
  43. package/dist/board/render/clip.d.ts +14 -0
  44. package/dist/board/render/clip.js +47 -0
  45. package/dist/board/render/index.d.ts +8 -5
  46. package/dist/board/render/index.js +7 -4
  47. package/dist/board/render/media-interaction.d.ts +4 -5
  48. package/dist/board/render/media-interaction.js +1 -2
  49. package/dist/board/render/palette.d.ts +6 -2
  50. package/dist/board/render/palette.js +7 -1
  51. package/dist/board/render/renderers/arrow-card-renderer.js +69 -71
  52. package/dist/board/render/renderers/audio-card-renderer.js +3 -3
  53. package/dist/board/render/renderers/base-card-renderer.d.ts +6 -17
  54. package/dist/board/render/renderers/base-card-renderer.js +1 -24
  55. package/dist/board/render/renderers/board-renderer-registry.d.ts +20 -50
  56. package/dist/board/render/renderers/board-renderer-registry.js +6 -7
  57. package/dist/board/render/renderers/draw-card-renderer.js +89 -56
  58. package/dist/board/render/renderers/effect-card-renderer.d.ts +6 -0
  59. package/dist/board/render/renderers/effect-card-renderer.js +197 -0
  60. package/dist/board/render/renderers/far-plate.d.ts +4 -21
  61. package/dist/board/render/renderers/far-plate.js +15 -34
  62. package/dist/board/render/renderers/file-card-renderer.d.ts +4 -25
  63. package/dist/board/render/renderers/file-card-renderer.js +8 -58
  64. package/dist/board/render/renderers/frame-card-renderer.js +28 -28
  65. package/dist/board/render/renderers/image-card-renderer.d.ts +4 -3
  66. package/dist/board/render/renderers/image-card-renderer.js +0 -9
  67. package/dist/board/render/renderers/shape-card-renderer.d.ts +9 -0
  68. package/dist/board/render/renderers/shape-card-renderer.js +240 -0
  69. package/dist/board/render/renderers/sketch-card-renderer.d.ts +5 -0
  70. package/dist/board/render/renderers/sketch-card-renderer.js +98 -0
  71. package/dist/board/render/renderers/task-card-renderer.d.ts +0 -1
  72. package/dist/board/render/renderers/task-card-renderer.js +14 -16
  73. package/dist/board/render/renderers/text-card-renderer.d.ts +1 -3
  74. package/dist/board/render/renderers/text-card-renderer.js +56 -46
  75. package/dist/board/render/renderers/unknown-card-renderer.js +4 -10
  76. package/dist/board/render/renderers/video-card-renderer.d.ts +4 -2
  77. package/dist/board/render/renderers/video-card-renderer.js +2 -1
  78. package/dist/board/render/sketch-host.d.ts +14 -0
  79. package/dist/board/render/sketch-host.js +216 -0
  80. package/dist/board/render/stroke.d.ts +12 -0
  81. package/dist/board/render/stroke.js +90 -0
  82. package/dist/board/render/text-measurement.d.ts +6 -26
  83. package/dist/board/render/text-measurement.js +11 -30
  84. package/dist/board/replay.d.ts +6 -31
  85. package/dist/board/replay.js +45 -203
  86. package/dist/board/runtime/board-player.d.ts +24 -0
  87. package/dist/board/runtime/board-player.js +161 -0
  88. package/dist/board/task.d.ts +2 -10
  89. package/dist/board/task.js +1 -10
  90. package/dist/chunks/environment.d.ts +2291 -3864
  91. package/dist/chunks/host-bridge.d.ts +253 -0
  92. package/dist/chunks/http.d.ts +233 -58
  93. package/dist/chunks/http.js +1046 -1028
  94. package/dist/chunks/transport.js +113 -59
  95. package/dist/chunks/websocket.d.ts +1 -1
  96. package/dist/chunks/websocket.js +1 -1
  97. package/dist/host-bridge.d.ts +54 -0
  98. package/dist/host-bridge.js +322 -0
  99. package/dist/http.d.ts +3 -3
  100. package/dist/index.d.ts +74 -191
  101. package/dist/index.js +2032 -1186
  102. package/dist/protocol/dist/board-constants.d.ts +1 -29
  103. package/dist/protocol/dist/board-constants.js +2 -115
  104. package/dist/protocol/dist/board-layout.d.ts +59 -0
  105. package/dist/protocol/dist/board-layout.js +482 -0
  106. package/dist/protocol/dist/board-model.d.ts +2052 -0
  107. package/dist/protocol/dist/board-model.js +592 -0
  108. package/dist/protocol/dist/board-patch.d.ts +86 -0
  109. package/dist/protocol/dist/board-patch.js +734 -0
  110. package/dist/protocol/dist/board-schema.d.ts +33 -0
  111. package/dist/protocol/dist/board-schema.js +59 -0
  112. package/dist/protocol/dist/board-upgrade.d.ts +1 -0
  113. package/dist/protocol/dist/board-url.d.ts +1 -3
  114. package/dist/protocol/dist/board-url.js +2 -2
  115. package/dist/protocol/dist/board.d.ts +37 -232
  116. package/dist/protocol/dist/board.js +62 -160
  117. package/dist/protocol/dist/display/actions.d.ts +1 -0
  118. package/dist/protocol/dist/display/index.d.ts +2 -0
  119. package/dist/protocol/dist/index.d.ts +11 -12
  120. package/dist/protocol/dist/model/metrics.d.ts +2 -0
  121. package/dist/protocol/dist/model/session.d.ts +2 -1
  122. package/dist/protocol/dist/realtime/types.d.ts +2 -2
  123. package/dist/protocol/dist/runtime/index.d.ts +1 -0
  124. package/dist/space-picker.d.ts +1 -0
  125. package/dist/space-picker.js +1 -0
  126. package/dist/types.d.ts +2 -5
  127. package/package.json +9 -1
  128. package/dist/board/core/connections.d.ts +0 -108
  129. package/dist/board/core/connections.js +0 -455
  130. package/dist/board/mutation.d.ts +0 -6
  131. package/dist/board/mutation.js +0 -14
  132. package/dist/board/render/connection-layer.d.ts +0 -53
  133. package/dist/board/render/connection-layer.js +0 -375
  134. package/dist/board/render/renderers/geo-card-renderer.d.ts +0 -5
  135. package/dist/board/render/renderers/geo-card-renderer.js +0 -127
  136. package/dist/board/semantic-document.d.ts +0 -37
  137. package/dist/board/semantic-document.js +0 -288
  138. package/dist/board/semantic-mutation.d.ts +0 -10
  139. package/dist/board/semantic-mutation.js +0 -209
  140. package/dist/protocol/dist/board-animation.js +0 -34
  141. package/dist/protocol/dist/board-authoring.d.ts +0 -1326
  142. package/dist/protocol/dist/board-authoring.js +0 -302
  143. package/dist/protocol/dist/board-capability-registry.d.ts +0 -2
  144. package/dist/protocol/dist/board-capability-registry.js +0 -123
  145. package/dist/protocol/dist/board-codec.d.ts +0 -3
  146. package/dist/protocol/dist/board-codec.js +0 -383
  147. package/dist/protocol/dist/board-composition.d.ts +0 -383
  148. package/dist/protocol/dist/board-composition.js +0 -310
  149. package/dist/protocol/dist/board-connection.d.ts +0 -317
  150. package/dist/protocol/dist/board-connection.js +0 -219
  151. package/dist/protocol/dist/board-document.d.ts +0 -1566
  152. package/dist/protocol/dist/board-document.js +0 -456
  153. package/dist/protocol/dist/board-effect.d.ts +0 -96
  154. package/dist/protocol/dist/board-effect.js +0 -54
  155. package/dist/protocol/dist/board-geometry.d.ts +0 -15
  156. package/dist/protocol/dist/board-geometry.js +0 -137
  157. package/dist/protocol/dist/board-node.d.ts +0 -8
  158. package/dist/protocol/dist/board-node.js +0 -252
  159. /package/dist/protocol/dist/{board-animation.d.ts → host-bridge.d.ts} +0 -0
@@ -1,137 +0,0 @@
1
- //#region ../protocol/dist/board-geometry.js
2
- /**
3
- * Renderer-independent Board geometry contracts.
4
- *
5
- * Renderers build their own primitives from these results, but validation and
6
- * item factories use the same coordinate and bounds rules.
7
- */
8
- /** Radius of a draw sample in world units given stroke size and pressure. */
9
- function boardDrawSampleRadius(size, pressure) {
10
- const clamped = Math.min(1, Math.max(0, pressure));
11
- return Math.max(.5, size / 2 * (.5 + clamped));
12
- }
13
- /** Convert persisted frame-local draw points to world-space authoring points. */
14
- function boardDrawPointsToWorld(points, x, y) {
15
- return points.map((point) => ({
16
- x: point.x + x,
17
- y: point.y + y,
18
- p: point.p
19
- }));
20
- }
21
- /** Convert world-space authoring points to persisted frame-local points. */
22
- function boardDrawPointsToLocal(points, x, y) {
23
- return points.map((point) => ({
24
- x: point.x - x,
25
- y: point.y - y,
26
- p: point.p
27
- }));
28
- }
29
- /** Exact local bounds required by the draw node contract. */
30
- function boardDrawBounds(points, size) {
31
- if (points.length === 0) return {
32
- x: 0,
33
- y: 0,
34
- width: 1,
35
- height: 1
36
- };
37
- let minX = Number.POSITIVE_INFINITY;
38
- let minY = Number.POSITIVE_INFINITY;
39
- let maxX = Number.NEGATIVE_INFINITY;
40
- let maxY = Number.NEGATIVE_INFINITY;
41
- for (const point of points) {
42
- const radius = boardDrawSampleRadius(size, point.p);
43
- minX = Math.min(minX, point.x - radius);
44
- minY = Math.min(minY, point.y - radius);
45
- maxX = Math.max(maxX, point.x + radius);
46
- maxY = Math.max(maxY, point.y + radius);
47
- }
48
- return {
49
- x: minX,
50
- y: minY,
51
- width: Math.max(1, maxX - minX),
52
- height: Math.max(1, maxY - minY)
53
- };
54
- }
55
- /** Resolve the world-space quadratic curve represented by a free arrow. */
56
- function boardResolveArrow(input) {
57
- const start = input.start;
58
- const end = input.end;
59
- const mid = {
60
- x: (start.x + end.x) / 2,
61
- y: (start.y + end.y) / 2
62
- };
63
- if (!input.bend) return {
64
- start,
65
- end,
66
- control: mid
67
- };
68
- const dx = end.x - start.x;
69
- const dy = end.y - start.y;
70
- const length = Math.hypot(dx, dy) || 1;
71
- const offset = input.bend * length;
72
- return {
73
- start,
74
- end,
75
- control: {
76
- x: mid.x + -dy / length * offset,
77
- y: mid.y + dx / length * offset
78
- }
79
- };
80
- }
81
- /** Sample an already resolved arrow curve. */
82
- function boardSampleResolvedArrow(resolved, segments) {
83
- const { start, control, end } = resolved;
84
- const count = Math.max(1, Math.floor(segments));
85
- const points = [];
86
- for (let index = 0; index <= count; index += 1) {
87
- const t = index / count;
88
- const mt = 1 - t;
89
- points.push({
90
- x: mt * mt * start.x + 2 * mt * t * control.x + t * t * end.x,
91
- y: mt * mt * start.y + 2 * mt * t * control.y + t * t * end.y
92
- });
93
- }
94
- return points;
95
- }
96
- /** World bounds of the curve, padded for the stroke. */
97
- function boardArrowBounds(input) {
98
- const { start, control, end } = boardResolveArrow(input);
99
- const points = [start, end];
100
- for (const axis of ["x", "y"]) {
101
- const denominator = start[axis] - 2 * control[axis] + end[axis];
102
- if (Math.abs(denominator) < 1e-12) continue;
103
- const t = (start[axis] - control[axis]) / denominator;
104
- if (t > 0 && t < 1) {
105
- const mt = 1 - t;
106
- points.push({
107
- x: mt * mt * start.x + 2 * mt * t * control.x + t * t * end.x,
108
- y: mt * mt * start.y + 2 * mt * t * control.y + t * t * end.y
109
- });
110
- }
111
- }
112
- let minX = Number.POSITIVE_INFINITY;
113
- let minY = Number.POSITIVE_INFINITY;
114
- let maxX = Number.NEGATIVE_INFINITY;
115
- let maxY = Number.NEGATIVE_INFINITY;
116
- for (const point of points) {
117
- minX = Math.min(minX, point.x);
118
- minY = Math.min(minY, point.y);
119
- maxX = Math.max(maxX, point.x);
120
- maxY = Math.max(maxY, point.y);
121
- }
122
- const pad = Math.max(8, input.size * 2);
123
- return {
124
- x: minX - pad,
125
- y: minY - pad,
126
- width: Math.max(1, maxX - minX + pad * 2),
127
- height: Math.max(1, maxY - minY + pad * 2)
128
- };
129
- }
130
- function boardArrowFrame(input) {
131
- return {
132
- ...boardArrowBounds(input),
133
- rotation: 0
134
- };
135
- }
136
- //#endregion
137
- export { boardArrowBounds, boardArrowFrame, boardDrawBounds, boardDrawPointsToLocal, boardDrawPointsToWorld, boardDrawSampleRadius, boardResolveArrow, boardSampleResolvedArrow };
@@ -1,8 +0,0 @@
1
- import { z } from "zod";
2
- //#region ../protocol/dist/board-node.d.ts
3
- declare const BOARD_COLOR_IDS: readonly ["brand", "neutral", "black", "white", "blue", "green", "amber", "violet", "rose"];
4
- type BoardColorId = (typeof BOARD_COLOR_IDS)[number];
5
- declare const BOARD_GEO_KINDS: readonly ["rectangle", "rounded", "ellipse", "diamond", "triangle"];
6
- type BoardGeoKind = (typeof BOARD_GEO_KINDS)[number];
7
- //#endregion
8
- export { BOARD_COLOR_IDS, BOARD_GEO_KINDS, BoardColorId, BoardGeoKind };
@@ -1,252 +0,0 @@
1
- import { BOARD_ARROW_STROKE_SIZE } from "./board-constants.js";
2
- import { BoardTaskSnapshotSchema } from "./board-document.js";
3
- import { boardArrowFrame, boardDrawBounds } from "./board-geometry.js";
4
- import { z } from "zod";
5
- //#region ../protocol/dist/board-node.js
6
- const BOARD_COLOR_IDS = [
7
- "brand",
8
- "neutral",
9
- "black",
10
- "white",
11
- "blue",
12
- "green",
13
- "amber",
14
- "violet",
15
- "rose"
16
- ];
17
- const BoardColorIdSchema = z.enum(BOARD_COLOR_IDS);
18
- const BOARD_GEO_KINDS = [
19
- "rectangle",
20
- "rounded",
21
- "ellipse",
22
- "diamond",
23
- "triangle"
24
- ];
25
- const BoardGeoKindSchema = z.enum(BOARD_GEO_KINDS);
26
- const BOARD_NATIVE_NODE_TYPES = [
27
- "image",
28
- "video",
29
- "audio",
30
- "file",
31
- "task",
32
- "text",
33
- "geo",
34
- "draw",
35
- "arrow",
36
- "frame"
37
- ];
38
- const metadataSchema = z.record(z.string(), z.unknown());
39
- const commonData = {
40
- locked: z.boolean().optional(),
41
- metadata: metadataSchema.optional()
42
- };
43
- const pointSchema = z.object({
44
- x: z.number().finite(),
45
- y: z.number().finite(),
46
- p: z.number().finite().min(0).max(1).default(.5)
47
- }).strict();
48
- const worldPointSchema = z.object({
49
- x: z.number().finite(),
50
- y: z.number().finite()
51
- }).strict();
52
- const strokeSizeSchema = z.number().finite().min(1).max(64);
53
- const mediaViewSchema = z.object({
54
- title: z.string().optional(),
55
- mimeType: z.string().optional(),
56
- size: z.number().finite().nonnegative().optional(),
57
- mtimeMs: z.number().finite().nonnegative().optional(),
58
- naturalWidth: z.number().finite().positive().optional(),
59
- naturalHeight: z.number().finite().positive().optional()
60
- }).strict();
61
- const audioViewSchema = mediaViewSchema.extend({ durationMs: z.number().finite().nonnegative().optional() });
62
- const dataSchemas = {
63
- text: z.object({
64
- ...commonData,
65
- text: z.string().default(""),
66
- color: BoardColorIdSchema.default("neutral"),
67
- fontSize: z.number().finite().min(2).max(512).default(24)
68
- }).strict(),
69
- geo: z.object({
70
- ...commonData,
71
- geo: BoardGeoKindSchema.default("rectangle"),
72
- text: z.string().default(""),
73
- color: BoardColorIdSchema.default("brand"),
74
- fillOpacity: z.number().finite().min(0).max(1).default(0)
75
- }).strict(),
76
- draw: z.object({
77
- ...commonData,
78
- points: z.array(pointSchema).min(1),
79
- color: BoardColorIdSchema.default("brand"),
80
- size: strokeSizeSchema.default(4)
81
- }).strict(),
82
- arrow: z.object({
83
- ...commonData,
84
- start: worldPointSchema,
85
- end: worldPointSchema,
86
- bend: z.number().finite().min(-.85).max(.85).default(0),
87
- color: BoardColorIdSchema.default("brand"),
88
- size: strokeSizeSchema.default(BOARD_ARROW_STROKE_SIZE),
89
- arrowStart: z.boolean().default(false),
90
- arrowEnd: z.boolean().default(true),
91
- label: z.string().default("")
92
- }).strict(),
93
- frame: z.object({
94
- ...commonData,
95
- label: z.string().default("Frame"),
96
- color: BoardColorIdSchema.default("neutral")
97
- }).strict(),
98
- image: z.object({
99
- ...commonData,
100
- crop: z.object({
101
- x: z.number().finite().min(0).max(1),
102
- y: z.number().finite().min(0).max(1),
103
- w: z.number().finite().min(0).max(1),
104
- h: z.number().finite().min(0).max(1)
105
- }).strict().optional()
106
- }).strict(),
107
- video: z.object(commonData).strict(),
108
- audio: z.object(commonData).strict(),
109
- file: z.object(commonData).strict(),
110
- task: z.object({
111
- ...commonData,
112
- taskRunId: z.string().min(1)
113
- }).strict()
114
- };
115
- const fileViewSchema = z.object({
116
- title: z.string().optional(),
117
- mimeType: z.string().optional(),
118
- size: z.number().finite().nonnegative().optional(),
119
- mtimeMs: z.number().finite().nonnegative().optional(),
120
- excerpt: z.string().optional(),
121
- coverPath: z.string().optional(),
122
- coverUrl: z.string().url().optional()
123
- }).strict();
124
- const taskViewSchema = BoardTaskSnapshotSchema;
125
- const emptyViewSchema = z.object({}).strict();
126
- const viewSchemas = {
127
- image: mediaViewSchema,
128
- video: mediaViewSchema,
129
- audio: audioViewSchema,
130
- file: fileViewSchema,
131
- task: taskViewSchema,
132
- text: emptyViewSchema,
133
- geo: emptyViewSchema,
134
- draw: emptyViewSchema,
135
- arrow: emptyViewSchema,
136
- frame: emptyViewSchema
137
- };
138
- const nodeEnvelopeSchema = z.object({
139
- nodeId: z.string().min(1).max(160),
140
- type: z.string().min(1).max(40),
141
- parentId: z.string().min(1).max(160).nullable(),
142
- orderKey: z.string().max(4096).nullable(),
143
- x: z.number().finite(),
144
- y: z.number().finite(),
145
- width: z.number().finite().positive(),
146
- height: z.number().finite().positive(),
147
- rotation: z.number().finite(),
148
- refKind: z.string().max(40).nullable(),
149
- refPath: z.string().max(4096).nullable(),
150
- refUrl: z.string().max(4096).nullable(),
151
- view: z.record(z.string(), z.unknown()),
152
- style: z.record(z.string(), z.unknown()),
153
- data: z.record(z.string(), z.unknown())
154
- }).strict();
155
- function jsonSchema(schema) {
156
- return z.toJSONSchema(schema);
157
- }
158
- jsonSchema(nodeEnvelopeSchema), Object.fromEntries(BOARD_NATIVE_NODE_TYPES.map((type) => [type, jsonSchema(dataSchemas[type])])), Object.fromEntries(BOARD_NATIVE_NODE_TYPES.map((type) => [type, jsonSchema(viewSchemas[type])]));
159
- function issueDiagnostic(issue, path) {
160
- const fullPath = [path, ...issue.path].join(".");
161
- const values = "values" in issue && Array.isArray(issue.values) ? issue.values.filter((value) => typeof value === "string") : void 0;
162
- return {
163
- severity: "error",
164
- code: "INVALID_BOARD_NODE",
165
- message: `${fullPath}: ${issue.message}`,
166
- path: fullPath,
167
- ...values?.length ? { allowedValues: values } : {}
168
- };
169
- }
170
- function drawGeometryDiagnostic(node, data, path) {
171
- const { x: minX, y: minY, width, height } = boardDrawBounds(data.points, data.size);
172
- const tolerance = Math.max(.01, node.width * 1e-6, node.height * 1e-6);
173
- if (Math.abs(minX) <= tolerance && Math.abs(minY) <= tolerance && Math.abs(width - node.width) <= tolerance && Math.abs(height - node.height) <= tolerance) return null;
174
- return {
175
- severity: "error",
176
- code: "INVALID_BOARD_GEOMETRY",
177
- message: `${path}.data.points must use frame-local coordinates and match the node frame`,
178
- path: `${path}.data.points`,
179
- expected: `frame-local bounds x=0, y=0, width=${width}, height=${height}`,
180
- received: {
181
- frame: {
182
- x: node.x,
183
- y: node.y,
184
- width: node.width,
185
- height: node.height
186
- },
187
- pointsBounds: {
188
- x: minX,
189
- y: minY,
190
- width,
191
- height
192
- }
193
- },
194
- coordinateSpace: "frame-local"
195
- };
196
- }
197
- function validateBoardNodeInput(node, path = "node") {
198
- const envelopeResult = nodeEnvelopeSchema.safeParse(node);
199
- if (!envelopeResult.success) return envelopeResult.error.issues.map((issue) => issueDiagnostic(issue, path));
200
- if (typeof node.type !== "string" || !BOARD_NATIVE_NODE_TYPES.includes(node.type)) return [{
201
- severity: "error",
202
- code: "INVALID_BOARD_NODE",
203
- message: `${path}.type is not supported`,
204
- path: `${path}.type`,
205
- expected: "BoardNativeNodeType",
206
- received: node.type,
207
- allowedValues: BOARD_NATIVE_NODE_TYPES
208
- }];
209
- const type = node.type;
210
- const dataResult = dataSchemas[type].safeParse(node.data ?? {});
211
- if (!dataResult.success) return dataResult.error.issues.map((issue) => issueDiagnostic(issue, `${path}.data`));
212
- const viewResult = viewSchemas[type].safeParse(node.view ?? {});
213
- if (!viewResult.success) return viewResult.error.issues.map((issue) => issueDiagnostic(issue, `${path}.view`));
214
- if (type === "image" || type === "video" || type === "audio" || type === "file") {
215
- if (node.refKind !== "space_file" || typeof node.refPath !== "string" || !node.refPath) return [{
216
- severity: "error",
217
- code: "INVALID_BOARD_NODE",
218
- message: `${path} requires a space file reference`,
219
- path: `${path}.refPath`,
220
- expected: "non-empty refPath with refKind space_file"
221
- }];
222
- }
223
- if (type === "draw") {
224
- const diagnostic = drawGeometryDiagnostic(node, dataResult.data, path);
225
- return diagnostic ? [diagnostic] : [];
226
- }
227
- if (type === "arrow") {
228
- const data = dataResult.data;
229
- const expected = boardArrowFrame(data);
230
- const tolerance = Math.max(.01, node.width * 1e-6, node.height * 1e-6);
231
- if (Math.abs(node.x - expected.x) > tolerance || Math.abs(node.y - expected.y) > tolerance || Math.abs(node.width - expected.width) > tolerance || Math.abs(node.height - expected.height) > tolerance) return [{
232
- severity: "error",
233
- code: "INVALID_BOARD_GEOMETRY",
234
- message: `${path}.data endpoints must use world-space coordinates and match the arrow frame`,
235
- path: `${path}.data`,
236
- expected: `world-space curve bounds x=${expected.x}, y=${expected.y}, width=${expected.width}, height=${expected.height}`,
237
- received: {
238
- frame: {
239
- x: node.x,
240
- y: node.y,
241
- width: node.width,
242
- height: node.height
243
- },
244
- curveBounds: expected
245
- },
246
- coordinateSpace: "world"
247
- }];
248
- }
249
- return [];
250
- }
251
- //#endregion
252
- export { BOARD_COLOR_IDS, BOARD_GEO_KINDS, BOARD_NATIVE_NODE_TYPES, BoardColorIdSchema, BoardGeoKindSchema, validateBoardNodeInput };