@neta-art/cohub 10.0.0 → 11.1.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 +42 -7
- package/dist/board/editor/animation.d.ts +3 -0
- package/dist/board/editor/animation.js +16 -1
- package/dist/board/editor/clipboard.js +7 -0
- package/dist/board/editor/copy.js +23 -18
- package/dist/board/editor/creation.d.ts +7 -3
- package/dist/board/editor/creation.js +5 -4
- package/dist/board/editor/deletion.js +3 -3
- package/dist/board/editor/document.d.ts +8 -2
- package/dist/board/editor/document.js +54 -7
- package/dist/board/editor/editor.d.ts +22 -7
- package/dist/board/editor/editor.js +12 -2
- package/dist/board/editor/index.d.ts +2 -2
- package/dist/board/editor/interaction.d.ts +8 -2
- package/dist/board/editor/interaction.js +34 -1
- package/dist/board/editor/query.d.ts +5 -5
- package/dist/board/editor/query.js +14 -12
- package/dist/board/editor/selection.js +2 -1
- package/dist/board/editor/snapshots.d.ts +0 -2
- package/dist/board/editor/snapshots.js +4 -20
- package/dist/board/export/index.d.ts +25 -4
- package/dist/board/export/index.js +45 -12
- package/dist/board/export/node/index.d.ts +5 -4
- package/dist/board/export/node/index.js +16 -11
- 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 +2 -1
- package/dist/board/export/scene.js +24 -7
- package/dist/board/model/animation.d.ts +4 -1
- package/dist/board/model/animation.js +34 -7
- package/dist/board/model/authoring.d.ts +20 -0
- package/dist/board/model/authoring.js +185 -0
- package/dist/board/model/export-plan.js +1 -0
- package/dist/board/model/file-preview.js +1 -1
- package/dist/board/model/file-snapshot.js +3 -2
- package/dist/board/model/image-key.js +7 -3
- package/dist/board/model/index.d.ts +15 -7
- package/dist/board/model/index.js +16 -9
- package/dist/board/model/items/builtin.js +2 -2
- package/dist/board/model/items/create.d.ts +19 -4
- package/dist/board/model/items/create.js +130 -9
- package/dist/board/model/items/index.d.ts +2 -2
- package/dist/board/model/items/index.js +2 -2
- package/dist/board/model/media-playback.d.ts +2 -1
- package/dist/board/model/media-playback.js +15 -5
- package/dist/board/model/media.js +7 -1
- package/dist/board/model/overlay-placement.d.ts +25 -0
- package/dist/board/model/overlay-placement.js +35 -0
- package/dist/board/model/replay.d.ts +1 -1
- package/dist/board/model/replay.js +1 -0
- package/dist/board/model/sampling.d.ts +19 -0
- package/dist/board/model/sampling.js +96 -0
- 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 +27 -0
- package/dist/board/model/script-hit.js +109 -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-observers.d.ts +18 -0
- package/dist/board/model/script-observers.js +92 -0
- package/dist/board/model/script-scene.d.ts +24 -0
- package/dist/board/model/script-scene.js +294 -0
- package/dist/board/model/script.d.ts +149 -0
- package/dist/board/model/script.js +1 -0
- package/dist/board/render/board-background.js +5 -4
- 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.js +1 -1
- package/dist/board/render/palette.d.ts +2 -1
- package/dist/board/render/palette.js +6 -2
- package/dist/board/render/renderers/arrow-card-renderer.js +3 -2
- package/dist/board/render/renderers/audio-card-renderer.js +2 -1
- package/dist/board/render/renderers/board-renderer-registry.d.ts +25 -5
- package/dist/board/render/renderers/board-renderer-registry.js +11 -4
- 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} +18 -16
- package/dist/board/render/renderers/draw-card-renderer.js +3 -2
- package/dist/board/render/renderers/effect-card-renderer.js +22 -5
- package/dist/board/render/renderers/frame-card-renderer.js +30 -14
- package/dist/board/render/renderers/image-card-renderer.js +43 -4
- package/dist/board/render/renderers/shape-card-renderer.js +10 -27
- package/dist/board/render/renderers/task-card-renderer.d.ts +2 -1
- package/dist/board/render/renderers/task-card-renderer.js +220 -71
- package/dist/board/render/renderers/text-card-renderer.js +5 -3
- package/dist/board/render/renderers/unknown-card-renderer.js +1 -0
- 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 +446 -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 +223 -0
- package/dist/board/render/script-sandbox.d.ts +4 -0
- package/dist/board/render/script-sandbox.js +173 -0
- package/dist/board/render/script-texture.d.ts +11 -0
- package/dist/board/render/script-texture.js +33 -0
- package/dist/board/render/stroke.d.ts +2 -1
- package/dist/board/render/stroke.js +22 -1
- package/dist/board/render/text-measurement.js +1 -1
- package/dist/board/stage/assets.js +7 -2
- package/dist/board/stage/maintenance.d.ts +5 -0
- package/dist/board/stage/maintenance.js +11 -0
- package/dist/board/stage/scene.d.ts +2 -0
- package/dist/board/stage/scene.js +21 -2
- package/dist/board/stage/script-pointer.d.ts +20 -0
- package/dist/board/stage/script-pointer.js +41 -0
- package/dist/board/stage/stage.d.ts +21 -3
- package/dist/board/stage/stage.js +350 -47
- package/dist/board/stage/texture-pool.js +2 -3
- package/dist/chunks/environment.d.ts +305 -27
- package/dist/chunks/environment.js +12 -4
- package/dist/chunks/host-bridge.d.ts +2 -2
- package/dist/chunks/http.d.ts +90 -7
- package/dist/chunks/http.js +157 -64
- package/dist/chunks/transport.js +4 -2
- 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 +3 -3
- package/dist/index.d.ts +182 -4
- package/dist/index.js +1559 -299
- 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 +236 -11
- package/dist/protocol/dist/board-model.js +46 -17
- package/dist/protocol/dist/board-patch.js +2 -1
- 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-task.d.ts +22 -0
- package/dist/{board/model/task.js → protocol/dist/board-task.js} +34 -7
- package/dist/protocol/dist/display/index.d.ts +1 -0
- package/dist/protocol/dist/generation/blocks.d.ts +8 -0
- package/dist/{generation-blocks.js → protocol/dist/generation/blocks.js} +14 -15
- package/dist/protocol/dist/index.d.ts +7 -2
- package/dist/protocol/dist/realtime/types.d.ts +1 -0
- package/dist/protocol/dist/rtc/index.d.ts +1 -0
- package/dist/protocol/dist/task/index.d.ts +4 -0
- package/package.json +2 -1
- package/dist/board/export/node/sketch.d.ts +0 -19
- package/dist/board/export/node/sketch.js +0 -146
- package/dist/board/model/task.d.ts +0 -11
- 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
- package/dist/types.d.ts +0 -36
package/README.md
CHANGED
|
@@ -46,18 +46,39 @@ Development uses:
|
|
|
46
46
|
- API: `https://api-dev.cohub.live`
|
|
47
47
|
- WebSocket: `wss://gateway-dev.cohub.live/ws`
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Override endpoints for self-hosted deployments or proxies:
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
const client = createCohubClient({
|
|
53
53
|
baseUrl: "https://api.example.com",
|
|
54
|
+
webBaseUrl: "https://cohub.example.com",
|
|
54
55
|
getAccessToken: async () => localStorage.getItem("token"),
|
|
55
56
|
websocket: {
|
|
56
57
|
url: "https://gateway.example.com",
|
|
57
58
|
},
|
|
59
|
+
voice: {
|
|
60
|
+
url: "https://gateway.example.com",
|
|
61
|
+
},
|
|
58
62
|
});
|
|
59
63
|
```
|
|
60
64
|
|
|
65
|
+
In Node.js, the SDK and CLI share these optional environment variables:
|
|
66
|
+
|
|
67
|
+
| Variable | Endpoint |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `COHUB_BASE_URL` | API base URL |
|
|
70
|
+
| `COHUB_WS_URL` | Realtime gateway URL (`http(s)` or `ws(s)`; `/ws` is added when omitted) |
|
|
71
|
+
| `COHUB_WEB_URL` | Web origin for App authorization and CLI links |
|
|
72
|
+
| `COHUB_VOICE_WS_URL` | Voice input gateway URL; falls back to `COHUB_WS_URL` with `/asr/ws` |
|
|
73
|
+
|
|
74
|
+
Explicit client options take precedence over environment variables. Unconfigured
|
|
75
|
+
endpoints use the selected environment's defaults. API, web, and gateway addresses
|
|
76
|
+
are configured separately; changing `baseUrl` does not change the gateway.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
COHUB_BASE_URL=http://localhost:3000 COHUB_WS_URL=ws://localhost:8080 node app.js
|
|
80
|
+
```
|
|
81
|
+
|
|
61
82
|
## Spaces and sessions
|
|
62
83
|
|
|
63
84
|
A **Space** is a live, isolated working environment where users and agents create together.
|
|
@@ -101,10 +122,15 @@ const stop = board.subscribe({
|
|
|
101
122
|
});
|
|
102
123
|
```
|
|
103
124
|
|
|
104
|
-
Task Items
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
125
|
+
Task Items show a run by its `taskRunId`. Write only the id; the server fills
|
|
126
|
+
the display snapshot from the run and rewrites it when the run finishes, on
|
|
127
|
+
every Board in the Space that shows it. Lay a run's results out as media with
|
|
128
|
+
`createTaskResultItems`; each result keeps an `origin` leading back to the run.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
const { taskRunId } = await client.generations.create({ spaceId, model, content });
|
|
132
|
+
await board.apply({ items: { hero: { type: "task", position: { x: 80, y: 80 }, size: { width: 480, height: 270 }, props: { taskRunId } } } });
|
|
133
|
+
```
|
|
108
134
|
|
|
109
135
|
### Layers
|
|
110
136
|
|
|
@@ -131,7 +157,7 @@ The editor has no framework. Read state through its getters and listen with
|
|
|
131
157
|
change, so they work directly with `useSyncExternalStore`:
|
|
132
158
|
|
|
133
159
|
```ts
|
|
134
|
-
import { createBoardRegistry, defineBoardItem } from "@neta-art/cohub/board";
|
|
160
|
+
import { createBoardRegistry, defineBoardItem, worldPoint } from "@neta-art/cohub/board";
|
|
135
161
|
import { createBoardEditor } from "@neta-art/cohub/board/editor";
|
|
136
162
|
import { createBoardReplica } from "@neta-art/cohub/board/replica";
|
|
137
163
|
import { createBoardAssetManager, mountBoardStage } from "@neta-art/cohub/board/stage";
|
|
@@ -157,7 +183,16 @@ const editor = createBoardEditor({
|
|
|
157
183
|
});
|
|
158
184
|
replica.subscribe((state) => state.document && editor.loadDocument(state.document, boardId));
|
|
159
185
|
|
|
160
|
-
//
|
|
186
|
+
// Prefer stable media URLs. Existing Space paths remain supported by addFile.
|
|
187
|
+
editor.addMedia("https://cdn.example.com/cover.webp", worldPoint(0, 0));
|
|
188
|
+
// Supply a kind for sources without a file extension.
|
|
189
|
+
editor.addMedia("https://cdn.example.com/media?id=42", worldPoint(400, 0), {
|
|
190
|
+
kind: "video",
|
|
191
|
+
snapshot: { title: "Launch", naturalWidth: 1920, naturalHeight: 1080 },
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Media URLs load directly; these callbacks only receive Space paths.
|
|
195
|
+
// A published copy can resolve paths against captured artifacts instead.
|
|
161
196
|
const source = {
|
|
162
197
|
resolveFileUrl: (path: string) => space.files.resolveUrl(path, { purpose: "preview" }),
|
|
163
198
|
resolvePlaybackUrl: (path: string) => space.files.resolveUrl(path, { purpose: "playback" }),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BoardChapter } from "../model/authoring.js";
|
|
2
|
+
import "../model/index.js";
|
|
1
3
|
import { BoardPlayhead, EditorContext } from "./context.js";
|
|
2
4
|
//#region src/board/editor/animation.d.ts
|
|
3
5
|
declare function createAnimationModule(ctx: EditorContext): {
|
|
@@ -8,6 +10,7 @@ declare function createAnimationModule(ctx: EditorContext): {
|
|
|
8
10
|
removeKeyframe: (trackId: string, at: number) => void;
|
|
9
11
|
setKeyframeEase: (trackId: string, at: number, ease: string | null) => void;
|
|
10
12
|
createAnimation: (name: string, duration?: number) => string;
|
|
13
|
+
createSequence: (name: string, chapters: BoardChapter[]) => string | null;
|
|
11
14
|
};
|
|
12
15
|
type AnimationModule = ReturnType<typeof createAnimationModule>;
|
|
13
16
|
//#endregion
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { boardSequence } from "../model/authoring.js";
|
|
1
2
|
import { createBoardItemId } from "../model/items/id.js";
|
|
2
3
|
import { readPath, sameJson } from "./document-edits.js";
|
|
3
4
|
//#region src/board/editor/animation.ts
|
|
@@ -158,6 +159,19 @@ function createAnimationModule(ctx) {
|
|
|
158
159
|
});
|
|
159
160
|
return id;
|
|
160
161
|
}
|
|
162
|
+
function createSequence(name, chapters) {
|
|
163
|
+
if (options.readonly) return null;
|
|
164
|
+
const id = createBoardItemId();
|
|
165
|
+
commitAnimation(id, {
|
|
166
|
+
...boardSequence(state.base, chapters),
|
|
167
|
+
name
|
|
168
|
+
});
|
|
169
|
+
setPlayhead({
|
|
170
|
+
animationId: id,
|
|
171
|
+
time: 0
|
|
172
|
+
});
|
|
173
|
+
return id;
|
|
174
|
+
}
|
|
161
175
|
return {
|
|
162
176
|
setPlayhead,
|
|
163
177
|
setRecording,
|
|
@@ -165,7 +179,8 @@ function createAnimationModule(ctx) {
|
|
|
165
179
|
toggleKeyframe,
|
|
166
180
|
removeKeyframe,
|
|
167
181
|
setKeyframeEase,
|
|
168
|
-
createAnimation
|
|
182
|
+
createAnimation,
|
|
183
|
+
createSequence
|
|
169
184
|
};
|
|
170
185
|
}
|
|
171
186
|
//#endregion
|
|
@@ -65,6 +65,13 @@ function remapItems(items, idMap, place = (item) => item, resolveEnd = () => nul
|
|
|
65
65
|
let item = place(source);
|
|
66
66
|
const { locked: _locked, ...unlocked } = item;
|
|
67
67
|
item = unlocked;
|
|
68
|
+
if (item.script) item = {
|
|
69
|
+
...item,
|
|
70
|
+
script: {
|
|
71
|
+
...item.script,
|
|
72
|
+
targets: Object.fromEntries(Object.entries(item.script.targets).map(([name, target]) => [name, idMap.get(target) ?? target]))
|
|
73
|
+
}
|
|
74
|
+
};
|
|
68
75
|
if (item.parent) {
|
|
69
76
|
const parent = idMap.get(item.parent);
|
|
70
77
|
if (parent) item = {
|
|
@@ -7,35 +7,39 @@ function createCopyModule(ctx) {
|
|
|
7
7
|
const { state, options } = ctx;
|
|
8
8
|
let internalClipboard = null;
|
|
9
9
|
let pasteCount = 0;
|
|
10
|
-
function detachedSubtrees(ids) {
|
|
11
|
-
const { scene } = state;
|
|
10
|
+
function detachedSubtrees(ids, scene) {
|
|
12
11
|
const items = {};
|
|
13
12
|
for (const root of ctx.query.rootsOf(ids)) {
|
|
14
13
|
const item = scene.get(root);
|
|
15
|
-
if (!item) continue;
|
|
14
|
+
if (!item || !state.base.items[root]) continue;
|
|
16
15
|
const { id: _id, frame, ...stored } = item;
|
|
17
16
|
items[root] = ctx.document.reparent(stored, frame, void 0, scene.layout.box(root));
|
|
18
17
|
for (const child of scene.descendants(root)) {
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
if (!state.base.items[child]) continue;
|
|
19
|
+
const shown = scene.get(child);
|
|
20
|
+
if (shown) {
|
|
21
|
+
const { id: _id, frame: _frame, ...value } = shown;
|
|
22
|
+
items[child] = value;
|
|
23
|
+
}
|
|
21
24
|
}
|
|
22
25
|
}
|
|
23
26
|
return items;
|
|
24
27
|
}
|
|
25
|
-
function arrowEndPoint(id, which) {
|
|
26
|
-
const arrow =
|
|
28
|
+
function arrowEndPoint(scene, id, which) {
|
|
29
|
+
const arrow = scene.get(id);
|
|
27
30
|
if (arrow?.type !== "arrow") return null;
|
|
28
|
-
const resolved = resolveSceneArrow(arrow,
|
|
29
|
-
return applyMatrix(invertMatrix(
|
|
31
|
+
const resolved = resolveSceneArrow(arrow, scene);
|
|
32
|
+
return applyMatrix(invertMatrix(scene.layout.matrix(id)), (which === "start" ? resolved.start : resolved.end).point);
|
|
30
33
|
}
|
|
31
34
|
function duplicates(ids, offset) {
|
|
32
|
-
const
|
|
33
|
-
const copied = detachedSubtrees(ids);
|
|
35
|
+
const scene = ctx.document.copyScene();
|
|
36
|
+
const copied = detachedSubtrees(ids, scene);
|
|
34
37
|
for (const id of Object.keys(copied)) for (const arrowId of scene.binders(id)) {
|
|
35
|
-
|
|
38
|
+
if (!state.base.items[arrowId]) continue;
|
|
36
39
|
const shown = scene.get(arrowId);
|
|
37
|
-
if (copied[arrowId] || !
|
|
38
|
-
|
|
40
|
+
if (copied[arrowId] || !shown || !arrowBindings(shown).every((bound) => copied[bound])) continue;
|
|
41
|
+
const { id: _id, frame, ...arrow } = shown;
|
|
42
|
+
copied[arrowId] = ctx.document.reparent(arrow, frame, void 0, scene.layout.box(arrowId));
|
|
39
43
|
}
|
|
40
44
|
const idMap = new Map(Object.keys(copied).map((id) => [id, createBoardItemId()]));
|
|
41
45
|
const moved = remapItems(copied, idMap, (item) => item.parent && copied[item.parent] ? item : {
|
|
@@ -44,8 +48,8 @@ function createCopyModule(ctx) {
|
|
|
44
48
|
x: item.position.x + offset,
|
|
45
49
|
y: item.position.y + offset
|
|
46
50
|
}
|
|
47
|
-
}, arrowEndPoint);
|
|
48
|
-
let z = ctx.document.topZ(void 0);
|
|
51
|
+
}, (id, which) => arrowEndPoint(scene, id, which));
|
|
52
|
+
let z = ctx.document.topZ(void 0, scene);
|
|
49
53
|
return new Map(Object.entries(moved).map(([id, item]) => [id, item.parent ? item : {
|
|
50
54
|
...item,
|
|
51
55
|
z: z++
|
|
@@ -66,8 +70,9 @@ function createCopyModule(ctx) {
|
|
|
66
70
|
function copySelection() {
|
|
67
71
|
const { selection } = state;
|
|
68
72
|
if (selection.length === 0) return null;
|
|
69
|
-
const
|
|
70
|
-
const
|
|
73
|
+
const scene = ctx.document.copyScene();
|
|
74
|
+
const copied = detachedSubtrees(selection, scene);
|
|
75
|
+
const origin = ctx.query.contentBounds(ctx.query.rootsOf(selection), scene);
|
|
71
76
|
const payload = origin ? encodeClipboard(copied, {
|
|
72
77
|
x: origin.x,
|
|
73
78
|
y: origin.y
|
|
@@ -3,7 +3,7 @@ import { BoardMatrix } from "../../protocol/dist/board-layout.js";
|
|
|
3
3
|
import { WorldPoint } from "../model/geometry.js";
|
|
4
4
|
import { BoardFileSnapshotFacts } from "../model/file-snapshot.js";
|
|
5
5
|
import { ShapeKind } from "../model/shape-types.js";
|
|
6
|
-
import { BoardItemEntry, createAppBoardItem } from "../model/items/create.js";
|
|
6
|
+
import { BoardItemEntry, BoardMediaItemKind, createAppBoardItem } from "../model/items/create.js";
|
|
7
7
|
import { BoardItemInput } from "../model/items/registry.js";
|
|
8
8
|
import "../model/index.js";
|
|
9
9
|
import { BoardInteraction } from "./interaction.js";
|
|
@@ -23,9 +23,13 @@ declare function createCreationModule(ctx: EditorContext): {
|
|
|
23
23
|
}) => void;
|
|
24
24
|
addItem: (type: string, input: BoardItemInput) => string | null;
|
|
25
25
|
addApp: (app: BoardAppMetadata, at: WorldPoint) => string;
|
|
26
|
+
addMedia: (src: string, at: WorldPoint, options?: {
|
|
27
|
+
kind?: BoardMediaItemKind;
|
|
28
|
+
snapshot?: BoardMediaSnapshot;
|
|
29
|
+
}) => string;
|
|
26
30
|
addFile: (path: string, at: WorldPoint, snapshot?: BoardMediaSnapshot & BoardFileSnapshotFacts) => string;
|
|
27
|
-
addTask: (taskRunId: string, snapshot: BoardTaskSnapshot, at: WorldPoint, metadata?: Record<string, unknown
|
|
28
|
-
addTaskWithSources: (taskRunId: string, snapshot: BoardTaskSnapshot, at: WorldPoint, sources: BoardTaskSource[], metadata?: Record<string, unknown
|
|
31
|
+
addTask: (taskRunId: string, snapshot: BoardTaskSnapshot, at: WorldPoint, metadata?: Record<string, unknown>, aspect?: number) => string;
|
|
32
|
+
addTaskWithSources: (taskRunId: string, snapshot: BoardTaskSnapshot, at: WorldPoint, sources: BoardTaskSource[], metadata?: Record<string, unknown>, aspect?: number) => string | null;
|
|
29
33
|
addText: (text: string, at: WorldPoint) => void;
|
|
30
34
|
addShape: (at: WorldPoint, geometry?: ShapeKind) => void;
|
|
31
35
|
addFrame: (at: WorldPoint) => void;
|
|
@@ -3,7 +3,7 @@ import { rectCenter } from "../model/geometry.js";
|
|
|
3
3
|
import { buildBoardScene } from "../model/scene.js";
|
|
4
4
|
import { isShapeKind } from "../model/shape-types.js";
|
|
5
5
|
import { createBoardItemId } from "../model/items/id.js";
|
|
6
|
-
import { createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createShapeBoardItem, createTaskBoardItem, createTextBoardItem } from "../model/items/create.js";
|
|
6
|
+
import { createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTextBoardItem } from "../model/items/create.js";
|
|
7
7
|
import { sameJson } from "./document-edits.js";
|
|
8
8
|
import { isContinuousBoardTool } from "./tool.js";
|
|
9
9
|
//#region src/board/editor/creation.ts
|
|
@@ -53,10 +53,10 @@ function createCreationModule(ctx) {
|
|
|
53
53
|
if (options.readonly) return null;
|
|
54
54
|
return addOne(ctx.registry.create(type, input));
|
|
55
55
|
}
|
|
56
|
-
function addTaskWithSources(taskRunId, snapshot, at, sources, metadata) {
|
|
56
|
+
function addTaskWithSources(taskRunId, snapshot, at, sources, metadata, aspect) {
|
|
57
57
|
if (options.readonly) return null;
|
|
58
58
|
const { arrow } = state.toolStyles;
|
|
59
|
-
const task = createTaskBoardItem(taskRunId, snapshot, at.x, at.y, metadata);
|
|
59
|
+
const task = createTaskBoardItem(taskRunId, snapshot, at.x, at.y, metadata, void 0, aspect);
|
|
60
60
|
add([task, ...sources.filter((source) => source.itemId !== task.id && state.scene.get(source.itemId)).map((source) => {
|
|
61
61
|
const entry = createArrowBoardItem({
|
|
62
62
|
x: 0,
|
|
@@ -197,8 +197,9 @@ function createCreationModule(ctx) {
|
|
|
197
197
|
add,
|
|
198
198
|
addItem,
|
|
199
199
|
addApp: (app, at) => addOne(createAppBoardItem(app, at.x, at.y)),
|
|
200
|
+
addMedia: (src, at, options = {}) => addOne(createMediaBoardItem(src, at.x, at.y, options.snapshot, void 0, options.kind)),
|
|
200
201
|
addFile: (path, at, snapshot) => addOne(createFileNodeForPath(path, at.x, at.y, snapshot)),
|
|
201
|
-
addTask: (taskRunId, snapshot, at, metadata) => addOne(createTaskBoardItem(taskRunId, snapshot, at.x, at.y, metadata)),
|
|
202
|
+
addTask: (taskRunId, snapshot, at, metadata, aspect) => addOne(createTaskBoardItem(taskRunId, snapshot, at.x, at.y, metadata, void 0, aspect)),
|
|
202
203
|
addTaskWithSources,
|
|
203
204
|
addText: (text, at) => {
|
|
204
205
|
add([createTextBoardItem(text, at.x, at.y, styles().text.color)]);
|
|
@@ -8,14 +8,14 @@ function createDeletionModule(ctx) {
|
|
|
8
8
|
const { scene, base } = state;
|
|
9
9
|
const doomed = /* @__PURE__ */ new Set();
|
|
10
10
|
for (const id of ids) {
|
|
11
|
-
if (!
|
|
11
|
+
if (!base.items[id]) continue;
|
|
12
12
|
doomed.add(id);
|
|
13
|
-
for (const child of scene.descendants(id)) doomed.add(child);
|
|
13
|
+
for (const child of scene.descendants(id)) if (base.items[child]) doomed.add(child);
|
|
14
14
|
}
|
|
15
15
|
const changes = /* @__PURE__ */ new Map();
|
|
16
16
|
for (const id of doomed) changes.set(id, null);
|
|
17
17
|
for (const id of doomed) for (const arrowId of scene.binders(id)) {
|
|
18
|
-
if (doomed.has(arrowId) || changes.has(arrowId)) continue;
|
|
18
|
+
if (!base.items[arrowId] || doomed.has(arrowId) || changes.has(arrowId)) continue;
|
|
19
19
|
const arrow = scene.get(arrowId);
|
|
20
20
|
if (!arrow) continue;
|
|
21
21
|
const resolved = resolveSceneArrow(arrow, scene);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { BoardAnimation, BoardDocument, BoardItem, BoardSettings } from "../../protocol/dist/board-model.js";
|
|
1
|
+
import { BoardAnimation, BoardDocument, BoardItem, BoardPatch, BoardSettings } from "../../protocol/dist/board-model.js";
|
|
2
2
|
import { BoardFrame } from "../../protocol/dist/board-layout.js";
|
|
3
3
|
import { Rect } from "../model/geometry.js";
|
|
4
|
+
import { BoardScene } from "../model/scene.js";
|
|
4
5
|
import "../model/index.js";
|
|
5
6
|
import { EditorContext } from "./context.js";
|
|
6
7
|
//#region src/board/editor/document.d.ts
|
|
@@ -8,8 +9,13 @@ declare function createDocumentModule(ctx: EditorContext): {
|
|
|
8
9
|
markAdded: (ids: readonly string[]) => void;
|
|
9
10
|
consumeRecentlyAdded: () => string[];
|
|
10
11
|
displayItem: (id: string) => BoardItem | undefined;
|
|
12
|
+
copyScene: () => BoardScene;
|
|
11
13
|
reevaluate: () => void;
|
|
12
14
|
setPlayedItems: (items: ReadonlyMap<string, BoardItem>) => void;
|
|
15
|
+
readonly hasScriptItems: boolean;
|
|
16
|
+
setScriptItems: (items: ReadonlyMap<string, BoardItem>) => void;
|
|
17
|
+
animationItems: () => Map<string, BoardItem>;
|
|
18
|
+
commitPatch: (patch: BoardPatch) => Promise<void> | undefined;
|
|
13
19
|
rescene: (ids?: Iterable<string>) => void;
|
|
14
20
|
reset: (next: BoardDocument) => void;
|
|
15
21
|
setDraftItem: (id: string, item: BoardItem | null) => void;
|
|
@@ -28,7 +34,7 @@ declare function createDocumentModule(ctx: EditorContext): {
|
|
|
28
34
|
previewSettings: (settings: BoardSettings) => void;
|
|
29
35
|
setSettings: (settings: BoardSettings) => void;
|
|
30
36
|
reparent: (item: BoardItem, frame: BoardFrame, parent: string | undefined, box: Rect) => BoardItem;
|
|
31
|
-
topZ: (parent: string | undefined) => number;
|
|
37
|
+
topZ: (parent: string | undefined, scene?: BoardScene) => number;
|
|
32
38
|
};
|
|
33
39
|
type DocumentModule = ReturnType<typeof createDocumentModule>;
|
|
34
40
|
//#endregion
|
|
@@ -11,6 +11,7 @@ function createDocumentModule(ctx) {
|
|
|
11
11
|
const recentlyAdded = /* @__PURE__ */ new Set();
|
|
12
12
|
let evaluated = /* @__PURE__ */ new Map();
|
|
13
13
|
let played = /* @__PURE__ */ new Map();
|
|
14
|
+
let scripted = /* @__PURE__ */ new Map();
|
|
14
15
|
let compiled = null;
|
|
15
16
|
function markAdded(ids) {
|
|
16
17
|
if (ids.length === 0) return;
|
|
@@ -24,14 +25,15 @@ function createDocumentModule(ctx) {
|
|
|
24
25
|
}
|
|
25
26
|
function displayItem(id) {
|
|
26
27
|
if (draft.has(id)) return draft.get(id) ?? void 0;
|
|
27
|
-
return evaluated.get(id) ?? played.get(id) ?? state.base.items[id];
|
|
28
|
+
return scripted.get(id) ?? evaluated.get(id) ?? played.get(id) ?? state.base.items[id];
|
|
28
29
|
}
|
|
29
|
-
function displayDocument() {
|
|
30
|
+
function displayDocument(includeScripts = true) {
|
|
30
31
|
const base = state.base;
|
|
31
|
-
if (draft.size === 0 && evaluated.size === 0 && played.size === 0) return base;
|
|
32
|
+
if (draft.size === 0 && evaluated.size === 0 && played.size === 0 && (!includeScripts || scripted.size === 0)) return base;
|
|
32
33
|
const items = { ...base.items };
|
|
33
34
|
for (const [id, item] of played) items[id] = item;
|
|
34
35
|
for (const [id, item] of evaluated) items[id] = item;
|
|
36
|
+
if (includeScripts) for (const [id, item] of scripted) items[id] = item;
|
|
35
37
|
for (const [id, item] of draft) if (item) items[id] = item;
|
|
36
38
|
else delete items[id];
|
|
37
39
|
return {
|
|
@@ -59,6 +61,17 @@ function createDocumentModule(ctx) {
|
|
|
59
61
|
for (const id of changed) if (draft.has(id) || evaluated.has(id) || sameJson(previous.get(id), played.get(id))) changed.delete(id);
|
|
60
62
|
if (changed.size) rescene(changed);
|
|
61
63
|
}
|
|
64
|
+
function setScriptItems(items) {
|
|
65
|
+
const previous = scripted;
|
|
66
|
+
scripted = items;
|
|
67
|
+
const changed = [.../* @__PURE__ */ new Set([...previous.keys(), ...items.keys()])].filter((id) => !sameJson(previous.get(id), items.get(id)));
|
|
68
|
+
if (!changed.length) return;
|
|
69
|
+
rescene(changed.some((id) => {
|
|
70
|
+
const before = previous.get(id) ?? state.base.items[id];
|
|
71
|
+
const after = items.get(id) ?? state.base.items[id];
|
|
72
|
+
return !before || !after || before.parent !== after.parent || before.z !== after.z || !sameJson(arrowBindings(before), arrowBindings(after));
|
|
73
|
+
}) ? void 0 : changed);
|
|
74
|
+
}
|
|
62
75
|
function rescene(ids) {
|
|
63
76
|
if (ids) {
|
|
64
77
|
const changed = [...ids];
|
|
@@ -76,6 +89,7 @@ function createDocumentModule(ctx) {
|
|
|
76
89
|
draft.clear();
|
|
77
90
|
draftOrigins.clear();
|
|
78
91
|
played = /* @__PURE__ */ new Map();
|
|
92
|
+
scripted = /* @__PURE__ */ new Map();
|
|
79
93
|
reevaluate();
|
|
80
94
|
state.scene = buildBoardScene(next);
|
|
81
95
|
ctx.query.invalidate();
|
|
@@ -114,12 +128,20 @@ function createDocumentModule(ctx) {
|
|
|
114
128
|
rescene();
|
|
115
129
|
}
|
|
116
130
|
function send(patch) {
|
|
117
|
-
if (options.readonly || isEmptyBoardPatch(patch)) return;
|
|
131
|
+
if (options.readonly || isEmptyBoardPatch(patch)) return Promise.resolve(null);
|
|
118
132
|
state.pendingCommits += 1;
|
|
119
|
-
|
|
133
|
+
let completion;
|
|
134
|
+
try {
|
|
135
|
+
completion = Promise.resolve(options.onCommit(patch));
|
|
136
|
+
} catch (error) {
|
|
137
|
+
completion = Promise.reject(error);
|
|
138
|
+
}
|
|
139
|
+
return completion.then(() => {
|
|
120
140
|
state.saveError = null;
|
|
141
|
+
return null;
|
|
121
142
|
}).catch((error) => {
|
|
122
143
|
state.saveError = error instanceof Error ? error.message : "Failed to sync board";
|
|
144
|
+
return error instanceof Error ? error : new Error(state.saveError);
|
|
123
145
|
}).finally(() => {
|
|
124
146
|
state.pendingCommits -= 1;
|
|
125
147
|
});
|
|
@@ -183,6 +205,24 @@ function createDocumentModule(ctx) {
|
|
|
183
205
|
for (const [id, item] of changes) setDraftItem(id, item);
|
|
184
206
|
commit({}, record);
|
|
185
207
|
}
|
|
208
|
+
function commitPatch(patch) {
|
|
209
|
+
if (options.readonly) throw new Error("Board is read-only.");
|
|
210
|
+
const before = state.base;
|
|
211
|
+
const result = applyBoardPatchToDocument(before, patch);
|
|
212
|
+
if (!result.ok) throw new Error(result.diagnostics[0]?.message ?? "Invalid board patch.");
|
|
213
|
+
const ids = Object.keys(patch.items ?? {});
|
|
214
|
+
const redo = diffBoardEdits(before, result.document, ids);
|
|
215
|
+
if (isEmptyBoardPatch(redo)) return;
|
|
216
|
+
state.undoStack = [...state.undoStack.slice(-199), {
|
|
217
|
+
undo: diffBoardEdits(result.document, before, ids),
|
|
218
|
+
redo
|
|
219
|
+
}];
|
|
220
|
+
state.redoStack = [];
|
|
221
|
+
adopt(result.document, ids);
|
|
222
|
+
return send(redo).then((error) => {
|
|
223
|
+
if (error) throw error;
|
|
224
|
+
});
|
|
225
|
+
}
|
|
186
226
|
function applyPatch(patch) {
|
|
187
227
|
const result = applyBoardPatchToDocument(state.base, patch);
|
|
188
228
|
if (!result.ok) {
|
|
@@ -222,17 +262,24 @@ function createDocumentModule(ctx) {
|
|
|
222
262
|
const matrix = parent ? state.scene.layout.matrix(parent) : IDENTITY_MATRIX;
|
|
223
263
|
return placeItem(next, frame, matrix, box);
|
|
224
264
|
}
|
|
225
|
-
function topZ(parent) {
|
|
265
|
+
function topZ(parent, scene = state.scene) {
|
|
226
266
|
let z = 0;
|
|
227
|
-
for (const id of
|
|
267
|
+
for (const id of scene.children(parent)) z = Math.max(z, scene.get(id)?.z ?? 0);
|
|
228
268
|
return z + 1;
|
|
229
269
|
}
|
|
230
270
|
return {
|
|
231
271
|
markAdded,
|
|
232
272
|
consumeRecentlyAdded,
|
|
233
273
|
displayItem,
|
|
274
|
+
copyScene: () => scripted.size ? buildBoardScene(displayDocument(false)) : state.scene,
|
|
234
275
|
reevaluate,
|
|
235
276
|
setPlayedItems,
|
|
277
|
+
get hasScriptItems() {
|
|
278
|
+
return scripted.size > 0;
|
|
279
|
+
},
|
|
280
|
+
setScriptItems,
|
|
281
|
+
animationItems: () => new Map([...played, ...evaluated]),
|
|
282
|
+
commitPatch,
|
|
236
283
|
rescene,
|
|
237
284
|
reset,
|
|
238
285
|
setDraftItem,
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { BoardDocument, BoardItem, BoardMediaSnapshot, BoardSettings, BoardTaskSnapshot } from "../../protocol/dist/board-model.js";
|
|
1
|
+
import { BoardDocument, BoardItem, BoardMediaSnapshot, BoardPatch, BoardSettings, BoardTaskSnapshot } from "../../protocol/dist/board-model.js";
|
|
2
2
|
import { BoardFrame } from "../../protocol/dist/board-layout.js";
|
|
3
3
|
import { BoardViewport, Rect, ScreenPoint, WorldPoint } from "../model/geometry.js";
|
|
4
4
|
import { BoardScene, BoardSceneItem } from "../model/scene.js";
|
|
5
|
+
import { BoardChapter } from "../model/authoring.js";
|
|
5
6
|
import { BoardFileSnapshotFacts } from "../model/file-snapshot.js";
|
|
6
7
|
import { ShapeKind } from "../model/shape-types.js";
|
|
8
|
+
import { BoardItemEntry, BoardMediaItemKind } from "../model/items/create.js";
|
|
7
9
|
import { BoardItemInput, BoardRegistry } from "../model/items/registry.js";
|
|
8
10
|
import "../model/index.js";
|
|
9
11
|
import { AlignMode, DistributeAxis } from "./align.js";
|
|
10
12
|
import { BoardFocusOptions } from "./camera.js";
|
|
11
13
|
import { BoardSelectionTransform, BoardTransformControl } from "./selection-transform.js";
|
|
12
|
-
import { BoardInteraction, BoardPointerEvent } from "./interaction.js";
|
|
14
|
+
import { BoardInteraction, BoardPointerEvent, BoardTransformEnd } from "./interaction.js";
|
|
13
15
|
import { BoardAppMetadata, BoardTaskSource } from "./creation.js";
|
|
14
16
|
import { BoardClipboardPayload } from "./clipboard.js";
|
|
15
17
|
import { BoardNaturalSize } from "./snapshots.js";
|
|
@@ -22,6 +24,7 @@ declare function createBoardEditor(options: BoardEditorOptions): {
|
|
|
22
24
|
registry: BoardRegistry;
|
|
23
25
|
readonly: boolean;
|
|
24
26
|
subscribe: (channels: BoardEditorChannel | readonly BoardEditorChannel[], listener: BoardEditorListener) => () => void;
|
|
27
|
+
readonly hasScripts: boolean;
|
|
25
28
|
readonly document: BoardDocument;
|
|
26
29
|
readonly settings: {
|
|
27
30
|
title?: string | undefined;
|
|
@@ -130,11 +133,14 @@ declare function createBoardEditor(options: BoardEditorOptions): {
|
|
|
130
133
|
setSettings: (settings: BoardSettings) => void;
|
|
131
134
|
previewSettings: (settings: BoardSettings) => void;
|
|
132
135
|
setPlayedItems: (items: ReadonlyMap<string, BoardItem>) => void;
|
|
136
|
+
setScriptItems: (items: ReadonlyMap<string, BoardItem>) => void;
|
|
137
|
+
animationItems: () => Map<string, BoardItem>;
|
|
138
|
+
commitPatch: (patch: BoardPatch) => Promise<void> | undefined;
|
|
133
139
|
consumeRecentlyAdded: () => string[];
|
|
134
|
-
itemAt: (point: WorldPoint, exclude?: ReadonlySet<string> | undefined) => BoardSceneItem | null;
|
|
140
|
+
itemAt: (point: WorldPoint, exclude?: ReadonlySet<string> | undefined, includeTemporary?: boolean | undefined) => BoardSceneItem | null;
|
|
135
141
|
itemById: (id: string) => BoardSceneItem | null;
|
|
136
142
|
labelItemAt: (point: WorldPoint) => BoardSceneItem | null;
|
|
137
|
-
idsInRect: (rect: Rect) => string[];
|
|
143
|
+
idsInRect: (rect: Rect, includeTemporary?: boolean | undefined) => string[];
|
|
138
144
|
setCamera: (viewport: BoardViewport) => void;
|
|
139
145
|
setCameraPolicy: (policy: BoardCameraPolicy) => void;
|
|
140
146
|
takeCameraControl: () => void;
|
|
@@ -162,10 +168,18 @@ declare function createBoardEditor(options: BoardEditorOptions): {
|
|
|
162
168
|
bringToFront: () => void;
|
|
163
169
|
sendToBack: () => void;
|
|
164
170
|
addItem: (type: string, input: BoardItemInput) => string | null;
|
|
171
|
+
addItems: (entries: BoardItemEntry[], { select, enter }?: {
|
|
172
|
+
select?: boolean;
|
|
173
|
+
enter?: boolean;
|
|
174
|
+
}) => void;
|
|
165
175
|
addApp: (app: BoardAppMetadata, at: WorldPoint) => string;
|
|
166
176
|
addFile: (path: string, at: WorldPoint, snapshot?: BoardMediaSnapshot & BoardFileSnapshotFacts) => string;
|
|
167
|
-
|
|
168
|
-
|
|
177
|
+
addMedia: (src: string, at: WorldPoint, options?: {
|
|
178
|
+
kind?: BoardMediaItemKind;
|
|
179
|
+
snapshot?: BoardMediaSnapshot;
|
|
180
|
+
}) => string;
|
|
181
|
+
addTask: (taskRunId: string, snapshot: BoardTaskSnapshot, at: WorldPoint, metadata?: Record<string, unknown>, aspect?: number) => string;
|
|
182
|
+
addTaskWithSources: (taskRunId: string, snapshot: BoardTaskSnapshot, at: WorldPoint, sources: BoardTaskSource[], metadata?: Record<string, unknown>, aspect?: number) => string | null;
|
|
169
183
|
addText: (text: string, at: WorldPoint) => void;
|
|
170
184
|
addShape: (at: WorldPoint, geometry?: ShapeKind) => void;
|
|
171
185
|
addFrame: (at: WorldPoint) => void;
|
|
@@ -190,7 +204,6 @@ declare function createBoardEditor(options: BoardEditorOptions): {
|
|
|
190
204
|
snapshot: BoardFileSnapshotFacts;
|
|
191
205
|
replace?: boolean;
|
|
192
206
|
}>) => void;
|
|
193
|
-
applyTaskSnapshots: (snapshots: ReadonlyMap<string, BoardTaskSnapshot>) => void;
|
|
194
207
|
setPlayhead: (next: BoardPlayhead | null) => void;
|
|
195
208
|
setRecording: (value: boolean) => void;
|
|
196
209
|
keyframeState: (property: string) => "animated" | "keyframe" | "none";
|
|
@@ -198,10 +211,12 @@ declare function createBoardEditor(options: BoardEditorOptions): {
|
|
|
198
211
|
removeKeyframe: (trackId: string, at: number) => void;
|
|
199
212
|
setKeyframeEase: (trackId: string, at: number, ease: string | null) => void;
|
|
200
213
|
createAnimation: (name: string, duration?: number) => string;
|
|
214
|
+
createSequence: (name: string, chapters: BoardChapter[]) => string | null;
|
|
201
215
|
pointerDown: (event: BoardPointerEvent) => void;
|
|
202
216
|
pointerMove: (event: BoardPointerEvent) => void;
|
|
203
217
|
pointerUp: (event: BoardPointerEvent) => void;
|
|
204
218
|
pointerLeave: () => void;
|
|
219
|
+
subscribeTransforms: (listener: (event: BoardTransformEnd) => void) => () => void;
|
|
205
220
|
cancelPointerInteraction: () => void;
|
|
206
221
|
destroy(): void;
|
|
207
222
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { clampBoardStrokeSize } from "../../protocol/dist/board-constants.js";
|
|
2
|
+
import { hasBoardScripts } from "../model/script-index.js";
|
|
2
3
|
import { normalizeViewport } from "../model/geometry.js";
|
|
3
|
-
import { isBoardColorId } from "../model/palette.js";
|
|
4
4
|
import { buildBoardScene } from "../model/scene.js";
|
|
5
|
+
import { isBoardColorId } from "../model/palette.js";
|
|
5
6
|
import { isShapeKind } from "../model/shape-types.js";
|
|
6
7
|
import { createBoardToolStyles } from "../model/tool-styles.js";
|
|
7
8
|
import { titleForBoardItem } from "../model/items/create.js";
|
|
@@ -145,6 +146,9 @@ function createBoardEditor(options) {
|
|
|
145
146
|
registry,
|
|
146
147
|
readonly: options.readonly === true,
|
|
147
148
|
subscribe: channels.subscribe,
|
|
149
|
+
get hasScripts() {
|
|
150
|
+
return read("document", () => hasBoardScripts(state.base));
|
|
151
|
+
},
|
|
148
152
|
get document() {
|
|
149
153
|
return read("document", () => state.base);
|
|
150
154
|
},
|
|
@@ -344,6 +348,9 @@ function createBoardEditor(options) {
|
|
|
344
348
|
setSettings: document.setSettings,
|
|
345
349
|
previewSettings: document.previewSettings,
|
|
346
350
|
setPlayedItems: document.setPlayedItems,
|
|
351
|
+
setScriptItems: document.setScriptItems,
|
|
352
|
+
animationItems: document.animationItems,
|
|
353
|
+
commitPatch: document.commitPatch,
|
|
347
354
|
consumeRecentlyAdded: document.consumeRecentlyAdded,
|
|
348
355
|
itemAt: tracked(["scene", "camera"], query.itemAt),
|
|
349
356
|
itemById: tracked(["scene"], query.itemById),
|
|
@@ -380,8 +387,10 @@ function createBoardEditor(options) {
|
|
|
380
387
|
bringToFront: selection.bringToFront,
|
|
381
388
|
sendToBack: selection.sendToBack,
|
|
382
389
|
addItem: creation.addItem,
|
|
390
|
+
addItems: creation.add,
|
|
383
391
|
addApp: creation.addApp,
|
|
384
392
|
addFile: creation.addFile,
|
|
393
|
+
addMedia: creation.addMedia,
|
|
385
394
|
addTask: creation.addTask,
|
|
386
395
|
addTaskWithSources: creation.addTaskWithSources,
|
|
387
396
|
addText: creation.addText,
|
|
@@ -400,7 +409,6 @@ function createBoardEditor(options) {
|
|
|
400
409
|
applyMediaFileChange: snapshots.applyMediaFileChange,
|
|
401
410
|
adoptMediaNaturalSizes: snapshots.adoptMediaNaturalSizes,
|
|
402
411
|
applyFileSnapshots: snapshots.applyFileSnapshots,
|
|
403
|
-
applyTaskSnapshots: snapshots.applyTaskSnapshots,
|
|
404
412
|
setPlayhead: animation.setPlayhead,
|
|
405
413
|
setRecording: animation.setRecording,
|
|
406
414
|
keyframeState: tracked([
|
|
@@ -413,10 +421,12 @@ function createBoardEditor(options) {
|
|
|
413
421
|
removeKeyframe: animation.removeKeyframe,
|
|
414
422
|
setKeyframeEase: animation.setKeyframeEase,
|
|
415
423
|
createAnimation: animation.createAnimation,
|
|
424
|
+
createSequence: animation.createSequence,
|
|
416
425
|
pointerDown: interaction.pointerDown,
|
|
417
426
|
pointerMove: interaction.pointerMove,
|
|
418
427
|
pointerUp: interaction.pointerUp,
|
|
419
428
|
pointerLeave: interaction.pointerLeave,
|
|
429
|
+
subscribeTransforms: interaction.subscribeTransforms,
|
|
420
430
|
cancelPointerInteraction: interaction.cancel,
|
|
421
431
|
destroy() {
|
|
422
432
|
stopViewState();
|
|
@@ -2,7 +2,7 @@ import { BOARD_CLIPBOARD_MIME } from "../../protocol/dist/board.js";
|
|
|
2
2
|
import { AlignMode, DistributeAxis, alignFrames, distributeFrames, framesBounds } from "./align.js";
|
|
3
3
|
import { BoardFocusOptions } from "./camera.js";
|
|
4
4
|
import { BoardSelectionTransform, BoardTransformControl, resizeCursorForHandle, resolveSelectionTransform, selectionTransformControlAt } from "./selection-transform.js";
|
|
5
|
-
import { BoardInteraction, BoardPointerEvent } from "./interaction.js";
|
|
5
|
+
import { BoardInteraction, BoardPointerEvent, BoardTransformEnd } from "./interaction.js";
|
|
6
6
|
import { BoardAppMetadata, BoardTaskSource } from "./creation.js";
|
|
7
7
|
import { BOARD_CLIPBOARD_VERSION, BoardClipboardPayload, DUPLICATE_OFFSET, MAX_CLIPBOARD_CHARS, MAX_CLIPBOARD_ITEMS, defaultPasteOffset, encodeClipboard, materializeClipboard, parseClipboard, remapItems } from "./clipboard.js";
|
|
8
8
|
import { BoardNaturalSize } from "./snapshots.js";
|
|
@@ -15,4 +15,4 @@ import { BoardEditPlayhead, diffBoardEdits, isEmptyBoardPatch, readPath, routeBo
|
|
|
15
15
|
import { BoardEditor, createBoardEditor } from "./editor.js";
|
|
16
16
|
import { SpatialEntry, SpatialIndex, createSpatialIndex } from "./spatial.js";
|
|
17
17
|
import { normalizeWheelDelta, wheelZoomFactor } from "./wheel.js";
|
|
18
|
-
export { AlignMode, BOARD_CLIPBOARD_MIME, BOARD_CLIPBOARD_VERSION, BOARD_HAND_TAP_SLOP, type BoardAppMetadata, type BoardCameraPolicy, BoardClipboardPayload, BoardEditPlayhead, type BoardEditor, type BoardEditorChannel, type BoardEditorListener, type BoardEditorOptions, type BoardEditorPreferences, type BoardFocusOptions, type BoardInteraction, type BoardNaturalSize, type BoardPlayhead, type BoardPointerEvent, BoardSelectionTransform, type BoardTaskSource, BoardToolId, BoardTransformControl, type BoardViewState, CONNECTION_PORT_HIT_RADIUS, CONNECTION_PORT_OFFSET, CONNECTION_PORT_RADIUS, CONNECTION_PORT_TOUCH_HIT_RADIUS, CONNECTION_SIDES, ConnectionPort, DUPLICATE_OFFSET, DistributeAxis, MAX_CLIPBOARD_CHARS, MAX_CLIPBOARD_ITEMS, SnapAxis, SnapGuide, SnapOptions, SnapResult, SpatialEntry, SpatialIndex, alignFrames, canTapSelectWithHand, computeSnap, connectionPortAt, connectionPorts, createBoardEditor, createSpatialIndex, defaultBoardTool, defaultPasteOffset, diffBoardEdits, distributeFrames, encodeClipboard, framesBounds, isContinuousBoardTool, isCreationBoardTool, isEmptyBoardPatch, isWithinHandTapSlop, materializeClipboard, normalizeWheelDelta, parseClipboard, portHitRadius, readPath, remapItems, resizeCursorForHandle, resolveSelectionTransform, routeBoardEdits, sameJson, selectionTransformControlAt, wheelZoomFactor, writePath };
|
|
18
|
+
export { AlignMode, BOARD_CLIPBOARD_MIME, BOARD_CLIPBOARD_VERSION, BOARD_HAND_TAP_SLOP, type BoardAppMetadata, type BoardCameraPolicy, BoardClipboardPayload, BoardEditPlayhead, type BoardEditor, type BoardEditorChannel, type BoardEditorListener, type BoardEditorOptions, type BoardEditorPreferences, type BoardFocusOptions, type BoardInteraction, type BoardNaturalSize, type BoardPlayhead, type BoardPointerEvent, BoardSelectionTransform, type BoardTaskSource, BoardToolId, BoardTransformControl, type BoardTransformEnd, type BoardViewState, CONNECTION_PORT_HIT_RADIUS, CONNECTION_PORT_OFFSET, CONNECTION_PORT_RADIUS, CONNECTION_PORT_TOUCH_HIT_RADIUS, CONNECTION_SIDES, ConnectionPort, DUPLICATE_OFFSET, DistributeAxis, MAX_CLIPBOARD_CHARS, MAX_CLIPBOARD_ITEMS, SnapAxis, SnapGuide, SnapOptions, SnapResult, SpatialEntry, SpatialIndex, alignFrames, canTapSelectWithHand, computeSnap, connectionPortAt, connectionPorts, createBoardEditor, createSpatialIndex, defaultBoardTool, defaultPasteOffset, diffBoardEdits, distributeFrames, encodeClipboard, framesBounds, isContinuousBoardTool, isCreationBoardTool, isEmptyBoardPatch, isWithinHandTapSlop, materializeClipboard, normalizeWheelDelta, parseClipboard, portHitRadius, readPath, remapItems, resizeCursorForHandle, resolveSelectionTransform, routeBoardEdits, sameJson, selectionTransformControlAt, wheelZoomFactor, writePath };
|