mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-04 00:28:33 +00:00
feat: improve native
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -44,6 +44,7 @@ dependencies = [
|
||||
"docx-parser",
|
||||
"infer",
|
||||
"nanoid",
|
||||
"napi",
|
||||
"path-ext",
|
||||
"pdf-extract",
|
||||
"pulldown-cmark",
|
||||
@@ -126,6 +127,7 @@ dependencies = [
|
||||
"affine_nbstore",
|
||||
"affine_sqlite_v1",
|
||||
"chrono",
|
||||
"mimalloc",
|
||||
"napi",
|
||||
"napi-build",
|
||||
"napi-derive",
|
||||
|
||||
@@ -11,6 +11,7 @@ crate-type = ["cdylib"]
|
||||
affine_common = { workspace = true, features = [
|
||||
"doc-loader",
|
||||
"hashcash",
|
||||
"napi",
|
||||
"ydoc-loader",
|
||||
] }
|
||||
chrono = { workspace = true }
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use affine_common::doc_parser::{self, BlockInfo, CrawlResult, MarkdownResult, PageDocContent, WorkspaceDocContent};
|
||||
use affine_common::{
|
||||
doc_parser::{self, BlockInfo, CrawlResult, MarkdownResult, PageDocContent, WorkspaceDocContent},
|
||||
napi_utils::map_napi_err,
|
||||
};
|
||||
use napi::bindgen_prelude::*;
|
||||
use napi_derive::napi;
|
||||
|
||||
@@ -95,22 +98,25 @@ impl From<CrawlResult> for NativeCrawlResult {
|
||||
|
||||
#[napi]
|
||||
pub fn parse_doc_from_binary(doc_bin: Buffer, doc_id: String) -> Result<NativeCrawlResult> {
|
||||
let result = doc_parser::parse_doc_from_binary(doc_bin.into(), doc_id)
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::parse_doc_from_binary(doc_bin.into(), doc_id),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn parse_page_doc(doc_bin: Buffer, max_summary_length: Option<i32>) -> Result<Option<NativePageDocContent>> {
|
||||
let result = doc_parser::parse_page_doc(doc_bin.into(), max_summary_length.map(|v| v as isize))
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::parse_page_doc(doc_bin.into(), max_summary_length.map(|v| v as isize)),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(result.map(Into::into))
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn parse_workspace_doc(doc_bin: Buffer) -> Result<Option<NativeWorkspaceDocContent>> {
|
||||
let result =
|
||||
doc_parser::parse_workspace_doc(doc_bin.into()).map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(doc_parser::parse_workspace_doc(doc_bin.into()), Status::GenericFailure)?;
|
||||
Ok(result.map(Into::into))
|
||||
}
|
||||
|
||||
@@ -121,15 +127,19 @@ pub fn parse_doc_to_markdown(
|
||||
ai_editable: Option<bool>,
|
||||
doc_url_prefix: Option<String>,
|
||||
) -> Result<NativeMarkdownResult> {
|
||||
let result = doc_parser::parse_doc_to_markdown(doc_bin.into(), doc_id, ai_editable.unwrap_or(false), doc_url_prefix)
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::parse_doc_to_markdown(doc_bin.into(), doc_id, ai_editable.unwrap_or(false), doc_url_prefix),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(result.into())
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn read_all_doc_ids_from_root_doc(doc_bin: Buffer, include_trash: Option<bool>) -> Result<Vec<String>> {
|
||||
let result = doc_parser::get_doc_ids_from_binary(doc_bin.into(), include_trash.unwrap_or(false))
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::get_doc_ids_from_binary(doc_bin.into(), include_trash.unwrap_or(false)),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@@ -144,8 +154,10 @@ pub fn read_all_doc_ids_from_root_doc(doc_bin: Buffer, include_trash: Option<boo
|
||||
/// A Buffer containing the y-octo document update binary
|
||||
#[napi]
|
||||
pub fn create_doc_with_markdown(title: String, markdown: String, doc_id: String) -> Result<Buffer> {
|
||||
let result = doc_parser::build_full_doc(&title, &markdown, &doc_id)
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::build_full_doc(&title, &markdown, &doc_id),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(Buffer::from(result))
|
||||
}
|
||||
|
||||
@@ -161,8 +173,10 @@ pub fn create_doc_with_markdown(title: String, markdown: String, doc_id: String)
|
||||
/// A Buffer containing only the delta (changes) as a y-octo update binary
|
||||
#[napi]
|
||||
pub fn update_doc_with_markdown(existing_binary: Buffer, new_markdown: String, doc_id: String) -> Result<Buffer> {
|
||||
let result = doc_parser::update_doc(&existing_binary, &new_markdown, &doc_id)
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::update_doc(&existing_binary, &new_markdown, &doc_id),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(Buffer::from(result))
|
||||
}
|
||||
|
||||
@@ -177,8 +191,10 @@ pub fn update_doc_with_markdown(existing_binary: Buffer, new_markdown: String, d
|
||||
/// A Buffer containing only the delta (changes) as a y-octo update binary
|
||||
#[napi]
|
||||
pub fn update_doc_title(existing_binary: Buffer, title: String, doc_id: String) -> Result<Buffer> {
|
||||
let result = doc_parser::update_doc_title(&existing_binary, &doc_id, &title)
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::update_doc_title(&existing_binary, &doc_id, &title),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(Buffer::from(result))
|
||||
}
|
||||
|
||||
@@ -202,14 +218,16 @@ pub fn update_doc_properties(
|
||||
created_by: Option<String>,
|
||||
updated_by: Option<String>,
|
||||
) -> Result<Buffer> {
|
||||
let result = doc_parser::update_doc_properties(
|
||||
let result = map_napi_err(
|
||||
doc_parser::update_doc_properties(
|
||||
&existing_binary,
|
||||
&properties_doc_id,
|
||||
&target_doc_id,
|
||||
created_by.as_deref(),
|
||||
updated_by.as_deref(),
|
||||
)
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(Buffer::from(result))
|
||||
}
|
||||
|
||||
@@ -225,8 +243,10 @@ pub fn update_doc_properties(
|
||||
/// A Buffer containing the y-octo update binary to apply to the root doc
|
||||
#[napi]
|
||||
pub fn add_doc_to_root_doc(root_doc_bin: Buffer, doc_id: String, title: Option<String>) -> Result<Buffer> {
|
||||
let result = doc_parser::add_doc_to_root_doc(root_doc_bin.into(), &doc_id, title.as_deref())
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::add_doc_to_root_doc(root_doc_bin.into(), &doc_id, title.as_deref()),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(Buffer::from(result))
|
||||
}
|
||||
|
||||
@@ -241,7 +261,9 @@ pub fn add_doc_to_root_doc(root_doc_bin: Buffer, doc_id: String, title: Option<S
|
||||
/// A Buffer containing the y-octo update binary to apply to the root doc
|
||||
#[napi]
|
||||
pub fn update_root_doc_meta_title(root_doc_bin: Buffer, doc_id: String, title: String) -> Result<Buffer> {
|
||||
let result = doc_parser::update_root_doc_meta_title(&root_doc_bin, &doc_id, &title)
|
||||
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
|
||||
let result = map_napi_err(
|
||||
doc_parser::update_root_doc_meta_title(&root_doc_bin, &doc_id, &title),
|
||||
Status::GenericFailure,
|
||||
)?;
|
||||
Ok(Buffer::from(result))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use affine_common::doc_loader::Doc;
|
||||
use affine_common::{doc_loader::Doc, napi_utils::map_napi_err};
|
||||
use napi::{
|
||||
Env, Result, Task,
|
||||
anyhow::anyhow,
|
||||
Env, Result, Status, Task,
|
||||
bindgen_prelude::{AsyncTask, Buffer},
|
||||
};
|
||||
|
||||
@@ -54,7 +53,7 @@ impl Task for AsyncParseDocResponse {
|
||||
type JsValue = ParsedDoc;
|
||||
|
||||
fn compute(&mut self) -> Result<Self::Output> {
|
||||
let doc = Doc::new(&self.file_path, &self.doc).map_err(|e| anyhow!(e))?;
|
||||
let doc = map_napi_err(Doc::new(&self.file_path, &self.doc), Status::GenericFailure)?;
|
||||
Ok(Document { inner: doc })
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,8 @@ pub mod hashcash;
|
||||
pub mod html_sanitize;
|
||||
pub mod tiktoken;
|
||||
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
use napi::{Error, Result, Status, bindgen_prelude::*};
|
||||
use affine_common::napi_utils::map_napi_err;
|
||||
use napi::{Result, Status, bindgen_prelude::*};
|
||||
use y_octo::Doc;
|
||||
|
||||
#[cfg(not(target_arch = "arm"))]
|
||||
@@ -21,35 +20,16 @@ static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
#[macro_use]
|
||||
extern crate napi_derive;
|
||||
|
||||
fn map_err_inner<T, E: Display + Debug>(v: std::result::Result<T, E>, status: Status) -> Result<T> {
|
||||
match v {
|
||||
Ok(val) => Ok(val),
|
||||
Err(e) => {
|
||||
dbg!(&e);
|
||||
Err(Error::new(status, e.to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! map_err {
|
||||
($val: expr) => {
|
||||
map_err_inner($val, Status::GenericFailure)
|
||||
};
|
||||
($val: expr, $stauts: ident) => {
|
||||
map_err_inner($val, $stauts)
|
||||
};
|
||||
}
|
||||
|
||||
/// Merge updates in form like `Y.applyUpdate(doc, update)` way and return the
|
||||
/// result binary.
|
||||
#[napi(catch_unwind)]
|
||||
pub fn merge_updates_in_apply_way(updates: Vec<Buffer>) -> Result<Buffer> {
|
||||
let mut doc = Doc::default();
|
||||
for update in updates {
|
||||
map_err!(doc.apply_update_from_binary_v1(update.as_ref()))?;
|
||||
map_napi_err(doc.apply_update_from_binary_v1(update.as_ref()), Status::GenericFailure)?;
|
||||
}
|
||||
|
||||
let buf = map_err!(doc.encode_update_v1())?;
|
||||
let buf = map_napi_err(doc.encode_update_v1(), Status::GenericFailure)?;
|
||||
|
||||
Ok(buf.into())
|
||||
}
|
||||
@@ -59,3 +39,17 @@ pub const AFFINE_PRO_PUBLIC_KEY: Option<&'static str> = std::option_env!("AFFINE
|
||||
|
||||
#[napi]
|
||||
pub const AFFINE_PRO_LICENSE_AES_KEY: Option<&'static str> = std::option_env!("AFFINE_PRO_LICENSE_AES_KEY");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn merge_updates_reports_generic_failure() {
|
||||
let err = match merge_updates_in_apply_way(vec![Buffer::from(vec![0])]) {
|
||||
Ok(_) => panic!("expected error"),
|
||||
Err(err) => err,
|
||||
};
|
||||
assert_eq!(err.status, Status::GenericFailure);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ doc-loader = [
|
||||
"url",
|
||||
]
|
||||
hashcash = ["chrono", "sha3", "rand"]
|
||||
napi = ["dep:napi"]
|
||||
tree-sitter = [
|
||||
"cc",
|
||||
"dep:tree-sitter",
|
||||
@@ -53,6 +54,7 @@ chrono = { workspace = true, optional = true }
|
||||
docx-parser = { workspace = true, optional = true }
|
||||
infer = { workspace = true, optional = true }
|
||||
nanoid = { workspace = true, optional = true }
|
||||
napi = { workspace = true, optional = true }
|
||||
path-ext = { workspace = true, optional = true }
|
||||
pdf-extract = { workspace = true, optional = true }
|
||||
pulldown-cmark = { workspace = true, optional = true }
|
||||
|
||||
@@ -4,3 +4,5 @@ pub mod doc_loader;
|
||||
pub mod doc_parser;
|
||||
#[cfg(feature = "hashcash")]
|
||||
pub mod hashcash;
|
||||
#[cfg(feature = "napi")]
|
||||
pub mod napi_utils;
|
||||
|
||||
22
packages/common/native/src/napi_utils.rs
Normal file
22
packages/common/native/src/napi_utils.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
use napi::{Error, Result, Status};
|
||||
|
||||
pub fn to_napi_error<E: Display + Debug>(err: E, status: Status) -> Error {
|
||||
Error::new(status, err.to_string())
|
||||
}
|
||||
|
||||
pub fn map_napi_err<T, E: Display + Debug>(value: std::result::Result<T, E>, status: Status) -> Result<T> {
|
||||
value.map_err(|err| to_napi_error(err, status))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn map_napi_err_keeps_message() {
|
||||
let err = map_napi_err::<(), _>(Err("boom"), Status::GenericFailure).unwrap_err();
|
||||
assert!(err.to_string().contains("boom"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user