1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 23:34:47 -05:00

refactor(extensions): reintroduce builder (#10412)

This commit is contained in:
Aaron O'Mullan 2021-04-29 00:16:45 +02:00 committed by GitHub
parent e63c533154
commit e89295b176
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 141 additions and 112 deletions

View file

@ -15,38 +15,13 @@ pub struct Extension {
initialized: bool,
}
impl Extension {
pub fn new(
js_files: Option<Vec<SourcePair>>,
ops: Option<Vec<OpPair>>,
opstate_fn: Option<Box<OpStateFn>>,
middleware_fn: Option<Box<OpMiddlewareFn>>,
) -> Self {
Self {
js_files,
ops,
opstate_fn,
middleware_fn,
initialized: false,
}
}
pub fn pure_js(js_files: Vec<SourcePair>) -> Self {
Self::new(Some(js_files), None, None, None)
}
pub fn with_ops(
js_files: Vec<SourcePair>,
ops: Vec<OpPair>,
opstate_fn: Option<Box<OpStateFn>>,
) -> Self {
Self::new(Some(js_files), Some(ops), opstate_fn, None)
}
}
// Note: this used to be a trait, but we "downgraded" it to a single concrete type
// for the initial iteration, it will likely become a trait in the future
impl Extension {
pub fn builder() -> ExtensionBuilder {
Default::default()
}
/// returns JS source code to be loaded into the isolate (either at snapshotting,
/// or at startup). as a vector of a tuple of the file name, and the source code.
pub(crate) fn init_js(&self) -> Vec<SourcePair> {
@ -81,6 +56,54 @@ impl Extension {
}
}
// Provides a convenient builder pattern to declare Extensions
#[derive(Default)]
pub struct ExtensionBuilder {
js: Vec<SourcePair>,
ops: Vec<OpPair>,
state: Option<Box<OpStateFn>>,
middleware: Option<Box<OpMiddlewareFn>>,
}
impl ExtensionBuilder {
pub fn js(&mut self, js_files: Vec<SourcePair>) -> &mut Self {
self.js.extend(js_files);
self
}
pub fn ops(&mut self, ops: Vec<OpPair>) -> &mut Self {
self.ops.extend(ops);
self
}
pub fn state<F>(&mut self, opstate_fn: F) -> &mut Self
where
F: Fn(&mut OpState) -> Result<(), AnyError> + 'static,
{
self.state = Some(Box::new(opstate_fn));
self
}
pub fn middleware<F>(&mut self, middleware_fn: F) -> &mut Self
where
F: Fn(&'static str, Box<OpFn>) -> Box<OpFn> + 'static,
{
self.middleware = Some(Box::new(middleware_fn));
self
}
pub fn build(&mut self) -> Extension {
let js_files = Some(std::mem::take(&mut self.js));
let ops = Some(std::mem::take(&mut self.ops));
Extension {
js_files,
ops,
opstate_fn: self.state.take(),
middleware_fn: self.middleware.take(),
initialized: false,
}
}
}
/// Helps embed JS files in an extension. Returns Vec<(&'static str, &'static str)>
/// representing the filename and source code.
///

View file

@ -5,11 +5,13 @@ use deno_core::Extension;
use std::path::PathBuf;
pub fn init() -> Extension {
Extension::pure_js(include_js_files!(
prefix "deno:op_crates/console",
"01_colors.js",
"02_console.js",
))
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/console",
"01_colors.js",
"02_console.js",
))
.build()
}
pub fn get_declaration() -> PathBuf {

View file

@ -16,22 +16,22 @@ use std::path::PathBuf;
pub use rand; // Re-export rand
pub fn init(maybe_seed: Option<u64>) -> Extension {
Extension::with_ops(
include_js_files!(
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/crypto",
"01_crypto.js",
),
vec![(
))
.ops(vec![(
"op_crypto_get_random_values",
op_sync(op_crypto_get_random_values),
)],
Some(Box::new(move |state| {
)])
.state(move |state| {
if let Some(seed) = maybe_seed {
state.put(StdRng::seed_from_u64(seed));
}
Ok(())
})),
)
})
.build()
}
pub fn op_crypto_get_random_values(

View file

@ -56,8 +56,8 @@ pub fn init<P: FetchPermissions + 'static>(
user_agent: String,
ca_data: Option<Vec<u8>>,
) -> Extension {
Extension::with_ops(
include_js_files!(
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/fetch",
"01_fetch_util.js",
"11_streams.js",
@ -68,15 +68,15 @@ pub fn init<P: FetchPermissions + 'static>(
"23_request.js",
"23_response.js",
"26_fetch.js",
),
vec![
))
.ops(vec![
("op_fetch", op_sync(op_fetch::<P>)),
("op_fetch_send", op_async(op_fetch_send)),
("op_fetch_request_write", op_async(op_fetch_request_write)),
("op_fetch_response_read", op_async(op_fetch_response_read)),
("op_create_http_client", op_sync(op_create_http_client::<P>)),
],
Some(Box::new(move |state| {
])
.state(move |state| {
state.put::<reqwest::Client>({
create_http_client(user_agent.clone(), ca_data.clone()).unwrap()
});
@ -85,8 +85,8 @@ pub fn init<P: FetchPermissions + 'static>(
user_agent: user_agent.clone(),
});
Ok(())
})),
)
})
.build()
}
pub struct HttpClientDefaults {

View file

@ -88,14 +88,14 @@ pub fn init(
blob_url_store: BlobUrlStore,
maybe_location: Option<Url>,
) -> Extension {
Extension::with_ops(
include_js_files!(
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/file",
"01_file.js",
"02_filereader.js",
"03_blob_url.js",
),
vec![
))
.ops(vec![
(
"op_file_create_object_url",
op_sync(op_file_create_object_url),
@ -104,15 +104,15 @@ pub fn init(
"op_file_revoke_object_url",
op_sync(op_file_revoke_object_url),
),
],
Some(Box::new(move |state| {
])
.state(move |state| {
state.put(blob_url_store.clone());
if let Some(location) = maybe_location.clone() {
state.put(Location(location));
}
Ok(())
})),
)
})
.build()
}
pub fn get_declaration() -> PathBuf {

View file

@ -13,6 +13,7 @@ use deno_core::futures;
use deno_core::futures::channel::oneshot;
use deno_core::futures::FutureExt;
use deno_core::futures::TryFutureExt;
use deno_core::include_js_files;
use deno_core::op_async;
use deno_core::op_sync;
use deno_core::Extension;
@ -41,24 +42,24 @@ impl TimersPermission for NoTimersPermission {
}
pub fn init<P: TimersPermission + 'static>() -> Extension {
Extension::with_ops(
vec![(
"deno:op_crates/timers/01_timers.js",
include_str!("01_timers.js"),
)],
vec![
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/timers",
"01_timers.js",
))
.ops(vec![
("op_global_timer_stop", op_sync(op_global_timer_stop)),
("op_global_timer_start", op_sync(op_global_timer_start)),
("op_global_timer", op_async(op_global_timer)),
("op_now", op_sync(op_now::<P>)),
("op_sleep_sync", op_sync(op_sleep_sync::<P>)),
],
Some(Box::new(|state| {
])
.state(|state| {
state.put(GlobalTimer::default());
state.put(StartTime::now());
Ok(())
})),
)
})
.build()
}
pub type StartTime = Instant;

View file

@ -17,12 +17,12 @@ use std::panic::catch_unwind;
use std::path::PathBuf;
pub fn init() -> Extension {
Extension::with_ops(
include_js_files!(
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/url",
"00_url.js",
),
vec![
))
.ops(vec![
("op_url_parse", op_sync(op_url_parse)),
(
"op_url_parse_search_params",
@ -32,9 +32,8 @@ pub fn init() -> Extension {
"op_url_stringify_search_params",
op_sync(op_url_stringify_search_params),
),
],
None,
)
])
.build()
}
#[derive(Deserialize)]

View file

@ -6,17 +6,19 @@ use std::path::PathBuf;
/// Load and execute the javascript code.
pub fn init() -> Extension {
Extension::pure_js(include_js_files!(
prefix "deno:op_crates/web",
"00_infra.js",
"01_dom_exception.js",
"01_mimesniff.js",
"02_event.js",
"03_abort_signal.js",
"04_global_interfaces.js",
"08_text_encoding.js",
"12_location.js",
))
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/web",
"00_infra.js",
"01_dom_exception.js",
"01_mimesniff.js",
"02_event.js",
"03_abort_signal.js",
"04_global_interfaces.js",
"08_text_encoding.js",
"12_location.js",
))
.build()
}
pub fn get_declaration() -> PathBuf {

View file

@ -95,22 +95,22 @@ impl Resource for WebGpuQuerySet {
}
pub fn init(unstable: bool) -> Extension {
Extension::with_ops(
include_js_files!(
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/webgpu",
"01_webgpu.js",
"02_idl_types.js",
),
declare_webgpu_ops(),
Some(Box::new(move |state| {
))
.ops(declare_webgpu_ops())
.state(move |state| {
// TODO: check & possibly streamline this
// Unstable might be able to be OpMiddleware
// let unstable_checker = state.borrow::<super::UnstableChecker>();
// let unstable = unstable_checker.unstable;
state.put(Unstable(unstable));
Ok(())
})),
)
})
.build()
}
pub fn get_declaration() -> PathBuf {

View file

@ -1,11 +1,14 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
use deno_core::include_js_files;
use deno_core::Extension;
/// Load and execute the javascript code.
pub fn init() -> Extension {
Extension::pure_js(vec![(
"deno:op_crates/webidl/00_webidl.js",
include_str!("00_webidl.js"),
)])
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/webidl",
"00_webidl.js",
))
.build()
}

View file

@ -340,12 +340,12 @@ pub fn init<P: WebSocketPermissions + 'static>(
user_agent: String,
ca_data: Option<Vec<u8>>,
) -> Extension {
Extension::with_ops(
include_js_files!(
Extension::builder()
.js(include_js_files!(
prefix "deno:op_crates/websocket",
"01_websocket.js",
),
vec![
))
.ops(vec![
(
"op_ws_check_permission",
op_sync(op_ws_check_permission::<P>),
@ -354,15 +354,15 @@ pub fn init<P: WebSocketPermissions + 'static>(
("op_ws_send", op_async(op_ws_send)),
("op_ws_close", op_async(op_ws_close)),
("op_ws_next_event", op_async(op_ws_next_event)),
],
Some(Box::new(move |state| {
])
.state(move |state| {
state.put::<WsUserAgent>(WsUserAgent(user_agent.clone()));
if let Some(ca_data) = ca_data.clone() {
state.put::<WsCaData>(WsCaData(ca_data));
}
Ok(())
})),
)
})
.build()
}
pub fn get_declaration() -> PathBuf {

View file

@ -10,15 +10,14 @@ use deno_core::OpState;
use deno_core::ZeroCopyBuf;
pub fn init() -> Extension {
Extension::new(
None,
Some(vec![("op_metrics", op_sync(op_metrics))]),
Some(Box::new(|state| {
Extension::builder()
.ops(vec![("op_metrics", op_sync(op_metrics))])
.state(|state| {
state.put(RuntimeMetrics::default());
Ok(())
})),
Some(Box::new(metrics_op)),
)
})
.middleware(metrics_op)
.build()
}
#[derive(serde::Serialize)]