{"id":15645321,"url":"https://github.com/dunnock/wasi-worker","last_synced_at":"2025-04-13T18:14:16.865Z","repository":{"id":35610444,"uuid":"218065435","full_name":"dunnock/wasi-worker","owner":"dunnock","description":"WASM / WASI interface for browser service workers","archived":false,"fork":false,"pushed_at":"2022-04-11T19:42:59.000Z","size":724,"stargazers_count":59,"open_issues_count":6,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-13T18:14:11.094Z","etag":null,"topics":["javascript","rollup","rust","typescript","wasi","wasm","yew"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dunnock.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-28T14:26:39.000Z","updated_at":"2025-01-24T10:28:58.000Z","dependencies_parsed_at":"2022-08-08T09:31:26.532Z","dependency_job_id":null,"html_url":"https://github.com/dunnock/wasi-worker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunnock%2Fwasi-worker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunnock%2Fwasi-worker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunnock%2Fwasi-worker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunnock%2Fwasi-worker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dunnock","download_url":"https://codeload.github.com/dunnock/wasi-worker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248758418,"owners_count":21156957,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","rollup","rust","typescript","wasi","wasm","yew"],"created_at":"2024-10-03T12:06:21.301Z","updated_at":"2025-04-13T18:14:16.840Z","avatar_url":"https://github.com/dunnock.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"The proper way to create WASM browser service workers.\n\nThis crate provides rust library and JS glue code allowing to wrap POSIX compatible code into WASM/WASI target to be able to run in the browser service worker. It also provides imput/output message channel with main web application.\n\n# Why WASI?\n\n\u003e WebAssembly System Interfaces (WASI) is an exciting new specification that allows running POSIX-like applications anywhere, safely and securely with WebAssembly. [-\u003e Medium / Running WASI in Javascript with Wasmer-JS](https://medium.com/wasmer/wasmer-js-9a53e837b80)\n\nPOSIX-compatible applications compiled to WASI can now also run in browser, think of code-reuse and delegating server workload to client side. On top of that it appears code compiled to wasm32-wasi target is executing about 2 times faster than code compiled to other wasm32 targets with web bindings, CPU intensive workloads can now execute with performance close to native targets (try http://wabench.com:8080).\n\n# Why might I need wasi-worker?\n\nWASI target allows to compile many crates which are using standard library, except threads and networking which is not supported yet. The only problem is that WASI is not built to be executed from browser, rather it is standard which aims to run WASM code on server side. Leveraging [@wasmer/wasi](https://github.com/wasmerio/wasmer-js) this crate provides browser service worker WASI runtime as well as communication bridge to/from web application.\n\nAnother possible reason is WASM code which executes as part of web application occupies same javascript thread, hence if wasm code is running complex calculations it will block browser application while working. To make it working in separate thread we can employ [browser service workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers).\n\n\n# Usage example\n\nThis example requires WASI JavaScript bindings [which can be deployed with wasi-worker-cli](https://github.com/dunnock/wasi-worker/tree/master/crates/wasi-worker-cli) or [WASI environment](https://github.com/dunnock/wasi-worker/tree/master/examples/myworker) with properly preconfigured filesystem\n\n```rust\nuse wasi_worker::*;\n\nstruct MyWorker;\nimpl Handler for MyWorker {\n  fn on_message(\u0026self, msg: \u0026[u8]) -\u003e std::io::Result\u003c()\u003e {\n    println!(\"My Worker got message: {:?}\", msg);\n    Ok(())\n  }\n}\n\nfn main() {\n  // JS glue code will hook to /output.bin\n  ServiceWorker::initialize(ServiceOptions::default());\n  ServiceWorker::set_message_handler(Box::new(MyWorker {}));\n  // Send binary message to main browser application\n  ServiceWorker::post_message(b\"message\");\n}\n```\n\n\n# JavaScript WASI bindings\n\nJavaScript WASI bindings are built on top of [@wasmer](https://www.npmjs.com/search?q=%40wasmer) libraries can be easily deployed with [wasiworker](https://github.com/dunnock/wasi-worker/tree/master/wasi-worker-cli) tool:\n```\ncargo install wasi-worker-cli\n```\n\n`wasiworker install` will add sample `worker` code and bin target to current crate directory:\n```\nwasiworker install\n```\n\n`wasiworker deploy` will build `worker` bin target and deploy it with JS glue code under `./dist`:\n```\nwasiworker deploy\n```\n\nFor hacking [JS glue code source code](https://github.com/dunnock/wasi-worker/tree/master/wasi-worker-cli/js) is located in the same repository.\n\n\n# More detailed example\n\n```rust\nuse wasi_worker::*;\n\nstruct MyWorker {}\nimpl Handler for MyWorker {\n  fn on_message(\u0026self, msg: \u0026[u8]) -\u003e std::io::Result\u003c()\u003e {\n    // Process incoming message\n    println!(\"My Worker got message: {:?}\", msg);\n    Ok(())\n  }\n}\n\nfn main() {\n  // In WASI setup output will go to /output.bin\n  #[cfg(target_os=\"wasi\")]\n  let opt = ServiceOptions::default();\n  // In user filesystem we operate under current dir\n  #[cfg(not(target_os=\"wasi\"))]\n  let opt = ServiceOptions { \n    output: FileOptions::File(\"./testdata/output.bin\".to_string()) \n  };\n  let output_file = match \u0026opt.output { \n    FileOptions::File(path) =\u003e path.clone() \n  };\n  ServiceWorker::initialize(opt)\n    .expect(\"ServiceWorker::initialize\");\n\n  // Attach Agent to ServiceWorker as message handler singleton\n  ServiceWorker::set_message_handler(Box::new(MyWorker {}));\n\n  // Send binary message to main browser application\n  // this requires JS glue see wasi-worker-cli\n  ServiceWorker::post_message(b\"message\")\n    .expect(\"ServiceWorker::post_message\");\n\n  // It does not autodelete output file\n  std::fs::remove_file(output_file)\n    .expect(\"Remove output.bin\");\n}\n```\n\n\n# TODO\n\n- [X] library code with WASI fs interface\n- [X] basic example\n- [X] documentation\n- [X] CLI for worker setup\n- [X] drop output file on exit","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunnock%2Fwasi-worker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdunnock%2Fwasi-worker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunnock%2Fwasi-worker/lists"}