Skip to content

Commit

Permalink
Decrease overhead of lz-str-wasm (#33)
Browse files Browse the repository at this point in the history
* Decrease overhead of `lz-str-wasm`

* fmt

* Add inline js injector
  • Loading branch information
adumbidiot authored Oct 21, 2022
1 parent 1365381 commit f57c164
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
.PHONY: build-wasm

# --reference-types

build-wasm:
wasm-pack build --target nodejs bindings/lz-str-wasm
wasm-pack build --target nodejs bindings/lz-str-wasm
cd bindings/lz-str-wasm && python inject-inline-js.py

build-wasm-browser:
wasm-pack build --target web bindings/lz-str-wasm
cd bindings/lz-str-wasm && python inject-inline-js.py
5 changes: 4 additions & 1 deletion bindings/lz-str-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
js-sys = "0.3.47"
lz-str = { path = "../.." }
wasm-bindgen = "0.2.70"
wasm-bindgen = "0.2.70"

[package.metadata.wasm-pack.profile.release]
wasm-opt = [ '-O4' ]
12 changes: 12 additions & 0 deletions bindings/lz-str-wasm/inject-inline-js.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
if __name__ == "__main__":
js_file_str = None
with open('pkg/lz_str_wasm.js', 'r') as file:
js_file_str = file.read()

inline_js = None
with open('src/inline.js', 'r') as file:
inline_js = file.read()

js_file_str += '\n' + inline_js
with open('pkg/lz_str_wasm.js', 'w') as file:
file.write(js_file_str)
12 changes: 12 additions & 0 deletions bindings/lz-str-wasm/src/inline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const CHUNK_SIZE = 10_000;

function convertUint16ArrayToString(array) {
let ret = '';
let num_chunks = Math.ceil(array.length / CHUNK_SIZE);
for(let i = 0; i < array.length; i += CHUNK_SIZE) {
let end_index = Math.min(i + CHUNK_SIZE, i + array.length);
ret += String.fromCharCode(...array.subarray(i, end_index));
}

return ret;
}
32 changes: 26 additions & 6 deletions bindings/lz-str-wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
use js_sys::JsString;
use js_sys::Uint16Array;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;

#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_name = "convertUint16ArrayToString")]
fn convert_uint16_array_to_string(array: &Uint16Array) -> JsString;
}

/// Compress a [`JsString`].
#[wasm_bindgen]
pub fn compress(data: &JsValue) -> JsString {
let data: &JsString = data.dyn_ref::<JsString>().expect("invalid `JsString`");
pub fn compress(data: &JsValue) -> JsValue {
let data: &JsString = match data.dyn_ref::<JsString>() {
Some(data) => data,
None => {
return JsValue::NULL;
}
};
let data: Vec<u16> = data.iter().collect();
let compressed = lz_str::compress(&data);
JsString::from_char_code(&compressed)
let array: Uint16Array = compressed.as_slice().into();
convert_uint16_array_to_string(&array).into()
}

/// Decompress a [`JsString`].
#[wasm_bindgen]
pub fn decompress(data: &JsValue) -> JsValue {
let data: &JsString = data.dyn_ref::<JsString>().expect("invalid `JsString`");
let data: &JsString = match data.dyn_ref::<JsString>() {
Some(data) => data,
None => {
return JsValue::NULL;
}
};
let data: Vec<u16> = data.iter().collect();
lz_str::decompress(&data)
.map(|s| JsString::from_char_code(&s))
.map(Into::into)
.map(|decompressed| {
let array: Uint16Array = decompressed.as_slice().into();
convert_uint16_array_to_string(&array).into()
})
.unwrap_or(JsValue::NULL)
}

0 comments on commit f57c164

Please sign in to comment.