Repository navigation
Conversation
- Core#destroy(): destroys plugins in reverse construction order and unregisters their public APIs, then UndoRedoManager, SelectionManager, BlockRenderer and the adapter. Idempotent, safe before and during initialize(), never mutates the model. use()/initialize() throw after it. - EditorJS#destroy() delegates to Core. - BlockRenderer keeps each block's tool instance and destroys it on block removal and on teardown; a render settling after teardown is dropped. - Optional destroy() on BlockTool/InlineTool; throwaway inline tool instances (SelectionManager, ToolsManager validation) are destroyed right after use. - Listeners are released through AbortController: onUpdate/onCaretUpdate subscribe through their own controller, BlockToolAdapter owns one and exposes a protected signal to subclasses, core services abort theirs on destroy. Model addEventListener overloads accept options. Part of the editor-destroy OpenSpec change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Cover teardown error logging, services that were never resolved, an
adapter without destroy(), and blocks removed without a tracked tool.
- Cover ToolsManager inline tool validation around the destroyed
validation instance.
- Drop the redundant destroyed guard in Core.destroy(): clearing plugin
instances and services already makes a second call a no-op.
- Drop { once: true } on the BlockToolAdapter abort listener: a signal
aborts only once.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tError - Core.initialize() rejects with a DOMException named AbortError when destroy() runs while tools are being prepared, instead of resolving. - The EditorJS bundle handles its own ready promise: an AbortError is ignored, any other initialization error is logged, so neither is reported as an unhandled rejection. Awaiting isReady still rejects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Unit Tests
Mutation Tests
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
First implementation step of the
editor-destroyOpenSpec change (spec PR #195, the base of this one). Adds the editor teardown lifecycle and the API changes it needs; the adapters/UI/plugins side follows in a stacked PR.What Changes
Core#destroy(): plugins in reverse construction order (destroy?.()+PluginRegistry.unregister), thenUndoRedoManager,SelectionManager,BlockRenderer, then the adapter (destroy?.()— it becomes required in the next PR together withDOMAdapters.destroy()). Each step runs through a helper that logs and continues. Services resolved ininitialize()are recorded in#services, so teardown never constructs one. A second call is a no-op because instances and services are cleared.use()/initialize()throw afterwards.initialize()rejects with aDOMExceptionnamedAbortErrorinstead of booting the document or dispatchingcore:ready.EditorJS#destroy()delegates toCore. The bundle attachesreportUnlessAborted()to its ready promise:AbortErroris ignored, other init errors are logged, so nothing is reported as an unhandled rejection; awaitingisReadystill rejects.BlockRendererkeeps each block's tool instance; destroys it on block removal and on teardown. A render that settles after teardown dispatches nothing.destroy()onBlockTool/InlineTool. Throwaway inline instances (SelectionManager.applyInlineTool,ToolsManagervalidation) are destroyed right after use.AbortController:onUpdate/onCaretUpdatesubscribe through their own controller (signatures unchanged);UndoRedoManager,SelectionManager,BlockRendererabort one controller each;BlockToolAdapterowns its controller and exposesprotected signalto subclasses.EditorJSModel's typedaddEventListeneroverloads acceptoptions.Verification
-w): all mutants killed incore, and insdk/editorjsvia an ad-hoc run (those packages have no Stryker config).modelchanges are type-only. Packages' ownyarn test:mutationspass.AbortErrorhandling (including that it is not left unhandled), andToolsManagervalidation.Notes
ToolsManager's inline-toolrendercheck is pinned by tests as-is; removing it is tracked on the board ("Remove inverted inline tool render check in ToolsManager").Stack
🤖 Generated with Claude Code