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.
File
blocksuite/framework/store/src/model/block/block-model.tsDescribe the bug
In
BlockModel, Yjs observers are registered viayBlock.get('sys:children').observe(...)yBlock.observe(...)but there is no corresponding
unobservecall when the block is disposed.This can cause memory leaks and lingering event listeners, since the observer closures hold references to the
BlockModelinstance even after the block is deleted.To Reproduce
BlockModel.dispose()is called), but Yjs observers remain active.Expected behavior
Yjs observers should be properly removed in
dispose()or[Symbol.dispose]so that:Suggested fix
Store observer references and call
unobserveduring cleanup:Environment
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.