move flowy-ot document to flowy-document

This commit is contained in:
appflowy 2021-09-22 23:21:44 +08:00
parent 47f3a187c4
commit 2b9bc7a0cd
66 changed files with 611 additions and 522 deletions

View File

@ -7,6 +7,7 @@
import 'dart:core' as $core;
import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;
class CreateDocParams extends $pb.GeneratedMessage {
@ -74,6 +75,7 @@ class Doc extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Doc', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
..aInt64(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'revision')
..hasRequiredFields = false
;
@ -81,6 +83,7 @@ class Doc extends $pb.GeneratedMessage {
factory Doc({
$core.String? id,
$core.List<$core.int>? data,
$fixnum.Int64? revision,
}) {
final _result = create();
if (id != null) {
@ -89,6 +92,9 @@ class Doc extends $pb.GeneratedMessage {
if (data != null) {
_result.data = data;
}
if (revision != null) {
_result.revision = revision;
}
return _result;
}
factory Doc.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
@ -129,49 +135,58 @@ class Doc extends $pb.GeneratedMessage {
$core.bool hasData() => $_has(1);
@$pb.TagNumber(2)
void clearData() => clearField(2);
@$pb.TagNumber(3)
$fixnum.Int64 get revision => $_getI64(2);
@$pb.TagNumber(3)
set revision($fixnum.Int64 v) { $_setInt64(2, v); }
@$pb.TagNumber(3)
$core.bool hasRevision() => $_has(2);
@$pb.TagNumber(3)
void clearRevision() => clearField(3);
}
class SaveDocParams extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'SaveDocParams', createEmptyInstance: create)
class UpdateDocParams extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'UpdateDocParams', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'docData', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
SaveDocParams._() : super();
factory SaveDocParams({
UpdateDocParams._() : super();
factory UpdateDocParams({
$core.String? id,
$core.List<$core.int>? data,
$core.List<$core.int>? docData,
}) {
final _result = create();
if (id != null) {
_result.id = id;
}
if (data != null) {
_result.data = data;
if (docData != null) {
_result.docData = docData;
}
return _result;
}
factory SaveDocParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory SaveDocParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
factory UpdateDocParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory UpdateDocParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
SaveDocParams clone() => SaveDocParams()..mergeFromMessage(this);
UpdateDocParams clone() => UpdateDocParams()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
SaveDocParams copyWith(void Function(SaveDocParams) updates) => super.copyWith((message) => updates(message as SaveDocParams)) as SaveDocParams; // ignore: deprecated_member_use
UpdateDocParams copyWith(void Function(UpdateDocParams) updates) => super.copyWith((message) => updates(message as UpdateDocParams)) as UpdateDocParams; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static SaveDocParams create() => SaveDocParams._();
SaveDocParams createEmptyInstance() => create();
static $pb.PbList<SaveDocParams> createRepeated() => $pb.PbList<SaveDocParams>();
static UpdateDocParams create() => UpdateDocParams._();
UpdateDocParams createEmptyInstance() => create();
static $pb.PbList<UpdateDocParams> createRepeated() => $pb.PbList<UpdateDocParams>();
@$core.pragma('dart2js:noInline')
static SaveDocParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<SaveDocParams>(create);
static SaveDocParams? _defaultInstance;
static UpdateDocParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<UpdateDocParams>(create);
static UpdateDocParams? _defaultInstance;
@$pb.TagNumber(1)
$core.String get id => $_getSZ(0);
@ -183,24 +198,24 @@ class SaveDocParams extends $pb.GeneratedMessage {
void clearId() => clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get data => $_getN(1);
$core.List<$core.int> get docData => $_getN(1);
@$pb.TagNumber(2)
set data($core.List<$core.int> v) { $_setBytes(1, v); }
set docData($core.List<$core.int> v) { $_setBytes(1, v); }
@$pb.TagNumber(2)
$core.bool hasData() => $_has(1);
$core.bool hasDocData() => $_has(1);
@$pb.TagNumber(2)
void clearData() => clearField(2);
void clearDocData() => clearField(2);
}
class ApplyChangesetParams extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ApplyChangesetParams', createEmptyInstance: create)
class DocChangeset extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DocChangeset', createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id')
..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'data', $pb.PbFieldType.OY)
..hasRequiredFields = false
;
ApplyChangesetParams._() : super();
factory ApplyChangesetParams({
DocChangeset._() : super();
factory DocChangeset({
$core.String? id,
$core.List<$core.int>? data,
}) {
@ -213,26 +228,26 @@ class ApplyChangesetParams extends $pb.GeneratedMessage {
}
return _result;
}
factory ApplyChangesetParams.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory ApplyChangesetParams.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
factory DocChangeset.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory DocChangeset.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
ApplyChangesetParams clone() => ApplyChangesetParams()..mergeFromMessage(this);
DocChangeset clone() => DocChangeset()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
ApplyChangesetParams copyWith(void Function(ApplyChangesetParams) updates) => super.copyWith((message) => updates(message as ApplyChangesetParams)) as ApplyChangesetParams; // ignore: deprecated_member_use
DocChangeset copyWith(void Function(DocChangeset) updates) => super.copyWith((message) => updates(message as DocChangeset)) as DocChangeset; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static ApplyChangesetParams create() => ApplyChangesetParams._();
ApplyChangesetParams createEmptyInstance() => create();
static $pb.PbList<ApplyChangesetParams> createRepeated() => $pb.PbList<ApplyChangesetParams>();
static DocChangeset create() => DocChangeset._();
DocChangeset createEmptyInstance() => create();
static $pb.PbList<DocChangeset> createRepeated() => $pb.PbList<DocChangeset>();
@$core.pragma('dart2js:noInline')
static ApplyChangesetParams getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ApplyChangesetParams>(create);
static ApplyChangesetParams? _defaultInstance;
static DocChangeset getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<DocChangeset>(create);
static DocChangeset? _defaultInstance;
@$pb.TagNumber(1)
$core.String get id => $_getSZ(0);

View File

@ -25,33 +25,34 @@ const Doc$json = const {
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'data', '3': 2, '4': 1, '5': 12, '10': 'data'},
const {'1': 'revision', '3': 3, '4': 1, '5': 3, '10': 'revision'},
],
};
/// Descriptor for `Doc`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List docDescriptor = $convert.base64Decode('CgNEb2MSDgoCaWQYASABKAlSAmlkEhIKBGRhdGEYAiABKAxSBGRhdGE=');
@$core.Deprecated('Use saveDocParamsDescriptor instead')
const SaveDocParams$json = const {
'1': 'SaveDocParams',
final $typed_data.Uint8List docDescriptor = $convert.base64Decode('CgNEb2MSDgoCaWQYASABKAlSAmlkEhIKBGRhdGEYAiABKAxSBGRhdGESGgoIcmV2aXNpb24YAyABKANSCHJldmlzaW9u');
@$core.Deprecated('Use updateDocParamsDescriptor instead')
const UpdateDocParams$json = const {
'1': 'UpdateDocParams',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'doc_data', '3': 2, '4': 1, '5': 12, '10': 'docData'},
],
};
/// Descriptor for `UpdateDocParams`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List updateDocParamsDescriptor = $convert.base64Decode('Cg9VcGRhdGVEb2NQYXJhbXMSDgoCaWQYASABKAlSAmlkEhkKCGRvY19kYXRhGAIgASgMUgdkb2NEYXRh');
@$core.Deprecated('Use docChangesetDescriptor instead')
const DocChangeset$json = const {
'1': 'DocChangeset',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'data', '3': 2, '4': 1, '5': 12, '10': 'data'},
],
};
/// Descriptor for `SaveDocParams`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List saveDocParamsDescriptor = $convert.base64Decode('Cg1TYXZlRG9jUGFyYW1zEg4KAmlkGAEgASgJUgJpZBISCgRkYXRhGAIgASgMUgRkYXRh');
@$core.Deprecated('Use applyChangesetParamsDescriptor instead')
const ApplyChangesetParams$json = const {
'1': 'ApplyChangesetParams',
'2': const [
const {'1': 'id', '3': 1, '4': 1, '5': 9, '10': 'id'},
const {'1': 'data', '3': 2, '4': 1, '5': 12, '10': 'data'},
],
};
/// Descriptor for `ApplyChangesetParams`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List applyChangesetParamsDescriptor = $convert.base64Decode('ChRBcHBseUNoYW5nZXNldFBhcmFtcxIOCgJpZBgBIAEoCVICaWQSEgoEZGF0YRgCIAEoDFIEZGF0YQ==');
/// Descriptor for `DocChangeset`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List docChangesetDescriptor = $convert.base64Decode('CgxEb2NDaGFuZ2VzZXQSDgoCaWQYASABKAlSAmlkEhIKBGRhdGEYAiABKAxSBGRhdGE=');
@$core.Deprecated('Use queryDocParamsDescriptor instead')
const QueryDocParams$json = const {
'1': 'QueryDocParams',

View File

@ -13,6 +13,9 @@ class ErrorCode extends $pb.ProtobufEnum {
static const ErrorCode DocIdInvalid = ErrorCode._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocIdInvalid');
static const ErrorCode DocNotfound = ErrorCode._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DocNotfound');
static const ErrorCode WsConnectError = ErrorCode._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'WsConnectError');
static const ErrorCode UndoFail = ErrorCode._(200, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UndoFail');
static const ErrorCode RedoFail = ErrorCode._(201, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'RedoFail');
static const ErrorCode OutOfBound = ErrorCode._(202, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'OutOfBound');
static const ErrorCode UserUnauthorized = ErrorCode._(999, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UserUnauthorized');
static const ErrorCode InternalError = ErrorCode._(1000, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'InternalError');
@ -20,6 +23,9 @@ class ErrorCode extends $pb.ProtobufEnum {
DocIdInvalid,
DocNotfound,
WsConnectError,
UndoFail,
RedoFail,
OutOfBound,
UserUnauthorized,
InternalError,
];

View File

@ -15,13 +15,16 @@ const ErrorCode$json = const {
const {'1': 'DocIdInvalid', '2': 0},
const {'1': 'DocNotfound', '2': 1},
const {'1': 'WsConnectError', '2': 10},
const {'1': 'UndoFail', '2': 200},
const {'1': 'RedoFail', '2': 201},
const {'1': 'OutOfBound', '2': 202},
const {'1': 'UserUnauthorized', '2': 999},
const {'1': 'InternalError', '2': 1000},
],
};
/// Descriptor for `ErrorCode`. Decode as a `google.protobuf.EnumDescriptorProto`.
final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSEAoMRG9jSWRJbnZhbGlkEAASDwoLRG9jTm90Zm91bmQQARISCg5Xc0Nvbm5lY3RFcnJvchAKEhUKEFVzZXJVbmF1dGhvcml6ZWQQ5wcSEgoNSW50ZXJuYWxFcnJvchDoBw==');
final $typed_data.Uint8List errorCodeDescriptor = $convert.base64Decode('CglFcnJvckNvZGUSEAoMRG9jSWRJbnZhbGlkEAASDwoLRG9jTm90Zm91bmQQARISCg5Xc0Nvbm5lY3RFcnJvchAKEg0KCFVuZG9GYWlsEMgBEg0KCFJlZG9GYWlsEMkBEg8KCk91dE9mQm91bmQQygESFQoQVXNlclVuYXV0aG9yaXplZBDnBxISCg1JbnRlcm5hbEVycm9yEOgH');
@$core.Deprecated('Use docErrorDescriptor instead')
const DocError$json = const {
'1': 'DocError',

View File

@ -2,5 +2,5 @@
CREATE TABLE doc_table (
id TEXT NOT NULL PRIMARY KEY,
data BLOB NOT NULL DEFAULT (x''),
version BIGINT NOT NULL DEFAULT 0
revision BIGINT NOT NULL DEFAULT 0
);

View File

@ -0,0 +1 @@
-- This file should undo anything in `up.sql`

View File

@ -0,0 +1 @@
-- Your SQL goes here

View File

@ -17,7 +17,7 @@ table! {
doc_table (id) {
id -> Text,
data -> Binary,
version -> BigInt,
revision -> BigInt,
}
}
@ -58,4 +58,10 @@ table! {
}
}
allow_tables_to_appear_in_same_query!(app_table, doc_table, user_table, view_table, workspace_table,);
allow_tables_to_appear_in_same_query!(
app_table,
doc_table,
user_table,
view_table,
workspace_table,
);

View File

@ -57,8 +57,8 @@ pub fn category_from_str(type_str: &str) -> TypeCategory {
| "WsMessage"
| "CreateDocParams"
| "Doc"
| "SaveDocParams"
| "ApplyChangesetParams"
| "UpdateDocParams"
| "DocChangeset"
| "QueryDocParams"
| "WsDocumentData"
| "DocError"

View File

@ -30,9 +30,19 @@ strum = "0.21"
strum_macros = "0.21"
dashmap = "4.0"
parking_lot = "0.11"
bytecount = "0.6.0"
url = "2.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = {version = "1.0"}
chrono = "0.4.19"
[dev-dependencies]
flowy-test = { path = "../flowy-test" }
color-eyre = { version = "0.5", default-features = false }
criterion = "0.3"
rand = "0.7.3"
env_logger = "0.8.2"
[features]
http_server = []

View File

@ -20,19 +20,22 @@ pub struct Doc {
#[pb(index = 2)]
pub data: Vec<u8>,
#[pb(index = 3)]
pub revision: i64,
}
#[derive(ProtoBuf, Default, Debug, Clone)]
pub struct SaveDocParams {
pub struct UpdateDocParams {
#[pb(index = 1)]
pub id: String,
#[pb(index = 2)]
pub data: Vec<u8>,
pub doc_data: Vec<u8>,
}
#[derive(ProtoBuf, Default, Debug, Clone)]
pub struct ApplyChangesetParams {
pub struct DocChangeset {
#[pb(index = 1)]
pub id: String,

View File

@ -41,6 +41,9 @@ impl DocError {
static_doc_error!(not_found, ErrorCode::DocNotfound);
static_doc_error!(unauthorized, ErrorCode::UserUnauthorized);
static_doc_error!(ws, ErrorCode::WsConnectError);
static_doc_error!(undo, ErrorCode::UndoFail);
static_doc_error!(redo, ErrorCode::RedoFail);
static_doc_error!(out_of_bound, ErrorCode::OutOfBound);
}
pub fn internal_error<T>(e: T) -> DocError
@ -61,6 +64,14 @@ pub enum ErrorCode {
#[display(fmt = "Document websocket error")]
WsConnectError = 10,
#[display(fmt = "Undo failed")]
UndoFail = 200,
#[display(fmt = "Redo failed")]
RedoFail = 201,
#[display(fmt = "Interval out of bound")]
OutOfBound = 202,
#[display(fmt = "UserUnauthorized")]
UserUnauthorized = 999,
@ -89,6 +100,10 @@ impl std::convert::From<std::io::Error> for DocError {
fn from(error: std::io::Error) -> Self { DocError::internal().context(error) }
}
impl std::convert::From<serde_json::Error> for DocError {
fn from(error: serde_json::Error) -> Self { DocError::internal().context(error) }
}
// impl std::convert::From<::r2d2::Error> for DocError {
// fn from(error: r2d2::Error) -> Self {
// ErrorBuilder::new(ErrorCode::InternalError).error(error).build() } }

View File

@ -3,7 +3,7 @@ pub mod errors;
pub mod module;
mod observable;
pub mod protobuf;
mod services;
pub mod services;
mod sql_tables;
#[macro_use]

View File

@ -1,7 +1,7 @@
use crate::{
entities::doc::{ApplyChangesetParams, CreateDocParams, Doc, QueryDocParams},
entities::doc::{CreateDocParams, Doc, DocChangeset, QueryDocParams},
errors::DocError,
services::{doc_controller::DocController, open_doc::OpenedDocManager, server::construct_doc_server, ws::WsManager},
services::{doc_controller::DocController, server::construct_doc_server, ws::WsManager},
};
use bytes::Bytes;
use diesel::SqliteConnection;
@ -17,16 +17,13 @@ pub trait DocumentUser: Send + Sync {
pub struct FlowyDocument {
controller: Arc<DocController>,
doc_manager: Arc<OpenedDocManager>,
}
impl FlowyDocument {
pub fn new(user: Arc<dyn DocumentUser>, ws_manager: Arc<RwLock<WsManager>>) -> FlowyDocument {
let server = construct_doc_server();
let controller = Arc::new(DocController::new(server.clone(), user.clone()));
let doc_manager = Arc::new(OpenedDocManager::new(ws_manager, controller.clone()));
Self { controller, doc_manager }
let controller = Arc::new(DocController::new(server.clone(), user.clone(), ws_manager.clone()));
Self { controller }
}
pub fn create(&self, params: CreateDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
@ -35,31 +32,23 @@ impl FlowyDocument {
}
pub fn delete(&self, params: QueryDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
let _ = self.doc_manager.close(&params.doc_id)?;
let _ = self.controller.delete(params.into(), conn)?;
let _ = self.controller.delete(params, conn)?;
Ok(())
}
pub async fn open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
let doc = match self.doc_manager.is_opened(&params.doc_id) {
true => {
let data = self.doc_manager.read_doc(&params.doc_id).await?;
Doc { id: params.doc_id, data }
},
false => {
let doc = self.controller.open(params, pool).await?;
let _ = self.doc_manager.open(&doc.id, doc.data.clone())?;
doc
},
};
Ok(doc)
let open_doc = self.controller.open(params, pool).await?;
Ok(open_doc.doc())
}
pub async fn apply_changeset(&self, params: ApplyChangesetParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
let _ = self.doc_manager.apply_changeset(&params.id, Bytes::from(params.data), pool).await?;
let data = self.doc_manager.read_doc(&params.id).await?;
let doc = Doc { id: params.id, data };
Ok(doc)
pub async fn apply_changeset(&self, params: DocChangeset, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
// let _ = self.doc_manager.apply_changeset(&params.id,
// Bytes::from(params.data), pool).await?;
//
// // workaround: compare the rust's delta with flutter's delta. Will be removed
// // very soon
// let doc = self.doc_manager.read_doc(&params.id)?;
// Ok(doc)
unimplemented!()
}
}

View File

@ -229,6 +229,7 @@ pub struct Doc {
// message fields
pub id: ::std::string::String,
pub data: ::std::vec::Vec<u8>,
pub revision: i64,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
@ -296,6 +297,21 @@ impl Doc {
pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
::std::mem::replace(&mut self.data, ::std::vec::Vec::new())
}
// int64 revision = 3;
pub fn get_revision(&self) -> i64 {
self.revision
}
pub fn clear_revision(&mut self) {
self.revision = 0;
}
// Param is passed by value, moved
pub fn set_revision(&mut self, v: i64) {
self.revision = v;
}
}
impl ::protobuf::Message for Doc {
@ -313,6 +329,13 @@ impl ::protobuf::Message for Doc {
2 => {
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?;
},
3 => {
if wire_type != ::protobuf::wire_format::WireTypeVarint {
return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type));
}
let tmp = is.read_int64()?;
self.revision = tmp;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
},
@ -331,6 +354,9 @@ impl ::protobuf::Message for Doc {
if !self.data.is_empty() {
my_size += ::protobuf::rt::bytes_size(2, &self.data);
}
if self.revision != 0 {
my_size += ::protobuf::rt::value_size(3, self.revision, ::protobuf::wire_format::WireTypeVarint);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
my_size
@ -343,6 +369,9 @@ impl ::protobuf::Message for Doc {
if !self.data.is_empty() {
os.write_bytes(2, &self.data)?;
}
if self.revision != 0 {
os.write_int64(3, self.revision)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
}
@ -391,6 +420,11 @@ impl ::protobuf::Message for Doc {
|m: &Doc| { &m.data },
|m: &mut Doc| { &mut m.data },
));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeInt64>(
"revision",
|m: &Doc| { &m.revision },
|m: &mut Doc| { &mut m.revision },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<Doc>(
"Doc",
fields,
@ -409,6 +443,7 @@ impl ::protobuf::Clear for Doc {
fn clear(&mut self) {
self.id.clear();
self.data.clear();
self.revision = 0;
self.unknown_fields.clear();
}
}
@ -426,23 +461,23 @@ impl ::protobuf::reflect::ProtobufValue for Doc {
}
#[derive(PartialEq,Clone,Default)]
pub struct SaveDocParams {
pub struct UpdateDocParams {
// message fields
pub id: ::std::string::String,
pub data: ::std::vec::Vec<u8>,
pub doc_data: ::std::vec::Vec<u8>,
// special fields
pub unknown_fields: ::protobuf::UnknownFields,
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a SaveDocParams {
fn default() -> &'a SaveDocParams {
<SaveDocParams as ::protobuf::Message>::default_instance()
impl<'a> ::std::default::Default for &'a UpdateDocParams {
fn default() -> &'a UpdateDocParams {
<UpdateDocParams as ::protobuf::Message>::default_instance()
}
}
impl SaveDocParams {
pub fn new() -> SaveDocParams {
impl UpdateDocParams {
pub fn new() -> UpdateDocParams {
::std::default::Default::default()
}
@ -472,34 +507,34 @@ impl SaveDocParams {
::std::mem::replace(&mut self.id, ::std::string::String::new())
}
// bytes data = 2;
// bytes doc_data = 2;
pub fn get_data(&self) -> &[u8] {
&self.data
pub fn get_doc_data(&self) -> &[u8] {
&self.doc_data
}
pub fn clear_data(&mut self) {
self.data.clear();
pub fn clear_doc_data(&mut self) {
self.doc_data.clear();
}
// Param is passed by value, moved
pub fn set_data(&mut self, v: ::std::vec::Vec<u8>) {
self.data = v;
pub fn set_doc_data(&mut self, v: ::std::vec::Vec<u8>) {
self.doc_data = v;
}
// Mutable pointer to the field.
// If field is not initialized, it is initialized with default value first.
pub fn mut_data(&mut self) -> &mut ::std::vec::Vec<u8> {
&mut self.data
pub fn mut_doc_data(&mut self) -> &mut ::std::vec::Vec<u8> {
&mut self.doc_data
}
// Take field
pub fn take_data(&mut self) -> ::std::vec::Vec<u8> {
::std::mem::replace(&mut self.data, ::std::vec::Vec::new())
pub fn take_doc_data(&mut self) -> ::std::vec::Vec<u8> {
::std::mem::replace(&mut self.doc_data, ::std::vec::Vec::new())
}
}
impl ::protobuf::Message for SaveDocParams {
impl ::protobuf::Message for UpdateDocParams {
fn is_initialized(&self) -> bool {
true
}
@ -512,7 +547,7 @@ impl ::protobuf::Message for SaveDocParams {
::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?;
},
2 => {
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.data)?;
::protobuf::rt::read_singular_proto3_bytes_into(wire_type, is, &mut self.doc_data)?;
},
_ => {
::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?;
@ -529,8 +564,8 @@ impl ::protobuf::Message for SaveDocParams {
if !self.id.is_empty() {
my_size += ::protobuf::rt::string_size(1, &self.id);
}
if !self.data.is_empty() {
my_size += ::protobuf::rt::bytes_size(2, &self.data);
if !self.doc_data.is_empty() {
my_size += ::protobuf::rt::bytes_size(2, &self.doc_data);
}
my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields());
self.cached_size.set(my_size);
@ -541,8 +576,8 @@ impl ::protobuf::Message for SaveDocParams {
if !self.id.is_empty() {
os.write_string(1, &self.id)?;
}
if !self.data.is_empty() {
os.write_bytes(2, &self.data)?;
if !self.doc_data.is_empty() {
os.write_bytes(2, &self.doc_data)?;
}
os.write_unknown_fields(self.get_unknown_fields())?;
::std::result::Result::Ok(())
@ -574,8 +609,8 @@ impl ::protobuf::Message for SaveDocParams {
Self::descriptor_static()
}
fn new() -> SaveDocParams {
SaveDocParams::new()
fn new() -> UpdateDocParams {
UpdateDocParams::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -584,50 +619,50 @@ impl ::protobuf::Message for SaveDocParams {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"id",
|m: &SaveDocParams| { &m.id },
|m: &mut SaveDocParams| { &mut m.id },
|m: &UpdateDocParams| { &m.id },
|m: &mut UpdateDocParams| { &mut m.id },
));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"data",
|m: &SaveDocParams| { &m.data },
|m: &mut SaveDocParams| { &mut m.data },
"doc_data",
|m: &UpdateDocParams| { &m.doc_data },
|m: &mut UpdateDocParams| { &mut m.doc_data },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<SaveDocParams>(
"SaveDocParams",
::protobuf::reflect::MessageDescriptor::new_pb_name::<UpdateDocParams>(
"UpdateDocParams",
fields,
file_descriptor_proto()
)
})
}
fn default_instance() -> &'static SaveDocParams {
static instance: ::protobuf::rt::LazyV2<SaveDocParams> = ::protobuf::rt::LazyV2::INIT;
instance.get(SaveDocParams::new)
fn default_instance() -> &'static UpdateDocParams {
static instance: ::protobuf::rt::LazyV2<UpdateDocParams> = ::protobuf::rt::LazyV2::INIT;
instance.get(UpdateDocParams::new)
}
}
impl ::protobuf::Clear for SaveDocParams {
impl ::protobuf::Clear for UpdateDocParams {
fn clear(&mut self) {
self.id.clear();
self.data.clear();
self.doc_data.clear();
self.unknown_fields.clear();
}
}
impl ::std::fmt::Debug for SaveDocParams {
impl ::std::fmt::Debug for UpdateDocParams {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for SaveDocParams {
impl ::protobuf::reflect::ProtobufValue for UpdateDocParams {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self)
}
}
#[derive(PartialEq,Clone,Default)]
pub struct ApplyChangesetParams {
pub struct DocChangeset {
// message fields
pub id: ::std::string::String,
pub data: ::std::vec::Vec<u8>,
@ -636,14 +671,14 @@ pub struct ApplyChangesetParams {
pub cached_size: ::protobuf::CachedSize,
}
impl<'a> ::std::default::Default for &'a ApplyChangesetParams {
fn default() -> &'a ApplyChangesetParams {
<ApplyChangesetParams as ::protobuf::Message>::default_instance()
impl<'a> ::std::default::Default for &'a DocChangeset {
fn default() -> &'a DocChangeset {
<DocChangeset as ::protobuf::Message>::default_instance()
}
}
impl ApplyChangesetParams {
pub fn new() -> ApplyChangesetParams {
impl DocChangeset {
pub fn new() -> DocChangeset {
::std::default::Default::default()
}
@ -700,7 +735,7 @@ impl ApplyChangesetParams {
}
}
impl ::protobuf::Message for ApplyChangesetParams {
impl ::protobuf::Message for DocChangeset {
fn is_initialized(&self) -> bool {
true
}
@ -775,8 +810,8 @@ impl ::protobuf::Message for ApplyChangesetParams {
Self::descriptor_static()
}
fn new() -> ApplyChangesetParams {
ApplyChangesetParams::new()
fn new() -> DocChangeset {
DocChangeset::new()
}
fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor {
@ -785,29 +820,29 @@ impl ::protobuf::Message for ApplyChangesetParams {
let mut fields = ::std::vec::Vec::new();
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>(
"id",
|m: &ApplyChangesetParams| { &m.id },
|m: &mut ApplyChangesetParams| { &mut m.id },
|m: &DocChangeset| { &m.id },
|m: &mut DocChangeset| { &mut m.id },
));
fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBytes>(
"data",
|m: &ApplyChangesetParams| { &m.data },
|m: &mut ApplyChangesetParams| { &mut m.data },
|m: &DocChangeset| { &m.data },
|m: &mut DocChangeset| { &mut m.data },
));
::protobuf::reflect::MessageDescriptor::new_pb_name::<ApplyChangesetParams>(
"ApplyChangesetParams",
::protobuf::reflect::MessageDescriptor::new_pb_name::<DocChangeset>(
"DocChangeset",
fields,
file_descriptor_proto()
)
})
}
fn default_instance() -> &'static ApplyChangesetParams {
static instance: ::protobuf::rt::LazyV2<ApplyChangesetParams> = ::protobuf::rt::LazyV2::INIT;
instance.get(ApplyChangesetParams::new)
fn default_instance() -> &'static DocChangeset {
static instance: ::protobuf::rt::LazyV2<DocChangeset> = ::protobuf::rt::LazyV2::INIT;
instance.get(DocChangeset::new)
}
}
impl ::protobuf::Clear for ApplyChangesetParams {
impl ::protobuf::Clear for DocChangeset {
fn clear(&mut self) {
self.id.clear();
self.data.clear();
@ -815,13 +850,13 @@ impl ::protobuf::Clear for ApplyChangesetParams {
}
}
impl ::std::fmt::Debug for ApplyChangesetParams {
impl ::std::fmt::Debug for DocChangeset {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
::protobuf::text_format::fmt(self, f)
}
}
impl ::protobuf::reflect::ProtobufValue for ApplyChangesetParams {
impl ::protobuf::reflect::ProtobufValue for DocChangeset {
fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef {
::protobuf::reflect::ReflectValueRef::Message(self)
}
@ -988,44 +1023,48 @@ impl ::protobuf::reflect::ProtobufValue for QueryDocParams {
static file_descriptor_proto_data: &'static [u8] = b"\
\n\tdoc.proto\"5\n\x0fCreateDocParams\x12\x0e\n\x02id\x18\x01\x20\x01(\t\
R\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\x0cR\x04data\")\n\x03Doc\x12\
R\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\x0cR\x04data\"E\n\x03Doc\x12\
\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04data\x18\x02\x20\x01\
(\x0cR\x04data\"3\n\rSaveDocParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\
\x02id\x12\x12\n\x04data\x18\x02\x20\x01(\x0cR\x04data\":\n\x14ApplyChan\
gesetParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04data\
\x18\x02\x20\x01(\x0cR\x04data\"'\n\x0eQueryDocParams\x12\x15\n\x06doc_i\
d\x18\x01\x20\x01(\tR\x05docIdJ\xf9\x04\n\x06\x12\x04\0\0\x14\x01\n\x08\
\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\
\x03\x04\0\x01\x12\x03\x02\x08\x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\
\x04\x12\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\
\x02\0\x01\x12\x03\x03\x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\
\x11\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\
\x01\x05\x12\x03\x04\x04\t\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\n\
\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x04\x01\
\x12\x04\x06\0\t\x01\n\n\n\x03\x04\x01\x01\x12\x03\x06\x08\x0b\n\x0b\n\
\x04\x04\x01\x02\0\x12\x03\x07\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\
\x03\x07\x04\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x07\x0b\r\n\x0c\n\
\x05\x04\x01\x02\0\x03\x12\x03\x07\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\
\x12\x03\x08\x04\x13\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\t\n\
\x0c\n\x05\x04\x01\x02\x01\x01\x12\x03\x08\n\x0e\n\x0c\n\x05\x04\x01\x02\
\x01\x03\x12\x03\x08\x11\x12\n\n\n\x02\x04\x02\x12\x04\n\0\r\x01\n\n\n\
\x03\x04\x02\x01\x12\x03\n\x08\x15\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x0b\
\x04\x12\n\x0c\n\x05\x04\x02\x02\0\x05\x12\x03\x0b\x04\n\n\x0c\n\x05\x04\
\x02\x02\0\x01\x12\x03\x0b\x0b\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\
\x0b\x10\x11\n\x0b\n\x04\x04\x02\x02\x01\x12\x03\x0c\x04\x13\n\x0c\n\x05\
\x04\x02\x02\x01\x05\x12\x03\x0c\x04\t\n\x0c\n\x05\x04\x02\x02\x01\x01\
\x12\x03\x0c\n\x0e\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03\x0c\x11\x12\n\
\n\n\x02\x04\x03\x12\x04\x0e\0\x11\x01\n\n\n\x03\x04\x03\x01\x12\x03\x0e\
\x08\x1c\n\x0b\n\x04\x04\x03\x02\0\x12\x03\x0f\x04\x12\n\x0c\n\x05\x04\
\x03\x02\0\x05\x12\x03\x0f\x04\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\
\x0f\x0b\r\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03\x0f\x10\x11\n\x0b\n\x04\
\x04\x03\x02\x01\x12\x03\x10\x04\x13\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\
\x03\x10\x04\t\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03\x10\n\x0e\n\x0c\n\
\x05\x04\x03\x02\x01\x03\x12\x03\x10\x11\x12\n\n\n\x02\x04\x04\x12\x04\
\x12\0\x14\x01\n\n\n\x03\x04\x04\x01\x12\x03\x12\x08\x16\n\x0b\n\x04\x04\
\x04\x02\0\x12\x03\x13\x04\x16\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x13\
\x04\n\n\x0c\n\x05\x04\x04\x02\0\x01\x12\x03\x13\x0b\x11\n\x0c\n\x05\x04\
\x04\x02\0\x03\x12\x03\x13\x14\x15b\x06proto3\
(\x0cR\x04data\x12\x1a\n\x08revision\x18\x03\x20\x01(\x03R\x08revision\"\
<\n\x0fUpdateDocParams\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x19\
\n\x08doc_data\x18\x02\x20\x01(\x0cR\x07docData\"2\n\x0cDocChangeset\x12\
\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x12\n\x04data\x18\x02\x20\x01\
(\x0cR\x04data\"'\n\x0eQueryDocParams\x12\x15\n\x06doc_id\x18\x01\x20\
\x01(\tR\x05docIdJ\xb0\x05\n\x06\x12\x04\0\0\x15\x01\n\x08\n\x01\x0c\x12\
\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\
\x12\x03\x02\x08\x17\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x12\n\x0c\n\
\x05\x04\0\x02\0\x05\x12\x03\x03\x04\n\n\x0c\n\x05\x04\0\x02\0\x01\x12\
\x03\x03\x0b\r\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x10\x11\n\x0b\n\
\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\
\x03\x04\x04\t\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\n\x0e\n\x0c\n\
\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x04\x01\x12\x04\x06\
\0\n\x01\n\n\n\x03\x04\x01\x01\x12\x03\x06\x08\x0b\n\x0b\n\x04\x04\x01\
\x02\0\x12\x03\x07\x04\x12\n\x0c\n\x05\x04\x01\x02\0\x05\x12\x03\x07\x04\
\n\n\x0c\n\x05\x04\x01\x02\0\x01\x12\x03\x07\x0b\r\n\x0c\n\x05\x04\x01\
\x02\0\x03\x12\x03\x07\x10\x11\n\x0b\n\x04\x04\x01\x02\x01\x12\x03\x08\
\x04\x13\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x03\x08\x04\t\n\x0c\n\x05\
\x04\x01\x02\x01\x01\x12\x03\x08\n\x0e\n\x0c\n\x05\x04\x01\x02\x01\x03\
\x12\x03\x08\x11\x12\n\x0b\n\x04\x04\x01\x02\x02\x12\x03\t\x04\x17\n\x0c\
\n\x05\x04\x01\x02\x02\x05\x12\x03\t\x04\t\n\x0c\n\x05\x04\x01\x02\x02\
\x01\x12\x03\t\n\x12\n\x0c\n\x05\x04\x01\x02\x02\x03\x12\x03\t\x15\x16\n\
\n\n\x02\x04\x02\x12\x04\x0b\0\x0e\x01\n\n\n\x03\x04\x02\x01\x12\x03\x0b\
\x08\x17\n\x0b\n\x04\x04\x02\x02\0\x12\x03\x0c\x04\x12\n\x0c\n\x05\x04\
\x02\x02\0\x05\x12\x03\x0c\x04\n\n\x0c\n\x05\x04\x02\x02\0\x01\x12\x03\
\x0c\x0b\r\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03\x0c\x10\x11\n\x0b\n\x04\
\x04\x02\x02\x01\x12\x03\r\x04\x17\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\
\x03\r\x04\t\n\x0c\n\x05\x04\x02\x02\x01\x01\x12\x03\r\n\x12\n\x0c\n\x05\
\x04\x02\x02\x01\x03\x12\x03\r\x15\x16\n\n\n\x02\x04\x03\x12\x04\x0f\0\
\x12\x01\n\n\n\x03\x04\x03\x01\x12\x03\x0f\x08\x14\n\x0b\n\x04\x04\x03\
\x02\0\x12\x03\x10\x04\x12\n\x0c\n\x05\x04\x03\x02\0\x05\x12\x03\x10\x04\
\n\n\x0c\n\x05\x04\x03\x02\0\x01\x12\x03\x10\x0b\r\n\x0c\n\x05\x04\x03\
\x02\0\x03\x12\x03\x10\x10\x11\n\x0b\n\x04\x04\x03\x02\x01\x12\x03\x11\
\x04\x13\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03\x11\x04\t\n\x0c\n\x05\
\x04\x03\x02\x01\x01\x12\x03\x11\n\x0e\n\x0c\n\x05\x04\x03\x02\x01\x03\
\x12\x03\x11\x11\x12\n\n\n\x02\x04\x04\x12\x04\x13\0\x15\x01\n\n\n\x03\
\x04\x04\x01\x12\x03\x13\x08\x16\n\x0b\n\x04\x04\x04\x02\0\x12\x03\x14\
\x04\x16\n\x0c\n\x05\x04\x04\x02\0\x05\x12\x03\x14\x04\n\n\x0c\n\x05\x04\
\x04\x02\0\x01\x12\x03\x14\x0b\x11\n\x0c\n\x05\x04\x04\x02\0\x03\x12\x03\
\x14\x14\x15b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -218,6 +218,9 @@ pub enum ErrorCode {
DocIdInvalid = 0,
DocNotfound = 1,
WsConnectError = 10,
UndoFail = 200,
RedoFail = 201,
OutOfBound = 202,
UserUnauthorized = 999,
InternalError = 1000,
}
@ -232,6 +235,9 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
0 => ::std::option::Option::Some(ErrorCode::DocIdInvalid),
1 => ::std::option::Option::Some(ErrorCode::DocNotfound),
10 => ::std::option::Option::Some(ErrorCode::WsConnectError),
200 => ::std::option::Option::Some(ErrorCode::UndoFail),
201 => ::std::option::Option::Some(ErrorCode::RedoFail),
202 => ::std::option::Option::Some(ErrorCode::OutOfBound),
999 => ::std::option::Option::Some(ErrorCode::UserUnauthorized),
1000 => ::std::option::Option::Some(ErrorCode::InternalError),
_ => ::std::option::Option::None
@ -243,6 +249,9 @@ impl ::protobuf::ProtobufEnum for ErrorCode {
ErrorCode::DocIdInvalid,
ErrorCode::DocNotfound,
ErrorCode::WsConnectError,
ErrorCode::UndoFail,
ErrorCode::RedoFail,
ErrorCode::OutOfBound,
ErrorCode::UserUnauthorized,
ErrorCode::InternalError,
];
@ -274,29 +283,36 @@ impl ::protobuf::reflect::ProtobufValue for ErrorCode {
static file_descriptor_proto_data: &'static [u8] = b"\
\n\x0cerrors.proto\"<\n\x08DocError\x12\x1e\n\x04code\x18\x01\x20\x01(\
\x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*m\
\n\tErrorCode\x12\x10\n\x0cDocIdInvalid\x10\0\x12\x0f\n\x0bDocNotfound\
\x10\x01\x12\x12\n\x0eWsConnectError\x10\n\x12\x15\n\x10UserUnauthorized\
\x10\xe7\x07\x12\x12\n\rInternalError\x10\xe8\x07J\xfd\x02\n\x06\x12\x04\
\0\0\x0c\x01\n\x08\n\x01\x0c\x12\x03\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\
\0\x05\x01\n\n\n\x03\x04\0\x01\x12\x03\x02\x08\x10\n\x0b\n\x04\x04\0\x02\
\0\x12\x03\x03\x04\x17\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x03\x04\r\n\
\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x03\x0e\x12\n\x0c\n\x05\x04\0\x02\0\
\x03\x12\x03\x03\x15\x16\n\x0b\n\x04\x04\0\x02\x01\x12\x03\x04\x04\x13\n\
\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\
\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\x04\0\x02\x01\x03\x12\x03\x04\x11\
\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x0c\x01\n\n\n\x03\x05\0\x01\x12\x03\
\x06\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\x03\x07\x04\x15\n\x0c\n\x05\x05\
\0\x02\0\x01\x12\x03\x07\x04\x10\n\x0c\n\x05\x05\0\x02\0\x02\x12\x03\x07\
\x13\x14\n\x0b\n\x04\x05\0\x02\x01\x12\x03\x08\x04\x14\n\x0c\n\x05\x05\0\
\x02\x01\x01\x12\x03\x08\x04\x0f\n\x0c\n\x05\x05\0\x02\x01\x02\x12\x03\
\x08\x12\x13\n\x0b\n\x04\x05\0\x02\x02\x12\x03\t\x04\x18\n\x0c\n\x05\x05\
\0\x02\x02\x01\x12\x03\t\x04\x12\n\x0c\n\x05\x05\0\x02\x02\x02\x12\x03\t\
\x15\x17\n\x0b\n\x04\x05\0\x02\x03\x12\x03\n\x04\x1b\n\x0c\n\x05\x05\0\
\x02\x03\x01\x12\x03\n\x04\x14\n\x0c\n\x05\x05\0\x02\x03\x02\x12\x03\n\
\x17\x1a\n\x0b\n\x04\x05\0\x02\x04\x12\x03\x0b\x04\x19\n\x0c\n\x05\x05\0\
\x02\x04\x01\x12\x03\x0b\x04\x11\n\x0c\n\x05\x05\0\x02\x04\x02\x12\x03\
\x0b\x14\x18b\x06proto3\
\x0e2\n.ErrorCodeR\x04code\x12\x10\n\x03msg\x18\x02\x20\x01(\tR\x03msg*\
\x9c\x01\n\tErrorCode\x12\x10\n\x0cDocIdInvalid\x10\0\x12\x0f\n\x0bDocNo\
tfound\x10\x01\x12\x12\n\x0eWsConnectError\x10\n\x12\r\n\x08UndoFail\x10\
\xc8\x01\x12\r\n\x08RedoFail\x10\xc9\x01\x12\x0f\n\nOutOfBound\x10\xca\
\x01\x12\x15\n\x10UserUnauthorized\x10\xe7\x07\x12\x12\n\rInternalError\
\x10\xe8\x07J\xf8\x03\n\x06\x12\x04\0\0\x0f\x01\n\x08\n\x01\x0c\x12\x03\
\0\0\x12\n\n\n\x02\x04\0\x12\x04\x02\0\x05\x01\n\n\n\x03\x04\0\x01\x12\
\x03\x02\x08\x10\n\x0b\n\x04\x04\0\x02\0\x12\x03\x03\x04\x17\n\x0c\n\x05\
\x04\0\x02\0\x06\x12\x03\x03\x04\r\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\
\x03\x0e\x12\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x03\x15\x16\n\x0b\n\x04\
\x04\0\x02\x01\x12\x03\x04\x04\x13\n\x0c\n\x05\x04\0\x02\x01\x05\x12\x03\
\x04\x04\n\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03\x04\x0b\x0e\n\x0c\n\x05\
\x04\0\x02\x01\x03\x12\x03\x04\x11\x12\n\n\n\x02\x05\0\x12\x04\x06\0\x0f\
\x01\n\n\n\x03\x05\0\x01\x12\x03\x06\x05\x0e\n\x0b\n\x04\x05\0\x02\0\x12\
\x03\x07\x04\x15\n\x0c\n\x05\x05\0\x02\0\x01\x12\x03\x07\x04\x10\n\x0c\n\
\x05\x05\0\x02\0\x02\x12\x03\x07\x13\x14\n\x0b\n\x04\x05\0\x02\x01\x12\
\x03\x08\x04\x14\n\x0c\n\x05\x05\0\x02\x01\x01\x12\x03\x08\x04\x0f\n\x0c\
\n\x05\x05\0\x02\x01\x02\x12\x03\x08\x12\x13\n\x0b\n\x04\x05\0\x02\x02\
\x12\x03\t\x04\x18\n\x0c\n\x05\x05\0\x02\x02\x01\x12\x03\t\x04\x12\n\x0c\
\n\x05\x05\0\x02\x02\x02\x12\x03\t\x15\x17\n\x0b\n\x04\x05\0\x02\x03\x12\
\x03\n\x04\x13\n\x0c\n\x05\x05\0\x02\x03\x01\x12\x03\n\x04\x0c\n\x0c\n\
\x05\x05\0\x02\x03\x02\x12\x03\n\x0f\x12\n\x0b\n\x04\x05\0\x02\x04\x12\
\x03\x0b\x04\x13\n\x0c\n\x05\x05\0\x02\x04\x01\x12\x03\x0b\x04\x0c\n\x0c\
\n\x05\x05\0\x02\x04\x02\x12\x03\x0b\x0f\x12\n\x0b\n\x04\x05\0\x02\x05\
\x12\x03\x0c\x04\x15\n\x0c\n\x05\x05\0\x02\x05\x01\x12\x03\x0c\x04\x0e\n\
\x0c\n\x05\x05\0\x02\x05\x02\x12\x03\x0c\x11\x14\n\x0b\n\x04\x05\0\x02\
\x06\x12\x03\r\x04\x1b\n\x0c\n\x05\x05\0\x02\x06\x01\x12\x03\r\x04\x14\n\
\x0c\n\x05\x05\0\x02\x06\x02\x12\x03\r\x17\x1a\n\x0b\n\x04\x05\0\x02\x07\
\x12\x03\x0e\x04\x19\n\x0c\n\x05\x05\0\x02\x07\x01\x12\x03\x0e\x04\x11\n\
\x0c\n\x05\x05\0\x02\x07\x02\x12\x03\x0e\x14\x18b\x06proto3\
";
static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT;

View File

@ -7,12 +7,13 @@ message CreateDocParams {
message Doc {
string id = 1;
bytes data = 2;
int64 revision = 3;
}
message SaveDocParams {
message UpdateDocParams {
string id = 1;
bytes data = 2;
bytes doc_data = 2;
}
message ApplyChangesetParams {
message DocChangeset {
string id = 1;
bytes data = 2;
}

View File

@ -8,6 +8,9 @@ enum ErrorCode {
DocIdInvalid = 0;
DocNotfound = 1;
WsConnectError = 10;
UndoFail = 200;
RedoFail = 201;
OutOfBound = 202;
UserUnauthorized = 999;
InternalError = 1000;
}

View File

@ -0,0 +1,48 @@
use crate::{
entities::doc::Doc,
errors::DocError,
services::{
open_doc::{DocId, OpenedDoc},
ws::WsManager,
},
};
use bytes::Bytes;
use dashmap::DashMap;
use flowy_database::ConnectionPool;
use flowy_ot::{core::Delta, errors::OTError};
use parking_lot::RwLock;
use std::{convert::TryInto, fmt::Debug, sync::Arc};
pub(crate) struct DocCache {
doc_map: DashMap<DocId, Arc<OpenedDoc>>,
}
impl DocCache {
pub(crate) fn new() -> Self { Self { doc_map: DashMap::new() } }
pub(crate) fn set(&self, doc: Arc<OpenedDoc>) -> Result<(), DocError> {
self.doc_map.insert(doc.id.clone(), doc);
Ok(())
}
pub(crate) fn is_opened(&self, doc_id: &str) -> bool {
let doc_id: DocId = doc_id.into();
self.doc_map.get(&doc_id).is_some()
}
pub(crate) fn get(&self, doc_id: &str) -> Result<Arc<OpenedDoc>, DocError> {
if !self.is_opened(&doc_id) {
return Err(doc_not_found());
}
let doc_id: DocId = doc_id.into();
let opened_doc = self.doc_map.get(&doc_id).unwrap();
Ok(opened_doc.clone())
}
pub(crate) fn remove(&self, id: &str) {
let doc_id: DocId = id.into();
self.doc_map.remove(&doc_id);
}
}
fn doc_not_found() -> DocError { DocError::not_found().context("Doc is close or you should call open first") }

View File

@ -1,8 +1,8 @@
use crate::{client::DocumentData, errors::OTError};
use crate::{errors::DocError, services::doc::DocumentData};
use serde::{Deserialize, Serialize};
impl<T: AsRef<str>> DocumentData for T {
fn into_string(self) -> Result<String, OTError> { Ok(self.as_ref().to_string()) }
fn into_string(self) -> Result<String, DocError> { Ok(self.as_ref().to_string()) }
}
#[derive(Serialize, Deserialize, Debug)]
@ -11,7 +11,7 @@ pub struct ImageData {
}
impl DocumentData for ImageData {
fn into_string(self) -> Result<String, OTError> {
fn into_string(self) -> Result<String, DocError> {
let s = serde_json::to_string(&self)?;
Ok(s)
}

View File

@ -1,12 +1,13 @@
use crate::{
client::{view::View, History, RevId, UndoResult, RECORD_THRESHOLD},
core::*,
errors::{ErrorBuilder, OTError, OTErrorCode, OTErrorCode::*},
errors::DocError,
services::doc::{view::View, History, UndoResult, RECORD_THRESHOLD},
};
use bytes::Bytes;
use flowy_ot::core::*;
use std::convert::TryInto;
pub trait DocumentData {
fn into_string(self) -> Result<String, OTError>;
fn into_string(self) -> Result<String, DocError>;
}
pub trait CustomDocument {
@ -23,6 +24,19 @@ impl CustomDocument for FlowyDoc {
fn init_delta() -> Delta { DeltaBuilder::new().insert("\n").build() }
}
#[derive(Debug, Clone)]
pub struct RevId(pub usize);
#[derive(Debug, Clone)]
pub struct Revision {
rev_id: RevId,
pub delta: Delta,
}
impl Revision {
pub fn new(rev_id: RevId, delta: Delta) -> Revision { Self { rev_id, delta } }
}
pub struct Document {
delta: Delta,
history: History,
@ -44,7 +58,7 @@ impl Document {
}
}
pub fn from_json(json: &str) -> Result<Self, OTError> {
pub fn from_json(json: &str) -> Result<Self, DocError> {
let delta = Delta::from_json(json)?;
Ok(Self::from_delta(delta))
}
@ -55,18 +69,20 @@ impl Document {
pub fn to_string(&self) -> String { self.delta.apply("").unwrap() }
pub fn apply_changeset<T>(&mut self, changeset: T) -> Result<(), OTError>
where
T: TryInto<Delta, Error = OTError>,
{
let new_delta: Delta = changeset.try_into()?;
log::debug!("Delta changeset: {}", new_delta);
pub fn apply_delta(&mut self, data: Bytes) -> Result<(), DocError> {
let new_delta = Delta::from_bytes(data.to_vec())?;
log::debug!("Apply delta: {}", new_delta);
let rev_id = self.next_rev_id();
let revision = Revision::new(rev_id, new_delta.clone());
let _ = self.add_delta(&new_delta)?;
log::debug!("Document: {}", self.to_json());
Ok(())
}
pub fn insert<T: DocumentData>(&mut self, index: usize, data: T) -> Result<Delta, OTError> {
pub fn insert<T: DocumentData>(&mut self, index: usize, data: T) -> Result<Delta, DocError> {
let interval = Interval::new(index, index);
let _ = validate_interval(&self.delta, &interval)?;
@ -77,7 +93,7 @@ impl Document {
Ok(delta)
}
pub fn delete(&mut self, interval: Interval) -> Result<Delta, OTError> {
pub fn delete(&mut self, interval: Interval) -> Result<Delta, DocError> {
let _ = validate_interval(&self.delta, &interval)?;
debug_assert_eq!(interval.is_empty(), false);
let delete = self.view.delete(&self.delta, interval)?;
@ -88,7 +104,7 @@ impl Document {
Ok(delete)
}
pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<(), OTError> {
pub fn format(&mut self, interval: Interval, attribute: Attribute) -> Result<(), DocError> {
let _ = validate_interval(&self.delta, &interval)?;
log::trace!("format with {} at {}", attribute, interval);
let format_delta = self.view.format(&self.delta, attribute.clone(), interval).unwrap();
@ -98,7 +114,7 @@ impl Document {
Ok(())
}
pub fn replace<T: DocumentData>(&mut self, interval: Interval, data: T) -> Result<Delta, OTError> {
pub fn replace<T: DocumentData>(&mut self, interval: Interval, data: T) -> Result<Delta, DocError> {
let _ = validate_interval(&self.delta, &interval)?;
let mut delta = Delta::default();
let text = data.into_string()?;
@ -120,9 +136,9 @@ impl Document {
pub fn can_redo(&self) -> bool { self.history.can_redo() }
pub fn undo(&mut self) -> Result<UndoResult, OTError> {
pub fn undo(&mut self) -> Result<UndoResult, DocError> {
match self.history.undo() {
None => Err(ErrorBuilder::new(UndoFail).msg("Undo stack is empty").build()),
None => Err(DocError::undo().context("Undo stack is empty")),
Some(undo_delta) => {
let (new_delta, inverted_delta) = self.invert_change(&undo_delta)?;
let result = UndoResult::success(new_delta.target_len as usize);
@ -134,9 +150,9 @@ impl Document {
}
}
pub fn redo(&mut self) -> Result<UndoResult, OTError> {
pub fn redo(&mut self) -> Result<UndoResult, DocError> {
match self.history.redo() {
None => Err(ErrorBuilder::new(RedoFail).build()),
None => Err(DocError::redo()),
Some(redo_delta) => {
let (new_delta, inverted_delta) = self.invert_change(&redo_delta)?;
let result = UndoResult::success(new_delta.target_len as usize);
@ -154,7 +170,7 @@ impl Document {
}
impl Document {
fn add_delta(&mut self, delta: &Delta) -> Result<(), OTError> {
fn add_delta(&mut self, delta: &Delta) -> Result<(), DocError> {
let composed_delta = self.delta.compose(delta)?;
let mut undo_delta = delta.invert(&self.delta);
self.rev_id_counter += 1;
@ -181,7 +197,7 @@ impl Document {
Ok(())
}
fn invert_change(&self, change: &Delta) -> Result<(Delta, Delta), OTError> {
fn invert_change(&self, change: &Delta) -> Result<(Delta, Delta), DocError> {
// c = a.compose(b)
// d = b.invert(a)
// a = c.compose(d)
@ -195,10 +211,10 @@ impl Document {
fn next_rev_id(&self) -> RevId { RevId(self.rev_id_counter) }
}
fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), OTError> {
fn validate_interval(delta: &Delta, interval: &Interval) -> Result<(), DocError> {
if delta.target_len < interval.end {
log::error!("{:?} out of bounds. should 0..{}", interval, delta.target_len);
return Err(ErrorBuilder::new(OTErrorCode::IntervalOutOfBound).build());
return Err(DocError::out_of_bound());
}
Ok(())
}

View File

@ -1,7 +1,5 @@
use crate::{
client::extensions::DeleteExt,
core::{Delta, DeltaBuilder, Interval},
};
use crate::services::doc::extensions::DeleteExt;
use flowy_ot::core::{Delta, DeltaBuilder, Interval};
pub struct DefaultDelete {}
impl DeleteExt for DefaultDelete {

View File

@ -1,7 +1,5 @@
use crate::{
client::{extensions::DeleteExt, util::is_newline},
core::{plain_attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, Interval, NEW_LINE},
};
use crate::services::doc::{extensions::DeleteExt, util::is_newline};
use flowy_ot::core::{plain_attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, Interval, NEW_LINE};
pub struct PreserveLineFormatOnMerge {}
impl DeleteExt for PreserveLineFormatOnMerge {

View File

@ -1,7 +1,5 @@
use crate::{
client::util::find_newline,
core::{plain_attributes, Attribute, AttributeScope, Delta, Operation},
};
use crate::services::doc::util::find_newline;
use flowy_ot::core::{plain_attributes, Attribute, AttributeScope, Delta, Operation};
pub(crate) fn line_break(op: &Operation, attribute: &Attribute, scope: AttributeScope) -> Delta {
let mut new_delta = Delta::new();

View File

@ -1,10 +1,8 @@
use crate::{
client::{
extensions::{format::helper::line_break, FormatExt},
util::find_newline,
},
core::{plain_attributes, Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval},
use crate::services::doc::{
extensions::{format::helper::line_break, FormatExt},
util::find_newline,
};
use flowy_ot::core::{plain_attributes, Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval};
pub struct ResolveBlockFormat {}
impl FormatExt for ResolveBlockFormat {

View File

@ -1,10 +1,8 @@
use crate::{
client::{
extensions::{format::helper::line_break, FormatExt},
util::find_newline,
},
core::{Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval},
use crate::services::doc::{
extensions::{format::helper::line_break, FormatExt},
util::find_newline,
};
use flowy_ot::core::{Attribute, AttributeScope, Delta, DeltaBuilder, DeltaIter, Interval};
pub struct ResolveInlineFormat {}
impl FormatExt for ResolveInlineFormat {

View File

@ -1,9 +1,5 @@
use crate::{
client::{extensions::InsertExt, util::is_newline},
core::{AttributeKey, Delta, DeltaBuilder, DeltaIter},
};
use crate::core::{attributes_except_header, is_empty_line_at_index};
use crate::services::doc::{extensions::InsertExt, util::is_newline};
use flowy_ot::core::{attributes_except_header, is_empty_line_at_index, AttributeKey, Delta, DeltaBuilder, DeltaIter};
pub struct AutoExitBlock {}

View File

@ -1,7 +1,8 @@
use crate::{
client::{extensions::InsertExt, util::is_whitespace},
core::{Delta, DeltaIter},
};
use crate::services::doc::{extensions::InsertExt, util::is_whitespace};
use bytecount::num_chars;
use flowy_ot::core::{plain_attributes, Attribute, Attributes, Delta, DeltaBuilder, DeltaIter};
use std::cmp::min;
use url::Url;
pub struct AutoFormatExt {}
impl InsertExt for AutoFormatExt {
@ -50,11 +51,6 @@ impl InsertExt for AutoFormatExt {
}
}
use crate::core::{plain_attributes, Attribute, Attributes, DeltaBuilder};
use bytecount::num_chars;
use std::cmp::min;
use url::Url;
pub enum AutoFormatter {
Url(Url),
}

View File

@ -1,7 +1,5 @@
use crate::{
client::extensions::InsertExt,
core::{AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, NEW_LINE},
};
use crate::services::doc::extensions::InsertExt;
use flowy_ot::core::{AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, NEW_LINE};
pub struct DefaultInsertAttribute {}
impl InsertExt for DefaultInsertAttribute {

View File

@ -1,6 +1,8 @@
use crate::services::doc::extensions::InsertExt;
pub use auto_exit_block::*;
pub use auto_format::*;
pub use default_insert::*;
use flowy_ot::core::Delta;
pub use preserve_block_format::*;
pub use preserve_inline_format::*;
pub use reset_format_on_new_line::*;
@ -12,8 +14,6 @@ mod preserve_block_format;
mod preserve_inline_format;
mod reset_format_on_new_line;
use crate::{client::extensions::InsertExt, core::Delta};
pub struct InsertEmbedsExt {}
impl InsertExt for InsertEmbedsExt {
fn ext_name(&self) -> &str { "InsertEmbedsExt" }

View File

@ -1,6 +1,14 @@
use crate::{
client::{extensions::InsertExt, util::is_newline},
core::{attributes_except_header, plain_attributes, Attribute, AttributeKey, Attributes, Delta, DeltaBuilder, DeltaIter, NEW_LINE},
use crate::services::doc::{extensions::InsertExt, util::is_newline};
use flowy_ot::core::{
attributes_except_header,
plain_attributes,
Attribute,
AttributeKey,
Attributes,
Delta,
DeltaBuilder,
DeltaIter,
NEW_LINE,
};
pub struct PreserveBlockFormatOnInsert {}

View File

@ -1,10 +1,8 @@
use crate::{
client::{
extensions::InsertExt,
util::{contain_newline, is_newline},
},
core::{plain_attributes, AttributeKey, Delta, DeltaBuilder, DeltaIter, OpNewline, NEW_LINE},
use crate::services::doc::{
extensions::InsertExt,
util::{contain_newline, is_newline},
};
use flowy_ot::core::{plain_attributes, AttributeKey, Delta, DeltaBuilder, DeltaIter, OpNewline, NEW_LINE};
pub struct PreserveInlineFormat {}
impl InsertExt for PreserveInlineFormat {

View File

@ -1,7 +1,5 @@
use crate::{
client::{extensions::InsertExt, util::is_newline},
core::{AttributeKey, Attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, NEW_LINE},
};
use crate::services::doc::{extensions::InsertExt, util::is_newline};
use flowy_ot::core::{AttributeKey, Attributes, CharMetric, Delta, DeltaBuilder, DeltaIter, NEW_LINE};
pub struct ResetLineFormatOnNewLine {}
impl InsertExt for ResetLineFormatOnNewLine {

View File

@ -2,7 +2,7 @@ pub use delete::*;
pub use format::*;
pub use insert::*;
use crate::core::{Attribute, Delta, Interval};
use flowy_ot::core::{Attribute, Delta, Interval};
mod delete;
mod format;

View File

@ -1,20 +1,7 @@
use crate::core::Delta;
use flowy_ot::core::Delta;
const MAX_UNDOS: usize = 20;
#[derive(Debug, Clone)]
pub struct RevId(pub usize);
#[derive(Debug, Clone)]
pub struct Revision {
rev_id: RevId,
pub delta: Delta,
}
impl Revision {
pub fn new(rev_id: RevId, delta: Delta) -> Revision { Self { rev_id, delta } }
}
#[derive(Debug, Clone)]
pub struct UndoResult {
success: bool,

View File

@ -1,4 +1,4 @@
use crate::core::{NEW_LINE, WHITESPACE};
use flowy_ot::core::{NEW_LINE, WHITESPACE};
#[inline]
pub fn find_newline(s: &str) -> Option<usize> {

View File

@ -1,5 +1,5 @@
use super::extensions::*;
use crate::{
use flowy_ot::{
core::{Attribute, Delta, Interval},
errors::{ErrorBuilder, OTError, OTErrorCode},
};

View File

@ -1,5 +1,5 @@
use crate::{
entities::doc::{CreateDocParams, Doc, QueryDocParams, SaveDocParams},
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
errors::DocError,
module::DocumentUser,
services::server::Server,
@ -7,20 +7,37 @@ use crate::{
};
use flowy_database::{ConnectionPool, SqliteConnection};
use crate::{errors::internal_error, services::open_doc::OpenedDocPersistence};
use crate::{
errors::internal_error,
services::{
cache::DocCache,
open_doc::{DocId, OpenedDoc, OpenedDocPersistence},
ws::WsManager,
},
};
use parking_lot::RwLock;
use std::sync::Arc;
use tokio::task::JoinHandle;
pub(crate) struct DocController {
server: Server,
sql: Arc<DocTableSql>,
ws: Arc<RwLock<WsManager>>,
cache: Arc<DocCache>,
user: Arc<dyn DocumentUser>,
}
impl DocController {
pub(crate) fn new(server: Server, user: Arc<dyn DocumentUser>) -> Self {
pub(crate) fn new(server: Server, user: Arc<dyn DocumentUser>, ws: Arc<RwLock<WsManager>>) -> Self {
let sql = Arc::new(DocTableSql {});
Self { sql, server, user }
let cache = Arc::new(DocCache::new());
Self {
sql,
server,
user,
ws,
cache,
}
}
#[tracing::instrument(skip(self, conn), err)]
@ -28,22 +45,53 @@ impl DocController {
let doc = Doc {
id: params.id,
data: params.data,
revision: 0,
};
let _ = self.sql.create_doc_table(DocTable::new(doc), conn)?;
Ok(())
}
#[tracing::instrument(level = "debug", skip(self, pool), err)]
pub(crate) async fn open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
match self._open(params.clone(), pool.clone()) {
Ok(doc_table) => Ok(doc_table.into()),
Err(error) => self.try_read_on_server(params, pool.clone(), error).await,
pub(crate) async fn open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Arc<OpenedDoc>, DocError> {
if self.cache.is_opened(&params.doc_id) == false {
return match self._open(params.clone(), pool.clone()) {
Ok(doc) => Ok(doc),
Err(error) => Err(error),
};
}
let doc = self.cache.get(&params.doc_id)?;
Ok(doc)
}
pub(crate) fn close(&self, doc_id: &str) -> Result<(), DocError> {
self.cache.remove(doc_id);
self.ws.write().remove_handler(doc_id);
Ok(())
}
// #[tracing::instrument(level = "debug", skip(self, changeset, pool), err)]
// pub(crate) async fn apply_changeset<T>(&self, id: T, changeset: Bytes, pool:
// Arc<ConnectionPool>) -> Result<(), DocError> where
// T: Into<DocId> + Debug,
// {
// let id = id.into();
// match self.doc_map.get(&id) {
// None => Err(doc_not_found()),
// Some(doc) => {
// let _ = doc.apply_delta(changeset, pool)?;
// Ok(())
// },
// }
// }
#[tracing::instrument(level = "debug", skip(self, conn), err)]
pub(crate) fn delete(&self, params: QueryDocParams, conn: &SqliteConnection) -> Result<(), DocError> {
let _ = self.sql.delete_doc(&params.doc_id, &*conn)?;
let doc_id = &params.doc_id;
let _ = self.sql.delete_doc(doc_id, &*conn)?;
self.cache.remove(doc_id);
self.ws.write().remove_handler(doc_id);
let _ = self.delete_doc_on_server(params)?;
Ok(())
}
@ -51,7 +99,7 @@ impl DocController {
impl DocController {
#[tracing::instrument(level = "debug", skip(self, params), err)]
fn update_doc_on_server(&self, params: SaveDocParams) -> Result<(), DocError> {
fn update_doc_on_server(&self, params: UpdateDocParams) -> Result<(), DocError> {
let token = self.user.token()?;
let server = self.server.clone();
tokio::spawn(async move {
@ -89,15 +137,6 @@ impl DocController {
}))
}
#[tracing::instrument(level = "debug", skip(self), err)]
async fn sync_read_doc_from_server(&self, params: QueryDocParams) -> Result<Doc, DocError> {
let token = self.user.token()?;
match self.server.read_doc(&token, params).await? {
None => Err(DocError::not_found()),
Some(doc) => Ok(doc),
}
}
#[tracing::instrument(level = "debug", skip(self), err)]
fn delete_doc_on_server(&self, params: QueryDocParams) -> Result<(), DocError> {
let token = self.user.token()?;
@ -114,25 +153,30 @@ impl DocController {
Ok(())
}
fn _open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Doc, DocError> {
let doc_table = self.sql.read_doc_table(&params.doc_id, &*(pool.get().map_err(internal_error)?))?;
let doc: Doc = doc_table.into();
let _ = self.read_doc_from_server(params, pool.clone())?;
Ok(doc)
}
fn _open(&self, params: QueryDocParams, pool: Arc<ConnectionPool>) -> Result<Arc<OpenedDoc>, DocError> {
match self.sql.read_doc_table(&params.doc_id, &*(pool.get().map_err(internal_error)?)) {
Ok(doc_table) => {
let doc = Arc::new(OpenedDoc::new(doc_table.into(), self.ws.read().sender.clone())?);
self.ws.write().register_handler(doc.id.as_ref(), doc.clone());
self.cache.set(doc.clone());
async fn try_read_on_server(&self, params: QueryDocParams, pool: Arc<ConnectionPool>, error: DocError) -> Result<Doc, DocError> {
if error.is_record_not_found() {
log::debug!("Doc:{} don't exist, reading from server", params.doc_id);
self.read_doc_from_server(params, pool)?.await.map_err(internal_error)?
} else {
Err(error)
Ok(doc)
},
Err(error) => {
if error.is_record_not_found() {
log::debug!("Doc:{} don't exist, reading from server", params.doc_id);
// TODO: notify doc update
let _ = self.read_doc_from_server(params, pool);
}
return Err(error);
},
}
}
}
impl OpenedDocPersistence for DocController {
fn save(&self, params: SaveDocParams, pool: Arc<ConnectionPool>) -> Result<(), DocError> {
fn save(&self, params: UpdateDocParams, pool: Arc<ConnectionPool>) -> Result<(), DocError> {
let changeset = DocTableChangeset::new(params.clone());
let _ = self.sql.update_doc_table(changeset, &*(pool.get().map_err(internal_error)?))?;
Ok(())

View File

@ -1,4 +1,6 @@
mod cache;
pub mod doc;
pub(crate) mod doc_controller;
pub(crate) mod open_doc;
mod open_doc;
pub mod server;
pub mod ws;

View File

@ -1,16 +1,19 @@
use crate::{
entities::{
doc::SaveDocParams,
doc::{Doc, UpdateDocParams},
ws::{WsDocumentData, WsSource},
},
errors::DocError,
services::ws::{WsHandler, WsSender},
services::{
doc::Document,
ws::{WsHandler, WsSender},
},
};
use bytes::Bytes;
use flowy_database::ConnectionPool;
use flowy_ot::{client::Document, core::Delta};
use flowy_ot::core::Delta;
use parking_lot::RwLock;
use std::sync::Arc;
use std::{convert::TryInto, sync::Arc};
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct DocId(pub(crate) String);
@ -25,32 +28,42 @@ where
}
pub(crate) trait OpenedDocPersistence: Send + Sync {
fn save(&self, params: SaveDocParams, pool: Arc<ConnectionPool>) -> Result<(), DocError>;
fn save(&self, params: UpdateDocParams, pool: Arc<ConnectionPool>) -> Result<(), DocError>;
}
pub(crate) struct OpenedDoc {
pub(crate) id: DocId,
pub(crate) revision: i64,
document: RwLock<Document>,
ws_sender: Arc<dyn WsSender>,
persistence: Arc<dyn OpenedDocPersistence>,
}
impl OpenedDoc {
pub(crate) fn new(id: DocId, delta: Delta, persistence: Arc<dyn OpenedDocPersistence>, ws_sender: Arc<dyn WsSender>) -> Self {
pub(crate) fn new(doc: Doc, ws_sender: Arc<dyn WsSender>) -> Result<Self, DocError> {
let id: DocId = doc.id.into();
let revision = doc.revision;
let delta: Delta = doc.data.try_into()?;
let document = RwLock::new(Document::from_delta(delta));
Self {
Ok(Self {
id,
revision,
document,
ws_sender,
persistence,
})
}
pub(crate) fn doc(&self) -> Doc {
Doc {
id: self.id.0.clone(),
data: self.document.read().to_bytes(),
revision: self.revision,
}
}
pub(crate) fn data(&self) -> Vec<u8> { self.document.read().to_bytes() }
pub(crate) fn apply_delta(&self, data: Bytes, pool: Arc<ConnectionPool>) -> Result<(), DocError> {
let mut write_guard = self.document.write();
let _ = write_guard.apply_changeset(data.clone())?;
let _ = write_guard.apply_delta(data.clone())?;
match self.ws_sender.send_data(data) {
Ok(_) => {},
@ -61,11 +74,11 @@ impl OpenedDoc {
}
// Opti: strategy to save the document
let save = SaveDocParams {
let save = UpdateDocParams {
id: self.id.0.clone(),
data: write_guard.to_bytes(),
doc_data: write_guard.to_bytes(),
};
let _ = self.persistence.save(save, pool)?;
// let _ = self.persistence.save(save, pool)?;
Ok(())
}

View File

@ -1,94 +0,0 @@
use crate::{
errors::DocError,
services::{
open_doc::{DocId, OpenedDoc, OpenedDocPersistence},
ws::WsManager,
},
};
use bytes::Bytes;
use dashmap::DashMap;
use flowy_database::ConnectionPool;
use flowy_ot::{core::Delta, errors::OTError};
use parking_lot::RwLock;
use std::{convert::TryInto, fmt::Debug, sync::Arc};
pub(crate) struct OpenedDocManager {
doc_map: DashMap<DocId, Arc<OpenedDoc>>,
ws_manager: Arc<RwLock<WsManager>>,
persistence: Arc<dyn OpenedDocPersistence>,
}
impl OpenedDocManager {
pub(crate) fn new(ws_manager: Arc<RwLock<WsManager>>, persistence: Arc<dyn OpenedDocPersistence>) -> Self {
Self {
doc_map: DashMap::new(),
ws_manager,
persistence,
}
}
#[tracing::instrument(level = "debug", skip(self, data), err)]
pub(crate) fn open<T, D>(&self, id: T, data: D) -> Result<(), DocError>
where
T: Into<DocId> + Debug,
D: TryInto<Delta, Error = OTError>,
{
let doc = Arc::new(OpenedDoc::new(
id.into(),
data.try_into()?,
self.persistence.clone(),
self.ws_manager.read().sender.clone(),
));
self.ws_manager.write().register_handler(doc.id.as_ref(), doc.clone());
self.doc_map.insert(doc.id.clone(), doc.clone());
Ok(())
}
pub(crate) fn is_opened<T>(&self, id: T) -> bool
where
T: Into<DocId>,
{
let doc_id = id.into();
self.doc_map.get(&doc_id).is_some()
}
#[tracing::instrument(level = "debug", skip(self, changeset, pool), err)]
pub(crate) async fn apply_changeset<T>(&self, id: T, changeset: Bytes, pool: Arc<ConnectionPool>) -> Result<(), DocError>
where
T: Into<DocId> + Debug,
{
let id = id.into();
match self.doc_map.get(&id) {
None => Err(doc_not_found()),
Some(doc) => {
let _ = doc.apply_delta(changeset, pool)?;
Ok(())
},
}
}
pub(crate) async fn read_doc<T>(&self, id: T) -> Result<Vec<u8>, DocError>
where
T: Into<DocId> + Clone,
{
if !self.is_opened(id.clone()) {
return Err(doc_not_found());
}
let doc_id = id.into();
let doc = self.doc_map.get(&doc_id).unwrap();
Ok(doc.data())
}
pub(crate) fn close<T>(&self, id: T) -> Result<(), DocError>
where
T: Into<DocId>,
{
let doc_id = id.into();
self.doc_map.remove(&doc_id);
self.ws_manager.write().remove_handler(doc_id.as_ref());
Ok(())
}
}
fn doc_not_found() -> DocError { DocError::not_found().context("Doc is close or you should call open first") }

View File

@ -1,5 +0,0 @@
mod manager;
mod open_doc;
pub(crate) use manager::*;
pub use open_doc::*;

View File

@ -5,7 +5,7 @@ mod server_api_mock;
pub use server_api::*;
// TODO: ignore mock files in production
use crate::{
entities::doc::{CreateDocParams, Doc, QueryDocParams, SaveDocParams},
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
errors::DocError,
};
use flowy_infra::future::ResultFuture;
@ -18,7 +18,7 @@ pub trait DocumentServerAPI {
fn read_doc(&self, token: &str, params: QueryDocParams) -> ResultFuture<Option<Doc>, DocError>;
fn update_doc(&self, token: &str, params: SaveDocParams) -> ResultFuture<(), DocError>;
fn update_doc(&self, token: &str, params: UpdateDocParams) -> ResultFuture<(), DocError>;
fn delete_doc(&self, token: &str, params: QueryDocParams) -> ResultFuture<(), DocError>;
}

View File

@ -1,5 +1,5 @@
use crate::{
entities::doc::{CreateDocParams, Doc, QueryDocParams, SaveDocParams},
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
errors::DocError,
services::server::DocumentServerAPI,
};
@ -19,7 +19,7 @@ impl DocumentServerAPI for DocServer {
ResultFuture::new(async move { read_doc_request(&token, params, DOC_URL.as_ref()).await })
}
fn update_doc(&self, token: &str, params: SaveDocParams) -> ResultFuture<(), DocError> {
fn update_doc(&self, token: &str, params: UpdateDocParams) -> ResultFuture<(), DocError> {
let token = token.to_owned();
ResultFuture::new(async move { update_doc_request(&token, params, DOC_URL.as_ref()).await })
}
@ -53,7 +53,7 @@ pub async fn read_doc_request(token: &str, params: QueryDocParams, url: &str) ->
Ok(doc)
}
pub async fn update_doc_request(token: &str, params: SaveDocParams, url: &str) -> Result<(), DocError> {
pub async fn update_doc_request(token: &str, params: UpdateDocParams, url: &str) -> Result<(), DocError> {
let _ = request_builder()
.patch(&url.to_owned())
.header(HEADER_TOKEN, token)

View File

@ -1,5 +1,5 @@
use crate::{
entities::doc::{CreateDocParams, Doc, QueryDocParams, SaveDocParams},
entities::doc::{CreateDocParams, Doc, QueryDocParams, UpdateDocParams},
errors::DocError,
services::server::DocumentServerAPI,
};
@ -13,7 +13,7 @@ impl DocumentServerAPI for DocServerMock {
ResultFuture::new(async { Ok(None) })
}
fn update_doc(&self, _token: &str, _params: SaveDocParams) -> ResultFuture<(), DocError> { ResultFuture::new(async { Ok(()) }) }
fn update_doc(&self, _token: &str, _params: UpdateDocParams) -> ResultFuture<(), DocError> { ResultFuture::new(async { Ok(()) }) }
fn delete_doc(&self, _token: &str, _params: QueryDocParams) -> ResultFuture<(), DocError> { ResultFuture::new(async { Ok(()) }) }
}

View File

@ -1,4 +1,4 @@
use crate::entities::doc::{Doc, SaveDocParams};
use crate::entities::doc::{Doc, UpdateDocParams};
use flowy_database::schema::doc_table;
#[derive(PartialEq, Clone, Debug, Queryable, Identifiable, Insertable, Associations)]
@ -6,7 +6,7 @@ use flowy_database::schema::doc_table;
pub(crate) struct DocTable {
pub id: String,
pub data: Vec<u8>,
pub version: i64,
pub revision: i64,
}
impl DocTable {
@ -14,7 +14,7 @@ impl DocTable {
Self {
id: doc.id,
data: doc.data,
version: 0,
revision: 0,
}
}
}
@ -27,10 +27,10 @@ pub(crate) struct DocTableChangeset {
}
impl DocTableChangeset {
pub(crate) fn new(params: SaveDocParams) -> Self {
pub(crate) fn new(params: UpdateDocParams) -> Self {
Self {
id: params.id,
data: params.data,
data: params.doc_data,
}
}
}
@ -40,6 +40,7 @@ impl std::convert::Into<Doc> for DocTable {
Doc {
id: self.id,
data: self.data,
revision: self.revision,
}
}
}

View File

@ -1,10 +1,6 @@
pub mod helper;
use crate::helper::{TestOp::*, *};
use flowy_ot::{
client::{FlowyDoc, PlainDoc},
core::{Interval, NEW_LINE, WHITESPACE},
};
use crate::editor::{TestBuilder, TestOp::*};
use flowy_document::services::doc::{FlowyDoc, PlainDoc};
use flowy_ot::core::{Interval, NEW_LINE, WHITESPACE};
#[test]
fn attributes_bold_added() {

View File

@ -1,8 +1,11 @@
mod attribute_test;
mod op_test;
mod serde_test;
mod undo_redo_test;
use derive_more::Display;
use flowy_ot::{
client::{CustomDocument, Document},
core::*,
};
use flowy_document::services::doc::{CustomDocument, Document};
use flowy_ot::core::*;
use rand::{prelude::*, Rng as WrappedRng};
use std::{sync::Once, time::Duration};

View File

@ -1,9 +1,7 @@
pub mod helper;
use crate::helper::TestOp::*;
use crate::editor::{Rng, TestBuilder, TestOp::*};
use bytecount::num_chars;
use flowy_ot::{client::PlainDoc, core::*};
use helper::*;
use flowy_document::services::doc::PlainDoc;
use flowy_ot::core::*;
#[test]
fn attributes_insert_text() {

View File

@ -1,7 +1,5 @@
use flowy_ot::{
client::{Document, PlainDoc},
core::*,
};
use flowy_document::services::doc::{Document, PlainDoc};
use flowy_ot::core::*;
#[test]
fn operation_insert_serialize_test() {

View File

@ -1,10 +1,6 @@
pub mod helper;
use crate::helper::{TestOp::*, *};
use flowy_ot::{
client::{FlowyDoc, PlainDoc, RECORD_THRESHOLD},
core::{Interval, NEW_LINE, WHITESPACE},
};
use crate::editor::{TestBuilder, TestOp::*};
use flowy_document::services::doc::{FlowyDoc, PlainDoc, RECORD_THRESHOLD};
use flowy_ot::core::{Interval, NEW_LINE, WHITESPACE};
#[test]
fn history_insert_undo() {

View File

@ -0,0 +1 @@
mod editor;

View File

@ -11,17 +11,10 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = {version = "1.0"}
derive_more = {version = "0.99", features = ["display"]}
log = "0.4"
color-eyre = { version = "0.5", default-features = false }
chrono = "0.4.19"
lazy_static = "1.4.0"
url = "2.2"
strum = "0.21"
strum_macros = "0.21"
bytes = "1.0"
[dev-dependencies]
criterion = "0.3"
rand = "0.7.3"
env_logger = "0.8.2"

View File

@ -1,4 +1,2 @@
pub mod client;
pub mod core;
pub mod errors;
pub mod server;

View File

@ -1 +0,0 @@

View File

@ -3,7 +3,7 @@ use crate::{
errors::WorkspaceError,
};
use flowy_derive::ProtoBuf;
use flowy_document::entities::doc::{ApplyChangesetParams, SaveDocParams};
use flowy_document::entities::doc::{DocChangeset, UpdateDocParams};
use std::convert::TryInto;
#[derive(Default, ProtoBuf)]
@ -109,16 +109,19 @@ pub struct SaveViewDataRequest {
pub data: Vec<u8>,
}
impl TryInto<SaveDocParams> for SaveViewDataRequest {
impl TryInto<UpdateDocParams> for SaveViewDataRequest {
type Error = WorkspaceError;
fn try_into(self) -> Result<SaveDocParams, Self::Error> {
fn try_into(self) -> Result<UpdateDocParams, Self::Error> {
let view_id = ViewId::parse(self.view_id).map_err(|e| WorkspaceError::view_id().context(e))?.0;
// Opti: Vec<u8> -> Delta -> Vec<u8>
let data = DeltaData::parse(self.data).map_err(|e| WorkspaceError::view_data().context(e))?.0;
Ok(SaveDocParams { id: view_id, data })
Ok(UpdateDocParams {
id: view_id,
doc_data: data,
})
}
}
@ -131,15 +134,15 @@ pub struct ApplyChangesetRequest {
pub data: Vec<u8>,
}
impl TryInto<ApplyChangesetParams> for ApplyChangesetRequest {
impl TryInto<DocChangeset> for ApplyChangesetRequest {
type Error = WorkspaceError;
fn try_into(self) -> Result<ApplyChangesetParams, Self::Error> {
fn try_into(self) -> Result<DocChangeset, Self::Error> {
let view_id = ViewId::parse(self.view_id).map_err(|e| WorkspaceError::view_id().context(e))?.0;
// Opti: Vec<u8> -> Delta -> Vec<u8>
let data = DeltaData::parse(self.data).map_err(|e| WorkspaceError::view_data().context(e))?.0;
Ok(ApplyChangesetParams { id: view_id, data })
Ok(DocChangeset { id: view_id, data })
}
}

View File

@ -49,6 +49,6 @@ pub enum WorkspaceEvent {
#[event(input = "OpenViewRequest", output = "Doc")]
OpenView = 205,
#[event(input = "ApplyChangesetRequest", output = "Doc")]
#[event(input = "DocChangeset", output = "Doc")]
ApplyChangeset = 206,
}

View File

@ -16,7 +16,7 @@ use crate::{
services::ViewController,
};
use flowy_dispatch::prelude::{data_result, Data, DataResult, Unit};
use flowy_document::entities::doc::{ApplyChangesetParams, Doc, QueryDocParams};
use flowy_document::entities::doc::{Doc, DocChangeset, QueryDocParams};
use std::{convert::TryInto, sync::Arc};
#[tracing::instrument(skip(data, controller), err)]
@ -60,7 +60,7 @@ pub(crate) async fn apply_changeset_handler(
data: Data<ApplyChangesetRequest>,
controller: Unit<Arc<ViewController>>,
) -> DataResult<Doc, WorkspaceError> {
let params: ApplyChangesetParams = data.into_inner().try_into()?;
let params: DocChangeset = data.into_inner().try_into()?;
let doc = controller.apply_changeset(params).await?;
data_result(doc)
}

View File

@ -14,7 +14,7 @@ use crate::{
};
use flowy_database::SqliteConnection;
use flowy_document::{
entities::doc::{ApplyChangesetParams, CreateDocParams, Doc, QueryDocParams},
entities::doc::{CreateDocParams, Doc, DocChangeset, QueryDocParams},
module::FlowyDocument,
};
use std::sync::Arc;
@ -125,7 +125,7 @@ impl ViewController {
Ok(())
}
pub(crate) async fn apply_changeset(&self, params: ApplyChangesetParams) -> Result<Doc, WorkspaceError> {
pub(crate) async fn apply_changeset(&self, params: DocChangeset) -> Result<Doc, WorkspaceError> {
let pool = self.database.db_pool()?;
let doc = self.document.apply_changeset(params, pool).await?;
Ok(doc)