From 6544d41188e74dc8dc37e328f01029b91aacf330 Mon Sep 17 00:00:00 2001 From: linonetwo Date: Mon, 9 Jan 2023 12:04:07 +0800 Subject: [PATCH] feat: latest provider for ipc provider --- client-app/src-tauri/src/commands/blob.rs | 8 +- client-app/src-tauri/types/src/blob.rs | 4 +- packages/data-center/src/datacenter.ts | 7 +- .../src/{globalTypes.ts => global-types.ts} | 0 .../tauri-ipc/blocksuite-provider/blob.ts | 43 ++++++++++ .../src/provider/tauri-ipc/index.ts | 78 ++++++++++--------- .../provider/tauri-ipc/ipc/types/blob.json | 8 +- .../src/provider/tauri-ipc/ipc/types/blob.ts | 4 +- 8 files changed, 99 insertions(+), 53 deletions(-) rename packages/data-center/src/{globalTypes.ts => global-types.ts} (100%) create mode 100644 packages/data-center/src/provider/tauri-ipc/blocksuite-provider/blob.ts diff --git a/client-app/src-tauri/src/commands/blob.rs b/client-app/src-tauri/src/commands/blob.rs index 041116d790..65ab8eb71e 100644 --- a/client-app/src-tauri/src/commands/blob.rs +++ b/client-app/src-tauri/src/commands/blob.rs @@ -18,7 +18,7 @@ pub async fn put_blob<'s>( if let Ok(path) = blob_storage .put_blob( // TODO: ask octobase to accept blob directly or wrap/await tauri command to create a real stream, so we don't need to construct stream manually - Some(parameters.workspace_id), + parameters.workspace_id, stream::iter::>(vec![Bytes::from(parameters.blob)]), ) .await @@ -37,7 +37,7 @@ pub async fn get_blob<'s>( let GetBlob { workspace_id, id } = parameters; // TODO: check user permission? Or just assume there will only be one user let blob_storage = &state.0.lock().await.blob_storage; - if let Ok(mut file_stream) = blob_storage.get_blob(Some(workspace_id.clone()), id.clone()).await { + if let Ok(mut file_stream) = blob_storage.get_blob(workspace_id.clone(), id.clone()).await { // Read all of the chunks into a vector. let mut stream_contents = Vec::new(); let mut error_message = "".to_string(); @@ -47,7 +47,7 @@ pub async fn get_blob<'s>( Err(err) => { error_message = format!( "Failed to read blob file {}/{} from stream, error: {}", - workspace_id.to_string(), + workspace_id.clone().unwrap_or_default().to_string(), id, err ); @@ -61,7 +61,7 @@ pub async fn get_blob<'s>( } else { Err(format!( "Failed to read blob file {}/{} ", - workspace_id.to_string(), + workspace_id.unwrap_or_default().to_string(), id )) } diff --git a/client-app/src-tauri/types/src/blob.rs b/client-app/src-tauri/types/src/blob.rs index 6c85fa1e29..5ac1ef6474 100644 --- a/client-app/src-tauri/types/src/blob.rs +++ b/client-app/src-tauri/types/src/blob.rs @@ -3,13 +3,13 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct PutBlob { - pub workspace_id: String, + pub workspace_id: Option, pub blob: Vec, } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct GetBlob { - pub workspace_id: String, + pub workspace_id: Option, pub id: String, } diff --git a/packages/data-center/src/datacenter.ts b/packages/data-center/src/datacenter.ts index bfd0bf2ce2..d41c4546b9 100644 --- a/packages/data-center/src/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -44,12 +44,7 @@ export class DataCenter { workspaces: dc._workspaces.createScope(), }) ); - dc.registerProvider( - new SelfHostedProvider({ - logger: dc._logger, - workspaces: dc._workspaces.createScope(), - }) - ); + dc.registerProvider(new SelfHostedProvider()); if (typeof window !== 'undefined' && window.CLIENT_APP) { dc.registerProvider( new TauriIPCProvider({ diff --git a/packages/data-center/src/globalTypes.ts b/packages/data-center/src/global-types.ts similarity index 100% rename from packages/data-center/src/globalTypes.ts rename to packages/data-center/src/global-types.ts diff --git a/packages/data-center/src/provider/tauri-ipc/blocksuite-provider/blob.ts b/packages/data-center/src/provider/tauri-ipc/blocksuite-provider/blob.ts new file mode 100644 index 0000000000..4a5af06e43 --- /dev/null +++ b/packages/data-center/src/provider/tauri-ipc/blocksuite-provider/blob.ts @@ -0,0 +1,43 @@ +import { + BlobId, + BlobProvider, + BlobURL, +} from '@blocksuite/store/dist/blob/types'; +import * as ipcMethods from '../ipc/methods.js'; +import { Signal } from '@blocksuite/store'; + +export class IPCBlobProvider implements BlobProvider { + #ipc = ipcMethods; + + blobs: Set; + signals: { + blobAdded: Signal; + }; + + static async init( + workspace: string, + cloudApi?: string + ): Promise { + const provider = new IPCBlobProvider(workspace, cloudApi); + await provider._initBlobs(); + return provider; + } + + async get(id: BlobId): Promise { + const blobArray = await this.#ipc.getBlob({ + id, + }); + // Make a Blob from the bytes + const blob = new Blob([new Uint8Array(blobArray)], { type: 'image/bmp' }); + return window.URL.createObjectURL(blob); + } + + async set(blob: Blob): Promise { + return this.#ipc.putBlob({ + blob: Array.from(new Uint8Array(await blob.arrayBuffer())), + }); + } + + delete(id: BlobId): Promise; + clear(): Promise; +} diff --git a/packages/data-center/src/provider/tauri-ipc/index.ts b/packages/data-center/src/provider/tauri-ipc/index.ts index d81722c557..c3f1e178e0 100644 --- a/packages/data-center/src/provider/tauri-ipc/index.ts +++ b/packages/data-center/src/provider/tauri-ipc/index.ts @@ -1,25 +1,24 @@ import * as Y from 'yjs'; import assert from 'assert'; -import type { - ConfigStore, - DataCenterSignals, - InitialParams, - Logger, -} from '../index.js'; import { LocalProvider } from '../local/index.js'; import * as ipcMethods from './ipc/methods.js'; -import { getApis } from 'src/apis/index.js'; -import { token } from 'src/apis/token.js'; -import { IndexedDBProvider } from '../local/indexeddb.js'; +import { ProviderConstructorParams } from '../base.js'; +import { BlockSchema } from '@blocksuite/blocks/models.js'; +import { Workspace } from '@blocksuite/store'; +import { ConfigStore } from 'src/store.js'; +import { User, Workspace as WS, WorkspaceMeta, Logger } from '../../types'; +import { getDefaultHeadImgBlob } from 'src/utils/index.js'; +import { IPCBlobProvider } from './blocksuite-provider/blob.js'; export class TauriIPCProvider extends LocalProvider { static id = 'tauri-ipc'; #ipc = ipcMethods; - async init(params: InitialParams) { - // set members like this._workspace in super - super.init(params); + constructor(params: ProviderConstructorParams) { + super(params); + // TODO: let blocksuite's blob provider get blob receive workspace id. Currently, all blobs are placed together + this._blobs = new IPCBlobProvider(); } async initData() { @@ -96,32 +95,41 @@ export class TauriIPCProvider extends LocalProvider { await super.clear(); } - async destroy(): Promise { - super.destroy(); - } + public override async createWorkspace( + meta: WorkspaceMeta + ): Promise { + assert(meta.name, 'Workspace name is required'); + if (!meta.avatar) { + // set default avatar + const blob = await getDefaultHeadImgBlob(meta.name); + meta.avatar = (await this.setBlob(blob)) || ''; + } + const { id } = await this.#ipc.createWorkspace({ + name: meta.name, + // TODO: get userID here + user_id: 0, + }); + this._logger('Creating affine workspace'); + const nw = new Workspace({ + room: id, + }).register(BlockSchema); + nw.meta.setName(meta.name); + nw.meta.setAvatar(meta.avatar); + // this._initWorkspaceDb(nw); - async getBlob(id: string) { - const blobArray = await this.#ipc.getBlob({ - workspace_id: this.id, + const workspaceInfo: WS = { + name: meta.name, id, - }); - // Make a Blob from the bytes - const blob = new Blob([new Uint8Array(blobArray)], { type: 'image/bmp' }); - return window.URL.createObjectURL(blob); - } + isPublish: false, + avatar: '', + owner: undefined, + isLocal: true, + memberCount: 1, + provider: 'local', + }; - async setBlob(blob: Blob) { - return this.#ipc.putBlob({ - blob: Array.from(new Uint8Array(await blob.arrayBuffer())), - workspace_id: this.id, - }); - } - - async createWorkspace( - name: string - ): Promise<{ id: string; name: string } | undefined> { - // TODO: get userID here - return this.#ipc.createWorkspace({ name, user_id: 0 }); + this._workspaces.add(workspaceInfo); + return nw; } async getWorkspaces( diff --git a/packages/data-center/src/provider/tauri-ipc/ipc/types/blob.json b/packages/data-center/src/provider/tauri-ipc/ipc/types/blob.json index 1eea646b60..9b00a5148e 100644 --- a/packages/data-center/src/provider/tauri-ipc/ipc/types/blob.json +++ b/packages/data-center/src/provider/tauri-ipc/ipc/types/blob.json @@ -26,19 +26,19 @@ "definitions": { "GetBlob": { "type": "object", - "required": ["id", "workspace_id"], + "required": ["id"], "properties": { "id": { "type": "string" }, "workspace_id": { - "type": "string" + "type": ["string", "null"] } } }, "PutBlob": { "type": "object", - "required": ["blob", "workspace_id"], + "required": ["blob"], "properties": { "blob": { "type": "array", @@ -49,7 +49,7 @@ } }, "workspace_id": { - "type": "string" + "type": ["string", "null"] } } } diff --git a/packages/data-center/src/provider/tauri-ipc/ipc/types/blob.ts b/packages/data-center/src/provider/tauri-ipc/ipc/types/blob.ts index 549d979f9e..5331469048 100644 --- a/packages/data-center/src/provider/tauri-ipc/ipc/types/blob.ts +++ b/packages/data-center/src/provider/tauri-ipc/ipc/types/blob.ts @@ -15,11 +15,11 @@ export type IBlobParameters = export interface PutBlob { blob: number[]; - workspace_id: string; + workspace_id?: string | null; [k: string]: unknown; } export interface GetBlob { id: string; - workspace_id: string; + workspace_id?: string | null; [k: string]: unknown; }