mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-21 23:04:49 +01:00
Merge pull request #19 from hexedtech/fix/js-event
fix: add Workspace::event to js api
This commit is contained in:
commit
799123c681
3 changed files with 19 additions and 105 deletions
|
@ -2,7 +2,6 @@ pub mod client;
|
||||||
pub mod workspace;
|
pub mod workspace;
|
||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
pub mod buffer;
|
pub mod buffer;
|
||||||
pub mod op_cache;
|
|
||||||
pub mod ext;
|
pub mod ext;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,104 +0,0 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
use napi_derive::napi;
|
|
||||||
|
|
||||||
pub type OpTuple = (String, u32, String, u32); // buf_path, start, text, end
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub struct OpCache {
|
|
||||||
store: HashMap<OpTuple, i32>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
impl OpCache {
|
|
||||||
#[napi(constructor)]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
OpCache {
|
|
||||||
store: HashMap::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn to_string(&self) -> String {
|
|
||||||
self.store.iter()
|
|
||||||
.map(|(k, v)| format!("{}x Op(@{} {}:{} '{}')", k.0, v, k.1, k.3, k.2))
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn put(&mut self, buf: String, start: u32, text: String, end: u32) -> i32 {
|
|
||||||
let op = (buf, start, text, end);
|
|
||||||
match self.store.get_mut(&op) {
|
|
||||||
Some(val) => {
|
|
||||||
if *val < 0 { *val = 0 }
|
|
||||||
*val += 1;
|
|
||||||
*val
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
self.store.insert(op, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[napi]
|
|
||||||
pub fn get(&mut self, buf: String, start: u32, text: String, end: u32) -> bool {
|
|
||||||
let op = (buf, start, text, end);
|
|
||||||
match self.store.get_mut(&op) {
|
|
||||||
Some(val) => {
|
|
||||||
*val -= 1;
|
|
||||||
*val >= 0
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
tracing::warn!("never seen this op: {:?}", op);
|
|
||||||
self.store.insert(op, -1);
|
|
||||||
false
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//a
|
|
||||||
//consume a
|
|
||||||
//a
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
#[test]
|
|
||||||
fn opcache_put_increments_internal_counter() {
|
|
||||||
let mut op = super::OpCache::new();
|
|
||||||
assert_eq!(op.put("default".into(), 0, "hello world".into(), 0), 1); // 1: did not already contain it
|
|
||||||
assert_eq!(op.put("default".into(), 0, "hello world".into(), 0), 2); // 2: already contained it
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn op_cache_get_checks_count() {
|
|
||||||
let mut op = super::OpCache::new();
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), false);
|
|
||||||
assert_eq!(op.put("default".into(), 0, "hello world".into(), 0), 1);
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), true);
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), false);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn op_cache_get_works_for_multiple_puts() {
|
|
||||||
let mut op = super::OpCache::new();
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), false);
|
|
||||||
assert_eq!(op.put("default".into(), 0, "hello world".into(), 0), 1);
|
|
||||||
assert_eq!(op.put("default".into(), 0, "hello world".into(), 0), 2);
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), true);
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), true);
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn op_cache_different_keys(){
|
|
||||||
let mut op = super::OpCache::new();
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), false);
|
|
||||||
assert_eq!(op.put("default".into(), 0, "hello world".into(), 0), 1);
|
|
||||||
assert_eq!(op.get("workspace".into(), 0, "hi".into(), 0), false);
|
|
||||||
assert_eq!(op.put("workspace".into(), 0, "hi".into(), 0), 1);
|
|
||||||
assert_eq!(op.get("workspace".into(), 0, "hi".into(), 0), true);
|
|
||||||
assert_eq!(op.get("default".into(), 0, "hello world".into(), 0), true);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,21 @@ use crate::Workspace;
|
||||||
use crate::buffer::controller::BufferController;
|
use crate::buffer::controller::BufferController;
|
||||||
use crate::cursor::controller::CursorController;
|
use crate::cursor::controller::CursorController;
|
||||||
|
|
||||||
|
#[napi(object, js_name = "Event")]
|
||||||
|
pub struct JsEvent {
|
||||||
|
pub r#type: String,
|
||||||
|
pub value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<crate::api::Event> for JsEvent {
|
||||||
|
fn from(value: crate::api::Event) -> Self {
|
||||||
|
match value {
|
||||||
|
crate::api::Event::FileTreeUpdated(value) => Self { r#type: "filetree".into(), value },
|
||||||
|
crate::api::Event::UserJoin(value) => Self { r#type: "join".into(), value },
|
||||||
|
crate::api::Event::UserLeave(value) => Self { r#type: "leave".into(), value },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
impl Workspace {
|
impl Workspace {
|
||||||
|
@ -46,4 +61,8 @@ impl Workspace {
|
||||||
Ok(self.delete(&path).await?)
|
Ok(self.delete(&path).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi(js_name = "event")]
|
||||||
|
pub async fn js_event(&self) -> napi::Result<JsEvent> {
|
||||||
|
Ok(JsEvent::from(self.event().await?))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue