Skip to content

Commit

Permalink
feat: map api simulate
Browse files Browse the repository at this point in the history
  • Loading branch information
darkskygit committed Jul 9, 2024
1 parent cc95ee4 commit 4332610
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 6 deletions.
6 changes: 5 additions & 1 deletion y-octo-node/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class Doc {
getOrCreateMap(key: string): YMap
createArray(): YArray
createText(text?: string | undefined | null): YText
createMap(): YMap
createMap(entries?: JsArray | undefined | null): YMap
applyUpdate(update: Buffer): void
encodeStateAsUpdateV1(state?: Buffer | undefined | null): Buffer
gc(): void
Expand All @@ -65,6 +65,7 @@ export class YMap {
toJson(): object
entries(): YMapEntriesIterator
keys(): YMapKeyIterator
values(): YMapValuesIterator
observe(callback: (...args: any[]) => any): void
observeDeep(callback: (...args: any[]) => any): void
}
Expand All @@ -74,6 +75,9 @@ export class YMapEntriesIterator {
export class YMapKeyIterator {
[Symbol.iterator](): Iterator<string, void, number | undefined | null>
}
export class YMapValuesIterator {
[Symbol.iterator](): Iterator<unknown, void, number | undefined | null>
}
export class YText {
constructor()
get len(): number
Expand Down
3 changes: 2 additions & 1 deletion y-octo-node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { YArray, YArrayIterator, Doc, encodeStateAsUpdate, encodeStateVector, compareStructStores, compareIds, createDeleteSetFromStructStore, equalDeleteSets, snapshot, encodeSnapshot, applyUpdate, mergeUpdates, isAbstractType, YMap, YMapEntriesIterator, YMapKeyIterator, YText, Id, Store, DeleteSet, YSnapshot } = nativeBinding
const { YArray, YArrayIterator, Doc, encodeStateAsUpdate, encodeStateVector, compareStructStores, compareIds, createDeleteSetFromStructStore, equalDeleteSets, snapshot, encodeSnapshot, applyUpdate, mergeUpdates, isAbstractType, YMap, YMapEntriesIterator, YMapKeyIterator, YMapValuesIterator, YText, Id, Store, DeleteSet, YSnapshot } = nativeBinding

module.exports.YArray = YArray
module.exports.YArrayIterator = YArrayIterator
Expand All @@ -271,6 +271,7 @@ module.exports.isAbstractType = isAbstractType
module.exports.YMap = YMap
module.exports.YMapEntriesIterator = YMapEntriesIterator
module.exports.YMapKeyIterator = YMapKeyIterator
module.exports.YMapValuesIterator = YMapValuesIterator
module.exports.YText = YText
module.exports.Id = Id
module.exports.Store = Store
Expand Down
23 changes: 20 additions & 3 deletions y-octo-node/src/doc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use napi::{
bindgen_prelude::{Buffer as JsBuffer, JsFunction},
bindgen_prelude::{Array as JsArray, Buffer as JsBuffer, JsFunction},
threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode},
Env, JsString, JsUnknown,
};
use y_octo::{CrdtRead, Doc, History, RawDecoder, StateVector};

Expand Down Expand Up @@ -91,8 +92,24 @@ impl YDoc {
}

#[napi]
pub fn create_map(&self) -> Result<YMap> {
self.doc.create_map().map(YMap::inner_new).map_err(anyhow::Error::from)
pub fn create_map(&self, env: Env, entries: Option<JsArray>) -> Result<YMap> {
let mut ymap = self.doc.create_map().map(YMap::inner_new)?;
if let Some(entries) = entries {
for i in 0..entries.len() {
if let Ok(Some(value)) = entries.get::<JsArray>(i) {
let key = value.get::<JsString>(0)?;
let value = value.get::<JsUnknown>(1)?;
if let (Some(key), Some(value)) = (key, value) {
ymap.set(env, key.into_utf8()?.into_owned()?, MixedRefYType::D(value))?;
continue;
}
}

return Err(anyhow::anyhow!("Invalid entry"));
}
}

Ok(ymap)
}

#[napi]
Expand Down
45 changes: 44 additions & 1 deletion y-octo-node/src/map.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use napi::{bindgen_prelude::Array as JsArray, iterator::Generator, Env, JsFunction, JsObject, ValueType};
use napi::{bindgen_prelude::Array as JsArray, iterator::Generator, Env, JsFunction, JsObject, JsUnknown, ValueType};
use y_octo::{Any, Map, Value};

use super::*;
Expand Down Expand Up @@ -158,6 +158,15 @@ impl YMap {
}
}

#[napi]
pub fn values(&self, env: Env) -> YMapValuesIterator {
YMapValuesIterator {
entries: self.map.iter().map(|(_, v)| v).collect(),
env,
current: 0,
}
}

// TODO(@darkskygit): impl type based observe
#[napi]
pub fn observe(&mut self, _callback: JsFunction) -> Result<()> {
Expand Down Expand Up @@ -239,6 +248,40 @@ impl Generator for YMapKeyIterator {
}
}

#[napi(iterator)]
pub struct YMapValuesIterator {
entries: Vec<Value>,
env: Env,
current: i64,
}

#[napi]
impl Generator for YMapValuesIterator {
type Yield = JsUnknown;

type Next = Option<i64>;

type Return = ();

fn next(&mut self, value: Option<Self::Next>) -> Option<Self::Yield> {
let current = self.current as usize;
if self.entries.len() <= current {
return None;
}
let ret = if let Some(value) = self.entries.get(current) {
get_js_unknown_from_value(self.env, value.clone()).ok()
} else {
None
};
self.current = if let Some(value) = value.and_then(|v| v) {
value
} else {
self.current + 1
};
ret
}
}

#[cfg(test)]
mod tests {

Expand Down

0 comments on commit 4332610

Please sign in to comment.