@neta-art/cohub 8.10.2 → 8.12.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.
- package/dist/board/animation.js +14 -2
- package/dist/board/core/file-preview.d.ts +20 -141
- package/dist/board/core/file-preview.js +25 -202
- package/dist/board/core/file-snapshot.d.ts +106 -0
- package/dist/board/core/file-snapshot.js +503 -0
- package/dist/board/index.d.ts +4 -2
- package/dist/board/index.js +4 -2
- package/dist/board/mutation.js +2 -1
- package/dist/board/render/board-background.d.ts +16 -0
- package/dist/board/render/{themes/clean-theme.js → board-background.js} +28 -35
- package/dist/board/render/index.d.ts +3 -3
- package/dist/board/render/index.js +2 -2
- package/dist/board/render/renderers/file-card-renderer.js +62 -17
- package/dist/board/replay.d.ts +52 -0
- package/dist/board/replay.js +261 -0
- package/dist/board/semantic-document.d.ts +9 -2
- package/dist/board/semantic-document.js +1 -3
- package/dist/chunks/environment.d.ts +272 -7
- package/dist/chunks/environment.js +1 -0
- package/dist/chunks/http.d.ts +109 -7
- package/dist/chunks/http.js +47 -10
- package/dist/chunks/websocket.d.ts +1 -1
- package/dist/http.d.ts +3 -3
- package/dist/index.d.ts +65 -4
- package/dist/index.js +514 -64
- package/dist/protocol/dist/board-animation.d.ts +1 -0
- package/dist/protocol/dist/board-animation.js +34 -0
- package/dist/protocol/dist/board-authoring.d.ts +2 -1
- package/dist/protocol/dist/board-capability-registry.js +53 -3
- package/dist/protocol/dist/board-codec.js +149 -2
- package/dist/protocol/dist/board-constants.js +29 -7
- package/dist/protocol/dist/board-document.d.ts +30 -16
- package/dist/protocol/dist/board-document.js +15 -12
- package/dist/protocol/dist/board-effect.d.ts +4 -2
- package/dist/protocol/dist/board-effect.js +3 -2
- package/dist/protocol/dist/board.d.ts +148 -3
- package/dist/protocol/dist/board.js +7 -0
- package/dist/protocol/dist/index.d.ts +4 -2
- package/dist/protocol/dist/provenance.d.ts +21 -0
- package/dist/types.d.ts +1 -1
- package/docs/app-runtime-guide.md +28 -3
- package/package.json +1 -1
- package/dist/board/render/themes/board-theme-registry.d.ts +0 -22
- package/dist/board/render/themes/board-theme-registry.js +0 -13
- package/dist/board/render/themes/clean-theme.d.ts +0 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region ../protocol/dist/board-animation.js
|
|
3
|
+
const extensionKindSchema = z.string().regex(/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+$/).max(160);
|
|
4
|
+
const jsonObjectSchema = z.record(z.string(), z.unknown());
|
|
5
|
+
const finiteSchema = z.number().finite();
|
|
6
|
+
/** Parameters shared by the built-in deal entrance preset. */
|
|
7
|
+
const BoardDealParamsSchema = z.object({
|
|
8
|
+
lift: finiteSchema.nonnegative().max(2e3).optional(),
|
|
9
|
+
swing: finiteSchema.nonnegative().max(2e3).optional(),
|
|
10
|
+
curve: finiteSchema.nonnegative().max(2e3).optional(),
|
|
11
|
+
tilt: finiteSchema.nonnegative().max(180).optional(),
|
|
12
|
+
scale: finiteSchema.positive().max(2).optional(),
|
|
13
|
+
duration: finiteSchema.positive().max(1e4).optional(),
|
|
14
|
+
landing: finiteSchema.nonnegative().max(1e4).optional()
|
|
15
|
+
}).strict();
|
|
16
|
+
/** A versioned, reusable animation preset reference. */
|
|
17
|
+
const BoardAnimationSpecSchema = z.object({
|
|
18
|
+
kind: extensionKindSchema,
|
|
19
|
+
kindVersion: z.number().int().positive().default(1),
|
|
20
|
+
params: jsonObjectSchema.default({})
|
|
21
|
+
}).strict().superRefine((spec, context) => {
|
|
22
|
+
if (spec.kind !== "effects.deal" || spec.kindVersion !== 1) return;
|
|
23
|
+
const parsed = BoardDealParamsSchema.safeParse(spec.params);
|
|
24
|
+
if (parsed.success) return;
|
|
25
|
+
context.addIssue({
|
|
26
|
+
code: "custom",
|
|
27
|
+
message: parsed.error.issues[0]?.message ?? "invalid effects.deal parameters",
|
|
28
|
+
path: ["params", ...parsed.error.issues[0]?.path ?? []]
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
/** Board-wide default motion policies. Omitted policies mean no motion. */
|
|
32
|
+
const BoardMotionSchema = z.object({ enter: BoardAnimationSpecSchema.optional() }).strict();
|
|
33
|
+
//#endregion
|
|
34
|
+
export { BoardAnimationSpecSchema, BoardDealParamsSchema, BoardMotionSchema };
|
|
@@ -1140,10 +1140,11 @@ declare const BoardSemanticCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1140
1140
|
type: z.ZodLiteral<"board">;
|
|
1141
1141
|
}, z.core.$strict>], "type">;
|
|
1142
1142
|
kind: z.ZodString;
|
|
1143
|
-
kindVersion: z.ZodNumber
|
|
1143
|
+
kindVersion: z.ZodDefault<z.ZodNumber>;
|
|
1144
1144
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1145
1145
|
lifecycle: z.ZodEnum<{
|
|
1146
1146
|
manual: "manual";
|
|
1147
|
+
"on-enter": "on-enter";
|
|
1147
1148
|
persistent: "persistent";
|
|
1148
1149
|
"when-visible": "when-visible";
|
|
1149
1150
|
}>;
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import { BOARD_BUILTIN_CLIP_KINDS, BOARD_BUILTIN_EFFECT_KINDS, DEFAULT_BOARD_RENDER_LIMITS } from "./board-constants.js";
|
|
1
|
+
import { BOARD_BUILTIN_CAPABILITIES, BOARD_BUILTIN_CLIP_KINDS, BOARD_BUILTIN_EFFECT_KINDS, DEFAULT_BOARD_RENDER_LIMITS } from "./board-constants.js";
|
|
2
2
|
import { BoardCameraFocusParamsSchema } from "./board.js";
|
|
3
|
+
import { BoardDealParamsSchema } from "./board-animation.js";
|
|
3
4
|
//#region ../protocol/dist/board-capability-registry.js
|
|
4
5
|
const CLIPS = new Set(BOARD_BUILTIN_CLIP_KINDS);
|
|
5
|
-
new Set(BOARD_BUILTIN_EFFECT_KINDS);
|
|
6
|
+
const EFFECTS = new Set(BOARD_BUILTIN_EFFECT_KINDS);
|
|
7
|
+
const BUILTIN_VERSIONS = new Set(BOARD_BUILTIN_CAPABILITIES.map((c) => `${c.kind}:${c.id}@${c.version}`));
|
|
8
|
+
/**
|
|
9
|
+
* True when a built-in renderer exists for exactly this kind@version. A known
|
|
10
|
+
* kind at an unknown version is not built-in: it must not pass as one.
|
|
11
|
+
*/
|
|
12
|
+
function isBuiltinBoardCapability(kind, id, version) {
|
|
13
|
+
return BUILTIN_VERSIONS.has(`${kind}:${id}@${version}`);
|
|
14
|
+
}
|
|
6
15
|
const record = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
7
16
|
const finite = (value) => typeof value === "number" && Number.isFinite(value);
|
|
8
17
|
function validateBuiltinBoardClip(clip, path = "clip") {
|
|
@@ -36,6 +45,47 @@ function validateBuiltinBoardClip(clip, path = "clip") {
|
|
|
36
45
|
}
|
|
37
46
|
return errors;
|
|
38
47
|
}
|
|
48
|
+
function validateBuiltinBoardEffect(effect, path = "effect") {
|
|
49
|
+
const diagnostics = [];
|
|
50
|
+
if (effect.lifecycle === "on-enter") {
|
|
51
|
+
if (effect.target.type !== "item") diagnostics.push({
|
|
52
|
+
severity: "error",
|
|
53
|
+
code: "INVALID_BOARD_EFFECT",
|
|
54
|
+
message: "on-enter effects must target an item",
|
|
55
|
+
path: `${path}.target`
|
|
56
|
+
});
|
|
57
|
+
if (effect.timeOrigin !== "activation") diagnostics.push({
|
|
58
|
+
severity: "error",
|
|
59
|
+
code: "INVALID_BOARD_EFFECT",
|
|
60
|
+
message: "on-enter effects must use activation time",
|
|
61
|
+
path: `${path}.timeOrigin`
|
|
62
|
+
});
|
|
63
|
+
} else if (EFFECTS.has(effect.kind) && effect.target.type !== "item") diagnostics.push({
|
|
64
|
+
severity: "error",
|
|
65
|
+
code: "INVALID_BOARD_EFFECT",
|
|
66
|
+
message: `${effect.kind} must target an item`,
|
|
67
|
+
path: `${path}.target`
|
|
68
|
+
});
|
|
69
|
+
if (effect.kind === "effects.deal" && effect.kindVersion === 1) {
|
|
70
|
+
if (effect.lifecycle !== "on-enter") diagnostics.push({
|
|
71
|
+
severity: "error",
|
|
72
|
+
code: "INVALID_BOARD_EFFECT",
|
|
73
|
+
message: "effects.deal must use the on-enter lifecycle",
|
|
74
|
+
path: `${path}.lifecycle`
|
|
75
|
+
});
|
|
76
|
+
const parsed = BoardDealParamsSchema.safeParse(effect.params);
|
|
77
|
+
if (!parsed.success) diagnostics.push({
|
|
78
|
+
severity: "error",
|
|
79
|
+
code: "INVALID_BOARD_EFFECT",
|
|
80
|
+
message: parsed.error.issues[0]?.message ?? "invalid effects.deal parameters",
|
|
81
|
+
path: `${path}.params`
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
return diagnostics;
|
|
85
|
+
}
|
|
86
|
+
function estimateBuiltinBoardEffectCost(effect) {
|
|
87
|
+
return isBuiltinBoardCapability("effect", effect.kind, effect.kindVersion) ? { drawCalls: 1 } : {};
|
|
88
|
+
}
|
|
39
89
|
function estimateBuiltinBoardClipCost(clip) {
|
|
40
90
|
switch (clip.kind) {
|
|
41
91
|
case "effects.particles": {
|
|
@@ -70,4 +120,4 @@ function estimateBuiltinBoardClipCost(clip) {
|
|
|
70
120
|
}
|
|
71
121
|
}
|
|
72
122
|
//#endregion
|
|
73
|
-
export { estimateBuiltinBoardClipCost, validateBuiltinBoardClip };
|
|
123
|
+
export { estimateBuiltinBoardClipCost, estimateBuiltinBoardEffectCost, isBuiltinBoardCapability, validateBuiltinBoardClip, validateBuiltinBoardEffect };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BoardAuthoringItemSchema, BoardItemPatchSchema } from "./board-authoring.js";
|
|
2
2
|
import { BoardNodeInputSchema } from "./board.js";
|
|
3
|
-
import { boardArrowFrame, boardDrawBounds, boardDrawPointsToLocal } from "./board-geometry.js";
|
|
3
|
+
import { boardArrowFrame, boardDrawBounds, boardDrawPointsToLocal, boardDrawPointsToWorld } from "./board-geometry.js";
|
|
4
4
|
import { BOARD_NATIVE_NODE_TYPES, validateBoardNodeInput } from "./board-node.js";
|
|
5
5
|
//#region ../protocol/dist/board-codec.js
|
|
6
6
|
var BoardItemValidationError = class extends Error {
|
|
@@ -30,6 +30,153 @@ function authoringDiagnostic(diagnostic, path) {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
const isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
33
|
+
function baseItem(node) {
|
|
34
|
+
return {
|
|
35
|
+
id: node.nodeId,
|
|
36
|
+
position: {
|
|
37
|
+
x: node.x,
|
|
38
|
+
y: node.y
|
|
39
|
+
},
|
|
40
|
+
size: {
|
|
41
|
+
width: node.width,
|
|
42
|
+
height: node.height
|
|
43
|
+
},
|
|
44
|
+
rotation: node.rotation,
|
|
45
|
+
...node.parentId ? { parentId: node.parentId } : {},
|
|
46
|
+
...node.data.locked === true ? { locked: true } : {},
|
|
47
|
+
...isRecord(node.data.metadata) ? { metadata: node.data.metadata } : {}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function filePath(node) {
|
|
51
|
+
if (!node.refPath) throw new Error(`Board item ${node.nodeId} is missing its source path`);
|
|
52
|
+
return node.refPath;
|
|
53
|
+
}
|
|
54
|
+
function style(node) {
|
|
55
|
+
const value = {};
|
|
56
|
+
if (typeof node.data.color === "string") value.color = node.data.color;
|
|
57
|
+
if (typeof node.data.size === "number") value.strokeWidth = node.data.size;
|
|
58
|
+
if (typeof node.data.fillOpacity === "number") value.fillOpacity = node.data.fillOpacity;
|
|
59
|
+
return Object.keys(value).length ? value : void 0;
|
|
60
|
+
}
|
|
61
|
+
function boardNodeToAuthoringItem(node) {
|
|
62
|
+
const base = baseItem(node);
|
|
63
|
+
if (node.type === "draw" || node.type === "arrow") {
|
|
64
|
+
delete base.size;
|
|
65
|
+
delete base.position;
|
|
66
|
+
}
|
|
67
|
+
const visual = style(node);
|
|
68
|
+
let candidate;
|
|
69
|
+
switch (node.type) {
|
|
70
|
+
case "text":
|
|
71
|
+
candidate = {
|
|
72
|
+
...base,
|
|
73
|
+
type: "text",
|
|
74
|
+
props: {
|
|
75
|
+
text: node.data.text ?? "",
|
|
76
|
+
fontSize: node.data.fontSize ?? 24
|
|
77
|
+
},
|
|
78
|
+
...visual ? { style: visual } : {}
|
|
79
|
+
};
|
|
80
|
+
break;
|
|
81
|
+
case "geo":
|
|
82
|
+
candidate = {
|
|
83
|
+
...base,
|
|
84
|
+
type: "geo",
|
|
85
|
+
props: {
|
|
86
|
+
shape: node.data.geo ?? "rectangle",
|
|
87
|
+
text: node.data.text ?? ""
|
|
88
|
+
},
|
|
89
|
+
...visual ? { style: visual } : {}
|
|
90
|
+
};
|
|
91
|
+
break;
|
|
92
|
+
case "draw":
|
|
93
|
+
candidate = {
|
|
94
|
+
...base,
|
|
95
|
+
type: "draw",
|
|
96
|
+
props: { points: Array.isArray(node.data.points) ? boardDrawPointsToWorld(node.data.points, node.x, node.y) : [] },
|
|
97
|
+
...visual ? { style: visual } : {}
|
|
98
|
+
};
|
|
99
|
+
break;
|
|
100
|
+
case "arrow":
|
|
101
|
+
candidate = {
|
|
102
|
+
...base,
|
|
103
|
+
type: "arrow",
|
|
104
|
+
props: {
|
|
105
|
+
start: node.data.start,
|
|
106
|
+
end: node.data.end,
|
|
107
|
+
bend: node.data.bend ?? 0,
|
|
108
|
+
arrowStart: node.data.arrowStart ?? false,
|
|
109
|
+
arrowEnd: node.data.arrowEnd ?? true,
|
|
110
|
+
label: node.data.label ?? ""
|
|
111
|
+
},
|
|
112
|
+
...visual ? { style: visual } : {}
|
|
113
|
+
};
|
|
114
|
+
break;
|
|
115
|
+
case "frame":
|
|
116
|
+
candidate = {
|
|
117
|
+
...base,
|
|
118
|
+
type: "frame",
|
|
119
|
+
props: { label: node.data.label ?? "Frame" },
|
|
120
|
+
...visual ? { style: visual } : {}
|
|
121
|
+
};
|
|
122
|
+
break;
|
|
123
|
+
case "image":
|
|
124
|
+
candidate = {
|
|
125
|
+
...base,
|
|
126
|
+
type: "image",
|
|
127
|
+
props: isRecord(node.data.crop) ? { crop: node.data.crop } : {},
|
|
128
|
+
source: {
|
|
129
|
+
kind: "space-file",
|
|
130
|
+
path: filePath(node),
|
|
131
|
+
...Object.keys(node.view).length ? { snapshot: node.view } : {}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
break;
|
|
135
|
+
case "video":
|
|
136
|
+
case "audio":
|
|
137
|
+
case "file":
|
|
138
|
+
candidate = {
|
|
139
|
+
...base,
|
|
140
|
+
type: node.type,
|
|
141
|
+
props: {},
|
|
142
|
+
source: {
|
|
143
|
+
kind: "space-file",
|
|
144
|
+
path: filePath(node),
|
|
145
|
+
...Object.keys(node.view).length ? { snapshot: node.view } : {}
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
break;
|
|
149
|
+
case "task":
|
|
150
|
+
candidate = {
|
|
151
|
+
...base,
|
|
152
|
+
type: "task",
|
|
153
|
+
props: {
|
|
154
|
+
taskRunId: node.data.taskRunId,
|
|
155
|
+
snapshot: node.view
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
break;
|
|
159
|
+
default: {
|
|
160
|
+
const props = { ...node.data };
|
|
161
|
+
delete props.locked;
|
|
162
|
+
delete props.metadata;
|
|
163
|
+
delete props.kindVersion;
|
|
164
|
+
candidate = {
|
|
165
|
+
...base,
|
|
166
|
+
type: node.type,
|
|
167
|
+
kindVersion: typeof node.data.kindVersion === "number" ? node.data.kindVersion : 1,
|
|
168
|
+
props,
|
|
169
|
+
...Object.keys(node.style).length ? { style: node.style } : {},
|
|
170
|
+
...node.refPath ? { source: {
|
|
171
|
+
kind: node.refKind ?? "space-file",
|
|
172
|
+
ref: node.refPath,
|
|
173
|
+
...Object.keys(node.view).length ? { snapshot: node.view } : {}
|
|
174
|
+
} } : {}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return BoardAuthoringItemSchema.parse(candidate);
|
|
179
|
+
}
|
|
33
180
|
function commonData(item) {
|
|
34
181
|
return {
|
|
35
182
|
...item.locked ? { locked: true } : {},
|
|
@@ -233,4 +380,4 @@ function mergePatch(current, patch) {
|
|
|
233
380
|
return result;
|
|
234
381
|
}
|
|
235
382
|
//#endregion
|
|
236
|
-
export { BoardItemValidationError, applyBoardItemPatch, authoringSchemaDiagnostics, boardAuthoringItemToNode };
|
|
383
|
+
export { BoardItemValidationError, applyBoardItemPatch, authoringSchemaDiagnostics, boardAuthoringItemToNode, boardNodeToAuthoringItem };
|
|
@@ -21,7 +21,11 @@ const BOARD_BUILTIN_CLIP_KINDS = [
|
|
|
21
21
|
"camera.focus",
|
|
22
22
|
"camera.shake"
|
|
23
23
|
];
|
|
24
|
-
const BOARD_BUILTIN_EFFECT_KINDS = [
|
|
24
|
+
const BOARD_BUILTIN_EFFECT_KINDS = [
|
|
25
|
+
"effects.pulse",
|
|
26
|
+
"effects.float",
|
|
27
|
+
"effects.deal"
|
|
28
|
+
];
|
|
25
29
|
/**
|
|
26
30
|
* World-space typography for board text.
|
|
27
31
|
*
|
|
@@ -85,6 +89,20 @@ function clipSchema(id) {
|
|
|
85
89
|
default: return;
|
|
86
90
|
}
|
|
87
91
|
}
|
|
92
|
+
function effectSchema(id) {
|
|
93
|
+
switch (id) {
|
|
94
|
+
case "effects.deal": return { params: {
|
|
95
|
+
lift: { unit: "board" },
|
|
96
|
+
swing: { unit: "board" },
|
|
97
|
+
curve: { unit: "board" },
|
|
98
|
+
tilt: { unit: "degree" },
|
|
99
|
+
scale: { unit: "ratio" },
|
|
100
|
+
duration: { unit: "ms" },
|
|
101
|
+
landing: { unit: "ms" }
|
|
102
|
+
} };
|
|
103
|
+
default: return;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
88
106
|
const BOARD_BUILTIN_CAPABILITIES = [...BOARD_BUILTIN_CLIP_KINDS.map((id) => {
|
|
89
107
|
const schema = clipSchema(id);
|
|
90
108
|
return {
|
|
@@ -94,11 +112,15 @@ const BOARD_BUILTIN_CAPABILITIES = [...BOARD_BUILTIN_CLIP_KINDS.map((id) => {
|
|
|
94
112
|
renderers: ["webgpu", "webgl"],
|
|
95
113
|
...schema ? { schema } : {}
|
|
96
114
|
};
|
|
97
|
-
}), ...BOARD_BUILTIN_EFFECT_KINDS.map((id) =>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
115
|
+
}), ...BOARD_BUILTIN_EFFECT_KINDS.map((id) => {
|
|
116
|
+
const schema = effectSchema(id);
|
|
117
|
+
return {
|
|
118
|
+
kind: "effect",
|
|
119
|
+
id,
|
|
120
|
+
version: 1,
|
|
121
|
+
renderers: ["webgpu", "webgl"],
|
|
122
|
+
...schema ? { schema } : {}
|
|
123
|
+
};
|
|
124
|
+
})];
|
|
103
125
|
//#endregion
|
|
104
126
|
export { BOARD_ARROW_STROKE_SIZE, BOARD_BUILTIN_CAPABILITIES, BOARD_BUILTIN_CLIP_KINDS, BOARD_BUILTIN_EFFECT_KINDS, BOARD_CONNECTION_STROKE_SIZE, BOARD_FONT_STACK, BOARD_MONO_FONT_STACK, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TEXT_FONT_FAMILY, DEFAULT_BOARD_RENDER_LIMITS, clampBoardStrokeSize };
|
|
@@ -21,7 +21,21 @@ declare const BoardViewportSchema: z.ZodObject<{
|
|
|
21
21
|
zoom: z.ZodNumber;
|
|
22
22
|
}, z.core.$strip>;
|
|
23
23
|
declare const BoardAppearanceSchema: z.ZodObject<{
|
|
24
|
-
theme: z.
|
|
24
|
+
theme: z.ZodOptional<z.ZodString>;
|
|
25
|
+
motion: z.ZodOptional<z.ZodObject<{
|
|
26
|
+
enter: z.ZodOptional<z.ZodObject<{
|
|
27
|
+
kind: z.ZodString;
|
|
28
|
+
kindVersion: z.ZodDefault<z.ZodNumber>;
|
|
29
|
+
params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
30
|
+
}, z.core.$strict>>;
|
|
31
|
+
}, z.core.$strict>>;
|
|
32
|
+
mood: z.ZodOptional<z.ZodEnum<{
|
|
33
|
+
arcane: "arcane";
|
|
34
|
+
clean: "clean";
|
|
35
|
+
cyber: "cyber";
|
|
36
|
+
natural: "natural";
|
|
37
|
+
playful: "playful";
|
|
38
|
+
}>>;
|
|
25
39
|
background: z.ZodDefault<z.ZodObject<{
|
|
26
40
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
27
41
|
custom: "custom";
|
|
@@ -52,13 +66,6 @@ declare const BoardAppearanceSchema: z.ZodObject<{
|
|
|
52
66
|
size: z.ZodDefault<z.ZodNumber>;
|
|
53
67
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
54
68
|
}, z.core.$strip>>;
|
|
55
|
-
mood: z.ZodDefault<z.ZodEnum<{
|
|
56
|
-
arcane: "arcane";
|
|
57
|
-
clean: "clean";
|
|
58
|
-
cyber: "cyber";
|
|
59
|
-
natural: "natural";
|
|
60
|
-
playful: "playful";
|
|
61
|
-
}>>;
|
|
62
69
|
}, z.core.$strip>;
|
|
63
70
|
/** Optional visual chrome still carried by a few older shapes. */
|
|
64
71
|
declare const BoardItemStyleSchema: z.ZodObject<{
|
|
@@ -1046,7 +1053,21 @@ declare const BoardDocumentSchema: z.ZodObject<{
|
|
|
1046
1053
|
kind: z.ZodLiteral<"cohub.board">;
|
|
1047
1054
|
version: z.ZodLiteral<1>;
|
|
1048
1055
|
appearance: z.ZodDefault<z.ZodObject<{
|
|
1049
|
-
theme: z.
|
|
1056
|
+
theme: z.ZodOptional<z.ZodString>;
|
|
1057
|
+
motion: z.ZodOptional<z.ZodObject<{
|
|
1058
|
+
enter: z.ZodOptional<z.ZodObject<{
|
|
1059
|
+
kind: z.ZodString;
|
|
1060
|
+
kindVersion: z.ZodDefault<z.ZodNumber>;
|
|
1061
|
+
params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1062
|
+
}, z.core.$strict>>;
|
|
1063
|
+
}, z.core.$strict>>;
|
|
1064
|
+
mood: z.ZodOptional<z.ZodEnum<{
|
|
1065
|
+
arcane: "arcane";
|
|
1066
|
+
clean: "clean";
|
|
1067
|
+
cyber: "cyber";
|
|
1068
|
+
natural: "natural";
|
|
1069
|
+
playful: "playful";
|
|
1070
|
+
}>>;
|
|
1050
1071
|
background: z.ZodDefault<z.ZodObject<{
|
|
1051
1072
|
kind: z.ZodDefault<z.ZodEnum<{
|
|
1052
1073
|
custom: "custom";
|
|
@@ -1077,13 +1098,6 @@ declare const BoardDocumentSchema: z.ZodObject<{
|
|
|
1077
1098
|
size: z.ZodDefault<z.ZodNumber>;
|
|
1078
1099
|
opacity: z.ZodDefault<z.ZodNumber>;
|
|
1079
1100
|
}, z.core.$strip>>;
|
|
1080
|
-
mood: z.ZodDefault<z.ZodEnum<{
|
|
1081
|
-
arcane: "arcane";
|
|
1082
|
-
clean: "clean";
|
|
1083
|
-
cyber: "cyber";
|
|
1084
|
-
natural: "natural";
|
|
1085
|
-
playful: "playful";
|
|
1086
|
-
}>>;
|
|
1087
1101
|
}, z.core.$strip>>;
|
|
1088
1102
|
viewport: z.ZodObject<{
|
|
1089
1103
|
x: z.ZodNumber;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BOARD_ARROW_STROKE_SIZE } from "./board-constants.js";
|
|
2
2
|
import { BoardConnectionSchema } from "./board-connection.js";
|
|
3
3
|
import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION } from "./board.js";
|
|
4
|
+
import { BoardMotionSchema } from "./board-animation.js";
|
|
4
5
|
import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "./board-url.js";
|
|
5
6
|
import { z } from "zod";
|
|
6
7
|
//#region ../protocol/dist/board-document.js
|
|
@@ -23,7 +24,18 @@ const BoardViewportSchema = z.object({
|
|
|
23
24
|
zoom: z.number().finite().min(.05).max(8)
|
|
24
25
|
});
|
|
25
26
|
const BoardAppearanceSchema = z.object({
|
|
26
|
-
|
|
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(),
|
|
27
39
|
background: z.object({
|
|
28
40
|
kind: z.enum([
|
|
29
41
|
"solid",
|
|
@@ -57,14 +69,7 @@ const BoardAppearanceSchema = z.object({
|
|
|
57
69
|
visible: false,
|
|
58
70
|
size: 24,
|
|
59
71
|
opacity: .12
|
|
60
|
-
})
|
|
61
|
-
mood: z.enum([
|
|
62
|
-
"clean",
|
|
63
|
-
"playful",
|
|
64
|
-
"arcane",
|
|
65
|
-
"cyber",
|
|
66
|
-
"natural"
|
|
67
|
-
]).default("clean")
|
|
72
|
+
})
|
|
68
73
|
});
|
|
69
74
|
/** Optional visual chrome still carried by a few older shapes. */
|
|
70
75
|
const BoardItemStyleSchema = z.object({
|
|
@@ -390,14 +395,12 @@ const BoardDocumentSchema = z.object({
|
|
|
390
395
|
kind: z.literal(BOARD_DOCUMENT_KIND),
|
|
391
396
|
version: z.literal(1),
|
|
392
397
|
appearance: BoardAppearanceSchema.default({
|
|
393
|
-
theme: "clean",
|
|
394
398
|
background: { kind: "solid" },
|
|
395
399
|
grid: {
|
|
396
400
|
visible: false,
|
|
397
401
|
size: 24,
|
|
398
402
|
opacity: .12
|
|
399
|
-
}
|
|
400
|
-
mood: "clean"
|
|
403
|
+
}
|
|
401
404
|
}),
|
|
402
405
|
viewport: BoardViewportSchema,
|
|
403
406
|
items: z.array(BoardItemSchema),
|
|
@@ -18,10 +18,11 @@ declare const BoardEffectSchema: z.ZodObject<{
|
|
|
18
18
|
type: z.ZodLiteral<"board">;
|
|
19
19
|
}, z.core.$strict>], "type">;
|
|
20
20
|
kind: z.ZodString;
|
|
21
|
-
kindVersion: z.ZodNumber
|
|
21
|
+
kindVersion: z.ZodDefault<z.ZodNumber>;
|
|
22
22
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
23
23
|
lifecycle: z.ZodEnum<{
|
|
24
24
|
manual: "manual";
|
|
25
|
+
"on-enter": "on-enter";
|
|
25
26
|
persistent: "persistent";
|
|
26
27
|
"when-visible": "when-visible";
|
|
27
28
|
}>;
|
|
@@ -60,10 +61,11 @@ declare const BoardEffectInputSchema: z.ZodObject<{
|
|
|
60
61
|
type: z.ZodLiteral<"board">;
|
|
61
62
|
}, z.core.$strict>], "type">;
|
|
62
63
|
kind: z.ZodString;
|
|
63
|
-
kindVersion: z.ZodNumber
|
|
64
|
+
kindVersion: z.ZodDefault<z.ZodNumber>;
|
|
64
65
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
65
66
|
lifecycle: z.ZodEnum<{
|
|
66
67
|
manual: "manual";
|
|
68
|
+
"on-enter": "on-enter";
|
|
67
69
|
persistent: "persistent";
|
|
68
70
|
"when-visible": "when-visible";
|
|
69
71
|
}>;
|
|
@@ -21,12 +21,13 @@ const BoardEffectSchema = z.object({
|
|
|
21
21
|
itemId: idSchema
|
|
22
22
|
}).strict(), z.object({ type: z.literal("board") }).strict()]),
|
|
23
23
|
kind: extensionIdSchema,
|
|
24
|
-
kindVersion: z.number().int().positive(),
|
|
24
|
+
kindVersion: z.number().int().positive().default(1),
|
|
25
25
|
enabled: z.boolean().default(true),
|
|
26
26
|
lifecycle: z.enum([
|
|
27
27
|
"persistent",
|
|
28
28
|
"when-visible",
|
|
29
|
-
"manual"
|
|
29
|
+
"manual",
|
|
30
|
+
"on-enter"
|
|
30
31
|
]),
|
|
31
32
|
timeOrigin: z.enum([
|
|
32
33
|
"board",
|