Skip to content

Commit

Permalink
feat: support richtext in wasm & mark text with arbitrary value (#142)
Browse files Browse the repository at this point in the history
- Support mark text with custom value [LORO-299] Allow users to mark text with custom value #139
- Expose richtext in wasm
  • Loading branch information
zxch3n authored Nov 2, 2023
1 parent 95e6130 commit a40b5c6
Show file tree
Hide file tree
Showing 26 changed files with 433 additions and 193 deletions.
67 changes: 33 additions & 34 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,46 @@ name: Rust

on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
branches: [ "main" ]
branches: ["main"]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: jetli/[email protected]
with:
# Optional version of wasm-pack to install(eg. 'v0.9.1', 'latest')
version: 'latest'
- uses: denoland/setup-deno@v1
with:
deno-version: v1.x
- uses: actions/setup-node@v3
with:
node-version: 18
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Install nextest
uses: taiki-e/install-action@v1
with:
tool: nextest
- run: rustup toolchain install stable --profile minimal
- run: rustup target add wasm32-unknown-unknown
- uses: jetli/[email protected]
with:
version: 'latest'
- uses: Swatinem/rust-cache@v2
- name: Build
run: cargo build --verbose
- name: Run rust tests
run: deno task test
- name: Run wasm tests
run: deno task test-wasm
- uses: actions/checkout@v3
- uses: jetli/[email protected]
with:
# Optional version of wasm-pack to install(eg. 'v0.9.1', 'latest')
version: "latest"
- uses: denoland/setup-deno@v1
with:
deno-version: v1.x
- uses: actions/setup-node@v3
with:
node-version: 18
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Install nextest
uses: taiki-e/install-action@v1
with:
tool: nextest

- run: rustup toolchain install stable --profile minimal
- run: rustup target add wasm32-unknown-unknown
- uses: jetli/[email protected]
with:
version: "0.2.86"
- uses: Swatinem/rust-cache@v2
- name: Build
run: cargo build --verbose
- name: Run rust tests
run: deno task test
- name: Run wasm tests
run: deno task test-wasm
24 changes: 12 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/loro-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ edition = "2021"
serde = {version="1", features=["derive"]}
thiserror = "1.0.43"
rle = {path = "../rle"}
wasm-bindgen = {version= "0.2.87", optional=true}
wasm-bindgen = {version= "=0.2.86", optional=true}
fxhash = "0.2.1"
enum-as-inner = "0.6.0"
string_cache = "0.8.7"
arbitrary = {version = "1.3.0", features=["derive"]}
js-sys = {version="0.3.64", optional=true}
js-sys = {version="0.3.60", optional=true}
zerovec = "0.9.4"

[features]
Expand Down
2 changes: 1 addition & 1 deletion crates/loro-internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ crdt-list = { version = "0.4.0" }
rand = { version = "0.8.5", optional = true }
arbitrary = { version = "1", optional = true }
tabled = { version = "0.10.0", optional = true }
wasm-bindgen = { version = "0.2.83", optional = true }
wasm-bindgen = { version = "=0.2.86", optional = true }
serde-wasm-bindgen = { version = "0.5.0", optional = true }
js-sys = { version = "0.3.60", optional = true }
serde_json = { version = "1" }
Expand Down
4 changes: 4 additions & 0 deletions crates/loro-internal/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ impl<'a> OpConverter<'a> {
end,
info,
key,
value,
} => Op {
counter,
container,
Expand All @@ -152,6 +153,7 @@ impl<'a> OpConverter<'a> {
end,
info,
key,
value,
}),
},
ListOp::StyleEnd => Op {
Expand Down Expand Up @@ -448,6 +450,7 @@ impl SharedArena {
end,
info,
key,
value,
} => Op {
counter,
container,
Expand All @@ -456,6 +459,7 @@ impl SharedArena {
end,
key,
info,
value,
}),
},
ListOp::StyleEnd => Op {
Expand Down
3 changes: 3 additions & 0 deletions crates/loro-internal/src/container/list/list_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::ops::Range;

use append_only_bytes::BytesSlice;
use enum_as_inner::EnumAsInner;
use loro_common::LoroValue;
use rle::{HasLength, Mergable, Sliceable};
use serde::{Deserialize, Serialize};

Expand All @@ -27,6 +28,7 @@ pub enum ListOp<'a> {
end: u32,
key: InternalString,
info: TextStyleInfoFlag,
value: LoroValue,
},
StyleEnd,
}
Expand All @@ -51,6 +53,7 @@ pub enum InnerListOp {
start: u32,
end: u32,
key: InternalString,
value: LoroValue,
info: TextStyleInfoFlag,
},
StyleEnd,
Expand Down
51 changes: 38 additions & 13 deletions crates/loro-internal/src/container/richtext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub struct StyleOp {
pub(crate) peer: PeerID,
pub(crate) cnt: Counter,
pub(crate) key: InternalString,
pub(crate) value: LoroValue,
pub(crate) info: TextStyleInfoFlag,
}

Expand All @@ -66,7 +67,7 @@ impl StyleKey {
pub fn to_attr_key(&self) -> String {
match self {
Self::Key(key) => key.to_string(),
Self::KeyWithId { key, id } => format!("id:{}", id),
Self::KeyWithId { key: _, id } => format!("id:{}", id),
}
}

Expand All @@ -76,6 +77,10 @@ impl StyleKey {
Self::KeyWithId { key, .. } => key,
}
}

pub fn contains_id(&self) -> bool {
matches!(self, Self::KeyWithId { .. })
}
}

impl StyleOp {
Expand Down Expand Up @@ -105,17 +110,7 @@ impl StyleOp {
}

pub fn to_value(&self) -> LoroValue {
if self.info.is_delete() {
LoroValue::Bool(false)
} else if self.info.is_container() {
LoroValue::Container(loro_common::ContainerID::Normal {
peer: self.peer,
counter: self.cnt,
container_type: loro_common::ContainerType::Map,
})
} else {
LoroValue::Bool(true)
}
self.value.clone()
}

pub(crate) fn get_style_key(&self) -> StyleKey {
Expand All @@ -130,12 +125,13 @@ impl StyleOp {
}

#[cfg(test)]
pub fn new_for_test(n: isize, key: &str, info: TextStyleInfoFlag) -> Self {
pub fn new_for_test(n: isize, key: &str, value: LoroValue, info: TextStyleInfoFlag) -> Self {
Self {
lamport: n as Lamport,
peer: n as PeerID,
cnt: n as Counter,
key: key.to_string().into(),
value,
info,
}
}
Expand Down Expand Up @@ -224,6 +220,35 @@ impl ExpandType {
pub const fn expand_after(&self) -> bool {
matches!(self, ExpandType::After | ExpandType::Both)
}

/// 'before'|'after'|'both'|'none'
pub fn try_from_str(s: &str) -> Option<Self> {
match s {
"before" => Some(ExpandType::Before),
"after" => Some(ExpandType::After),
"both" => Some(ExpandType::Both),
"none" => Some(ExpandType::None),
_ => None,
}
}

/// Create reversed expand type.
///
/// Beofre -> After
/// After -> Before
/// Both -> None
/// None -> Both
///
/// Because the creation of text styles and the deletion of the text styles have reversed expand type.
/// This method is useful to convert between the two
pub fn reverse(self) -> Self {
match self {
ExpandType::Before => ExpandType::After,
ExpandType::After => ExpandType::Before,
ExpandType::Both => ExpandType::None,
ExpandType::None => ExpandType::Both,
}
}
}

impl TextStyleInfoFlag {
Expand Down
Loading

0 comments on commit a40b5c6

Please sign in to comment.