1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-06 22:35:51 -05:00

refactor(runtime): remove 40_files.js, 40_write_file.js and 40_read_file.js (#18018)

JavaScript APIs from "runtime/js/40_files.js" combined abstractions
for stdio streams ("Stdout", "Stderr", "Stdin") and file system file
("File", "FsFile"). APIs from "runtime/js/40_read_file.js" and 
"runtime/js/40_write_file.js" were implemented using ops from 
"runtime/ops/fs.rs".

This file was removed and relevant APIs were moved to "deno_io/12_io.js"
and "runtime/js/30_fs.js".

This work is meant to enable factoring out "deno_fs" crate.
This commit is contained in:
Bartek Iwańczuk 2023-03-04 23:37:37 -04:00 committed by Yoshiya Hinosawa
parent 1b1de27958
commit dea5de1c45
13 changed files with 482 additions and 508 deletions

View file

@ -342,6 +342,7 @@ fn create_cli_snapshot(snapshot_path: PathBuf) {
deno_broadcast_channel::InMemoryBroadcastChannel::default(), deno_broadcast_channel::InMemoryBroadcastChannel::default(),
false, // No --unstable. false, // No --unstable.
), ),
deno_io::init(Default::default()),
deno_node::init::<PermissionsContainer>(None), // No --unstable. deno_node::init::<PermissionsContainer>(None), // No --unstable.
deno_node::init_polyfill(), deno_node::init_polyfill(),
deno_ffi::init::<PermissionsContainer>(false), deno_ffi::init::<PermissionsContainer>(false),
@ -351,7 +352,6 @@ fn create_cli_snapshot(snapshot_path: PathBuf) {
), ),
deno_napi::init::<PermissionsContainer>(), deno_napi::init::<PermissionsContainer>(),
deno_http::init(), deno_http::init(),
deno_io::init(Default::default()),
deno_flash::init::<PermissionsContainer>(false), // No --unstable deno_flash::init::<PermissionsContainer>(false), // No --unstable
]; ];

View file

@ -7,6 +7,10 @@
const core = globalThis.Deno.core; const core = globalThis.Deno.core;
const ops = core.ops; const ops = core.ops;
const primordials = globalThis.__bootstrap.primordials; const primordials = globalThis.__bootstrap.primordials;
import {
readableStreamForRid,
writableStreamForRid,
} from "internal:deno_web/06_streams.js";
const { const {
Uint8Array, Uint8Array,
ArrayPrototypePush, ArrayPrototypePush,
@ -221,6 +225,105 @@ async function readAllInnerSized(r, size, options) {
} }
} }
class Stdin {
#readable;
constructor() {
}
get rid() {
return 0;
}
read(p) {
return read(this.rid, p);
}
readSync(p) {
return readSync(this.rid, p);
}
close() {
core.close(this.rid);
}
get readable() {
if (this.#readable === undefined) {
this.#readable = readableStreamForRid(this.rid);
}
return this.#readable;
}
setRaw(mode, options = {}) {
const cbreak = !!(options.cbreak ?? false);
ops.op_stdin_set_raw(mode, cbreak);
}
}
class Stdout {
#writable;
constructor() {
}
get rid() {
return 1;
}
write(p) {
return write(this.rid, p);
}
writeSync(p) {
return writeSync(this.rid, p);
}
close() {
core.close(this.rid);
}
get writable() {
if (this.#writable === undefined) {
this.#writable = writableStreamForRid(this.rid);
}
return this.#writable;
}
}
class Stderr {
#writable;
constructor() {
}
get rid() {
return 2;
}
write(p) {
return write(this.rid, p);
}
writeSync(p) {
return writeSync(this.rid, p);
}
close() {
core.close(this.rid);
}
get writable() {
if (this.#writable === undefined) {
this.#writable = writableStreamForRid(this.rid);
}
return this.#writable;
}
}
const stdin = new Stdin();
const stdout = new Stdout();
const stderr = new Stderr();
export { export {
copy, copy,
iter, iter,
@ -233,6 +336,9 @@ export {
readAllSyncSized, readAllSyncSized,
readSync, readSync,
SeekMode, SeekMode,
stderr,
stdin,
stdout,
write, write,
writeSync, writeSync,
}; };

View file

@ -365,6 +365,7 @@ pub fn init_polyfill() -> Extension {
Extension::builder(env!("CARGO_PKG_NAME")) Extension::builder(env!("CARGO_PKG_NAME"))
.esm(esm_files) .esm(esm_files)
.esm_entry_point("internal:deno_node/module_all.ts") .esm_entry_point("internal:deno_node/module_all.ts")
.dependencies(vec!["deno_io"])
.ops(vec![ .ops(vec![
crypto::op_node_create_hash::decl(), crypto::op_node_create_hash::decl(),
crypto::op_node_hash_update::decl(), crypto::op_node_hash_update::decl(),

View file

@ -11,7 +11,7 @@ import {
import { Duplex, Readable, Writable } from "internal:deno_node/stream.ts"; import { Duplex, Readable, Writable } from "internal:deno_node/stream.ts";
import { isWindows } from "internal:deno_node/_util/os.ts"; import { isWindows } from "internal:deno_node/_util/os.ts";
import { fs as fsConstants } from "internal:deno_node/internal_binding/constants.ts"; import { fs as fsConstants } from "internal:deno_node/internal_binding/constants.ts";
import * as files from "internal:runtime/40_files.js"; import * as io from "internal:deno_io/12_io.js";
// https://github.com/nodejs/node/blob/00738314828074243c9a52a228ab4c68b04259ef/lib/internal/bootstrap/switches/is_main_thread.js#L41 // https://github.com/nodejs/node/blob/00738314828074243c9a52a228ab4c68b04259ef/lib/internal/bootstrap/switches/is_main_thread.js#L41
export function createWritableStdioStream(writer, name) { export function createWritableStdioStream(writer, name) {
@ -140,7 +140,7 @@ function _guessStdinType(fd) {
const _read = function (size) { const _read = function (size) {
const p = Buffer.alloc(size || 16 * 1024); const p = Buffer.alloc(size || 16 * 1024);
files.stdin?.read(p).then((length) => { io.stdin?.read(p).then((length) => {
this.push(length === null ? null : p.slice(0, length)); this.push(length === null ? null : p.slice(0, length));
}, (error) => { }, (error) => {
this.destroy(error); this.destroy(error);
@ -151,7 +151,7 @@ const _read = function (size) {
// https://github.com/nodejs/node/blob/v18.12.1/lib/internal/bootstrap/switches/is_main_thread.js#L189 // https://github.com/nodejs/node/blob/v18.12.1/lib/internal/bootstrap/switches/is_main_thread.js#L189
/** Create process.stdin */ /** Create process.stdin */
export const initStdin = () => { export const initStdin = () => {
const fd = files.stdin?.rid; const fd = io.stdin?.rid;
let stdin; let stdin;
const stdinType = _guessStdinType(fd); const stdinType = _guessStdinType(fd);
@ -210,8 +210,8 @@ export const initStdin = () => {
} }
} }
stdin.on("close", () => files.stdin?.close()); stdin.on("close", () => io.stdin?.close());
stdin.fd = files.stdin?.rid ?? -1; stdin.fd = io.stdin?.rid ?? -1;
Object.defineProperty(stdin, "isTTY", { Object.defineProperty(stdin, "isTTY", {
enumerable: true, enumerable: true,
configurable: true, configurable: true,
@ -221,7 +221,7 @@ export const initStdin = () => {
}); });
stdin._isRawMode = false; stdin._isRawMode = false;
stdin.setRawMode = (enable) => { stdin.setRawMode = (enable) => {
files.stdin?.setRaw?.(enable); io.stdin?.setRaw?.(enable);
stdin._isRawMode = enable; stdin._isRawMode = enable;
return stdin; return stdin;
}; };

View file

@ -38,7 +38,7 @@ import {
runNextTicks, runNextTicks,
} from "internal:deno_node/_next_tick.ts"; } from "internal:deno_node/_next_tick.ts";
import { isWindows } from "internal:deno_node/_util/os.ts"; import { isWindows } from "internal:deno_node/_util/os.ts";
import * as files from "internal:runtime/40_files.js"; import * as io from "internal:deno_io/12_io.js";
// TODO(kt3k): This should be set at start up time // TODO(kt3k): This should be set at start up time
export let arch = ""; export let arch = "";
@ -755,13 +755,13 @@ internals.__bootstrapNodeProcess = function (
/** https://nodejs.org/api/process.html#process_process_stderr */ /** https://nodejs.org/api/process.html#process_process_stderr */
stderr = process.stderr = createWritableStdioStream( stderr = process.stderr = createWritableStdioStream(
files.stderr, io.stderr,
"stderr", "stderr",
); );
/** https://nodejs.org/api/process.html#process_process_stdout */ /** https://nodejs.org/api/process.html#process_process_stdout */
stdout = process.stdout = createWritableStdioStream( stdout = process.stdout = createWritableStdioStream(
files.stdout, io.stdout,
"stdout", "stdout",
); );

View file

@ -203,15 +203,12 @@ mod startup_snapshot {
"13_buffer.js", "13_buffer.js",
"30_fs.js", "30_fs.js",
"30_os.js", "30_os.js",
"40_files.js",
"40_fs_events.js", "40_fs_events.js",
"40_http.js", "40_http.js",
"40_process.js", "40_process.js",
"40_read_file.js",
"40_signals.js", "40_signals.js",
"40_spawn.js", "40_spawn.js",
"40_tty.js", "40_tty.js",
"40_write_file.js",
"41_prompt.js", "41_prompt.js",
"90_deno_ns.js", "90_deno_ns.js",
"98_global_scope.js", "98_global_scope.js",

View file

@ -4,16 +4,26 @@ const core = globalThis.Deno.core;
const ops = core.ops; const ops = core.ops;
const primordials = globalThis.__bootstrap.primordials; const primordials = globalThis.__bootstrap.primordials;
const { const {
ArrayPrototypeFilter,
Date, Date,
DatePrototype, DatePrototype,
Error,
Function,
MathTrunc, MathTrunc,
ObjectEntries,
ObjectPrototypeIsPrototypeOf, ObjectPrototypeIsPrototypeOf,
ObjectValues,
SymbolAsyncIterator, SymbolAsyncIterator,
SymbolIterator, SymbolIterator,
Function,
ObjectEntries,
Uint32Array, Uint32Array,
} = primordials; } = primordials;
import { read, readSync, write, writeSync } from "internal:deno_io/12_io.js";
import * as abortSignal from "internal:deno_web/03_abort_signal.js";
import {
readableStreamForRid,
ReadableStreamPrototype,
writableStreamForRid,
} from "internal:deno_web/06_streams.js";
import { pathFromURL } from "internal:runtime/06_util.js"; import { pathFromURL } from "internal:runtime/06_util.js";
import { build } from "internal:runtime/01_build.js"; import { build } from "internal:runtime/01_build.js";
@ -503,6 +513,322 @@ async function funlock(rid) {
await core.opAsync("op_funlock_async", rid); await core.opAsync("op_funlock_async", rid);
} }
function seekSync(
rid,
offset,
whence,
) {
return ops.op_seek_sync({ rid, offset, whence });
}
function seek(
rid,
offset,
whence,
) {
return core.opAsync("op_seek_async", { rid, offset, whence });
}
function openSync(
path,
options,
) {
if (options) checkOpenOptions(options);
const mode = options?.mode;
const rid = ops.op_open_sync(
pathFromURL(path),
options,
mode,
);
return new FsFile(rid);
}
async function open(
path,
options,
) {
if (options) checkOpenOptions(options);
const mode = options?.mode;
const rid = await core.opAsync(
"op_open_async",
pathFromURL(path),
options,
mode,
);
return new FsFile(rid);
}
function createSync(path) {
return openSync(path, {
read: true,
write: true,
truncate: true,
create: true,
});
}
function create(path) {
return open(path, {
read: true,
write: true,
truncate: true,
create: true,
});
}
class FsFile {
#rid = 0;
#readable;
#writable;
constructor(rid) {
this.#rid = rid;
}
get rid() {
return this.#rid;
}
write(p) {
return write(this.rid, p);
}
writeSync(p) {
return writeSync(this.rid, p);
}
truncate(len) {
return ftruncate(this.rid, len);
}
truncateSync(len) {
return ftruncateSync(this.rid, len);
}
read(p) {
return read(this.rid, p);
}
readSync(p) {
return readSync(this.rid, p);
}
seek(offset, whence) {
return seek(this.rid, offset, whence);
}
seekSync(offset, whence) {
return seekSync(this.rid, offset, whence);
}
stat() {
return fstat(this.rid);
}
statSync() {
return fstatSync(this.rid);
}
close() {
core.close(this.rid);
}
get readable() {
if (this.#readable === undefined) {
this.#readable = readableStreamForRid(this.rid);
}
return this.#readable;
}
get writable() {
if (this.#writable === undefined) {
this.#writable = writableStreamForRid(this.rid);
}
return this.#writable;
}
}
function checkOpenOptions(options) {
if (
ArrayPrototypeFilter(
ObjectValues(options),
(val) => val === true,
).length === 0
) {
throw new Error("OpenOptions requires at least one option to be true");
}
if (options.truncate && !options.write) {
throw new Error("'truncate' option requires 'write' option");
}
const createOrCreateNewWithoutWriteOrAppend =
(options.create || options.createNew) &&
!(options.write || options.append);
if (createOrCreateNewWithoutWriteOrAppend) {
throw new Error(
"'create' or 'createNew' options require 'write' or 'append' option",
);
}
}
const File = FsFile;
function readFileSync(path) {
return ops.op_readfile_sync(pathFromURL(path));
}
async function readFile(path, options) {
let cancelRid;
let abortHandler;
if (options?.signal) {
options.signal.throwIfAborted();
cancelRid = ops.op_cancel_handle();
abortHandler = () => core.tryClose(cancelRid);
options.signal[abortSignal.add](abortHandler);
}
try {
const read = await core.opAsync(
"op_readfile_async",
pathFromURL(path),
cancelRid,
);
return read;
} finally {
if (options?.signal) {
options.signal[abortSignal.remove](abortHandler);
// always throw the abort error when aborted
options.signal.throwIfAborted();
}
}
}
function readTextFileSync(path) {
return ops.op_readfile_text_sync(pathFromURL(path));
}
async function readTextFile(path, options) {
let cancelRid;
let abortHandler;
if (options?.signal) {
options.signal.throwIfAborted();
cancelRid = ops.op_cancel_handle();
abortHandler = () => core.tryClose(cancelRid);
options.signal[abortSignal.add](abortHandler);
}
try {
const read = await core.opAsync(
"op_readfile_text_async",
pathFromURL(path),
cancelRid,
);
return read;
} finally {
if (options?.signal) {
options.signal[abortSignal.remove](abortHandler);
// always throw the abort error when aborted
options.signal.throwIfAborted();
}
}
}
function writeFileSync(
path,
data,
options = {},
) {
options.signal?.throwIfAborted();
ops.op_write_file_sync(
pathFromURL(path),
options.mode,
options.append ?? false,
options.create ?? true,
options.createNew ?? false,
data,
);
}
async function writeFile(
path,
data,
options = {},
) {
let cancelRid;
let abortHandler;
if (options.signal) {
options.signal.throwIfAborted();
cancelRid = ops.op_cancel_handle();
abortHandler = () => core.tryClose(cancelRid);
options.signal[abortSignal.add](abortHandler);
}
try {
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
const file = await open(path, {
mode: options.mode,
append: options.append ?? false,
create: options.create ?? true,
createNew: options.createNew ?? false,
write: true,
});
await data.pipeTo(file.writable, {
signal: options.signal,
});
} else {
await core.opAsync(
"op_write_file_async",
pathFromURL(path),
options.mode,
options.append ?? false,
options.create ?? true,
options.createNew ?? false,
data,
cancelRid,
);
}
} finally {
if (options.signal) {
options.signal[abortSignal.remove](abortHandler);
// always throw the abort error when aborted
options.signal.throwIfAborted();
}
}
}
function writeTextFileSync(
path,
data,
options = {},
) {
const encoder = new TextEncoder();
return writeFileSync(path, encoder.encode(data), options);
}
function writeTextFile(
path,
data,
options = {},
) {
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
return writeFile(
path,
data.pipeThrough(new TextEncoderStream()),
options,
);
} else {
const encoder = new TextEncoder();
return writeFile(path, encoder.encode(data), options);
}
}
export { export {
chdir, chdir,
chmod, chmod,
@ -511,11 +837,15 @@ export {
chownSync, chownSync,
copyFile, copyFile,
copyFileSync, copyFileSync,
create,
createSync,
cwd, cwd,
fdatasync, fdatasync,
fdatasyncSync, fdatasyncSync,
File,
flock, flock,
flockSync, flockSync,
FsFile,
fstat, fstat,
fstatSync, fstatSync,
fsync, fsync,
@ -536,16 +866,24 @@ export {
makeTempFileSync, makeTempFileSync,
mkdir, mkdir,
mkdirSync, mkdirSync,
open,
openSync,
readDir, readDir,
readDirSync, readDirSync,
readFile,
readFileSync,
readLink, readLink,
readLinkSync, readLinkSync,
readTextFile,
readTextFileSync,
realPath, realPath,
realPathSync, realPathSync,
remove, remove,
removeSync, removeSync,
rename, rename,
renameSync, renameSync,
seek,
seekSync,
stat, stat,
statSync, statSync,
symlink, symlink,
@ -555,4 +893,8 @@ export {
umask, umask,
utime, utime,
utimeSync, utimeSync,
writeFile,
writeFileSync,
writeTextFile,
writeTextFileSync,
}; };

View file

@ -1,299 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
const core = globalThis.Deno.core;
const ops = core.ops;
import { read, readSync, write, writeSync } from "internal:deno_io/12_io.js";
import {
fstat,
fstatSync,
ftruncate,
ftruncateSync,
} from "internal:runtime/30_fs.js";
import { pathFromURL } from "internal:runtime/06_util.js";
import {
readableStreamForRid,
writableStreamForRid,
} from "internal:deno_web/06_streams.js";
const primordials = globalThis.__bootstrap.primordials;
const {
ArrayPrototypeFilter,
Error,
ObjectValues,
} = primordials;
function seekSync(
rid,
offset,
whence,
) {
return ops.op_seek_sync({ rid, offset, whence });
}
function seek(
rid,
offset,
whence,
) {
return core.opAsync("op_seek_async", { rid, offset, whence });
}
function openSync(
path,
options,
) {
if (options) checkOpenOptions(options);
const mode = options?.mode;
const rid = ops.op_open_sync(
pathFromURL(path),
options,
mode,
);
return new FsFile(rid);
}
async function open(
path,
options,
) {
if (options) checkOpenOptions(options);
const mode = options?.mode;
const rid = await core.opAsync(
"op_open_async",
pathFromURL(path),
options,
mode,
);
return new FsFile(rid);
}
function createSync(path) {
return openSync(path, {
read: true,
write: true,
truncate: true,
create: true,
});
}
function create(path) {
return open(path, {
read: true,
write: true,
truncate: true,
create: true,
});
}
class FsFile {
#rid = 0;
#readable;
#writable;
constructor(rid) {
this.#rid = rid;
}
get rid() {
return this.#rid;
}
write(p) {
return write(this.rid, p);
}
writeSync(p) {
return writeSync(this.rid, p);
}
truncate(len) {
return ftruncate(this.rid, len);
}
truncateSync(len) {
return ftruncateSync(this.rid, len);
}
read(p) {
return read(this.rid, p);
}
readSync(p) {
return readSync(this.rid, p);
}
seek(offset, whence) {
return seek(this.rid, offset, whence);
}
seekSync(offset, whence) {
return seekSync(this.rid, offset, whence);
}
stat() {
return fstat(this.rid);
}
statSync() {
return fstatSync(this.rid);
}
close() {
core.close(this.rid);
}
get readable() {
if (this.#readable === undefined) {
this.#readable = readableStreamForRid(this.rid);
}
return this.#readable;
}
get writable() {
if (this.#writable === undefined) {
this.#writable = writableStreamForRid(this.rid);
}
return this.#writable;
}
}
class Stdin {
#readable;
constructor() {
}
get rid() {
return 0;
}
read(p) {
return read(this.rid, p);
}
readSync(p) {
return readSync(this.rid, p);
}
close() {
core.close(this.rid);
}
get readable() {
if (this.#readable === undefined) {
this.#readable = readableStreamForRid(this.rid);
}
return this.#readable;
}
setRaw(mode, options = {}) {
const cbreak = !!(options.cbreak ?? false);
ops.op_stdin_set_raw(mode, cbreak);
}
}
class Stdout {
#writable;
constructor() {
}
get rid() {
return 1;
}
write(p) {
return write(this.rid, p);
}
writeSync(p) {
return writeSync(this.rid, p);
}
close() {
core.close(this.rid);
}
get writable() {
if (this.#writable === undefined) {
this.#writable = writableStreamForRid(this.rid);
}
return this.#writable;
}
}
class Stderr {
#writable;
constructor() {
}
get rid() {
return 2;
}
write(p) {
return write(this.rid, p);
}
writeSync(p) {
return writeSync(this.rid, p);
}
close() {
core.close(this.rid);
}
get writable() {
if (this.#writable === undefined) {
this.#writable = writableStreamForRid(this.rid);
}
return this.#writable;
}
}
const stdin = new Stdin();
const stdout = new Stdout();
const stderr = new Stderr();
function checkOpenOptions(options) {
if (
ArrayPrototypeFilter(
ObjectValues(options),
(val) => val === true,
).length === 0
) {
throw new Error("OpenOptions requires at least one option to be true");
}
if (options.truncate && !options.write) {
throw new Error("'truncate' option requires 'write' option");
}
const createOrCreateNewWithoutWriteOrAppend =
(options.create || options.createNew) &&
!(options.write || options.append);
if (createOrCreateNewWithoutWriteOrAppend) {
throw new Error(
"'create' or 'createNew' options require 'write' or 'append' option",
);
}
}
const File = FsFile;
export {
create,
createSync,
File,
FsFile,
open,
openSync,
seek,
seekSync,
stderr,
stdin,
stdout,
};

View file

@ -2,7 +2,7 @@
const core = globalThis.Deno.core; const core = globalThis.Deno.core;
const ops = core.ops; const ops = core.ops;
import { FsFile } from "internal:runtime/40_files.js"; import { FsFile } from "internal:runtime/30_fs.js";
import { readAll } from "internal:deno_io/12_io.js"; import { readAll } from "internal:deno_io/12_io.js";
import { pathFromURL } from "internal:runtime/06_util.js"; import { pathFromURL } from "internal:runtime/06_util.js";
import { assert } from "internal:deno_web/00_infra.js"; import { assert } from "internal:deno_web/00_infra.js";

View file

@ -1,70 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
const core = globalThis.Deno.core;
const ops = core.ops;
import { pathFromURL } from "internal:runtime/06_util.js";
import * as abortSignal from "internal:deno_web/03_abort_signal.js";
function readFileSync(path) {
return ops.op_readfile_sync(pathFromURL(path));
}
async function readFile(path, options) {
let cancelRid;
let abortHandler;
if (options?.signal) {
options.signal.throwIfAborted();
cancelRid = ops.op_cancel_handle();
abortHandler = () => core.tryClose(cancelRid);
options.signal[abortSignal.add](abortHandler);
}
try {
const read = await core.opAsync(
"op_readfile_async",
pathFromURL(path),
cancelRid,
);
return read;
} finally {
if (options?.signal) {
options.signal[abortSignal.remove](abortHandler);
// always throw the abort error when aborted
options.signal.throwIfAborted();
}
}
}
function readTextFileSync(path) {
return ops.op_readfile_text_sync(pathFromURL(path));
}
async function readTextFile(path, options) {
let cancelRid;
let abortHandler;
if (options?.signal) {
options.signal.throwIfAborted();
cancelRid = ops.op_cancel_handle();
abortHandler = () => core.tryClose(cancelRid);
options.signal[abortSignal.add](abortHandler);
}
try {
const read = await core.opAsync(
"op_readfile_text_async",
pathFromURL(path),
cancelRid,
);
return read;
} finally {
if (options?.signal) {
options.signal[abortSignal.remove](abortHandler);
// always throw the abort error when aborted
options.signal.throwIfAborted();
}
}
}
export { readFile, readFileSync, readTextFile, readTextFileSync };

View file

@ -1,100 +0,0 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
const core = globalThis.Deno.core;
const ops = core.ops;
const primordials = globalThis.__bootstrap.primordials;
import * as abortSignal from "internal:deno_web/03_abort_signal.js";
import { pathFromURL } from "internal:runtime/06_util.js";
import { open } from "internal:runtime/40_files.js";
import { ReadableStreamPrototype } from "internal:deno_web/06_streams.js";
const { ObjectPrototypeIsPrototypeOf } = primordials;
function writeFileSync(
path,
data,
options = {},
) {
options.signal?.throwIfAborted();
ops.op_write_file_sync(
pathFromURL(path),
options.mode,
options.append ?? false,
options.create ?? true,
options.createNew ?? false,
data,
);
}
async function writeFile(
path,
data,
options = {},
) {
let cancelRid;
let abortHandler;
if (options.signal) {
options.signal.throwIfAborted();
cancelRid = ops.op_cancel_handle();
abortHandler = () => core.tryClose(cancelRid);
options.signal[abortSignal.add](abortHandler);
}
try {
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
const file = await open(path, {
mode: options.mode,
append: options.append ?? false,
create: options.create ?? true,
createNew: options.createNew ?? false,
write: true,
});
await data.pipeTo(file.writable, {
signal: options.signal,
});
} else {
await core.opAsync(
"op_write_file_async",
pathFromURL(path),
options.mode,
options.append ?? false,
options.create ?? true,
options.createNew ?? false,
data,
cancelRid,
);
}
} finally {
if (options.signal) {
options.signal[abortSignal.remove](abortHandler);
// always throw the abort error when aborted
options.signal.throwIfAborted();
}
}
}
function writeTextFileSync(
path,
data,
options = {},
) {
const encoder = new TextEncoder();
return writeFileSync(path, encoder.encode(data), options);
}
function writeTextFile(
path,
data,
options = {},
) {
if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, data)) {
return writeFile(
path,
data.pipeThrough(new TextEncoderStream()),
options,
);
} else {
const encoder = new TextEncoder();
return writeFile(path, encoder.encode(data), options);
}
}
export { writeFile, writeFileSync, writeTextFile, writeTextFileSync };

View file

@ -2,7 +2,7 @@
const core = globalThis.Deno.core; const core = globalThis.Deno.core;
const primordials = globalThis.__bootstrap.primordials; const primordials = globalThis.__bootstrap.primordials;
import { isatty } from "internal:runtime/40_tty.js"; import { isatty } from "internal:runtime/40_tty.js";
import { stdin } from "internal:runtime/40_files.js"; import { stdin } from "internal:deno_io/12_io.js";
const { ArrayPrototypePush, StringPrototypeCharCodeAt, Uint8Array } = const { ArrayPrototypePush, StringPrototypeCharCodeAt, Uint8Array } =
primordials; primordials;
const LF = StringPrototypeCharCodeAt("\n", 0); const LF = StringPrototypeCharCodeAt("\n", 0);

View file

@ -18,13 +18,10 @@ import * as io from "internal:deno_io/12_io.js";
import * as buffer from "internal:runtime/13_buffer.js"; import * as buffer from "internal:runtime/13_buffer.js";
import * as fs from "internal:runtime/30_fs.js"; import * as fs from "internal:runtime/30_fs.js";
import * as os from "internal:runtime/30_os.js"; import * as os from "internal:runtime/30_os.js";
import * as files from "internal:runtime/40_files.js";
import * as fsEvents from "internal:runtime/40_fs_events.js"; import * as fsEvents from "internal:runtime/40_fs_events.js";
import * as process from "internal:runtime/40_process.js"; import * as process from "internal:runtime/40_process.js";
import * as readFile from "internal:runtime/40_read_file.js";
import * as signals from "internal:runtime/40_signals.js"; import * as signals from "internal:runtime/40_signals.js";
import * as tty from "internal:runtime/40_tty.js"; import * as tty from "internal:runtime/40_tty.js";
import * as writeFile from "internal:runtime/40_write_file.js";
import * as spawn from "internal:runtime/40_spawn.js"; import * as spawn from "internal:runtime/40_spawn.js";
// TODO(bartlomieju): this is funky we have two `http` imports // TODO(bartlomieju): this is funky we have two `http` imports
import * as httpRuntime from "internal:runtime/40_http.js"; import * as httpRuntime from "internal:runtime/40_http.js";
@ -34,14 +31,14 @@ const denoNs = {
Process: process.Process, Process: process.Process,
run: process.run, run: process.run,
isatty: tty.isatty, isatty: tty.isatty,
writeFileSync: writeFile.writeFileSync, writeFileSync: fs.writeFileSync,
writeFile: writeFile.writeFile, writeFile: fs.writeFile,
writeTextFileSync: writeFile.writeTextFileSync, writeTextFileSync: fs.writeTextFileSync,
writeTextFile: writeFile.writeTextFile, writeTextFile: fs.writeTextFile,
readTextFile: readFile.readTextFile, readTextFile: fs.readTextFile,
readTextFileSync: readFile.readTextFileSync, readTextFileSync: fs.readTextFileSync,
readFile: readFile.readFile, readFile: fs.readFile,
readFileSync: readFile.readFileSync, readFileSync: fs.readFileSync,
watchFs: fsEvents.watchFs, watchFs: fsEvents.watchFs,
chmodSync: fs.chmodSync, chmodSync: fs.chmodSync,
chmod: fs.chmod, chmod: fs.chmod,
@ -101,17 +98,17 @@ const denoNs = {
readSync: io.readSync, readSync: io.readSync,
write: io.write, write: io.write,
writeSync: io.writeSync, writeSync: io.writeSync,
File: files.File, File: fs.File,
FsFile: files.FsFile, FsFile: fs.FsFile,
open: files.open, open: fs.open,
openSync: files.openSync, openSync: fs.openSync,
create: files.create, create: fs.create,
createSync: files.createSync, createSync: fs.createSync,
stdin: files.stdin, stdin: io.stdin,
stdout: files.stdout, stdout: io.stdout,
stderr: files.stderr, stderr: io.stderr,
seek: files.seek, seek: fs.seek,
seekSync: files.seekSync, seekSync: fs.seekSync,
connect: net.connect, connect: net.connect,
listen: net.listen, listen: net.listen,
loadavg: os.loadavg, loadavg: os.loadavg,