Skip to content

Commit

Permalink
Merge branch 'main' into support-multiple-env-file-26425
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlomieju committed Nov 17, 2024
2 parents ac09628 + 73411bb commit df0cea4
Show file tree
Hide file tree
Showing 26 changed files with 411 additions and 50 deletions.
79 changes: 79 additions & 0 deletions cli/js/40_jupyter.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,52 @@ function isCanvasLike(obj) {
return obj !== null && typeof obj === "object" && "toDataURL" in obj;
}

function isJpg(obj) {
// Check if obj is a Uint8Array
if (!(obj instanceof Uint8Array)) {
return false;
}

// JPG files start with the magic bytes FF D8
if (obj.length < 2 || obj[0] !== 0xFF || obj[1] !== 0xD8) {
return false;
}

// JPG files end with the magic bytes FF D9
if (
obj.length < 2 || obj[obj.length - 2] !== 0xFF ||
obj[obj.length - 1] !== 0xD9
) {
return false;
}

return true;
}

function isPng(obj) {
// Check if obj is a Uint8Array
if (!(obj instanceof Uint8Array)) {
return false;
}

// PNG files start with a specific 8-byte signature
const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];

// Check if the array is at least as long as the signature
if (obj.length < pngSignature.length) {
return false;
}

// Check each byte of the signature
for (let i = 0; i < pngSignature.length; i++) {
if (obj[i] !== pngSignature[i]) {
return false;
}
}

return true;
}

/** Possible HTML and SVG Elements */
function isSVGElementLike(obj) {
return obj !== null && typeof obj === "object" && "outerHTML" in obj &&
Expand Down Expand Up @@ -233,6 +279,16 @@ async function format(obj) {
if (isDataFrameLike(obj)) {
return extractDataFrame(obj);
}
if (isJpg(obj)) {
return {
"image/jpeg": core.ops.op_base64_encode(obj),
};
}
if (isPng(obj)) {
return {
"image/png": core.ops.op_base64_encode(obj),
};
}
if (isSVGElementLike(obj)) {
return {
"image/svg+xml": obj.outerHTML,
Expand Down Expand Up @@ -314,6 +370,28 @@ const html = createTaggedTemplateDisplayable("text/html");
*/
const svg = createTaggedTemplateDisplayable("image/svg+xml");

function image(obj) {
if (typeof obj === "string") {
try {
obj = Deno.readFileSync(obj);
} catch {
// pass
}
}

if (isJpg(obj)) {
return makeDisplayable({ "image/jpeg": core.ops.op_base64_encode(obj) });
}

if (isPng(obj)) {
return makeDisplayable({ "image/png": core.ops.op_base64_encode(obj) });
}

throw new TypeError(
"Object is not a valid image or a path to an image. `Deno.jupyter.image` supports displaying JPG or PNG images.",
);
}

function isMediaBundle(obj) {
if (obj == null || typeof obj !== "object" || Array.isArray(obj)) {
return false;
Expand Down Expand Up @@ -465,6 +543,7 @@ function enableJupyter() {
md,
html,
svg,
image,
$display,
};
}
Expand Down
1 change: 1 addition & 0 deletions cli/tools/bench/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ pub async fn run_benchmarks_with_watch(
),
move |flags, watcher_communicator, changed_paths| {
let bench_flags = bench_flags.clone();
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags_for_watcher(
flags,
Expand Down
1 change: 1 addition & 0 deletions cli/tools/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub async fn format(
file_watcher::PrintConfig::new("Fmt", !watch_flags.no_clear_screen),
move |flags, watcher_communicator, changed_paths| {
let fmt_flags = fmt_flags.clone();
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags(flags);
let cli_options = factory.cli_options()?;
Expand Down
1 change: 1 addition & 0 deletions cli/tools/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub async fn lint(
file_watcher::PrintConfig::new("Lint", !watch_flags.no_clear_screen),
move |flags, watcher_communicator, changed_paths| {
let lint_flags = lint_flags.clone();
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags(flags);
let cli_options = factory.cli_options()?;
Expand Down
3 changes: 2 additions & 1 deletion cli/tools/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ async fn run_with_watch(
!watch_flags.no_clear_screen,
),
WatcherRestartMode::Automatic,
move |flags, watcher_communicator, _changed_paths| {
move |flags, watcher_communicator, changed_paths| {
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags_for_watcher(
flags,
Expand Down
3 changes: 2 additions & 1 deletion cli/tools/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ async fn serve_with_watch(
!watch_flags.no_clear_screen,
),
WatcherRestartMode::Automatic,
move |flags, watcher_communicator, _changed_paths| {
move |flags, watcher_communicator, changed_paths| {
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags_for_watcher(
flags,
Expand Down
1 change: 1 addition & 0 deletions cli/tools/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,7 @@ pub async fn run_tests_with_watch(
),
move |flags, watcher_communicator, changed_paths| {
let test_flags = test_flags.clone();
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags_for_watcher(
flags,
Expand Down
26 changes: 26 additions & 0 deletions cli/tsc/dts/lib.deno.unstable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,32 @@ declare namespace Deno {
...values: unknown[]
): Displayable;

/**
* Display a JPG or PNG image.
*
* ```
* Deno.jupyter.image("./cat.jpg");
* Deno.jupyter.image("./dog.png");
* ```
*
* @category Jupyter
* @experimental
*/
export function image(path: string): Displayable;

/**
* Display a JPG or PNG image.
*
* ```
* const img = Deno.readFileSync("./cat.jpg");
* Deno.jupyter.image(img);
* ```
*
* @category Jupyter
* @experimental
*/
export function image(data: Uint8Array): Displayable;

/**
* Format an object for displaying in Deno
*
Expand Down
21 changes: 11 additions & 10 deletions cli/util/file_watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,12 @@ impl PrintConfig {
}
}

fn create_print_after_restart_fn(
banner: &'static str,
clear_screen: bool,
) -> impl Fn() {
fn create_print_after_restart_fn(clear_screen: bool) -> impl Fn() {
move || {
#[allow(clippy::print_stderr)]
if clear_screen && std::io::stderr().is_terminal() {
eprint!("{}", CLEAR_SCREEN);
}
info!(
"{} File change detected! Restarting!",
colors::intense_blue(banner),
);
}
}

Expand Down Expand Up @@ -187,7 +180,15 @@ impl WatcherCommunicator {
}

pub fn print(&self, msg: String) {
log::info!("{} {}", self.banner, msg);
log::info!("{} {}", self.banner, colors::gray(msg));
}

pub fn show_path_changed(&self, changed_paths: Option<Vec<PathBuf>>) {
if let Some(paths) = changed_paths {
self.print(
format!("Restarting! File change detected: {:?}", paths[0]).to_string(),
)
}
}
}

Expand Down Expand Up @@ -263,7 +264,7 @@ where
clear_screen,
} = print_config;

let print_after_restart = create_print_after_restart_fn(banner, clear_screen);
let print_after_restart = create_print_after_restart_fn(clear_screen);
let watcher_communicator = Arc::new(WatcherCommunicator {
paths_to_watch_tx: paths_to_watch_tx.clone(),
changed_paths_rx: changed_paths_rx.resubscribe(),
Expand Down
2 changes: 1 addition & 1 deletion ext/net/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub mod ops_tls;
pub mod ops_unix;
pub mod raw;
pub mod resolve_addr;
mod tcp;
pub mod tcp;

use deno_core::error::AnyError;
use deno_core::OpState;
Expand Down
88 changes: 86 additions & 2 deletions ext/node/polyfills/timers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ import {
setUnrefTimeout,
Timeout,
} from "ext:deno_node/internal/timers.mjs";
import { validateFunction } from "ext:deno_node/internal/validators.mjs";
import {
validateAbortSignal,
validateBoolean,
validateFunction,
validateObject,
} from "ext:deno_node/internal/validators.mjs";
import { promisify } from "ext:deno_node/internal/util.mjs";
export { setUnrefTimeout } from "ext:deno_node/internal/timers.mjs";
import * as timers from "ext:deno_web/02_timers.js";
import { AbortError } from "ext:deno_node/internal/errors.ts";

const clearTimeout_ = timers.clearTimeout;
const clearInterval_ = timers.clearInterval;
Expand Down Expand Up @@ -89,10 +95,88 @@ export function clearImmediate(immediate: Immediate) {
clearTimeout_(immediate._immediateId);
}

async function* setIntervalAsync(
after: number,
value: number,
options: { signal?: AbortSignal; ref?: boolean } = { __proto__: null },
) {
validateObject(options, "options");

if (typeof options?.signal !== "undefined") {
validateAbortSignal(options.signal, "options.signal");
}

if (typeof options?.ref !== "undefined") {
validateBoolean(options.ref, "options.ref");
}

const { signal, ref = true } = options;

if (signal?.aborted) {
throw new AbortError(undefined, { cause: signal?.reason });
}

let onCancel: (() => void) | undefined = undefined;
let interval: Timeout | undefined = undefined;
try {
let notYielded = 0;
let callback: ((value?: object) => void) | undefined = undefined;
let rejectCallback: ((message?: string) => void) | undefined = undefined;
interval = new Timeout(
() => {
notYielded++;
if (callback) {
callback();
callback = undefined;
rejectCallback = undefined;
}
},
after,
[],
true,
ref,
);
if (signal) {
onCancel = () => {
clearInterval(interval);
if (rejectCallback) {
rejectCallback(signal.reason);
callback = undefined;
rejectCallback = undefined;
}
};
signal.addEventListener("abort", onCancel, { once: true });
}
while (!signal?.aborted) {
if (notYielded === 0) {
await new Promise((resolve: () => void, reject: () => void) => {
callback = resolve;
rejectCallback = reject;
});
}
for (; notYielded > 0; notYielded--) {
yield value;
}
}
} catch (error) {
if (signal?.aborted) {
throw new AbortError(undefined, { cause: signal?.reason });
}
throw error;
} finally {
if (interval) {
clearInterval(interval);
}
if (onCancel) {
signal?.removeEventListener("abort", onCancel);
}
}
}

export const promises = {
setTimeout: promisify(setTimeout),
setImmediate: promisify(setImmediate),
setInterval: promisify(setInterval),
setInterval: setIntervalAsync,
};

promises.scheduler = {
Expand Down
12 changes: 6 additions & 6 deletions ext/webgpu/01_webgpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -6982,6 +6982,12 @@ webidl.converters.GPUComputePassEncoder = webidl.createInterfaceConverter(
GPUComputePassEncoder.prototype,
);

// INTERFACE: GPUQuerySet
webidl.converters.GPUQuerySet = webidl.createInterfaceConverter(
"GPUQuerySet",
GPUQuerySet.prototype,
);

// DICTIONARY: GPUComputePassTimestampWrites
webidl.converters["GPUComputePassTimestampWrites"] = webidl
.createDictionaryConverter(
Expand Down Expand Up @@ -7154,12 +7160,6 @@ webidl.converters["GPURenderPassDepthStencilAttachment"] = webidl
dictMembersGPURenderPassDepthStencilAttachment,
);

// INTERFACE: GPUQuerySet
webidl.converters.GPUQuerySet = webidl.createInterfaceConverter(
"GPUQuerySet",
GPUQuerySet.prototype,
);

// DICTIONARY: GPURenderPassTimestampWrites
webidl.converters["GPURenderPassTimestampWrites"] = webidl
.createDictionaryConverter(
Expand Down
2 changes: 2 additions & 0 deletions runtime/js/99_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ const NOT_IMPORTED_OPS = [
// Related to `Deno.jupyter` API
"op_jupyter_broadcast",
"op_jupyter_input",
// Used in jupyter API
"op_base64_encode",

// Related to `Deno.test()` API
"op_test_event_step_result_failed",
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/watcher_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ where
let mut str = String::new();
while let Some(t) = next_line(stderr_lines).await {
let t = util::strip_ansi_codes(&t);
if t.starts_with("Watcher File change detected") {
if t.starts_with("Watcher Restarting! File change detected") {
continue;
}
if t.starts_with("Watcher") {
Expand Down
Loading

0 comments on commit df0cea4

Please sign in to comment.