mirror of
https://github.com/toeverything/AFFiNE.git
synced 2025-01-01 18:06:10 +03:00
feat: add signal for list events
This commit is contained in:
parent
ae94c901b3
commit
151a2a4311
@ -1,6 +1,6 @@
|
||||
import assert from 'assert';
|
||||
import { BlockSchema } from '@blocksuite/blocks/models';
|
||||
import { Workspace } from '@blocksuite/store';
|
||||
import { Workspace, Signal } from '@blocksuite/store';
|
||||
|
||||
import { getLogger } from './index.js';
|
||||
import { getApis, Apis } from './apis/index.js';
|
||||
@ -16,6 +16,17 @@ type LoadConfig = {
|
||||
config?: Record<string, any>;
|
||||
};
|
||||
|
||||
export type DataCenterSignals = DataCenter['signals'];
|
||||
type WorkspaceItem = {
|
||||
// provider id
|
||||
provider: string;
|
||||
// data exists locally
|
||||
locally: boolean;
|
||||
};
|
||||
type WorkspaceLoadEvent = WorkspaceItem & {
|
||||
workspace: string;
|
||||
};
|
||||
|
||||
export class DataCenter {
|
||||
private readonly _apis: Apis;
|
||||
private readonly _providers = new Map<string, typeof BaseProvider>();
|
||||
@ -23,6 +34,12 @@ export class DataCenter {
|
||||
private readonly _config;
|
||||
private readonly _logger;
|
||||
|
||||
readonly signals = {
|
||||
listAdd: new Signal<WorkspaceLoadEvent>(),
|
||||
listRemove: new Signal<string>(),
|
||||
workspaceLoaded: new Signal<WorkspaceLoadEvent>(),
|
||||
};
|
||||
|
||||
static async init(debug: boolean): Promise<DataCenter> {
|
||||
const dc = new DataCenter(debug);
|
||||
dc.addProvider(AffineProvider);
|
||||
@ -36,6 +53,22 @@ export class DataCenter {
|
||||
this._config = getKVConfigure('sys');
|
||||
this._logger = getLogger('dc');
|
||||
this._logger.enabled = debug;
|
||||
|
||||
this.signals.listAdd.on(e => {
|
||||
this._config.set(`list:${e.workspace}`, {
|
||||
provider: e.provider,
|
||||
locally: e.locally,
|
||||
});
|
||||
});
|
||||
this.signals.listRemove.on(workspace => {
|
||||
this._config.delete(`list:${workspace}`);
|
||||
});
|
||||
this.signals.workspaceLoaded.on(e => {
|
||||
this._config.set(`list:${e.workspace}`, {
|
||||
provider: e.provider,
|
||||
locally: e.locally,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
get apis(): Readonly<Apis> {
|
||||
@ -86,9 +119,9 @@ export class DataCenter {
|
||||
await provider.init({
|
||||
apis: this._apis,
|
||||
config,
|
||||
globalConfig: getKVConfigure(`provider:${providerId}`),
|
||||
debug: this._logger.enabled,
|
||||
logger: this._logger.extend(`${Provider.id}:${id}`),
|
||||
signals: this.signals,
|
||||
workspace,
|
||||
});
|
||||
await provider.initData();
|
||||
@ -169,21 +202,14 @@ export class DataCenter {
|
||||
* data state is also map, the key is the provider id, and the data exists locally when the value is true, otherwise it does not exist
|
||||
*/
|
||||
async list(): Promise<Record<string, Record<string, boolean>>> {
|
||||
const lists = await Promise.all(
|
||||
Array.from(this._providers.entries()).map(([providerId, provider]) =>
|
||||
provider
|
||||
.list(getKVConfigure(`provider:${providerId}`))
|
||||
.then(list => [providerId, list || []] as const)
|
||||
)
|
||||
);
|
||||
|
||||
return lists.reduce((ret, [providerId, list]) => {
|
||||
for (const [item, isLocal] of list) {
|
||||
const workspace = ret[item] || {};
|
||||
workspace[providerId] = isLocal;
|
||||
ret[item] = workspace;
|
||||
const entries: [string, WorkspaceItem][] = await this._config.entries();
|
||||
return entries.reduce((acc, [k, i]) => {
|
||||
if (k.startsWith('list:')) {
|
||||
const key = k.slice(5);
|
||||
acc[key] = acc[key] || {};
|
||||
acc[key][i.provider] = i.locally;
|
||||
}
|
||||
return ret;
|
||||
return acc;
|
||||
}, {} as Record<string, Record<string, boolean>>);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,14 @@ const _initializeDataCenter = () => {
|
||||
if (!_dataCenterInstance) {
|
||||
_dataCenterInstance = DataCenter.init(debug);
|
||||
_dataCenterInstance.then(dc => {
|
||||
(window as any).dc = dc;
|
||||
try {
|
||||
if (window) {
|
||||
(window as any).dc = dc;
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return dc;
|
||||
});
|
||||
}
|
||||
|
@ -1,14 +1,20 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
|
||||
import type { Apis, Logger, InitialParams, ConfigStore } from './index';
|
||||
import type {
|
||||
Apis,
|
||||
DataCenterSignals,
|
||||
Logger,
|
||||
InitialParams,
|
||||
ConfigStore,
|
||||
} from './index';
|
||||
|
||||
export class BaseProvider {
|
||||
static id = 'base';
|
||||
protected _apis!: Readonly<Apis>;
|
||||
protected _config!: Readonly<ConfigStore>;
|
||||
protected _globalConfig!: Readonly<ConfigStore>;
|
||||
protected _logger!: Logger;
|
||||
protected _signals!: DataCenterSignals;
|
||||
protected _workspace!: Workspace;
|
||||
|
||||
constructor() {
|
||||
@ -22,8 +28,8 @@ export class BaseProvider {
|
||||
async init(params: InitialParams) {
|
||||
this._apis = params.apis;
|
||||
this._config = params.config;
|
||||
this._globalConfig = params.globalConfig;
|
||||
this._logger = params.logger;
|
||||
this._signals = params.signals;
|
||||
this._workspace = params.workspace;
|
||||
this._logger.enabled = params.debug;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
|
||||
import type { Apis } from '../apis';
|
||||
import type { DataCenterSignals } from '../datacenter';
|
||||
import type { getLogger } from '../index';
|
||||
import type { ConfigStore } from '../store';
|
||||
|
||||
@ -9,13 +10,13 @@ export type Logger = ReturnType<typeof getLogger>;
|
||||
export type InitialParams = {
|
||||
apis: Apis;
|
||||
config: Readonly<ConfigStore>;
|
||||
globalConfig: Readonly<ConfigStore>;
|
||||
debug: boolean;
|
||||
logger: Logger;
|
||||
signals: DataCenterSignals;
|
||||
workspace: Workspace;
|
||||
};
|
||||
|
||||
export type { Apis, ConfigStore, Workspace };
|
||||
export type { Apis, ConfigStore, DataCenterSignals, Workspace };
|
||||
export type { BaseProvider } from './base.js';
|
||||
export { AffineProvider } from './affine/index.js';
|
||||
export { LocalProvider } from './local/index.js';
|
||||
|
@ -32,14 +32,19 @@ export class LocalProvider extends BaseProvider {
|
||||
await this._idb.whenSynced;
|
||||
this._logger('Local data loaded');
|
||||
|
||||
await this._globalConfig.set(`list:${this._workspace.room}`, true);
|
||||
this._signals.listAdd.emit({
|
||||
workspace: this._workspace.room,
|
||||
provider: this.id,
|
||||
locally: true,
|
||||
});
|
||||
}
|
||||
|
||||
async clear() {
|
||||
assert(this._workspace.room);
|
||||
await super.clear();
|
||||
await this._blobs.clear();
|
||||
await this._idb?.clearData();
|
||||
await this._globalConfig.delete(`list:${this._workspace.room}`);
|
||||
this._signals.listRemove.emit(this._workspace.room);
|
||||
}
|
||||
|
||||
async destroy(): Promise<void> {
|
||||
|
@ -35,7 +35,7 @@ test.describe('Workspace', () => {
|
||||
|
||||
await dataCenter.reload('test3', { providerId: 'affine' });
|
||||
expect(await dataCenter.list()).toStrictEqual({
|
||||
test3: { affine: true, local: true },
|
||||
test3: { affine: true },
|
||||
test4: { local: true },
|
||||
test5: { local: true },
|
||||
test6: { local: true },
|
||||
|
Loading…
Reference in New Issue
Block a user