@neta-art/cohub 9.0.1 → 11.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.
- package/README.md +108 -102
- package/dist/board/editor/align.d.ts +11 -0
- package/dist/board/editor/align.js +72 -0
- package/dist/board/editor/animation.d.ts +17 -0
- package/dist/board/editor/animation.js +187 -0
- package/dist/board/editor/camera.d.ts +32 -0
- package/dist/board/editor/camera.js +137 -0
- package/dist/board/editor/clipboard.d.ts +41 -0
- package/dist/board/editor/clipboard.js +129 -0
- package/dist/board/editor/connection-ports.d.ts +19 -0
- package/dist/board/editor/connection-ports.js +85 -0
- package/dist/board/editor/context.d.ts +111 -0
- package/dist/board/editor/context.js +30 -0
- package/dist/board/editor/copy.d.ts +17 -0
- package/dist/board/editor/copy.js +121 -0
- package/dist/board/editor/creation.d.ts +51 -0
- package/dist/board/editor/creation.js +225 -0
- package/dist/board/editor/deletion.d.ts +9 -0
- package/dist/board/editor/deletion.js +90 -0
- package/dist/board/editor/document-edits.d.ts +22 -0
- package/dist/board/editor/document-edits.js +193 -0
- package/dist/board/editor/document.d.ts +41 -0
- package/dist/board/editor/document.js +302 -0
- package/dist/board/editor/editor.d.ts +225 -0
- package/dist/board/editor/editor.js +439 -0
- package/dist/board/editor/index.d.ts +18 -0
- package/dist/board/editor/index.js +12 -0
- package/dist/board/editor/interaction.d.ts +115 -0
- package/dist/board/editor/interaction.js +584 -0
- package/dist/board/editor/query.d.ts +27 -0
- package/dist/board/editor/query.js +203 -0
- package/dist/board/editor/remote.d.ts +11 -0
- package/dist/board/editor/remote.js +55 -0
- package/dist/board/editor/selection-transform.d.ts +24 -0
- package/dist/board/editor/selection-transform.js +81 -0
- package/dist/board/editor/selection.d.ts +33 -0
- package/dist/board/editor/selection.js +197 -0
- package/dist/board/editor/snapping.d.ts +33 -0
- package/dist/board/editor/snapping.js +75 -0
- package/dist/board/editor/snapshots.d.ts +27 -0
- package/dist/board/editor/snapshots.js +132 -0
- package/dist/board/editor/spatial.d.ts +41 -0
- package/dist/board/editor/spatial.js +191 -0
- package/dist/board/editor/state.d.ts +12 -0
- package/dist/board/editor/state.js +49 -0
- package/dist/board/editor/tool.d.ts +10 -0
- package/dist/board/editor/tool.js +19 -0
- package/dist/board/editor/wheel.d.ts +5 -0
- package/dist/board/editor/wheel.js +17 -0
- package/dist/board/export/index.d.ts +28 -6
- package/dist/board/export/index.js +47 -13
- package/dist/board/export/node/index.d.ts +56 -0
- package/dist/board/{headless → export/node}/index.js +26 -21
- package/dist/board/export/node/scripts.d.ts +16 -0
- package/dist/board/export/node/scripts.js +258 -0
- package/dist/board/export/scene.d.ts +8 -5
- package/dist/board/export/scene.js +24 -9
- package/dist/board/{animation.d.ts → model/animation.d.ts} +8 -5
- package/dist/board/{animation.js → model/animation.js} +37 -10
- package/dist/board/{core → model}/arrow-geometry.d.ts +2 -2
- package/dist/board/{core → model}/arrow-geometry.js +2 -2
- package/dist/board/model/authoring.d.ts +20 -0
- package/dist/board/model/authoring.js +185 -0
- package/dist/board/{core → model}/draw-geometry.d.ts +2 -2
- package/dist/board/{core → model}/draw-geometry.js +1 -1
- package/dist/board/model/draw-input.d.ts +14 -0
- package/dist/board/model/draw-input.js +28 -0
- package/dist/board/{core → model}/export-assets.d.ts +1 -1
- package/dist/board/{core → model}/export-assets.js +1 -1
- package/dist/board/{core → model}/export-plan.d.ts +2 -2
- package/dist/board/{core → model}/export-plan.js +3 -2
- package/dist/board/{core → model}/file-preview.d.ts +1 -1
- package/dist/board/{core → model}/file-preview.js +2 -2
- package/dist/board/{core → model}/file-snapshot.d.ts +1 -1
- package/dist/board/{core → model}/file-snapshot.js +4 -3
- package/dist/board/{geometry.d.ts → model/geometry.d.ts} +3 -3
- package/dist/board/{geometry.js → model/geometry.js} +1 -1
- package/dist/board/{image-key.d.ts → model/image-key.d.ts} +2 -2
- package/dist/board/{image-key.js → model/image-key.js} +7 -3
- package/dist/board/model/index.d.ts +42 -0
- package/dist/board/model/index.js +39 -0
- package/dist/board/model/items/builtin.d.ts +5 -0
- package/dist/board/model/items/builtin.js +119 -0
- package/dist/board/model/items/create.d.ts +61 -0
- package/dist/board/model/items/create.js +272 -0
- package/dist/board/model/items/definition.d.ts +35 -0
- package/dist/board/model/items/definition.js +18 -0
- package/dist/board/model/items/id.d.ts +5 -0
- package/dist/board/model/items/id.js +11 -0
- package/dist/board/model/items/index.d.ts +6 -0
- package/dist/board/model/items/index.js +6 -0
- package/dist/board/model/items/registry.d.ts +35 -0
- package/dist/board/model/items/registry.js +84 -0
- package/dist/board/{media-playback.d.ts → model/media-playback.d.ts} +4 -3
- package/dist/board/{media-playback.js → model/media-playback.js} +15 -5
- package/dist/board/{media.d.ts → model/media.d.ts} +1 -1
- package/dist/board/{media.js → model/media.js} +8 -2
- package/dist/board/{core → model}/palette.d.ts +1 -1
- package/dist/board/{core → model}/palette.js +1 -1
- package/dist/board/{presets.d.ts → model/presets.d.ts} +3 -3
- package/dist/board/{presets.js → model/presets.js} +1 -1
- package/dist/board/{replay.d.ts → model/replay.d.ts} +5 -5
- package/dist/board/{replay.js → model/replay.js} +2 -2
- package/dist/board/model/sampling.d.ts +19 -0
- package/dist/board/model/sampling.js +96 -0
- package/dist/board/{core → model}/scene.d.ts +1 -1
- package/dist/board/{core → model}/scene.js +1 -1
- package/dist/board/model/script-example.d.ts +4 -0
- package/dist/board/model/script-example.js +21 -0
- package/dist/board/model/script-hit.d.ts +10 -0
- package/dist/board/model/script-hit.js +52 -0
- package/dist/board/model/script-index.d.ts +7 -0
- package/dist/board/model/script-index.js +15 -0
- package/dist/board/model/script-scene.d.ts +24 -0
- package/dist/board/model/script-scene.js +267 -0
- package/dist/board/model/script.d.ts +105 -0
- package/dist/board/model/script.js +1 -0
- package/dist/board/model/shape-types.d.ts +8 -0
- package/dist/board/model/shape-types.js +8 -0
- package/dist/board/{task.d.ts → model/task.d.ts} +4 -4
- package/dist/board/{task.js → model/task.js} +3 -3
- package/dist/board/{core → model}/text-metrics.d.ts +1 -1
- package/dist/board/{core → model}/text-metrics.js +1 -1
- package/dist/board/{core → model}/tool-styles.d.ts +1 -1
- package/dist/board/{core → model}/tool-styles.js +1 -1
- package/dist/board/{runtime/board-player.d.ts → player/index.d.ts} +2 -2
- package/dist/board/{runtime/board-player.js → player/index.js} +5 -4
- package/dist/board/render/board-background.d.ts +1 -1
- package/dist/board/render/clip.d.ts +1 -1
- package/dist/board/render/css-color.d.ts +6 -1
- package/dist/board/render/css-color.js +34 -20
- package/dist/board/render/diagnostics.d.ts +20 -0
- package/dist/board/render/diagnostics.js +117 -0
- package/dist/board/render/index.d.ts +9 -6
- package/dist/board/render/index.js +10 -7
- package/dist/board/render/media-interaction.d.ts +2 -2
- package/dist/board/render/media-interaction.js +1 -1
- package/dist/board/render/palette.d.ts +3 -2
- package/dist/board/render/palette.js +7 -3
- package/dist/board/render/renderers/arrow-card-renderer.js +4 -3
- package/dist/board/render/renderers/audio-card-renderer.js +2 -1
- package/dist/board/render/renderers/board-renderer-registry.d.ts +20 -10
- package/dist/board/render/renderers/board-renderer-registry.js +17 -17
- package/dist/board/render/renderers/custom-card-renderer.d.ts +5 -0
- package/dist/board/render/renderers/{sketch-card-renderer.js → custom-card-renderer.js} +16 -15
- package/dist/board/render/renderers/draw-card-renderer.js +4 -3
- package/dist/board/render/renderers/effect-card-renderer.js +22 -5
- package/dist/board/render/renderers/far-plate.js +1 -1
- package/dist/board/render/renderers/file-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/file-card-renderer.js +2 -2
- package/dist/board/render/renderers/frame-card-renderer.js +30 -14
- package/dist/board/render/renderers/image-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/image-card-renderer.js +43 -4
- package/dist/board/render/renderers/shape-card-renderer.js +11 -28
- package/dist/board/render/renderers/task-card-renderer.js +1 -1
- package/dist/board/render/renderers/text-card-renderer.js +6 -4
- package/dist/board/render/renderers/unknown-card-renderer.js +1 -0
- package/dist/board/render/renderers/video-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/video-card-renderer.js +2 -1
- package/dist/board/render/sampling.d.ts +22 -0
- package/dist/board/render/sampling.js +21 -0
- package/dist/board/render/script-export.d.ts +11 -0
- package/dist/board/render/script-export.js +86 -0
- package/dist/board/render/script-host.d.ts +31 -0
- package/dist/board/render/script-host.js +421 -0
- package/dist/board/render/script-modules.d.ts +2 -0
- package/dist/board/render/script-modules.js +2 -0
- package/dist/board/render/script-runtime.d.ts +29 -0
- package/dist/board/render/script-runtime.js +213 -0
- package/dist/board/render/script-sandbox.d.ts +4 -0
- package/dist/board/render/script-sandbox.js +173 -0
- package/dist/board/render/stroke.d.ts +3 -2
- package/dist/board/render/stroke.js +23 -2
- package/dist/board/render/text-measurement.js +2 -2
- package/dist/board/replica/index.d.ts +70 -0
- package/dist/board/replica/index.js +276 -0
- package/dist/board/stage/assets.d.ts +41 -0
- package/dist/board/stage/assets.js +355 -0
- package/dist/board/stage/index.d.ts +8 -0
- package/dist/board/stage/index.js +8 -0
- package/dist/board/stage/lru.d.ts +32 -0
- package/dist/board/stage/lru.js +29 -0
- package/dist/board/stage/maintenance.d.ts +5 -0
- package/dist/board/stage/maintenance.js +11 -0
- package/dist/board/stage/pointer.d.ts +8 -0
- package/dist/board/stage/pointer.js +33 -0
- package/dist/board/stage/scene.d.ts +85 -0
- package/dist/board/stage/scene.js +515 -0
- package/dist/board/stage/script-pointer.d.ts +19 -0
- package/dist/board/stage/script-pointer.js +35 -0
- package/dist/board/stage/stage.d.ts +76 -0
- package/dist/board/stage/stage.js +774 -0
- package/dist/board/stage/texture-pool.d.ts +24 -0
- package/dist/board/stage/texture-pool.js +153 -0
- package/dist/board/stage/views.d.ts +38 -0
- package/dist/board/stage/views.js +93 -0
- package/dist/chunks/environment.d.ts +289 -23
- package/dist/chunks/host-bridge.d.ts +2 -2
- package/dist/chunks/http.d.ts +185 -71
- package/dist/chunks/http.js +368 -269
- package/dist/chunks/transport.js +3 -1
- package/dist/chunks/websocket.d.ts +9 -1
- package/dist/chunks/websocket.js +16 -2
- package/dist/host-bridge.js +2 -1
- package/dist/http.d.ts +2 -2
- package/dist/index.d.ts +182 -4
- package/dist/index.js +1393 -129
- package/dist/media.d.ts +1 -10
- package/dist/media.js +16 -27
- package/dist/protocol/dist/board-assets.d.ts +1 -0
- package/dist/protocol/dist/board-constants.js +2 -2
- package/dist/protocol/dist/board-model.d.ts +201 -11
- package/dist/protocol/dist/board-model.js +33 -14
- package/dist/protocol/dist/board-patch.js +3 -2
- package/dist/protocol/dist/board-schema.d.ts +4 -2
- package/dist/protocol/dist/board-schema.js +18 -4
- package/dist/protocol/dist/board-script-modules.d.ts +25 -0
- package/dist/protocol/dist/board-script-modules.js +127 -0
- package/dist/protocol/dist/board.d.ts +28 -2
- package/dist/protocol/dist/board.js +3 -1
- package/dist/protocol/dist/core/media.d.ts +5 -0
- package/dist/protocol/dist/core/media.js +39 -0
- package/dist/protocol/dist/display/index.d.ts +1 -0
- package/dist/protocol/dist/index.d.ts +7 -5
- package/dist/protocol/dist/realtime/types.d.ts +1 -0
- package/dist/protocol/dist/rtc/index.d.ts +1 -0
- package/dist/types.d.ts +1 -1
- package/package.json +21 -8
- package/dist/board/core/shape-definition.d.ts +0 -23
- package/dist/board/core/shape-definition.js +0 -45
- package/dist/board/core/shape-types.d.ts +0 -38
- package/dist/board/core/shape-types.js +0 -22
- package/dist/board/headless/index.d.ts +0 -55
- package/dist/board/headless/sketch.d.ts +0 -19
- package/dist/board/headless/sketch.js +0 -146
- package/dist/board/index.d.ts +0 -30
- package/dist/board/index.js +0 -29
- package/dist/board/render/renderers/sketch-card-renderer.d.ts +0 -5
- package/dist/board/render/sketch-host.d.ts +0 -14
- package/dist/board/render/sketch-host.js +0 -216
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { parseBoardItem as parseBoardItem$1 } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import { applyMatrix, createBoardLayout } from "../../protocol/dist/board-layout.js";
|
|
3
|
+
import { applyBoardPatchToDocument, mergePatch } from "../../protocol/dist/board-patch.js";
|
|
4
|
+
//#region src/board/model/script-scene.ts
|
|
5
|
+
function parseBoardItem(value) {
|
|
6
|
+
const parsed = parseBoardItem$1(value);
|
|
7
|
+
if (!parsed.ok) throw new Error(parsed.diagnostics[0]?.message ?? "Invalid script item.");
|
|
8
|
+
return parsed.item;
|
|
9
|
+
}
|
|
10
|
+
const DISPLAY_FIELDS = /* @__PURE__ */ new Set([
|
|
11
|
+
"position",
|
|
12
|
+
"size",
|
|
13
|
+
"rotation",
|
|
14
|
+
"scale",
|
|
15
|
+
"opacity",
|
|
16
|
+
"style",
|
|
17
|
+
"props"
|
|
18
|
+
]);
|
|
19
|
+
function boardScriptScope(document, id) {
|
|
20
|
+
const scope = /* @__PURE__ */ new Set([id, ...Object.values(document.items[id]?.script?.targets ?? {}).filter((target) => Boolean(document.items[target]))]);
|
|
21
|
+
if (document.items[id]?.type !== "frame") return scope;
|
|
22
|
+
for (const candidate of Object.keys(document.items)) {
|
|
23
|
+
let parent = document.items[candidate]?.parent;
|
|
24
|
+
for (let depth = 0; parent && depth < 64; depth++) {
|
|
25
|
+
if (parent === id) {
|
|
26
|
+
scope.add(candidate);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
parent = document.items[parent]?.parent;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return scope;
|
|
33
|
+
}
|
|
34
|
+
function validateBoardScriptOutput(output, scope) {
|
|
35
|
+
if (!output || typeof output !== "object" || !output.patches || !output.items || !output.hits || !Array.isArray(output.listens)) throw new Error("Invalid script output.");
|
|
36
|
+
if (JSON.stringify(output).length > 1e6) throw new Error("Script output exceeds the 1 MB limit.");
|
|
37
|
+
if (output.space !== void 0 && output.space !== "world" && output.space !== "screen") throw new Error("Invalid script scene space.");
|
|
38
|
+
if (output.parameters) {
|
|
39
|
+
if (Object.keys(output.parameters).length > 64) throw new Error("A script may declare at most 64 parameters.");
|
|
40
|
+
for (const spec of Object.values(output.parameters)) {
|
|
41
|
+
if (!spec || ![
|
|
42
|
+
"number",
|
|
43
|
+
"boolean",
|
|
44
|
+
"string",
|
|
45
|
+
"color"
|
|
46
|
+
].includes(spec.type)) throw new Error("Invalid script parameter type.");
|
|
47
|
+
if (spec.label !== void 0 && typeof spec.label !== "string") throw new Error("Invalid script parameter label.");
|
|
48
|
+
if ([
|
|
49
|
+
spec.min,
|
|
50
|
+
spec.max,
|
|
51
|
+
spec.step
|
|
52
|
+
].some((value) => value !== void 0 && !Number.isFinite(value))) throw new Error("Invalid script parameter range.");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (Object.keys(output.items).length > 1e3 || Object.keys(output.hits).length > 1e3) throw new Error("A script may create at most 1000 temporary items or hit regions.");
|
|
56
|
+
for (const [id, patch] of Object.entries(output.patches)) {
|
|
57
|
+
if (!scope.has(id)) throw new Error(`Item is outside the script scope: ${id}`);
|
|
58
|
+
if (!patch || typeof patch !== "object" || Object.keys(patch).some((key) => !DISPLAY_FIELDS.has(key))) throw new Error("Scripts may only present display properties.");
|
|
59
|
+
}
|
|
60
|
+
for (const hit of Object.values(output.hits)) {
|
|
61
|
+
if (hit.cursor && ![
|
|
62
|
+
"default",
|
|
63
|
+
"pointer",
|
|
64
|
+
"grab",
|
|
65
|
+
"grabbing",
|
|
66
|
+
"crosshair",
|
|
67
|
+
"text",
|
|
68
|
+
"move",
|
|
69
|
+
"ew-resize",
|
|
70
|
+
"ns-resize",
|
|
71
|
+
"not-allowed"
|
|
72
|
+
].includes(hit.cursor)) throw new Error("Invalid script cursor.");
|
|
73
|
+
if (![
|
|
74
|
+
hit.x,
|
|
75
|
+
hit.y,
|
|
76
|
+
hit.width,
|
|
77
|
+
hit.height
|
|
78
|
+
].every(Number.isFinite) || hit.width < 0 || hit.height < 0) throw new Error("Invalid script hit region.");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function validateBoardScriptCommit(document, id, patch) {
|
|
82
|
+
if (!patch || typeof patch !== "object" || Object.keys(patch).some((key) => key !== "items")) throw new Error("Scripts may only commit items in their scope.");
|
|
83
|
+
const scope = boardScriptScope(document, id);
|
|
84
|
+
for (const [target, value] of Object.entries(patch.items ?? {})) {
|
|
85
|
+
if (!scope.has(target)) {
|
|
86
|
+
if (document.items[target]) throw new Error(`Item is outside the script scope: ${target}`);
|
|
87
|
+
if (!value || typeof value !== "object" || !("parent" in value) || typeof value.parent !== "string" || !scope.has(value.parent) || document.items[value.parent]?.type !== "frame") throw new Error("New items must belong to a frame in the script scope.");
|
|
88
|
+
if ("script" in value) throw new Error("Scripts cannot start other scripts.");
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (value && typeof value === "object" && ("script" in value || "parent" in value || "type" in value)) throw new Error("A script cannot replace scripts, types, or parent relationships.");
|
|
92
|
+
}
|
|
93
|
+
const result = applyBoardPatchToDocument(document, patch);
|
|
94
|
+
if (!result.ok) throw new Error(result.diagnostics[0]?.message ?? "Invalid script commit.");
|
|
95
|
+
}
|
|
96
|
+
function scriptTemporaryPrefix(owner) {
|
|
97
|
+
let hash = 2166136261;
|
|
98
|
+
for (const char of owner) hash = Math.imul(hash ^ char.charCodeAt(0), 16777619) >>> 0;
|
|
99
|
+
return `~script-${hash.toString(36)}-`;
|
|
100
|
+
}
|
|
101
|
+
const preparedOutputs = /* @__PURE__ */ new WeakMap();
|
|
102
|
+
const preparedScopes = /* @__PURE__ */ new WeakMap();
|
|
103
|
+
function prepareBoardScriptOutput(document, owner, output) {
|
|
104
|
+
const previous = preparedOutputs.get(output);
|
|
105
|
+
if (previous?.document === document && previous.owner === owner) return previous;
|
|
106
|
+
let scopes = preparedScopes.get(document);
|
|
107
|
+
if (!scopes) {
|
|
108
|
+
scopes = /* @__PURE__ */ new Map();
|
|
109
|
+
preparedScopes.set(document, scopes);
|
|
110
|
+
}
|
|
111
|
+
let scope = scopes.get(owner);
|
|
112
|
+
if (!scope) {
|
|
113
|
+
scope = boardScriptScope(document, owner);
|
|
114
|
+
scopes.set(owner, scope);
|
|
115
|
+
}
|
|
116
|
+
validateBoardScriptOutput(output, scope);
|
|
117
|
+
const presented = /* @__PURE__ */ new Map();
|
|
118
|
+
for (const [id, patch] of Object.entries(output.patches)) {
|
|
119
|
+
const base = document.items[id];
|
|
120
|
+
if (base) presented.set(id, {
|
|
121
|
+
base,
|
|
122
|
+
item: parseBoardItem(mergePatch(base, patch))
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const prefix = scriptTemporaryPrefix(owner);
|
|
126
|
+
const rootId = `${prefix}root`;
|
|
127
|
+
if (document.items[rootId]) throw new Error("Temporary item ID conflicts with the document.");
|
|
128
|
+
const items = /* @__PURE__ */ new Map();
|
|
129
|
+
const parsed = new Map(Object.entries(output.items).map(([id, value]) => [id, parseBoardItem(value)]));
|
|
130
|
+
for (const [local, value] of parsed) {
|
|
131
|
+
if (!/^[a-zA-Z0-9_-]{1,80}$/.test(local) || local === "root") throw new Error("Temporary IDs must be 1–80 letters, digits, underscores or hyphens; root is reserved.");
|
|
132
|
+
if (value.script) throw new Error("Temporary items cannot start scripts.");
|
|
133
|
+
if (value.parent && !(value.parent in output.items)) throw new Error("Temporary parents must belong to the same instance.");
|
|
134
|
+
let cursor = value.parent;
|
|
135
|
+
const visited = /* @__PURE__ */ new Set([local]);
|
|
136
|
+
while (cursor) {
|
|
137
|
+
if (visited.has(cursor)) throw new Error("Temporary parents must not form a cycle.");
|
|
138
|
+
visited.add(cursor);
|
|
139
|
+
const parentItem = parsed.get(cursor);
|
|
140
|
+
if (!parentItem) throw new Error("Temporary parent is missing.");
|
|
141
|
+
if (parentItem.type !== "frame") throw new Error("Only frames can contain temporary items.");
|
|
142
|
+
cursor = parentItem.parent;
|
|
143
|
+
}
|
|
144
|
+
const id = `${prefix}${local}`;
|
|
145
|
+
if (document.items[id]) throw new Error("Temporary item ID conflicts with the document.");
|
|
146
|
+
const parent = value.parent ? `${prefix}${value.parent}` : rootId;
|
|
147
|
+
if (value.type === "arrow") {
|
|
148
|
+
const remap = (endpoint) => {
|
|
149
|
+
if (!("item" in endpoint)) return endpoint;
|
|
150
|
+
if (!(endpoint.item in output.items) && !scope.has(endpoint.item)) throw new Error("Arrow target is outside the script scope.");
|
|
151
|
+
return endpoint.item in output.items ? {
|
|
152
|
+
...endpoint,
|
|
153
|
+
item: `${prefix}${endpoint.item}`
|
|
154
|
+
} : endpoint;
|
|
155
|
+
};
|
|
156
|
+
items.set(id, {
|
|
157
|
+
...value,
|
|
158
|
+
parent,
|
|
159
|
+
props: {
|
|
160
|
+
...value.props,
|
|
161
|
+
start: remap(value.props.start),
|
|
162
|
+
end: remap(value.props.end)
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
} else items.set(id, {
|
|
166
|
+
...value,
|
|
167
|
+
parent
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
const prepared = {
|
|
171
|
+
document,
|
|
172
|
+
owner,
|
|
173
|
+
rootId,
|
|
174
|
+
items,
|
|
175
|
+
presented
|
|
176
|
+
};
|
|
177
|
+
preparedOutputs.set(output, prepared);
|
|
178
|
+
return prepared;
|
|
179
|
+
}
|
|
180
|
+
function composeBoardScriptItems(document, scene, outputs, incoming = /* @__PURE__ */ new Map(), screen, onError) {
|
|
181
|
+
const result = new Map(incoming);
|
|
182
|
+
const screenAnchors = /* @__PURE__ */ new Map();
|
|
183
|
+
if (outputs.size === 0) return result;
|
|
184
|
+
for (const owner of Object.keys(document.items)) {
|
|
185
|
+
const output = outputs.get(owner);
|
|
186
|
+
if (!output) continue;
|
|
187
|
+
try {
|
|
188
|
+
const changes = /* @__PURE__ */ new Map();
|
|
189
|
+
const prepared = prepareBoardScriptOutput(document, owner, output);
|
|
190
|
+
for (const [id, patch] of Object.entries(output.patches)) {
|
|
191
|
+
const base = result.get(id) ?? document.items[id];
|
|
192
|
+
if (!base) continue;
|
|
193
|
+
let cached = prepared.presented.get(id);
|
|
194
|
+
if (cached?.base !== base) {
|
|
195
|
+
cached = {
|
|
196
|
+
base,
|
|
197
|
+
item: parseBoardItem(mergePatch(base, patch))
|
|
198
|
+
};
|
|
199
|
+
prepared.presented.set(id, cached);
|
|
200
|
+
}
|
|
201
|
+
changes.set(id, cached.item);
|
|
202
|
+
}
|
|
203
|
+
if (!prepared.items.size || output.space === "screen" && !screen) {
|
|
204
|
+
for (const [id, item] of changes) result.set(id, item);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const rootId = prepared.rootId;
|
|
208
|
+
const item = changes.get(owner) ?? result.get(owner) ?? document.items[owner];
|
|
209
|
+
if (!item) continue;
|
|
210
|
+
const box = scene.layout.box(owner);
|
|
211
|
+
const overlay = output.space === "screen" && screen ? {
|
|
212
|
+
parent: void 0,
|
|
213
|
+
position: {
|
|
214
|
+
x: 0,
|
|
215
|
+
y: 0
|
|
216
|
+
},
|
|
217
|
+
scale: 1 / screen.zoom,
|
|
218
|
+
rotation: 0,
|
|
219
|
+
origin: {
|
|
220
|
+
x: 0,
|
|
221
|
+
y: 0
|
|
222
|
+
}
|
|
223
|
+
} : {};
|
|
224
|
+
changes.set(rootId, parseBoardItem({
|
|
225
|
+
type: "frame",
|
|
226
|
+
parent: item.parent,
|
|
227
|
+
position: item.position,
|
|
228
|
+
rotation: item.rotation,
|
|
229
|
+
scale: item.scale,
|
|
230
|
+
origin: item.origin,
|
|
231
|
+
opacity: item.opacity,
|
|
232
|
+
size: {
|
|
233
|
+
width: Math.max(1, box.width),
|
|
234
|
+
height: Math.max(1, box.height)
|
|
235
|
+
},
|
|
236
|
+
z: (item.z ?? 0) + .001,
|
|
237
|
+
props: {
|
|
238
|
+
decoration: "none",
|
|
239
|
+
clip: false
|
|
240
|
+
},
|
|
241
|
+
...overlay
|
|
242
|
+
}));
|
|
243
|
+
for (const [id, value] of prepared.items) changes.set(id, value);
|
|
244
|
+
for (const [id, item] of changes) result.set(id, item);
|
|
245
|
+
if (output.space === "screen") screenAnchors.set(owner, rootId);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
if (!onError) throw error;
|
|
248
|
+
onError(owner, error);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (screenAnchors.size) {
|
|
252
|
+
const layout = createBoardLayout((id) => result.get(id) ?? document.items[id]);
|
|
253
|
+
for (const [owner, rootId] of screenAnchors) {
|
|
254
|
+
const root = result.get(rootId);
|
|
255
|
+
if (root) result.set(rootId, {
|
|
256
|
+
...root,
|
|
257
|
+
position: applyMatrix(layout.matrix(owner), {
|
|
258
|
+
x: 0,
|
|
259
|
+
y: 0
|
|
260
|
+
})
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
//#endregion
|
|
267
|
+
export { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, scriptTemporaryPrefix, validateBoardScriptCommit, validateBoardScriptOutput };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { BoardItem, BoardPatch, BoardScript, BoardVec2 } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import "../../protocol/dist/index.js";
|
|
3
|
+
//#region src/board/model/script.d.ts
|
|
4
|
+
type BoardScriptEvent = {
|
|
5
|
+
type: string;
|
|
6
|
+
target?: string;
|
|
7
|
+
relatedTarget?: string;
|
|
8
|
+
relatedOwner?: string;
|
|
9
|
+
point?: BoardVec2;
|
|
10
|
+
pointerId?: number;
|
|
11
|
+
pointerType?: string;
|
|
12
|
+
buttons?: number;
|
|
13
|
+
key?: string;
|
|
14
|
+
shiftKey?: boolean;
|
|
15
|
+
altKey?: boolean;
|
|
16
|
+
ctrlKey?: boolean;
|
|
17
|
+
metaKey?: boolean;
|
|
18
|
+
data?: unknown;
|
|
19
|
+
};
|
|
20
|
+
type BoardScriptFrame = {
|
|
21
|
+
t: number;
|
|
22
|
+
dt: number;
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
seed: string;
|
|
26
|
+
params: BoardScript["params"];
|
|
27
|
+
state: Record<string, unknown>;
|
|
28
|
+
};
|
|
29
|
+
type BoardScriptItemPatch = Partial<Pick<BoardItem, "position" | "scale" | "rotation" | "opacity" | "style">> & {
|
|
30
|
+
size?: {
|
|
31
|
+
width?: number;
|
|
32
|
+
height?: number;
|
|
33
|
+
};
|
|
34
|
+
props?: Record<string, unknown>;
|
|
35
|
+
};
|
|
36
|
+
type BoardScriptHit = {
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
label?: string;
|
|
42
|
+
cursor?: string;
|
|
43
|
+
};
|
|
44
|
+
type BoardScriptSnapshot = {
|
|
45
|
+
state: Record<string, unknown>;
|
|
46
|
+
time: number;
|
|
47
|
+
random: number;
|
|
48
|
+
configuration?: string;
|
|
49
|
+
effects?: Pick<BoardScriptOutput, "patches" | "items" | "hits" | "space">;
|
|
50
|
+
};
|
|
51
|
+
type BoardScriptParameter = {
|
|
52
|
+
type: "number" | "boolean" | "string" | "color";
|
|
53
|
+
label?: string;
|
|
54
|
+
default?: string | number | boolean;
|
|
55
|
+
min?: number;
|
|
56
|
+
max?: number;
|
|
57
|
+
step?: number;
|
|
58
|
+
};
|
|
59
|
+
type BoardScriptOutput = {
|
|
60
|
+
parameters?: Record<string, BoardScriptParameter>;
|
|
61
|
+
space?: "world" | "screen";
|
|
62
|
+
patches: Record<string, Record<string, unknown>>;
|
|
63
|
+
items: Record<string, unknown>;
|
|
64
|
+
hits: Record<string, BoardScriptHit>;
|
|
65
|
+
listens: string[];
|
|
66
|
+
animated: boolean;
|
|
67
|
+
updating?: boolean;
|
|
68
|
+
version: number;
|
|
69
|
+
};
|
|
70
|
+
type BoardScriptContext = {
|
|
71
|
+
readonly self: {
|
|
72
|
+
readonly id: string;
|
|
73
|
+
readonly base: BoardItem;
|
|
74
|
+
present(patch: BoardScriptItemPatch | null): void;
|
|
75
|
+
};
|
|
76
|
+
readonly params: BoardScript["params"];
|
|
77
|
+
readonly targets: Readonly<Record<string, string>>;
|
|
78
|
+
emit(target: string, type: string, data?: unknown): Promise<void>;
|
|
79
|
+
readonly state: Record<string, unknown>;
|
|
80
|
+
readonly frame: BoardScriptFrame;
|
|
81
|
+
random(): number;
|
|
82
|
+
on(type: string, handler: (event: BoardScriptEvent) => void): () => void;
|
|
83
|
+
onFrame(handler: (frame: BoardScriptFrame) => void): () => void;
|
|
84
|
+
onDispose(handler: () => void): void;
|
|
85
|
+
invalidate(): void;
|
|
86
|
+
get(id: string): BoardItem | undefined;
|
|
87
|
+
present(id: string, patch: BoardScriptItemPatch | null): void;
|
|
88
|
+
scene(items: Record<string, unknown>, options?: {
|
|
89
|
+
space?: "world" | "screen";
|
|
90
|
+
}): void;
|
|
91
|
+
hitRegions(hits: Record<string, BoardScriptHit>): void;
|
|
92
|
+
commit(patch: BoardPatch): Promise<void>;
|
|
93
|
+
capabilities: {
|
|
94
|
+
has(name: string): boolean;
|
|
95
|
+
call(name: string, input?: unknown): Promise<unknown>;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
type BoardScriptModule = {
|
|
99
|
+
parameters?: Record<string, BoardScriptParameter>;
|
|
100
|
+
default?: ((context: BoardScriptContext) => void) | ((context: BoardScriptContext) => () => void);
|
|
101
|
+
draw?: (context: CanvasRenderingContext2D, frame: BoardScriptFrame) => void;
|
|
102
|
+
animated?: boolean;
|
|
103
|
+
};
|
|
104
|
+
//#endregion
|
|
105
|
+
export { BoardScriptContext, BoardScriptEvent, BoardScriptFrame, BoardScriptHit, BoardScriptItemPatch, BoardScriptModule, BoardScriptOutput, BoardScriptParameter, BoardScriptSnapshot };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BoardShapeGeometry } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import "../../protocol/dist/index.js";
|
|
3
|
+
//#region src/board/model/shape-types.d.ts
|
|
4
|
+
type ShapeKind = Exclude<BoardShapeGeometry, "path">;
|
|
5
|
+
declare const SHAPE_KINDS: ShapeKind[];
|
|
6
|
+
declare function isShapeKind(value: unknown): value is ShapeKind;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { SHAPE_KINDS, ShapeKind, isShapeKind };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { BOARD_SHAPE_GEOMETRIES } from "../../protocol/dist/board-model.js";
|
|
2
|
+
//#region src/board/model/shape-types.ts
|
|
3
|
+
const SHAPE_KINDS = BOARD_SHAPE_GEOMETRIES.filter((kind) => kind !== "path");
|
|
4
|
+
function isShapeKind(value) {
|
|
5
|
+
return typeof value === "string" && SHAPE_KINDS.includes(value);
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { SHAPE_KINDS, isShapeKind };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { BoardTaskArtifact, BoardTaskSnapshot } from "
|
|
2
|
-
import "
|
|
3
|
-
import { TaskRunRecord } from "
|
|
4
|
-
//#region src/board/task.d.ts
|
|
1
|
+
import { BoardTaskArtifact, BoardTaskSnapshot } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import "../../protocol/dist/index.js";
|
|
3
|
+
import { TaskRunRecord } from "../../types.js";
|
|
4
|
+
//#region src/board/model/task.d.ts
|
|
5
5
|
declare function taskArtifacts(blocks: Record<string, unknown>[]): BoardTaskArtifact[];
|
|
6
6
|
declare function rankedTaskArtifacts(artifacts: readonly BoardTaskArtifact[]): BoardTaskArtifact[];
|
|
7
7
|
declare function featuredTaskArtifact(artifacts: readonly BoardTaskArtifact[]): BoardTaskArtifact | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "
|
|
2
|
-
import { blockDurationMs, blockIdentity, blockMimeType, blockNaturalSize, blockPreviewUrl, blockText, blockTitle, blockUrl, cleanExcerpt, generationCovers, generationOutput, generationPrompt, taskData } from "
|
|
3
|
-
//#region src/board/task.ts
|
|
1
|
+
import "../../protocol/dist/board-model.js";
|
|
2
|
+
import { blockDurationMs, blockIdentity, blockMimeType, blockNaturalSize, blockPreviewUrl, blockText, blockTitle, blockUrl, cleanExcerpt, generationCovers, generationOutput, generationPrompt, taskData } from "../../generation-blocks.js";
|
|
3
|
+
//#region src/board/model/task.ts
|
|
4
4
|
function artifactId(base, used, suffix) {
|
|
5
5
|
const stem = cleanExcerpt(base, 220) ?? "output";
|
|
6
6
|
let candidate = suffix ? `${stem}-${suffix}` : stem;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clampBoardFontSize } from "../../protocol/dist/board-layout.js";
|
|
2
2
|
import "../../protocol/dist/index.js";
|
|
3
|
-
//#region src/board/
|
|
3
|
+
//#region src/board/model/text-metrics.d.ts
|
|
4
4
|
declare const TEXT_FONT_FAMILY = "Geist";
|
|
5
5
|
declare const TEXT_FONT_SIZE = 24;
|
|
6
6
|
declare const TEXT_LINE_HEIGHT = 32;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BOARD_TEXT_FONT_FAMILY } from "../../protocol/dist/board-constants.js";
|
|
2
2
|
import { clampBoardFontSize } from "../../protocol/dist/board-layout.js";
|
|
3
|
-
//#region src/board/
|
|
3
|
+
//#region src/board/model/text-metrics.ts
|
|
4
4
|
const TEXT_FONT_FAMILY = BOARD_TEXT_FONT_FAMILY;
|
|
5
5
|
const TEXT_FONT_SIZE = 24;
|
|
6
6
|
const TEXT_LINE_HEIGHT = 32;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, clampBoardStrokeSize } from "../../protocol/dist/board-constants.js";
|
|
2
2
|
import { BoardColorId } from "./palette.js";
|
|
3
3
|
import { ShapeKind } from "./shape-types.js";
|
|
4
|
-
//#region src/board/
|
|
4
|
+
//#region src/board/model/tool-styles.d.ts
|
|
5
5
|
type BoardToolStyleMap = {
|
|
6
6
|
text: {
|
|
7
7
|
color: BoardColorId;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BOARD_ARROW_STROKE_SIZE, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, clampBoardStrokeSize } from "../../protocol/dist/board-constants.js";
|
|
2
2
|
import { isBoardColorId } from "./palette.js";
|
|
3
3
|
import { isShapeKind } from "./shape-types.js";
|
|
4
|
-
//#region src/board/
|
|
4
|
+
//#region src/board/model/tool-styles.ts
|
|
5
5
|
const DEFAULT_BOARD_TOOL_STYLES = {
|
|
6
6
|
text: { color: "neutral" },
|
|
7
7
|
shape: {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BoardDocument, BoardItem } from "../../protocol/dist/board-model.js";
|
|
2
2
|
import { BoardPlaybackCommand, BoardPlaybackSnapshot } from "../../protocol/dist/board.js";
|
|
3
3
|
import "../../protocol/dist/index.js";
|
|
4
|
-
import { BoardCameraOverride, BoardColorResolver } from "../animation.js";
|
|
5
|
-
//#region src/board/
|
|
4
|
+
import { BoardCameraOverride, BoardColorResolver } from "../model/animation.js";
|
|
5
|
+
//#region src/board/player/index.d.ts
|
|
6
6
|
type BoardPlayerFrame = {
|
|
7
7
|
items: ReadonlyMap<string, BoardItem>;
|
|
8
8
|
camera: BoardCameraOverride;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { boardAnimationTime, compileBoardAnimations, evaluateBoardAnimations } from "../animation.js";
|
|
2
|
-
import { boardPresetTracks, isBoardPresetName } from "../presets.js";
|
|
3
|
-
|
|
1
|
+
import { boardAnimationTime, compileBoardAnimations, evaluateBoardAnimations } from "../model/animation.js";
|
|
2
|
+
import { boardPresetTracks, isBoardPresetName } from "../model/presets.js";
|
|
3
|
+
import { createBoardEntityId } from "../model/items/id.js";
|
|
4
|
+
//#region src/board/player/index.ts
|
|
4
5
|
const ENTER_ANIMATION = "\0enter";
|
|
5
6
|
const ENTER_STAGGER_MS = 45;
|
|
6
7
|
const ENTER_MAX_ITEMS = 80;
|
|
@@ -118,7 +119,7 @@ function nextLocalPlayback(current, command, document, now = Date.now()) {
|
|
|
118
119
|
};
|
|
119
120
|
switch (command.type) {
|
|
120
121
|
case "play": return {
|
|
121
|
-
playbackId:
|
|
122
|
+
playbackId: createBoardEntityId(),
|
|
122
123
|
animationId: command.animationId,
|
|
123
124
|
animationRevision: 0,
|
|
124
125
|
status: "playing",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BoardSettings } from "../../protocol/dist/board-model.js";
|
|
2
2
|
import "../../protocol/dist/index.js";
|
|
3
|
-
import { BoardViewport } from "../geometry.js";
|
|
3
|
+
import { BoardViewport } from "../model/geometry.js";
|
|
4
4
|
import { BoardRenderPalette } from "./renderers/board-renderer-registry.js";
|
|
5
5
|
import { Application, Container } from "pixi.js";
|
|
6
6
|
//#region src/board/render/board-background.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BoardScene, BoardSceneItem } from "../
|
|
1
|
+
import { BoardScene, BoardSceneItem } from "../model/scene.js";
|
|
2
2
|
import { Container, Graphics } from "pixi.js";
|
|
3
3
|
//#region src/board/render/clip.d.ts
|
|
4
4
|
declare function isClippingFrame(item: BoardSceneItem): boolean;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
//#region src/board/render/css-color.d.ts
|
|
2
|
+
type BoardCssPaint = {
|
|
3
|
+
color: number;
|
|
4
|
+
alpha: number;
|
|
5
|
+
};
|
|
6
|
+
declare function parseBoardCssPaint(value: string): BoardCssPaint | null;
|
|
2
7
|
declare function parseBoardCssColor(value: string): number | null;
|
|
3
8
|
//#endregion
|
|
4
|
-
export { parseBoardCssColor };
|
|
9
|
+
export { BoardCssPaint, parseBoardCssColor, parseBoardCssPaint };
|
|
@@ -1,36 +1,50 @@
|
|
|
1
1
|
import { DOMAdapter } from "pixi.js";
|
|
2
2
|
//#region src/board/render/css-color.ts
|
|
3
|
-
const CACHE_LIMIT = 256;
|
|
4
3
|
const cache = /* @__PURE__ */ new Map();
|
|
5
4
|
let canvas = null;
|
|
6
|
-
function
|
|
5
|
+
function parseBoardCssPaint(value) {
|
|
7
6
|
const key = value.trim();
|
|
8
7
|
if (!key) return null;
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
if (key.toLowerCase() === "transparent") return {
|
|
9
|
+
color: 0,
|
|
10
|
+
alpha: 0
|
|
11
|
+
};
|
|
12
|
+
const hex = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(key)?.[1];
|
|
13
|
+
if (hex) {
|
|
14
|
+
const digits = hex.length <= 4 ? [...hex].map((digit) => digit + digit).join("") : hex;
|
|
15
|
+
return {
|
|
16
|
+
color: Number.parseInt(digits.slice(0, 6), 16),
|
|
17
|
+
alpha: digits.length === 8 ? Number.parseInt(digits.slice(6), 16) / 255 : 1
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
if (cache.has(key)) return cache.get(key) ?? null;
|
|
11
21
|
let result = null;
|
|
12
22
|
try {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
canvas ??= DOMAdapter.get().createCanvas(1, 1);
|
|
24
|
+
const context = canvas.getContext("2d");
|
|
25
|
+
context.fillStyle = "#010203";
|
|
26
|
+
context.fillStyle = key;
|
|
27
|
+
const first = context.fillStyle;
|
|
28
|
+
context.fillStyle = "#040506";
|
|
29
|
+
context.fillStyle = key;
|
|
30
|
+
if (first === context.fillStyle) {
|
|
31
|
+
context.clearRect(0, 0, 1, 1);
|
|
32
|
+
context.fillRect(0, 0, 1, 1);
|
|
33
|
+
const [r = 0, g = 0, b = 0, a = 0] = context.getImageData(0, 0, 1, 1).data;
|
|
34
|
+
result = {
|
|
35
|
+
color: r << 16 | g << 8 | b,
|
|
36
|
+
alpha: a / 255
|
|
37
|
+
};
|
|
27
38
|
}
|
|
28
39
|
} catch {
|
|
29
40
|
result = null;
|
|
30
41
|
}
|
|
31
|
-
if (cache.size >=
|
|
42
|
+
if (cache.size >= 256) cache.clear();
|
|
32
43
|
cache.set(key, result);
|
|
33
44
|
return result;
|
|
34
45
|
}
|
|
46
|
+
function parseBoardCssColor(value) {
|
|
47
|
+
return parseBoardCssPaint(value)?.color ?? null;
|
|
48
|
+
}
|
|
35
49
|
//#endregion
|
|
36
|
-
export { parseBoardCssColor };
|
|
50
|
+
export { parseBoardCssColor, parseBoardCssPaint };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BoardTextItem } from "../../protocol/dist/board-model.js";
|
|
2
|
+
import "../../protocol/dist/index.js";
|
|
3
|
+
import { BoardScene } from "../model/scene.js";
|
|
4
|
+
//#region src/board/render/diagnostics.d.ts
|
|
5
|
+
type BoardRenderDiagnostic = {
|
|
6
|
+
code: "text-clipped" | "text-overlap" | "glyph-unavailable" | "effect-follow-unused";
|
|
7
|
+
item: string;
|
|
8
|
+
related?: string;
|
|
9
|
+
characters?: string;
|
|
10
|
+
};
|
|
11
|
+
declare function measureBoardText(props: BoardTextItem["props"]): {
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
lines: string[];
|
|
15
|
+
lineHeight: number;
|
|
16
|
+
missingCharacters: string;
|
|
17
|
+
};
|
|
18
|
+
declare function inspectBoardScene(scene: BoardScene, limit?: number): BoardRenderDiagnostic[];
|
|
19
|
+
//#endregion
|
|
20
|
+
export { BoardRenderDiagnostic, inspectBoardScene, measureBoardText };
|