core: introduce extensions (#9800)

Extensions allow declarative extensions to "JsRuntime" (ops, state, JS or middleware).

This allows for:
- `op_crates` to be plug-and-play & self-contained, reducing complexity leaked to consumers
- op middleware (like metrics_op) to be opt-in and for new middleware (unstable, tracing,...)
- `MainWorker` and `WebWorker` to be composable, allowing users to extend workers with their ops whilst benefiting from the other infrastructure (inspector, etc...)

In short extensions improve deno's modularity, reducing complexity and leaky abstractions for embedders and the internal codebase.
This commit is contained in:
Aaron O'Mullan 2021-04-28 18:41:50 +02:00 committed by GitHub
parent b28f9445aa
commit 0260b488fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 857 additions and 835 deletions

View file

@ -4,7 +4,7 @@ use crate::inspector::DenoInspector;
use crate::inspector::InspectorServer;
use crate::inspector::InspectorSession;
use crate::js;
use crate::metrics::RuntimeMetrics;
use crate::metrics;
use crate::ops;
use crate::permissions::Permissions;
use deno_core::error::AnyError;
@ -15,6 +15,7 @@ use deno_core::futures::stream::StreamExt;
use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::url::Url;
use deno_core::Extension;
use deno_core::GetErrorClassFn;
use deno_core::JsErrorCreateFn;
use deno_core::JsRuntime;
@ -77,11 +78,35 @@ impl MainWorker {
permissions: Permissions,
options: &WorkerOptions,
) -> Self {
// Internal modules
let extensions: Vec<Extension> = vec![
// Web APIs
deno_webidl::init(),
deno_console::init(),
deno_url::init(),
deno_web::init(),
deno_file::init(options.blob_url_store.clone(), options.location.clone()),
deno_fetch::init::<Permissions>(
options.user_agent.clone(),
options.ca_data.clone(),
),
deno_websocket::init::<Permissions>(
options.user_agent.clone(),
options.ca_data.clone(),
),
deno_crypto::init(options.seed),
deno_webgpu::init(options.unstable),
deno_timers::init::<Permissions>(),
// Metrics
metrics::init(),
];
let mut js_runtime = JsRuntime::new(RuntimeOptions {
module_loader: Some(options.module_loader.clone()),
startup_snapshot: Some(js::deno_isolate_init()),
js_error_create_fn: options.js_error_create_fn.clone(),
get_error_class_fn: options.get_error_class_fn,
extensions,
..Default::default()
});
@ -109,34 +134,22 @@ impl MainWorker {
{
let op_state = js_runtime.op_state();
let mut op_state = op_state.borrow_mut();
op_state.put(RuntimeMetrics::default());
op_state.put::<Permissions>(permissions);
op_state.put(ops::UnstableChecker {
unstable: options.unstable,
});
}
js_runtime.init_extension_ops().unwrap();
ops::runtime::init(js_runtime, main_module);
ops::fetch::init(
js_runtime,
options.user_agent.clone(),
options.ca_data.clone(),
);
ops::timers::init(js_runtime);
ops::worker_host::init(
js_runtime,
None,
options.create_web_worker_cb.clone(),
);
ops::crypto::init(js_runtime, options.seed);
ops::reg_sync(js_runtime, "op_close", deno_core::op_close);
ops::reg_sync(js_runtime, "op_resources", deno_core::op_resources);
ops::url::init(js_runtime);
ops::file::init(
js_runtime,
options.blob_url_store.clone(),
options.location.clone(),
);
ops::fs_events::init(js_runtime);
ops::fs::init(js_runtime);
ops::http::init(js_runtime);
@ -149,12 +162,6 @@ impl MainWorker {
ops::signal::init(js_runtime);
ops::tls::init(js_runtime);
ops::tty::init(js_runtime);
ops::webgpu::init(js_runtime);
ops::websocket::init(
js_runtime,
options.user_agent.clone(),
options.ca_data.clone(),
);
}
{
let op_state = js_runtime.op_state();