diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml new file mode 100644 index 0000000..63d3ddd --- /dev/null +++ b/.github/workflows/deploy-demo.yml @@ -0,0 +1,70 @@ +name: Deploy Web Demo + +on: + push: + branches: [ main ] + paths: + - 'web-demo/**' + - 'doublets/**' + - '.github/workflows/deploy-demo.yml' + pull_request: + branches: [ main ] + paths: + - 'web-demo/**' + - 'doublets/**' + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: read + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + override: true + + - name: Install wasm-pack + run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + + - name: Cache cargo dependencies + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Build web demo + run: | + cd web-demo + wasm-pack build --target web --out-dir pkg + + - name: Setup Pages + if: github.ref == 'refs/heads/main' + uses: actions/configure-pages@v3 + + - name: Upload artifact + if: github.ref == 'refs/heads/main' + uses: actions/upload-pages-artifact@v2 + with: + path: ./web-demo + + - name: Deploy to GitHub Pages + if: github.ref == 'refs/heads/main' + id: deployment + uses: actions/deploy-pages@v2 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/Cargo.lock b/Cargo.lock index fbf94c6..37dfa3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -96,6 +96,16 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "criterion" version = "0.3.6" @@ -220,7 +230,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn", + "syn 1.0.98", ] [[package]] @@ -231,7 +241,7 @@ checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -242,7 +252,7 @@ checksum = "d70a2d4995466955a415223acf3c9c934b9ff2339631cdf4ffc893da4bacd717" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -281,6 +291,19 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "doublets-web-demo" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "serde", + "serde-wasm-bindgen", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "either" version = "1.7.0" @@ -293,7 +316,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -323,7 +346,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn", + "syn 1.0.98", ] [[package]] @@ -624,9 +647,9 @@ checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.42" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c278e965f1d8cf32d6e0e96de3d3e79712178ae67986d9cf9151f51e95aac89b" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -650,14 +673,14 @@ checksum = "b22a693222d716a9587786f37ac3f6b4faedb5b80c23914e7303ff5a1d8016e9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -777,6 +800,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + [[package]] name = "ryu" version = "1.0.10" @@ -807,6 +836,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_cbor" version = "0.11.2" @@ -825,7 +865,7 @@ checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -877,6 +917,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tap" version = "1.0.1" @@ -923,7 +974,7 @@ checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -980,7 +1031,7 @@ checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.98", ] [[package]] @@ -1020,9 +1071,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.2" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-width" @@ -1055,34 +1106,36 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.106", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1090,22 +1143,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" diff --git a/Cargo.toml b/Cargo.toml index 8176e2d..baff8b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,9 @@ members = [ "doublets-ffi", "doublets", + # web demo + "web-demo", + # dev "dev-deps/mem-rs", "dev-deps/data-rs", diff --git a/README.md b/README.md index 96d8b46..66d7345 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,16 @@ later later +## Web Demo + +Try the interactive WebAssembly demo: [**🔗 Doublets Playground**](https://linksplatform.github.io/doublets-rs/) + +The web demo allows you to: +- Create and manage doublets interactively +- Explore link relationships visually +- Learn doublets concepts in your browser +- See real-time operations and results + ## Example A basic operations in doublets: diff --git a/web-demo/Cargo.toml b/web-demo/Cargo.toml new file mode 100644 index 0000000..152c4fa --- /dev/null +++ b/web-demo/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "doublets-web-demo" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wasm-bindgen = "0.2" +js-sys = "0.3" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde-wasm-bindgen = "0.4" +console_error_panic_hook = "0.1" + +[dependencies.web-sys] +version = "0.3" +features = [ + "console", + "Document", + "Element", + "HtmlElement", + "Window", +] \ No newline at end of file diff --git a/web-demo/README.md b/web-demo/README.md new file mode 100644 index 0000000..f13cc16 --- /dev/null +++ b/web-demo/README.md @@ -0,0 +1,102 @@ +# Doublets Web Demo + +An interactive WebAssembly playground for exploring doublets operations in your browser. + +## Features + +- **Create Links**: Build custom doublets with specified source and target +- **Create Points**: Generate self-referencing links (points) +- **Delete Links**: Remove links by ID +- **Search & Filter**: Find links by source and/or target +- **Real-time Display**: Live view of all links in the store +- **Operations Log**: Track all operations performed + +## Quick Start + +### Prerequisites + +- Rust toolchain with WebAssembly target +- `wasm-pack` tool for building WebAssembly modules + +### Building + +1. Install the WebAssembly target: + ```bash + rustup target add wasm32-unknown-unknown + ``` + +2. Install wasm-pack (if not already installed): + ```bash + curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + ``` + +3. Build the demo: + ```bash + cd web-demo + ./build.sh + ``` + +### Running + +Start a local web server: +```bash +python3 -m http.server 8000 +``` + +Then open [http://localhost:8000](http://localhost:8000) in your browser. + +## Usage + +### Creating Links + +1. **Points**: Click "Create Point" to create a self-referencing link (1 → 1) +2. **Custom Links**: Enter source and target values, then click "Create Link" + +### Managing Links + +- View all links in the table on the right +- Delete links by entering their ID and clicking "Delete Link" +- Search for specific links using source/target filters + +### Understanding Doublets + +Doublets are a fundamental data structure where: +- Each **link** connects a **source** to a **target** +- Links themselves have unique **IDs** +- **Points** are special links where source equals target +- The system maintains referential integrity + +## Architecture + +The demo consists of: + +- **Rust/WebAssembly Core**: Uses the `doublets` crate for all operations +- **JavaScript Interface**: Provides UI interactions and state management +- **HTML/CSS Frontend**: Responsive web interface + +## Example Operations + +```javascript +// Create a new doublets store +const demo = new DoubletsDemo(); + +// Create a point (self-link) +const point = demo.create_point(); // Returns: 1 + +// Create a custom link +const link = demo.create_link(2, 3); // Returns: 2 + +// Get all links +const allLinks = demo.get_all_links(); +// Returns: [ +// { id: 1, source: 1, target: 1 }, +// { id: 2, source: 2, target: 3 } +// ] + +// Search for links +const results = demo.search_links(2, null); // Find links with source=2 +``` + +## Contributing + +This demo is part of the [doublets-rs](https://github.com/linksplatform/doublets-rs) project. Contributions are welcome! \ No newline at end of file diff --git a/web-demo/build.sh b/web-demo/build.sh new file mode 100755 index 0000000..dcdff5c --- /dev/null +++ b/web-demo/build.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +echo "Building Doublets WebAssembly Demo..." + +# Check if wasm-pack is installed +if ! command -v wasm-pack &> /dev/null; then + echo "Installing wasm-pack..." + curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh +fi + +# Build the WebAssembly module +echo "Building WebAssembly module..." +wasm-pack build --target web --out-dir pkg + +echo "Build complete! The demo is ready to serve." +echo "To run the demo locally:" +echo " cd web-demo" +echo " python3 -m http.server 8000" +echo " # Then open http://localhost:8000 in your browser" \ No newline at end of file diff --git a/web-demo/index.html b/web-demo/index.html new file mode 100644 index 0000000..ed09010 --- /dev/null +++ b/web-demo/index.html @@ -0,0 +1,465 @@ + + +
+ +Interactive WebAssembly demo for exploring doublets operations
+| ID | +Source | +Target | +
|---|