Skip to content

Commit

Permalink
fix: adapt cuid1, cuid2 to avoid runtime panics on wasm32-unknown-unk…
Browse files Browse the repository at this point in the history
…nown
  • Loading branch information
jkomyno committed Nov 21, 2024
1 parent 5fdaee7 commit c8e835c
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 23 deletions.
1 change: 1 addition & 0 deletions crates/cuid-util/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ radix_fmt = "1.0.0"
# WASM-only deps
[target.wasm32-unknown-unknown.dependencies]
web-time = "1.1.0"
js-sys = "0.3.72"
13 changes: 13 additions & 0 deletions crates/cuid-util/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ pub fn millis_since_unix_epoch() -> u128 {
.as_millis()
}

#[cfg(not(target_arch = "wasm32"))]
pub fn process_id_fallback() -> u128 {
std::process::id() as u128
}

#[cfg(target_arch = "wasm32")]
pub fn process_id_fallback() -> u128 {
use js_sys::Object as JsObject;

Check failure on line 45 in crates/cuid-util/src/lib.rs

View workflow job for this annotation

GitHub Actions / WASM Builds (wasm32-wasi)

unresolved import `js_sys`

// See: https://github.com/paralleldrive/cuid2/blob/768d132d559c712c26d6ccc26a2895c3c180b60c/src/index.js#L58
JsObject::keys(&js_sys::global()).length() as u128

Check failure on line 48 in crates/cuid-util/src/lib.rs

View workflow job for this annotation

GitHub Actions / WASM Builds (wasm32-wasi)

failed to resolve: use of undeclared crate or module `js_sys`
}

/// Converts any number representable as a u128 into a base36 String.
///
/// Benchmarking has shown this function to be faster than anything I've been
Expand Down
14 changes: 9 additions & 5 deletions crates/cuid/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ homepage.workspace = true
repository.workspace = true

[dependencies]
base36 = "0.0.1"
cuid1.workspace = true
cuid2.workspace = true
num = { version = "0.4.0", features = ["num-bigint"] }
once_cell = "1.19.0"
rand.workspace = true

[dev-dependencies]
# WASM-only deps
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0", features = ["js"] }

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
criterion.workspace = true

# WASM-only dev-deps
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test.workspace = true
wasm-rs-dbg = "0.1.2"

[lib]
name = "cuid"
Expand Down
20 changes: 20 additions & 0 deletions crates/cuid/tests/wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use wasm_bindgen_test::*;

Check failure on line 1 in crates/cuid/tests/wasm.rs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, nightly, -p cuid)

unresolved import `wasm_bindgen_test`

Check failure on line 1 in crates/cuid/tests/wasm.rs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, beta, -p cuid)

unresolved import `wasm_bindgen_test`
use wasm_rs_dbg::dbg;

Check failure on line 2 in crates/cuid/tests/wasm.rs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, nightly, -p cuid)

unresolved import `wasm_rs_dbg`

Check failure on line 2 in crates/cuid/tests/wasm.rs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, beta, -p cuid)

unresolved import `wasm_rs_dbg`

#[wasm_bindgen_test]

Check failure on line 4 in crates/cuid/tests/wasm.rs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, nightly, -p cuid)

cannot find attribute `wasm_bindgen_test` in this scope

Check failure on line 4 in crates/cuid/tests/wasm.rs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, beta, -p cuid)

cannot find attribute `wasm_bindgen_test` in this scope
fn cuid1_length() {
// e.g.: "cm3rpdbhn0001w10gi9au8cul"
let id = cuid::cuid1();
dbg!("cuid1: {}", &id);

assert!(id.len() == 25);
}

#[wasm_bindgen_test]

Check failure on line 13 in crates/cuid/tests/wasm.rs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, nightly, -p cuid)

cannot find attribute `wasm_bindgen_test` in this scope

Check failure on line 13 in crates/cuid/tests/wasm.rs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, beta, -p cuid)

cannot find attribute `wasm_bindgen_test` in this scope
fn cuid2_length() {
// e.g.: "u8yjmh700jcegr5oi3onij1u"
let id = cuid::cuid2();
dbg!("cuid2: {}", &id);

assert!(id.len() == 24);
}
12 changes: 6 additions & 6 deletions crates/cuid1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ num = { version = "0.4.0", features = ["num-bigint"] }
once_cell = "1.19.0"
rand.workspace = true
uuid = { version = "1.10.0", features = ["v4"] }
getrandom = { version = "0" }

[dev-dependencies]
criterion.workspace = true

# Not WASM deps
[target.'cfg(not(target_family = "wasm"))'.dependencies]
hostname = "0.4.0"

# WASM-only deps
[target.'cfg(target_arch = "wasm32")'.dependencies.getrandom]
features = ["js"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0", features = ["js"] }
wasm-rs-dbg = "0.1.2"

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
criterion.workspace = true

[lib]
name = "cuid1"
Expand Down
8 changes: 3 additions & 5 deletions crates/cuid1/src/fingerprint.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::process;

use crate::text::{pad, to_base_string};
use crate::BASE;
use cuid_util::process_id_fallback;

static FINGERPRINT_PADDING: usize = 2;

fn pid() -> String {
pad(FINGERPRINT_PADDING, to_base_string(process::id()))
pad(FINGERPRINT_PADDING, to_base_string(process_id_fallback()))
}

/// Convert the hostname to a padded String in the appropriate base.
Expand Down Expand Up @@ -43,8 +42,7 @@ fn host_id() -> String {

pub fn fingerprint() -> String {
let mut hid = host_id();
let procid = pid();
hid.push_str(&procid);
hid.push_str(pid().as_str());
hid
}

Expand Down
11 changes: 10 additions & 1 deletion crates/cuid2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,18 @@ num = { version = "0.4.0", features = ["num-bigint"] }
rand.workspace = true
sha3 = "0.10.6"

# WASM-only deps
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0", features = ["js"] }

[dev-dependencies]
criterion.workspace = true
num_cpus = "1.15.0"
proptest.workspace = true
radix_fmt = "1.0.0"

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
criterion.workspace = true

# WASM-only dev-deps
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test.workspace = true
9 changes: 3 additions & 6 deletions crates/cuid2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ use std::{
hash::{Hash, Hasher},
};

use cuid_util::ToBase36;
use cuid_util::{process_id_fallback, ToBase36};
use num::bigint;
use rand::{seq::SliceRandom, thread_rng, Rng};
use sha3::{Digest, Sha3_512};
Expand Down Expand Up @@ -103,16 +103,13 @@ thread_local! {
///
/// For us, we'll use
/// - A few random numbers
/// - the process ID
/// - the process ID (falling back to the number of entries in `globalThis` on wasm32-*, to avoid runtime panics)
/// - the thread ID (which also ensures our CUIDs will be different per thread)
///
/// This is pretty non-language, non-system dependent, so it allows us to
/// compile to wasm and so on.
static FINGERPRINT: String = hash(
[
thread_rng().gen::<u128>().to_be_bytes(),
thread_rng().gen::<u128>().to_be_bytes(),
u128::from(std::process::id()).to_be_bytes(),
process_id_fallback().to_be_bytes(),
u128::from(get_thread_id()).to_be_bytes(),
],
BIG_LENGTH.into(),
Expand Down

0 comments on commit c8e835c

Please sign in to comment.