refactor(native): rename folder name

This commit is contained in:
LongYinan
2023-05-09 18:05:52 +08:00
parent 268636c440
commit ee1e50f391
13 changed files with 3 additions and 3 deletions

View File

@@ -0,0 +1,216 @@
use super::DynamicValue;
use jwst::{Block as JwstBlock, Workspace};
use lib0::any::Any;
#[napi()]
pub struct Block {
pub workspace: Workspace,
pub block: JwstBlock,
}
#[napi()]
impl Block {
#[napi(constructor)]
pub fn new(workspace: Workspace, block: JwstBlock) -> Self {
Self { workspace, block }
}
#[napi]
pub fn get(&self, key: String) -> Option<DynamicValue> {
self.workspace
.with_trx(|trx| self.block.get(&trx.trx, &key).map(DynamicValue::new))
}
#[napi]
pub fn children(&self) -> Vec<String> {
self.workspace.with_trx(|trx| self.block.children(&trx.trx))
}
#[napi]
pub fn push_children(&self, block: &Block) {
self.workspace
.with_trx(|mut trx| self.block.push_children(&mut trx.trx, &block.block));
}
#[napi]
pub fn insert_children_at(&self, block: &Block, pos: u32) {
self.workspace.with_trx(|mut trx| {
self.block
.insert_children_at(&mut trx.trx, &block.block, pos)
});
}
#[napi]
pub fn insert_children_before(&self, block: &Block, reference: &str) {
self.workspace.with_trx(|mut trx| {
self.block
.insert_children_before(&mut trx.trx, &block.block, reference)
});
}
#[napi]
pub fn insert_children_after(&self, block: &Block, reference: &str) {
self.workspace.with_trx(|mut trx| {
self.block
.insert_children_after(&mut trx.trx, &block.block, reference)
});
}
#[napi]
pub fn remove_children(&self, block: &Block) {
self.workspace
.with_trx(|mut trx| self.block.remove_children(&mut trx.trx, &block.block));
}
#[napi]
pub fn exists_children(&self, block_id: &str) -> i32 {
self.workspace
.with_trx(|trx| self.block.exists_children(&trx.trx, block_id))
.map(|i| i as i32)
.unwrap_or(-1)
}
#[napi]
pub fn parent(&self) -> String {
self.workspace
.with_trx(|trx| self.block.parent(&trx.trx).unwrap())
}
#[napi]
pub fn updated(&self) -> u64 {
self.workspace.with_trx(|trx| self.block.updated(&trx.trx))
}
#[napi]
pub fn id(&self) -> String {
self.block.block_id()
}
#[napi]
pub fn flavor(&self) -> String {
self.workspace.with_trx(|trx| self.block.flavor(&trx.trx))
}
#[napi]
pub fn version(&self) -> String {
self.workspace.with_trx(|trx| {
let [major, minor] = self.block.version(&trx.trx);
format!("{major}.{minor}")
})
}
#[napi]
pub fn created(&self) -> u64 {
self.workspace.with_trx(|trx| self.block.created(&trx.trx))
}
#[napi]
pub fn set_bool(&self, key: String, value: bool) {
self.workspace
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, value));
}
#[napi]
pub fn set_string(&self, key: String, value: String) {
self.workspace
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, value));
}
#[napi]
pub fn set_float(&self, key: String, value: f64) {
self.workspace
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, value));
}
#[napi]
pub fn set_integer(&self, key: String, value: i64) {
self.workspace
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, value));
}
#[napi]
pub fn set_null(&self, key: String) {
self.workspace
.with_trx(|mut trx| self.block.set(&mut trx.trx, &key, Any::Null));
}
#[napi]
pub fn is_bool(&self, key: String) -> bool {
self.workspace.with_trx(|trx| {
self.block
.get(&trx.trx, &key)
.map(|a| matches!(a, Any::Bool(_)))
.unwrap_or(false)
})
}
#[napi]
pub fn is_string(&self, key: String) -> bool {
self.workspace.with_trx(|trx| {
self.block
.get(&trx.trx, &key)
.map(|a| matches!(a, Any::String(_)))
.unwrap_or(false)
})
}
#[napi]
pub fn is_float(&self, key: String) -> bool {
self.workspace.with_trx(|trx| {
self.block
.get(&trx.trx, &key)
.map(|a| matches!(a, Any::Number(_)))
.unwrap_or(false)
})
}
#[napi]
pub fn is_integer(&self, key: String) -> bool {
self.workspace.with_trx(|trx| {
self.block
.get(&trx.trx, &key)
.map(|a| matches!(a, Any::BigInt(_)))
.unwrap_or(false)
})
}
#[napi]
pub fn get_bool(&self, key: String) -> Option<i64> {
self.workspace.with_trx(|trx| {
self.block.get(&trx.trx, &key).and_then(|a| match a {
Any::Bool(i) => Some(i.into()),
_ => None,
})
})
}
#[napi]
pub fn get_string(&self, key: String) -> Option<String> {
self.workspace.with_trx(|trx| {
self.block.get(&trx.trx, &key).and_then(|a| match a {
Any::String(i) => Some(i.into()),
_ => None,
})
})
}
#[napi]
pub fn get_float(&self, key: String) -> Option<f64> {
self.workspace.with_trx(|trx| {
self.block.get(&trx.trx, &key).and_then(|a| match a {
Any::Number(i) => Some(i),
_ => None,
})
})
}
#[napi]
pub fn get_integer(&self, key: String) -> Option<i64> {
self.workspace.with_trx(|trx| {
self.block.get(&trx.trx, &key).and_then(|a| match a {
Any::BigInt(i) => Some(i),
_ => None,
})
})
}
}

View File

@@ -0,0 +1,68 @@
use lib0::any::Any;
use std::collections::HashMap;
pub type DynamicValueMap = HashMap<String, DynamicValue>;
pub struct DynamicValue {
any: Any,
}
impl DynamicValue {
pub fn new(any: Any) -> Self {
Self { any }
}
pub fn as_bool(&self) -> Option<bool> {
match self.any {
Any::Bool(value) => Some(value),
_ => None,
}
}
pub fn as_number(&self) -> Option<f64> {
match self.any {
Any::Number(value) => Some(value),
_ => None,
}
}
pub fn as_int(&self) -> Option<i64> {
match self.any {
Any::BigInt(value) => Some(value),
_ => None,
}
}
pub fn as_string(&self) -> Option<String> {
match &self.any {
Any::String(value) => Some(value.to_string()),
_ => None,
}
}
pub fn as_buffer(&self) -> Option<Vec<u8>> {
match &self.any {
Any::Buffer(value) => Some(value.to_vec()),
_ => None,
}
}
pub fn as_array(&self) -> Option<Vec<DynamicValue>> {
match &self.any {
Any::Array(value) => Some(value.iter().map(|a| DynamicValue::new(a.clone())).collect()),
_ => None,
}
}
pub fn as_map(&self) -> Option<HashMap<String, DynamicValue>> {
match &self.any {
Any::Map(value) => Some(
value
.iter()
.map(|(key, value)| (key.clone(), DynamicValue::new(value.clone())))
.collect(),
),
_ => None,
}
}
}

View File

@@ -0,0 +1,12 @@
// mod block;
mod dynamic_value;
mod storage;
mod workspace;
// pub use block::Block;
pub use dynamic_value::{DynamicValue, DynamicValueMap};
pub use storage::Storage;
pub use workspace::Workspace;
#[macro_use]
extern crate napi_derive;

View File

@@ -0,0 +1,125 @@
use crate::Workspace;
use jwst::{error, info, BlobStorage, DocStorage};
use jwst_rpc::start_client;
use jwst_storage::JwstStorage as AutoStorage;
use std::sync::Arc;
use tokio::{runtime::Runtime, sync::RwLock};
use napi::bindgen_prelude::*;
use napi::{Error, Result, Status};
#[napi]
#[derive(Clone)]
pub struct Storage {
pub(crate) storage: Option<Arc<RwLock<AutoStorage>>>,
pub(crate) error: Option<String>,
}
#[napi]
impl Storage {
#[napi(constructor)]
pub fn new(path: String) -> Self {
let rt = Runtime::new().unwrap();
// FIXME: do not use block_on
match rt.block_on(AutoStorage::new(&format!("sqlite:{path}?mode=rwc"))) {
Ok(pool) => Self {
storage: Some(Arc::new(RwLock::new(pool))),
error: None,
},
Err(e) => Self {
storage: None,
error: Some(e.to_string()),
},
}
}
#[napi]
pub fn error(&self) -> Option<String> {
self.error.clone()
}
#[napi]
pub async fn get_blob(&self, workspace_id: Option<String>, id: String) -> Result<Buffer> {
if let Some(storage) = &self.storage {
let storage_handle = storage.read().await;
let blobs = storage_handle.blobs();
let blob = blobs.get_blob(workspace_id.clone(), id.clone(), None).await.map_err(|e| {
Error::new(
Status::GenericFailure,
format!(
"Failed to get blob file {}/{} from storage, error: {}",
workspace_id.clone().unwrap_or_default().to_string(),
id,
e
),
)
})?;
Ok(blob.into())
} else {
return Err(Error::new(
Status::GenericFailure,
"Storage is not connected",
));
}
}
#[napi]
pub fn connect(&mut self, workspace_id: String, remote: String) -> Option<Workspace> {
match self.sync(workspace_id, remote) {
Ok(workspace) => Some(workspace),
Err(e) => {
error!("Failed to connect to workspace: {}", e);
self.error = Some(e.to_string());
None
}
}
}
#[napi]
pub fn sync(&self, workspace_id: String, remote: String) -> Result<Workspace> {
if let Some(storage) = &self.storage {
let rt = Runtime::new().unwrap();
// FIXME: do not use block_on
let mut workspace = rt
.block_on(async move {
let storage = storage.read().await;
start_client(&storage, workspace_id, remote).await
})
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
let (sub, workspace) = {
let id = workspace.id();
let storage = self.storage.clone();
let sub = workspace.observe(move |_, e| {
let id = id.clone();
if let Some(storage) = storage.clone() {
let rt = Runtime::new().unwrap();
info!("update: {:?}", &e.update);
if let Err(e) = rt.block_on(async move {
let storage = storage.write().await;
storage.docs().write_update(id, &e.update).await
}) {
error!("Failed to write update to storage: {}", e);
}
}
});
(sub, workspace)
};
Ok(Workspace {
workspace,
_sub: sub,
})
} else {
Err(Error::new(
Status::GenericFailure,
"Storage is not connected",
))
}
}
}

View File

@@ -0,0 +1,84 @@
// use super::Block;
use jwst::Workspace as JwstWorkspace;
use yrs::UpdateSubscription;
#[napi()]
pub struct Workspace {
pub(crate) workspace: JwstWorkspace,
pub(crate) _sub: Option<UpdateSubscription>,
}
#[napi()]
impl Workspace {
#[napi(constructor)]
pub fn new(id: String) -> Self {
Self {
workspace: JwstWorkspace::new(id),
_sub: None,
}
}
#[napi]
pub fn id(&self) -> String {
self.workspace.id()
}
#[napi]
pub fn client_id(&self) -> i64 {
self.workspace.client_id() as i64
}
// #[napi]
// pub fn get(&self, block_id: String) -> Option<Block> {
// let workspace = self.workspace.clone();
// self.workspace.with_trx(|mut trx| {
// let block = trx
// .get_blocks()
// .get(&trx.trx, &block_id)
// .map(|b| Block::new(workspace, b));
// drop(trx);
// block
// })
// }
// #[napi]
// pub fn create(&self, block_id: String, flavor: String) -> Block {
// let workspace = self.workspace.clone();
// self.workspace.with_trx(|mut trx| {
// let block = Block::new(
// workspace,
// trx.get_blocks().create(&mut trx.trx, block_id, flavor),
// );
// drop(trx);
// block
// })
// }
#[napi]
pub fn search(&self, query: String) -> String {
self.workspace.search_result(query)
}
// #[napi]
// pub fn get_blocks_by_flavour(&self, flavour: &str) -> Vec<Block> {
// self.workspace
// .with_trx(|mut trx| trx.get_blocks().get_blocks_by_flavour(&trx.trx, flavour))
// .iter()
// .map(|block| Block {
// workspace: self.workspace.clone(),
// block: block.clone(),
// })
// .collect()
// }
#[napi]
pub fn get_search_index(&self) -> Vec<String> {
self.workspace.metadata().search_index
}
#[napi]
pub fn set_search_index(&self, fields: Vec<String>) -> bool {
self.workspace.set_search_index(fields)
}
}