openpencil/packages/core
Danila Poyarkov cb7018a2d7
perf: stop repeating glyph coverage and component sync during layout (#957)
* perf(text): keep glyph coverage when layout resizes a text box

Every layout write invalidated a text node's coverage record by id, and the record compared its width and height, so each measurement shaped the text twice. Coverage now ignores the box size unless the text is truncated, and an update that changes only fields coverage compares keeps the record. A demo load went from about 38,000 coverage checks with 228 hits to one shaping per text node.

* perf(editor): skip component sync for layout's own writes

Layout lays out instances itself, and the edit that made it run has already scheduled its sync. Its size and position writes scheduled about 56,000 more, so each yield of an async build re-synchronised components and re-laid out whole pages.
2026-10-07 18:46:56 +00:00
..
assets fix(fonts): include bundled Arabic fallback asset 2026-05-18 01:04:29 +03:00
src perf: stop repeating glyph coverage and component sync during layout (#957) 2026-10-07 18:46:56 +00:00
tests perf: stop repeating glyph coverage and component sync during layout (#957) 2026-10-07 18:46:56 +00:00
AGENTS.md refactor(canvas): draw screen-sized chrome through one outline helper (#947) 2026-10-07 18:37:05 +00:00
package.json feat: behaviours and preview mode (#893) 2026-10-06 13:23:05 +00:00
README.md feat: behaviours and preview mode (#893) 2026-10-06 13:23:05 +00:00
tsconfig.json fix: explain unsupported browsers instead of a blank window (#745) 2026-09-22 14:40:59 +04:00
tsconfig.test.json test(core): move the editor suite into the package (#792) 2026-09-30 10:22:42 +04:00
tsdown.config.ts fix(figma-api): validate effects like Figma (#794) 2026-09-30 21:18:20 +04:00

@open-pencil/core

Editor engine for OpenPencil: the CanvasKit (Skia WASM) renderer, Yoga layout, the framework-agnostic editor with undo and selection, the Figma Plugin API compatibility layer, the AI/MCP tool definitions, clipboard and vector conversion, and format-neutral document I/O.

It depends on @open-pencil/scene-graph, @open-pencil/pen, @open-pencil/kiwi, and @open-pencil/fig, and keeps browser DOM out so it runs in the app, the CLI, the MCP server, and headless scripts alike.

Import the root barrel or the targeted subpaths listed in package.json exports, for example @open-pencil/core/io, @open-pencil/core/geometry, and @open-pencil/core/canvaskit.

Scripts get two globals through compileScript from @open-pencil/core/tools: figma, the Figma Plugin API over a document, and openpencil (OpenPencilAPI from @open-pencil/core/openpencil-api), what OpenPencil adds to it in the same style, such as making a component behave as a Reka UI control:

import { FigmaAPI } from '@open-pencil/core/figma-api'
import { compileScript } from '@open-pencil/core/tools'

await compileScript(`
  const set = figma.currentPage.findOne((n) => n.name === 'Switch')
  openpencil.setBehaviour(set, { kind: 'switch', values: { value: 'State' } })
`)(new FigmaAPI(graph))

MIT License.