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:
parent
e63c533154
commit
e89295b176
12 changed files with 141 additions and 112 deletions
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)]
|
||||
|
|
Loading…
Reference in a new issue