5bed43ef32
A new `cdylib + rlib` workspace member that wraps `solitaire_core::
GameState` for use from JavaScript. The web replay viewer fetches a
replay JSON, hands it to `ReplayPlayer::new`, and steps through
moves one at a time — same Rust rules engine the desktop client
uses, so the two implementations cannot drift.
The crate intentionally does NOT depend on `solitaire_data` (which
pulls dirs/keyring/reqwest, none wasm-friendly). Instead it defines
a minimal `Replay` mirror with the same serde shape; the JSON wire
format is the contract.
Public surface (#[wasm_bindgen]):
- `ReplayPlayer::new(json)` — parse + rebuild deal from seed/mode
- `state()` / `step()` — return JS-friendly StateSnapshot
- `total_steps()` / `step_idx()` / `is_finished()` — progress helpers
Native-callable mirror (`from_json`, `step_native`) lets unit tests
exercise the state machine without going through `serde_wasm_bindgen`,
which panics off-target. 3 tests cover construction, step advance,
and invalid-JSON handling.
`getrandom` needs the `wasm_js` feature on the wasm32 target;
configured via the cfg target dep table so non-wasm builds aren't
affected.
Build pipeline (executed from the repo root):
rustup target add wasm32-unknown-unknown
RUSTFLAGS='--cfg getrandom_backend="wasm_js"' \
cargo build -p solitaire_wasm \
--target wasm32-unknown-unknown --release
wasm-bindgen --target web \
--out-dir solitaire_server/web/pkg --no-typescript \
target/wasm32-unknown-unknown/release/solitaire_wasm.wasm
The generated bindings land in solitaire_server/web/pkg/ and are
committed alongside the web UI (next commit).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
84 lines
2.5 KiB
TOML
84 lines
2.5 KiB
TOML
[workspace]
|
|
members = [
|
|
"solitaire_core",
|
|
"solitaire_sync",
|
|
"solitaire_data",
|
|
"solitaire_engine",
|
|
"solitaire_server",
|
|
"solitaire_app",
|
|
"solitaire_assetgen",
|
|
"solitaire_wasm",
|
|
]
|
|
resolver = "2"
|
|
|
|
[workspace.package]
|
|
edition = "2024"
|
|
version = "0.1.0"
|
|
license = "MIT"
|
|
rust-version = "1.95"
|
|
|
|
[workspace.dependencies]
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
uuid = { version = "1", features = ["v4", "serde"] }
|
|
chrono = { version = "0.4", features = ["serde"] }
|
|
thiserror = "2"
|
|
rand = "0.9"
|
|
async-trait = "0.1"
|
|
tokio = { version = "1", features = ["full"] }
|
|
dirs = "6"
|
|
keyring = "4"
|
|
keyring-core = "1"
|
|
reqwest = { version = "0.13", features = ["json", "rustls", "rustls-native-certs"], default-features = false }
|
|
|
|
solitaire_core = { path = "solitaire_core" }
|
|
solitaire_sync = { path = "solitaire_sync" }
|
|
solitaire_data = { path = "solitaire_data" }
|
|
solitaire_engine = { path = "solitaire_engine" }
|
|
|
|
bevy = "0.18"
|
|
kira = "0.12"
|
|
|
|
# SVG rasterisation pipeline for the runtime card-theme system.
|
|
# usvg parses + simplifies; resvg renders to a tiny-skia Pixmap;
|
|
# tiny-skia provides the CPU rasteriser. All three are maintained
|
|
# together by the resvg-rs project and version in lockstep.
|
|
usvg = "0.47"
|
|
resvg = "0.47"
|
|
tiny-skia = "0.12"
|
|
|
|
# Theme manifest format. RON keeps the file human-editable while
|
|
# preserving Rust-style structures the importer can validate.
|
|
ron = "0.12"
|
|
|
|
# Importer-only: reads user-supplied theme zip archives, validates
|
|
# their contents, and unpacks them into the user themes directory.
|
|
# Default features are disabled to keep the dependency footprint small;
|
|
# only `deflate` is needed because the importer rejects other
|
|
# compression methods anyway (see Phase 7 spec).
|
|
zip = { version = "8.6", default-features = false, features = ["deflate"] }
|
|
|
|
# Importer-only test dependency: tests build zip archives in a
|
|
# scratch directory so they don't pollute the real user themes path
|
|
# on the developer's machine.
|
|
tempfile = "3.27"
|
|
|
|
axum = "0.8"
|
|
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
|
|
jsonwebtoken = { version = "10", default-features = false, features = ["rust_crypto"] }
|
|
bcrypt = "0.19"
|
|
tower_governor = "0.8"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
dotenvy = "0.15"
|
|
|
|
[profile.dev]
|
|
opt-level = 1
|
|
|
|
[profile.dev.package."*"]
|
|
opt-level = 3
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = "thin"
|