From 16033c4c56a3a0bc2eaf517be53768bc39129571 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Sun, 8 Mar 2026 14:33:56 +0300 Subject: [PATCH] Revert mermaid plugin (crashes VitePress dev), use tables instead vitepress-plugin-mermaid patches vitepress's client app entry, which breaks ESM module resolution and renders all pages blank. Replace mermaid diagrams with offset/content tables and pipeline code blocks that render correctly. --- bun.lock | 10 ---- packages/docs/.vitepress/config.ts | 5 +- packages/docs/de/reference/file-format.md | 62 ++++++++--------------- packages/docs/es/reference/file-format.md | 62 ++++++++--------------- packages/docs/fr/reference/file-format.md | 62 ++++++++--------------- packages/docs/it/reference/file-format.md | 62 ++++++++--------------- packages/docs/package.json | 4 +- packages/docs/pl/reference/file-format.md | 62 ++++++++--------------- packages/docs/reference/file-format.md | 62 ++++++++--------------- packages/docs/ru/reference/file-format.md | 62 ++++++++--------------- 10 files changed, 143 insertions(+), 310 deletions(-) diff --git a/bun.lock b/bun.lock index a9dd2f44a..49905c69c 100644 --- a/bun.lock +++ b/bun.lock @@ -122,9 +122,7 @@ "name": "@open-pencil/docs", "version": "0.1.0", "devDependencies": { - "mermaid": "11.4.1", "vitepress": "^1.6.4", - "vitepress-plugin-mermaid": "^2.0.17", }, }, "packages/mcp": { @@ -644,8 +642,6 @@ "@libp2p/websockets": ["@libp2p/websockets@9.2.16", "", { "dependencies": { "@libp2p/interface": "^2.10.4", "@libp2p/utils": "^6.7.0", "@multiformats/multiaddr": "^12.4.4", "@multiformats/multiaddr-matcher": "^1.7.2", "@multiformats/multiaddr-to-uri": "^11.0.0", "@types/ws": "^8.18.1", "it-ws": "^6.1.5", "main-event": "^1.0.1", "p-defer": "^4.0.1", "p-event": "^6.0.1", "progress-events": "^1.0.1", "race-signal": "^1.1.3", "ws": "^8.18.2" } }, "sha512-jD96ClKeaZvTs+YyGJxOOQSWVe9e9SHmacJ9uE9dqWZjCbPICdCJnOj2pLg258WxVrc+/MRFKSHE/v5f2ZJGCA=="], - "@mermaid-js/mermaid-mindmap": ["@mermaid-js/mermaid-mindmap@9.3.0", "", { "dependencies": { "@braintree/sanitize-url": "^6.0.0", "cytoscape": "^3.23.0", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.1.0", "d3": "^7.0.0", "khroma": "^2.0.0", "non-layered-tidy-tree-layout": "^2.0.2" } }, "sha512-IhtYSVBBRYviH1Ehu8gk69pMDF8DSRqXBRDMWrEfHoaMruHeaP2DXA3PBnuwsMaCdPQhlUUcy/7DBLAEIXvCAw=="], - "@mermaid-js/parser": ["@mermaid-js/parser@0.3.0", "", { "dependencies": { "langium": "3.0.0" } }, "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA=="], "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.27.1", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA=="], @@ -2058,8 +2054,6 @@ "node-sarif-builder": ["node-sarif-builder@3.4.0", "", { "dependencies": { "@types/sarif": "^2.1.7", "fs-extra": "^11.1.1" } }, "sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg=="], - "non-layered-tidy-tree-layout": ["non-layered-tidy-tree-layout@2.0.2", "", {}, "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw=="], - "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], "number-allocator": ["number-allocator@1.0.14", "", { "dependencies": { "debug": "^4.3.1", "js-sdsl": "4.3.0" } }, "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA=="], @@ -2506,8 +2500,6 @@ "vitepress": ["vitepress@1.6.4", "", { "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg=="], - "vitepress-plugin-mermaid": ["vitepress-plugin-mermaid@2.0.17", "", { "optionalDependencies": { "@mermaid-js/mermaid-mindmap": "^9.3.0" }, "peerDependencies": { "mermaid": "10 || 11", "vitepress": "^1.0.0 || ^1.0.0-alpha" } }, "sha512-IUzYpwf61GC6k0XzfmAmNrLvMi9TRrVRMsUyCA8KNXhg/mQ1VqWnO0/tBVPiX5UoKF1mDUwqn5QV4qAJl6JnUg=="], - "void-elements": ["void-elements@3.1.0", "", {}, "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="], "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], @@ -2650,8 +2642,6 @@ "@libp2p/crypto/@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="], - "@mermaid-js/mermaid-mindmap/@braintree/sanitize-url": ["@braintree/sanitize-url@6.0.4", "", {}, "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A=="], - "@modelcontextprotocol/sdk/@hono/node-server": ["@hono/node-server@1.19.9", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="], "@modelcontextprotocol/sdk/hono": ["hono@4.12.3", "", {}, "sha512-SFsVSjp8sj5UumXOOFlkZOG6XS9SJDKw0TbwFeV+AJ8xlST8kxK5Z/5EYa111UY8732lK2S/xB653ceuaoGwpg=="], diff --git a/packages/docs/.vitepress/config.ts b/packages/docs/.vitepress/config.ts index 0808b0ee0..e947d27cc 100644 --- a/packages/docs/.vitepress/config.ts +++ b/packages/docs/.vitepress/config.ts @@ -1,5 +1,4 @@ import { defineConfig, type DefaultTheme } from 'vitepress' -import { withMermaid } from 'vitepress-plugin-mermaid' interface SidebarLabels { gettingAround: string @@ -207,7 +206,7 @@ const LOCALES: Recordfig-kiwi (8 bytes)"] - B["Version (4 bytes, uint32 LE)"] - C["Schema length (4 bytes, uint32 LE)"] - D["Compressed Kiwi schema"] - E["Message length (4 bytes, uint32 LE)"] - F["Compressed Kiwi message — NodeChange[]"] - G["Blob data — images, vector networks, fonts"] -``` +| Offset | Content | +|--------|---------| +| 0 | Magic header `fig-kiwi` (8 bytes) | +| 8 | Version (4 bytes, uint32 LE) | +| 12 | Schema length (4 bytes, uint32 LE) | +| 16 | Compressed Kiwi schema | +| … | Message length (4 bytes, uint32 LE) | +| … | Compressed Kiwi message — `NodeChange[]` (entire document) | +| … | Blob data — images, vector networks, fonts | ## Import Pipeline -```mermaid -flowchart LR - A[".fig file"] --> B["Parse header"] - B --> C["Decompress Zstd"] - C --> D["Decode Kiwi schema"] - D --> E["Decode message"] - E --> F["NodeChange[]"] - F --> G["Build SceneGraph"] - G --> H["Resolve blob refs"] - H --> I["Render"] +``` +.fig file → parse header → decompress Zstd → decode Kiwi schema + → decode message → NodeChange[] → build SceneGraph + → resolve blob refs → render on canvas ``` ## Export Pipeline -```mermaid -flowchart LR - A["SceneGraph"] --> B["NodeChange[]"] - B --> C["Kiwi encode"] - C --> D["Compress"] - D --> E["Build ZIP"] - E --> F[".fig file"] +``` +SceneGraph → NodeChange[] → Kiwi encode → compress (Zstd/deflate) + → build ZIP (header + schema + message + thumbnail.png) + → write .fig file ``` Export uses S (Save) and S (Save As) with native OS dialogs on the desktop app. The exported file includes a `thumbnail.png` required by Figma for file preview. @@ -77,18 +66,7 @@ Figma's schema uses non-contiguous field IDs (e.g. 1, 2, 5, 10 with gaps). The k Copy/paste uses the same Kiwi binary encoding: -```mermaid -flowchart LR - subgraph Copy - A["Selected nodes"] --> B["Encode NodeChange[]"] - B --> C["Compress"] - C --> D["Clipboard
application/x-figma-design"] - end - subgraph Paste - D --> E["Decompress"] - E --> F["Decode Kiwi"] - F --> G["Create nodes"] - end -``` +1. **Copy** — encode selected `NodeChange[]` to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type +2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph -This enables bidirectional clipboard between OpenPencil and Figma. +Encoding happens synchronously in the copy event handler (not async Clipboard API) for browser compatibility. This enables bidirectional clipboard between OpenPencil and Figma. diff --git a/packages/docs/es/reference/file-format.md b/packages/docs/es/reference/file-format.md index 1182e4b2b..ea94b8fb6 100644 --- a/packages/docs/es/reference/file-format.md +++ b/packages/docs/es/reference/file-format.md @@ -4,41 +4,30 @@ A `.fig` file is a ZIP archive containing a Kiwi-encoded binary message: -```mermaid -block-beta - columns 1 - A["Magic header: fig-kiwi (8 bytes)"] - B["Version (4 bytes, uint32 LE)"] - C["Schema length (4 bytes, uint32 LE)"] - D["Compressed Kiwi schema"] - E["Message length (4 bytes, uint32 LE)"] - F["Compressed Kiwi message — NodeChange[]"] - G["Blob data — images, vector networks, fonts"] -``` +| Offset | Content | +|--------|---------| +| 0 | Magic header `fig-kiwi` (8 bytes) | +| 8 | Version (4 bytes, uint32 LE) | +| 12 | Schema length (4 bytes, uint32 LE) | +| 16 | Compressed Kiwi schema | +| … | Message length (4 bytes, uint32 LE) | +| … | Compressed Kiwi message — `NodeChange[]` (entire document) | +| … | Blob data — images, vector networks, fonts | ## Import Pipeline -```mermaid -flowchart LR - A[".fig file"] --> B["Parse header"] - B --> C["Decompress Zstd"] - C --> D["Decode Kiwi schema"] - D --> E["Decode message"] - E --> F["NodeChange[]"] - F --> G["Build SceneGraph"] - G --> H["Resolve blob refs"] - H --> I["Render"] +``` +.fig file → parse header → decompress Zstd → decode Kiwi schema + → decode message → NodeChange[] → build SceneGraph + → resolve blob refs → render on canvas ``` ## Export Pipeline -```mermaid -flowchart LR - A["SceneGraph"] --> B["NodeChange[]"] - B --> C["Kiwi encode"] - C --> D["Compress"] - D --> E["Build ZIP"] - E --> F[".fig file"] +``` +SceneGraph → NodeChange[] → Kiwi encode → compress (Zstd/deflate) + → build ZIP (header + schema + message + thumbnail.png) + → write .fig file ``` Export uses S (Save) and S (Save As) with native OS dialogs on the desktop app. The exported file includes a `thumbnail.png` required by Figma for file preview. @@ -77,18 +66,7 @@ Figma's schema uses non-contiguous field IDs (e.g. 1, 2, 5, 10 with gaps). The k Copy/paste uses the same Kiwi binary encoding: -```mermaid -flowchart LR - subgraph Copy - A["Selected nodes"] --> B["Encode NodeChange[]"] - B --> C["Compress"] - C --> D["Clipboard
application/x-figma-design"] - end - subgraph Paste - D --> E["Decompress"] - E --> F["Decode Kiwi"] - F --> G["Create nodes"] - end -``` +1. **Copy** — encode selected `NodeChange[]` to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type +2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph -This enables bidirectional clipboard between OpenPencil and Figma. +Encoding happens synchronously in the copy event handler (not async Clipboard API) for browser compatibility. This enables bidirectional clipboard between OpenPencil and Figma. diff --git a/packages/docs/fr/reference/file-format.md b/packages/docs/fr/reference/file-format.md index 1182e4b2b..ea94b8fb6 100644 --- a/packages/docs/fr/reference/file-format.md +++ b/packages/docs/fr/reference/file-format.md @@ -4,41 +4,30 @@ A `.fig` file is a ZIP archive containing a Kiwi-encoded binary message: -```mermaid -block-beta - columns 1 - A["Magic header: fig-kiwi (8 bytes)"] - B["Version (4 bytes, uint32 LE)"] - C["Schema length (4 bytes, uint32 LE)"] - D["Compressed Kiwi schema"] - E["Message length (4 bytes, uint32 LE)"] - F["Compressed Kiwi message — NodeChange[]"] - G["Blob data — images, vector networks, fonts"] -``` +| Offset | Content | +|--------|---------| +| 0 | Magic header `fig-kiwi` (8 bytes) | +| 8 | Version (4 bytes, uint32 LE) | +| 12 | Schema length (4 bytes, uint32 LE) | +| 16 | Compressed Kiwi schema | +| … | Message length (4 bytes, uint32 LE) | +| … | Compressed Kiwi message — `NodeChange[]` (entire document) | +| … | Blob data — images, vector networks, fonts | ## Import Pipeline -```mermaid -flowchart LR - A[".fig file"] --> B["Parse header"] - B --> C["Decompress Zstd"] - C --> D["Decode Kiwi schema"] - D --> E["Decode message"] - E --> F["NodeChange[]"] - F --> G["Build SceneGraph"] - G --> H["Resolve blob refs"] - H --> I["Render"] +``` +.fig file → parse header → decompress Zstd → decode Kiwi schema + → decode message → NodeChange[] → build SceneGraph + → resolve blob refs → render on canvas ``` ## Export Pipeline -```mermaid -flowchart LR - A["SceneGraph"] --> B["NodeChange[]"] - B --> C["Kiwi encode"] - C --> D["Compress"] - D --> E["Build ZIP"] - E --> F[".fig file"] +``` +SceneGraph → NodeChange[] → Kiwi encode → compress (Zstd/deflate) + → build ZIP (header + schema + message + thumbnail.png) + → write .fig file ``` Export uses S (Save) and S (Save As) with native OS dialogs on the desktop app. The exported file includes a `thumbnail.png` required by Figma for file preview. @@ -77,18 +66,7 @@ Figma's schema uses non-contiguous field IDs (e.g. 1, 2, 5, 10 with gaps). The k Copy/paste uses the same Kiwi binary encoding: -```mermaid -flowchart LR - subgraph Copy - A["Selected nodes"] --> B["Encode NodeChange[]"] - B --> C["Compress"] - C --> D["Clipboard
application/x-figma-design"] - end - subgraph Paste - D --> E["Decompress"] - E --> F["Decode Kiwi"] - F --> G["Create nodes"] - end -``` +1. **Copy** — encode selected `NodeChange[]` to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type +2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph -This enables bidirectional clipboard between OpenPencil and Figma. +Encoding happens synchronously in the copy event handler (not async Clipboard API) for browser compatibility. This enables bidirectional clipboard between OpenPencil and Figma. diff --git a/packages/docs/it/reference/file-format.md b/packages/docs/it/reference/file-format.md index 1182e4b2b..ea94b8fb6 100644 --- a/packages/docs/it/reference/file-format.md +++ b/packages/docs/it/reference/file-format.md @@ -4,41 +4,30 @@ A `.fig` file is a ZIP archive containing a Kiwi-encoded binary message: -```mermaid -block-beta - columns 1 - A["Magic header: fig-kiwi (8 bytes)"] - B["Version (4 bytes, uint32 LE)"] - C["Schema length (4 bytes, uint32 LE)"] - D["Compressed Kiwi schema"] - E["Message length (4 bytes, uint32 LE)"] - F["Compressed Kiwi message — NodeChange[]"] - G["Blob data — images, vector networks, fonts"] -``` +| Offset | Content | +|--------|---------| +| 0 | Magic header `fig-kiwi` (8 bytes) | +| 8 | Version (4 bytes, uint32 LE) | +| 12 | Schema length (4 bytes, uint32 LE) | +| 16 | Compressed Kiwi schema | +| … | Message length (4 bytes, uint32 LE) | +| … | Compressed Kiwi message — `NodeChange[]` (entire document) | +| … | Blob data — images, vector networks, fonts | ## Import Pipeline -```mermaid -flowchart LR - A[".fig file"] --> B["Parse header"] - B --> C["Decompress Zstd"] - C --> D["Decode Kiwi schema"] - D --> E["Decode message"] - E --> F["NodeChange[]"] - F --> G["Build SceneGraph"] - G --> H["Resolve blob refs"] - H --> I["Render"] +``` +.fig file → parse header → decompress Zstd → decode Kiwi schema + → decode message → NodeChange[] → build SceneGraph + → resolve blob refs → render on canvas ``` ## Export Pipeline -```mermaid -flowchart LR - A["SceneGraph"] --> B["NodeChange[]"] - B --> C["Kiwi encode"] - C --> D["Compress"] - D --> E["Build ZIP"] - E --> F[".fig file"] +``` +SceneGraph → NodeChange[] → Kiwi encode → compress (Zstd/deflate) + → build ZIP (header + schema + message + thumbnail.png) + → write .fig file ``` Export uses S (Save) and S (Save As) with native OS dialogs on the desktop app. The exported file includes a `thumbnail.png` required by Figma for file preview. @@ -77,18 +66,7 @@ Figma's schema uses non-contiguous field IDs (e.g. 1, 2, 5, 10 with gaps). The k Copy/paste uses the same Kiwi binary encoding: -```mermaid -flowchart LR - subgraph Copy - A["Selected nodes"] --> B["Encode NodeChange[]"] - B --> C["Compress"] - C --> D["Clipboard
application/x-figma-design"] - end - subgraph Paste - D --> E["Decompress"] - E --> F["Decode Kiwi"] - F --> G["Create nodes"] - end -``` +1. **Copy** — encode selected `NodeChange[]` to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type +2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph -This enables bidirectional clipboard between OpenPencil and Figma. +Encoding happens synchronously in the copy event handler (not async Clipboard API) for browser compatibility. This enables bidirectional clipboard between OpenPencil and Figma. diff --git a/packages/docs/package.json b/packages/docs/package.json index 724a9dda8..9892af164 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -10,8 +10,6 @@ "preview": "vitepress preview" }, "devDependencies": { - "mermaid": "11.4.1", - "vitepress": "^1.6.4", - "vitepress-plugin-mermaid": "^2.0.17" + "vitepress": "^1.6.4" } } diff --git a/packages/docs/pl/reference/file-format.md b/packages/docs/pl/reference/file-format.md index 1182e4b2b..ea94b8fb6 100644 --- a/packages/docs/pl/reference/file-format.md +++ b/packages/docs/pl/reference/file-format.md @@ -4,41 +4,30 @@ A `.fig` file is a ZIP archive containing a Kiwi-encoded binary message: -```mermaid -block-beta - columns 1 - A["Magic header: fig-kiwi (8 bytes)"] - B["Version (4 bytes, uint32 LE)"] - C["Schema length (4 bytes, uint32 LE)"] - D["Compressed Kiwi schema"] - E["Message length (4 bytes, uint32 LE)"] - F["Compressed Kiwi message — NodeChange[]"] - G["Blob data — images, vector networks, fonts"] -``` +| Offset | Content | +|--------|---------| +| 0 | Magic header `fig-kiwi` (8 bytes) | +| 8 | Version (4 bytes, uint32 LE) | +| 12 | Schema length (4 bytes, uint32 LE) | +| 16 | Compressed Kiwi schema | +| … | Message length (4 bytes, uint32 LE) | +| … | Compressed Kiwi message — `NodeChange[]` (entire document) | +| … | Blob data — images, vector networks, fonts | ## Import Pipeline -```mermaid -flowchart LR - A[".fig file"] --> B["Parse header"] - B --> C["Decompress Zstd"] - C --> D["Decode Kiwi schema"] - D --> E["Decode message"] - E --> F["NodeChange[]"] - F --> G["Build SceneGraph"] - G --> H["Resolve blob refs"] - H --> I["Render"] +``` +.fig file → parse header → decompress Zstd → decode Kiwi schema + → decode message → NodeChange[] → build SceneGraph + → resolve blob refs → render on canvas ``` ## Export Pipeline -```mermaid -flowchart LR - A["SceneGraph"] --> B["NodeChange[]"] - B --> C["Kiwi encode"] - C --> D["Compress"] - D --> E["Build ZIP"] - E --> F[".fig file"] +``` +SceneGraph → NodeChange[] → Kiwi encode → compress (Zstd/deflate) + → build ZIP (header + schema + message + thumbnail.png) + → write .fig file ``` Export uses S (Save) and S (Save As) with native OS dialogs on the desktop app. The exported file includes a `thumbnail.png` required by Figma for file preview. @@ -77,18 +66,7 @@ Figma's schema uses non-contiguous field IDs (e.g. 1, 2, 5, 10 with gaps). The k Copy/paste uses the same Kiwi binary encoding: -```mermaid -flowchart LR - subgraph Copy - A["Selected nodes"] --> B["Encode NodeChange[]"] - B --> C["Compress"] - C --> D["Clipboard
application/x-figma-design"] - end - subgraph Paste - D --> E["Decompress"] - E --> F["Decode Kiwi"] - F --> G["Create nodes"] - end -``` +1. **Copy** — encode selected `NodeChange[]` to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type +2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph -This enables bidirectional clipboard between OpenPencil and Figma. +Encoding happens synchronously in the copy event handler (not async Clipboard API) for browser compatibility. This enables bidirectional clipboard between OpenPencil and Figma. diff --git a/packages/docs/reference/file-format.md b/packages/docs/reference/file-format.md index 1182e4b2b..ea94b8fb6 100644 --- a/packages/docs/reference/file-format.md +++ b/packages/docs/reference/file-format.md @@ -4,41 +4,30 @@ A `.fig` file is a ZIP archive containing a Kiwi-encoded binary message: -```mermaid -block-beta - columns 1 - A["Magic header: fig-kiwi (8 bytes)"] - B["Version (4 bytes, uint32 LE)"] - C["Schema length (4 bytes, uint32 LE)"] - D["Compressed Kiwi schema"] - E["Message length (4 bytes, uint32 LE)"] - F["Compressed Kiwi message — NodeChange[]"] - G["Blob data — images, vector networks, fonts"] -``` +| Offset | Content | +|--------|---------| +| 0 | Magic header `fig-kiwi` (8 bytes) | +| 8 | Version (4 bytes, uint32 LE) | +| 12 | Schema length (4 bytes, uint32 LE) | +| 16 | Compressed Kiwi schema | +| … | Message length (4 bytes, uint32 LE) | +| … | Compressed Kiwi message — `NodeChange[]` (entire document) | +| … | Blob data — images, vector networks, fonts | ## Import Pipeline -```mermaid -flowchart LR - A[".fig file"] --> B["Parse header"] - B --> C["Decompress Zstd"] - C --> D["Decode Kiwi schema"] - D --> E["Decode message"] - E --> F["NodeChange[]"] - F --> G["Build SceneGraph"] - G --> H["Resolve blob refs"] - H --> I["Render"] +``` +.fig file → parse header → decompress Zstd → decode Kiwi schema + → decode message → NodeChange[] → build SceneGraph + → resolve blob refs → render on canvas ``` ## Export Pipeline -```mermaid -flowchart LR - A["SceneGraph"] --> B["NodeChange[]"] - B --> C["Kiwi encode"] - C --> D["Compress"] - D --> E["Build ZIP"] - E --> F[".fig file"] +``` +SceneGraph → NodeChange[] → Kiwi encode → compress (Zstd/deflate) + → build ZIP (header + schema + message + thumbnail.png) + → write .fig file ``` Export uses S (Save) and S (Save As) with native OS dialogs on the desktop app. The exported file includes a `thumbnail.png` required by Figma for file preview. @@ -77,18 +66,7 @@ Figma's schema uses non-contiguous field IDs (e.g. 1, 2, 5, 10 with gaps). The k Copy/paste uses the same Kiwi binary encoding: -```mermaid -flowchart LR - subgraph Copy - A["Selected nodes"] --> B["Encode NodeChange[]"] - B --> C["Compress"] - C --> D["Clipboard
application/x-figma-design"] - end - subgraph Paste - D --> E["Decompress"] - E --> F["Decode Kiwi"] - F --> G["Create nodes"] - end -``` +1. **Copy** — encode selected `NodeChange[]` to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type +2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph -This enables bidirectional clipboard between OpenPencil and Figma. +Encoding happens synchronously in the copy event handler (not async Clipboard API) for browser compatibility. This enables bidirectional clipboard between OpenPencil and Figma. diff --git a/packages/docs/ru/reference/file-format.md b/packages/docs/ru/reference/file-format.md index 1182e4b2b..ea94b8fb6 100644 --- a/packages/docs/ru/reference/file-format.md +++ b/packages/docs/ru/reference/file-format.md @@ -4,41 +4,30 @@ A `.fig` file is a ZIP archive containing a Kiwi-encoded binary message: -```mermaid -block-beta - columns 1 - A["Magic header: fig-kiwi (8 bytes)"] - B["Version (4 bytes, uint32 LE)"] - C["Schema length (4 bytes, uint32 LE)"] - D["Compressed Kiwi schema"] - E["Message length (4 bytes, uint32 LE)"] - F["Compressed Kiwi message — NodeChange[]"] - G["Blob data — images, vector networks, fonts"] -``` +| Offset | Content | +|--------|---------| +| 0 | Magic header `fig-kiwi` (8 bytes) | +| 8 | Version (4 bytes, uint32 LE) | +| 12 | Schema length (4 bytes, uint32 LE) | +| 16 | Compressed Kiwi schema | +| … | Message length (4 bytes, uint32 LE) | +| … | Compressed Kiwi message — `NodeChange[]` (entire document) | +| … | Blob data — images, vector networks, fonts | ## Import Pipeline -```mermaid -flowchart LR - A[".fig file"] --> B["Parse header"] - B --> C["Decompress Zstd"] - C --> D["Decode Kiwi schema"] - D --> E["Decode message"] - E --> F["NodeChange[]"] - F --> G["Build SceneGraph"] - G --> H["Resolve blob refs"] - H --> I["Render"] +``` +.fig file → parse header → decompress Zstd → decode Kiwi schema + → decode message → NodeChange[] → build SceneGraph + → resolve blob refs → render on canvas ``` ## Export Pipeline -```mermaid -flowchart LR - A["SceneGraph"] --> B["NodeChange[]"] - B --> C["Kiwi encode"] - C --> D["Compress"] - D --> E["Build ZIP"] - E --> F[".fig file"] +``` +SceneGraph → NodeChange[] → Kiwi encode → compress (Zstd/deflate) + → build ZIP (header + schema + message + thumbnail.png) + → write .fig file ``` Export uses S (Save) and S (Save As) with native OS dialogs on the desktop app. The exported file includes a `thumbnail.png` required by Figma for file preview. @@ -77,18 +66,7 @@ Figma's schema uses non-contiguous field IDs (e.g. 1, 2, 5, 10 with gaps). The k Copy/paste uses the same Kiwi binary encoding: -```mermaid -flowchart LR - subgraph Copy - A["Selected nodes"] --> B["Encode NodeChange[]"] - B --> C["Compress"] - C --> D["Clipboard
application/x-figma-design"] - end - subgraph Paste - D --> E["Decompress"] - E --> F["Decode Kiwi"] - F --> G["Create nodes"] - end -``` +1. **Copy** — encode selected `NodeChange[]` to Kiwi binary, compress, write to clipboard as `application/x-figma-design` MIME type +2. **Paste** — read clipboard, decompress, decode Kiwi binary, create nodes in scene graph -This enables bidirectional clipboard between OpenPencil and Figma. +Encoding happens synchronously in the copy event handler (not async Clipboard API) for browser compatibility. This enables bidirectional clipboard between OpenPencil and Figma.