feat: cascading events

This commit is contained in:
DarkSky 2022-08-24 17:37:16 +08:00
parent 712566ca84
commit 6ac1f618f0
3 changed files with 41 additions and 18 deletions

View File

@ -21,6 +21,7 @@ const logger_debug = getLogger('debug:BlockDB:block');
const _GET_BLOCK = Symbol('GET_BLOCK');
const _SET_PARENT = Symbol('SET_PARENT');
const _EMIT_EVENT = Symbol('EMIT_EVENT');
export class AbstractBlock<
B extends BlockInstance<C>,
@ -30,7 +31,12 @@ export class AbstractBlock<
private readonly _block: BlockInstance<C>;
private readonly _history: HistoryManager;
private readonly _root: AbstractBlock<B, C> | undefined;
private readonly _parentListener: Map<string, BlockListener>;
private readonly _listeners: {
cascade: Map<string, BlockListener>;
children: Map<string, BlockListener>;
content: Map<string, BlockListener>;
parent: Map<string, BlockListener>;
};
private _parent: AbstractBlock<B, C> | undefined;
private _changeParent?: () => void;
@ -45,7 +51,19 @@ export class AbstractBlock<
this._history = this._block.scopedHistory([this._id]);
this._root = root;
this._parentListener = new Map();
this._listeners = {
cascade: new Map(),
children: new Map(),
content: new Map(),
parent: new Map(),
};
this._block.on('content', 'internal', states =>
this[_EMIT_EVENT]('content', states)
);
this._block.on('children', 'internal', states =>
this[_EMIT_EVENT]('children', states)
);
JWT_DEV && logger_debug(`init: exists ${this._id}`);
if (parent) {
@ -83,19 +101,11 @@ export class AbstractBlock<
name: string,
callback: BlockListener
) {
if (event === 'parent') {
this._parentListener.set(name, callback);
} else {
this._block.on(event, name, callback);
}
this._listeners[event]?.set(name, callback);
}
public off(event: 'content' | 'children' | 'parent', name: string) {
if (event === 'parent') {
this._parentListener.delete(name);
} else {
this._block.off(event, name);
}
this._listeners[event]?.delete(name);
}
public addChildrenListener(name: string, listener: BlockListener) {
@ -189,11 +199,24 @@ export class AbstractBlock<
const states: Map<string, 'update' | 'delete'> = new Map([
[parentId, type],
]);
for (const listener of this._parentListener.values()) {
for (const listener of this._listeners.parent.values()) {
listener(states);
}
}
[_EMIT_EVENT](
event: 'cascade' | 'content' | 'children',
states: Parameters<BlockListener>[0]
) {
const listeners = this._listeners[event];
if (listeners) {
for (const listener of listeners.values()) {
listener(states);
}
}
this._parent?.[_EMIT_EVENT]('cascade', states);
}
private _refreshParent(parent: AbstractBlock<B, C>) {
this._changeParent?.();
parent.addChildrenListener(this._id, states => {

View File

@ -123,8 +123,8 @@ export class BlockIndexer<
constructor(
adapter: A,
workspace: string,
block_builder: (block: BlockInstance<C>) => Promise<BaseBlock<B, C>>,
event_bus: BlockEventBus
blockBuilder: (block: BlockInstance<C>) => Promise<BaseBlock<B, C>>,
eventBus: BlockEventBus
) {
this._adapter = adapter;
this._idb = initIndexIdb(workspace);
@ -144,8 +144,8 @@ export class BlockIndexer<
ttl: 1000 * 60 * 30,
});
this._blockBuilder = block_builder;
this._eventBus = event_bus;
this._blockBuilder = blockBuilder;
this._eventBus = eventBus;
this._delayIndex = { documents: new Map() };

View File

@ -679,7 +679,7 @@ export type {
ReadableContentExporter as BlockContentExporter,
} from './block';
export { BlockTypes, BucketBackend as BlockBackend } from './types';
export type { BlockTypeKeys } from './types';
export type { BlockFlavorKeys, BlockTypeKeys } from './types';
export { isBlock } from './utils';
export type {
ArrayOperation,