feat(core) deno_core::extension! macro to simplify extension registration (#18210)

This implements two macros to simplify extension registration and centralize a lot of the boilerplate as a base for future improvements:

* `deno_core::ops!` registers a block of `#[op]`s, optionally with type
parameters, useful for places where we share lists of ops
* `deno_core::extension!` is used to register an extension, and creates
two methods that can be used at runtime/snapshot generation time:
`init_ops` and `init_ops_and_esm`.

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit is contained in:
Matt Mastracci 2023-03-17 12:22:15 -06:00 committed by GitHub
parent 0bc6bf5d33
commit e55b448730
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 1690 additions and 1851 deletions

View file

@ -10,10 +10,8 @@ use deno_core::futures::stream::Peekable;
use deno_core::futures::Future;
use deno_core::futures::Stream;
use deno_core::futures::StreamExt;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::BufView;
use deno_core::ExtensionBuilder;
use deno_core::WriteOutcome;
use deno_core::url::Url;
@ -24,7 +22,6 @@ use deno_core::CancelFuture;
use deno_core::CancelHandle;
use deno_core::CancelTryFuture;
use deno_core::Canceled;
use deno_core::Extension;
use deno_core::OpState;
use deno_core::RcRef;
use deno_core::Resource;
@ -93,65 +90,41 @@ impl Default for Options {
}
}
fn ext() -> ExtensionBuilder {
Extension::builder_with_deps(
env!("CARGO_PKG_NAME"),
&["deno_webidl", "deno_web", "deno_url", "deno_console"],
)
}
fn ops<FP>(
ext: &mut ExtensionBuilder,
options: Options,
) -> &mut ExtensionBuilder
where
FP: FetchPermissions + 'static,
{
ext
.ops(vec![
op_fetch::decl::<FP>(),
op_fetch_send::decl(),
op_fetch_custom_client::decl::<FP>(),
])
.state(move |state| {
state.put::<Options>(options.clone());
state.put::<reqwest::Client>({
create_http_client(
options.user_agent.clone(),
options.root_cert_store.clone(),
vec![],
options.proxy.clone(),
options.unsafely_ignore_certificate_errors.clone(),
options.client_cert_chain_and_key.clone(),
)
.unwrap()
});
})
}
pub fn init_ops_and_esm<FP>(options: Options) -> Extension
where
FP: FetchPermissions + 'static,
{
ops::<FP>(&mut ext(), options)
.esm(include_js_files!(
"20_headers.js",
"21_formdata.js",
"22_body.js",
"22_http_client.js",
"23_request.js",
"23_response.js",
"26_fetch.js",
))
.build()
}
pub fn init_ops<FP>(options: Options) -> Extension
where
FP: FetchPermissions + 'static,
{
ops::<FP>(&mut ext(), options).build()
}
deno_core::extension!(deno_fetch,
deps = [ deno_webidl, deno_web, deno_url, deno_console ],
parameters = [FP: FetchPermissions],
ops = [
op_fetch<FP>,
op_fetch_send,
op_fetch_custom_client<FP>,
],
esm = [
"20_headers.js",
"21_formdata.js",
"22_body.js",
"22_http_client.js",
"23_request.js",
"23_response.js",
"26_fetch.js"
],
config = {
options: Options,
},
state = |state, options| {
state.put::<Options>(options.clone());
state.put::<reqwest::Client>({
create_http_client(
options.user_agent,
options.root_cert_store,
vec![],
options.proxy,
options.unsafely_ignore_certificate_errors,
options.client_cert_chain_and_key
)
.unwrap()
});
},
);
pub type CancelableResponseFuture =
Pin<Box<dyn Future<Output = CancelableResponseResult>>>;