* perf(scene-graph): give imported nodes the shape every node shares createDefaultNode had no default for booleanOperation, and the .fig importer sets that key on every node. A key outside an object's initial shape turns it into a JavaScriptCore dictionary, so every imported node had its own structure and dictionary property storage. Fully loading material3.fig took 3.7 GB RSS in Bun; with the default it takes 2.8 GB, with 0.5 GB less JS heap and 0.46 GB less memory outside it. V8 keeps these objects fast either way. The defaults now must name every SceneNode field, which the compiler enforces, and a test checks that imported nodes carry exactly the default fields. booleanOperation states the explicit undefined the importer already stores. * fix(scene-graph): require booleanOperation and compare node keys in order Every SceneNode field is required except booleanOperation, so a typed producer could still omit it and build a node with a different shape. It is now required, with undefined still meaning no operation. The node-shape test compares keys in insertion order, since JavaScriptCore lays out the same keys added in another order as a different shape. The changelog entry no longer quotes the Bun measurement as figures for the macOS app and Safari, and records the type change as breaking. |
||
|---|---|---|
| .. | ||
| docs | ||
| scripts | ||
| src | ||
| tests | ||
| AGENTS.md | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsconfig.test.json | ||
| tsdown.config.ts | ||
@open-pencil/fig
.fig file-format package for OpenPencil.
The package owns the outer .fig archive boundary and is the staged home for Figma-specific
SceneGraph conversion policy. Production SceneGraph read/write remains available through
@open-pencil/core/io while conversion modules move behind this package's public API.
Current ownership:
- Complete
.figarchive parsing throughparseFigBuffer() .figarchive assembly throughwriteFigArchive()- Canvas payload and image resource handling
readFigContainer()/writeFigContainer()helpers for rawfig-kiwipayloads.figsource and archive result types- NodeChange-to-SceneGraph property conversion, including styles, plugin metadata, text, paint, vector, and font policy, through
@open-pencil/fig/node-change - Component-property, symbol-override, derived-symbol-data, and instance synchronization policy through
@open-pencil/fig/instance-overrides - Effective raw-metadata precedence and invalidation over SceneGraph's format-neutral edited-field tracking
- SceneGraph-to-
NodeChangeexport conversion with an explicit glyph-outline runtime service - Package-local archive, conversion, instance, export, and dist smoke tests
Architecture documentation
Start with the package docs for the source model, instance evaluation, materialization, document sessions, export, and validation contracts.
Planned ownership:
- Oracle-backed
.figfixtures
Non-goals:
- Generic Kiwi schema/runtime internals — use
@open-pencil/kiwi - Format-neutral IO registration, export targeting, CanvasKit thumbnails, or browser workers — use
@open-pencil/core/io - Editor actions, renderer behavior, Vue/app UI, CLI formatting, or MCP transport
This follows the existing @open-pencil/pen pattern: a format package owns its source model/parser
and SceneGraph policy, while core registers it in the shared IO system.
Checks
cd packages/fig
bun run check