From ffdf247517ff611eb16d05dcaa7e61cb1498672c Mon Sep 17 00:00:00 2001 From: DarkSky Date: Wed, 10 Aug 2022 17:44:30 +0800 Subject: [PATCH] feat: parent refresh event --- .../jwt/src/adapter/yjs/listener.ts | 6 +- libs/datasource/jwt/src/block/abstract.ts | 83 ++++++++++--------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/libs/datasource/jwt/src/adapter/yjs/listener.ts b/libs/datasource/jwt/src/adapter/yjs/listener.ts index d9b4de123b..36c203bbce 100644 --- a/libs/datasource/jwt/src/adapter/yjs/listener.ts +++ b/libs/datasource/jwt/src/adapter/yjs/listener.ts @@ -67,8 +67,12 @@ export function ChildrenListenerHandler( const keys = Array.from(event.keys.entries()).map( ([key, { action }]) => [key, action] as [string, ChangedStateKeys] ); + const deleted = Array.from(event.changes.deleted.values()) + .flatMap(val => val.content.getContent() as string[]) + .filter(v => v) + .map(k => [k, 'delete'] as [string, ChangedStateKeys]); for (const listener of listeners.values()) { - EmitEvents(keys, listener); + EmitEvents([...keys, ...deleted], listener); } } } diff --git a/libs/datasource/jwt/src/block/abstract.ts b/libs/datasource/jwt/src/block/abstract.ts index 0225aa0897..468fd53321 100644 --- a/libs/datasource/jwt/src/block/abstract.ts +++ b/libs/datasource/jwt/src/block/abstract.ts @@ -27,12 +27,13 @@ export class AbstractBlock< C extends ContentOperation > { private readonly _id: string; - readonly #block: BlockInstance; + private readonly _block: BlockInstance; private readonly _history: HistoryManager; private readonly _root?: AbstractBlock; private readonly _parentListener: Map; - _parent?: AbstractBlock; + private _parent?: AbstractBlock; + private _changeParent?: () => void; constructor( block: B, @@ -40,20 +41,14 @@ export class AbstractBlock< parent?: AbstractBlock ) { this._id = block.id; - this.#block = block; - this._history = this.#block.scopedHistory([this._id]); + this._block = block; + this._history = this._block.scopedHistory([this._id]); this._root = root; this._parentListener = new Map(); - this._parent = parent; + JWT_DEV && logger_debug(`init: exists ${this._id}`); - if (parent) { - parent.addChildrenListener(this._id, states => { - if (states.get(this._id) === 'delete') { - this._emitParent(parent._id, 'delete'); - } - }); - } + if (parent) this._refreshParent(parent); } public get root() { @@ -66,7 +61,7 @@ export class AbstractBlock< protected _getParentPage(warning = true): string | undefined { if (this.flavor === 'page') { - return this.#block.id; + return this._block.id; } else if (!this._parent) { if (warning && this.flavor !== 'workspace') { console.warn('parent not found'); @@ -89,7 +84,7 @@ export class AbstractBlock< if (event === 'parent') { this._parentListener.set(name, callback); } else { - this.#block.on(event, name, callback); + this._block.on(event, name, callback); } } @@ -97,42 +92,40 @@ export class AbstractBlock< if (event === 'parent') { this._parentListener.delete(name); } else { - this.#block.off(event, name); + this._block.off(event, name); } } public addChildrenListener(name: string, listener: BlockListener) { - this.#block.addChildrenListener(name, listener); + this._block.addChildrenListener(name, listener); } public removeChildrenListener(name: string) { - this.#block.removeChildrenListener(name); + this._block.removeChildrenListener(name); } public addContentListener(name: string, listener: BlockListener) { - this.#block.addContentListener(name, listener); + this._block.addContentListener(name, listener); } public removeContentListener(name: string) { - this.#block.removeContentListener(name); + this._block.removeContentListener(name); } public getContent< T extends ContentTypes = ContentOperation >(): MapOperation { - if (this.#block.type === BlockTypes.block) { - return this.#block.content.asMap() as MapOperation; + if (this._block.type === BlockTypes.block) { + return this._block.content.asMap() as MapOperation; } throw new Error( - `this block not a structured block: ${this._id}, ${ - this.#block.type - }` + `this block not a structured block: ${this._id}, ${this._block.type}` ); } public getBinary(): ArrayBuffer | undefined { - if (this.#block.type === BlockTypes.binary) { - return this.#block.content.asArray()?.get(0); + if (this._block.type === BlockTypes.binary) { + return this._block.content.asArray()?.get(0); } throw new Error('this block not a binary block'); } @@ -162,7 +155,7 @@ export class AbstractBlock< // Last update UTC time public get lastUpdated(): number { - return this.#block.updated || this.#block.created; + return this._block.updated || this._block.created; } private get last_updated_date(): string | undefined { @@ -171,7 +164,7 @@ export class AbstractBlock< // create UTC time public get created(): number { - return this.#block.created; + return this._block.created; } private get created_date(): string | undefined { @@ -180,11 +173,11 @@ export class AbstractBlock< // creator id public get creator(): string | undefined { - return this.#block.creator; + return this._block.creator; } [_GET_BLOCK]() { - return this.#block; + return this._block; } private _emitParent( @@ -199,8 +192,20 @@ export class AbstractBlock< } } - [_SET_PARENT](parent: AbstractBlock) { + private _refreshParent(parent: AbstractBlock) { + this._changeParent?.(); + parent.addChildrenListener(this._id, states => { + if (states.get(this._id) === 'delete') { + this._emitParent(parent._id, 'delete'); + } + }); + this._parent = parent; + this._changeParent = () => parent.removeChildrenListener(this._id); + } + + [_SET_PARENT](parent: AbstractBlock) { + this._refreshParent(parent); this._emitParent(parent.id); } @@ -234,23 +239,23 @@ export class AbstractBlock< * current block type */ public get type(): typeof BlockTypes[BlockTypeKeys] { - return this.#block.type; + return this._block.type; } /** * current block flavor */ public get flavor(): typeof BlockFlavors[BlockFlavorKeys] { - return this.#block.flavor; + return this._block.flavor; } // TODO: flavor needs optimization setFlavor(flavor: typeof BlockFlavors[BlockFlavorKeys]) { - this.#block.setFlavor(flavor); + this._block.setFlavor(flavor); } public get children(): string[] { - return this.#block.children; + return this._block.children; } /** @@ -274,12 +279,12 @@ export class AbstractBlock< throw new Error('insertChildren: binary not allow insert children'); } - this.#block.insertChildren(block[_GET_BLOCK](), position); + this._block.insertChildren(block[_GET_BLOCK](), position); block[_SET_PARENT](this); } public hasChildren(id: string): boolean { - return this.#block.hasChildren(id); + return this._block.hasChildren(id); } /** @@ -289,11 +294,11 @@ export class AbstractBlock< */ protected get_children(blockId?: string): BlockInstance[] { JWT_DEV && logger(`get children: ${blockId}`); - return this.#block.getChildren([blockId]); + return this._block.getChildren([blockId]); } public removeChildren(blockId?: string) { - this.#block.removeChildren([blockId]); + this._block.removeChildren([blockId]); } public remove() {