diff --git a/worker-build/src/install.rs b/worker-build/src/install.rs index 50448968..89cd0893 100644 --- a/worker-build/src/install.rs +++ b/worker-build/src/install.rs @@ -35,7 +35,7 @@ pub fn ensure_wasm_pack() -> Result<()> { if is_installed("wasm-pack")?.is_none() { println!("Installing wasm-pack..."); let exit_status = Command::new("cargo") - .args(&["install", "wasm-pack"]) + .args(["install", "wasm-pack"]) .spawn()? .wait()?; diff --git a/worker-build/src/main.rs b/worker-build/src/main.rs index 219a56f8..3dccf8a5 100644 --- a/worker-build/src/main.rs +++ b/worker-build/src/main.rs @@ -49,9 +49,9 @@ where let exit_status = Command::new("wasm-pack") .arg("build") .arg("--no-typescript") - .args(&["--target", "bundler"]) - .args(&["--out-dir", OUT_DIR]) - .args(&["--out-name", OUT_NAME]) + .args(["--target", "bundler"]) + .args(["--out-dir", OUT_DIR]) + .args(["--out-name", OUT_NAME]) .args(args) .spawn()? .wait()?; @@ -122,7 +122,7 @@ fn bundle(esbuild_path: &Path) -> Result<()> { let path = PathBuf::from(OUT_DIR).join(WORKER_SUBDIR).canonicalize()?; let esbuild_path = esbuild_path.canonicalize()?; let mut command = Command::new(esbuild_path); - command.args(&[ + command.args([ "--external:./index.wasm", "--format=esm", "--bundle", diff --git a/worker-sandbox/remote-service/package.json b/worker-sandbox/remote-service/package.json new file mode 100644 index 00000000..8f5067aa --- /dev/null +++ b/worker-sandbox/remote-service/package.json @@ -0,0 +1,3 @@ +{ + "main": "./service.js" +} diff --git a/worker-sandbox/remote-service/service.js b/worker-sandbox/remote-service/service.js new file mode 100644 index 00000000..27d56bf8 --- /dev/null +++ b/worker-sandbox/remote-service/service.js @@ -0,0 +1,3 @@ +addEventListener('fetch', event => { + event.respondWith(new Response('hello world')) +}) diff --git a/worker-sandbox/remote-service/wrangler.toml b/worker-sandbox/remote-service/wrangler.toml new file mode 100644 index 00000000..19e9f373 --- /dev/null +++ b/worker-sandbox/remote-service/wrangler.toml @@ -0,0 +1,2 @@ +name = "remote-service" +type = "javascript" diff --git a/worker-sandbox/src/lib.rs b/worker-sandbox/src/lib.rs index 4781d04e..2d57b69b 100644 --- a/worker-sandbox/src/lib.rs +++ b/worker-sandbox/src/lib.rs @@ -646,6 +646,17 @@ pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result Result { self.get_binding(binding) } + + /// Get a [Service Binding](https://developers.cloudflare.com/workers/runtime-apis/service-bindings/) + /// for Worker-to-Worker communication. + pub fn service(&self, binding: &str) -> Result { + self.get_binding(binding) + } } pub trait EnvBinding: Sized + JsCast { diff --git a/worker/src/fetcher.rs b/worker/src/fetcher.rs index 3572590d..98355a1e 100644 --- a/worker/src/fetcher.rs +++ b/worker/src/fetcher.rs @@ -1,20 +1,20 @@ -use wasm_bindgen::JsCast; +use wasm_bindgen::{JsCast, JsValue}; use wasm_bindgen_futures::JsFuture; use worker_sys::{Fetcher as FetcherSys, Response as ResponseSys}; -use crate::{Request, RequestInit, Response, Result}; +use crate::{env::EnvBinding, Request, RequestInit, Response, Result}; /// A struct for invoking fetch events to other Workers. pub struct Fetcher(FetcherSys); impl Fetcher { - /// Invoke a fetch event in a worker with a path and optionally a [RequestInit]. + /// Invoke a fetch event in a worker with a url and optionally a [RequestInit]. pub async fn fetch( &self, - path: impl Into, + url: impl Into, init: Option, ) -> Result { - let path = path.into(); + let path = url.into(); let promise = match init { Some(ref init) => self.0.fetch_with_str_and_init(&path, &init.into()), None => self.0.fetch_with_str(&path), @@ -32,6 +32,36 @@ impl Fetcher { } } +impl EnvBinding for Fetcher { + const TYPE_NAME: &'static str = "Fetcher"; +} + +impl JsCast for Fetcher { + fn instanceof(val: &wasm_bindgen::JsValue) -> bool { + val.is_instance_of::() + } + + fn unchecked_from_js(val: wasm_bindgen::JsValue) -> Self { + Self(val.into()) + } + + fn unchecked_from_js_ref(val: &wasm_bindgen::JsValue) -> &Self { + unsafe { &*(val as *const JsValue as *const Self) } + } +} + +impl From for JsValue { + fn from(service: Fetcher) -> Self { + JsValue::from(service.0) + } +} + +impl AsRef for Fetcher { + fn as_ref(&self) -> &wasm_bindgen::JsValue { + &self.0 + } +} + impl From for Fetcher { fn from(inner: FetcherSys) -> Self { Self(inner) diff --git a/worker/src/router.rs b/worker/src/router.rs index 89e6a193..8eca726d 100644 --- a/worker/src/router.rs +++ b/worker/src/router.rs @@ -10,7 +10,7 @@ use crate::{ http::Method, request::Request, response::Response, - Result, + Fetcher, Result, }; type HandlerFn = fn(Request, RouteContext) -> Result; @@ -94,6 +94,12 @@ impl RouteContext { pub fn param(&self, key: &str) -> Option<&String> { self.params.get(key) } + + /// Get a [Service Binding](https://developers.cloudflare.com/workers/runtime-apis/service-bindings/) + /// for Worker-to-Worker communication. + pub fn service(&self, binding: &str) -> Result { + self.env.service(binding) + } } impl<'a> Router<'a, ()> {