mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
refactor: remove more compiler runtime code (#6841)
This commit is contained in:
parent
e18e46a3b3
commit
b449964d1a
23 changed files with 227 additions and 4316 deletions
|
@ -38,7 +38,7 @@ fn compiler_snapshot() {
|
|||
deno_core::js_check(isolate.execute(
|
||||
"<anon>",
|
||||
r#"
|
||||
if (!(bootstrap.tsCompilerRuntime)) {
|
||||
if (!(bootstrapCompilerRuntime)) {
|
||||
throw Error("bad");
|
||||
}
|
||||
console.log(`ts version: ${ts.version}`);
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
use super::dispatch_json::{JsonOp, Value};
|
||||
use crate::op_error::OpError;
|
||||
use crate::ops::json_op;
|
||||
use crate::ops::JsonOpDispatcher;
|
||||
use crate::state::State;
|
||||
use deno_core::CoreIsolate;
|
||||
use deno_core::CoreIsolateState;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub fn init(i: &mut CoreIsolate, _s: &State) {
|
||||
pub fn init(
|
||||
i: &mut CoreIsolate,
|
||||
_s: &State,
|
||||
response: Arc<Mutex<Option<String>>>,
|
||||
) {
|
||||
let custom_assets = std::collections::HashMap::new();
|
||||
// TODO(ry) use None.
|
||||
// TODO(bartlomieju): is this op even required?
|
||||
|
@ -10,4 +22,42 @@ pub fn init(i: &mut CoreIsolate, _s: &State) {
|
|||
"op_fetch_asset",
|
||||
crate::op_fetch_asset::op_fetch_asset(custom_assets),
|
||||
);
|
||||
|
||||
i.register_op(
|
||||
"op_compiler_respond",
|
||||
json_op(compiler_op(response, op_compiler_respond)),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn compiler_op<D>(
|
||||
response: Arc<Mutex<Option<String>>>,
|
||||
dispatcher: D,
|
||||
) -> impl JsonOpDispatcher
|
||||
where
|
||||
D: Fn(
|
||||
Arc<Mutex<Option<String>>>,
|
||||
Value,
|
||||
&mut [ZeroCopyBuf],
|
||||
) -> Result<JsonOp, OpError>,
|
||||
{
|
||||
move |_isolate_state: &mut CoreIsolateState,
|
||||
args: Value,
|
||||
zero_copy: &mut [ZeroCopyBuf]|
|
||||
-> Result<JsonOp, OpError> {
|
||||
dispatcher(response.clone(), args, zero_copy)
|
||||
}
|
||||
}
|
||||
|
||||
fn op_compiler_respond(
|
||||
response: Arc<Mutex<Option<String>>>,
|
||||
args: Value,
|
||||
_zero_copy: &mut [ZeroCopyBuf],
|
||||
) -> Result<JsonOp, OpError> {
|
||||
let mut r = response.lock().unwrap();
|
||||
assert!(
|
||||
r.is_none(),
|
||||
"op_compiler_respond found unexpected existing compiler output"
|
||||
);
|
||||
*r = Some(args.to_string());
|
||||
Ok(JsonOp::Sync(json!({})))
|
||||
}
|
||||
|
|
|
@ -689,7 +689,7 @@ fn ts_reload() {
|
|||
assert!(std::str::from_utf8(&output.stdout)
|
||||
.unwrap()
|
||||
.trim()
|
||||
.contains("compiler::host.writeFile deno://002_hello.js"));
|
||||
.contains("\"compiler::host.writeFile\" \"deno://002_hello.js\""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[WILDCARD]
|
||||
DEBUG TS - compiler::host.getSourceFile http://127.0.0.1:4545/xTypeScriptTypes.d.ts
|
||||
DEBUG TS - "compiler::host.getSourceFile" "http://127.0.0.1:4545/xTypeScriptTypes.d.ts"
|
||||
[WILDCARD]
|
|
@ -1,3 +1,3 @@
|
|||
[WILDCARD]
|
||||
DEBUG TS - compiler::host.getSourceFile file:[WILDCARD]cli/tests/subdir/type_reference.d.ts
|
||||
DEBUG TS - "compiler::host.getSourceFile" "file:[WILDCARD]cli/tests/subdir/type_reference.d.ts"
|
||||
[WILDCARD]
|
132
cli/tsc.rs
132
cli/tsc.rs
|
@ -28,14 +28,11 @@ use crate::swc_ecma_visit::Visit;
|
|||
use crate::swc_util::AstParser;
|
||||
use crate::swc_util::SwcDiagnosticBuffer;
|
||||
use crate::version;
|
||||
use crate::web_worker::WebWorker;
|
||||
use crate::worker::WorkerEvent;
|
||||
use crate::worker::Worker;
|
||||
use core::task::Context;
|
||||
use deno_core::Buf;
|
||||
use deno_core::ErrBox;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::StartupData;
|
||||
use futures::future::Either;
|
||||
use futures::future::Future;
|
||||
use futures::future::FutureExt;
|
||||
use log::debug;
|
||||
|
@ -130,30 +127,47 @@ pub struct CompiledModule {
|
|||
pub name: String,
|
||||
}
|
||||
|
||||
pub struct CompilerWorker(WebWorker);
|
||||
pub struct CompilerWorker {
|
||||
worker: Worker,
|
||||
response: Arc<Mutex<Option<String>>>,
|
||||
}
|
||||
|
||||
impl CompilerWorker {
|
||||
pub fn new(name: String, startup_data: StartupData, state: State) -> Self {
|
||||
let state_ = state.clone();
|
||||
let mut worker = WebWorker::new(name, startup_data, state_, false);
|
||||
let mut worker = Worker::new(name, startup_data, state_);
|
||||
let response = Arc::new(Mutex::new(None));
|
||||
{
|
||||
let isolate = &mut worker.isolate;
|
||||
ops::compiler::init(isolate, &state);
|
||||
ops::runtime::init(isolate, &state);
|
||||
ops::errors::init(isolate, &state);
|
||||
ops::timers::init(isolate, &state);
|
||||
ops::compiler::init(isolate, &state, response.clone());
|
||||
}
|
||||
Self(worker)
|
||||
|
||||
Self { worker, response }
|
||||
}
|
||||
|
||||
pub fn get_response(&mut self) -> String {
|
||||
let mut maybe_response = self.response.lock().unwrap();
|
||||
assert!(
|
||||
maybe_response.is_some(),
|
||||
"Unexpected missing response from TS compiler"
|
||||
);
|
||||
maybe_response.take().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for CompilerWorker {
|
||||
type Target = WebWorker;
|
||||
type Target = Worker;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
&self.worker
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for CompilerWorker {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
&mut self.worker
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,7 +176,7 @@ impl Future for CompilerWorker {
|
|||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
let inner = self.get_mut();
|
||||
inner.0.poll_unpin(cx)
|
||||
inner.worker.poll_unpin(cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,7 +226,9 @@ fn create_compiler_worker(
|
|||
startup_data::compiler_isolate_init(),
|
||||
worker_state,
|
||||
);
|
||||
worker.execute("bootstrap.tsCompilerRuntime()").unwrap();
|
||||
worker
|
||||
.execute("globalThis.bootstrapCompilerRuntime()")
|
||||
.unwrap();
|
||||
worker
|
||||
}
|
||||
|
||||
|
@ -604,17 +620,15 @@ impl TsCompiler {
|
|||
}),
|
||||
};
|
||||
|
||||
let req_msg = j.to_string().into_boxed_str().into_boxed_bytes();
|
||||
let req_msg = j.to_string();
|
||||
|
||||
// TODO(bartlomieju): lift this call up - TSC shouldn't print anything
|
||||
info!("{} {}", colors::green("Check"), module_url.to_string());
|
||||
|
||||
let msg =
|
||||
let json_str =
|
||||
execute_in_same_thread(global_state, permissions, req_msg).await?;
|
||||
|
||||
let json_str = std::str::from_utf8(&msg).unwrap();
|
||||
|
||||
let compile_response: CompileResponse = serde_json::from_str(json_str)?;
|
||||
let compile_response: CompileResponse = serde_json::from_str(&json_str)?;
|
||||
|
||||
if !compile_response.diagnostics.items.is_empty() {
|
||||
return Err(ErrBox::from(compile_response.diagnostics));
|
||||
|
@ -713,13 +727,12 @@ impl TsCompiler {
|
|||
}),
|
||||
};
|
||||
|
||||
let req_msg = j.to_string().into_boxed_str().into_boxed_bytes();
|
||||
let req_msg = j.to_string();
|
||||
|
||||
let msg =
|
||||
let json_str =
|
||||
execute_in_same_thread(global_state, permissions, req_msg).await?;
|
||||
let json_str = std::str::from_utf8(&msg).unwrap();
|
||||
|
||||
let bundle_response: BundleResponse = serde_json::from_str(json_str)?;
|
||||
let bundle_response: BundleResponse = serde_json::from_str(&json_str)?;
|
||||
|
||||
maybe_log_stats(bundle_response.stats);
|
||||
|
||||
|
@ -778,15 +791,14 @@ impl TsCompiler {
|
|||
}),
|
||||
};
|
||||
|
||||
let req_msg = j.to_string().into_boxed_str().into_boxed_bytes();
|
||||
let req_msg = j.to_string();
|
||||
|
||||
let msg =
|
||||
let json_str =
|
||||
execute_in_same_thread(global_state.clone(), permissions, req_msg)
|
||||
.await?;
|
||||
|
||||
let json_str = std::str::from_utf8(&msg).unwrap();
|
||||
|
||||
let transpile_response: TranspileResponse = serde_json::from_str(json_str)?;
|
||||
let transpile_response: TranspileResponse =
|
||||
serde_json::from_str(&json_str)?;
|
||||
|
||||
if !transpile_response.diagnostics.items.is_empty() {
|
||||
return Err(ErrBox::from(transpile_response.diagnostics));
|
||||
|
@ -1079,35 +1091,13 @@ impl TsCompiler {
|
|||
async fn execute_in_same_thread(
|
||||
global_state: GlobalState,
|
||||
permissions: Permissions,
|
||||
req: Buf,
|
||||
) -> Result<Buf, ErrBox> {
|
||||
req: String,
|
||||
) -> Result<String, ErrBox> {
|
||||
let mut worker = create_compiler_worker(global_state.clone(), permissions);
|
||||
let handle = worker.thread_safe_handle();
|
||||
handle.post_message(req)?;
|
||||
|
||||
let mut event_fut = handle.get_event().boxed_local();
|
||||
|
||||
loop {
|
||||
let select_result = futures::future::select(event_fut, &mut worker).await;
|
||||
match select_result {
|
||||
Either::Left((event_result, _worker)) => {
|
||||
let event = event_result
|
||||
.expect("Compiler didn't respond")
|
||||
.expect("Empty message");
|
||||
|
||||
let buf = match event {
|
||||
WorkerEvent::Message(buf) => Ok(buf),
|
||||
WorkerEvent::Error(error) => Err(error),
|
||||
WorkerEvent::TerminalError(error) => Err(error),
|
||||
}?;
|
||||
return Ok(buf);
|
||||
}
|
||||
Either::Right((worker_result, event_fut_)) => {
|
||||
event_fut = event_fut_;
|
||||
worker_result?;
|
||||
}
|
||||
}
|
||||
}
|
||||
let script = format!("globalThis.tsCompilerOnMessage({{ data: {} }});", req);
|
||||
worker.execute2("<compiler>", &script)?;
|
||||
(&mut *worker).await?;
|
||||
Ok(worker.get_response())
|
||||
}
|
||||
|
||||
async fn create_runtime_module_graph(
|
||||
|
@ -1200,18 +1190,15 @@ pub async fn runtime_compile(
|
|||
"options": maybe_options,
|
||||
"unstable": global_state.flags.unstable,
|
||||
})
|
||||
.to_string()
|
||||
.into_boxed_str()
|
||||
.into_boxed_bytes();
|
||||
.to_string();
|
||||
|
||||
let compiler = global_state.ts_compiler.clone();
|
||||
|
||||
let msg = execute_in_same_thread(global_state, permissions, req_msg)
|
||||
let json_str = execute_in_same_thread(global_state, permissions, req_msg)
|
||||
.await
|
||||
.map_err(js_error_to_op_error)?;
|
||||
let json_str = std::str::from_utf8(&msg).unwrap();
|
||||
|
||||
let response: RuntimeCompileResponse = serde_json::from_str(json_str)?;
|
||||
let response: RuntimeCompileResponse = serde_json::from_str(&json_str)?;
|
||||
|
||||
if response.diagnostics.is_empty() && sources.is_none() {
|
||||
compiler.cache_emitted_files(response.emit_map)?;
|
||||
|
@ -1220,7 +1207,7 @@ pub async fn runtime_compile(
|
|||
// We're returning `Ok()` instead of `Err()` because it's not runtime
|
||||
// error if there were diagnostics produced; we want to let user handle
|
||||
// diagnostics in the runtime.
|
||||
Ok(serde_json::from_str::<Value>(json_str).unwrap())
|
||||
Ok(serde_json::from_str::<Value>(&json_str).unwrap())
|
||||
}
|
||||
|
||||
/// This function is used by `Deno.bundle()` API.
|
||||
|
@ -1250,19 +1237,16 @@ pub async fn runtime_bundle(
|
|||
"options": maybe_options,
|
||||
"unstable": global_state.flags.unstable,
|
||||
})
|
||||
.to_string()
|
||||
.into_boxed_str()
|
||||
.into_boxed_bytes();
|
||||
.to_string();
|
||||
|
||||
let msg = execute_in_same_thread(global_state, permissions, req_msg)
|
||||
let json_str = execute_in_same_thread(global_state, permissions, req_msg)
|
||||
.await
|
||||
.map_err(js_error_to_op_error)?;
|
||||
let json_str = std::str::from_utf8(&msg).unwrap();
|
||||
let _response: RuntimeBundleResponse = serde_json::from_str(json_str)?;
|
||||
let _response: RuntimeBundleResponse = serde_json::from_str(&json_str)?;
|
||||
// We're returning `Ok()` instead of `Err()` because it's not runtime
|
||||
// error if there were diagnostics produced; we want to let user handle
|
||||
// diagnostics in the runtime.
|
||||
Ok(serde_json::from_str::<Value>(json_str).unwrap())
|
||||
Ok(serde_json::from_str::<Value>(&json_str).unwrap())
|
||||
}
|
||||
|
||||
/// This function is used by `Deno.transpileOnly()` API.
|
||||
|
@ -1277,15 +1261,12 @@ pub async fn runtime_transpile(
|
|||
"sources": sources,
|
||||
"options": options,
|
||||
})
|
||||
.to_string()
|
||||
.into_boxed_str()
|
||||
.into_boxed_bytes();
|
||||
.to_string();
|
||||
|
||||
let msg = execute_in_same_thread(global_state, permissions, req_msg)
|
||||
let json_str = execute_in_same_thread(global_state, permissions, req_msg)
|
||||
.await
|
||||
.map_err(js_error_to_op_error)?;
|
||||
let json_str = std::str::from_utf8(&msg).unwrap();
|
||||
let v = serde_json::from_str::<serde_json::Value>(json_str)
|
||||
let v = serde_json::from_str::<serde_json::Value>(&json_str)
|
||||
.expect("Error decoding JSON string.");
|
||||
Ok(v)
|
||||
}
|
||||
|
@ -1775,6 +1756,7 @@ mod tests {
|
|||
.ts_compiler
|
||||
.bundle(mock_state.clone(), module_name)
|
||||
.await;
|
||||
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
const build = {
|
||||
target: "unknown",
|
||||
arch: "unknown",
|
||||
os: "unknown",
|
||||
vendor: "unknown",
|
||||
env: undefined,
|
||||
};
|
||||
|
||||
function setBuildInfo(target) {
|
||||
const [arch, vendor, os, env] = target.split("-", 4);
|
||||
build.target = target;
|
||||
build.arch = arch;
|
||||
build.vendor = vendor;
|
||||
build.os = os;
|
||||
build.env = env;
|
||||
Object.freeze(build);
|
||||
}
|
||||
|
||||
window.__bootstrap.build = {
|
||||
build,
|
||||
setBuildInfo,
|
||||
};
|
||||
})(this);
|
|
@ -1,89 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
function code(open, close) {
|
||||
return {
|
||||
open: `\x1b[${open}m`,
|
||||
close: `\x1b[${close}m`,
|
||||
regexp: new RegExp(`\\x1b\\[${close}m`, "g"),
|
||||
};
|
||||
}
|
||||
|
||||
function run(str, code) {
|
||||
return !globalThis || !globalThis.Deno || globalThis.Deno.noColor
|
||||
? str
|
||||
: `${code.open}${str.replace(code.regexp, code.open)}${code.close}`;
|
||||
}
|
||||
|
||||
function bold(str) {
|
||||
return run(str, code(1, 22));
|
||||
}
|
||||
|
||||
function italic(str) {
|
||||
return run(str, code(3, 23));
|
||||
}
|
||||
|
||||
function yellow(str) {
|
||||
return run(str, code(33, 39));
|
||||
}
|
||||
|
||||
function cyan(str) {
|
||||
return run(str, code(36, 39));
|
||||
}
|
||||
|
||||
function red(str) {
|
||||
return run(str, code(31, 39));
|
||||
}
|
||||
|
||||
function green(str) {
|
||||
return run(str, code(32, 39));
|
||||
}
|
||||
|
||||
function bgRed(str) {
|
||||
return run(str, code(41, 49));
|
||||
}
|
||||
|
||||
function white(str) {
|
||||
return run(str, code(37, 39));
|
||||
}
|
||||
|
||||
function gray(str) {
|
||||
return run(str, code(90, 39));
|
||||
}
|
||||
|
||||
function magenta(str) {
|
||||
return run(str, code(35, 39));
|
||||
}
|
||||
|
||||
function dim(str) {
|
||||
return run(str, code(2, 22));
|
||||
}
|
||||
|
||||
// https://github.com/chalk/ansi-regex/blob/2b56fb0c7a07108e5b54241e8faec160d393aedb/index.js
|
||||
const ANSI_PATTERN = new RegExp(
|
||||
[
|
||||
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
|
||||
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))",
|
||||
].join("|"),
|
||||
"g",
|
||||
);
|
||||
|
||||
function stripColor(string) {
|
||||
return string.replace(ANSI_PATTERN, "");
|
||||
}
|
||||
|
||||
window.__bootstrap.colors = {
|
||||
bold,
|
||||
italic,
|
||||
yellow,
|
||||
cyan,
|
||||
red,
|
||||
green,
|
||||
bgRed,
|
||||
white,
|
||||
gray,
|
||||
magenta,
|
||||
dim,
|
||||
stripColor,
|
||||
};
|
||||
})(this);
|
1044
cli/tsc/01_event.js
1044
cli/tsc/01_event.js
File diff suppressed because it is too large
Load diff
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
const internalSymbol = Symbol("Deno.internal");
|
||||
|
||||
// The object where all the internal fields for testing will be living.
|
||||
const internalObject = {};
|
||||
|
||||
// Register a field to internalObject for test access,
|
||||
// through Deno[Deno.internal][name].
|
||||
function exposeForTest(name, value) {
|
||||
Object.defineProperty(internalObject, name, {
|
||||
value,
|
||||
enumerable: false,
|
||||
});
|
||||
}
|
||||
|
||||
window.__bootstrap.internals = {
|
||||
internalSymbol,
|
||||
internalObject,
|
||||
exposeForTest,
|
||||
};
|
||||
})(this);
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
const version = {
|
||||
deno: "",
|
||||
v8: "",
|
||||
typescript: "",
|
||||
};
|
||||
|
||||
function setVersions(
|
||||
denoVersion,
|
||||
v8Version,
|
||||
tsVersion,
|
||||
) {
|
||||
version.deno = denoVersion;
|
||||
version.v8 = v8Version;
|
||||
version.typescript = tsVersion;
|
||||
|
||||
Object.freeze(version);
|
||||
}
|
||||
|
||||
window.__bootstrap.version = {
|
||||
version,
|
||||
setVersions,
|
||||
};
|
||||
})(this);
|
|
@ -1,202 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
function isTypedArray(x) {
|
||||
return ArrayBuffer.isView(x) && !(x instanceof DataView);
|
||||
}
|
||||
|
||||
function isInvalidDate(x) {
|
||||
return isNaN(x.getTime());
|
||||
}
|
||||
|
||||
function requiredArguments(
|
||||
name,
|
||||
length,
|
||||
required,
|
||||
) {
|
||||
if (length < required) {
|
||||
const errMsg = `${name} requires at least ${required} argument${
|
||||
required === 1 ? "" : "s"
|
||||
}, but only ${length} present`;
|
||||
throw new TypeError(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
function immutableDefine(
|
||||
o,
|
||||
p,
|
||||
value,
|
||||
) {
|
||||
Object.defineProperty(o, p, {
|
||||
value,
|
||||
configurable: false,
|
||||
writable: false,
|
||||
});
|
||||
}
|
||||
|
||||
function hasOwnProperty(obj, v) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
return Object.prototype.hasOwnProperty.call(obj, v);
|
||||
}
|
||||
|
||||
/** Returns whether o is iterable. */
|
||||
function isIterable(
|
||||
o,
|
||||
) {
|
||||
// checks for null and undefined
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
typeof (o)[Symbol.iterator] === "function"
|
||||
);
|
||||
}
|
||||
|
||||
const objectCloneMemo = new WeakMap();
|
||||
|
||||
function cloneArrayBuffer(
|
||||
srcBuffer,
|
||||
srcByteOffset,
|
||||
srcLength,
|
||||
_cloneConstructor,
|
||||
) {
|
||||
// this function fudges the return type but SharedArrayBuffer is disabled for a while anyway
|
||||
return srcBuffer.slice(
|
||||
srcByteOffset,
|
||||
srcByteOffset + srcLength,
|
||||
);
|
||||
}
|
||||
|
||||
/** Clone a value in a similar way to structured cloning. It is similar to a
|
||||
* StructureDeserialize(StructuredSerialize(...)). */
|
||||
function cloneValue(value) {
|
||||
switch (typeof value) {
|
||||
case "number":
|
||||
case "string":
|
||||
case "boolean":
|
||||
case "undefined":
|
||||
case "bigint":
|
||||
return value;
|
||||
case "object": {
|
||||
if (objectCloneMemo.has(value)) {
|
||||
return objectCloneMemo.get(value);
|
||||
}
|
||||
if (value === null) {
|
||||
return value;
|
||||
}
|
||||
if (value instanceof Date) {
|
||||
return new Date(value.valueOf());
|
||||
}
|
||||
if (value instanceof RegExp) {
|
||||
return new RegExp(value);
|
||||
}
|
||||
if (value instanceof SharedArrayBuffer) {
|
||||
return value;
|
||||
}
|
||||
if (value instanceof ArrayBuffer) {
|
||||
const cloned = cloneArrayBuffer(
|
||||
value,
|
||||
0,
|
||||
value.byteLength,
|
||||
ArrayBuffer,
|
||||
);
|
||||
objectCloneMemo.set(value, cloned);
|
||||
return cloned;
|
||||
}
|
||||
if (ArrayBuffer.isView(value)) {
|
||||
const clonedBuffer = cloneValue(value.buffer);
|
||||
// Use DataViewConstructor type purely for type-checking, can be a
|
||||
// DataView or TypedArray. They use the same constructor signature,
|
||||
// only DataView has a length in bytes and TypedArrays use a length in
|
||||
// terms of elements, so we adjust for that.
|
||||
let length;
|
||||
if (value instanceof DataView) {
|
||||
length = value.byteLength;
|
||||
} else {
|
||||
length = value.length;
|
||||
}
|
||||
return new (value.constructor)(
|
||||
clonedBuffer,
|
||||
value.byteOffset,
|
||||
length,
|
||||
);
|
||||
}
|
||||
if (value instanceof Map) {
|
||||
const clonedMap = new Map();
|
||||
objectCloneMemo.set(value, clonedMap);
|
||||
value.forEach((v, k) => clonedMap.set(k, cloneValue(v)));
|
||||
return clonedMap;
|
||||
}
|
||||
if (value instanceof Set) {
|
||||
const clonedSet = new Map();
|
||||
objectCloneMemo.set(value, clonedSet);
|
||||
value.forEach((v, k) => clonedSet.set(k, cloneValue(v)));
|
||||
return clonedSet;
|
||||
}
|
||||
|
||||
const clonedObj = {};
|
||||
objectCloneMemo.set(value, clonedObj);
|
||||
const sourceKeys = Object.getOwnPropertyNames(value);
|
||||
for (const key of sourceKeys) {
|
||||
clonedObj[key] = cloneValue(value[key]);
|
||||
}
|
||||
return clonedObj;
|
||||
}
|
||||
case "symbol":
|
||||
case "function":
|
||||
default:
|
||||
throw new DOMException("Uncloneable value in stream", "DataCloneError");
|
||||
}
|
||||
}
|
||||
|
||||
/** A helper function which ensures accessors are enumerable, as they normally
|
||||
* are not. */
|
||||
function defineEnumerableProps(
|
||||
Ctor,
|
||||
props,
|
||||
) {
|
||||
for (const prop of props) {
|
||||
Reflect.defineProperty(Ctor.prototype, prop, { enumerable: true });
|
||||
}
|
||||
}
|
||||
|
||||
function getHeaderValueParams(value) {
|
||||
const params = new Map();
|
||||
// Forced to do so for some Map constructor param mismatch
|
||||
value
|
||||
.split(";")
|
||||
.slice(1)
|
||||
.map((s) => s.trim().split("="))
|
||||
.filter((arr) => arr.length > 1)
|
||||
.map(([k, v]) => [k, v.replace(/^"([^"]*)"$/, "$1")])
|
||||
.forEach(([k, v]) => params.set(k, v));
|
||||
return params;
|
||||
}
|
||||
|
||||
function hasHeaderValueOf(s, value) {
|
||||
return new RegExp(`^${value}[\t\s]*;?`).test(s);
|
||||
}
|
||||
|
||||
/** An internal function which provides a function name for some generated
|
||||
* functions, so stack traces are a bit more readable.
|
||||
*/
|
||||
function setFunctionName(fn, value) {
|
||||
Object.defineProperty(fn, "name", { value, configurable: true });
|
||||
}
|
||||
|
||||
window.__bootstrap.webUtil = {
|
||||
isTypedArray,
|
||||
isInvalidDate,
|
||||
requiredArguments,
|
||||
immutableDefine,
|
||||
hasOwnProperty,
|
||||
isIterable,
|
||||
cloneValue,
|
||||
defineEnumerableProps,
|
||||
getHeaderValueParams,
|
||||
hasHeaderValueOf,
|
||||
setFunctionName,
|
||||
};
|
||||
})(this);
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,7 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
const { build } = window.__bootstrap.build;
|
||||
const internals = window.__bootstrap.internals;
|
||||
const core = Deno.core;
|
||||
let logDebug = false;
|
||||
let logSource = "JS";
|
||||
|
||||
|
@ -15,9 +14,8 @@
|
|||
|
||||
function log(...args) {
|
||||
if (logDebug) {
|
||||
// if we destructure `console` off `globalThis` too early, we don't bind to
|
||||
// the right console, therefore we don't log anything out.
|
||||
globalThis.console.log(`DEBUG ${logSource} -`, ...args);
|
||||
const stringifiedArgs = args.map(JSON.stringify).join(" ");
|
||||
core.print(`DEBUG ${logSource} - ${stringifiedArgs}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,93 +48,6 @@
|
|||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
function immutableDefine(
|
||||
o,
|
||||
p,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
value,
|
||||
) {
|
||||
Object.defineProperty(o, p, {
|
||||
value,
|
||||
configurable: false,
|
||||
writable: false,
|
||||
});
|
||||
}
|
||||
|
||||
function pathFromURLWin32(url) {
|
||||
const hostname = url.hostname;
|
||||
const pathname = decodeURIComponent(url.pathname.replace(/\//g, "\\"));
|
||||
|
||||
if (hostname !== "") {
|
||||
//TODO(actual-size) Node adds a punycode decoding step, we should consider adding this
|
||||
return `\\\\${hostname}${pathname}`;
|
||||
}
|
||||
|
||||
const validPath = /^\\(?<driveLetter>[A-Za-z]):\\/;
|
||||
const matches = validPath.exec(pathname);
|
||||
|
||||
if (!matches?.groups?.driveLetter) {
|
||||
throw new TypeError("A URL with the file schema must be absolute.");
|
||||
}
|
||||
|
||||
// we don't want a leading slash on an absolute path in Windows
|
||||
return pathname.slice(1);
|
||||
}
|
||||
|
||||
function pathFromURLPosix(url) {
|
||||
if (url.hostname !== "") {
|
||||
throw new TypeError(`Host must be empty.`);
|
||||
}
|
||||
|
||||
return decodeURIComponent(url.pathname);
|
||||
}
|
||||
|
||||
function pathFromURL(pathOrUrl) {
|
||||
if (pathOrUrl instanceof URL) {
|
||||
if (pathOrUrl.protocol != "file:") {
|
||||
throw new TypeError("Must be a file URL.");
|
||||
}
|
||||
|
||||
return build.os == "windows"
|
||||
? pathFromURLWin32(pathOrUrl)
|
||||
: pathFromURLPosix(pathOrUrl);
|
||||
}
|
||||
return pathOrUrl;
|
||||
}
|
||||
|
||||
internals.exposeForTest("pathFromURL", pathFromURL);
|
||||
|
||||
function writable(value) {
|
||||
return {
|
||||
value,
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
};
|
||||
}
|
||||
|
||||
function nonEnumerable(value) {
|
||||
return {
|
||||
value,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
};
|
||||
}
|
||||
|
||||
function readOnly(value) {
|
||||
return {
|
||||
value,
|
||||
enumerable: true,
|
||||
};
|
||||
}
|
||||
|
||||
function getterOnly(getter) {
|
||||
return {
|
||||
get: getter,
|
||||
enumerable: true,
|
||||
};
|
||||
}
|
||||
|
||||
window.__bootstrap.util = {
|
||||
log,
|
||||
setLogDebug,
|
||||
|
@ -144,11 +55,5 @@
|
|||
createResolvable,
|
||||
assert,
|
||||
AssertionError,
|
||||
immutableDefine,
|
||||
pathFromURL,
|
||||
writable,
|
||||
nonEnumerable,
|
||||
readOnly,
|
||||
getterOnly,
|
||||
};
|
||||
})(this);
|
||||
|
|
|
@ -1,638 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// The following code is based off of text-encoding at:
|
||||
// https://github.com/inexorabletash/text-encoding
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
//
|
||||
// In jurisdictions that recognize copyright laws, the author or authors
|
||||
// of this software dedicate any and all copyright interest in the
|
||||
// software to the public domain. We make this dedication for the benefit
|
||||
// of the public at large and to the detriment of our heirs and
|
||||
// successors. We intend this dedication to be an overt act of
|
||||
// relinquishment in perpetuity of all present and future rights to this
|
||||
// software under copyright law.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
((window) => {
|
||||
const core = Deno.core;
|
||||
|
||||
const CONTINUE = null;
|
||||
const END_OF_STREAM = -1;
|
||||
const FINISHED = -1;
|
||||
|
||||
function decoderError(fatal) {
|
||||
if (fatal) {
|
||||
throw new TypeError("Decoder error.");
|
||||
}
|
||||
return 0xfffd; // default code point
|
||||
}
|
||||
|
||||
function inRange(a, min, max) {
|
||||
return min <= a && a <= max;
|
||||
}
|
||||
|
||||
function isASCIIByte(a) {
|
||||
return inRange(a, 0x00, 0x7f);
|
||||
}
|
||||
|
||||
function stringToCodePoints(input) {
|
||||
const u = [];
|
||||
for (const c of input) {
|
||||
u.push(c.codePointAt(0));
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
class UTF8Encoder {
|
||||
handler(codePoint) {
|
||||
if (codePoint === END_OF_STREAM) {
|
||||
return "finished";
|
||||
}
|
||||
|
||||
if (inRange(codePoint, 0x00, 0x7f)) {
|
||||
return [codePoint];
|
||||
}
|
||||
|
||||
let count;
|
||||
let offset;
|
||||
if (inRange(codePoint, 0x0080, 0x07ff)) {
|
||||
count = 1;
|
||||
offset = 0xc0;
|
||||
} else if (inRange(codePoint, 0x0800, 0xffff)) {
|
||||
count = 2;
|
||||
offset = 0xe0;
|
||||
} else if (inRange(codePoint, 0x10000, 0x10ffff)) {
|
||||
count = 3;
|
||||
offset = 0xf0;
|
||||
} else {
|
||||
throw TypeError(
|
||||
`Code point out of range: \\x${codePoint.toString(16)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const bytes = [(codePoint >> (6 * count)) + offset];
|
||||
|
||||
while (count > 0) {
|
||||
const temp = codePoint >> (6 * (count - 1));
|
||||
bytes.push(0x80 | (temp & 0x3f));
|
||||
count--;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
class SingleByteDecoder {
|
||||
#index = [];
|
||||
#fatal = false;
|
||||
|
||||
constructor(
|
||||
index,
|
||||
{ ignoreBOM = false, fatal = false } = {},
|
||||
) {
|
||||
if (ignoreBOM) {
|
||||
throw new TypeError("Ignoring the BOM is available only with utf-8.");
|
||||
}
|
||||
this.#fatal = fatal;
|
||||
this.#index = index;
|
||||
}
|
||||
handler(_stream, byte) {
|
||||
if (byte === END_OF_STREAM) {
|
||||
return FINISHED;
|
||||
}
|
||||
if (isASCIIByte(byte)) {
|
||||
return byte;
|
||||
}
|
||||
const codePoint = this.#index[byte - 0x80];
|
||||
|
||||
if (codePoint == null) {
|
||||
return decoderError(this.#fatal);
|
||||
}
|
||||
|
||||
return codePoint;
|
||||
}
|
||||
}
|
||||
|
||||
// The encodingMap is a hash of labels that are indexed by the conical
|
||||
// encoding.
|
||||
const encodingMap = {
|
||||
"windows-1252": [
|
||||
"ansi_x3.4-1968",
|
||||
"ascii",
|
||||
"cp1252",
|
||||
"cp819",
|
||||
"csisolatin1",
|
||||
"ibm819",
|
||||
"iso-8859-1",
|
||||
"iso-ir-100",
|
||||
"iso8859-1",
|
||||
"iso88591",
|
||||
"iso_8859-1",
|
||||
"iso_8859-1:1987",
|
||||
"l1",
|
||||
"latin1",
|
||||
"us-ascii",
|
||||
"windows-1252",
|
||||
"x-cp1252",
|
||||
],
|
||||
"utf-8": ["unicode-1-1-utf-8", "utf-8", "utf8"],
|
||||
};
|
||||
// We convert these into a Map where every label resolves to its canonical
|
||||
// encoding type.
|
||||
const encodings = new Map();
|
||||
for (const key of Object.keys(encodingMap)) {
|
||||
const labels = encodingMap[key];
|
||||
for (const label of labels) {
|
||||
encodings.set(label, key);
|
||||
}
|
||||
}
|
||||
|
||||
// A map of functions that return new instances of a decoder indexed by the
|
||||
// encoding type.
|
||||
const decoders = new Map();
|
||||
|
||||
// Single byte decoders are an array of code point lookups
|
||||
const encodingIndexes = new Map();
|
||||
// deno-fmt-ignore
|
||||
encodingIndexes.set("windows-1252", [
|
||||
8364,
|
||||
129,
|
||||
8218,
|
||||
402,
|
||||
8222,
|
||||
8230,
|
||||
8224,
|
||||
8225,
|
||||
710,
|
||||
8240,
|
||||
352,
|
||||
8249,
|
||||
338,
|
||||
141,
|
||||
381,
|
||||
143,
|
||||
144,
|
||||
8216,
|
||||
8217,
|
||||
8220,
|
||||
8221,
|
||||
8226,
|
||||
8211,
|
||||
8212,
|
||||
732,
|
||||
8482,
|
||||
353,
|
||||
8250,
|
||||
339,
|
||||
157,
|
||||
382,
|
||||
376,
|
||||
160,
|
||||
161,
|
||||
162,
|
||||
163,
|
||||
164,
|
||||
165,
|
||||
166,
|
||||
167,
|
||||
168,
|
||||
169,
|
||||
170,
|
||||
171,
|
||||
172,
|
||||
173,
|
||||
174,
|
||||
175,
|
||||
176,
|
||||
177,
|
||||
178,
|
||||
179,
|
||||
180,
|
||||
181,
|
||||
182,
|
||||
183,
|
||||
184,
|
||||
185,
|
||||
186,
|
||||
187,
|
||||
188,
|
||||
189,
|
||||
190,
|
||||
191,
|
||||
192,
|
||||
193,
|
||||
194,
|
||||
195,
|
||||
196,
|
||||
197,
|
||||
198,
|
||||
199,
|
||||
200,
|
||||
201,
|
||||
202,
|
||||
203,
|
||||
204,
|
||||
205,
|
||||
206,
|
||||
207,
|
||||
208,
|
||||
209,
|
||||
210,
|
||||
211,
|
||||
212,
|
||||
213,
|
||||
214,
|
||||
215,
|
||||
216,
|
||||
217,
|
||||
218,
|
||||
219,
|
||||
220,
|
||||
221,
|
||||
222,
|
||||
223,
|
||||
224,
|
||||
225,
|
||||
226,
|
||||
227,
|
||||
228,
|
||||
229,
|
||||
230,
|
||||
231,
|
||||
232,
|
||||
233,
|
||||
234,
|
||||
235,
|
||||
236,
|
||||
237,
|
||||
238,
|
||||
239,
|
||||
240,
|
||||
241,
|
||||
242,
|
||||
243,
|
||||
244,
|
||||
245,
|
||||
246,
|
||||
247,
|
||||
248,
|
||||
249,
|
||||
250,
|
||||
251,
|
||||
252,
|
||||
253,
|
||||
254,
|
||||
255,
|
||||
]);
|
||||
for (const [key, index] of encodingIndexes) {
|
||||
decoders.set(
|
||||
key,
|
||||
(options) => {
|
||||
return new SingleByteDecoder(index, options);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
function codePointsToString(codePoints) {
|
||||
let s = "";
|
||||
for (const cp of codePoints) {
|
||||
s += String.fromCodePoint(cp);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
class Stream {
|
||||
#tokens = [];
|
||||
constructor(tokens) {
|
||||
this.#tokens = [...tokens];
|
||||
this.#tokens.reverse();
|
||||
}
|
||||
|
||||
endOfStream() {
|
||||
return !this.#tokens.length;
|
||||
}
|
||||
|
||||
read() {
|
||||
return !this.#tokens.length ? END_OF_STREAM : this.#tokens.pop();
|
||||
}
|
||||
|
||||
prepend(token) {
|
||||
if (Array.isArray(token)) {
|
||||
while (token.length) {
|
||||
this.#tokens.push(token.pop());
|
||||
}
|
||||
} else {
|
||||
this.#tokens.push(token);
|
||||
}
|
||||
}
|
||||
|
||||
push(token) {
|
||||
if (Array.isArray(token)) {
|
||||
while (token.length) {
|
||||
this.#tokens.unshift(token.shift());
|
||||
}
|
||||
} else {
|
||||
this.#tokens.unshift(token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function isEitherArrayBuffer(x) {
|
||||
return x instanceof SharedArrayBuffer || x instanceof ArrayBuffer;
|
||||
}
|
||||
|
||||
class TextDecoder {
|
||||
#encoding = "";
|
||||
|
||||
get encoding() {
|
||||
return this.#encoding;
|
||||
}
|
||||
fatal = false;
|
||||
ignoreBOM = false;
|
||||
|
||||
constructor(label = "utf-8", options = { fatal: false }) {
|
||||
if (options.ignoreBOM) {
|
||||
this.ignoreBOM = true;
|
||||
}
|
||||
if (options.fatal) {
|
||||
this.fatal = true;
|
||||
}
|
||||
label = String(label).trim().toLowerCase();
|
||||
const encoding = encodings.get(label);
|
||||
if (!encoding) {
|
||||
throw new RangeError(
|
||||
`The encoding label provided ('${label}') is invalid.`,
|
||||
);
|
||||
}
|
||||
if (!decoders.has(encoding) && encoding !== "utf-8") {
|
||||
throw new TypeError(`Internal decoder ('${encoding}') not found.`);
|
||||
}
|
||||
this.#encoding = encoding;
|
||||
}
|
||||
|
||||
decode(
|
||||
input,
|
||||
options = { stream: false },
|
||||
) {
|
||||
if (options.stream) {
|
||||
throw new TypeError("Stream not supported.");
|
||||
}
|
||||
|
||||
let bytes;
|
||||
if (input instanceof Uint8Array) {
|
||||
bytes = input;
|
||||
} else if (isEitherArrayBuffer(input)) {
|
||||
bytes = new Uint8Array(input);
|
||||
} else if (
|
||||
typeof input === "object" &&
|
||||
"buffer" in input &&
|
||||
isEitherArrayBuffer(input.buffer)
|
||||
) {
|
||||
bytes = new Uint8Array(
|
||||
input.buffer,
|
||||
input.byteOffset,
|
||||
input.byteLength,
|
||||
);
|
||||
} else {
|
||||
bytes = new Uint8Array(0);
|
||||
}
|
||||
|
||||
// For simple utf-8 decoding "Deno.core.decode" can be used for performance
|
||||
if (
|
||||
this.#encoding === "utf-8" &&
|
||||
this.fatal === false &&
|
||||
this.ignoreBOM === false
|
||||
) {
|
||||
return core.decode(bytes);
|
||||
}
|
||||
|
||||
// For performance reasons we utilise a highly optimised decoder instead of
|
||||
// the general decoder.
|
||||
if (this.#encoding === "utf-8") {
|
||||
return decodeUtf8(bytes, this.fatal, this.ignoreBOM);
|
||||
}
|
||||
|
||||
const decoder = decoders.get(this.#encoding)({
|
||||
fatal: this.fatal,
|
||||
ignoreBOM: this.ignoreBOM,
|
||||
});
|
||||
const inputStream = new Stream(bytes);
|
||||
const output = [];
|
||||
|
||||
while (true) {
|
||||
const result = decoder.handler(inputStream, inputStream.read());
|
||||
if (result === FINISHED) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (result !== CONTINUE) {
|
||||
output.push(result);
|
||||
}
|
||||
}
|
||||
|
||||
if (output.length > 0 && output[0] === 0xfeff) {
|
||||
output.shift();
|
||||
}
|
||||
|
||||
return codePointsToString(output);
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return "TextDecoder";
|
||||
}
|
||||
}
|
||||
|
||||
class TextEncoder {
|
||||
encoding = "utf-8";
|
||||
encode(input = "") {
|
||||
// Deno.core.encode() provides very efficient utf-8 encoding
|
||||
if (this.encoding === "utf-8") {
|
||||
return core.encode(input);
|
||||
}
|
||||
|
||||
const encoder = new UTF8Encoder();
|
||||
const inputStream = new Stream(stringToCodePoints(input));
|
||||
const output = [];
|
||||
|
||||
while (true) {
|
||||
const result = encoder.handler(inputStream.read());
|
||||
if (result === "finished") {
|
||||
break;
|
||||
}
|
||||
output.push(...result);
|
||||
}
|
||||
|
||||
return new Uint8Array(output);
|
||||
}
|
||||
encodeInto(input, dest) {
|
||||
const encoder = new UTF8Encoder();
|
||||
const inputStream = new Stream(stringToCodePoints(input));
|
||||
|
||||
let written = 0;
|
||||
let read = 0;
|
||||
while (true) {
|
||||
const result = encoder.handler(inputStream.read());
|
||||
if (result === "finished") {
|
||||
break;
|
||||
}
|
||||
if (dest.length - written >= result.length) {
|
||||
read++;
|
||||
dest.set(result, written);
|
||||
written += result.length;
|
||||
if (result.length > 3) {
|
||||
// increment read a second time if greater than U+FFFF
|
||||
read++;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
read,
|
||||
written,
|
||||
};
|
||||
}
|
||||
get [Symbol.toStringTag]() {
|
||||
return "TextEncoder";
|
||||
}
|
||||
}
|
||||
|
||||
// This function is based on Bjoern Hoehrmann's DFA UTF-8 decoder.
|
||||
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
//
|
||||
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
function decodeUtf8(
|
||||
input,
|
||||
fatal,
|
||||
ignoreBOM,
|
||||
) {
|
||||
let outString = "";
|
||||
|
||||
// Prepare a buffer so that we don't have to do a lot of string concats, which
|
||||
// are very slow.
|
||||
const outBufferLength = Math.min(1024, input.length);
|
||||
const outBuffer = new Uint16Array(outBufferLength);
|
||||
let outIndex = 0;
|
||||
|
||||
let state = 0;
|
||||
let codepoint = 0;
|
||||
let type;
|
||||
|
||||
let i =
|
||||
ignoreBOM && input[0] === 0xef && input[1] === 0xbb && input[2] === 0xbf
|
||||
? 3
|
||||
: 0;
|
||||
|
||||
for (; i < input.length; ++i) {
|
||||
// Encoding error handling
|
||||
if (state === 12 || (state !== 0 && (input[i] & 0xc0) !== 0x80)) {
|
||||
if (fatal) {
|
||||
throw new TypeError(
|
||||
`Decoder error. Invalid byte in sequence at position ${i} in data.`,
|
||||
);
|
||||
}
|
||||
outBuffer[outIndex++] = 0xfffd; // Replacement character
|
||||
if (outIndex === outBufferLength) {
|
||||
outString += String.fromCharCode.apply(null, outBuffer);
|
||||
outIndex = 0;
|
||||
}
|
||||
state = 0;
|
||||
}
|
||||
|
||||
// deno-fmt-ignore
|
||||
type = [
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8
|
||||
][input[i]];
|
||||
codepoint = state !== 0
|
||||
? (input[i] & 0x3f) | (codepoint << 6)
|
||||
: (0xff >> type) & input[i];
|
||||
// deno-fmt-ignore
|
||||
state = [
|
||||
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
|
||||
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
|
||||
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
||||
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
||||
12,36,12,12,12,12,12,12,12,12,12,12
|
||||
][state + type];
|
||||
|
||||
if (state !== 0) continue;
|
||||
|
||||
// Add codepoint to buffer (as charcodes for utf-16), and flush buffer to
|
||||
// string if needed.
|
||||
if (codepoint > 0xffff) {
|
||||
outBuffer[outIndex++] = 0xd7c0 + (codepoint >> 10);
|
||||
if (outIndex === outBufferLength) {
|
||||
outString += String.fromCharCode.apply(null, outBuffer);
|
||||
outIndex = 0;
|
||||
}
|
||||
outBuffer[outIndex++] = 0xdc00 | (codepoint & 0x3ff);
|
||||
if (outIndex === outBufferLength) {
|
||||
outString += String.fromCharCode.apply(null, outBuffer);
|
||||
outIndex = 0;
|
||||
}
|
||||
} else {
|
||||
outBuffer[outIndex++] = codepoint;
|
||||
if (outIndex === outBufferLength) {
|
||||
outString += String.fromCharCode.apply(null, outBuffer);
|
||||
outIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a replacement character if we ended in the middle of a sequence or
|
||||
// encountered an invalid code at the end.
|
||||
if (state !== 0) {
|
||||
if (fatal) throw new TypeError(`Decoder error. Unexpected end of data.`);
|
||||
outBuffer[outIndex++] = 0xfffd; // Replacement character
|
||||
}
|
||||
|
||||
// Final flush of buffer
|
||||
outString += String.fromCharCode.apply(
|
||||
null,
|
||||
outBuffer.subarray(0, outIndex),
|
||||
);
|
||||
|
||||
return outString;
|
||||
}
|
||||
|
||||
window.TextEncoder = TextEncoder;
|
||||
window.TextDecoder = TextDecoder;
|
||||
})(this);
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
const dispatchJson = window.__bootstrap.dispatchJson;
|
||||
|
||||
function opNow() {
|
||||
return dispatchJson.sendSync("op_now");
|
||||
}
|
||||
|
||||
window.__bootstrap.timers = { opNow };
|
||||
})(this);
|
|
@ -1,231 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
((window) => {
|
||||
const { log } = window.__bootstrap.util;
|
||||
const { sendSync, sendAsync } = window.__bootstrap.dispatchJson;
|
||||
/*
|
||||
import { blobURLMap } from "./web/url.ts";
|
||||
*/
|
||||
|
||||
function createWorker(
|
||||
specifier,
|
||||
hasSourceCode,
|
||||
sourceCode,
|
||||
useDenoNamespace,
|
||||
name,
|
||||
) {
|
||||
return sendSync("op_create_worker", {
|
||||
specifier,
|
||||
hasSourceCode,
|
||||
sourceCode,
|
||||
name,
|
||||
useDenoNamespace,
|
||||
});
|
||||
}
|
||||
|
||||
function hostTerminateWorker(id) {
|
||||
sendSync("op_host_terminate_worker", { id });
|
||||
}
|
||||
|
||||
function hostPostMessage(id, data) {
|
||||
sendSync("op_host_post_message", { id }, data);
|
||||
}
|
||||
|
||||
function hostGetMessage(id) {
|
||||
return sendAsync("op_host_get_message", { id });
|
||||
}
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
class MessageEvent extends Event {
|
||||
constructor(type, eventInitDict) {
|
||||
super(type, {
|
||||
bubbles: eventInitDict?.bubbles ?? false,
|
||||
cancelable: eventInitDict?.cancelable ?? false,
|
||||
composed: eventInitDict?.composed ?? false,
|
||||
});
|
||||
|
||||
this.data = eventInitDict?.data ?? null;
|
||||
this.origin = eventInitDict?.origin ?? "";
|
||||
this.lastEventId = eventInitDict?.lastEventId ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
function encodeMessage(data) {
|
||||
const dataJson = JSON.stringify(data);
|
||||
return encoder.encode(dataJson);
|
||||
}
|
||||
|
||||
function decodeMessage(dataIntArray) {
|
||||
const dataJson = decoder.decode(dataIntArray);
|
||||
return JSON.parse(dataJson);
|
||||
}
|
||||
|
||||
class Worker extends EventTarget {
|
||||
#id = 0;
|
||||
#name = "";
|
||||
#terminated = false;
|
||||
|
||||
constructor(specifier, options) {
|
||||
super();
|
||||
const { type = "classic", name = "unknown" } = options ?? {};
|
||||
|
||||
if (type !== "module") {
|
||||
throw new Error(
|
||||
'Not yet implemented: only "module" type workers are supported',
|
||||
);
|
||||
}
|
||||
|
||||
this.#name = name;
|
||||
const hasSourceCode = false;
|
||||
const sourceCode = decoder.decode(new Uint8Array());
|
||||
|
||||
/* TODO(bartlomieju):
|
||||
// Handle blob URL.
|
||||
if (specifier.startsWith("blob:")) {
|
||||
hasSourceCode = true;
|
||||
const b = blobURLMap.get(specifier);
|
||||
if (!b) {
|
||||
throw new Error("No Blob associated with the given URL is found");
|
||||
}
|
||||
const blobBytes = blobBytesWeakMap.get(b!);
|
||||
if (!blobBytes) {
|
||||
throw new Error("Invalid Blob");
|
||||
}
|
||||
sourceCode = blobBytes!;
|
||||
}
|
||||
*/
|
||||
|
||||
const useDenoNamespace = options ? !!options.deno : false;
|
||||
|
||||
const { id } = createWorker(
|
||||
specifier,
|
||||
hasSourceCode,
|
||||
sourceCode,
|
||||
useDenoNamespace,
|
||||
options?.name,
|
||||
);
|
||||
this.#id = id;
|
||||
this.#poll();
|
||||
}
|
||||
|
||||
#handleMessage = (msgData) => {
|
||||
let data;
|
||||
try {
|
||||
data = decodeMessage(new Uint8Array(msgData));
|
||||
} catch (e) {
|
||||
const msgErrorEvent = new MessageEvent("messageerror", {
|
||||
cancelable: false,
|
||||
data,
|
||||
});
|
||||
if (this.onmessageerror) {
|
||||
this.onmessageerror(msgErrorEvent);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const msgEvent = new MessageEvent("message", {
|
||||
cancelable: false,
|
||||
data,
|
||||
});
|
||||
|
||||
if (this.onmessage) {
|
||||
this.onmessage(msgEvent);
|
||||
}
|
||||
|
||||
this.dispatchEvent(msgEvent);
|
||||
};
|
||||
|
||||
#handleError = (e) => {
|
||||
const event = new ErrorEvent("error", {
|
||||
cancelable: true,
|
||||
message: e.message,
|
||||
lineno: e.lineNumber ? e.lineNumber + 1 : undefined,
|
||||
colno: e.columnNumber ? e.columnNumber + 1 : undefined,
|
||||
filename: e.fileName,
|
||||
error: null,
|
||||
});
|
||||
|
||||
let handled = false;
|
||||
if (this.onerror) {
|
||||
this.onerror(event);
|
||||
}
|
||||
|
||||
this.dispatchEvent(event);
|
||||
if (event.defaultPrevented) {
|
||||
handled = true;
|
||||
}
|
||||
|
||||
return handled;
|
||||
};
|
||||
|
||||
#poll = async () => {
|
||||
while (!this.#terminated) {
|
||||
const event = await hostGetMessage(this.#id);
|
||||
|
||||
// If terminate was called then we ignore all messages
|
||||
if (this.#terminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
const type = event.type;
|
||||
|
||||
if (type === "terminalError") {
|
||||
this.#terminated = true;
|
||||
if (!this.#handleError(event.error)) {
|
||||
throw Error(event.error.message);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type === "msg") {
|
||||
this.#handleMessage(event.data);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type === "error") {
|
||||
if (!this.#handleError(event.error)) {
|
||||
throw Error(event.error.message);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type === "close") {
|
||||
log(`Host got "close" message from worker: ${this.#name}`);
|
||||
this.#terminated = true;
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error(`Unknown worker event: "${type}"`);
|
||||
}
|
||||
};
|
||||
|
||||
postMessage(message, transferOrOptions) {
|
||||
if (transferOrOptions) {
|
||||
throw new Error(
|
||||
"Not yet implemented: `transfer` and `options` are not supported.",
|
||||
);
|
||||
}
|
||||
|
||||
if (this.#terminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
hostPostMessage(this.#id, encodeMessage(message));
|
||||
}
|
||||
|
||||
terminate() {
|
||||
if (!this.#terminated) {
|
||||
this.#terminated = true;
|
||||
hostTerminateWorker(this.#id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.__bootstrap.worker = {
|
||||
Worker,
|
||||
MessageEvent,
|
||||
};
|
||||
})(this);
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// Diagnostic provides an abstraction for advice/errors received from a
|
||||
// compiler, which is strongly influenced by the format of TypeScript
|
||||
// diagnostics.
|
||||
|
||||
((window) => {
|
||||
const DiagnosticCategory = {
|
||||
0: "Log",
|
||||
1: "Debug",
|
||||
2: "Info",
|
||||
3: "Error",
|
||||
4: "Warning",
|
||||
5: "Suggestion",
|
||||
|
||||
Log: 0,
|
||||
Debug: 1,
|
||||
Info: 2,
|
||||
Error: 3,
|
||||
Warning: 4,
|
||||
Suggestion: 5,
|
||||
};
|
||||
|
||||
window.__bootstrap.diagnostics = {
|
||||
DiagnosticCategory,
|
||||
};
|
||||
})(this);
|
|
@ -3,22 +3,19 @@
|
|||
((window) => {
|
||||
// Some of the code here is adapted directly from V8 and licensed under a BSD
|
||||
// style license available here: https://github.com/v8/v8/blob/24886f2d1c565287d33d71e4109a53bf0b54b75c/LICENSE.v8
|
||||
const colors = window.__bootstrap.colors;
|
||||
const assert = window.__bootstrap.util.assert;
|
||||
const internals = window.__bootstrap.internals;
|
||||
const dispatchJson = window.__bootstrap.dispatchJson;
|
||||
|
||||
function opFormatDiagnostics(items) {
|
||||
return dispatchJson.sendSync("op_format_diagnostic", { items });
|
||||
}
|
||||
// https://github.com/chalk/ansi-regex/blob/2b56fb0c7a07108e5b54241e8faec160d393aedb/index.js
|
||||
const ANSI_PATTERN = new RegExp(
|
||||
[
|
||||
"[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
|
||||
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))",
|
||||
].join("|"),
|
||||
"g",
|
||||
);
|
||||
|
||||
function opApplySourceMap(location) {
|
||||
const res = dispatchJson.sendSync("op_apply_source_map", location);
|
||||
return {
|
||||
fileName: res.fileName,
|
||||
lineNumber: res.lineNumber,
|
||||
columnNumber: res.columnNumber,
|
||||
};
|
||||
function stripColor(string) {
|
||||
return string.replace(ANSI_PATTERN, "");
|
||||
}
|
||||
|
||||
function patchCallSite(callSite, location) {
|
||||
|
@ -109,12 +106,9 @@
|
|||
return result;
|
||||
}
|
||||
|
||||
function getFileLocation(callSite, internal = false) {
|
||||
const cyan = internal ? colors.gray : colors.cyan;
|
||||
const yellow = internal ? colors.gray : colors.yellow;
|
||||
const black = internal ? colors.gray : (s) => s;
|
||||
function getFileLocation(callSite) {
|
||||
if (callSite.isNative()) {
|
||||
return cyan("native");
|
||||
return "native";
|
||||
}
|
||||
|
||||
let result = "";
|
||||
|
@ -123,32 +117,29 @@
|
|||
if (!fileName && callSite.isEval()) {
|
||||
const evalOrigin = callSite.getEvalOrigin();
|
||||
assert(evalOrigin != null);
|
||||
result += cyan(`${evalOrigin}, `);
|
||||
result += `${evalOrigin}, `;
|
||||
}
|
||||
|
||||
if (fileName) {
|
||||
result += cyan(fileName);
|
||||
result += fileName;
|
||||
} else {
|
||||
result += cyan("<anonymous>");
|
||||
result += "<anonymous>";
|
||||
}
|
||||
|
||||
const lineNumber = callSite.getLineNumber();
|
||||
if (lineNumber != null) {
|
||||
result += `${black(":")}${yellow(lineNumber.toString())}`;
|
||||
result += `:${lineNumber.toString()}`;
|
||||
|
||||
const columnNumber = callSite.getColumnNumber();
|
||||
if (columnNumber != null) {
|
||||
result += `${black(":")}${yellow(columnNumber.toString())}`;
|
||||
result += `:${columnNumber.toString()}`;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function callSiteToString(callSite, internal = false) {
|
||||
const cyan = internal ? colors.gray : colors.cyan;
|
||||
const black = internal ? colors.gray : (s) => s;
|
||||
|
||||
function callSiteToString(callSite) {
|
||||
let result = "";
|
||||
const functionName = callSite.getFunctionName();
|
||||
|
||||
|
@ -159,35 +150,29 @@
|
|||
const isMethodCall = !(isTopLevel || isConstructor);
|
||||
|
||||
if (isAsync) {
|
||||
result += colors.gray("async ");
|
||||
result += "async ";
|
||||
}
|
||||
if (isPromiseAll) {
|
||||
result += colors.bold(
|
||||
colors.italic(
|
||||
black(`Promise.all (index ${callSite.getPromiseIndex()})`),
|
||||
),
|
||||
);
|
||||
result += `Promise.all (index ${callSite.getPromiseIndex()})`;
|
||||
return result;
|
||||
}
|
||||
if (isMethodCall) {
|
||||
result += colors.bold(colors.italic(black(getMethodCall(callSite))));
|
||||
result += getMethodCall(callSite);
|
||||
} else if (isConstructor) {
|
||||
result += colors.gray("new ");
|
||||
result += "new ";
|
||||
if (functionName) {
|
||||
result += colors.bold(colors.italic(black(functionName)));
|
||||
result += functionName;
|
||||
} else {
|
||||
result += cyan("<anonymous>");
|
||||
result += "<anonymous>";
|
||||
}
|
||||
} else if (functionName) {
|
||||
result += colors.bold(colors.italic(black(functionName)));
|
||||
result += functionName;
|
||||
} else {
|
||||
result += getFileLocation(callSite, internal);
|
||||
result += getFileLocation(callSite);
|
||||
return result;
|
||||
}
|
||||
|
||||
result += ` ${black("(")}${getFileLocation(callSite, internal)}${
|
||||
black(")")
|
||||
}`;
|
||||
result += ` (${getFileLocation(callSite)})`;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -224,11 +209,11 @@
|
|||
if (fileName && lineNumber != null && columnNumber != null) {
|
||||
return patchCallSite(
|
||||
callSite,
|
||||
opApplySourceMap({
|
||||
{
|
||||
fileName,
|
||||
lineNumber,
|
||||
columnNumber,
|
||||
}),
|
||||
},
|
||||
);
|
||||
}
|
||||
return callSite;
|
||||
|
@ -240,15 +225,14 @@
|
|||
});
|
||||
for (const callSite of mappedCallSites) {
|
||||
error.__callSiteEvals.push(Object.freeze(evaluateCallSite(callSite)));
|
||||
const isInternal = callSite.getFileName()?.startsWith("$deno$") ?? false;
|
||||
error.__formattedFrames.push(callSiteToString(callSite, isInternal));
|
||||
error.__formattedFrames.push(callSiteToString(callSite));
|
||||
}
|
||||
Object.freeze(error.__callSiteEvals);
|
||||
Object.freeze(error.__formattedFrames);
|
||||
return (
|
||||
`${error.name}: ${error.message}\n` +
|
||||
error.__formattedFrames
|
||||
.map((s) => ` at ${colors.stripColor(s)}`)
|
||||
.map((s) => ` at ${stripColor(s)}`)
|
||||
.join("\n")
|
||||
);
|
||||
}
|
||||
|
@ -257,11 +241,7 @@
|
|||
ErrorConstructor.prepareStackTrace = prepareStackTrace;
|
||||
}
|
||||
|
||||
internals.exposeForTest("setPrepareStackTrace", setPrepareStackTrace);
|
||||
|
||||
window.__bootstrap.errorStack = {
|
||||
setPrepareStackTrace,
|
||||
opApplySourceMap,
|
||||
opFormatDiagnostics,
|
||||
};
|
||||
})(this);
|
||||
|
|
|
@ -1,321 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
((window) => {
|
||||
const { opNow } = window.__bootstrap.timers;
|
||||
const { customInspect, inspect } = window.__bootstrap.console;
|
||||
const { cloneValue } = window.__bootstrap.webUtil;
|
||||
|
||||
let performanceEntries = [];
|
||||
|
||||
function findMostRecent(
|
||||
name,
|
||||
type,
|
||||
) {
|
||||
return performanceEntries
|
||||
.slice()
|
||||
.reverse()
|
||||
.find((entry) => entry.name === name && entry.entryType === type);
|
||||
}
|
||||
|
||||
function convertMarkToTimestamp(mark) {
|
||||
if (typeof mark === "string") {
|
||||
const entry = findMostRecent(mark, "mark");
|
||||
if (!entry) {
|
||||
throw new SyntaxError(`Cannot find mark: "${mark}".`);
|
||||
}
|
||||
return entry.startTime;
|
||||
}
|
||||
if (mark < 0) {
|
||||
throw new TypeError("Mark cannot be negative.");
|
||||
}
|
||||
return mark;
|
||||
}
|
||||
|
||||
function filterByNameType(
|
||||
name,
|
||||
type,
|
||||
) {
|
||||
return performanceEntries.filter(
|
||||
(entry) =>
|
||||
(name ? entry.name === name : true) &&
|
||||
(type ? entry.entryType === type : true),
|
||||
);
|
||||
}
|
||||
|
||||
function now() {
|
||||
const res = opNow();
|
||||
return res.seconds * 1e3 + res.subsecNanos / 1e6;
|
||||
}
|
||||
|
||||
class PerformanceEntry {
|
||||
#name = "";
|
||||
#entryType = "";
|
||||
#startTime = 0;
|
||||
#duration = 0;
|
||||
|
||||
get name() {
|
||||
return this.#name;
|
||||
}
|
||||
|
||||
get entryType() {
|
||||
return this.#entryType;
|
||||
}
|
||||
|
||||
get startTime() {
|
||||
return this.#startTime;
|
||||
}
|
||||
|
||||
get duration() {
|
||||
return this.#duration;
|
||||
}
|
||||
|
||||
constructor(
|
||||
name,
|
||||
entryType,
|
||||
startTime,
|
||||
duration,
|
||||
) {
|
||||
this.#name = name;
|
||||
this.#entryType = entryType;
|
||||
this.#startTime = startTime;
|
||||
this.#duration = duration;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
name: this.#name,
|
||||
entryType: this.#entryType,
|
||||
startTime: this.#startTime,
|
||||
duration: this.#duration,
|
||||
};
|
||||
}
|
||||
|
||||
[customInspect]() {
|
||||
return `${this.constructor.name} { name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`;
|
||||
}
|
||||
}
|
||||
|
||||
class PerformanceMark extends PerformanceEntry {
|
||||
#detail = null;
|
||||
|
||||
get detail() {
|
||||
return this.#detail;
|
||||
}
|
||||
|
||||
get entryType() {
|
||||
return "mark";
|
||||
}
|
||||
|
||||
constructor(
|
||||
name,
|
||||
{ detail = null, startTime = now() } = {},
|
||||
) {
|
||||
super(name, "mark", startTime, 0);
|
||||
if (startTime < 0) {
|
||||
throw new TypeError("startTime cannot be negative");
|
||||
}
|
||||
this.#detail = cloneValue(detail);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
name: this.name,
|
||||
entryType: this.entryType,
|
||||
startTime: this.startTime,
|
||||
duration: this.duration,
|
||||
detail: this.detail,
|
||||
};
|
||||
}
|
||||
|
||||
[customInspect]() {
|
||||
return this.detail
|
||||
? `${this.constructor.name} {\n detail: ${
|
||||
inspect(this.detail, { depth: 3 })
|
||||
},\n name: "${this.name}",\n entryType: "${this.entryType}",\n startTime: ${this.startTime},\n duration: ${this.duration}\n}`
|
||||
: `${this.constructor.name} { detail: ${this.detail}, name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`;
|
||||
}
|
||||
}
|
||||
|
||||
class PerformanceMeasure extends PerformanceEntry {
|
||||
#detail = null;
|
||||
|
||||
get detail() {
|
||||
return this.#detail;
|
||||
}
|
||||
|
||||
get entryType() {
|
||||
return "measure";
|
||||
}
|
||||
|
||||
constructor(
|
||||
name,
|
||||
startTime,
|
||||
duration,
|
||||
detail = null,
|
||||
) {
|
||||
super(name, "measure", startTime, duration);
|
||||
this.#detail = cloneValue(detail);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
name: this.name,
|
||||
entryType: this.entryType,
|
||||
startTime: this.startTime,
|
||||
duration: this.duration,
|
||||
detail: this.detail,
|
||||
};
|
||||
}
|
||||
|
||||
[customInspect]() {
|
||||
return this.detail
|
||||
? `${this.constructor.name} {\n detail: ${
|
||||
inspect(this.detail, { depth: 3 })
|
||||
},\n name: "${this.name}",\n entryType: "${this.entryType}",\n startTime: ${this.startTime},\n duration: ${this.duration}\n}`
|
||||
: `${this.constructor.name} { detail: ${this.detail}, name: "${this.name}", entryType: "${this.entryType}", startTime: ${this.startTime}, duration: ${this.duration} }`;
|
||||
}
|
||||
}
|
||||
|
||||
class Performance {
|
||||
clearMarks(markName) {
|
||||
if (markName == null) {
|
||||
performanceEntries = performanceEntries.filter(
|
||||
(entry) => entry.entryType !== "mark",
|
||||
);
|
||||
} else {
|
||||
performanceEntries = performanceEntries.filter(
|
||||
(entry) => !(entry.name === markName && entry.entryType === "mark"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
clearMeasures(measureName) {
|
||||
if (measureName == null) {
|
||||
performanceEntries = performanceEntries.filter(
|
||||
(entry) => entry.entryType !== "measure",
|
||||
);
|
||||
} else {
|
||||
performanceEntries = performanceEntries.filter(
|
||||
(entry) =>
|
||||
!(entry.name === measureName && entry.entryType === "measure"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getEntries() {
|
||||
return filterByNameType();
|
||||
}
|
||||
|
||||
getEntriesByName(
|
||||
name,
|
||||
type,
|
||||
) {
|
||||
return filterByNameType(name, type);
|
||||
}
|
||||
|
||||
getEntriesByType(type) {
|
||||
return filterByNameType(undefined, type);
|
||||
}
|
||||
|
||||
mark(
|
||||
markName,
|
||||
options = {},
|
||||
) {
|
||||
// 3.1.1.1 If the global object is a Window object and markName uses the
|
||||
// same name as a read only attribute in the PerformanceTiming interface,
|
||||
// throw a SyntaxError. - not implemented
|
||||
const entry = new PerformanceMark(markName, options);
|
||||
// 3.1.1.7 Queue entry - not implemented
|
||||
performanceEntries.push(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
measure(
|
||||
measureName,
|
||||
startOrMeasureOptions = {},
|
||||
endMark,
|
||||
) {
|
||||
if (startOrMeasureOptions && typeof startOrMeasureOptions === "object") {
|
||||
if (endMark) {
|
||||
throw new TypeError("Options cannot be passed with endMark.");
|
||||
}
|
||||
if (
|
||||
!("start" in startOrMeasureOptions) &&
|
||||
!("end" in startOrMeasureOptions)
|
||||
) {
|
||||
throw new TypeError(
|
||||
"A start or end mark must be supplied in options.",
|
||||
);
|
||||
}
|
||||
if (
|
||||
"start" in startOrMeasureOptions &&
|
||||
"duration" in startOrMeasureOptions &&
|
||||
"end" in startOrMeasureOptions
|
||||
) {
|
||||
throw new TypeError(
|
||||
"Cannot specify start, end, and duration together in options.",
|
||||
);
|
||||
}
|
||||
}
|
||||
let endTime;
|
||||
if (endMark) {
|
||||
endTime = convertMarkToTimestamp(endMark);
|
||||
} else if (
|
||||
typeof startOrMeasureOptions === "object" &&
|
||||
"end" in startOrMeasureOptions
|
||||
) {
|
||||
endTime = convertMarkToTimestamp(startOrMeasureOptions.end);
|
||||
} else if (
|
||||
typeof startOrMeasureOptions === "object" &&
|
||||
"start" in startOrMeasureOptions &&
|
||||
"duration" in startOrMeasureOptions
|
||||
) {
|
||||
const start = convertMarkToTimestamp(startOrMeasureOptions.start);
|
||||
const duration = convertMarkToTimestamp(startOrMeasureOptions.duration);
|
||||
endTime = start + duration;
|
||||
} else {
|
||||
endTime = now();
|
||||
}
|
||||
let startTime;
|
||||
if (
|
||||
typeof startOrMeasureOptions === "object" &&
|
||||
"start" in startOrMeasureOptions
|
||||
) {
|
||||
startTime = convertMarkToTimestamp(startOrMeasureOptions.start);
|
||||
} else if (
|
||||
typeof startOrMeasureOptions === "object" &&
|
||||
"end" in startOrMeasureOptions &&
|
||||
"duration" in startOrMeasureOptions
|
||||
) {
|
||||
const end = convertMarkToTimestamp(startOrMeasureOptions.end);
|
||||
const duration = convertMarkToTimestamp(startOrMeasureOptions.duration);
|
||||
startTime = end - duration;
|
||||
} else if (typeof startOrMeasureOptions === "string") {
|
||||
startTime = convertMarkToTimestamp(startOrMeasureOptions);
|
||||
} else {
|
||||
startTime = 0;
|
||||
}
|
||||
const entry = new PerformanceMeasure(
|
||||
measureName,
|
||||
startTime,
|
||||
endTime - startTime,
|
||||
typeof startOrMeasureOptions === "object"
|
||||
? startOrMeasureOptions.detail ?? null
|
||||
: null,
|
||||
);
|
||||
performanceEntries.push(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
now() {
|
||||
return now();
|
||||
}
|
||||
}
|
||||
|
||||
window.__bootstrap.performance = {
|
||||
PerformanceEntry,
|
||||
PerformanceMark,
|
||||
PerformanceMeasure,
|
||||
Performance,
|
||||
};
|
||||
})(this);
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// This module exports stable Deno APIs.
|
||||
|
||||
((window) => {
|
||||
window.__bootstrap.denoNs = {
|
||||
version: window.__bootstrap.version.version,
|
||||
build: window.__bootstrap.build.build,
|
||||
errors: window.__bootstrap.errors.errors,
|
||||
customInspect: window.__bootstrap.console.customInspect,
|
||||
inspect: window.__bootstrap.console.inspect,
|
||||
};
|
||||
})(this);
|
|
@ -1,217 +0,0 @@
|
|||
// Removes the `__proto__` for security reasons. This intentionally makes
|
||||
// Deno non compliant with ECMA-262 Annex B.2.2.1
|
||||
//
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
delete Object.prototype.__proto__;
|
||||
|
||||
((window) => {
|
||||
const core = Deno.core;
|
||||
const util = window.__bootstrap.util;
|
||||
const eventTarget = window.__bootstrap.eventTarget;
|
||||
const dispatchJson = window.__bootstrap.dispatchJson;
|
||||
const build = window.__bootstrap.build;
|
||||
const version = window.__bootstrap.version;
|
||||
const errorStack = window.__bootstrap.errorStack;
|
||||
const Console = window.__bootstrap.console.Console;
|
||||
const worker = window.__bootstrap.worker;
|
||||
const { internalSymbol, internalObject } = window.__bootstrap.internals;
|
||||
const performance = window.__bootstrap.performance;
|
||||
const crypto = window.__bootstrap.crypto;
|
||||
const denoNs = window.__bootstrap.denoNs;
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
function workerClose() {
|
||||
if (isClosing) {
|
||||
return;
|
||||
}
|
||||
|
||||
isClosing = true;
|
||||
opCloseWorker();
|
||||
}
|
||||
|
||||
// TODO(bartlomieju): remove these funtions
|
||||
// Stuff for workers
|
||||
const onmessage = () => {};
|
||||
const onerror = () => {};
|
||||
|
||||
function postMessage(data) {
|
||||
const dataJson = JSON.stringify(data);
|
||||
const dataIntArray = encoder.encode(dataJson);
|
||||
opPostMessage(dataIntArray);
|
||||
}
|
||||
|
||||
let isClosing = false;
|
||||
async function workerMessageRecvCallback(data) {
|
||||
const msgEvent = new worker.MessageEvent("message", {
|
||||
cancelable: false,
|
||||
data,
|
||||
});
|
||||
|
||||
try {
|
||||
if (globalThis["onmessage"]) {
|
||||
const result = globalThis.onmessage(msgEvent);
|
||||
if (result && "then" in result) {
|
||||
await result;
|
||||
}
|
||||
}
|
||||
globalThis.dispatchEvent(msgEvent);
|
||||
} catch (e) {
|
||||
let handled = false;
|
||||
|
||||
const errorEvent = new ErrorEvent("error", {
|
||||
cancelable: true,
|
||||
message: e.message,
|
||||
lineno: e.lineNumber ? e.lineNumber + 1 : undefined,
|
||||
colno: e.columnNumber ? e.columnNumber + 1 : undefined,
|
||||
filename: e.fileName,
|
||||
error: null,
|
||||
});
|
||||
|
||||
if (globalThis["onerror"]) {
|
||||
const ret = globalThis.onerror(
|
||||
e.message,
|
||||
e.fileName,
|
||||
e.lineNumber,
|
||||
e.columnNumber,
|
||||
e,
|
||||
);
|
||||
handled = ret === true;
|
||||
}
|
||||
|
||||
globalThis.dispatchEvent(errorEvent);
|
||||
if (errorEvent.defaultPrevented) {
|
||||
handled = true;
|
||||
}
|
||||
|
||||
if (!handled) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function opPostMessage(data) {
|
||||
dispatchJson.sendSync("op_worker_post_message", {}, data);
|
||||
}
|
||||
|
||||
function opCloseWorker() {
|
||||
dispatchJson.sendSync("op_worker_close");
|
||||
}
|
||||
|
||||
function opStart() {
|
||||
return dispatchJson.sendSync("op_start");
|
||||
}
|
||||
|
||||
// TODO(bartlomieju): temporary solution, must be fixed when moving
|
||||
// dispatches to separate crates
|
||||
function initOps() {
|
||||
const opsMap = core.ops();
|
||||
for (const [_name, opId] of Object.entries(opsMap)) {
|
||||
core.setAsyncHandler(opId, dispatchJson.asyncMsgFromRust);
|
||||
}
|
||||
}
|
||||
|
||||
function runtimeStart(source) {
|
||||
initOps();
|
||||
// First we send an empty `Start` message to let the privileged side know we
|
||||
// are ready. The response should be a `StartRes` message containing the CLI
|
||||
// args and other info.
|
||||
const s = opStart();
|
||||
version.setVersions(s.denoVersion, s.v8Version, s.tsVersion);
|
||||
build.setBuildInfo(s.target);
|
||||
util.setLogDebug(s.debugFlag, source);
|
||||
errorStack.setPrepareStackTrace(Error);
|
||||
return s;
|
||||
}
|
||||
|
||||
// Other properties shared between WindowScope and WorkerGlobalScope
|
||||
const windowOrWorkerGlobalScopeProperties = {
|
||||
console: util.writable(new Console(core.print)),
|
||||
crypto: util.readOnly(crypto),
|
||||
CustomEvent: util.nonEnumerable(CustomEvent),
|
||||
ErrorEvent: util.nonEnumerable(ErrorEvent),
|
||||
Event: util.nonEnumerable(Event),
|
||||
EventTarget: util.nonEnumerable(EventTarget),
|
||||
performance: util.writable(new performance.Performance()),
|
||||
Performance: util.nonEnumerable(performance.Performance),
|
||||
PerformanceEntry: util.nonEnumerable(performance.PerformanceEntry),
|
||||
PerformanceMark: util.nonEnumerable(performance.PerformanceMark),
|
||||
PerformanceMeasure: util.nonEnumerable(performance.PerformanceMeasure),
|
||||
TextDecoder: util.nonEnumerable(TextDecoder),
|
||||
TextEncoder: util.nonEnumerable(TextEncoder),
|
||||
Worker: util.nonEnumerable(worker.Worker),
|
||||
};
|
||||
|
||||
const eventTargetProperties = {
|
||||
addEventListener: util.readOnly(
|
||||
EventTarget.prototype.addEventListener,
|
||||
),
|
||||
dispatchEvent: util.readOnly(EventTarget.prototype.dispatchEvent),
|
||||
removeEventListener: util.readOnly(
|
||||
EventTarget.prototype.removeEventListener,
|
||||
),
|
||||
};
|
||||
|
||||
const workerRuntimeGlobalProperties = {
|
||||
self: util.readOnly(globalThis),
|
||||
onmessage: util.writable(onmessage),
|
||||
onerror: util.writable(onerror),
|
||||
// TODO: should be readonly?
|
||||
close: util.nonEnumerable(workerClose),
|
||||
postMessage: util.writable(postMessage),
|
||||
workerMessageRecvCallback: util.nonEnumerable(workerMessageRecvCallback),
|
||||
};
|
||||
|
||||
let hasBootstrapped = false;
|
||||
|
||||
function bootstrapWorkerRuntime(name, useDenoNamespace, internalName) {
|
||||
if (hasBootstrapped) {
|
||||
throw new Error("Worker runtime already bootstrapped");
|
||||
}
|
||||
// Remove bootstrapping methods from global scope
|
||||
globalThis.__bootstrap = undefined;
|
||||
globalThis.bootstrap = undefined;
|
||||
util.log("bootstrapWorkerRuntime");
|
||||
hasBootstrapped = true;
|
||||
Object.defineProperties(globalThis, windowOrWorkerGlobalScopeProperties);
|
||||
Object.defineProperties(globalThis, workerRuntimeGlobalProperties);
|
||||
Object.defineProperties(globalThis, eventTargetProperties);
|
||||
Object.defineProperties(globalThis, { name: util.readOnly(name) });
|
||||
eventTarget.setEventTargetData(globalThis);
|
||||
const { noColor, args } = runtimeStart(
|
||||
internalName ?? name,
|
||||
);
|
||||
|
||||
const finalDenoNs = {
|
||||
core,
|
||||
internal: internalSymbol,
|
||||
[internalSymbol]: internalObject,
|
||||
...denoNs,
|
||||
};
|
||||
if (useDenoNamespace) {
|
||||
Object.defineProperties(finalDenoNs, {
|
||||
noColor: util.readOnly(noColor),
|
||||
args: util.readOnly(Object.freeze(args)),
|
||||
});
|
||||
// Setup `Deno` global - we're actually overriding already
|
||||
// existing global `Deno` with `Deno` namespace from "./deno.ts".
|
||||
util.immutableDefine(globalThis, "Deno", finalDenoNs);
|
||||
Object.freeze(globalThis.Deno);
|
||||
Object.freeze(globalThis.Deno.core);
|
||||
Object.freeze(globalThis.Deno.core.sharedQueue);
|
||||
} else {
|
||||
delete globalThis.Deno;
|
||||
util.assert(globalThis.Deno === undefined);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(globalThis, {
|
||||
bootstrap: {
|
||||
value: {
|
||||
workerRuntime: bootstrapWorkerRuntime,
|
||||
},
|
||||
configurable: true,
|
||||
writable: true,
|
||||
},
|
||||
});
|
||||
})(this);
|
|
@ -3,10 +3,13 @@
|
|||
// This module is the entry point for "compiler" isolate, ie. the one
|
||||
// that is created when Deno needs to compile TS/WASM to JS.
|
||||
//
|
||||
// It provides a single functions that should be called by Rust:
|
||||
// - `bootstrapTsCompilerRuntime`
|
||||
// It provides two functions that should be called by Rust:
|
||||
// - `bootstrapCompilerRuntime`
|
||||
// This functions must be called when creating isolate
|
||||
// to properly setup runtime.
|
||||
// - `tsCompilerOnMessage`
|
||||
// This function must be called when sending a request
|
||||
// to the compiler.
|
||||
|
||||
// Removes the `__proto__` for security reasons. This intentionally makes
|
||||
// Deno non compliant with ECMA-262 Annex B.2.2.1
|
||||
|
@ -16,9 +19,31 @@ delete Object.prototype.__proto__;
|
|||
|
||||
((window) => {
|
||||
const core = Deno.core;
|
||||
const { bold, cyan, yellow } = window.__bootstrap.colors;
|
||||
const { assert, log, notImplemented } = window.__bootstrap.util;
|
||||
const { DiagnosticCategory } = window.__bootstrap.diagnostics;
|
||||
const dispatchJson = window.__bootstrap.dispatchJson;
|
||||
const util = window.__bootstrap.util;
|
||||
const errorStack = window.__bootstrap.errorStack;
|
||||
|
||||
function opNow() {
|
||||
const res = dispatchJson.sendSync("op_now");
|
||||
return res.seconds * 1e3 + res.subsecNanos / 1e6;
|
||||
}
|
||||
|
||||
const DiagnosticCategory = {
|
||||
0: "Log",
|
||||
1: "Debug",
|
||||
2: "Info",
|
||||
3: "Error",
|
||||
4: "Warning",
|
||||
5: "Suggestion",
|
||||
|
||||
Log: 0,
|
||||
Debug: 1,
|
||||
Info: 2,
|
||||
Error: 3,
|
||||
Warning: 4,
|
||||
Suggestion: 5,
|
||||
};
|
||||
|
||||
const unstableDenoGlobalProperties = [
|
||||
"umask",
|
||||
|
@ -1136,7 +1161,7 @@ delete Object.prototype.__proto__;
|
|||
function performanceStart() {
|
||||
stats.length = 0;
|
||||
// TODO(kitsonk) replace with performance.mark() when landed
|
||||
statsStart = performance.now();
|
||||
statsStart = opNow();
|
||||
ts.performance.enable();
|
||||
}
|
||||
|
||||
|
@ -1176,7 +1201,7 @@ delete Object.prototype.__proto__;
|
|||
|
||||
function performanceEnd() {
|
||||
// TODO(kitsonk) replace with performance.measure() when landed
|
||||
const duration = performance.now() - statsStart;
|
||||
const duration = opNow() - statsStart;
|
||||
stats.push({ key: "Compile time", value: duration });
|
||||
return stats;
|
||||
}
|
||||
|
@ -1188,11 +1213,11 @@ delete Object.prototype.__proto__;
|
|||
) {
|
||||
const { ignoredOptions, diagnostics } = configResult;
|
||||
if (ignoredOptions) {
|
||||
console.warn(
|
||||
yellow(`Unsupported compiler options in "${configPath}"\n`) +
|
||||
cyan(` The following options were ignored:\n`) +
|
||||
` ${ignoredOptions.map((value) => bold(value)).join(", ")}`,
|
||||
);
|
||||
const msg =
|
||||
`Unsupported compiler options in "${configPath}"\n The following options were ignored:\n ${
|
||||
ignoredOptions.map((value) => value).join(", ")
|
||||
}\n`;
|
||||
core.print(msg, true);
|
||||
}
|
||||
return diagnostics;
|
||||
}
|
||||
|
@ -1545,6 +1570,7 @@ delete Object.prototype.__proto__;
|
|||
cwd,
|
||||
sourceFileMap,
|
||||
type,
|
||||
performance,
|
||||
}) {
|
||||
if (performance) {
|
||||
performanceStart();
|
||||
|
@ -1804,64 +1830,83 @@ delete Object.prototype.__proto__;
|
|||
return Promise.resolve(result);
|
||||
}
|
||||
|
||||
async function tsCompilerOnMessage({
|
||||
data: request,
|
||||
}) {
|
||||
function opCompilerRespond(msg) {
|
||||
dispatchJson.sendSync("op_compiler_respond", msg);
|
||||
}
|
||||
|
||||
async function tsCompilerOnMessage(msg) {
|
||||
const request = msg.data;
|
||||
switch (request.type) {
|
||||
case CompilerRequestType.Compile: {
|
||||
const result = compile(request);
|
||||
globalThis.postMessage(result);
|
||||
opCompilerRespond(result);
|
||||
break;
|
||||
}
|
||||
case CompilerRequestType.Transpile: {
|
||||
const result = transpile(request);
|
||||
globalThis.postMessage(result);
|
||||
opCompilerRespond(result);
|
||||
break;
|
||||
}
|
||||
case CompilerRequestType.Bundle: {
|
||||
const result = bundle(request);
|
||||
globalThis.postMessage(result);
|
||||
opCompilerRespond(result);
|
||||
break;
|
||||
}
|
||||
case CompilerRequestType.RuntimeCompile: {
|
||||
const result = runtimeCompile(request);
|
||||
globalThis.postMessage(result);
|
||||
opCompilerRespond(result);
|
||||
break;
|
||||
}
|
||||
case CompilerRequestType.RuntimeBundle: {
|
||||
const result = runtimeBundle(request);
|
||||
globalThis.postMessage(result);
|
||||
opCompilerRespond(result);
|
||||
break;
|
||||
}
|
||||
case CompilerRequestType.RuntimeTranspile: {
|
||||
const result = await runtimeTranspile(request);
|
||||
globalThis.postMessage(result);
|
||||
opCompilerRespond(result);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log(
|
||||
throw new Error(
|
||||
`!!! unhandled CompilerRequestType: ${request.type} (${
|
||||
CompilerRequestType[request.type]
|
||||
})`,
|
||||
);
|
||||
}
|
||||
// Shutdown after single request
|
||||
globalThis.close();
|
||||
}
|
||||
|
||||
function bootstrapTsCompilerRuntime() {
|
||||
globalThis.bootstrap.workerRuntime("TS", false);
|
||||
globalThis.onmessage = tsCompilerOnMessage;
|
||||
// TODO(bartlomieju): temporary solution, must be fixed when moving
|
||||
// dispatches to separate crates
|
||||
function initOps() {
|
||||
const opsMap = core.ops();
|
||||
for (const [_name, opId] of Object.entries(opsMap)) {
|
||||
core.setAsyncHandler(opId, dispatchJson.asyncMsgFromRust);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(globalThis, {
|
||||
bootstrap: {
|
||||
value: {
|
||||
...globalThis.bootstrap,
|
||||
tsCompilerRuntime: bootstrapTsCompilerRuntime,
|
||||
},
|
||||
configurable: true,
|
||||
writable: true,
|
||||
},
|
||||
});
|
||||
function runtimeStart(source) {
|
||||
initOps();
|
||||
// First we send an empty `Start` message to let the privileged side know we
|
||||
// are ready. The response should be a `StartRes` message containing the CLI
|
||||
// args and other info.
|
||||
const s = dispatchJson.sendSync("op_start");
|
||||
util.setLogDebug(s.debugFlag, source);
|
||||
errorStack.setPrepareStackTrace(Error);
|
||||
return s;
|
||||
}
|
||||
|
||||
let hasBootstrapped = false;
|
||||
|
||||
function bootstrapCompilerRuntime() {
|
||||
if (hasBootstrapped) {
|
||||
throw new Error("Worker runtime already bootstrapped");
|
||||
}
|
||||
hasBootstrapped = true;
|
||||
globalThis.__bootstrap = undefined;
|
||||
runtimeStart("TS");
|
||||
}
|
||||
|
||||
globalThis.bootstrapCompilerRuntime = bootstrapCompilerRuntime;
|
||||
globalThis.tsCompilerOnMessage = tsCompilerOnMessage;
|
||||
})(this);
|
||||
|
|
Loading…
Reference in a new issue