From 151a2a4311909a9940dccd3284c8ca6f1020ef3f Mon Sep 17 00:00:00 2001 From: DarkSky Date: Wed, 4 Jan 2023 21:22:31 +0800 Subject: [PATCH] feat: add signal for list events --- packages/data-center/src/datacenter.ts | 58 ++++++++++++++----- packages/data-center/src/index.ts | 9 ++- packages/data-center/src/provider/base.ts | 12 +++- packages/data-center/src/provider/index.ts | 5 +- .../data-center/src/provider/local/index.ts | 9 ++- .../data-center/tests/local/workspace.spec.ts | 2 +- 6 files changed, 70 insertions(+), 25 deletions(-) diff --git a/packages/data-center/src/datacenter.ts b/packages/data-center/src/datacenter.ts index a094b9def6..9427208690 100644 --- a/packages/data-center/src/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -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; }; +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(); @@ -23,6 +34,12 @@ export class DataCenter { private readonly _config; private readonly _logger; + readonly signals = { + listAdd: new Signal(), + listRemove: new Signal(), + workspaceLoaded: new Signal(), + }; + static async init(debug: boolean): Promise { 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 { @@ -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>> { - 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>); } diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index 72aa6015e1..0ca8f1cfee 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -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; }); } diff --git a/packages/data-center/src/provider/base.ts b/packages/data-center/src/provider/base.ts index 8ed184b6eb..3874ecc484 100644 --- a/packages/data-center/src/provider/base.ts +++ b/packages/data-center/src/provider/base.ts @@ -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; protected _config!: Readonly; - protected _globalConfig!: Readonly; 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; } diff --git a/packages/data-center/src/provider/index.ts b/packages/data-center/src/provider/index.ts index f3fc53f9ad..5718b7eef0 100644 --- a/packages/data-center/src/provider/index.ts +++ b/packages/data-center/src/provider/index.ts @@ -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; export type InitialParams = { apis: Apis; config: Readonly; - globalConfig: Readonly; 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'; diff --git a/packages/data-center/src/provider/local/index.ts b/packages/data-center/src/provider/local/index.ts index 89ec6ce192..9e6a695a56 100644 --- a/packages/data-center/src/provider/local/index.ts +++ b/packages/data-center/src/provider/local/index.ts @@ -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 { diff --git a/packages/data-center/tests/local/workspace.spec.ts b/packages/data-center/tests/local/workspace.spec.ts index 20c5182d65..771bf2ff69 100644 --- a/packages/data-center/tests/local/workspace.spec.ts +++ b/packages/data-center/tests/local/workspace.spec.ts @@ -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 },