feat: latest provider for ipc provider
This commit is contained in:
@@ -18,7 +18,7 @@ pub async fn put_blob<'s>(
|
|||||||
if let Ok(path) = blob_storage
|
if let Ok(path) = blob_storage
|
||||||
.put_blob(
|
.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
|
// 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>>(vec![Bytes::from(parameters.blob)]),
|
stream::iter::<Vec<Bytes>>(vec![Bytes::from(parameters.blob)]),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -37,7 +37,7 @@ pub async fn get_blob<'s>(
|
|||||||
let GetBlob { workspace_id, id } = parameters;
|
let GetBlob { workspace_id, id } = parameters;
|
||||||
// TODO: check user permission? Or just assume there will only be one user
|
// TODO: check user permission? Or just assume there will only be one user
|
||||||
let blob_storage = &state.0.lock().await.blob_storage;
|
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.
|
// Read all of the chunks into a vector.
|
||||||
let mut stream_contents = Vec::new();
|
let mut stream_contents = Vec::new();
|
||||||
let mut error_message = "".to_string();
|
let mut error_message = "".to_string();
|
||||||
@@ -47,7 +47,7 @@ pub async fn get_blob<'s>(
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
error_message = format!(
|
error_message = format!(
|
||||||
"Failed to read blob file {}/{} from stream, error: {}",
|
"Failed to read blob file {}/{} from stream, error: {}",
|
||||||
workspace_id.to_string(),
|
workspace_id.clone().unwrap_or_default().to_string(),
|
||||||
id,
|
id,
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
@@ -61,7 +61,7 @@ pub async fn get_blob<'s>(
|
|||||||
} else {
|
} else {
|
||||||
Err(format!(
|
Err(format!(
|
||||||
"Failed to read blob file {}/{} ",
|
"Failed to read blob file {}/{} ",
|
||||||
workspace_id.to_string(),
|
workspace_id.unwrap_or_default().to_string(),
|
||||||
id
|
id
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct PutBlob {
|
pub struct PutBlob {
|
||||||
pub workspace_id: String,
|
pub workspace_id: Option<String>,
|
||||||
pub blob: Vec<u8>,
|
pub blob: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct GetBlob {
|
pub struct GetBlob {
|
||||||
pub workspace_id: String,
|
pub workspace_id: Option<String>,
|
||||||
pub id: String,
|
pub id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,12 +44,7 @@ export class DataCenter {
|
|||||||
workspaces: dc._workspaces.createScope(),
|
workspaces: dc._workspaces.createScope(),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
dc.registerProvider(
|
dc.registerProvider(new SelfHostedProvider());
|
||||||
new SelfHostedProvider({
|
|
||||||
logger: dc._logger,
|
|
||||||
workspaces: dc._workspaces.createScope(),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
if (typeof window !== 'undefined' && window.CLIENT_APP) {
|
if (typeof window !== 'undefined' && window.CLIENT_APP) {
|
||||||
dc.registerProvider(
|
dc.registerProvider(
|
||||||
new TauriIPCProvider({
|
new TauriIPCProvider({
|
||||||
|
|||||||
@@ -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<BlobId>;
|
||||||
|
signals: {
|
||||||
|
blobAdded: Signal<BlobId>;
|
||||||
|
};
|
||||||
|
|
||||||
|
static async init(
|
||||||
|
workspace: string,
|
||||||
|
cloudApi?: string
|
||||||
|
): Promise<IPCBlobProvider> {
|
||||||
|
const provider = new IPCBlobProvider(workspace, cloudApi);
|
||||||
|
await provider._initBlobs();
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(id: BlobId): Promise<BlobURL | null> {
|
||||||
|
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<BlobId> {
|
||||||
|
return this.#ipc.putBlob({
|
||||||
|
blob: Array.from(new Uint8Array(await blob.arrayBuffer())),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(id: BlobId): Promise<void>;
|
||||||
|
clear(): Promise<void>;
|
||||||
|
}
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
|
||||||
import type {
|
|
||||||
ConfigStore,
|
|
||||||
DataCenterSignals,
|
|
||||||
InitialParams,
|
|
||||||
Logger,
|
|
||||||
} from '../index.js';
|
|
||||||
import { LocalProvider } from '../local/index.js';
|
import { LocalProvider } from '../local/index.js';
|
||||||
import * as ipcMethods from './ipc/methods.js';
|
import * as ipcMethods from './ipc/methods.js';
|
||||||
import { getApis } from 'src/apis/index.js';
|
import { ProviderConstructorParams } from '../base.js';
|
||||||
import { token } from 'src/apis/token.js';
|
import { BlockSchema } from '@blocksuite/blocks/models.js';
|
||||||
import { IndexedDBProvider } from '../local/indexeddb.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 {
|
export class TauriIPCProvider extends LocalProvider {
|
||||||
static id = 'tauri-ipc';
|
static id = 'tauri-ipc';
|
||||||
#ipc = ipcMethods;
|
#ipc = ipcMethods;
|
||||||
|
|
||||||
async init(params: InitialParams) {
|
constructor(params: ProviderConstructorParams) {
|
||||||
// set members like this._workspace in super
|
super(params);
|
||||||
super.init(params);
|
// TODO: let blocksuite's blob provider get blob receive workspace id. Currently, all blobs are placed together
|
||||||
|
this._blobs = new IPCBlobProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
async initData() {
|
async initData() {
|
||||||
@@ -96,32 +95,41 @@ export class TauriIPCProvider extends LocalProvider {
|
|||||||
await super.clear();
|
await super.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
async destroy(): Promise<void> {
|
public override async createWorkspace(
|
||||||
super.destroy();
|
meta: WorkspaceMeta
|
||||||
}
|
): Promise<Workspace | undefined> {
|
||||||
|
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 workspaceInfo: WS = {
|
||||||
const blobArray = await this.#ipc.getBlob({
|
name: meta.name,
|
||||||
workspace_id: this.id,
|
|
||||||
id,
|
id,
|
||||||
});
|
isPublish: false,
|
||||||
// Make a Blob from the bytes
|
avatar: '',
|
||||||
const blob = new Blob([new Uint8Array(blobArray)], { type: 'image/bmp' });
|
owner: undefined,
|
||||||
return window.URL.createObjectURL(blob);
|
isLocal: true,
|
||||||
}
|
memberCount: 1,
|
||||||
|
provider: 'local',
|
||||||
|
};
|
||||||
|
|
||||||
async setBlob(blob: Blob) {
|
this._workspaces.add(workspaceInfo);
|
||||||
return this.#ipc.putBlob({
|
return nw;
|
||||||
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 });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getWorkspaces(
|
async getWorkspaces(
|
||||||
|
|||||||
@@ -26,19 +26,19 @@
|
|||||||
"definitions": {
|
"definitions": {
|
||||||
"GetBlob": {
|
"GetBlob": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": ["id", "workspace_id"],
|
"required": ["id"],
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"workspace_id": {
|
"workspace_id": {
|
||||||
"type": "string"
|
"type": ["string", "null"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PutBlob": {
|
"PutBlob": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": ["blob", "workspace_id"],
|
"required": ["blob"],
|
||||||
"properties": {
|
"properties": {
|
||||||
"blob": {
|
"blob": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workspace_id": {
|
"workspace_id": {
|
||||||
"type": "string"
|
"type": ["string", "null"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ export type IBlobParameters =
|
|||||||
|
|
||||||
export interface PutBlob {
|
export interface PutBlob {
|
||||||
blob: number[];
|
blob: number[];
|
||||||
workspace_id: string;
|
workspace_id?: string | null;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}
|
}
|
||||||
export interface GetBlob {
|
export interface GetBlob {
|
||||||
id: string;
|
id: string;
|
||||||
workspace_id: string;
|
workspace_id?: string | null;
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user