Skip to content

Commit

Permalink
Add deno_websocket
Browse files Browse the repository at this point in the history
  • Loading branch information
kovaszab committed Jul 13, 2024
1 parent 2e8b8ed commit f500b14
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 27 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
.vscode
.vscode
.idea
70 changes: 66 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ readme = "readme.md"
[features]
default = ["worker", "web_stub", "console", "url", "crypto"]
no_extensions = []
all = ["web", "io", "webstorage", "cache"]
all = ["web", "io", "webstorage", "cache", "websocket"]

# By default, an extension stub is included in the runtime if the `web` feature is disabled
# It provides a minimal set of APIs for parts of the runtime, such as timers and the DOM exception class
Expand Down Expand Up @@ -59,6 +59,8 @@ web_stub = ["webidl"]
# [https://html.spec.whatwg.org/multipage/webstorage.html]
webstorage = ["deno_webstorage", "webidl"]

websocket = ["deno_websocket", "deno_web"]

# Features for the module loader
# Both will break sandboxing
# - fs_import allows arbitrary file imports
Expand Down Expand Up @@ -105,6 +107,7 @@ deno_url = {version = "0.160.0", optional = true}
deno_web = {version = "0.191.0", optional = true}
deno_webidl = {version = "0.160.0", optional = true}
deno_webstorage = {version = "0.155.0", optional = true}
deno_websocket = {version = "0.165.0", optional = true }

# Dependencies for the IO feature
deno_io = {version = "0.70.0", optional = true}
Expand Down Expand Up @@ -138,6 +141,10 @@ required-features = ["snapshot_builder"]
name = "url_import"
required-features = ["fs_import", "url_import"]

[[example]]
name = "websocket"
required-features = ["websocket", "web"]

[[bench]]
name = "runtime"
harness = false
53 changes: 53 additions & 0 deletions examples/websocket.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
///
/// This example demonstrates how to use websockets.
///
use rustyscript::{Error, json_args, Module, Runtime, RuntimeOptions, Undefined};

fn main() -> Result<(), Error> {
let module = Module::new(
"test.js",
"
export async function connect(url) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(url);
ws.addEventListener('open', () => {
console.log(ws.readyState);
ws.send('ping');
});
ws.addEventListener('message', (event) => {
console.log(event.data);
ws.close();
});
ws.addEventListener('close', (event) => {
if (event.wasClean) {
console.log(`Connection closed, code=${event.code} reason=${event.reason}`);
resolve(`Connection closed, code=${event.code} reason=${event.reason}`);
} else {
console.log('Connection died');
reject(new Error('Connection died'));
}
});
ws.addEventListener('error', (e) => {
console.log(`Error: ${e}`);
reject(new Error(`Error: ${e}`));
});
});
}
",
);

let mut runtime = Runtime::new(RuntimeOptions {
default_entrypoint: Some("connect".to_string()),
..Default::default()
})?;

let module_handle = runtime.load_module(&module)?;

runtime.call_entrypoint::<Undefined>(&module_handle, json_args!("wss://echo.websocket.org"))?;

Ok(())
}
43 changes: 22 additions & 21 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,27 +215,28 @@ More details on the features can be found in `Cargo.toml`
Please note that the 'web' feature will also enable fs_import and url_import, allowing arbitrary filesystem and network access for import statements
- This is because the deno_web crate allows both fetch and FS reads already

| Feature | Description | Preserves Sandbox| Dependencies |
|----------------|---------------------------------------------------------------------------------------------------|------------------|---------------------------------------------------------------------------------|
|cache |Implements the Cache API for Deno |**NO** |deno_cache, deno_webidl, deno_web, deno_crypto, deno_fetch, deno_url, deno_net |
|console |Provides `console.*` functionality from JS |yes |deno_console |
|crypto |Provides `crypto.*` functionality from JS |yes |deno_crypto, deno_webidl |
|url |Provides the URL, and URLPattern APIs from within JS |yes |deno_webidl, deno_url |
|io |Provides IO primitives such as stdio streams and abstraction over File System files. |**NO** |deno_io, rustyline, winapi, nix, libc, once_cell |
|web |Provides the Event, TextEncoder, TextDecoder, File, Web Cryptography, and fetch APIs from within JS|**NO** |deno_webidl, deno_web, deno_crypto, deno_fetch, deno_url, deno_net |
|webstorage |Provides the WebStorage API |**NO** |deno_webidl, deno_webstorage |
|webidl |Provides the webidl API |yes |deno_webidl |
| | | | |
|default |Provides only those extensions that preserve sandboxing |yes |deno_console, deno_crypto, deno_webidl, deno_url |
|no_extensions |Disables all extensions to the JS runtime - you can still add your own extensions in this mode |yes |None |
|all |Provides all available functionality |**NO** |deno_console, deno_webidl, deno_web, deno_net, deno_crypto, deno_fetch, deno_url |
| | | | |
|fs_import |Enables importing arbitrary code from the filesystem through JS |**NO** |None |
|url_import |Enables importing arbitrary code from network locations through JS |**NO** |reqwest |
| | | | |
|worker |Enables access to the threaded worker API [worker] |yes |None |
|snapshot_builder|Enables access to [SnapshotBuilder], a runtime for creating snapshots that can improve start-times |yes |None |
|web_stub |Enables a subset of `web` features that do not break sandboxing |yes |deno_webidl |
| Feature | Description | Preserves Sandbox| Dependencies |
|------------------|-----------------------------------------------------------------------------------------------------|------------------|----------------------------------------------------------------------------------|
| cache | Implements the Cache API for Deno |**NO** | deno_cache, deno_webidl, deno_web, deno_crypto, deno_fetch, deno_url, deno_net |
| console | Provides `console.*` functionality from JS |yes | deno_console |
| crypto | Provides `crypto.*` functionality from JS |yes | deno_crypto, deno_webidl |
| url | Provides the URL, and URLPattern APIs from within JS |yes | deno_webidl, deno_url |
| io | Provides IO primitives such as stdio streams and abstraction over File System files. |**NO** | deno_io, rustyline, winapi, nix, libc, once_cell |
| web | Provides the Event, TextEncoder, TextDecoder, File, Web Cryptography, and fetch APIs from within JS |**NO** | deno_webidl, deno_web, deno_crypto, deno_fetch, deno_url, deno_net |
| webstorage | Provides the WebStorage API |**NO** | deno_webidl, deno_webstorage |
| weboscket | Provides the WebSocket API |**NO** | deno_web, deno_websocket |
| webidl | Provides the webidl API |yes | deno_webidl |
| | | | |
| default | Provides only those extensions that preserve sandboxing |yes | deno_console, deno_crypto, deno_webidl, deno_url |
| no_extensions | Disables all extensions to the JS runtime - you can still add your own extensions in this mode |yes | None |
| all | Provides all available functionality |**NO** | deno_console, deno_webidl, deno_web, deno_net, deno_crypto, deno_fetch, deno_url |
| | | | |
| fs_import | Enables importing arbitrary code from the filesystem through JS |**NO** | None |
| url_import | Enables importing arbitrary code from network locations through JS |**NO** | reqwest |
| | | | |
| worker | Enables access to the threaded worker API [worker] |yes | None |
| snapshot_builder | Enables access to [SnapshotBuilder], a runtime for creating snapshots that can improve start-times |yes | None |
| web_stub | Enables a subset of `web` features that do not break sandboxing |yes | deno_webidl |

----

Expand Down
12 changes: 12 additions & 0 deletions src/ext/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub mod io;
#[cfg(feature = "webstorage")]
pub mod webstorage;

#[cfg(feature = "websocket")]
pub mod websocket;

/// Options for configuring extensions
pub struct ExtensionOptions {
/// Options specific to the deno_web, deno_fetch and deno_net extensions
Expand All @@ -52,6 +55,9 @@ pub struct ExtensionOptions {
/// Optional cache configuration for the deno_cache extension
#[cfg(feature = "cache")]
pub cache: Option<deno_cache::CreateCache<deno_cache::SqliteBackedCache>>,

#[cfg(feature = "websocket")]
pub websocket_user_agent: String,
}

impl Default for ExtensionOptions {
Expand All @@ -71,6 +77,9 @@ impl Default for ExtensionOptions {

#[cfg(feature = "cache")]
cache: None,

#[cfg(feature = "websocket")]
websocket_user_agent: String::from("Deno"),
}
}
}
Expand Down Expand Up @@ -112,6 +121,9 @@ pub fn all_extensions(
options.webstorage_origin_storage_dir,
));

#[cfg(feature = "websocket")]
extensions.extend(websocket::extensions(options.websocket_user_agent));

extensions.extend(user_extensions);
extensions
}
Expand Down
9 changes: 9 additions & 0 deletions src/ext/websocket/init_websocket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as websocket from "ext:deno_websocket/01_websocket.js";
import * as websocketStream from "ext:deno_websocket/02_websocketstream.js";

import { applyToGlobal, getterOnly, nonEnumerable } from 'ext:rustyscript/rustyscript.js';

applyToGlobal({
WebSocket: nonEnumerable(websocket.WebSocket),
CloseEvent: nonEnumerable(websocket.CloseEvent)
});
32 changes: 32 additions & 0 deletions src/ext/websocket/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use deno_core::{extension, Extension};
use deno_core::error::AnyError;
use deno_core::url::Url;
use deno_websocket::WebSocketPermissions;
use crate::ext::web::Permissions;

extension!(
init_websocket,
deps = [rustyscript],
esm_entry_point = "ext:init_websocket/init_websocket.js",
esm = [ dir "src/ext/websocket", "init_websocket.js" ],
);

impl WebSocketPermissions for Permissions {
fn check_net_url(&mut self, _url: &Url, _api_name: &str) -> Result<(), AnyError> {
Ok(())
}
}

pub fn extensions(user_agent: String) -> Vec<Extension> {
vec![
deno_websocket::deno_websocket::init_ops_and_esm::<Permissions>(user_agent, None, None),
init_websocket::init_ops_and_esm(),
]
}

pub fn snapshot_extensions(user_agent: String) -> Vec<Extension> {
vec![
deno_websocket::deno_websocket::init_ops::<Permissions>(user_agent, None, None),
init_websocket::init_ops(),
]
}

0 comments on commit f500b14

Please sign in to comment.