fix: seriailize update as list, not merge then on yrs side, which is broken

This commit is contained in:
linonetwo
2023-01-12 23:29:23 +08:00
parent 532d7c8a72
commit 3ab34de1e1
5 changed files with 76 additions and 21 deletions

View File

@@ -1,10 +1,14 @@
use std::io::ErrorKind;
use ipc_types::document::{ use ipc_types::document::{
CreateDocumentParameter, GetDocumentParameter, GetDocumentResponse, YDocumentUpdate, CreateDocumentParameter, GetDocumentParameter, GetDocumentResponse, YDocumentUpdate,
}; };
use jwst::DocStorage; use jwst::DocStorage;
use jwst::Workspace as OctoBaseWorkspace; use jwst::Workspace as OctoBaseWorkspace;
use lib0::any::Any; use lib0::any::Any;
use yrs::StateVector; use tokio::fs::File;
use tokio::io::AsyncReadExt;
use yrs::{updates::decoder::Decode, Doc, StateVector, Update};
use crate::state::AppState; use crate::state::AppState;
@@ -47,21 +51,33 @@ pub async fn get_doc<'s>(
) -> Result<GetDocumentResponse, String> { ) -> Result<GetDocumentResponse, String> {
// TODO: check user permission // TODO: check user permission
if let Some(doc) = &state let doc_file_path = &state
.0 .0
.lock() .lock()
.await .await
.doc_storage .doc_storage
.get(parameters.id.clone()) .get_path(parameters.id.clone());
.await let mut file = File::open(doc_file_path).await.unwrap();
.ok() let mut updates_vector: Vec<Vec<u8>> = Vec::new();
{ loop {
Ok(GetDocumentResponse { let len = file.read_u64_le().await;
update: doc.encode_state_as_update_v1(&StateVector::default()),
}) let len = match len {
} else { Ok(len) => len,
Err(format!("Failed to get yDoc from {}", parameters.id)) Err(e) if e.kind() == ErrorKind::UnexpectedEof => break,
Err(e) => return Err(format!("Failed to get yDoc from {}", parameters.id)),
};
let mut update = vec![0; len as usize];
file.read_exact(&mut update).await.unwrap();
updates_vector.push(update);
file.read_u64_le().await.unwrap();
} }
Ok(GetDocumentResponse {
updates: updates_vector,
})
} }
#[tauri::command] #[tauri::command]

View File

@@ -18,7 +18,7 @@ pub struct CreateDocumentParameter {
} }
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct GetDocumentResponse { pub struct GetDocumentResponse {
pub update: Vec<u8>, pub updates: Vec<Vec<u8>>,
} }
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]

View File

@@ -42,11 +42,17 @@ export class TauriIPCProvider extends LocalProvider {
async #initDocFromIPC(workspaceID: string, doc: Y.Doc) { async #initDocFromIPC(workspaceID: string, doc: Y.Doc) {
this._logger(`Loading ${workspaceID}...`); this._logger(`Loading ${workspaceID}...`);
const updates = await ipcMethods.getYDocument({ id: workspaceID }); const result = await ipcMethods.getYDocument({ id: workspaceID });
if (updates) { if (result) {
await new Promise(resolve => { await new Promise(resolve => {
doc.once('update', resolve); doc.once('update', resolve);
Y.applyUpdate(doc, new Uint8Array(updates.update)); const updates = result.updates.map(
binaryUpdate => new Uint8Array(binaryUpdate)
);
const mergedUpdate = Y.mergeUpdates(updates);
// DEBUG: console mergedUpdate
console.log(`mergedUpdate`, mergedUpdate);
Y.applyUpdate(doc, new Uint8Array(mergedUpdate));
}); });
this._logger(`Loaded: ${workspaceID}`); this._logger(`Loaded: ${workspaceID}`);
} }

View File

@@ -12,6 +12,16 @@
}, },
"additionalProperties": false "additionalProperties": false
}, },
{
"type": "object",
"required": ["CreateDocumentParameter"],
"properties": {
"CreateDocumentParameter": {
"$ref": "#/definitions/CreateDocumentParameter"
}
},
"additionalProperties": false
},
{ {
"type": "object", "type": "object",
"required": ["GetDocumentParameter"], "required": ["GetDocumentParameter"],
@@ -34,6 +44,18 @@
} }
], ],
"definitions": { "definitions": {
"CreateDocumentParameter": {
"type": "object",
"required": ["workspace_id", "workspace_name"],
"properties": {
"workspace_id": {
"type": "string"
},
"workspace_name": {
"type": "string"
}
}
},
"GetDocumentParameter": { "GetDocumentParameter": {
"type": "object", "type": "object",
"required": ["id"], "required": ["id"],
@@ -45,9 +67,11 @@
}, },
"GetDocumentResponse": { "GetDocumentResponse": {
"type": "object", "type": "object",
"required": ["update"], "required": ["updates"],
"properties": { "properties": {
"update": { "updates": {
"type": "array",
"items": {
"type": "array", "type": "array",
"items": { "items": {
"type": "integer", "type": "integer",
@@ -56,6 +80,7 @@
} }
} }
} }
}
}, },
"YDocumentUpdate": { "YDocumentUpdate": {
"type": "object", "type": "object",

View File

@@ -9,6 +9,9 @@ export type IDocumentParameters =
| { | {
YDocumentUpdate: YDocumentUpdate; YDocumentUpdate: YDocumentUpdate;
} }
| {
CreateDocumentParameter: CreateDocumentParameter;
}
| { | {
GetDocumentParameter: GetDocumentParameter; GetDocumentParameter: GetDocumentParameter;
} }
@@ -21,11 +24,16 @@ export interface YDocumentUpdate {
update: number[]; update: number[];
[k: string]: unknown; [k: string]: unknown;
} }
export interface CreateDocumentParameter {
workspace_id: string;
workspace_name: string;
[k: string]: unknown;
}
export interface GetDocumentParameter { export interface GetDocumentParameter {
id: string; id: string;
[k: string]: unknown; [k: string]: unknown;
} }
export interface GetDocumentResponse { export interface GetDocumentResponse {
update: number[]; updates: number[][];
[k: string]: unknown; [k: string]: unknown;
} }