Expose undiff to JS
This commit is contained in:
parent
c9c2b775a8
commit
ee6277c13f
5 changed files with 64 additions and 21 deletions
|
|
@ -4,7 +4,8 @@ import {
|
|||
TextWithCursors as wasmTextWithCursors,
|
||||
SpanWithHistory as wasmSpanWithHistory,
|
||||
reconcileWithHistory as wasmReconcileWithHistory,
|
||||
getCompactDiff as wasmGetCompactDiff,
|
||||
diff as wasmDiff,
|
||||
undiff as wasmUndiff,
|
||||
initSync,
|
||||
} from 'reconcile-text';
|
||||
|
||||
|
|
@ -182,7 +183,8 @@ export function reconcile(
|
|||
/**
|
||||
* Generates a compact diff representation between an original and changed text.
|
||||
*
|
||||
* These can be parsed and unpacked using Rust crate's EditedText::from_changes.
|
||||
* These can be parsed and unpacked using the `undiff` function or the Rust crate's EditedText::from_diff.
|
||||
* Cursor positions are omitted from the diff result.
|
||||
*
|
||||
* This function computes the differences between two versions of text and returns
|
||||
* a compact representation of those changes.
|
||||
|
|
@ -192,7 +194,7 @@ export function reconcile(
|
|||
* @param tokenizer - The tokenisation strategy, which is the same as used in `reconcile`.
|
||||
* @returns An array representing the compact diff, with inserts as strings and deletes as negative integers.
|
||||
*/
|
||||
export function getCompactDiff(
|
||||
export function diff(
|
||||
original: string,
|
||||
changed: string | TextWithOptionalCursors,
|
||||
tokenizer: BuiltinTokenizer = 'Word'
|
||||
|
|
@ -205,13 +207,38 @@ export function getCompactDiff(
|
|||
|
||||
const changedWasm = toWasmTextWithCursors(changed);
|
||||
|
||||
const result = wasmGetCompactDiff(original, changedWasm, tokenizer);
|
||||
const result = wasmDiff(original, changedWasm, tokenizer);
|
||||
|
||||
changedWasm.free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a compact diff to an original text to reconstruct the changed version.
|
||||
*
|
||||
* This function takes an original text and a compact diff representation (as produced
|
||||
* by the `diff` function) and reconstructs the modified text.
|
||||
*
|
||||
* @param original - The original/base version of the text
|
||||
* @param diff - The compact diff array representing changes (inserts as strings, deletes as negative integers)
|
||||
* @param tokenizer - The tokenisation strategy, which is the same as used in `reconcile`.
|
||||
* @returns The reconstructed changed text as a string.
|
||||
*/
|
||||
export function undiff(
|
||||
original: string,
|
||||
diff: Array<number | string>,
|
||||
tokenizer: BuiltinTokenizer = 'Word'
|
||||
): string {
|
||||
init();
|
||||
|
||||
if (!BUILTIN_TOKENIZERS.includes(tokenizer)) {
|
||||
throw new Error(UNSUPPORTED_TOKENIZER_ERROR);
|
||||
}
|
||||
|
||||
return wasmUndiff(original, diff, tokenizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges three versions of text and returns detailed provenance information.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@
|
|||
//! &changes.into()
|
||||
//! );
|
||||
//!
|
||||
//! let serialized = serde_yaml::to_string(&result.to_changes()).unwrap();
|
||||
//! let serialized = serde_yaml::to_string(&result.to_diff()).unwrap();
|
||||
//! assert_eq!(
|
||||
//! serialized,
|
||||
//! concat!(
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
//! );
|
||||
//!
|
||||
//! let deserialized = serde_yaml::from_str(&serialized).unwrap();
|
||||
//! let reconstructed = EditedText::from_changes(
|
||||
//! let reconstructed = EditedText::from_diff(
|
||||
//! original,
|
||||
//! deserialized,
|
||||
//! &*BuiltinTokenizer::Word
|
||||
|
|
|
|||
34
src/wasm.rs
34
src/wasm.rs
|
|
@ -3,7 +3,7 @@ use core::str;
|
|||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::{BuiltinTokenizer, CursorPosition, SpanWithHistory, TextWithCursors};
|
||||
use crate::{BuiltinTokenizer, CursorPosition, EditedText, SpanWithHistory, TextWithCursors};
|
||||
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc<'_> = wee_alloc::WeeAlloc::INIT;
|
||||
|
|
@ -32,6 +32,7 @@ pub fn reconcile_with_history(
|
|||
tokenizer: BuiltinTokenizer,
|
||||
) -> TextWithCursorsAndHistory {
|
||||
set_panic_hook();
|
||||
|
||||
let reconciled = crate::reconcile(parent, left, right, &*tokenizer);
|
||||
let text_with_cursors = reconciled.apply();
|
||||
|
||||
|
|
@ -80,22 +81,37 @@ pub fn generic_reconcile(
|
|||
|
||||
/// WASM wrapper around getting a compact diff representation of two texts as a
|
||||
/// list of numbers and strings.
|
||||
#[wasm_bindgen(js_name = getCompactDiff)]
|
||||
#[wasm_bindgen(js_name = diff)]
|
||||
#[must_use]
|
||||
pub fn get_compact_diff(
|
||||
parent: &str,
|
||||
changed: &TextWithCursors,
|
||||
tokenizer: BuiltinTokenizer,
|
||||
) -> Vec<JsValue> {
|
||||
pub fn diff(parent: &str, changed: &TextWithCursors, tokenizer: BuiltinTokenizer) -> Vec<JsValue> {
|
||||
set_panic_hook();
|
||||
let edited_text = crate::EditedText::from_strings_with_tokenizer(parent, changed, &*tokenizer);
|
||||
|
||||
let edited_text = EditedText::from_strings_with_tokenizer(parent, changed, &*tokenizer);
|
||||
edited_text
|
||||
.to_changes()
|
||||
.to_diff()
|
||||
.into_iter()
|
||||
.map(std::convert::Into::into)
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Inverse of `diff`, applies a compact diff representation to a parent text
|
||||
#[wasm_bindgen(js_name = undiff)]
|
||||
#[must_use]
|
||||
pub fn undiff(parent: &str, diff: Vec<JsValue>, tokenizer: BuiltinTokenizer) -> String {
|
||||
set_panic_hook();
|
||||
|
||||
EditedText::from_diff(
|
||||
parent,
|
||||
diff.into_iter()
|
||||
.map(|js_value| js_value.try_into())
|
||||
.collect::<Result<_, _>>()
|
||||
.expect("Invalid diff format"),
|
||||
&*tokenizer,
|
||||
)
|
||||
.apply()
|
||||
.text()
|
||||
}
|
||||
|
||||
fn set_panic_hook() {
|
||||
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
|
|
|
|||
|
|
@ -50,16 +50,16 @@ fn test_document_one_way_with_serialisation() {
|
|||
);
|
||||
|
||||
let serialised_left =
|
||||
serde_yaml::from_str(&serde_yaml::to_string(&left_operations.to_changes()).unwrap())
|
||||
serde_yaml::from_str(&serde_yaml::to_string(&left_operations.to_diff()).unwrap())
|
||||
.unwrap();
|
||||
let serialised_right =
|
||||
serde_yaml::from_str(&serde_yaml::to_string(&right_operations.to_changes()).unwrap())
|
||||
serde_yaml::from_str(&serde_yaml::to_string(&right_operations.to_diff()).unwrap())
|
||||
.unwrap();
|
||||
|
||||
let restored_left_operations =
|
||||
EditedText::from_changes(&parent, serialised_left, &*BuiltinTokenizer::Word);
|
||||
EditedText::from_diff(&parent, serialised_left, &*BuiltinTokenizer::Word);
|
||||
let restored_right_operations =
|
||||
EditedText::from_changes(&parent, serialised_right, &*BuiltinTokenizer::Word);
|
||||
EditedText::from_diff(&parent, serialised_right, &*BuiltinTokenizer::Word);
|
||||
|
||||
doc.assert_eq_without_cursors(
|
||||
&restored_left_operations
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ fn test_merge_binary() {
|
|||
}
|
||||
|
||||
#[wasm_bindgen_test] // JsValue isn't supported outside of wasm
|
||||
fn test_get_compact_diff() {
|
||||
fn test_diff() {
|
||||
let parent = "hello ";
|
||||
let changed = "world";
|
||||
|
||||
let result = get_compact_diff(parent, &changed.into(), BuiltinTokenizer::Word);
|
||||
let result = diff(parent, &changed.into(), BuiltinTokenizer::Word);
|
||||
|
||||
assert_eq!(result.len(), 2);
|
||||
let first: i64 = result[0].clone().try_into().unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue