fig-kiwi is the magic header string in .fig files, not a format name. The format is Kiwi binary — used for both .fig files and clipboard.
52 lines
2.5 KiB
Markdown
52 lines
2.5 KiB
Markdown
# kiwi-codec Specification
|
|
|
|
## Purpose
|
|
Vendored Kiwi binary codec for Figma's 194-definition schema. Encodes/decodes NodeChange messages, handles sparse field IDs, and integrates Zstd compression for .fig file compatibility.
|
|
## Requirements
|
|
### Requirement: Vendored kiwi-schema
|
|
The project SHALL vendor kiwi-schema (from evanw/kiwi) with patches for ESM module format and sparse field ID handling.
|
|
|
|
#### Scenario: ESM import
|
|
- **WHEN** kiwi-schema is imported as an ES module
|
|
- **THEN** all encoder/decoder functions are available without CommonJS compatibility issues
|
|
|
|
### Requirement: Kiwi binary codec
|
|
The codec SHALL encode and decode Figma's 194-definition Kiwi schema including the NodeChange message type with ~390 fields.
|
|
|
|
#### Scenario: Decode a Kiwi message
|
|
- **WHEN** a compressed Kiwi binary is provided
|
|
- **THEN** the codec decodes it into a structured NodeChange[] array
|
|
|
|
#### Scenario: Encode a Kiwi message
|
|
- **WHEN** a NodeChange[] array is provided
|
|
- **THEN** the codec encodes it into Kiwi binary format
|
|
|
|
### Requirement: Sparse field ID support
|
|
The kiwi-schema parser SHALL handle sparse field IDs (non-contiguous field numbering) used by Figma's schema.
|
|
|
|
#### Scenario: Parse schema with sparse IDs
|
|
- **WHEN** a Kiwi schema definition has field IDs like 1, 2, 5, 10 (with gaps)
|
|
- **THEN** the parser correctly handles all fields without errors
|
|
|
|
### Requirement: Zstd compression
|
|
The codec layer SHALL support Zstd decompression for .fig file payloads and compression for clipboard/export.
|
|
|
|
#### Scenario: Decompress .fig payload
|
|
- **WHEN** a Zstd-compressed Kiwi payload is encountered in a .fig file
|
|
- **THEN** it is decompressed before Kiwi decoding
|
|
|
|
### Requirement: Kiwi encoding for .fig export
|
|
The Kiwi codec SHALL support encoding NodeChange[] back to Kiwi binary format for .fig export. The encoding path mirrors the decoding path: scene graph → NodeChange[] → Kiwi encode → compress → ZIP with header.
|
|
|
|
#### Scenario: Encode scene graph to Kiwi binary
|
|
- **WHEN** the editor exports a document
|
|
- **THEN** all nodes are encoded as NodeChange messages using the Kiwi schema and the binary output is a valid Kiwi payload
|
|
|
|
### Requirement: .fig ZIP built in Rust
|
|
On the desktop app, the .fig ZIP archive SHALL be assembled in Rust instead of JavaScript (fflate) for better performance and correct Zstd framing (content size in header).
|
|
|
|
#### Scenario: Rust ZIP assembly
|
|
- **WHEN** a .fig file is exported on the desktop app
|
|
- **THEN** the ZIP is assembled by the Rust backend with correct Zstd frame headers
|
|
|