@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.
Files changed (155) hide show
  1. package/README.md +42 -7
  2. package/dist/board/editor/animation.d.ts +3 -0
  3. package/dist/board/editor/animation.js +16 -1
  4. package/dist/board/editor/clipboard.js +7 -0
  5. package/dist/board/editor/copy.js +23 -18
  6. package/dist/board/editor/creation.d.ts +7 -3
  7. package/dist/board/editor/creation.js +5 -4
  8. package/dist/board/editor/deletion.js +3 -3
  9. package/dist/board/editor/document.d.ts +8 -2
  10. package/dist/board/editor/document.js +54 -7
  11. package/dist/board/editor/editor.d.ts +22 -7
  12. package/dist/board/editor/editor.js +12 -2
  13. package/dist/board/editor/index.d.ts +2 -2
  14. package/dist/board/editor/interaction.d.ts +8 -2
  15. package/dist/board/editor/interaction.js +34 -1
  16. package/dist/board/editor/query.d.ts +5 -5
  17. package/dist/board/editor/query.js +14 -12
  18. package/dist/board/editor/selection.js +2 -1
  19. package/dist/board/editor/snapshots.d.ts +0 -2
  20. package/dist/board/editor/snapshots.js +4 -20
  21. package/dist/board/export/index.d.ts +25 -4
  22. package/dist/board/export/index.js +45 -12
  23. package/dist/board/export/node/index.d.ts +5 -4
  24. package/dist/board/export/node/index.js +16 -11
  25. package/dist/board/export/node/scripts.d.ts +16 -0
  26. package/dist/board/export/node/scripts.js +258 -0
  27. package/dist/board/export/scene.d.ts +2 -1
  28. package/dist/board/export/scene.js +24 -7
  29. package/dist/board/model/animation.d.ts +4 -1
  30. package/dist/board/model/animation.js +34 -7
  31. package/dist/board/model/authoring.d.ts +20 -0
  32. package/dist/board/model/authoring.js +185 -0
  33. package/dist/board/model/export-plan.js +1 -0
  34. package/dist/board/model/file-preview.js +1 -1
  35. package/dist/board/model/file-snapshot.js +3 -2
  36. package/dist/board/model/image-key.js +7 -3
  37. package/dist/board/model/index.d.ts +15 -7
  38. package/dist/board/model/index.js +16 -9
  39. package/dist/board/model/items/builtin.js +2 -2
  40. package/dist/board/model/items/create.d.ts +19 -4
  41. package/dist/board/model/items/create.js +130 -9
  42. package/dist/board/model/items/index.d.ts +2 -2
  43. package/dist/board/model/items/index.js +2 -2
  44. package/dist/board/model/media-playback.d.ts +2 -1
  45. package/dist/board/model/media-playback.js +15 -5
  46. package/dist/board/model/media.js +7 -1
  47. package/dist/board/model/overlay-placement.d.ts +25 -0
  48. package/dist/board/model/overlay-placement.js +35 -0
  49. package/dist/board/model/replay.d.ts +1 -1
  50. package/dist/board/model/replay.js +1 -0
  51. package/dist/board/model/sampling.d.ts +19 -0
  52. package/dist/board/model/sampling.js +96 -0
  53. package/dist/board/model/script-example.d.ts +4 -0
  54. package/dist/board/model/script-example.js +21 -0
  55. package/dist/board/model/script-hit.d.ts +27 -0
  56. package/dist/board/model/script-hit.js +109 -0
  57. package/dist/board/model/script-index.d.ts +7 -0
  58. package/dist/board/model/script-index.js +15 -0
  59. package/dist/board/model/script-observers.d.ts +18 -0
  60. package/dist/board/model/script-observers.js +92 -0
  61. package/dist/board/model/script-scene.d.ts +24 -0
  62. package/dist/board/model/script-scene.js +294 -0
  63. package/dist/board/model/script.d.ts +149 -0
  64. package/dist/board/model/script.js +1 -0
  65. package/dist/board/render/board-background.js +5 -4
  66. package/dist/board/render/css-color.d.ts +6 -1
  67. package/dist/board/render/css-color.js +34 -20
  68. package/dist/board/render/diagnostics.d.ts +20 -0
  69. package/dist/board/render/diagnostics.js +117 -0
  70. package/dist/board/render/index.d.ts +9 -6
  71. package/dist/board/render/index.js +10 -7
  72. package/dist/board/render/media-interaction.js +1 -1
  73. package/dist/board/render/palette.d.ts +2 -1
  74. package/dist/board/render/palette.js +6 -2
  75. package/dist/board/render/renderers/arrow-card-renderer.js +3 -2
  76. package/dist/board/render/renderers/audio-card-renderer.js +2 -1
  77. package/dist/board/render/renderers/board-renderer-registry.d.ts +25 -5
  78. package/dist/board/render/renderers/board-renderer-registry.js +11 -4
  79. package/dist/board/render/renderers/custom-card-renderer.d.ts +5 -0
  80. package/dist/board/render/renderers/{sketch-card-renderer.js → custom-card-renderer.js} +18 -16
  81. package/dist/board/render/renderers/draw-card-renderer.js +3 -2
  82. package/dist/board/render/renderers/effect-card-renderer.js +22 -5
  83. package/dist/board/render/renderers/frame-card-renderer.js +30 -14
  84. package/dist/board/render/renderers/image-card-renderer.js +43 -4
  85. package/dist/board/render/renderers/shape-card-renderer.js +10 -27
  86. package/dist/board/render/renderers/task-card-renderer.d.ts +2 -1
  87. package/dist/board/render/renderers/task-card-renderer.js +220 -71
  88. package/dist/board/render/renderers/text-card-renderer.js +5 -3
  89. package/dist/board/render/renderers/unknown-card-renderer.js +1 -0
  90. package/dist/board/render/renderers/video-card-renderer.js +2 -1
  91. package/dist/board/render/sampling.d.ts +22 -0
  92. package/dist/board/render/sampling.js +21 -0
  93. package/dist/board/render/script-export.d.ts +11 -0
  94. package/dist/board/render/script-export.js +86 -0
  95. package/dist/board/render/script-host.d.ts +31 -0
  96. package/dist/board/render/script-host.js +446 -0
  97. package/dist/board/render/script-modules.d.ts +2 -0
  98. package/dist/board/render/script-modules.js +2 -0
  99. package/dist/board/render/script-runtime.d.ts +29 -0
  100. package/dist/board/render/script-runtime.js +223 -0
  101. package/dist/board/render/script-sandbox.d.ts +4 -0
  102. package/dist/board/render/script-sandbox.js +173 -0
  103. package/dist/board/render/script-texture.d.ts +11 -0
  104. package/dist/board/render/script-texture.js +33 -0
  105. package/dist/board/render/stroke.d.ts +2 -1
  106. package/dist/board/render/stroke.js +22 -1
  107. package/dist/board/render/text-measurement.js +1 -1
  108. package/dist/board/stage/assets.js +7 -2
  109. package/dist/board/stage/maintenance.d.ts +5 -0
  110. package/dist/board/stage/maintenance.js +11 -0
  111. package/dist/board/stage/scene.d.ts +2 -0
  112. package/dist/board/stage/scene.js +21 -2
  113. package/dist/board/stage/script-pointer.d.ts +20 -0
  114. package/dist/board/stage/script-pointer.js +41 -0
  115. package/dist/board/stage/stage.d.ts +21 -3
  116. package/dist/board/stage/stage.js +350 -47
  117. package/dist/board/stage/texture-pool.js +2 -3
  118. package/dist/chunks/environment.d.ts +305 -27
  119. package/dist/chunks/environment.js +12 -4
  120. package/dist/chunks/host-bridge.d.ts +2 -2
  121. package/dist/chunks/http.d.ts +90 -7
  122. package/dist/chunks/http.js +157 -64
  123. package/dist/chunks/transport.js +4 -2
  124. package/dist/chunks/websocket.d.ts +9 -1
  125. package/dist/chunks/websocket.js +16 -2
  126. package/dist/host-bridge.js +2 -1
  127. package/dist/http.d.ts +3 -3
  128. package/dist/index.d.ts +182 -4
  129. package/dist/index.js +1559 -299
  130. package/dist/protocol/dist/board-assets.d.ts +1 -0
  131. package/dist/protocol/dist/board-constants.js +2 -2
  132. package/dist/protocol/dist/board-model.d.ts +236 -11
  133. package/dist/protocol/dist/board-model.js +46 -17
  134. package/dist/protocol/dist/board-patch.js +2 -1
  135. package/dist/protocol/dist/board-schema.d.ts +4 -2
  136. package/dist/protocol/dist/board-schema.js +18 -4
  137. package/dist/protocol/dist/board-script-modules.d.ts +25 -0
  138. package/dist/protocol/dist/board-script-modules.js +127 -0
  139. package/dist/protocol/dist/board-task.d.ts +22 -0
  140. package/dist/{board/model/task.js → protocol/dist/board-task.js} +34 -7
  141. package/dist/protocol/dist/display/index.d.ts +1 -0
  142. package/dist/protocol/dist/generation/blocks.d.ts +8 -0
  143. package/dist/{generation-blocks.js → protocol/dist/generation/blocks.js} +14 -15
  144. package/dist/protocol/dist/index.d.ts +7 -2
  145. package/dist/protocol/dist/realtime/types.d.ts +1 -0
  146. package/dist/protocol/dist/rtc/index.d.ts +1 -0
  147. package/dist/protocol/dist/task/index.d.ts +4 -0
  148. package/package.json +2 -1
  149. package/dist/board/export/node/sketch.d.ts +0 -19
  150. package/dist/board/export/node/sketch.js +0 -146
  151. package/dist/board/model/task.d.ts +0 -11
  152. package/dist/board/render/renderers/sketch-card-renderer.d.ts +0 -5
  153. package/dist/board/render/sketch-host.d.ts +0 -14
  154. package/dist/board/render/sketch-host.js +0 -216
  155. package/dist/types.d.ts +0 -36
@@ -3,7 +3,7 @@ import { RequestSource } from "../../protocol/dist/provenance.js";
3
3
  import { BoardHistoryPage } from "../../protocol/dist/board.js";
4
4
  import "../../protocol/dist/index.js";
5
5
  //#region src/board/model/replay.d.ts
6
- type BoardReplayActorKind = "human" | "cli" | "agent";
6
+ type BoardReplayActorKind = "human" | "cli" | "agent" | "task";
7
7
  type BoardReplayEntry = {
8
8
  version: number;
9
9
  actorId: string;
@@ -3,6 +3,7 @@ import { applyBoardDelta } from "../../protocol/dist/board-patch.js";
3
3
  function boardReplayActorKind(source) {
4
4
  if (!source) return "human";
5
5
  if (source.toolCallId) return "agent";
6
+ if (source.via === "task") return "task";
6
7
  return source.via === "cli" ? "cli" : "human";
7
8
  }
8
9
  function entryOf(transaction) {
@@ -0,0 +1,19 @@
1
+ import { BoardDocument } from "../../protocol/dist/board-model.js";
2
+ import { BoardFrame } from "../../protocol/dist/board-layout.js";
3
+ import "../../protocol/dist/index.js";
4
+ import { BoardViewport, Size } from "./geometry.js";
5
+ import { BoardScene } from "./scene.js";
6
+ import { BoardCameraOverride, BoardEvaluateOptions, BoardEvaluation } from "./animation.js";
7
+ //#region src/board/model/sampling.d.ts
8
+ declare function createBoardAnimationSampler(document: BoardDocument, animation: string | null, options?: BoardEvaluateOptions): {
9
+ frameAt(id: string, time: number): BoardFrame | undefined;
10
+ at(time: number): {
11
+ document: BoardDocument;
12
+ evaluation: BoardEvaluation;
13
+ scene: BoardScene;
14
+ };
15
+ };
16
+ type BoardAnimationSampler = ReturnType<typeof createBoardAnimationSampler>;
17
+ declare function resolveBoardAnimationCamera(override: BoardCameraOverride, bounds: (id: string) => BoardFrame | undefined, surface: Size, time: number, base?: BoardViewport): BoardViewport;
18
+ //#endregion
19
+ export { BoardAnimationSampler, createBoardAnimationSampler, resolveBoardAnimationCamera };
@@ -0,0 +1,96 @@
1
+ import { arrowBindings } from "../../protocol/dist/board-layout.js";
2
+ import { cameraForFocus, cameraForState } from "./geometry.js";
3
+ import { applyBoardEvaluation, boardAnimationTime, compileBoardAnimations, evaluateBoardAnimations } from "./animation.js";
4
+ import { buildBoardScene } from "./scene.js";
5
+ //#region src/board/model/sampling.ts
6
+ function createBoardAnimationSampler(document, animation, options = {}) {
7
+ const selected = animation ? document.animations[animation] : void 0;
8
+ if (animation && !selected) throw new Error(`Animation ${animation} does not exist.`);
9
+ const compiled = compileBoardAnimations(document);
10
+ const cache = /* @__PURE__ */ new Map();
11
+ const geometry = /* @__PURE__ */ new Map();
12
+ function sample(time) {
13
+ const times = /* @__PURE__ */ new Map();
14
+ for (const [id, entry] of compiled.animations) if (entry.header.play === "always") times.set(id, boardAnimationTime(entry.header, time) ?? 0);
15
+ if (animation && selected) times.set(animation, Math.min(time, selected.duration));
16
+ const evaluation = evaluateBoardAnimations(compiled, times, options);
17
+ return {
18
+ document: applyBoardEvaluation(document, evaluation),
19
+ evaluation
20
+ };
21
+ }
22
+ function stateAt(time) {
23
+ if (!Number.isFinite(time) || time < 0) throw new Error("Animation time must be finite and non-negative.");
24
+ let value = cache.get(time);
25
+ if (!value) {
26
+ value = sample(time);
27
+ const oldest = cache.keys().next().value;
28
+ if (cache.size >= 64 && oldest !== void 0) cache.delete(oldest);
29
+ cache.set(time, value);
30
+ }
31
+ return value;
32
+ }
33
+ let current;
34
+ return {
35
+ frameAt(id, time) {
36
+ const key = `${time}:${id}`;
37
+ if (geometry.has(key)) return geometry.get(key);
38
+ const sampled = stateAt(time).document;
39
+ const items = {};
40
+ const pending = [id];
41
+ while (pending.length) {
42
+ const next = pending.pop();
43
+ if (!next || items[next]) continue;
44
+ const item = sampled.items[next];
45
+ if (!item) continue;
46
+ items[next] = item;
47
+ if (item.parent) pending.push(item.parent);
48
+ pending.push(...arrowBindings(item));
49
+ }
50
+ const frame = buildBoardScene({
51
+ ...sampled,
52
+ items
53
+ }).get(id)?.frame;
54
+ if (geometry.size >= 2048) geometry.clear();
55
+ geometry.set(key, frame);
56
+ return frame;
57
+ },
58
+ at(time) {
59
+ if (current?.time === time) return current.value;
60
+ const sampled = stateAt(time);
61
+ const value = {
62
+ ...sampled,
63
+ scene: buildBoardScene(sampled.document)
64
+ };
65
+ current = {
66
+ time,
67
+ value
68
+ };
69
+ return value;
70
+ }
71
+ };
72
+ }
73
+ function resolveBoardAnimationCamera(override, bounds, surface, time, base = {
74
+ x: 0,
75
+ y: 0,
76
+ zoom: 1
77
+ }) {
78
+ let camera = override.focus === void 0 ? base : cameraForFocus(override.focus, bounds, surface, { padding: 48 }) ?? base;
79
+ if (override.zoom !== void 0) camera = {
80
+ ...camera,
81
+ zoom: override.zoom
82
+ };
83
+ if (override.center) camera = cameraForState({
84
+ centerX: override.center.x,
85
+ centerY: override.center.y,
86
+ zoom: camera.zoom
87
+ }, surface);
88
+ if (override.shake) camera = {
89
+ ...camera,
90
+ x: camera.x + Math.sin(time / 1e3 * 91.3) * override.shake,
91
+ y: camera.y + Math.cos(time / 1e3 * 77.9) * override.shake
92
+ };
93
+ return camera;
94
+ }
95
+ //#endregion
96
+ export { createBoardAnimationSampler, resolveBoardAnimationCamera };
@@ -0,0 +1,4 @@
1
+ //#region src/board/model/script-example.d.ts
2
+ declare const BOARD_SCRIPT_DRAWING_EXAMPLE = "export const animated = true;\n\nexport const parameters = {\n amplitude: { type: \"number\", label: \"Amplitude\", default: 40, min: 0, max: 120 }\n};\n\nexport function draw(ctx, { t, width, height, params }) {\n ctx.strokeStyle = \"#e67845\";\n ctx.lineWidth = 3;\n ctx.beginPath();\n for (let x = 0; x <= width; x += 2) {\n const y = height / 2 + Math.sin(x / 40 - t / 800) * params.amplitude;\n if (x === 0) ctx.moveTo(x, y);\n else ctx.lineTo(x, y);\n }\n ctx.stroke();\n}\n";
3
+ //#endregion
4
+ export { BOARD_SCRIPT_DRAWING_EXAMPLE };
@@ -0,0 +1,21 @@
1
+ //#region src/board/model/script-example.ts
2
+ const BOARD_SCRIPT_DRAWING_EXAMPLE = `export const animated = true;
3
+
4
+ export const parameters = {
5
+ amplitude: { type: "number", label: "Amplitude", default: 40, min: 0, max: 120 }
6
+ };
7
+
8
+ export function draw(ctx, { t, width, height, params }) {
9
+ ctx.strokeStyle = "#e67845";
10
+ ctx.lineWidth = 3;
11
+ ctx.beginPath();
12
+ for (let x = 0; x <= width; x += 2) {
13
+ const y = height / 2 + Math.sin(x / 40 - t / 800) * params.amplitude;
14
+ if (x === 0) ctx.moveTo(x, y);
15
+ else ctx.lineTo(x, y);
16
+ }
17
+ ctx.stroke();
18
+ }
19
+ `;
20
+ //#endregion
21
+ export { BOARD_SCRIPT_DRAWING_EXAMPLE };
@@ -0,0 +1,27 @@
1
+ import { BoardViewport, WorldPoint } from "./geometry.js";
2
+ import { BoardScriptHit, BoardScriptOutput } from "./script.js";
3
+ import { BoardScene, BoardSceneItem } from "./scene.js";
4
+ //#region src/board/model/script-hit.d.ts
5
+ declare function resolveBoardScriptHit(scene: BoardScene, owner: string, hit: BoardScriptHit): {
6
+ id: string;
7
+ item: BoardSceneItem;
8
+ rect: {
9
+ x: number;
10
+ y: number;
11
+ width: number;
12
+ height: number;
13
+ } & {
14
+ label?: string;
15
+ cursor?: string;
16
+ };
17
+ } | null;
18
+ declare function boardScriptHitVisible(scene: BoardScene, hit: NonNullable<ReturnType<typeof resolveBoardScriptHit>>, camera: BoardViewport, surface: {
19
+ width: number;
20
+ height: number;
21
+ }): boolean;
22
+ declare function boardScriptTarget(scene: BoardScene, candidates: readonly string[], point: WorldPoint, outputs: ReadonlyMap<string, BoardScriptOutput>, hitTest: (item: BoardSceneItem, point: WorldPoint) => boolean): {
23
+ owner: string;
24
+ target: string;
25
+ } | null;
26
+ //#endregion
27
+ export { boardScriptHitVisible, boardScriptTarget, resolveBoardScriptHit };
@@ -0,0 +1,109 @@
1
+ import { applyMatrix, invertMatrix } from "../../protocol/dist/board-layout.js";
2
+ import { frameContainsPoint } from "./geometry.js";
3
+ import { scriptTemporaryPrefix } from "./script-scene.js";
4
+ //#region src/board/model/script-hit.ts
5
+ function resolveBoardScriptHit(scene, owner, hit) {
6
+ const id = "item" in hit ? `${scriptTemporaryPrefix(owner)}${hit.item}` : owner;
7
+ const item = scene.get(id);
8
+ if (!item || scene.opacity(id) <= 0) return null;
9
+ const box = scene.layout.box(id);
10
+ return {
11
+ id,
12
+ item,
13
+ rect: "x" in hit ? hit : {
14
+ x: 0,
15
+ y: 0,
16
+ width: box.width,
17
+ height: box.height
18
+ }
19
+ };
20
+ }
21
+ function boardScriptHitVisible(scene, hit, camera, surface) {
22
+ const { x, y, width, height } = hit.rect;
23
+ if (width <= 0 || height <= 0) return false;
24
+ const matrix = scene.layout.matrix(hit.id);
25
+ const corners = [
26
+ applyMatrix(matrix, {
27
+ x,
28
+ y
29
+ }),
30
+ applyMatrix(matrix, {
31
+ x: x + width,
32
+ y
33
+ }),
34
+ applyMatrix(matrix, {
35
+ x,
36
+ y: y + height
37
+ }),
38
+ applyMatrix(matrix, {
39
+ x: x + width,
40
+ y: y + height
41
+ })
42
+ ];
43
+ const xs = corners.map((point) => point.x * camera.zoom + camera.x);
44
+ const ys = corners.map((point) => point.y * camera.zoom + camera.y);
45
+ return Math.max(...xs) > 0 && Math.min(...xs) < surface.width && Math.max(...ys) > 0 && Math.min(...ys) < surface.height;
46
+ }
47
+ const bindings = /* @__PURE__ */ new WeakMap();
48
+ function bindingsFor(owner, output) {
49
+ const cached = bindings.get(output);
50
+ if (cached?.owner === owner) return cached.byItem;
51
+ const byItem = /* @__PURE__ */ new Map();
52
+ for (const [target, hit] of Object.entries(output.hits)) {
53
+ const id = "item" in hit ? `${scriptTemporaryPrefix(owner)}${hit.item}` : owner;
54
+ const list = byItem.get(id) ?? [];
55
+ list.push({
56
+ owner,
57
+ target,
58
+ hit
59
+ });
60
+ byItem.set(id, list);
61
+ }
62
+ bindings.set(output, {
63
+ owner,
64
+ byItem
65
+ });
66
+ return byItem;
67
+ }
68
+ function boardScriptTarget(scene, candidates, point, outputs, hitTest) {
69
+ const declared = [...outputs].map(([owner, output]) => bindingsFor(owner, output));
70
+ const prefixes = [...outputs.keys()].map(scriptTemporaryPrefix);
71
+ for (const id of [...candidates].sort((a, b) => scene.indexOf(b) - scene.indexOf(a))) {
72
+ const item = scene.get(id);
73
+ if (!item || scene.opacity(id) <= 0) continue;
74
+ let parent = item.parent;
75
+ let clipped = false;
76
+ for (let depth = 0; parent && depth < 64; depth++) {
77
+ const ancestor = scene.get(parent);
78
+ if (!ancestor) break;
79
+ if (ancestor.type === "frame" && ancestor.props.clip && !frameContainsPoint(ancestor.frame, point)) {
80
+ clipped = true;
81
+ break;
82
+ }
83
+ parent = ancestor.parent;
84
+ }
85
+ if (clipped) continue;
86
+ for (const byItem of declared) {
87
+ const hits = byItem.get(id);
88
+ if (!hits) continue;
89
+ const local = applyMatrix(invertMatrix(scene.layout.matrix(id)), point);
90
+ for (let i = hits.length - 1; i >= 0; i--) {
91
+ const binding = hits[i];
92
+ if (!binding) continue;
93
+ const resolved = resolveBoardScriptHit(scene, binding.owner, binding.hit);
94
+ if (!resolved) continue;
95
+ const r = resolved.rect;
96
+ if (local.x >= r.x && local.y >= r.y && local.x <= r.x + r.width && local.y <= r.y + r.height && ("x" in binding.hit || hitTest(item, point))) return {
97
+ owner: binding.owner,
98
+ target: binding.target
99
+ };
100
+ }
101
+ }
102
+ if (prefixes.some((prefix) => id.startsWith(prefix))) continue;
103
+ if (item.type === "frame" && item.props.decoration === "none") continue;
104
+ if (hitTest(item, point)) return null;
105
+ }
106
+ return null;
107
+ }
108
+ //#endregion
109
+ export { boardScriptHitVisible, boardScriptTarget, resolveBoardScriptHit };
@@ -0,0 +1,7 @@
1
+ import { BoardDocument, BoardItem } from "../../protocol/dist/board-model.js";
2
+ import "../../protocol/dist/index.js";
3
+ //#region src/board/model/script-index.d.ts
4
+ declare function boardScriptItems(document: Pick<BoardDocument, "items">): readonly (readonly [string, BoardItem])[];
5
+ declare function hasBoardScripts(document: Pick<BoardDocument, "items">): boolean;
6
+ //#endregion
7
+ export { boardScriptItems, hasBoardScripts };
@@ -0,0 +1,15 @@
1
+ //#region src/board/model/script-index.ts
2
+ const scriptsByItems = /* @__PURE__ */ new WeakMap();
3
+ function boardScriptItems(document) {
4
+ let scripts = scriptsByItems.get(document.items);
5
+ if (!scripts) {
6
+ scripts = Object.entries(document.items).filter(([, item]) => item.script?.enabled);
7
+ scriptsByItems.set(document.items, scripts);
8
+ }
9
+ return scripts;
10
+ }
11
+ function hasBoardScripts(document) {
12
+ return boardScriptItems(document).length > 0;
13
+ }
14
+ //#endregion
15
+ export { boardScriptItems, hasBoardScripts };
@@ -0,0 +1,18 @@
1
+ import { BoardDocument } from "../../protocol/dist/board-model.js";
2
+ import "../../protocol/dist/index.js";
3
+ import { BoardScriptEvent, BoardScriptOutput, BoardScriptView } from "./script.js";
4
+ //#region src/board/model/script-observers.d.ts
5
+ declare function createBoardScriptObservers(send: (owner: string, event: BoardScriptEvent) => void): {
6
+ readonly size: number;
7
+ readonly transforms: boolean;
8
+ update(owner: string, output: BoardScriptOutput | null): void;
9
+ sync(document: BoardDocument, selection: readonly string[], readView: () => BoardScriptView): void;
10
+ transform(document: BoardDocument, event: {
11
+ ids: readonly string[];
12
+ operation: string;
13
+ cancelled: boolean;
14
+ }): void;
15
+ clear(): void;
16
+ };
17
+ //#endregion
18
+ export { createBoardScriptObservers };
@@ -0,0 +1,92 @@
1
+ import { boardScriptScope } from "./script-scene.js";
2
+ //#region src/board/model/script-observers.ts
3
+ const EVENTS = [
4
+ "viewchange",
5
+ "selectionchange",
6
+ "transformend"
7
+ ];
8
+ function createBoardScriptObservers(send) {
9
+ const subscribers = /* @__PURE__ */ new Map();
10
+ function scope(owner, entry, document) {
11
+ if (entry.document !== document) {
12
+ entry.scope = boardScriptScope(document, owner);
13
+ entry.document = document;
14
+ entry.selection = void 0;
15
+ }
16
+ return entry.scope;
17
+ }
18
+ return {
19
+ get size() {
20
+ return subscribers.size;
21
+ },
22
+ get transforms() {
23
+ return [...subscribers.values()].some((entry) => entry.listens.has("transformend"));
24
+ },
25
+ update(owner, output) {
26
+ const listens = new Set(EVENTS.filter((type) => output?.listens.includes(type)));
27
+ if (!listens.size) {
28
+ subscribers.delete(owner);
29
+ return;
30
+ }
31
+ const entry = subscribers.get(owner) ?? {
32
+ listens,
33
+ scope: /* @__PURE__ */ new Set()
34
+ };
35
+ if (!listens.has("viewchange")) entry.view = void 0;
36
+ if (!listens.has("selectionchange")) {
37
+ entry.selection = void 0;
38
+ entry.selected = void 0;
39
+ }
40
+ entry.listens = listens;
41
+ subscribers.set(owner, entry);
42
+ },
43
+ sync(document, selection, readView) {
44
+ let view;
45
+ let key;
46
+ for (const [owner, entry] of subscribers) {
47
+ if (entry.listens.has("viewchange")) {
48
+ view ??= readView();
49
+ key ??= JSON.stringify(view);
50
+ if (entry.view !== key) {
51
+ entry.view = key;
52
+ send(owner, {
53
+ type: "viewchange",
54
+ data: view
55
+ });
56
+ }
57
+ }
58
+ if (entry.listens.has("selectionchange")) {
59
+ const allowed = scope(owner, entry, document);
60
+ if (entry.selection === selection) continue;
61
+ entry.selection = selection;
62
+ const ids = selection.filter((id) => allowed.has(id));
63
+ if (entry.selected && ids.length === entry.selected.length && ids.every((id, i) => id === entry.selected?.[i])) continue;
64
+ entry.selected = ids;
65
+ send(owner, {
66
+ type: "selectionchange",
67
+ data: { ids }
68
+ });
69
+ }
70
+ }
71
+ },
72
+ transform(document, event) {
73
+ for (const [owner, entry] of subscribers) {
74
+ if (!entry.listens.has("transformend")) continue;
75
+ const allowed = scope(owner, entry, document);
76
+ const ids = event.ids.filter((id) => allowed.has(id));
77
+ if (ids.length) send(owner, {
78
+ type: "transformend",
79
+ data: {
80
+ ...event,
81
+ ids
82
+ }
83
+ });
84
+ }
85
+ },
86
+ clear() {
87
+ subscribers.clear();
88
+ }
89
+ };
90
+ }
91
+ //#endregion
92
+ export { createBoardScriptObservers };
@@ -0,0 +1,24 @@
1
+ import { BoardDocument, BoardItem, BoardPatch } from "../../protocol/dist/board-model.js";
2
+ import { BoardScriptOutput } from "./script.js";
3
+ import { BoardScene } from "./scene.js";
4
+ //#region src/board/model/script-scene.d.ts
5
+ declare function boardScriptScope(document: Pick<BoardDocument, "items">, id: string): Set<string>;
6
+ declare function validateBoardScriptOutput(output: BoardScriptOutput, scope: ReadonlySet<string>): void;
7
+ declare function validateBoardScriptCommit(document: BoardDocument, id: string, patch: BoardPatch): void;
8
+ declare function scriptTemporaryPrefix(owner: string): string;
9
+ type PreparedOutput = {
10
+ document: BoardDocument;
11
+ owner: string;
12
+ rootId: string;
13
+ items: Map<string, BoardItem>;
14
+ presented: Map<string, {
15
+ base: BoardItem;
16
+ item: BoardItem;
17
+ }>;
18
+ };
19
+ declare function prepareBoardScriptOutput(document: BoardDocument, owner: string, output: BoardScriptOutput): PreparedOutput;
20
+ declare function composeBoardScriptItems(document: BoardDocument, scene: BoardScene, outputs: ReadonlyMap<string, BoardScriptOutput>, incoming?: ReadonlyMap<string, BoardItem>, screen?: {
21
+ zoom: number;
22
+ }, onError?: (owner: string, error: unknown) => void, gestureLayout?: BoardScene["layout"]): Map<string, BoardItem>;
23
+ //#endregion
24
+ export { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, scriptTemporaryPrefix, validateBoardScriptCommit, validateBoardScriptOutput };