use std::cell::RefCell;
use std::thread;
use deno_core::v8;
use deno_core::ModuleSpecifier;
use deno_telemetry::OtelConfig;
use deno_terminal::colors;
use serde::Serialize;
#[derive(Copy, Clone)]
pub enum WorkerExecutionMode {
None,
Worker,
Run,
Repl,
Eval,
Test,
Bench,
ServeMain {
worker_count: usize,
},
ServeWorker {
worker_index: usize,
},
Jupyter,
}
impl WorkerExecutionMode {
pub fn discriminant(&self) -> u8 {
match self {
WorkerExecutionMode::None => 0,
WorkerExecutionMode::Worker => 1,
WorkerExecutionMode::Run => 2,
WorkerExecutionMode::Repl => 3,
WorkerExecutionMode::Eval => 4,
WorkerExecutionMode::Test => 5,
WorkerExecutionMode::Bench => 6,
WorkerExecutionMode::ServeMain { .. }
| WorkerExecutionMode::ServeWorker { .. } => 7,
WorkerExecutionMode::Jupyter => 8,
}
}
}
#[derive(Debug, Default, Clone, Copy)]
pub enum WorkerLogLevel {
Error = 1,
Warn = 2,
#[default]
Info = 3,
Debug = 4,
}
impl From<log::Level> for WorkerLogLevel {
fn from(value: log::Level) -> Self {
match value {
log::Level::Error => WorkerLogLevel::Error,
log::Level::Warn => WorkerLogLevel::Warn,
log::Level::Info => WorkerLogLevel::Info,
log::Level::Debug => WorkerLogLevel::Debug,
log::Level::Trace => WorkerLogLevel::Debug,
}
}
}
#[derive(Clone)]
pub struct BootstrapOptions {
pub deno_version: String,
pub args: Vec<String>,
pub cpu_count: usize,
pub log_level: WorkerLogLevel,
pub enable_op_summary_metrics: bool,
pub enable_testing_features: bool,
pub locale: String,
pub location: Option<ModuleSpecifier>,
pub color_level: deno_terminal::colors::ColorLevel,
pub unstable_features: Vec<i32>,
pub user_agent: String,
pub inspect: bool,
pub is_standalone: bool,
pub has_node_modules_dir: bool,
pub argv0: Option<String>,
pub node_debug: Option<String>,
pub node_ipc_fd: Option<i64>,
pub mode: WorkerExecutionMode,
pub no_legacy_abort: bool,
pub serve_port: Option<u16>,
pub serve_host: Option<String>,
pub auto_serve: bool,
pub otel_config: OtelConfig,
pub close_on_idle: bool,
}
impl Default for BootstrapOptions {
fn default() -> Self {
let cpu_count = thread::available_parallelism()
.map(|p| p.get())
.unwrap_or(1);
let runtime_version = env!("CARGO_PKG_VERSION");
let user_agent = format!("Deno/{runtime_version}");
Self {
deno_version: runtime_version.to_string(),
user_agent,
cpu_count,
color_level: colors::get_color_level(),
enable_op_summary_metrics: false,
enable_testing_features: false,
log_level: Default::default(),
locale: "en".to_string(),
location: Default::default(),
unstable_features: Default::default(),
inspect: false,
args: Default::default(),
is_standalone: false,
auto_serve: false,
has_node_modules_dir: false,
argv0: None,
node_debug: None,
node_ipc_fd: None,
mode: WorkerExecutionMode::None,
no_legacy_abort: false,
serve_port: Default::default(),
serve_host: Default::default(),
otel_config: Default::default(),
close_on_idle: false,
}
}
}
#[derive(Serialize)]
struct BootstrapV8<'a>(
&'a str,
Option<&'a str>,
&'a [i32],
bool,
bool,
bool,
Option<&'a str>,
Option<&'a str>,
i32,
u16,
Option<&'a str>,
bool,
Option<usize>,
Box<[u8]>,
bool,
bool,
bool,
);
impl BootstrapOptions {
pub fn as_v8<'s>(
&self,
scope: &mut v8::HandleScope<'s>,
) -> v8::Local<'s, v8::Value> {
let scope = RefCell::new(scope);
let ser = deno_core::serde_v8::Serializer::new(&scope);
let bootstrap = BootstrapV8(
&self.deno_version,
self.location.as_ref().map(|l| l.as_str()),
self.unstable_features.as_ref(),
self.inspect,
self.enable_testing_features,
self.has_node_modules_dir,
self.argv0.as_deref(),
self.node_debug.as_deref(),
self.mode.discriminant() as _,
self.serve_port.unwrap_or_default(),
self.serve_host.as_deref(),
matches!(self.mode, WorkerExecutionMode::ServeMain { .. }),
match self.mode {
WorkerExecutionMode::ServeMain { worker_count } => Some(worker_count),
WorkerExecutionMode::ServeWorker { worker_index } => Some(worker_index),
_ => None,
},
self.otel_config.as_v8(),
self.close_on_idle,
self.is_standalone,
self.auto_serve,
);
bootstrap.serialize(ser).unwrap()
}
}