@neta-art/cohub 8.23.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 +7 -27
  30. package/dist/board/headless/index.js +20 -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 +2296 -3864
  91. package/dist/chunks/host-bridge.d.ts +253 -0
  92. package/dist/chunks/http.d.ts +238 -58
  93. package/dist/chunks/http.js +1061 -1034
  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 +76 -193
  101. package/dist/index.js +2037 -1191
  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,456 +0,0 @@
1
- import { BOARD_ARROW_STROKE_SIZE } from "./board-constants.js";
2
- import { BoardConnectionSchema } from "./board-connection.js";
3
- import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION } from "./board.js";
4
- import { BoardMotionSchema } from "./board-animation.js";
5
- import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "./board-url.js";
6
- import { z } from "zod";
7
- //#region ../protocol/dist/board-document.js
8
- const BoardFrameSchema = z.object({
9
- x: z.number().finite(),
10
- y: z.number().finite(),
11
- width: z.number().finite().positive(),
12
- height: z.number().finite().positive(),
13
- rotation: z.number().finite().default(0)
14
- });
15
- /**
16
- * The board camera. This is local UI state, not synced content: semantic ops
17
- * (see diffBoardDocuments) never describe the viewport, and the editor holds
18
- * the live camera separately from the persisted document. Here it only serves
19
- * as an initial camera hint when a document is first loaded.
20
- */
21
- const BoardViewportSchema = z.object({
22
- x: z.number().finite(),
23
- y: z.number().finite(),
24
- zoom: z.number().finite().min(.05).max(8)
25
- });
26
- const BoardAppearanceSchema = z.object({
27
- /** Legacy field retained when reading older Board documents; not used for rendering. */
28
- theme: z.string().min(1).optional(),
29
- /** Board-wide motion policies. Omitted policies mean no motion. */
30
- motion: BoardMotionSchema.optional(),
31
- /** Legacy field retained when reading older Board documents; not used for rendering. */
32
- mood: z.enum([
33
- "clean",
34
- "playful",
35
- "arcane",
36
- "cyber",
37
- "natural"
38
- ]).optional(),
39
- background: z.object({
40
- kind: z.enum([
41
- "solid",
42
- "dots",
43
- "grid",
44
- "image",
45
- "shader",
46
- "custom"
47
- ]).default("dots"),
48
- color: z.string().optional(),
49
- imageUrl: BoardRemoteUrlSchema.optional(),
50
- fit: z.enum([
51
- "cover",
52
- "contain",
53
- "repeat"
54
- ]).optional(),
55
- position: z.enum([
56
- "center",
57
- "top",
58
- "bottom",
59
- "left",
60
- "right"
61
- ]).optional(),
62
- opacity: z.number().finite().min(0).max(1).optional()
63
- }).default({ kind: "solid" }),
64
- grid: z.object({
65
- visible: z.boolean().default(false),
66
- size: z.number().finite().min(4).default(24),
67
- opacity: z.number().finite().min(0).max(1).default(.12)
68
- }).default({
69
- visible: false,
70
- size: 24,
71
- opacity: .12
72
- })
73
- });
74
- /** Optional visual chrome still carried by a few older shapes. */
75
- const BoardItemStyleSchema = z.object({
76
- variant: z.string().min(1).default("default"),
77
- theme: z.string().min(1).optional(),
78
- accentColor: z.string().optional(),
79
- size: z.enum([
80
- "sm",
81
- "md",
82
- "lg"
83
- ]).default("md"),
84
- emphasis: z.enum([
85
- "normal",
86
- "rare",
87
- "epic",
88
- "legendary"
89
- ]).default("normal"),
90
- effects: z.array(z.string().min(1)).default([])
91
- });
92
- const SpaceFileRefSchema = z.object({
93
- kind: z.literal("space-file"),
94
- path: z.string().min(1)
95
- });
96
- const BoardMediaSnapshotSchema = z.object({
97
- title: z.string().optional(),
98
- mimeType: z.string().optional(),
99
- size: z.number().finite().nonnegative().optional(),
100
- mtimeMs: z.number().finite().nonnegative().optional(),
101
- /** Intrinsic pixel size once known. */
102
- naturalWidth: z.number().finite().positive().optional(),
103
- naturalHeight: z.number().finite().positive().optional()
104
- });
105
- const BoardItemBaseSchema = z.object({
106
- id: z.string().min(1),
107
- frame: BoardFrameSchema,
108
- parentId: z.string().min(1).nullable().optional(),
109
- /** When true the shape cannot be moved, resized, or deleted. */
110
- locked: z.boolean().optional(),
111
- style: BoardItemStyleSchema.optional(),
112
- metadata: z.record(z.string(), z.unknown()).optional()
113
- });
114
- /** Freestanding text — no card chrome; its frame always follows the glyphs. */
115
- const BoardTextItemSchema = BoardItemBaseSchema.extend({
116
- type: z.literal("text"),
117
- text: z.string().default(""),
118
- color: z.string().min(1).default("neutral"),
119
- fontSize: z.number().finite().min(2).max(512).default(24)
120
- });
121
- const BoardGeoItemSchema = BoardItemBaseSchema.extend({
122
- type: z.literal("geo"),
123
- geo: z.string().min(1).default("rectangle"),
124
- text: z.string().default(""),
125
- color: z.string().min(1).default("brand"),
126
- fillOpacity: z.number().finite().min(0).max(1).default(0)
127
- });
128
- /** A raw freehand sample. Pressure defaults to 0.5 (mouse) when absent. */
129
- const DrawPointSchema = z.object({
130
- x: z.number().finite(),
131
- y: z.number().finite(),
132
- p: z.number().finite().min(0).max(1).default(.5)
133
- });
134
- /** A world-space point. */
135
- const BoardPointSchema = z.object({
136
- x: z.number().finite(),
137
- y: z.number().finite()
138
- });
139
- const BoardDrawItemSchema = BoardItemBaseSchema.extend({
140
- type: z.literal("draw"),
141
- points: z.array(DrawPointSchema).default([]),
142
- color: z.string().min(1).default("brand"),
143
- size: z.number().finite().positive().default(4)
144
- });
145
- /**
146
- * A free arrow — a standalone annotation stroke between two world points.
147
- *
148
- * Arrows do not relate nodes. A relation between two nodes is a
149
- * `BoardConnection`, which is stored separately and resolves its geometry from
150
- * the live node frames. Keeping the two apart is what lets an arrow be a plain
151
- * shape (its own frame, freely movable) while a connection stays purely
152
- * semantic — neither has to pretend to be the other.
153
- */
154
- const BoardArrowItemSchema = BoardItemBaseSchema.extend({
155
- type: z.literal("arrow"),
156
- start: BoardPointSchema,
157
- end: BoardPointSchema,
158
- bend: z.number().finite().min(-.85).max(.85).default(0),
159
- color: z.string().min(1).default("brand"),
160
- size: z.number().finite().positive().default(BOARD_ARROW_STROKE_SIZE),
161
- arrowStart: z.boolean().default(false),
162
- arrowEnd: z.boolean().default(true),
163
- label: z.string().default("")
164
- });
165
- /** A frame container for organising shapes. */
166
- const BoardFrameItemSchema = BoardItemBaseSchema.extend({
167
- type: z.literal("frame"),
168
- label: z.string().default("Frame"),
169
- color: z.string().min(1).default("neutral")
170
- });
171
- /** Image node — space file only, natural aspect, no chrome. */
172
- const BoardImageItemSchema = BoardItemBaseSchema.extend({
173
- type: z.literal("image"),
174
- ref: SpaceFileRefSchema,
175
- snapshot: BoardMediaSnapshotSchema.optional(),
176
- /** Optional normalized crop in source image space (0..1). */
177
- crop: z.object({
178
- x: z.number().finite().min(0).max(1).default(0),
179
- y: z.number().finite().min(0).max(1).default(0),
180
- w: z.number().finite().min(0).max(1).default(1),
181
- h: z.number().finite().min(0).max(1).default(1)
182
- }).optional()
183
- });
184
- /** Video node — space file only. Playback state is local UI, never synced. */
185
- const BoardVideoItemSchema = BoardItemBaseSchema.extend({
186
- type: z.literal("video"),
187
- ref: SpaceFileRefSchema,
188
- snapshot: BoardMediaSnapshotSchema.optional()
189
- });
190
- /** Audio node — space file only. Playback state is local UI, never synced. */
191
- const BoardAudioItemSchema = BoardItemBaseSchema.extend({
192
- type: z.literal("audio"),
193
- ref: SpaceFileRefSchema,
194
- snapshot: BoardMediaSnapshotSchema.extend({ durationMs: z.number().finite().nonnegative().optional() }).optional()
195
- });
196
- /**
197
- * Cached display facts for a file card.
198
- *
199
- * Purely derived from the referenced file and versioned by `mtimeMs`, so it is a
200
- * cache and never a second source of truth: the workspace file remains
201
- * authoritative, and a stale snapshot is detectable rather than silently wrong.
202
- * It is stored so that opening a board renders complete cards immediately, with
203
- * no per-node file read on the first paint.
204
- */
205
- const BoardFileSnapshotSchema = z.object({
206
- title: z.string().optional(),
207
- mimeType: z.string().optional(),
208
- size: z.number().finite().nonnegative().optional(),
209
- mtimeMs: z.number().finite().nonnegative().optional(),
210
- /** Cleaned leading prose. Capped when written (see FILE_EXCERPT_MAX_CHARS). */
211
- excerpt: z.string().optional(),
212
- /** Cover image inside the space, already resolved to a workspace path. */
213
- coverPath: z.string().optional(),
214
- /** Cover image at an absolute https URL, as declared by the file itself. */
215
- coverUrl: z.string().optional()
216
- });
217
- /**
218
- * File node — a thumbnail entry point to any workspace file.
219
- *
220
- * This is the fallback for every dropped file that is not natively an image or
221
- * video, including binaries and unknown extensions: a board should never refuse
222
- * a file, only present it with less detail. Presentation tiers are derived from
223
- * the snapshot (see filePreviewKind), not stored, so there is no display state
224
- * to drift from the facts.
225
- */
226
- const BoardFileItemSchema = BoardItemBaseSchema.extend({
227
- type: z.literal("file"),
228
- ref: SpaceFileRefSchema,
229
- snapshot: BoardFileSnapshotSchema.optional()
230
- });
231
- const BOARD_TASK_ARTIFACT_LIMIT = 6;
232
- const BoardTaskMediaArtifactFields = {
233
- id: z.string().min(1).max(240),
234
- title: z.string().max(240).optional(),
235
- url: BoardRemoteUrlSchema,
236
- mimeType: z.string().max(160).optional()
237
- };
238
- const BoardTaskArtifactSchema = z.discriminatedUnion("type", [
239
- z.object({
240
- ...BoardTaskMediaArtifactFields,
241
- type: z.literal("image"),
242
- naturalWidth: z.number().positive().optional(),
243
- naturalHeight: z.number().positive().optional()
244
- }).strict(),
245
- z.object({
246
- ...BoardTaskMediaArtifactFields,
247
- type: z.literal("video"),
248
- previewUrl: BoardRemoteUrlSchema.optional(),
249
- durationMs: z.number().int().positive().optional(),
250
- naturalWidth: z.number().positive().optional(),
251
- naturalHeight: z.number().positive().optional()
252
- }).strict(),
253
- z.object({
254
- ...BoardTaskMediaArtifactFields,
255
- type: z.literal("audio"),
256
- previewUrl: BoardRemoteUrlSchema.optional(),
257
- durationMs: z.number().int().positive().optional()
258
- }).strict(),
259
- z.object({
260
- id: z.string().min(1).max(240),
261
- type: z.literal("text"),
262
- title: z.string().max(240).optional(),
263
- textExcerpt: z.string().min(1).max(480)
264
- }).strict()
265
- ]);
266
- /**
267
- * Cached task facts used for an immediate first paint. The task run remains the
268
- * source of truth and live clients refresh this projection by `taskRunId`.
269
- */
270
- const BoardTaskSnapshotSchema = z.object({
271
- taskType: z.string().min(1).max(120),
272
- status: z.enum([
273
- "pending",
274
- "running",
275
- "completed",
276
- "failed"
277
- ]),
278
- title: z.string().min(1).max(240),
279
- model: z.string().max(160).optional(),
280
- promptExcerpt: z.string().max(480).optional(),
281
- artifactCount: z.number().int().nonnegative(),
282
- artifacts: z.array(BoardTaskArtifactSchema).max(6).default([]),
283
- updatedAt: z.string().optional()
284
- }).strict();
285
- /** A stable reference to a task run with a small, replaceable display cache. */
286
- const BoardTaskItemSchema = BoardItemBaseSchema.extend({
287
- type: z.literal("task"),
288
- taskRunId: z.string().min(1),
289
- snapshot: BoardTaskSnapshotSchema
290
- });
291
- /**
292
- * The set of shape types this client understands natively. Anything else is
293
- * preserved verbatim as an unknown item (see BoardUnknownItem) so documents
294
- * authored by newer clients round-trip losslessly — data is never dropped or
295
- * silently downgraded just because this client predates a shape type.
296
- */
297
- const KNOWN_BOARD_ITEM_TYPES = [
298
- "image",
299
- "video",
300
- "audio",
301
- "file",
302
- "task",
303
- "text",
304
- "geo",
305
- "draw",
306
- "arrow",
307
- "frame"
308
- ];
309
- /**
310
- * A forward-compatible carrier for shape types this client does not recognise.
311
- * Its discriminant is the literal `"unknown"` so the item union still narrows
312
- * cleanly on `type`. The real type string and every original field are preserved
313
- * verbatim in `raw`.
314
- */
315
- const UNKNOWN_BOARD_ITEM_TYPE = "unknown";
316
- /** The real (preserved) type string of an unknown item. */
317
- function unknownRealType(item) {
318
- const real = item.raw.type;
319
- return typeof real === "string" && real ? real : "unknown";
320
- }
321
- const BoardItemSchema = z.any().transform((raw) => parseBoardItemLoose(raw));
322
- /**
323
- * Parse a single item leniently: known types are validated and normalised;
324
- * anything else becomes a lossless unknown item. Never throws on shape data —
325
- * a malformed known item degrades to unknown rather than failing the document.
326
- */
327
- function parseBoardItemLoose(raw) {
328
- if (!raw || typeof raw !== "object") return makeUnknownItem(raw);
329
- switch (raw.type) {
330
- case "image": {
331
- const parsed = BoardImageItemSchema.safeParse(raw);
332
- return parsed.success ? parsed.data : makeUnknownItem(raw);
333
- }
334
- case "video": {
335
- const parsed = BoardVideoItemSchema.safeParse(raw);
336
- return parsed.success ? parsed.data : makeUnknownItem(raw);
337
- }
338
- case "audio": {
339
- const parsed = BoardAudioItemSchema.safeParse(raw);
340
- return parsed.success ? parsed.data : makeUnknownItem(raw);
341
- }
342
- case "file": {
343
- const parsed = BoardFileItemSchema.safeParse(raw);
344
- return parsed.success ? parsed.data : makeUnknownItem(raw);
345
- }
346
- case "task": {
347
- const parsed = BoardTaskItemSchema.safeParse(raw);
348
- return parsed.success ? parsed.data : makeUnknownItem(raw);
349
- }
350
- case "text": {
351
- const parsed = BoardTextItemSchema.safeParse(raw);
352
- return parsed.success ? parsed.data : makeUnknownItem(raw);
353
- }
354
- case "geo": {
355
- const parsed = BoardGeoItemSchema.safeParse(raw);
356
- return parsed.success ? parsed.data : makeUnknownItem(raw);
357
- }
358
- case "draw": {
359
- const parsed = BoardDrawItemSchema.safeParse(raw);
360
- return parsed.success ? parsed.data : makeUnknownItem(raw);
361
- }
362
- case "arrow": {
363
- const parsed = BoardArrowItemSchema.safeParse(raw);
364
- return parsed.success ? parsed.data : makeUnknownItem(raw);
365
- }
366
- case "frame": {
367
- const parsed = BoardFrameItemSchema.safeParse(raw);
368
- return parsed.success ? parsed.data : makeUnknownItem(raw);
369
- }
370
- default: return makeUnknownItem(raw);
371
- }
372
- }
373
- function makeUnknownItem(raw) {
374
- const record = raw && typeof raw === "object" ? raw : {};
375
- const frameParsed = BoardFrameSchema.safeParse(record.frame);
376
- const styleParsed = BoardItemStyleSchema.safeParse(record.style);
377
- return {
378
- id: typeof record.id === "string" && record.id ? record.id : "unknown",
379
- type: UNKNOWN_BOARD_ITEM_TYPE,
380
- frame: frameParsed.success ? frameParsed.data : {
381
- x: 0,
382
- y: 0,
383
- width: 120,
384
- height: 80,
385
- rotation: 0
386
- },
387
- ...typeof record.parentId === "string" || record.parentId === null ? { parentId: record.parentId } : {},
388
- ...record.locked === true ? { locked: true } : {},
389
- ...styleParsed.success && record.style ? { style: styleParsed.data } : {},
390
- ...record.metadata && typeof record.metadata === "object" ? { metadata: record.metadata } : {},
391
- raw: record
392
- };
393
- }
394
- const BoardDocumentSchema = z.object({
395
- kind: z.literal(BOARD_DOCUMENT_KIND),
396
- version: z.literal(1),
397
- appearance: BoardAppearanceSchema.default({
398
- background: { kind: "solid" },
399
- grid: {
400
- visible: false,
401
- size: 24,
402
- opacity: .12
403
- }
404
- }),
405
- viewport: BoardViewportSchema,
406
- items: z.array(BoardItemSchema),
407
- /**
408
- * Node relations. Separate from `items` because a connection has no frame of
409
- * its own — its geometry is derived from the nodes it joins, so it is a
410
- * relation over the item set rather than a member of it.
411
- *
412
- * Connections referencing a missing node are dropped on parse: a relation to
413
- * nothing is not a relation, and keeping one would let an invisible dangling
414
- * edge accumulate silently. Callers that need to know write through the
415
- * transaction API, which reports the reference error instead.
416
- */
417
- connections: z.array(BoardConnectionSchema).default([])
418
- });
419
- /**
420
- * Parse a board document and drop connections whose endpoints are missing.
421
- *
422
- * The schema alone cannot express "every endpoint must name an existing item",
423
- * so referential integrity is enforced here, at the single place a document
424
- * enters the system. A dangling connection is dropped rather than repaired:
425
- * there is no correct node to invent, and keeping it would render nothing while
426
- * still counting as data.
427
- *
428
- * Item parsing stays lenient (see parseBoardItemLoose) — nodes carry content and
429
- * are never discarded — while connections are pure references and are only
430
- * meaningful with both ends present.
431
- */
432
- function parseBoardDocument(input) {
433
- return withResolvedConnections(BoardDocumentSchema.parse(input));
434
- }
435
- /** Keep only the connections whose endpoints both exist in `items`. */
436
- function withResolvedConnections(document) {
437
- if (document.connections.length === 0) return document;
438
- const ids = new Set(document.items.map((item) => item.id));
439
- const connections = document.connections.filter((connection) => ids.has(connection.source.itemId) && ids.has(connection.target.itemId));
440
- return connections.length === document.connections.length ? document : {
441
- ...document,
442
- connections
443
- };
444
- }
445
- function isUnknownItem(item) {
446
- return item.type === UNKNOWN_BOARD_ITEM_TYPE;
447
- }
448
- function isMediaItem(item) {
449
- return item.type === "image" || item.type === "video" || item.type === "audio";
450
- }
451
- /** Whether an item references a workspace file (media or file card). */
452
- function isFileBackedItem(item) {
453
- return item.type === "image" || item.type === "video" || item.type === "audio" || item.type === "file";
454
- }
455
- //#endregion
456
- export { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearanceSchema, BoardArrowItemSchema, BoardAudioItemSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema, BoardPointSchema, BoardRemoteUrlSchema, BoardTaskArtifactSchema, BoardTaskItemSchema, BoardTaskSnapshotSchema, BoardTextItemSchema, BoardVideoItemSchema, BoardViewportSchema, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isPublicBoardRemoteAddress, isUnknownItem, normalizeBoardRemoteUrl, parseBoardDocument, parseBoardItemLoose, unknownRealType, withResolvedConnections };
@@ -1,96 +0,0 @@
1
- import { z } from "zod";
2
- //#region ../protocol/dist/board-effect.d.ts
3
- declare const BoardAssetRefSchema: z.ZodObject<{
4
- type: z.ZodEnum<{
5
- extension: "extension";
6
- "space-file": "space-file";
7
- }>;
8
- ref: z.ZodString;
9
- digest: z.ZodOptional<z.ZodString>;
10
- }, z.core.$strict>;
11
- declare const BoardEffectSchema: z.ZodObject<{
12
- id: z.ZodString;
13
- boardId: z.ZodString;
14
- target: z.ZodDiscriminatedUnion<[z.ZodObject<{
15
- type: z.ZodLiteral<"item">;
16
- itemId: z.ZodString;
17
- }, z.core.$strict>, z.ZodObject<{
18
- type: z.ZodLiteral<"board">;
19
- }, z.core.$strict>], "type">;
20
- kind: z.ZodString;
21
- kindVersion: z.ZodDefault<z.ZodNumber>;
22
- enabled: z.ZodDefault<z.ZodBoolean>;
23
- lifecycle: z.ZodEnum<{
24
- manual: "manual";
25
- "on-enter": "on-enter";
26
- persistent: "persistent";
27
- "when-visible": "when-visible";
28
- }>;
29
- timeOrigin: z.ZodEnum<{
30
- activation: "activation";
31
- board: "board";
32
- visible: "visible";
33
- }>;
34
- layer: z.ZodDefault<z.ZodEnum<{
35
- behind: "behind";
36
- front: "front";
37
- screen: "screen";
38
- }>>;
39
- seed: z.ZodString;
40
- params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
41
- assetRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
42
- type: z.ZodEnum<{
43
- extension: "extension";
44
- "space-file": "space-file";
45
- }>;
46
- ref: z.ZodString;
47
- digest: z.ZodOptional<z.ZodString>;
48
- }, z.core.$strict>>>;
49
- metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
50
- revision: z.ZodNumber;
51
- }, z.core.$strict>;
52
- type BoardAssetRef = z.infer<typeof BoardAssetRefSchema>;
53
- type BoardEffect = z.infer<typeof BoardEffectSchema>;
54
- /** The client-authored effect form: no server-owned `boardId`/`revision`. */
55
- declare const BoardEffectInputSchema: z.ZodObject<{
56
- id: z.ZodString;
57
- target: z.ZodDiscriminatedUnion<[z.ZodObject<{
58
- type: z.ZodLiteral<"item">;
59
- itemId: z.ZodString;
60
- }, z.core.$strict>, z.ZodObject<{
61
- type: z.ZodLiteral<"board">;
62
- }, z.core.$strict>], "type">;
63
- kind: z.ZodString;
64
- kindVersion: z.ZodDefault<z.ZodNumber>;
65
- enabled: z.ZodDefault<z.ZodBoolean>;
66
- lifecycle: z.ZodEnum<{
67
- manual: "manual";
68
- "on-enter": "on-enter";
69
- persistent: "persistent";
70
- "when-visible": "when-visible";
71
- }>;
72
- timeOrigin: z.ZodEnum<{
73
- activation: "activation";
74
- board: "board";
75
- visible: "visible";
76
- }>;
77
- layer: z.ZodDefault<z.ZodEnum<{
78
- behind: "behind";
79
- front: "front";
80
- screen: "screen";
81
- }>>;
82
- seed: z.ZodString;
83
- params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
84
- assetRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
85
- type: z.ZodEnum<{
86
- extension: "extension";
87
- "space-file": "space-file";
88
- }>;
89
- ref: z.ZodString;
90
- digest: z.ZodOptional<z.ZodString>;
91
- }, z.core.$strict>>>;
92
- metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
93
- }, z.core.$strict>;
94
- type BoardEffectInput = z.infer<typeof BoardEffectInputSchema>;
95
- //#endregion
96
- export { BoardAssetRef, BoardAssetRefSchema, BoardEffect, BoardEffectInput, BoardEffectInputSchema, BoardEffectSchema };
@@ -1,54 +0,0 @@
1
- import { z } from "zod";
2
- //#region ../protocol/dist/board-effect.js
3
- /**
4
- * Board effect schema, isolated so `board-authoring.ts` can reuse the exact
5
- * definition without a runtime cycle through `board.ts`. One definition, one
6
- * strictness level — semantic mutations and Board create must not drift apart.
7
- */
8
- const idSchema = z.string().min(1).max(160);
9
- const extensionIdSchema = z.string().regex(/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+$/).max(160);
10
- const jsonObjectSchema = z.record(z.string(), z.unknown());
11
- const BoardAssetRefSchema = z.object({
12
- type: z.enum(["space-file", "extension"]),
13
- ref: z.string().min(1).max(4096),
14
- digest: z.string().min(16).max(160).optional()
15
- }).strict();
16
- const BoardEffectSchema = z.object({
17
- id: idSchema,
18
- boardId: z.string().uuid(),
19
- target: z.discriminatedUnion("type", [z.object({
20
- type: z.literal("item"),
21
- itemId: idSchema
22
- }).strict(), z.object({ type: z.literal("board") }).strict()]),
23
- kind: extensionIdSchema,
24
- kindVersion: z.number().int().positive().default(1),
25
- enabled: z.boolean().default(true),
26
- lifecycle: z.enum([
27
- "persistent",
28
- "when-visible",
29
- "manual",
30
- "on-enter"
31
- ]),
32
- timeOrigin: z.enum([
33
- "board",
34
- "visible",
35
- "activation"
36
- ]),
37
- layer: z.enum([
38
- "behind",
39
- "front",
40
- "screen"
41
- ]).default("front"),
42
- seed: z.string().min(1).max(160),
43
- params: jsonObjectSchema.default({}),
44
- assetRefs: z.array(BoardAssetRefSchema).default([]),
45
- metadata: jsonObjectSchema.default({}),
46
- revision: z.number().int().nonnegative()
47
- }).strict();
48
- /** The client-authored effect form: no server-owned `boardId`/`revision`. */
49
- const BoardEffectInputSchema = BoardEffectSchema.omit({
50
- boardId: true,
51
- revision: true
52
- });
53
- //#endregion
54
- export { BoardAssetRefSchema, BoardEffectInputSchema, BoardEffectSchema };
@@ -1,15 +0,0 @@
1
- import { BoardFrame, BoardPoint, DrawPoint } from "./board-document.js";
2
- //#region ../protocol/dist/board-geometry.d.ts
3
- type BoardArrowGeometryInput = {
4
- start: BoardPoint;
5
- end: BoardPoint;
6
- bend: number;
7
- size: number;
8
- };
9
- /** Radius of a draw sample in world units given stroke size and pressure. */
10
- declare function boardDrawSampleRadius(size: number, pressure: number): number;
11
- /** Exact local bounds required by the draw node contract. */
12
- declare function boardDrawBounds(points: readonly DrawPoint[], size: number): Pick<BoardFrame, "x" | "y" | "width" | "height">;
13
- declare function boardArrowFrame(input: BoardArrowGeometryInput): BoardFrame;
14
- //#endregion
15
- export { BoardArrowGeometryInput, boardArrowFrame, boardDrawBounds, boardDrawSampleRadius };