mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-15 21:41:52 +08:00
feat: update yrs doc using ipc from yjs doc
This commit is contained in:
@@ -16,7 +16,12 @@ export class TauriIPCProvider extends LocalProvider {
|
||||
async initData() {
|
||||
assert(this._workspace.room);
|
||||
this._logger('Loading local data');
|
||||
const { doc, room } = this._workspace;
|
||||
const {
|
||||
doc,
|
||||
room,
|
||||
meta: { id },
|
||||
} = this._workspace;
|
||||
this.#initDocFromIPC(id, doc);
|
||||
doc.on(
|
||||
'update',
|
||||
async (
|
||||
@@ -30,7 +35,7 @@ export class TauriIPCProvider extends LocalProvider {
|
||||
// TODO: update seems too frequent upon each keydown, why no batching?
|
||||
const success = await this.#ipc.updateYDocument({
|
||||
update: Array.from(update),
|
||||
room,
|
||||
id: Number(id),
|
||||
});
|
||||
if (!success) {
|
||||
throw new Error(
|
||||
@@ -44,8 +49,25 @@ export class TauriIPCProvider extends LocalProvider {
|
||||
}
|
||||
);
|
||||
this._logger('Local data loaded');
|
||||
}
|
||||
|
||||
await this._globalConfig.set(this._workspace.room, true);
|
||||
async #initDocFromIPC(workspaceID: string, doc: Y.Doc) {
|
||||
this._logger(`Loading ${workspaceID}...`);
|
||||
const updates = await this.#ipc.getYDocument({ id: Number(workspaceID) });
|
||||
if (updates) {
|
||||
await new Promise(resolve => {
|
||||
doc.once('update', resolve);
|
||||
Y.applyUpdate(doc, new Uint8Array(updates.update));
|
||||
});
|
||||
this._logger(`Loaded: ${workspaceID}`);
|
||||
|
||||
// only add to list as online workspace
|
||||
this._signals.listAdd.emit({
|
||||
workspace: workspaceID,
|
||||
provider: this.id,
|
||||
locally: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async clear() {
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import * as Y from 'yjs';
|
||||
import { Observable } from 'lib0/observable';
|
||||
import { DocProvider } from '@blocksuite/store';
|
||||
import type { Awareness } from 'y-protocols/awareness';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { updateYDocument } from './methods';
|
||||
|
||||
export class TauriIPCProvider
|
||||
extends Observable<string>
|
||||
implements DocProvider
|
||||
{
|
||||
#yDocument: Y.Doc;
|
||||
constructor(
|
||||
room: string,
|
||||
yDocument: Y.Doc,
|
||||
options?: { awareness?: Awareness }
|
||||
) {
|
||||
super();
|
||||
this.#yDocument = yDocument;
|
||||
this.#yDocument.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 updateYDocument({
|
||||
update: Array.from(update),
|
||||
room,
|
||||
});
|
||||
} catch (error) {
|
||||
// TODO: write error log to disk, and add button to open them in settings panel
|
||||
console.error("#yDocument.on('update'", error);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
connect() {}
|
||||
|
||||
destroy() {}
|
||||
disconnect() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
async clearData() {}
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { YDocumentUpdate } from './types/document';
|
||||
import {
|
||||
GetDocumentParameter,
|
||||
GetDocumentResponse,
|
||||
YDocumentUpdate,
|
||||
} from './types/document';
|
||||
import { CreateWorkspace, CreateWorkspaceResult } from './types/workspace';
|
||||
import { GetBlob, PutBlob } from './types/blob';
|
||||
|
||||
@@ -8,6 +12,11 @@ export const updateYDocument = async (parameters: YDocumentUpdate) =>
|
||||
parameters,
|
||||
});
|
||||
|
||||
export const getYDocument = async (parameters: GetDocumentParameter) =>
|
||||
await invoke<GetDocumentResponse>('get_doc', {
|
||||
parameters,
|
||||
});
|
||||
|
||||
export const createWorkspace = async (parameters: CreateWorkspace) =>
|
||||
await invoke<CreateWorkspaceResult>('create_workspace', {
|
||||
parameters,
|
||||
|
||||
@@ -1,18 +1,79 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "YDocumentUpdate",
|
||||
"type": "object",
|
||||
"required": ["room", "update"],
|
||||
"properties": {
|
||||
"room": {
|
||||
"type": "string"
|
||||
"title": "IDocumentParameters",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["YDocumentUpdate"],
|
||||
"properties": {
|
||||
"YDocumentUpdate": {
|
||||
"$ref": "#/definitions/YDocumentUpdate"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"update": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"minimum": 0.0
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["GetDocumentParameter"],
|
||||
"properties": {
|
||||
"GetDocumentParameter": {
|
||||
"$ref": "#/definitions/GetDocumentParameter"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["GetDocumentResponse"],
|
||||
"properties": {
|
||||
"GetDocumentResponse": {
|
||||
"$ref": "#/definitions/GetDocumentResponse"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
],
|
||||
"definitions": {
|
||||
"GetDocumentParameter": {
|
||||
"type": "object",
|
||||
"required": ["id"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
}
|
||||
}
|
||||
},
|
||||
"GetDocumentResponse": {
|
||||
"type": "object",
|
||||
"required": ["update"],
|
||||
"properties": {
|
||||
"update": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"YDocumentUpdate": {
|
||||
"type": "object",
|
||||
"required": ["id", "update"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"update": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,27 @@
|
||||
* and run json-schema-to-typescript to regenerate this file.
|
||||
*/
|
||||
|
||||
export type IDocumentParameters =
|
||||
| {
|
||||
YDocumentUpdate: YDocumentUpdate;
|
||||
}
|
||||
| {
|
||||
GetDocumentParameter: GetDocumentParameter;
|
||||
}
|
||||
| {
|
||||
GetDocumentResponse: GetDocumentResponse;
|
||||
};
|
||||
|
||||
export interface YDocumentUpdate {
|
||||
room: string;
|
||||
id: number;
|
||||
update: number[];
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface GetDocumentParameter {
|
||||
id: number;
|
||||
[k: string]: unknown;
|
||||
}
|
||||
export interface GetDocumentResponse {
|
||||
update: number[];
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user