use mozjs::jsapi::*;
use mozjs::jsval::{UndefinedValue, StringValue};
use mozjs::rooted;
use mozjs::rust::wrappers2::JS_NewPlainObject;
pub fn install_web_streams(
cx: &mut mozjs::context::JSContext,
global: mozjs::rust::Handle<*mut JSObject>,
) {
let src = include_str!("web_streams.js");
unsafe {
let raw = cx.raw_cx();
let mut rval = UndefinedValue();
let opts = mozjs::glue::NewCompileOptions(
raw,
c"web_streams".as_ptr(),
1,
);
if !opts.is_null() {
let mut src_text = mozjs::rust::transform_str_to_source_text(src);
mozjs_sys::jsapi::JS::Evaluate2(
raw,
opts,
&mut src_text,
MutableHandle::<Value> {
_phantom_0: ::std::marker::PhantomData,
ptr: &mut rval,
},
);
libc::free(opts as *mut _);
}
}
}
pub fn install_web_streams_on_target(
cx: &mut mozjs::context::JSContext,
target: mozjs::rust::Handle<*mut JSObject>,
) {
unsafe {
let raw = cx.raw_cx();
let global = CurrentGlobalOrNull(raw);
if global.is_null() {
return;
}
rooted!(&in(cx) let global_root = global);
install_web_streams(cx, global_root.handle());
let names = [
"ReadableStream", "ReadableStreamDefaultReader", "ReadableStreamBYOBReader",
"ReadableStreamDefaultController", "ReadableByteStreamController",
"ReadableStreamBYOBRequest",
"WritableStream", "WritableStreamDefaultWriter", "WritableStreamDefaultController",
"TransformStream", "TransformStreamDefaultController",
"ByteLengthQueuingStrategy", "CountQueuingStrategy",
"TextEncoderStream", "TextDecoderStream",
"CompressionStream", "DecompressionStream",
];
rooted!(&in(cx) let target_root = target.get());
for name in &names {
let mut val = UndefinedValue();
let cname = bun_core::ZBox::from_bytes(name.as_bytes());
JS_GetProperty(
raw,
global_root.handle().into(),
cname.as_ptr(),
MutableHandle::<Value> {
_phantom_0: ::std::marker::PhantomData,
ptr: &mut val,
},
);
if val.is_object() {
rooted!(&in(cx) let val_root = val);
JS_DefineProperty(
raw,
target_root.handle().into(),
cname.as_ptr(),
val_root.handle().into(),
JSPROP_ENUMERATE as u32,
);
}
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn web_streams_js_source_is_not_empty() {
let src = include_str!("web_streams.js");
assert!(!src.is_empty(), "web_streams.js must not be empty");
assert!(src.contains("ReadableStream"), "must define ReadableStream");
assert!(src.contains("WritableStream"), "must define WritableStream");
assert!(src.contains("TransformStream"), "must define TransformStream");
}
#[test]
fn web_streams_js_defines_all_constructors() {
let src = include_str!("web_streams.js");
let required = [
"ReadableStream",
"ReadableStreamDefaultReader",
"ReadableStreamBYOBReader",
"ReadableStreamDefaultController",
"ReadableByteStreamController",
"ReadableStreamBYOBRequest",
"WritableStream",
"WritableStreamDefaultWriter",
"WritableStreamDefaultController",
"TransformStream",
"TransformStreamDefaultController",
"ByteLengthQueuingStrategy",
"CountQueuingStrategy",
"TextEncoderStream",
"TextDecoderStream",
"CompressionStream",
"DecompressionStream",
];
for name in &required {
assert!(
src.contains(name),
"web_streams.js must define constructor: {}",
name
);
}
}
}