1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00
denoland-deno/runtime/js/40_files.js
Bartek Iwańczuk b40086fd7d
refactor(core): include_js_files! 'dir' option doesn't change specifiers (#18019)
This commit changes "include_js_files!" macro from "deno_core"
in a way that "dir" option doesn't cause specifiers to be rewritten 
to include it.

Example:
```
include_js_files! {
  dir "js",
  "hello.js",
}
```

The above definition required embedders to use:
`import ... from "internal:<ext_name>/js/hello.js"`. 
But with this change, the "js" directory in which the files are stored
is an implementation detail, which for embedders results in: 
`import ... from "internal:<ext_name>/hello.js"`.

The directory the files are stored in, is an implementation detail and 
in some cases might result in a significant size difference for the 
snapshot. As an example, in "deno_node" extension, we store the 
source code in "polyfills" directory; which resulted in each specifier 
to look like "internal:deno_node/polyfills/<module_name>", but with 
this change it's "internal:deno_node/<module_name>". 

Given that "deno_node" has over 100 files, many of them having 
several import specifiers to the same extension, this change removes
10 characters from each import specifier.
2023-03-05 02:31:38 +00:00

299 lines
4.7 KiB
JavaScript

// 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,
};