@neta-art/cohub 11.5.1 → 12.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/dist/board/editor/animation.js +2 -1
- package/dist/board/editor/creation.js +1 -1
- package/dist/board/editor/document-edits.d.ts +1 -1
- package/dist/board/editor/document-edits.js +1 -19
- package/dist/board/editor/document.js +2 -1
- package/dist/board/editor/index.d.ts +2 -1
- package/dist/board/editor/index.js +2 -1
- package/dist/board/editor/snapshots.js +11 -13
- package/dist/board/export/index.js +1 -1
- package/dist/board/export/scene.js +1 -1
- package/dist/board/model/client-geometry.d.ts +22 -0
- package/dist/board/model/client-geometry.js +94 -0
- package/dist/board/model/document-share.d.ts +5 -0
- package/dist/board/model/document-share.js +27 -0
- package/dist/board/model/index.d.ts +5 -4
- package/dist/board/model/index.js +4 -3
- package/dist/board/model/items/create.d.ts +5 -1
- package/dist/board/model/items/create.js +29 -58
- package/dist/board/model/items/index.d.ts +2 -2
- package/dist/board/model/items/index.js +2 -2
- package/dist/board/model/items/registry.js +2 -5
- package/dist/board/model/json.d.ts +4 -0
- package/dist/board/model/json.js +22 -0
- package/dist/board/model/media-playback.d.ts +6 -3
- package/dist/board/player/index.d.ts +6 -2
- package/dist/board/player/index.js +33 -15
- package/dist/board/render/index.d.ts +2 -2
- package/dist/board/render/index.js +6 -6
- package/dist/board/render/renderers/arrow-card-renderer.js +5 -1
- package/dist/board/render/renderers/audio-card-renderer.js +4 -1
- package/dist/board/render/renderers/board-renderer-registry.d.ts +4 -2
- package/dist/board/render/renderers/custom-card-renderer.js +5 -2
- package/dist/board/render/renderers/file-card-renderer.js +4 -1
- package/dist/board/render/renderers/frame-card-renderer.js +5 -1
- package/dist/board/render/renderers/image-card-renderer.js +13 -49
- package/dist/board/render/renderers/model-card-renderer.js +4 -1
- package/dist/board/render/renderers/shape-card-renderer.js +5 -1
- package/dist/board/render/renderers/task-card-renderer.js +6 -3
- package/dist/board/render/renderers/text-card-renderer.js +6 -2
- package/dist/board/render/renderers/unknown-card-renderer.js +4 -0
- package/dist/board/render/renderers/video-card-renderer.js +19 -18
- package/dist/board/render/script-host.d.ts +2 -0
- package/dist/board/render/script-host.js +44 -9
- package/dist/board/render/script-resolution.d.ts +4 -0
- package/dist/board/render/script-resolution.js +18 -0
- package/dist/board/render/surface.d.ts +9 -2
- package/dist/board/render/surface.js +15 -1
- package/dist/board/replica/index.js +4 -1
- package/dist/board/stage/assets.d.ts +12 -8
- package/dist/board/stage/assets.js +173 -88
- package/dist/board/stage/index.d.ts +3 -3
- package/dist/board/stage/index.js +3 -3
- package/dist/board/stage/lru.d.ts +3 -2
- package/dist/board/stage/lru.js +8 -4
- package/dist/board/stage/pointer.d.ts +1 -1
- package/dist/board/stage/pointer.js +4 -5
- package/dist/board/stage/scene.d.ts +3 -0
- package/dist/board/stage/scene.js +44 -8
- package/dist/board/stage/stage.d.ts +1 -0
- package/dist/board/stage/stage.js +123 -56
- package/dist/board/stage/views.d.ts +7 -2
- package/dist/board/stage/views.js +50 -21
- package/dist/chunks/environment.d.ts +16 -2
- package/dist/index.js +65 -22
- package/dist/protocol/dist/board-constants.js +56 -1
- package/dist/protocol/dist/board-layout.d.ts +8 -1
- package/dist/protocol/dist/board-layout.js +16 -4
- package/dist/protocol/dist/board-model.js +13 -19
- package/dist/protocol/dist/board-schema.d.ts +52 -0
- package/dist/protocol/dist/board-schema.js +8 -0
- package/dist/protocol/dist/core/media.js +1 -0
- package/dist/protocol/dist/index.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { applyMatrix, invertMatrix } from "../../protocol/dist/board-layout.js";
|
|
2
2
|
import { featuredTaskArtifact } from "../../protocol/dist/board-task.js";
|
|
3
|
-
import {
|
|
3
|
+
import { pointToWorld, stableCullRect, visibleWorldRect, worldPoint } from "../model/geometry.js";
|
|
4
4
|
import { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, validateBoardScriptCommit } from "../model/script-scene.js";
|
|
5
5
|
import { boardScriptTarget } from "../model/script-hit.js";
|
|
6
6
|
import { createBoardAnimationSampler, resolveBoardAnimationCamera } from "../model/sampling.js";
|
|
7
7
|
import { resolveSceneArrow } from "../model/arrow-geometry.js";
|
|
8
8
|
import { buildFallbackShapeColors, pickBoardColor, resolveItemColor } from "../model/palette.js";
|
|
9
|
+
import { elementClientToLocal } from "../model/client-geometry.js";
|
|
9
10
|
import { isCreationBoardTool } from "../editor/tool.js";
|
|
10
11
|
import { resizeCursorForHandle } from "../editor/selection-transform.js";
|
|
12
|
+
import { createBoardPlayer } from "../player/index.js";
|
|
13
|
+
import { createBoardScriptObservers } from "../model/script-observers.js";
|
|
11
14
|
import { parseBoardCssColor } from "../render/css-color.js";
|
|
12
|
-
import { defaultBoardPalette, itemAlpha } from "../render/palette.js";
|
|
13
15
|
import { createBoardBackground, updateBoardBackground } from "../render/board-background.js";
|
|
14
|
-
import { getBoardResolution
|
|
16
|
+
import { getBoardResolution } from "../render/text-resolution.js";
|
|
17
|
+
import { defaultBoardPalette, itemAlpha } from "../render/palette.js";
|
|
15
18
|
import { DEFAULT_BOARD_RENDER_LABELS, getBoardCardRenderer } from "../render/renderers/board-renderer-registry.js";
|
|
16
19
|
import { createBoardScriptHost } from "../render/script-host.js";
|
|
17
20
|
import { defaultBoardRenderStyle } from "../render/style.js";
|
|
18
|
-
import {
|
|
19
|
-
import { createBoardPlayer } from "../player/index.js";
|
|
21
|
+
import { boardTextureEdge } from "./assets.js";
|
|
20
22
|
import { observeDisplayDensity } from "./display-density.js";
|
|
21
23
|
import { toBoardPointerEvent } from "./pointer.js";
|
|
22
24
|
import { createBoardPointerGestures } from "./pointer-gestures.js";
|
|
@@ -49,6 +51,7 @@ function defaultTheme() {
|
|
|
49
51
|
const NO_IDS = /* @__PURE__ */ new Set();
|
|
50
52
|
const MARCH_STEP_MS = 160;
|
|
51
53
|
const MARCH_SMOOTH_MS = 40;
|
|
54
|
+
const TEXTURE_SETTLE_MS = 150;
|
|
52
55
|
const ROTATE_CURSOR = `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M21 12a9 9 0 1 1-2.64-6.36L21 8M21 3v5h-5' fill='none' stroke='%23fff' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M21 12a9 9 0 1 1-2.64-6.36L21 8M21 3v5h-5' fill='none' stroke='%231d1d1f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") 12 12, crosshair`;
|
|
53
56
|
const defaultStyles = /* @__PURE__ */ new Map();
|
|
54
57
|
function styleOf(theme) {
|
|
@@ -102,13 +105,13 @@ function mountBoardStage(host, options) {
|
|
|
102
105
|
let disposed = false;
|
|
103
106
|
let renderFrame = 0;
|
|
104
107
|
let tickFrame = 0;
|
|
108
|
+
let scriptTickFrame = 0;
|
|
105
109
|
let cardTickFrame = 0;
|
|
106
110
|
let cardTickTimer = null;
|
|
107
111
|
let cardTickDue = 0;
|
|
108
112
|
const staleIds = /* @__PURE__ */ new Set();
|
|
109
113
|
let resizeFrame = 0;
|
|
110
114
|
let cardEpoch = 0;
|
|
111
|
-
let assetVersion = 0;
|
|
112
115
|
let surface = {
|
|
113
116
|
width: 0,
|
|
114
117
|
height: 0
|
|
@@ -116,7 +119,7 @@ function mountBoardStage(host, options) {
|
|
|
116
119
|
let playbackCamera = null;
|
|
117
120
|
let cursor = "";
|
|
118
121
|
const renderCamera = () => playbackCamera ?? editor.camera;
|
|
119
|
-
const views = createBoardItemViewLayer(host, editor, options.views ?? [], renderCamera);
|
|
122
|
+
const views = createBoardItemViewLayer(host, editor, options.views ?? [], renderCamera, scheduleTick);
|
|
120
123
|
const player = createBoardPlayer({ resolveColor: (color) => {
|
|
121
124
|
const current = theme();
|
|
122
125
|
return {
|
|
@@ -140,29 +143,70 @@ function mountBoardStage(host, options) {
|
|
|
140
143
|
scene: editor.scene
|
|
141
144
|
};
|
|
142
145
|
options.onVisibleChange?.(cull.ids);
|
|
143
|
-
requestAssets = true;
|
|
144
146
|
return cull.ids;
|
|
145
147
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
const textureScale = () => renderCamera().zoom * (app?.renderer.resolution ?? 1);
|
|
149
|
+
let refined = {
|
|
150
|
+
scale: 0,
|
|
151
|
+
geometry: 0
|
|
152
|
+
};
|
|
153
|
+
let pendingRefine = "";
|
|
154
|
+
let refineTimer = null;
|
|
155
|
+
function stopRefine() {
|
|
156
|
+
if (refineTimer !== null) clearTimeout(refineTimer);
|
|
157
|
+
refineTimer = null;
|
|
158
|
+
refined = {
|
|
159
|
+
scale: 0,
|
|
160
|
+
geometry: 0
|
|
161
|
+
};
|
|
162
|
+
pendingRefine = "";
|
|
163
|
+
}
|
|
164
|
+
function scheduleRefine() {
|
|
165
|
+
const scale = textureScale();
|
|
166
|
+
const geometry = editor.geometryVersion;
|
|
167
|
+
const key = `${scale}:${geometry}`;
|
|
168
|
+
if (key === pendingRefine) return;
|
|
169
|
+
pendingRefine = key;
|
|
170
|
+
if (refineTimer !== null) clearTimeout(refineTimer);
|
|
171
|
+
refineTimer = null;
|
|
172
|
+
if (refined.scale === 0 || scale <= refined.scale && geometry === refined.geometry) {
|
|
173
|
+
refined = {
|
|
174
|
+
scale,
|
|
175
|
+
geometry
|
|
176
|
+
};
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
refineTimer = setTimeout(() => {
|
|
180
|
+
refineTimer = null;
|
|
181
|
+
refined = {
|
|
182
|
+
scale,
|
|
183
|
+
geometry
|
|
184
|
+
};
|
|
185
|
+
for (const id of scene?.liveIds() ?? []) {
|
|
186
|
+
const item = editor.scene.get(id);
|
|
187
|
+
if (item) assets.requestItem(item, boardTextureEdge(item, scale));
|
|
188
|
+
}
|
|
189
|
+
}, TEXTURE_SETTLE_MS);
|
|
190
|
+
}
|
|
191
|
+
const naturalIds = /* @__PURE__ */ new Set();
|
|
192
|
+
let liveVersion = -1;
|
|
193
|
+
function adoptNaturalSizes() {
|
|
194
|
+
if (naturalIds.size === 0) return;
|
|
150
195
|
const sizes = [];
|
|
151
|
-
for (const id of
|
|
196
|
+
for (const id of naturalIds) {
|
|
152
197
|
const item = editor.itemById(id);
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (!key) continue;
|
|
156
|
-
assets.requestItem(item);
|
|
198
|
+
const key = item && assets.assetKey(item);
|
|
199
|
+
if (!item || !key) continue;
|
|
157
200
|
const artifact = item.type === "task" ? featuredTaskArtifact(item.props.snapshot.artifacts) : null;
|
|
158
201
|
const recorded = artifact?.type === "image" || artifact?.type === "video" ? artifact : item.type === "image" || item.type === "video" ? item.props.snapshot : null;
|
|
159
202
|
if (!recorded || recorded.naturalWidth && recorded.naturalHeight) continue;
|
|
160
203
|
const natural = assets.getNaturalSize(key);
|
|
161
204
|
if (natural?.width && natural.height) sizes.push({
|
|
162
|
-
id
|
|
205
|
+
id,
|
|
163
206
|
...natural
|
|
164
207
|
});
|
|
165
208
|
}
|
|
209
|
+
naturalIds.clear();
|
|
166
210
|
if (sizes.length > 0) editor.adoptMediaNaturalSizes(sizes);
|
|
167
211
|
}
|
|
168
212
|
let lifted = null;
|
|
@@ -203,7 +247,11 @@ function mountBoardStage(host, options) {
|
|
|
203
247
|
getTexture: (key) => assets.getTexture(key),
|
|
204
248
|
hasError: (key) => assets.hasError(key),
|
|
205
249
|
fileState: (path) => options.fileState?.(path) ?? "ok",
|
|
206
|
-
acquireTexture: (key) =>
|
|
250
|
+
acquireTexture: (key, item) => {
|
|
251
|
+
assets.acquire(key);
|
|
252
|
+
assets.requestItem(item, boardTextureEdge(item, textureScale()));
|
|
253
|
+
if (assets.getTexture(key)) naturalIds.add(item.id);
|
|
254
|
+
},
|
|
207
255
|
releaseTexture: (key) => assets.release(key)
|
|
208
256
|
};
|
|
209
257
|
}
|
|
@@ -442,9 +490,37 @@ function mountBoardStage(host, options) {
|
|
|
442
490
|
}, owner, retained);
|
|
443
491
|
if (!retained || scriptHover && scriptHover.owner === owner && !Object.hasOwn(retained, scriptHover.target)) scriptHover = null;
|
|
444
492
|
}
|
|
493
|
+
function syncScripts() {
|
|
494
|
+
if (!scripts) return;
|
|
495
|
+
const now = performance.now();
|
|
496
|
+
if (scriptMode !== "paused") scriptTime += Math.min(250, Math.max(0, now - scriptLastTick));
|
|
497
|
+
scriptLastTick = now;
|
|
498
|
+
const camera = renderCamera();
|
|
499
|
+
if (scriptMode !== "paused" && scriptObservers.size) scriptObservers.sync(editor.document, editor.selection, () => ({
|
|
500
|
+
camera: { ...camera },
|
|
501
|
+
...surface,
|
|
502
|
+
safeRect: options.safeRect?.() ?? {
|
|
503
|
+
x: 0,
|
|
504
|
+
y: 0,
|
|
505
|
+
...surface
|
|
506
|
+
}
|
|
507
|
+
}));
|
|
508
|
+
scripts.sync(editor.document, editor.scene, camera, scriptTime, scriptMode === "interact", visibleIds());
|
|
509
|
+
}
|
|
510
|
+
function scheduleScriptTick() {
|
|
511
|
+
if (scriptTickFrame || !active || disposed) return;
|
|
512
|
+
scriptTickFrame = requestAnimationFrame(() => {
|
|
513
|
+
scriptTickFrame = 0;
|
|
514
|
+
if (tickFrame) return;
|
|
515
|
+
syncScripts();
|
|
516
|
+
if (scriptMode !== "paused" && scripts?.animated) scheduleScriptTick();
|
|
517
|
+
});
|
|
518
|
+
}
|
|
445
519
|
function createScripts() {
|
|
446
520
|
return createBoardScriptHost({
|
|
447
521
|
host,
|
|
522
|
+
isMaterialized: (id) => Boolean(scene?.getNode(id)),
|
|
523
|
+
onSchedule: scheduleScriptTick,
|
|
448
524
|
capabilities: {
|
|
449
525
|
...options.scriptCapabilities,
|
|
450
526
|
"board.emit": async (id, value) => {
|
|
@@ -552,25 +628,9 @@ function mountBoardStage(host, options) {
|
|
|
552
628
|
}
|
|
553
629
|
}
|
|
554
630
|
const renderScene = editor.scene;
|
|
555
|
-
if (scripts) {
|
|
556
|
-
const now = performance.now();
|
|
557
|
-
if (scriptMode !== "paused") scriptTime += Math.min(250, Math.max(0, now - scriptLastTick));
|
|
558
|
-
scriptLastTick = now;
|
|
559
|
-
if (scriptMode !== "paused" && scriptObservers.size) scriptObservers.sync(editor.document, editor.selection, () => ({
|
|
560
|
-
camera: { ...camera },
|
|
561
|
-
...surface,
|
|
562
|
-
safeRect: options.safeRect?.() ?? {
|
|
563
|
-
x: 0,
|
|
564
|
-
y: 0,
|
|
565
|
-
...surface
|
|
566
|
-
}
|
|
567
|
-
}));
|
|
568
|
-
scripts.sync(editor.document, renderScene, camera, scriptTime, scriptMode === "interact", visibleIds());
|
|
569
|
-
}
|
|
570
631
|
world.position.set(camera.x, camera.y);
|
|
571
632
|
world.scale.set(camera.zoom);
|
|
572
633
|
const ids = visibleIds();
|
|
573
|
-
syncAssets(ids);
|
|
574
634
|
const context = renderContext(current, renderScene, frame.time);
|
|
575
635
|
if (animationId && effectSampler) {
|
|
576
636
|
context.time = editor.playhead?.time ?? frame.time;
|
|
@@ -593,19 +653,20 @@ function mountBoardStage(host, options) {
|
|
|
593
653
|
getItem: (id) => renderScene.get(id) ?? null,
|
|
594
654
|
visibleIds: ids,
|
|
595
655
|
pinnedIds,
|
|
596
|
-
globalSig: [
|
|
597
|
-
assetVersion,
|
|
598
|
-
cardEpoch,
|
|
599
|
-
current.key,
|
|
600
|
-
textZoomBucket(camera.zoom),
|
|
601
|
-
getBoardResolution()
|
|
602
|
-
].join("|"),
|
|
656
|
+
globalSig: [cardEpoch, current.key].join("|"),
|
|
603
657
|
staleIds,
|
|
604
658
|
structureVersion: editor.structureVersion,
|
|
605
659
|
geometryVersion: editor.geometryVersion,
|
|
606
660
|
gestureActive: editor.gestureActive && editor.interaction.type !== "panning"
|
|
607
661
|
});
|
|
608
662
|
staleIds.clear();
|
|
663
|
+
if (scene.liveVersion !== liveVersion) {
|
|
664
|
+
liveVersion = scene.liveVersion;
|
|
665
|
+
options.onLiveChange?.(scene.liveIds());
|
|
666
|
+
}
|
|
667
|
+
adoptNaturalSizes();
|
|
668
|
+
scheduleRefine();
|
|
669
|
+
syncScripts();
|
|
609
670
|
drawInteraction();
|
|
610
671
|
views.sync({
|
|
611
672
|
ids,
|
|
@@ -617,7 +678,8 @@ function mountBoardStage(host, options) {
|
|
|
617
678
|
const nextCursor = cursorFor();
|
|
618
679
|
if (nextCursor !== cursor) host.style.cursor = cursor = nextCursor;
|
|
619
680
|
scheduleRender();
|
|
620
|
-
if (frame.running || scene.animated
|
|
681
|
+
if (frame.running || scene.animated) scheduleTick();
|
|
682
|
+
if (scriptMode !== "paused" && scripts?.animated) scheduleScriptTick();
|
|
621
683
|
const cardWait = scene.tick(performance.now());
|
|
622
684
|
if (cardWait !== null) scheduleCardTick(cardWait);
|
|
623
685
|
}
|
|
@@ -641,10 +703,10 @@ function mountBoardStage(host, options) {
|
|
|
641
703
|
sync();
|
|
642
704
|
});
|
|
643
705
|
}
|
|
644
|
-
const
|
|
706
|
+
const localPoint = (x, y) => elementClientToLocal(host)(x, y);
|
|
645
707
|
const inViews = (event) => event.target instanceof Node && views.element.contains(event.target);
|
|
646
708
|
function toInput(event) {
|
|
647
|
-
return toBoardPointerEvent(event,
|
|
709
|
+
return toBoardPointerEvent(event, host, renderCamera(), event.type === "pointermove" && editor.interaction.type === "drawing");
|
|
648
710
|
}
|
|
649
711
|
function scriptTarget(input) {
|
|
650
712
|
if (!scriptOutputs.size) return null;
|
|
@@ -751,13 +813,12 @@ function mountBoardStage(host, options) {
|
|
|
751
813
|
if (inViews(event)) return;
|
|
752
814
|
event.preventDefault();
|
|
753
815
|
editor.takeCameraControl();
|
|
754
|
-
const
|
|
755
|
-
const point = screenPoint(event.clientX - rect.left, event.clientY - rect.top);
|
|
816
|
+
const point = localPoint(event.clientX, event.clientY);
|
|
756
817
|
editor.wheel(point, event.deltaX, event.deltaY, event.ctrlKey || event.metaKey, event.deltaMode);
|
|
757
818
|
}
|
|
758
819
|
function handleDoubleClick(event) {
|
|
759
820
|
if (inViews(event)) return;
|
|
760
|
-
const point =
|
|
821
|
+
const point = pointToWorld(localPoint(event.clientX, event.clientY), renderCamera());
|
|
761
822
|
const item = editor.itemAt(point);
|
|
762
823
|
if (options.onDoubleClick?.(item, point) === true || editor.readonly) return;
|
|
763
824
|
if (item && !item.locked && editor.registry.capabilities(item).canEdit) {
|
|
@@ -783,9 +844,13 @@ function mountBoardStage(host, options) {
|
|
|
783
844
|
["dblclick", handleDoubleClick]
|
|
784
845
|
];
|
|
785
846
|
const stopEditor = editor.subscribe(LIVE_CHANNELS, scheduleTick);
|
|
786
|
-
const stopAssets = assets.subscribe(() => {
|
|
787
|
-
|
|
788
|
-
|
|
847
|
+
const stopAssets = assets.subscribe((key) => {
|
|
848
|
+
const ids = scene?.holders(key);
|
|
849
|
+
if (!ids?.size) return;
|
|
850
|
+
for (const id of ids) {
|
|
851
|
+
staleIds.add(id);
|
|
852
|
+
naturalIds.add(id);
|
|
853
|
+
}
|
|
789
854
|
scheduleTick();
|
|
790
855
|
});
|
|
791
856
|
const resizeObserver = new ResizeObserver(resize);
|
|
@@ -895,7 +960,10 @@ function mountBoardStage(host, options) {
|
|
|
895
960
|
if (!active) {
|
|
896
961
|
pointers.cancel();
|
|
897
962
|
stopMarch();
|
|
963
|
+
stopRefine();
|
|
898
964
|
cancelScriptPointers();
|
|
965
|
+
cancelAnimationFrame(scriptTickFrame);
|
|
966
|
+
scriptTickFrame = 0;
|
|
899
967
|
cancelAnimationFrame(renderFrame);
|
|
900
968
|
cancelAnimationFrame(tickFrame);
|
|
901
969
|
cancelAnimationFrame(cardTickFrame);
|
|
@@ -911,19 +979,17 @@ function mountBoardStage(host, options) {
|
|
|
911
979
|
resize();
|
|
912
980
|
},
|
|
913
981
|
invalidate(invalidation) {
|
|
914
|
-
if (invalidation?.cards)
|
|
915
|
-
cardEpoch += 1;
|
|
916
|
-
requestAssets = true;
|
|
917
|
-
}
|
|
982
|
+
if (invalidation?.cards) cardEpoch += 1;
|
|
918
983
|
for (const id of invalidation?.items ?? []) staleIds.add(id);
|
|
919
984
|
scheduleTick();
|
|
920
985
|
},
|
|
921
986
|
isMaterialized: (id) => Boolean(scene?.getNode(id)),
|
|
922
|
-
toWorld: (clientX, clientY) =>
|
|
987
|
+
toWorld: (clientX, clientY) => pointToWorld(localPoint(clientX, clientY), renderCamera()),
|
|
923
988
|
destroy() {
|
|
924
989
|
disposed = true;
|
|
925
990
|
pointers.cancel();
|
|
926
991
|
stopMarch();
|
|
992
|
+
stopRefine();
|
|
927
993
|
scriptPointers.clear();
|
|
928
994
|
stopTransforms?.();
|
|
929
995
|
scriptObservers.clear();
|
|
@@ -933,6 +999,7 @@ function mountBoardStage(host, options) {
|
|
|
933
999
|
stopEditor();
|
|
934
1000
|
stopAssets();
|
|
935
1001
|
resizeObserver.disconnect();
|
|
1002
|
+
cancelAnimationFrame(scriptTickFrame);
|
|
936
1003
|
cancelAnimationFrame(resizeFrame);
|
|
937
1004
|
cancelAnimationFrame(renderFrame);
|
|
938
1005
|
cancelAnimationFrame(tickFrame);
|
|
@@ -7,7 +7,7 @@ import "../editor/index.js";
|
|
|
7
7
|
//#region src/board/stage/views.d.ts
|
|
8
8
|
type BoardItemViewContext = {
|
|
9
9
|
editor: BoardEditor;
|
|
10
|
-
|
|
10
|
+
detailed: boolean;
|
|
11
11
|
selected: boolean;
|
|
12
12
|
toPointerEvent(event: PointerEvent): BoardPointerEvent;
|
|
13
13
|
};
|
|
@@ -17,6 +17,11 @@ type BoardItemViewInstance = {
|
|
|
17
17
|
};
|
|
18
18
|
type BoardItemView = {
|
|
19
19
|
type: string | ((item: BoardSceneItem) => boolean);
|
|
20
|
+
/** Optional screen-pixel threshold for expensive content, with built-in hysteresis. */
|
|
21
|
+
contentSize?: {
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
};
|
|
20
25
|
mount(element: HTMLElement, item: BoardSceneItem, context: BoardItemViewContext): BoardItemViewInstance;
|
|
21
26
|
};
|
|
22
27
|
type BoardItemViewLayer = {
|
|
@@ -33,6 +38,6 @@ type BoardItemViewLayer = {
|
|
|
33
38
|
}): void;
|
|
34
39
|
destroy(): void;
|
|
35
40
|
};
|
|
36
|
-
declare function createBoardItemViewLayer(host: HTMLElement, editor: BoardEditor, views: readonly BoardItemView[], camera: () => BoardViewport): BoardItemViewLayer;
|
|
41
|
+
declare function createBoardItemViewLayer(host: HTMLElement, editor: BoardEditor, views: readonly BoardItemView[], camera: () => BoardViewport, onInvalidate?: () => void): BoardItemViewLayer;
|
|
37
42
|
//#endregion
|
|
38
43
|
export { BoardItemView, BoardItemViewContext, BoardItemViewInstance, BoardItemViewLayer, createBoardItemViewLayer };
|
|
@@ -1,55 +1,80 @@
|
|
|
1
|
+
import { itemBounds } from "../model/geometry.js";
|
|
1
2
|
import { toBoardPointerEvent } from "./pointer.js";
|
|
2
3
|
//#region src/board/stage/views.ts
|
|
3
4
|
const VISIBLE_MARGIN = 240;
|
|
4
|
-
function
|
|
5
|
-
const { zoom } = camera;
|
|
5
|
+
function worldStyle(frame, order) {
|
|
6
6
|
return [
|
|
7
7
|
`z-index:${order}`,
|
|
8
|
-
`left:${frame.x
|
|
9
|
-
`top:${frame.y
|
|
10
|
-
`width:${frame.width
|
|
11
|
-
`height:${frame.height
|
|
12
|
-
`--board-zoom:${zoom}`,
|
|
8
|
+
`left:${frame.x}px`,
|
|
9
|
+
`top:${frame.y}px`,
|
|
10
|
+
`width:${frame.width}px`,
|
|
11
|
+
`height:${frame.height}px`,
|
|
13
12
|
`transform:rotate(${frame.rotation}deg)`
|
|
14
13
|
].join(";");
|
|
15
14
|
}
|
|
16
15
|
function onScreen(frame, camera, surface) {
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
16
|
+
const bounds = itemBounds(frame);
|
|
17
|
+
const left = bounds.x * camera.zoom + camera.x;
|
|
18
|
+
const top = bounds.y * camera.zoom + camera.y;
|
|
19
|
+
return left + bounds.width * camera.zoom >= -240 && top + bounds.height * camera.zoom >= -240 && left <= surface.width + VISIBLE_MARGIN && top <= surface.height + VISIBLE_MARGIN;
|
|
20
20
|
}
|
|
21
|
-
function createBoardItemViewLayer(host, editor, views, camera) {
|
|
21
|
+
function createBoardItemViewLayer(host, editor, views, camera, onInvalidate = () => {}) {
|
|
22
22
|
const element = host.ownerDocument.createElement("div");
|
|
23
23
|
element.dataset.boardViews = "";
|
|
24
24
|
element.style.cssText = "position:absolute;inset:0;z-index:2;overflow:hidden;pointer-events:none";
|
|
25
25
|
host.appendChild(element);
|
|
26
|
+
const world = host.ownerDocument.createElement("div");
|
|
27
|
+
world.style.cssText = "position:absolute;inset:0;transform-origin:0 0;pointer-events:none";
|
|
28
|
+
element.appendChild(world);
|
|
29
|
+
let cameraStyle = "";
|
|
26
30
|
const mounted = /* @__PURE__ */ new Map();
|
|
27
|
-
const
|
|
31
|
+
const pointers = /* @__PURE__ */ new Map();
|
|
32
|
+
const retained = (id, entry) => entry.element.contains(host.ownerDocument.activeElement) || [...pointers.values()].includes(id);
|
|
33
|
+
const pointerDown = (event) => {
|
|
34
|
+
const id = event.target?.closest("[data-board-item]")?.dataset.boardItem;
|
|
35
|
+
if (id && mounted.has(id)) pointers.set(event.pointerId, id);
|
|
36
|
+
};
|
|
37
|
+
const pointerEnd = (event) => {
|
|
38
|
+
if (pointers.delete(event.pointerId)) onInvalidate();
|
|
39
|
+
};
|
|
40
|
+
element.addEventListener("pointerdown", pointerDown, true);
|
|
41
|
+
element.addEventListener("focusout", onInvalidate);
|
|
42
|
+
host.ownerDocument.addEventListener("pointerup", pointerEnd, true);
|
|
43
|
+
host.ownerDocument.addEventListener("pointercancel", pointerEnd, true);
|
|
44
|
+
const toPointerEvent = (event) => toBoardPointerEvent(event, host, camera());
|
|
28
45
|
const viewFor = (item) => views.find((view) => typeof view.type === "string" ? view.type === item.type : view.type(item));
|
|
29
46
|
function unmount(id, entry) {
|
|
30
47
|
entry.instance.destroy?.();
|
|
31
48
|
entry.element.remove();
|
|
32
49
|
mounted.delete(id);
|
|
50
|
+
for (const [pointer, owner] of pointers) if (owner === id) pointers.delete(pointer);
|
|
33
51
|
}
|
|
34
52
|
return {
|
|
35
53
|
element,
|
|
36
54
|
sync({ ids, scene, camera: view, surface, selection }) {
|
|
37
55
|
if (views.length === 0) return;
|
|
56
|
+
const transform = `translate(${view.x}px,${view.y}px) scale(${view.zoom})`;
|
|
57
|
+
if (transform !== cameraStyle) world.style.transform = cameraStyle = transform;
|
|
38
58
|
const live = /* @__PURE__ */ new Set();
|
|
39
|
-
|
|
59
|
+
const candidates = new Set(ids ?? scene.items.map((item) => item.id));
|
|
60
|
+
for (const [id, entry] of mounted) if (retained(id, entry)) candidates.add(id);
|
|
61
|
+
for (const id of candidates) {
|
|
40
62
|
const item = scene.get(id);
|
|
41
63
|
if (!item) continue;
|
|
42
64
|
const itemView = viewFor(item);
|
|
43
|
-
|
|
65
|
+
let entry = mounted.get(item.id);
|
|
66
|
+
const held = entry ? retained(id, entry) : false;
|
|
67
|
+
if (!itemView || !held && !onScreen(item.frame, view, surface)) continue;
|
|
44
68
|
live.add(item.id);
|
|
69
|
+
const style = worldStyle(item.frame, scene.indexOf(item.id));
|
|
70
|
+
const minimum = itemView.contentSize;
|
|
71
|
+
const threshold = entry?.detailed ? .85 : 1;
|
|
45
72
|
const context = {
|
|
46
73
|
editor,
|
|
47
|
-
|
|
74
|
+
detailed: held || !minimum || item.frame.width * view.zoom >= minimum.width * threshold && item.frame.height * view.zoom >= minimum.height * threshold,
|
|
48
75
|
selected: selection.has(item.id),
|
|
49
76
|
toPointerEvent
|
|
50
77
|
};
|
|
51
|
-
const style = screenStyle(item.frame, view, scene.indexOf(item.id));
|
|
52
|
-
let entry = mounted.get(item.id);
|
|
53
78
|
if (entry && entry.view !== itemView) {
|
|
54
79
|
unmount(item.id, entry);
|
|
55
80
|
entry = void 0;
|
|
@@ -58,13 +83,13 @@ function createBoardItemViewLayer(host, editor, views, camera) {
|
|
|
58
83
|
const node = host.ownerDocument.createElement("div");
|
|
59
84
|
node.dataset.boardItem = item.id;
|
|
60
85
|
node.style.cssText = `position:absolute;pointer-events:none;transform-origin:center;${style}`;
|
|
61
|
-
|
|
86
|
+
world.appendChild(node);
|
|
62
87
|
mounted.set(item.id, {
|
|
63
88
|
view: itemView,
|
|
64
89
|
element: node,
|
|
65
90
|
instance: itemView.mount(node, item, context),
|
|
66
91
|
item,
|
|
67
|
-
|
|
92
|
+
detailed: context.detailed,
|
|
68
93
|
selected: context.selected,
|
|
69
94
|
style
|
|
70
95
|
});
|
|
@@ -74,9 +99,9 @@ function createBoardItemViewLayer(host, editor, views, camera) {
|
|
|
74
99
|
entry.element.style.cssText = `position:absolute;pointer-events:none;transform-origin:center;${style}`;
|
|
75
100
|
entry.style = style;
|
|
76
101
|
}
|
|
77
|
-
if (entry.item !== item || entry.
|
|
102
|
+
if (entry.item !== item || entry.detailed !== context.detailed || entry.selected !== context.selected) {
|
|
78
103
|
entry.item = item;
|
|
79
|
-
entry.
|
|
104
|
+
entry.detailed = context.detailed;
|
|
80
105
|
entry.selected = context.selected;
|
|
81
106
|
entry.instance.update?.(item, context);
|
|
82
107
|
}
|
|
@@ -84,6 +109,10 @@ function createBoardItemViewLayer(host, editor, views, camera) {
|
|
|
84
109
|
for (const [id, entry] of mounted) if (!live.has(id)) unmount(id, entry);
|
|
85
110
|
},
|
|
86
111
|
destroy() {
|
|
112
|
+
element.removeEventListener("pointerdown", pointerDown, true);
|
|
113
|
+
element.removeEventListener("focusout", onInvalidate);
|
|
114
|
+
host.ownerDocument.removeEventListener("pointerup", pointerEnd, true);
|
|
115
|
+
host.ownerDocument.removeEventListener("pointercancel", pointerEnd, true);
|
|
87
116
|
for (const [id, entry] of mounted) unmount(id, entry);
|
|
88
117
|
element.remove();
|
|
89
118
|
}
|
|
@@ -2767,6 +2767,7 @@ declare const harnessArchiveSchema: z.ZodObject<{
|
|
|
2767
2767
|
harness: z.ZodEnum<{
|
|
2768
2768
|
claude: "claude";
|
|
2769
2769
|
codex: "codex";
|
|
2770
|
+
cursor: "cursor";
|
|
2770
2771
|
pi: "pi";
|
|
2771
2772
|
workbuddy: "workbuddy";
|
|
2772
2773
|
}>;
|
|
@@ -2777,6 +2778,7 @@ declare const harnessArchiveIndexSchema: z.ZodObject<{
|
|
|
2777
2778
|
harness: z.ZodEnum<{
|
|
2778
2779
|
claude: "claude";
|
|
2779
2780
|
codex: "codex";
|
|
2781
|
+
cursor: "cursor";
|
|
2780
2782
|
pi: "pi";
|
|
2781
2783
|
workbuddy: "workbuddy";
|
|
2782
2784
|
}>;
|
|
@@ -2814,7 +2816,7 @@ declare function validateArchiveBoundary(index: HarnessArchiveIndex, parent: Har
|
|
|
2814
2816
|
//#endregion
|
|
2815
2817
|
//#region ../protocol/dist/runtime/harnesses.d.ts
|
|
2816
2818
|
/** Single source of truth for local Harness identities. Adding a Harness starts here. */
|
|
2817
|
-
declare const LOCAL_HARNESSES: readonly ["pi", "codex", "claude", "workbuddy"];
|
|
2819
|
+
declare const LOCAL_HARNESSES: readonly ["pi", "codex", "claude", "workbuddy", "cursor"];
|
|
2818
2820
|
type LocalHarness = typeof LOCAL_HARNESSES[number];
|
|
2819
2821
|
type LocalHarnessSpec = {
|
|
2820
2822
|
label: string;
|
|
@@ -2827,6 +2829,7 @@ declare const LOCAL_HARNESS_SPECS: Readonly<Record<LocalHarness, LocalHarnessSpe
|
|
|
2827
2829
|
declare const localHarnessSchema: z.ZodEnum<{
|
|
2828
2830
|
claude: "claude";
|
|
2829
2831
|
codex: "codex";
|
|
2832
|
+
cursor: "cursor";
|
|
2830
2833
|
pi: "pi";
|
|
2831
2834
|
workbuddy: "workbuddy";
|
|
2832
2835
|
}>;
|
|
@@ -2834,6 +2837,7 @@ declare const harnessSchema: z.ZodEnum<{
|
|
|
2834
2837
|
claude: "claude";
|
|
2835
2838
|
codex: "codex";
|
|
2836
2839
|
cohub: "cohub";
|
|
2840
|
+
cursor: "cursor";
|
|
2837
2841
|
pi: "pi";
|
|
2838
2842
|
workbuddy: "workbuddy";
|
|
2839
2843
|
}>;
|
|
@@ -2973,6 +2977,7 @@ declare const nativeIngestSchema: z.ZodObject<{
|
|
|
2973
2977
|
harness: z.ZodEnum<{
|
|
2974
2978
|
claude: "claude";
|
|
2975
2979
|
codex: "codex";
|
|
2980
|
+
cursor: "cursor";
|
|
2976
2981
|
pi: "pi";
|
|
2977
2982
|
workbuddy: "workbuddy";
|
|
2978
2983
|
}>;
|
|
@@ -3023,6 +3028,7 @@ declare const nativeRuntimeEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
3023
3028
|
harness: z.ZodEnum<{
|
|
3024
3029
|
claude: "claude";
|
|
3025
3030
|
codex: "codex";
|
|
3031
|
+
cursor: "cursor";
|
|
3026
3032
|
pi: "pi";
|
|
3027
3033
|
workbuddy: "workbuddy";
|
|
3028
3034
|
}>;
|
|
@@ -3271,6 +3277,7 @@ declare const runtimeCapabilitiesSchema: z.ZodObject<{
|
|
|
3271
3277
|
harnesses: z.ZodArray<z.ZodEnum<{
|
|
3272
3278
|
claude: "claude";
|
|
3273
3279
|
codex: "codex";
|
|
3280
|
+
cursor: "cursor";
|
|
3274
3281
|
pi: "pi";
|
|
3275
3282
|
workbuddy: "workbuddy";
|
|
3276
3283
|
}>>;
|
|
@@ -3278,6 +3285,7 @@ declare const runtimeCapabilitiesSchema: z.ZodObject<{
|
|
|
3278
3285
|
harness: z.ZodEnum<{
|
|
3279
3286
|
claude: "claude";
|
|
3280
3287
|
codex: "codex";
|
|
3288
|
+
cursor: "cursor";
|
|
3281
3289
|
pi: "pi";
|
|
3282
3290
|
workbuddy: "workbuddy";
|
|
3283
3291
|
}>;
|
|
@@ -3313,6 +3321,7 @@ declare const runtimePendingExecutionSchema: z.ZodObject<{
|
|
|
3313
3321
|
harness: z.ZodEnum<{
|
|
3314
3322
|
claude: "claude";
|
|
3315
3323
|
codex: "codex";
|
|
3324
|
+
cursor: "cursor";
|
|
3316
3325
|
pi: "pi";
|
|
3317
3326
|
workbuddy: "workbuddy";
|
|
3318
3327
|
}>;
|
|
@@ -3503,6 +3512,7 @@ declare const runtimeEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
3503
3512
|
harness: z.ZodEnum<{
|
|
3504
3513
|
claude: "claude";
|
|
3505
3514
|
codex: "codex";
|
|
3515
|
+
cursor: "cursor";
|
|
3506
3516
|
pi: "pi";
|
|
3507
3517
|
workbuddy: "workbuddy";
|
|
3508
3518
|
}>;
|
|
@@ -3533,6 +3543,7 @@ declare const runtimeCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
3533
3543
|
harness: z.ZodEnum<{
|
|
3534
3544
|
claude: "claude";
|
|
3535
3545
|
codex: "codex";
|
|
3546
|
+
cursor: "cursor";
|
|
3536
3547
|
pi: "pi";
|
|
3537
3548
|
workbuddy: "workbuddy";
|
|
3538
3549
|
}>;
|
|
@@ -3555,6 +3566,7 @@ declare const runtimeCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
3555
3566
|
harness: z.ZodEnum<{
|
|
3556
3567
|
claude: "claude";
|
|
3557
3568
|
codex: "codex";
|
|
3569
|
+
cursor: "cursor";
|
|
3558
3570
|
pi: "pi";
|
|
3559
3571
|
workbuddy: "workbuddy";
|
|
3560
3572
|
}>;
|
|
@@ -3603,6 +3615,7 @@ declare const runtimeCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
3603
3615
|
harness: z.ZodEnum<{
|
|
3604
3616
|
claude: "claude";
|
|
3605
3617
|
codex: "codex";
|
|
3618
|
+
cursor: "cursor";
|
|
3606
3619
|
pi: "pi";
|
|
3607
3620
|
workbuddy: "workbuddy";
|
|
3608
3621
|
}>;
|
|
@@ -3667,6 +3680,7 @@ declare const runtimeCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
3667
3680
|
harness: z.ZodEnum<{
|
|
3668
3681
|
claude: "claude";
|
|
3669
3682
|
codex: "codex";
|
|
3683
|
+
cursor: "cursor";
|
|
3670
3684
|
pi: "pi";
|
|
3671
3685
|
workbuddy: "workbuddy";
|
|
3672
3686
|
}>;
|
|
@@ -6536,7 +6550,7 @@ interface SystemOneRequest<Q extends Questions = Questions> {
|
|
|
6536
6550
|
model?: string;
|
|
6537
6551
|
}
|
|
6538
6552
|
//#endregion
|
|
6539
|
-
//#region ../../node_modules/.pnpm/@neta-art+generation@0.1.
|
|
6553
|
+
//#region ../../node_modules/.pnpm/@neta-art+generation@0.1.40/node_modules/@neta-art/generation/dist/builtins-BYR-8YTe.d.ts
|
|
6540
6554
|
//#region src/types.d.ts
|
|
6541
6555
|
declare const MODEL_SCHEMA: "neta.generation.model.v1";
|
|
6542
6556
|
declare const GENERATION_MODEL_CATEGORIES: readonly ["image", "video", "audio", "3d", "decision"];
|