From 7527d3654760b36539de2474255c8bb9c1d976ee Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Sat, 1 Mar 2025 08:10:41 +0000 Subject: [PATCH] feat: prevent cycle emit in slot (#10539) --- .../global/src/__tests__/slot.unit.spec.ts | 9 +++++++ blocksuite/framework/global/src/utils/slot.ts | 24 ++++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/blocksuite/framework/global/src/__tests__/slot.unit.spec.ts b/blocksuite/framework/global/src/__tests__/slot.unit.spec.ts index 61a84358d9..7ce32c93b3 100644 --- a/blocksuite/framework/global/src/__tests__/slot.unit.spec.ts +++ b/blocksuite/framework/global/src/__tests__/slot.unit.spec.ts @@ -43,4 +43,13 @@ describe('slot', () => { slot.emit(); expect(callback).toBeCalledTimes(0); }); + + test('cycle emit', () => { + const slot = new Slot(); + const callback = vi.fn(v => slot.emit(v + 1)); + slot.on(callback); + slot.emit(0); + expect(callback).toBeCalledTimes(1); + expect(callback).toBeCalledWith(0); + }); }); diff --git a/blocksuite/framework/global/src/utils/slot.ts b/blocksuite/framework/global/src/utils/slot.ts index c276a3a618..beac24d955 100644 --- a/blocksuite/framework/global/src/utils/slot.ts +++ b/blocksuite/framework/global/src/utils/slot.ts @@ -14,16 +14,24 @@ export class Slot implements Disposable { } emit(v: T) { + // Prevent recursive emit calls + if (this._emitting) { + return; + } + const prevEmitting = this._emitting; this._emitting = true; - this._callbacks.forEach(f => { - try { - f(v); - } catch (err) { - console.error(err); - } - }); - this._emitting = prevEmitting; + try { + this._callbacks.forEach(f => { + try { + f(v); + } catch (err) { + console.error(err); + } + }); + } finally { + this._emitting = prevEmitting; + } } on(callback: (v: T) => unknown): Disposable {