* fix(vue): release CanvasKit WebGL contexts when canvases go away GetWebGLContext registers a canvas's context in CanvasKit's global table, and the surface manager only called deleteContext on a failed setup. Every destroyed canvas, and every surface rebuilt after a resize or color-space change, stayed registered, and through the canvas element CanvasKit kept the closed editor's component tree, store, and graph alive. The manager now keeps the handle and releases it on rebuild and destroy. deleteContext also leaves CanvasKit holding the last current context, so when the released context was current, a parking context on a 1x1 offscreen canvas becomes current instead. * fix(core): uninstall an editor's text measurer when it closes setCanvasKit installed a global text measurer that closed over the editor and its renderer, and nothing uninstalled it, so the last editor to set up a canvas stayed alive after its tab closed and layout kept measuring with its destroyed renderer. installTextMeasurer returns an uninstall function; an editor uninstalls its measurer when disposed or when its last renderer goes, and the most recent measurer still installed takes over. * fix(app): give editor stores their own effect scope The first store is created during WorkspaceView's setup, so effects created while building it joined the view's scope. Their cleanups stayed registered there after the store was disposed and kept the startup document alive for the life of the app. Stores now build inside a detached effect scope that dispose stops. * fix(app): follow the active tab in app-level editor subscriptions App.vue provided a proxy that resolved to whichever store was active when a property was read, so app-level composables such as the menu and keyboard commands subscribed once to the startup store. They missed events from later documents and kept that store alive, and Undo and Redo availability came from the first document's history. The app-level editor now moves event subscriptions to the active store, and each tab's editor UI gets its own store through EditorTabScope, so per-tab components stay bound to their document when it closes. Selection capabilities read the undo history lazily instead of capturing the first store's manager. * fix(app): stop keeping closed documents in chat history and startup The chat history kept the last editor it served only to compare it with the next one; it now holds it weakly. WorkspaceView's first tab was a top-level setup binding, which Vue keeps on the instance; it is now block-scoped. * test(app): check that documents closed in tabs are released Opens a document in a new tab three times, closes each with discard, forces garbage collection, and checks that weak references to the closed graphs clear. On master all three graphs stay alive. * refactor(app): provide the tab's store from a tab-keyed editor view EditorTabScope existed only to provide a tab's store to its editor UI. WorkspaceView now keys EditorWorkspace by tab, whose contents were already remounted per tab, so the view provides the tab's store in its own setup and the wrapper component goes away. * fix(app): stop a store's effect scope when building the store throws Effects created before the throw would otherwise stay alive with the partial store, which no caller can dispose. * test(app): avoid empty callbacks in the store scope tests |
||
|---|---|---|
| .. | ||
| assets | ||
| src | ||
| tests | ||
| AGENTS.md | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsconfig.test.json | ||
| tsdown.config.ts | ||
@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.
- Programmable overview and SDK docs: https://openpencil.dev/programmable/
- Source and issues: https://github.com/open-pencil/open-pencil
MIT License.