init: the first public commit for AFFiNE

This commit is contained in:
DarkSky
2022-07-22 15:49:21 +08:00
commit e3e3741393
1451 changed files with 108124 additions and 0 deletions
+107
View File
@@ -0,0 +1,107 @@
import { debounce } from 'ts-debounce';
import { getLogger } from './index';
declare const JWT_DEV: boolean;
const logger = getLogger('BlockDB:event_bus');
export class BlockEventBus {
readonly #event_bus: EventTarget;
readonly #event_callback_cache: Map<string, any>;
readonly #scoped_cache: Map<string, BlockScopedEventBus<any>>;
constructor(event_bus?: EventTarget) {
this.#event_bus = event_bus || new EventTarget();
this.#event_callback_cache = new Map();
this.#scoped_cache = new Map();
}
protected on_listener(
topic: string,
name: string,
listener: (e: Event) => void
) {
const handler_name = `${topic}/${name}`;
if (!this.#event_callback_cache.has(handler_name)) {
this.#event_bus.addEventListener(topic, listener);
this.#event_callback_cache.set(handler_name, listener);
} else {
JWT_DEV && logger(`event handler ${handler_name} is existing`);
}
}
protected off_listener(topic: string, name: string) {
const handler_name = `${topic}/${name}`;
const listener = this.#event_callback_cache.get(handler_name);
if (listener) {
this.#event_bus.removeEventListener(topic, listener);
this.#event_callback_cache.delete(handler_name);
} else {
JWT_DEV && logger(`event handler ${handler_name} is not existing`);
}
}
protected has_listener(topic: string, name: string) {
return this.#event_callback_cache.has(`${topic}/${name}`);
}
protected emit_event<T>(topic: string, detail?: T) {
this.#event_bus.dispatchEvent(new CustomEvent(topic, { detail }));
}
topic<T = unknown>(topic: string): BlockScopedEventBus<T> {
return (
this.#scoped_cache.get(topic) ||
new BlockScopedEventBus<T>(topic, this.#event_bus)
);
}
}
type DebounceOptions = {
wait: number;
maxWait?: number;
};
type ListenerOptions = {
debounce?: DebounceOptions;
};
class BlockScopedEventBus<T> extends BlockEventBus {
readonly #topic: string;
constructor(topic: string, event_bus?: EventTarget) {
super(event_bus);
this.#topic = topic;
}
on(
name: string,
listener: ((e: T) => Promise<void>) | ((e: T) => void),
options?: ListenerOptions
) {
if (options?.debounce) {
const { wait, maxWait } = options.debounce;
const debounced = debounce(listener, wait, { maxWait });
this.on_listener(this.#topic, name, e => {
debounced((e as CustomEvent)?.detail);
});
} else {
this.on_listener(this.#topic, name, e => {
listener((e as CustomEvent)?.detail);
});
}
}
off(name: string) {
this.off_listener(this.#topic, name);
}
has(name: string) {
return this.has_listener(this.#topic, name);
}
emit(detail?: T) {
this.emit_event(this.#topic, detail);
}
}
+57
View File
@@ -0,0 +1,57 @@
import { Buffer } from 'buffer';
import debug from 'debug';
import { enableAllPlugins } from 'immer';
import { SHAKE } from 'sha3';
import { v5 as UUIDv5 } from 'uuid';
import { AbstractBlock } from '../block/abstract';
import { UUID } from '../types';
declare const JWT_DEV: boolean;
enableAllPlugins();
const hash = new SHAKE(128);
// sha3-256(toeverythinguuid) -> truncate 128 bits
// e66a34f77a3b09d2020eb20e1f77e3c56250c19788ed2c70993ad2c495e55de6
const UUID_NAMESPACE = Uint8Array.from([
0xe6, 0x6a, 0x34, 0xf7, 0x7a, 0x3b, 0x09, 0xd2, 0x02, 0x0e, 0xb2, 0x0e,
0x1f, 0x77, 0xe3, 0xc5,
]);
// eslint-disable-next-line @typescript-eslint/naming-convention
export function genUUID(workspace: string): UUID<string> {
return UUIDv5(workspace, UUID_NAMESPACE) as UUID<string>;
}
export function sha3(buffer: Buffer): string {
hash.reset();
hash.update(buffer);
return hash
.digest('base64')
.replace(/=/g, '')
.replace(/\+/g, '-')
.replace(/\//g, '_');
}
export function getLogger(namespace: string) {
if (JWT_DEV) {
const logger = debug(namespace);
logger.log = console.log.bind(console);
if (JWT_DEV === ('testing' as any)) logger.enabled = true;
return logger;
} else {
return () => {};
}
}
export function isBlock(obj: any) {
return obj && obj instanceof AbstractBlock;
}
export function sleep() {
return new Promise(resolve => setTimeout(resolve, 500));
}
export { BlockEventBus } from './event-bus';