mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat: add some ipc provider method
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import type { Workspace } from '@blocksuite/store';
|
||||
|
||||
import type { Apis, Logger, InitialParams, ConfigStore } from './index';
|
||||
import type { BlobURL } from '@blocksuite/store/dist/blob/types';
|
||||
|
||||
export class BaseProvider {
|
||||
static id = 'base';
|
||||
@@ -41,8 +42,10 @@ export class BaseProvider {
|
||||
throw Error('Not implemented: initData');
|
||||
}
|
||||
|
||||
// should return a blob url
|
||||
async getBlob(_id: string): Promise<string | null> {
|
||||
/**
|
||||
* should return a blob url
|
||||
*/
|
||||
async getBlob(_id: string): Promise<BlobURL | null> {
|
||||
throw Error('Not implemented: getBlob');
|
||||
}
|
||||
|
||||
|
||||
@@ -1,35 +1,48 @@
|
||||
import type { BlobStorage } from '@blocksuite/store';
|
||||
import * as Y from 'yjs';
|
||||
import assert from 'assert';
|
||||
|
||||
import type { ConfigStore, InitialParams } from '../index.js';
|
||||
import { BaseProvider } from '../base.js';
|
||||
import { IndexedDBProvider } from './indexeddb.js';
|
||||
import { LocalProvider } from '../local/index.js';
|
||||
import * as ipcMethods from './ipc/methods.js';
|
||||
|
||||
export class LocalProvider extends BaseProvider {
|
||||
export class TauriIPCProvider extends LocalProvider {
|
||||
static id = 'local';
|
||||
private _blobs!: BlobStorage;
|
||||
private _idb?: IndexedDBProvider = undefined;
|
||||
#ipc = ipcMethods;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
async init(params: InitialParams) {
|
||||
super.init(params);
|
||||
|
||||
const blobs = await this._workspace.blobs;
|
||||
assert(blobs);
|
||||
this._blobs = blobs;
|
||||
}
|
||||
|
||||
async initData() {
|
||||
assert(this._workspace.room);
|
||||
this._logger('Loading local data');
|
||||
this._idb = new IndexedDBProvider(
|
||||
this._workspace.room,
|
||||
this._workspace.doc
|
||||
const { doc, room } = this._workspace;
|
||||
doc.on(
|
||||
'update',
|
||||
async (
|
||||
update: Uint8Array,
|
||||
_origin: any,
|
||||
_yDocument: Y.Doc,
|
||||
_transaction: Y.Transaction
|
||||
) => {
|
||||
try {
|
||||
// TODO: need handle potential data race when update is frequent?
|
||||
// TODO: update seems too frequent upon each keydown, why no batching?
|
||||
const success = await this.#ipc.updateYDocument({
|
||||
update: Array.from(update),
|
||||
room,
|
||||
});
|
||||
if (!success) {
|
||||
throw new Error(
|
||||
`YDoc update failed, id: ${this.workspace.meta.id}`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
// TODO: write error log to disk, and add button to open them in settings panel
|
||||
console.error("#yDocument.on('update'", error);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
await this._idb.whenSynced;
|
||||
this._logger('Local data loaded');
|
||||
|
||||
await this._globalConfig.set(this._workspace.room, true);
|
||||
@@ -37,25 +50,37 @@ export class LocalProvider extends BaseProvider {
|
||||
|
||||
async clear() {
|
||||
await super.clear();
|
||||
await this._blobs.clear();
|
||||
await this._idb?.clearData();
|
||||
await this._globalConfig.delete(this._workspace.room!);
|
||||
}
|
||||
|
||||
async destroy(): Promise<void> {
|
||||
super.destroy();
|
||||
await this._idb?.destroy();
|
||||
}
|
||||
|
||||
async getBlob(id: string): Promise<string | null> {
|
||||
return this._blobs.get(id);
|
||||
async getBlob(id: string) {
|
||||
const blobArray = await this.#ipc.getBlob({
|
||||
workspace_id: this.id,
|
||||
id,
|
||||
});
|
||||
// Make a Blob from the bytes
|
||||
const blob = new Blob([new Uint8Array(blobArray)], { type: 'image/bmp' });
|
||||
return window.URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
async setBlob(blob: Blob): Promise<string> {
|
||||
return this._blobs.set(blob);
|
||||
async setBlob(blob: Blob) {
|
||||
return this.#ipc.putBlob({
|
||||
blob: Array.from(new Uint8Array(await blob.arrayBuffer())),
|
||||
workspace_id: this.id,
|
||||
});
|
||||
}
|
||||
|
||||
static async list(
|
||||
async createWorkspace(
|
||||
name: string
|
||||
): Promise<{ id: string; name: string } | undefined> {
|
||||
// TODO: get userID here
|
||||
return this.#ipc.createWorkspace({ name, user_id: 0 });
|
||||
}
|
||||
|
||||
async getWorkspaces(
|
||||
config: Readonly<ConfigStore<boolean>>
|
||||
): Promise<Map<string, boolean> | undefined> {
|
||||
const entries = await config.entries();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { YDocumentUpdate } from './types/document';
|
||||
import { CreateWorkspace } from './types/workspace';
|
||||
import { CreateWorkspace, CreateWorkspaceResult } from './types/workspace';
|
||||
import { GetBlob, PutBlob } from './types/blob';
|
||||
|
||||
export const updateYDocument = async (parameters: YDocumentUpdate) =>
|
||||
@@ -9,7 +9,7 @@ export const updateYDocument = async (parameters: YDocumentUpdate) =>
|
||||
});
|
||||
|
||||
export const createWorkspace = async (parameters: CreateWorkspace) =>
|
||||
await invoke<boolean>('create_workspace', {
|
||||
await invoke<CreateWorkspaceResult>('create_workspace', {
|
||||
parameters,
|
||||
});
|
||||
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"workspace_id": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -51,9 +49,7 @@
|
||||
}
|
||||
},
|
||||
"workspace_id": {
|
||||
"type": "integer",
|
||||
"format": "uint64",
|
||||
"minimum": 0.0
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,11 @@ export type IBlobParameters =
|
||||
|
||||
export interface PutBlob {
|
||||
blob: number[];
|
||||
workspace_id: number;
|
||||
workspace_id: string;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface GetBlob {
|
||||
id: string;
|
||||
workspace_id: number;
|
||||
workspace_id: string;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,77 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "CreateWorkspace",
|
||||
"type": "object",
|
||||
"required": ["avatar", "id", "name"],
|
||||
"properties": {
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
"title": "IWorkspaceParameters",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["CreateWorkspace"],
|
||||
"properties": {
|
||||
"CreateWorkspace": {
|
||||
"$ref": "#/definitions/CreateWorkspace"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["UpdateWorkspace"],
|
||||
"properties": {
|
||||
"UpdateWorkspace": {
|
||||
"$ref": "#/definitions/UpdateWorkspace"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["CreateWorkspaceResult"],
|
||||
"properties": {
|
||||
"CreateWorkspaceResult": {
|
||||
"$ref": "#/definitions/CreateWorkspaceResult"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
],
|
||||
"definitions": {
|
||||
"CreateWorkspace": {
|
||||
"type": "object",
|
||||
"required": ["name", "user_id"],
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "only set name, avatar is update in datacenter to yDoc directly",
|
||||
"type": "string"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"CreateWorkspaceResult": {
|
||||
"type": "object",
|
||||
"required": ["id", "name"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"UpdateWorkspace": {
|
||||
"type": "object",
|
||||
"required": ["id", "public"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"public": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,32 @@
|
||||
* and run json-schema-to-typescript to regenerate this file.
|
||||
*/
|
||||
|
||||
export type IWorkspaceParameters =
|
||||
| {
|
||||
CreateWorkspace: CreateWorkspace;
|
||||
}
|
||||
| {
|
||||
UpdateWorkspace: UpdateWorkspace;
|
||||
}
|
||||
| {
|
||||
CreateWorkspaceResult: CreateWorkspaceResult;
|
||||
};
|
||||
|
||||
export interface CreateWorkspace {
|
||||
avatar: string;
|
||||
/**
|
||||
* only set name, avatar is update in datacenter to yDoc directly
|
||||
*/
|
||||
name: string;
|
||||
user_id: number;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface UpdateWorkspace {
|
||||
id: number;
|
||||
public: boolean;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface CreateWorkspaceResult {
|
||||
id: string;
|
||||
name: string;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user