-
-
Notifications
You must be signed in to change notification settings - Fork 520
Open
Description
File
blocksuite/framework/store/src/model/block/block-model.ts
Describe the bug
In BlockModel, Yjs observers are registered via
yBlock.get('sys:children').observe(...)yBlock.observe(...)
but there is no corresponding unobserve call when the block is disposed.
This can cause memory leaks and lingering event listeners, since the observer closures hold references to the BlockModel instance even after the block is deleted.
To Reproduce
- Create a block that initializes
BlockModel. - Delete/dispose the block.
- Observe that the RxJS subscriptions are cleaned up (
dispose()is called), but Yjs observers remain active.
Expected behavior
Yjs observers should be properly removed in dispose() or [Symbol.dispose] so that:
- No memory leaks occur.
- Deleted blocks do not continue reacting to Yjs updates.
Suggested fix
Store observer references and call unobserve during cleanup:
// inside BlockModel
private _yChildren?: Y.Array<string>;
private _onYChildren?: (e: Y.YArrayEvent<string>) => void;
private _onYBlock?: (e: Y.YMapEvent<unknown>) => void;
private _cleanupYObservers() {
if (this._yChildren && this._onYChildren) {
this._yChildren.unobserve(this._onYChildren);
}
if (this._onYBlock) {
this.yBlock.unobserve(this._onYBlock);
}
this._onYChildren = undefined;
this._onYBlock = undefined;
this._yChildren = undefined;
}
dispose() {
this._cleanupYObservers();
this.created.complete();
this.deleted.complete();
this.propsUpdated.complete();
}Environment
- affine version: (commit hash / branch)
- Browser/Node: (if applicable)
Additional context
This issue may not surface immediately, but with long editing sessions and frequent block creation/deletion, it can lead to significant memory leaks.
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
No status