在已落地的节点注册表上加两层节点:展示层(Markdown / SVG / HTML / 全景)与 接入生成链的加工层(对比 / 图表 / 调色)。全部是第一方内置节点,不引入远程插件 加载,因此不涉及沙箱信任模型,也不需要把 CanvasNodeType 放开成任意字符串。 刻意保留穷尽性检查而不是改成运行时注册。全库只有 4 张按类型建的穷眉表 (NODE_DEFAULT_SIZE / NODE_SPECS / 注册表定义 / nodeContentRenderers), 让编译器强制每个新节点填满它们,比少改几个文件更值 —— 加第一个枚举成员时 编译器点出了 5 处,其中 pages/canvas/shared.tsx 是原先没编目的那一处; 换成运行时注册,那里会静默回落成「未知节点」。 两处前置基建: - CanvasNodeGraphContext:渲染器只拿到 node、没有 connections,而加工层三个节点 都要读上游。仿已有的 canvas-node-action-context(同一个问题:节点经 CanvasProjectWorldLayers 渲染不便逐个透传),取上游复用 canvas-resource-references 的 getContextResourceNodes,不另写一份。 Provider 值必须 memo —— 每帧新对象会让所有节点跟着重渲染。 - ToolbarHandlers.onAddExtensionNode(type):一个泛用入口,不给每种扩展节点单开 一个 onAddXxx。菜单另开「展示与加工」分区,不挤占上方调好的四列创作网格。 SVG 与 HTML 统一走 sandbox iframe:依赖里没有 DOMPurify,手写 SVG 消毒不可靠 (script / on* / foreignObject)。SandboxedFrame 只暴露 allowScripts 布尔而不是 sandbox 取值,让「同时给 allow-same-origin」这条没有入口。 全景节点三个取舍:点击才激活 WebGL(浏览器对同时存在的上下文有硬上限,画布可以有 任意多个全景节点,自动激活必然在某个数量后整片黑);用原生 three 而非 fiber (需要精确 dispose,forceContextLoss 才真正释放上下文);性能模式下只给静态预览。 调色是唯一碰生成路径的节点,照 Drawing 的先例:拖滑杆只做本地 CSS filter 预览, 落地成资源要等到生成消费它时才走 uploadResourceFile。预览与导出共用同一个 filter 字符串,两处各写一份就会「看到的和用的悄悄不一致」;未调色时直接透传源图, 省掉一次渲染与上传。ctx.filter 不受支持时明确报错而不是导出一张没调色的图。 resourceKind 与 inputKind 分开两个字段:空图片节点不是素材(不进 @ 引用), 但照样计入 imageCount。调色节点的 resourceKind 无条件返回 image —— 它的图来自 上游,按「有没有 content」判断会让它永远进不了生成输入,这是不报错的静默失效。 测试:新增 test/canvas-extension-nodes.test.ts(12 用例 / 64 断言),覆盖 7 个节点的 判据矩阵、调色参数、以及图表解析。图表解析函数刻意不抛 —— 数据来自模型输出, 非法 JSON 是常态而不是异常,抛出来会连带整个画布白屏,有 7 条断言钉这个。 测试列表是显式枚举,已把新文件加进 package.json,不加进去不会跑。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
92 lines
4.8 KiB
JSON
92 lines
4.8 KiB
JSON
{
|
|
"name": "infinite-canvas",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "vite --host 0.0.0.0 --port 3000",
|
|
"build": "tsc --noEmit && vite build",
|
|
"typecheck": "tsc --noEmit",
|
|
"test": "bun test test/api-request.test.ts test/video-api-contracts.test.ts test/image-api-contracts.test.ts test/channel-model-catalog.test.ts test/agent-prompt-cache.test.ts test/canvas-batch-connection.test.ts test/canvas-character-reference.test.ts test/canvas-document.test.ts test/canvas-drawing-engine.test.ts test/canvas-emotion-edit-plan.test.ts test/canvas-extension-nodes.test.ts test/canvas-folder.test.ts test/canvas-generation-layout.test.ts test/canvas-image-batch-retry.test.ts test/canvas-leafer-viewport.test.ts test/canvas-local-runtime.test.ts test/canvas-model-policy.test.ts test/canvas-resource-references.test.ts test/canvas-storyboard-references.test.ts test/canvas-node-config-reset.test.ts test/canvas-node-registry.test.ts test/canvas-video-regeneration.test.ts test/canvas-video-timeline-segments.test.ts test/create-canvas-handoff.test.ts test/create-library-button.test.ts test/creation-references.test.ts test/generation-asset-repository.node.test.ts test/generation-storage-consistency.test.ts test/generation-task-durability.node.test.ts test/generation-task-local.test.ts test/generation-task-materializer.test.ts test/task-media-fallback.test.ts test/user-scoped-generation-persistence.test.ts test/local-channel-permission.test.ts test/local-channel-runtime-projection.node.test.mjs test/local-channel-task-center.node.test.mjs test/local-channel-ui.node.test.mjs test/local-cli-settings.test.ts test/local-dreamina-cli.test.ts test/local-dreamina-generation.test.ts test/local-dreamina-model-catalog.test.ts test/local-runtime-bootstrap.test.ts test/local-runtime-connection.test.ts test/local-runtime.test.ts test/client-id.test.ts test/grok-image-prompt-limit.test.ts test/image-resolution-tiers.test.ts test/gemini-image.test.ts test/libtv-import.test.ts test/timeline-to-ffmpeg.test.ts test/canvas-video-segment-args.test.ts test/tapnow-import.test.ts && bun test test/local-dreamina-cross-runtime.test.ts",
|
|
"start": "vite preview --host 0.0.0.0 --port 3000",
|
|
"format": "prettier --write .",
|
|
"format:check": "prettier --check ."
|
|
},
|
|
"dependencies": {
|
|
"@ant-design/icons": "^6.3.2",
|
|
"@codemirror/lang-json": "^6.0.2",
|
|
"@excalidraw/excalidraw": "0.18.1",
|
|
"@ffmpeg/core": "0.12.10",
|
|
"@ffmpeg/ffmpeg": "^0.12.15",
|
|
"@ffmpeg/util": "^0.12.2",
|
|
"@lobehub/icons": "5.16.0",
|
|
"@mediapipe/tasks-vision": "^1.0.1",
|
|
"@react-three/drei": "^10.7.7",
|
|
"@react-three/fiber": "^9.6.1",
|
|
"@streamdown/code": "^1.1.1",
|
|
"@tanstack/react-query": "^5.101.2",
|
|
"@tanstack/react-virtual": "^3.14.8",
|
|
"@tiptap/core": "3.28.0",
|
|
"@tiptap/extension-character-count": "^3.28.0",
|
|
"@tiptap/extension-color": "^3.28.0",
|
|
"@tiptap/extension-highlight": "^3.28.0",
|
|
"@tiptap/extension-placeholder": "^3.28.0",
|
|
"@tiptap/extension-text-align": "^3.28.0",
|
|
"@tiptap/extension-text-style": "^3.28.0",
|
|
"@tiptap/react": "^3.28.0",
|
|
"@tiptap/starter-kit": "^3.28.0",
|
|
"@uiw/react-codemirror": "^4.25.11",
|
|
"@vidstack/react": "1.15.6",
|
|
"antd": "^6.5.1",
|
|
"axios": "^1.18.1",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"copy-to-clipboard": "^4.0.2",
|
|
"dayjs": "^1.11.21",
|
|
"fflate": "^0.8.3",
|
|
"file-saver": "^2.0.5",
|
|
"idb": "8.0.3",
|
|
"json-canonicalize": "2.0.0",
|
|
"leafer-ui": "^2.2.7",
|
|
"localforage": "^1.10.0",
|
|
"lucide-react": "^1.25.0",
|
|
"mammoth": "^1.12.0",
|
|
"motion": "^12.42.2",
|
|
"nanoid": "^6.0.0",
|
|
"react": "19.2.7",
|
|
"react-dom": "19.2.7",
|
|
"react-markdown": "^10.1.0",
|
|
"react-router": "^8.2.0",
|
|
"recharts": "^3.9.2",
|
|
"shadcn": "^4.13.1",
|
|
"streamdown": "^2.5.0",
|
|
"tailwind-merge": "^3.6.0",
|
|
"tailwindcss": "^4.3.3",
|
|
"three": "^0.185.1",
|
|
"three-stdlib": "^2.36.1",
|
|
"tldraw": "5.2.5",
|
|
"tw-animate-css": "^1.4.0",
|
|
"zustand": "^5.0.14"
|
|
},
|
|
"devDependencies": {
|
|
"@tailwindcss/postcss": "^4.3.3",
|
|
"@types/file-saver": "^2.0.7",
|
|
"@types/node": "^20.19.43",
|
|
"@types/react": "19.2.17",
|
|
"@types/react-dom": "19.2.3",
|
|
"@types/three": "0.185.4",
|
|
"@vitejs/plugin-react": "^6.0.3",
|
|
"prettier": "^3.9.5",
|
|
"typescript": "^7.0.2",
|
|
"vite": "^8.1.5"
|
|
},
|
|
"overrides": {
|
|
"@babel/core": "7.29.7",
|
|
"form-data": "4.0.6",
|
|
"hono": "4.12.30",
|
|
"js-yaml": "4.3.0",
|
|
"prismjs": "1.30.0",
|
|
"qs": "6.15.3"
|
|
}
|
|
}
|