feat: cascading events
This commit is contained in:
@@ -21,6 +21,7 @@ const logger_debug = getLogger('debug:BlockDB:block');
|
|||||||
|
|
||||||
const _GET_BLOCK = Symbol('GET_BLOCK');
|
const _GET_BLOCK = Symbol('GET_BLOCK');
|
||||||
const _SET_PARENT = Symbol('SET_PARENT');
|
const _SET_PARENT = Symbol('SET_PARENT');
|
||||||
|
const _EMIT_EVENT = Symbol('EMIT_EVENT');
|
||||||
|
|
||||||
export class AbstractBlock<
|
export class AbstractBlock<
|
||||||
B extends BlockInstance<C>,
|
B extends BlockInstance<C>,
|
||||||
@@ -30,7 +31,12 @@ export class AbstractBlock<
|
|||||||
private readonly _block: BlockInstance<C>;
|
private readonly _block: BlockInstance<C>;
|
||||||
private readonly _history: HistoryManager;
|
private readonly _history: HistoryManager;
|
||||||
private readonly _root: AbstractBlock<B, C> | undefined;
|
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 _parent: AbstractBlock<B, C> | undefined;
|
||||||
private _changeParent?: () => void;
|
private _changeParent?: () => void;
|
||||||
@@ -45,7 +51,19 @@ export class AbstractBlock<
|
|||||||
this._history = this._block.scopedHistory([this._id]);
|
this._history = this._block.scopedHistory([this._id]);
|
||||||
|
|
||||||
this._root = root;
|
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}`);
|
JWT_DEV && logger_debug(`init: exists ${this._id}`);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
@@ -83,19 +101,11 @@ export class AbstractBlock<
|
|||||||
name: string,
|
name: string,
|
||||||
callback: BlockListener
|
callback: BlockListener
|
||||||
) {
|
) {
|
||||||
if (event === 'parent') {
|
this._listeners[event]?.set(name, callback);
|
||||||
this._parentListener.set(name, callback);
|
|
||||||
} else {
|
|
||||||
this._block.on(event, name, callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public off(event: 'content' | 'children' | 'parent', name: string) {
|
public off(event: 'content' | 'children' | 'parent', name: string) {
|
||||||
if (event === 'parent') {
|
this._listeners[event]?.delete(name);
|
||||||
this._parentListener.delete(name);
|
|
||||||
} else {
|
|
||||||
this._block.off(event, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public addChildrenListener(name: string, listener: BlockListener) {
|
public addChildrenListener(name: string, listener: BlockListener) {
|
||||||
@@ -189,11 +199,24 @@ export class AbstractBlock<
|
|||||||
const states: Map<string, 'update' | 'delete'> = new Map([
|
const states: Map<string, 'update' | 'delete'> = new Map([
|
||||||
[parentId, type],
|
[parentId, type],
|
||||||
]);
|
]);
|
||||||
for (const listener of this._parentListener.values()) {
|
for (const listener of this._listeners.parent.values()) {
|
||||||
listener(states);
|
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>) {
|
private _refreshParent(parent: AbstractBlock<B, C>) {
|
||||||
this._changeParent?.();
|
this._changeParent?.();
|
||||||
parent.addChildrenListener(this._id, states => {
|
parent.addChildrenListener(this._id, states => {
|
||||||
|
|||||||
@@ -123,8 +123,8 @@ export class BlockIndexer<
|
|||||||
constructor(
|
constructor(
|
||||||
adapter: A,
|
adapter: A,
|
||||||
workspace: string,
|
workspace: string,
|
||||||
block_builder: (block: BlockInstance<C>) => Promise<BaseBlock<B, C>>,
|
blockBuilder: (block: BlockInstance<C>) => Promise<BaseBlock<B, C>>,
|
||||||
event_bus: BlockEventBus
|
eventBus: BlockEventBus
|
||||||
) {
|
) {
|
||||||
this._adapter = adapter;
|
this._adapter = adapter;
|
||||||
this._idb = initIndexIdb(workspace);
|
this._idb = initIndexIdb(workspace);
|
||||||
@@ -144,8 +144,8 @@ export class BlockIndexer<
|
|||||||
ttl: 1000 * 60 * 30,
|
ttl: 1000 * 60 * 30,
|
||||||
});
|
});
|
||||||
|
|
||||||
this._blockBuilder = block_builder;
|
this._blockBuilder = blockBuilder;
|
||||||
this._eventBus = event_bus;
|
this._eventBus = eventBus;
|
||||||
|
|
||||||
this._delayIndex = { documents: new Map() };
|
this._delayIndex = { documents: new Map() };
|
||||||
|
|
||||||
|
|||||||
@@ -679,7 +679,7 @@ export type {
|
|||||||
ReadableContentExporter as BlockContentExporter,
|
ReadableContentExporter as BlockContentExporter,
|
||||||
} from './block';
|
} from './block';
|
||||||
export { BlockTypes, BucketBackend as BlockBackend } from './types';
|
export { BlockTypes, BucketBackend as BlockBackend } from './types';
|
||||||
export type { BlockTypeKeys } from './types';
|
export type { BlockFlavorKeys, BlockTypeKeys } from './types';
|
||||||
export { isBlock } from './utils';
|
export { isBlock } from './utils';
|
||||||
export type {
|
export type {
|
||||||
ArrayOperation,
|
ArrayOperation,
|
||||||
|
|||||||
Reference in New Issue
Block a user