mirror of
https://github.com/denoland/deno.git
synced 2024-12-25 16:49:18 -05:00
refactor: add deno_file op crate (#10019)
Also enables WPT for FileReader.
This commit is contained in:
parent
ff5d072702
commit
00e63306cb
23 changed files with 470 additions and 321 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -616,6 +616,13 @@ dependencies = [
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deno_file"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"deno_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_lint"
|
name = "deno_lint"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
|
@ -643,6 +650,7 @@ dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_crypto",
|
"deno_crypto",
|
||||||
"deno_fetch",
|
"deno_fetch",
|
||||||
|
"deno_file",
|
||||||
"deno_url",
|
"deno_url",
|
||||||
"deno_web",
|
"deno_web",
|
||||||
"deno_webgpu",
|
"deno_webgpu",
|
||||||
|
|
|
@ -11,6 +11,7 @@ use deno_core::RuntimeOptions;
|
||||||
use deno_runtime::deno_console;
|
use deno_runtime::deno_console;
|
||||||
use deno_runtime::deno_crypto;
|
use deno_runtime::deno_crypto;
|
||||||
use deno_runtime::deno_fetch;
|
use deno_runtime::deno_fetch;
|
||||||
|
use deno_runtime::deno_file;
|
||||||
use deno_runtime::deno_url;
|
use deno_runtime::deno_url;
|
||||||
use deno_runtime::deno_web;
|
use deno_runtime::deno_web;
|
||||||
use deno_runtime::deno_webgpu;
|
use deno_runtime::deno_webgpu;
|
||||||
|
@ -66,6 +67,7 @@ fn create_compiler_snapshot(
|
||||||
op_crate_libs.insert("deno.console", deno_console::get_declaration());
|
op_crate_libs.insert("deno.console", deno_console::get_declaration());
|
||||||
op_crate_libs.insert("deno.url", deno_url::get_declaration());
|
op_crate_libs.insert("deno.url", deno_url::get_declaration());
|
||||||
op_crate_libs.insert("deno.web", deno_web::get_declaration());
|
op_crate_libs.insert("deno.web", deno_web::get_declaration());
|
||||||
|
op_crate_libs.insert("deno.file", deno_file::get_declaration());
|
||||||
op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration());
|
op_crate_libs.insert("deno.fetch", deno_fetch::get_declaration());
|
||||||
op_crate_libs.insert("deno.webgpu", deno_webgpu::get_declaration());
|
op_crate_libs.insert("deno.webgpu", deno_webgpu::get_declaration());
|
||||||
op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration());
|
op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration());
|
||||||
|
@ -270,6 +272,10 @@ fn main() {
|
||||||
"cargo:rustc-env=DENO_WEB_LIB_PATH={}",
|
"cargo:rustc-env=DENO_WEB_LIB_PATH={}",
|
||||||
deno_web::get_declaration().display()
|
deno_web::get_declaration().display()
|
||||||
);
|
);
|
||||||
|
println!(
|
||||||
|
"cargo:rustc-env=DENO_FILE_LIB_PATH={}",
|
||||||
|
deno_file::get_declaration().display()
|
||||||
|
);
|
||||||
println!(
|
println!(
|
||||||
"cargo:rustc-env=DENO_FETCH_LIB_PATH={}",
|
"cargo:rustc-env=DENO_FETCH_LIB_PATH={}",
|
||||||
deno_fetch::get_declaration().display()
|
deno_fetch::get_declaration().display()
|
||||||
|
|
1
cli/dts/lib.deno.shared_globals.d.ts
vendored
1
cli/dts/lib.deno.shared_globals.d.ts
vendored
|
@ -6,6 +6,7 @@
|
||||||
/// <reference no-default-lib="true" />
|
/// <reference no-default-lib="true" />
|
||||||
/// <reference lib="esnext" />
|
/// <reference lib="esnext" />
|
||||||
/// <reference lib="deno.console" />
|
/// <reference lib="deno.console" />
|
||||||
|
/// <reference lib="deno.file" />
|
||||||
/// <reference lib="deno.url" />
|
/// <reference lib="deno.url" />
|
||||||
/// <reference lib="deno.web" />
|
/// <reference lib="deno.web" />
|
||||||
/// <reference lib="deno.fetch" />
|
/// <reference lib="deno.fetch" />
|
||||||
|
|
|
@ -275,11 +275,12 @@ fn print_cache_info(
|
||||||
|
|
||||||
pub fn get_types(unstable: bool) -> String {
|
pub fn get_types(unstable: bool) -> String {
|
||||||
let mut types = format!(
|
let mut types = format!(
|
||||||
"{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
|
"{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}",
|
||||||
crate::tsc::DENO_NS_LIB,
|
crate::tsc::DENO_NS_LIB,
|
||||||
crate::tsc::DENO_CONSOLE_LIB,
|
crate::tsc::DENO_CONSOLE_LIB,
|
||||||
crate::tsc::DENO_URL_LIB,
|
crate::tsc::DENO_URL_LIB,
|
||||||
crate::tsc::DENO_WEB_LIB,
|
crate::tsc::DENO_WEB_LIB,
|
||||||
|
crate::tsc::DENO_FILE_LIB,
|
||||||
crate::tsc::DENO_FETCH_LIB,
|
crate::tsc::DENO_FETCH_LIB,
|
||||||
crate::tsc::DENO_WEBGPU_LIB,
|
crate::tsc::DENO_WEBGPU_LIB,
|
||||||
crate::tsc::DENO_WEBSOCKET_LIB,
|
crate::tsc::DENO_WEBSOCKET_LIB,
|
||||||
|
|
|
@ -32,6 +32,7 @@ pub static DENO_NS_LIB: &str = include_str!("dts/lib.deno.ns.d.ts");
|
||||||
pub static DENO_CONSOLE_LIB: &str = include_str!(env!("DENO_CONSOLE_LIB_PATH"));
|
pub static DENO_CONSOLE_LIB: &str = include_str!(env!("DENO_CONSOLE_LIB_PATH"));
|
||||||
pub static DENO_URL_LIB: &str = include_str!(env!("DENO_URL_LIB_PATH"));
|
pub static DENO_URL_LIB: &str = include_str!(env!("DENO_URL_LIB_PATH"));
|
||||||
pub static DENO_WEB_LIB: &str = include_str!(env!("DENO_WEB_LIB_PATH"));
|
pub static DENO_WEB_LIB: &str = include_str!(env!("DENO_WEB_LIB_PATH"));
|
||||||
|
pub static DENO_FILE_LIB: &str = include_str!(env!("DENO_FILE_LIB_PATH"));
|
||||||
pub static DENO_FETCH_LIB: &str = include_str!(env!("DENO_FETCH_LIB_PATH"));
|
pub static DENO_FETCH_LIB: &str = include_str!(env!("DENO_FETCH_LIB_PATH"));
|
||||||
pub static DENO_WEBGPU_LIB: &str = include_str!(env!("DENO_WEBGPU_LIB_PATH"));
|
pub static DENO_WEBGPU_LIB: &str = include_str!(env!("DENO_WEBGPU_LIB_PATH"));
|
||||||
pub static DENO_WEBSOCKET_LIB: &str =
|
pub static DENO_WEBSOCKET_LIB: &str =
|
||||||
|
|
10
op_crates/fetch/internal.d.ts
vendored
10
op_crates/fetch/internal.d.ts
vendored
|
@ -19,16 +19,6 @@ declare namespace globalThis {
|
||||||
Headers: typeof Headers;
|
Headers: typeof Headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
declare var file: {
|
|
||||||
Blob: typeof Blob & {
|
|
||||||
[globalThis.__bootstrap.file._byteSequence]: Uint8Array;
|
|
||||||
};
|
|
||||||
_byteSequence: unique symbol;
|
|
||||||
File: typeof File & {
|
|
||||||
[globalThis.__bootstrap.file._byteSequence]: Uint8Array;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
declare var streams: {
|
declare var streams: {
|
||||||
ReadableStream: typeof ReadableStream;
|
ReadableStream: typeof ReadableStream;
|
||||||
isReadableStreamDisturbed(stream: ReadableStream): boolean;
|
isReadableStreamDisturbed(stream: ReadableStream): boolean;
|
||||||
|
|
36
op_crates/fetch/lib.deno_fetch.d.ts
vendored
36
op_crates/fetch/lib.deno_fetch.d.ts
vendored
|
@ -287,42 +287,6 @@ interface TransformStreamDefaultControllerTransformCallback<I, O> {
|
||||||
): void | PromiseLike<void>;
|
): void | PromiseLike<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlobPart = BufferSource | Blob | string;
|
|
||||||
|
|
||||||
interface BlobPropertyBag {
|
|
||||||
type?: string;
|
|
||||||
endings?: "transparent" | "native";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system. */
|
|
||||||
declare class Blob {
|
|
||||||
constructor(blobParts?: BlobPart[], options?: BlobPropertyBag);
|
|
||||||
|
|
||||||
readonly size: number;
|
|
||||||
readonly type: string;
|
|
||||||
arrayBuffer(): Promise<ArrayBuffer>;
|
|
||||||
slice(start?: number, end?: number, contentType?: string): Blob;
|
|
||||||
stream(): ReadableStream;
|
|
||||||
text(): Promise<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FilePropertyBag extends BlobPropertyBag {
|
|
||||||
lastModified?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Provides information about files and allows JavaScript in a web page to
|
|
||||||
* access their content. */
|
|
||||||
declare class File extends Blob {
|
|
||||||
constructor(
|
|
||||||
fileBits: BlobPart[],
|
|
||||||
fileName: string,
|
|
||||||
options?: FilePropertyBag,
|
|
||||||
);
|
|
||||||
|
|
||||||
readonly lastModified: number;
|
|
||||||
readonly name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
type FormDataEntryValue = File | string;
|
type FormDataEntryValue = File | string;
|
||||||
|
|
||||||
/** Provides a way to easily construct a set of key/value pairs representing
|
/** Provides a way to easily construct a set of key/value pairs representing
|
||||||
|
|
|
@ -68,10 +68,6 @@ pub fn init(isolate: &mut JsRuntime) {
|
||||||
"deno:op_crates/fetch/20_headers.js",
|
"deno:op_crates/fetch/20_headers.js",
|
||||||
include_str!("20_headers.js"),
|
include_str!("20_headers.js"),
|
||||||
),
|
),
|
||||||
(
|
|
||||||
"deno:op_crates/fetch/21_file.js",
|
|
||||||
include_str!("21_file.js"),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"deno:op_crates/fetch/26_fetch.js",
|
"deno:op_crates/fetch/26_fetch.js",
|
||||||
include_str!("26_fetch.js"),
|
include_str!("26_fetch.js"),
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/// <reference path="../web/internal.d.ts" />
|
/// <reference path="../web/internal.d.ts" />
|
||||||
/// <reference path="../web/lib.deno_web.d.ts" />
|
/// <reference path="../web/lib.deno_web.d.ts" />
|
||||||
/// <reference path="./internal.d.ts" />
|
/// <reference path="./internal.d.ts" />
|
||||||
/// <reference path="./lib.deno_fetch.d.ts" />
|
/// <reference path="./lib.deno_file.d.ts" />
|
||||||
/// <reference lib="esnext" />
|
/// <reference lib="esnext" />
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
334
op_crates/file/02_filereader.js
Normal file
334
op_crates/file/02_filereader.js
Normal file
|
@ -0,0 +1,334 @@
|
||||||
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
/// <reference no-default-lib="true" />
|
||||||
|
/// <reference path="../../core/lib.deno_core.d.ts" />
|
||||||
|
/// <reference path="../webidl/internal.d.ts" />
|
||||||
|
/// <reference path="../web/internal.d.ts" />
|
||||||
|
/// <reference path="../web/lib.deno_web.d.ts" />
|
||||||
|
/// <reference path="./internal.d.ts" />
|
||||||
|
/// <reference path="./lib.deno_file.d.ts" />
|
||||||
|
/// <reference lib="esnext" />
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
((window) => {
|
||||||
|
const webidl = window.__bootstrap.webidl;
|
||||||
|
const base64 = window.__bootstrap.base64;
|
||||||
|
|
||||||
|
const state = Symbol("[[state]]");
|
||||||
|
const result = Symbol("[[result]]");
|
||||||
|
const error = Symbol("[[error]]");
|
||||||
|
const aborted = Symbol("[[aborted]]");
|
||||||
|
|
||||||
|
class FileReader extends EventTarget {
|
||||||
|
/** @type {"empty" | "loading" | "done"} */
|
||||||
|
[state] = "empty";
|
||||||
|
/** @type {null | string | ArrayBuffer} */
|
||||||
|
[result] = null;
|
||||||
|
/** @type {null | DOMException} */
|
||||||
|
[error] = null;
|
||||||
|
|
||||||
|
[aborted] = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Blob} blob
|
||||||
|
* @param {{kind: "ArrayBuffer" | "Text" | "DataUrl", encoding?: string}} readtype
|
||||||
|
*/
|
||||||
|
#readOperation = async (blob, readtype) => {
|
||||||
|
// 1. If fr’s state is "loading", throw an InvalidStateError DOMException.
|
||||||
|
if (this[state] === "loading") {
|
||||||
|
throw new DOMException(
|
||||||
|
"Invalid FileReader state.",
|
||||||
|
"InvalidStateError",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// 2. Set fr’s state to "loading".
|
||||||
|
this[state] = "loading";
|
||||||
|
// 3. Set fr’s result to null.
|
||||||
|
this[result] = null;
|
||||||
|
// 4. Set fr’s error to null.
|
||||||
|
this[error] = null;
|
||||||
|
|
||||||
|
// 5. Let stream be the result of calling get stream on blob.
|
||||||
|
const stream /*: ReadableStream<ArrayBufferView>*/ = blob.stream();
|
||||||
|
|
||||||
|
// 6. Let reader be the result of getting a reader from stream.
|
||||||
|
const reader = stream.getReader();
|
||||||
|
|
||||||
|
// 7. Let bytes be an empty byte sequence.
|
||||||
|
/** @type {Uint8Array[]} */
|
||||||
|
const chunks = [];
|
||||||
|
|
||||||
|
// 8. Let chunkPromise be the result of reading a chunk from stream with reader.
|
||||||
|
let chunkPromise = reader.read();
|
||||||
|
|
||||||
|
// 9. Let isFirstChunk be true.
|
||||||
|
let isFirstChunk = true;
|
||||||
|
|
||||||
|
// 10 in parallel while true
|
||||||
|
while (!this[aborted]) {
|
||||||
|
// 1. Wait for chunkPromise to be fulfilled or rejected.
|
||||||
|
try {
|
||||||
|
const chunk = await chunkPromise;
|
||||||
|
if (this[aborted]) return;
|
||||||
|
|
||||||
|
// 2. If chunkPromise is fulfilled, and isFirstChunk is true, queue a task to fire a progress event called loadstart at fr.
|
||||||
|
if (isFirstChunk) {
|
||||||
|
queueMicrotask(() => {
|
||||||
|
// fire a progress event for loadstart
|
||||||
|
const ev = new ProgressEvent("loadstart", {});
|
||||||
|
this.dispatchEvent(ev);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 3. Set isFirstChunk to false.
|
||||||
|
isFirstChunk = false;
|
||||||
|
|
||||||
|
// 4. If chunkPromise is fulfilled with an object whose done property is false
|
||||||
|
// and whose value property is a Uint8Array object, run these steps:
|
||||||
|
if (!chunk.done && chunk.value instanceof Uint8Array) {
|
||||||
|
chunks.push(chunk.value);
|
||||||
|
|
||||||
|
// TODO(bartlomieju): (only) If roughly 50ms have passed since last progress
|
||||||
|
{
|
||||||
|
const size = chunks.reduce((p, i) => p + i.byteLength, 0);
|
||||||
|
const ev = new ProgressEvent("progress", {
|
||||||
|
loaded: size,
|
||||||
|
});
|
||||||
|
this.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
chunkPromise = reader.read();
|
||||||
|
} // 5 Otherwise, if chunkPromise is fulfilled with an object whose done property is true, queue a task to run the following steps and abort this algorithm:
|
||||||
|
else if (chunk.done === true) {
|
||||||
|
queueMicrotask(() => {
|
||||||
|
// 1. Set fr’s state to "done".
|
||||||
|
this[state] = "done";
|
||||||
|
// 2. Let result be the result of package data given bytes, type, blob’s type, and encodingName.
|
||||||
|
const size = chunks.reduce((p, i) => p + i.byteLength, 0);
|
||||||
|
const bytes = new Uint8Array(size);
|
||||||
|
let offs = 0;
|
||||||
|
for (const chunk of chunks) {
|
||||||
|
bytes.set(chunk, offs);
|
||||||
|
offs += chunk.byteLength;
|
||||||
|
}
|
||||||
|
switch (readtype.kind) {
|
||||||
|
case "ArrayBuffer": {
|
||||||
|
this[result] = bytes.buffer;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Text": {
|
||||||
|
const decoder = new TextDecoder(readtype.encoding);
|
||||||
|
this[result] = decoder.decode(bytes.buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "DataUrl": {
|
||||||
|
this[result] = "data:application/octet-stream;base64," +
|
||||||
|
base64.fromByteArray(bytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 4.2 Fire a progress event called load at the fr.
|
||||||
|
{
|
||||||
|
const ev = new ProgressEvent("load", {
|
||||||
|
lengthComputable: true,
|
||||||
|
loaded: size,
|
||||||
|
total: size,
|
||||||
|
});
|
||||||
|
this.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. If fr’s state is not "loading", fire a progress event called loadend at the fr.
|
||||||
|
//Note: Event handler for the load or error events could have started another load, if that happens the loadend event for this load is not fired.
|
||||||
|
if (this[state] !== "loading") {
|
||||||
|
const ev = new ProgressEvent("loadend", {
|
||||||
|
lengthComputable: true,
|
||||||
|
loaded: size,
|
||||||
|
total: size,
|
||||||
|
});
|
||||||
|
this.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (this[aborted]) return;
|
||||||
|
|
||||||
|
// chunkPromise rejected
|
||||||
|
this[state] = "done";
|
||||||
|
this[error] = err;
|
||||||
|
|
||||||
|
{
|
||||||
|
const ev = new ProgressEvent("error", {});
|
||||||
|
this.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If fr’s state is not "loading", fire a progress event called loadend at fr.
|
||||||
|
//Note: Event handler for the error event could have started another load, if that happens the loadend event for this load is not fired.
|
||||||
|
if (this[state] !== "loading") {
|
||||||
|
const ev = new ProgressEvent("loadend", {});
|
||||||
|
this.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static EMPTY = 0;
|
||||||
|
static LOADING = 1;
|
||||||
|
static DONE = 2;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this[webidl.brand] = webidl.brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @returns {number} */
|
||||||
|
get readyState() {
|
||||||
|
webidl.assertBranded(this, FileReader);
|
||||||
|
switch (this[state]) {
|
||||||
|
case "empty":
|
||||||
|
return FileReader.EMPTY;
|
||||||
|
case "loading":
|
||||||
|
return FileReader.LOADING;
|
||||||
|
case "done":
|
||||||
|
return FileReader.DONE;
|
||||||
|
default:
|
||||||
|
throw new TypeError("Invalid state");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get result() {
|
||||||
|
webidl.assertBranded(this, FileReader);
|
||||||
|
return this[result];
|
||||||
|
}
|
||||||
|
|
||||||
|
get error() {
|
||||||
|
webidl.assertBranded(this, FileReader);
|
||||||
|
return this[error];
|
||||||
|
}
|
||||||
|
|
||||||
|
abort() {
|
||||||
|
webidl.assertBranded(this, FileReader);
|
||||||
|
// If context object's state is "empty" or if context object's state is "done" set context object's result to null and terminate this algorithm.
|
||||||
|
if (
|
||||||
|
this[state] === "empty" ||
|
||||||
|
this[state] === "done"
|
||||||
|
) {
|
||||||
|
this[result] = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If context object's state is "loading" set context object's state to "done" and set context object's result to null.
|
||||||
|
if (this[state] === "loading") {
|
||||||
|
this[state] = "done";
|
||||||
|
this[result] = null;
|
||||||
|
}
|
||||||
|
// If there are any tasks from the context object on the file reading task source in an affiliated task queue, then remove those tasks from that task queue.
|
||||||
|
// Terminate the algorithm for the read method being processed.
|
||||||
|
this[aborted] = true;
|
||||||
|
|
||||||
|
// Fire a progress event called abort at the context object.
|
||||||
|
const ev = new ProgressEvent("abort", {});
|
||||||
|
this.dispatchEvent(ev);
|
||||||
|
|
||||||
|
// If context object's state is not "loading", fire a progress event called loadend at the context object.
|
||||||
|
if (this[state] !== "loading") {
|
||||||
|
const ev = new ProgressEvent("loadend", {});
|
||||||
|
this.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {Blob} blob */
|
||||||
|
readAsArrayBuffer(blob) {
|
||||||
|
webidl.assertBranded(this, FileReader);
|
||||||
|
const prefix = "Failed to execute 'readAsArrayBuffer' on 'FileReader'";
|
||||||
|
webidl.requiredArguments(arguments.length, 1, { prefix });
|
||||||
|
this.#readOperation(blob, { kind: "ArrayBuffer" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {Blob} blob */
|
||||||
|
readAsBinaryString(blob) {
|
||||||
|
webidl.assertBranded(this, FileReader);
|
||||||
|
const prefix = "Failed to execute 'readAsBinaryString' on 'FileReader'";
|
||||||
|
webidl.requiredArguments(arguments.length, 1, { prefix });
|
||||||
|
// alias for readAsArrayBuffer
|
||||||
|
this.#readOperation(blob, { kind: "ArrayBuffer" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {Blob} blob */
|
||||||
|
readAsDataURL(blob) {
|
||||||
|
webidl.assertBranded(this, FileReader);
|
||||||
|
const prefix = "Failed to execute 'readAsBinaryString' on 'FileReader'";
|
||||||
|
webidl.requiredArguments(arguments.length, 1, { prefix });
|
||||||
|
// alias for readAsArrayBuffer
|
||||||
|
this.#readOperation(blob, { kind: "DataUrl" });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Blob} blob
|
||||||
|
* @param {string} [encoding]
|
||||||
|
*/
|
||||||
|
readAsText(blob, encoding) {
|
||||||
|
webidl.assertBranded(this, FileReader);
|
||||||
|
const prefix = "Failed to execute 'readAsBinaryString' on 'FileReader'";
|
||||||
|
webidl.requiredArguments(arguments.length, 1, { prefix });
|
||||||
|
if (encoding !== undefined) {
|
||||||
|
encoding = webidl.converters["DOMString"](encoding, {
|
||||||
|
prefix,
|
||||||
|
context: "Argument 2",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// alias for readAsArrayBuffer
|
||||||
|
this.#readOperation(blob, { kind: "Text", encoding });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlerSymbol = Symbol("eventHandlers");
|
||||||
|
|
||||||
|
function makeWrappedHandler(handler) {
|
||||||
|
function wrappedHandler(...args) {
|
||||||
|
if (typeof wrappedHandler.handler !== "function") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return wrappedHandler.handler.call(this, ...args);
|
||||||
|
}
|
||||||
|
wrappedHandler.handler = handler;
|
||||||
|
return wrappedHandler;
|
||||||
|
}
|
||||||
|
// TODO(benjamingr) reuse when we can reuse code between web crates
|
||||||
|
function defineEventHandler(emitter, name) {
|
||||||
|
// HTML specification section 8.1.5.1
|
||||||
|
Object.defineProperty(emitter, `on${name}`, {
|
||||||
|
get() {
|
||||||
|
return this[handlerSymbol]?.get(name)?.handler;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
if (!this[handlerSymbol]) {
|
||||||
|
this[handlerSymbol] = new Map();
|
||||||
|
}
|
||||||
|
let handlerWrapper = this[handlerSymbol]?.get(name);
|
||||||
|
if (handlerWrapper) {
|
||||||
|
handlerWrapper.handler = value;
|
||||||
|
} else {
|
||||||
|
handlerWrapper = makeWrappedHandler(value);
|
||||||
|
this.addEventListener(name, handlerWrapper);
|
||||||
|
}
|
||||||
|
this[handlerSymbol].set(name, handlerWrapper);
|
||||||
|
},
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
defineEventHandler(FileReader.prototype, "error");
|
||||||
|
defineEventHandler(FileReader.prototype, "loadstart");
|
||||||
|
defineEventHandler(FileReader.prototype, "load");
|
||||||
|
defineEventHandler(FileReader.prototype, "loadend");
|
||||||
|
defineEventHandler(FileReader.prototype, "progress");
|
||||||
|
defineEventHandler(FileReader.prototype, "abort");
|
||||||
|
|
||||||
|
window.__bootstrap.fileReader = {
|
||||||
|
FileReader,
|
||||||
|
};
|
||||||
|
})(this);
|
17
op_crates/file/Cargo.toml
Normal file
17
op_crates/file/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "deno_file"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
description = "File API implementation for Deno"
|
||||||
|
authors = ["the Deno authors"]
|
||||||
|
license = "MIT"
|
||||||
|
readme = "README.md"
|
||||||
|
repository = "https://github.com/denoland/deno"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
deno_core = { version = "0.83.0", path = "../../core" }
|
5
op_crates/file/README.md
Normal file
5
op_crates/file/README.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# deno_file
|
||||||
|
|
||||||
|
This crate implements the File API.
|
||||||
|
|
||||||
|
Spec: https://w3c.github.io/FileAPI
|
18
op_crates/file/internal.d.ts
vendored
Normal file
18
op_crates/file/internal.d.ts
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
/// <reference no-default-lib="true" />
|
||||||
|
/// <reference lib="esnext" />
|
||||||
|
|
||||||
|
declare namespace globalThis {
|
||||||
|
declare namespace __bootstrap {
|
||||||
|
declare var file: {
|
||||||
|
Blob: typeof Blob & {
|
||||||
|
[globalThis.__bootstrap.file._byteSequence]: Uint8Array;
|
||||||
|
};
|
||||||
|
_byteSequence: unique symbol;
|
||||||
|
File: typeof File & {
|
||||||
|
[globalThis.__bootstrap.file._byteSequence]: Uint8Array;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
40
op_crates/file/lib.deno_file.d.ts
vendored
Normal file
40
op_crates/file/lib.deno_file.d.ts
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
/// <reference no-default-lib="true" />
|
||||||
|
/// <reference lib="esnext" />
|
||||||
|
|
||||||
|
type BlobPart = BufferSource | Blob | string;
|
||||||
|
|
||||||
|
interface BlobPropertyBag {
|
||||||
|
type?: string;
|
||||||
|
endings?: "transparent" | "native";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system. */
|
||||||
|
declare class Blob {
|
||||||
|
constructor(blobParts?: BlobPart[], options?: BlobPropertyBag);
|
||||||
|
|
||||||
|
readonly size: number;
|
||||||
|
readonly type: string;
|
||||||
|
arrayBuffer(): Promise<ArrayBuffer>;
|
||||||
|
slice(start?: number, end?: number, contentType?: string): Blob;
|
||||||
|
stream(): ReadableStream<Uint8Array>;
|
||||||
|
text(): Promise<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FilePropertyBag extends BlobPropertyBag {
|
||||||
|
lastModified?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Provides information about files and allows JavaScript in a web page to
|
||||||
|
* access their content. */
|
||||||
|
declare class File extends Blob {
|
||||||
|
constructor(
|
||||||
|
fileBits: BlobPart[],
|
||||||
|
fileName: string,
|
||||||
|
options?: FilePropertyBag,
|
||||||
|
);
|
||||||
|
|
||||||
|
readonly lastModified: number;
|
||||||
|
readonly name: string;
|
||||||
|
}
|
22
op_crates/file/lib.rs
Normal file
22
op_crates/file/lib.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use deno_core::JsRuntime;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
/// Load and execute the javascript code.
|
||||||
|
pub fn init(isolate: &mut JsRuntime) {
|
||||||
|
let files = vec![
|
||||||
|
("deno:op_crates/file/01_file.js", include_str!("01_file.js")),
|
||||||
|
(
|
||||||
|
"deno:op_crates/file/02_filereader.js",
|
||||||
|
include_str!("02_filereader.js"),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (url, source_code) in files {
|
||||||
|
isolate.execute(url, source_code).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_declaration() -> PathBuf {
|
||||||
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_file.d.ts")
|
||||||
|
}
|
|
@ -1,261 +0,0 @@
|
||||||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
((window) => {
|
|
||||||
const base64 = window.__bootstrap.base64;
|
|
||||||
|
|
||||||
async function readOperation(fr, blob, readtype) {
|
|
||||||
// Implementation from https://w3c.github.io/FileAPI/ notes
|
|
||||||
// And body of deno blob.ts readBytes
|
|
||||||
|
|
||||||
fr.aborting = false;
|
|
||||||
|
|
||||||
// 1. If fr’s state is "loading", throw an InvalidStateError DOMException.
|
|
||||||
if (fr.readyState === FileReader.LOADING) {
|
|
||||||
throw new DOMException(
|
|
||||||
"Invalid FileReader state.",
|
|
||||||
"InvalidStateError",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// 2. Set fr’s state to "loading".
|
|
||||||
fr.readyState = FileReader.LOADING;
|
|
||||||
// 3. Set fr’s result to null.
|
|
||||||
fr.result = null;
|
|
||||||
// 4. Set fr’s error to null.
|
|
||||||
fr.error = null;
|
|
||||||
|
|
||||||
// 5. Let stream be the result of calling get stream on blob.
|
|
||||||
const stream /*: ReadableStream<ArrayBufferView>*/ = blob.stream();
|
|
||||||
|
|
||||||
// 6. Let reader be the result of getting a reader from stream.
|
|
||||||
const reader = stream.getReader();
|
|
||||||
|
|
||||||
// 7. Let bytes be an empty byte sequence.
|
|
||||||
//let bytes = new Uint8Array();
|
|
||||||
const chunks /*: Uint8Array[]*/ = [];
|
|
||||||
|
|
||||||
// 8. Let chunkPromise be the result of reading a chunk from stream with reader.
|
|
||||||
let chunkPromise = reader.read();
|
|
||||||
|
|
||||||
// 9. Let isFirstChunk be true.
|
|
||||||
let isFirstChunk = true;
|
|
||||||
|
|
||||||
// 10 in parallel while true
|
|
||||||
while (!fr.aborting) {
|
|
||||||
// 1. Wait for chunkPromise to be fulfilled or rejected.
|
|
||||||
try {
|
|
||||||
const chunk = await chunkPromise;
|
|
||||||
|
|
||||||
// 2. If chunkPromise is fulfilled, and isFirstChunk is true, queue a task to fire a progress event called loadstart at fr.
|
|
||||||
if (isFirstChunk) {
|
|
||||||
queueMicrotask(() => {
|
|
||||||
// fire a progress event for loadstart
|
|
||||||
const ev = new ProgressEvent("loadstart", {});
|
|
||||||
fr.dispatchEvent(ev);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 3. Set isFirstChunk to false.
|
|
||||||
isFirstChunk = false;
|
|
||||||
|
|
||||||
// 4. If chunkPromise is fulfilled with an object whose done property is false
|
|
||||||
// and whose value property is a Uint8Array object, run these steps:
|
|
||||||
if (!chunk.done && chunk.value instanceof Uint8Array) {
|
|
||||||
chunks.push(chunk.value);
|
|
||||||
|
|
||||||
// TODO(bartlomieju): (only) If roughly 50ms have passed since last progress
|
|
||||||
{
|
|
||||||
const size = chunks.reduce((p, i) => p + i.byteLength, 0);
|
|
||||||
const ev = new ProgressEvent("progress", {
|
|
||||||
loaded: size,
|
|
||||||
});
|
|
||||||
fr.dispatchEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
chunkPromise = reader.read();
|
|
||||||
} // 5 Otherwise, if chunkPromise is fulfilled with an object whose done property is true, queue a task to run the following steps and abort this algorithm:
|
|
||||||
else if (chunk.done === true) {
|
|
||||||
queueMicrotask(() => {
|
|
||||||
if (fr.aborting) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. Set fr’s state to "done".
|
|
||||||
fr.readyState = FileReader.DONE;
|
|
||||||
// 2. Let result be the result of package data given bytes, type, blob’s type, and encodingName.
|
|
||||||
const size = chunks.reduce((p, i) => p + i.byteLength, 0);
|
|
||||||
const bytes = new Uint8Array(size);
|
|
||||||
let offs = 0;
|
|
||||||
for (const chunk of chunks) {
|
|
||||||
bytes.set(chunk, offs);
|
|
||||||
offs += chunk.byteLength;
|
|
||||||
}
|
|
||||||
switch (readtype.kind) {
|
|
||||||
case "ArrayBuffer": {
|
|
||||||
fr.result = bytes.buffer;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "Text": {
|
|
||||||
const decoder = new TextDecoder(readtype.encoding);
|
|
||||||
fr.result = decoder.decode(bytes.buffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "DataUrl": {
|
|
||||||
fr.result = "data:application/octet-stream;base64," +
|
|
||||||
base64.fromByteArray(bytes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 4.2 Fire a progress event called load at the fr.
|
|
||||||
{
|
|
||||||
const ev = new ProgressEvent("load", {
|
|
||||||
lengthComputable: true,
|
|
||||||
loaded: size,
|
|
||||||
total: size,
|
|
||||||
});
|
|
||||||
fr.dispatchEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. If fr’s state is not "loading", fire a progress event called loadend at the fr.
|
|
||||||
//Note: Event handler for the load or error events could have started another load, if that happens the loadend event for this load is not fired.
|
|
||||||
if (fr.readyState !== FileReader.LOADING) {
|
|
||||||
const ev = new ProgressEvent("loadend", {
|
|
||||||
lengthComputable: true,
|
|
||||||
loaded: size,
|
|
||||||
total: size,
|
|
||||||
});
|
|
||||||
fr.dispatchEvent(ev);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
if (fr.aborting) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// chunkPromise rejected
|
|
||||||
fr.readyState = FileReader.DONE;
|
|
||||||
fr.error = err;
|
|
||||||
|
|
||||||
{
|
|
||||||
const ev = new ProgressEvent("error", {});
|
|
||||||
fr.dispatchEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
//If fr’s state is not "loading", fire a progress event called loadend at fr.
|
|
||||||
//Note: Event handler for the error event could have started another load, if that happens the loadend event for this load is not fired.
|
|
||||||
if (fr.readyState !== FileReader.LOADING) {
|
|
||||||
const ev = new ProgressEvent("loadend", {});
|
|
||||||
fr.dispatchEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FileReader extends EventTarget {
|
|
||||||
error = null;
|
|
||||||
readyState = FileReader.EMPTY;
|
|
||||||
result = null;
|
|
||||||
aborting = false;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
abort() {
|
|
||||||
// If context object's state is "empty" or if context object's state is "done" set context object's result to null and terminate this algorithm.
|
|
||||||
if (
|
|
||||||
this.readyState === FileReader.EMPTY ||
|
|
||||||
this.readyState === FileReader.DONE
|
|
||||||
) {
|
|
||||||
this.result = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// If context object's state is "loading" set context object's state to "done" and set context object's result to null.
|
|
||||||
if (this.readyState === FileReader.LOADING) {
|
|
||||||
this.readyState = FileReader.DONE;
|
|
||||||
this.result = null;
|
|
||||||
}
|
|
||||||
// If there are any tasks from the context object on the file reading task source in an affiliated task queue, then remove those tasks from that task queue.
|
|
||||||
// Terminate the algorithm for the read method being processed.
|
|
||||||
this.aborting = true;
|
|
||||||
|
|
||||||
// Fire a progress event called abort at the context object.
|
|
||||||
const ev = new ProgressEvent("abort", {});
|
|
||||||
this.dispatchEvent(ev);
|
|
||||||
|
|
||||||
// If context object's state is not "loading", fire a progress event called loadend at the context object.
|
|
||||||
if (this.readyState !== FileReader.LOADING) {
|
|
||||||
const ev = new ProgressEvent("loadend", {});
|
|
||||||
this.dispatchEvent(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
readAsArrayBuffer(blob) {
|
|
||||||
readOperation(this, blob, { kind: "ArrayBuffer" });
|
|
||||||
}
|
|
||||||
readAsBinaryString(blob) {
|
|
||||||
// alias for readAsArrayBuffer
|
|
||||||
readOperation(this, blob, { kind: "ArrayBuffer" });
|
|
||||||
}
|
|
||||||
readAsDataURL(blob) {
|
|
||||||
readOperation(this, blob, { kind: "DataUrl" });
|
|
||||||
}
|
|
||||||
readAsText(blob, encoding) {
|
|
||||||
readOperation(this, blob, { kind: "Text", encoding });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileReader.EMPTY = 0;
|
|
||||||
FileReader.LOADING = 1;
|
|
||||||
FileReader.DONE = 2;
|
|
||||||
|
|
||||||
const handlerSymbol = Symbol("eventHandlers");
|
|
||||||
|
|
||||||
function makeWrappedHandler(handler) {
|
|
||||||
function wrappedHandler(...args) {
|
|
||||||
if (typeof wrappedHandler.handler !== "function") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return wrappedHandler.handler.call(this, ...args);
|
|
||||||
}
|
|
||||||
wrappedHandler.handler = handler;
|
|
||||||
return wrappedHandler;
|
|
||||||
}
|
|
||||||
// TODO(benjamingr) reuse when we can reuse code between web crates
|
|
||||||
function defineEventHandler(emitter, name) {
|
|
||||||
// HTML specification section 8.1.5.1
|
|
||||||
Object.defineProperty(emitter, `on${name}`, {
|
|
||||||
get() {
|
|
||||||
return this[handlerSymbol]?.get(name)?.handler;
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
if (!this[handlerSymbol]) {
|
|
||||||
this[handlerSymbol] = new Map();
|
|
||||||
}
|
|
||||||
let handlerWrapper = this[handlerSymbol]?.get(name);
|
|
||||||
if (handlerWrapper) {
|
|
||||||
handlerWrapper.handler = value;
|
|
||||||
} else {
|
|
||||||
handlerWrapper = makeWrappedHandler(value);
|
|
||||||
this.addEventListener(name, handlerWrapper);
|
|
||||||
}
|
|
||||||
this[handlerSymbol].set(name, handlerWrapper);
|
|
||||||
},
|
|
||||||
configurable: true,
|
|
||||||
enumerable: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
defineEventHandler(FileReader.prototype, "error");
|
|
||||||
defineEventHandler(FileReader.prototype, "loadstart");
|
|
||||||
defineEventHandler(FileReader.prototype, "load");
|
|
||||||
defineEventHandler(FileReader.prototype, "loadend");
|
|
||||||
defineEventHandler(FileReader.prototype, "progress");
|
|
||||||
defineEventHandler(FileReader.prototype, "abort");
|
|
||||||
|
|
||||||
window.__bootstrap.fileReader = {
|
|
||||||
FileReader,
|
|
||||||
};
|
|
||||||
})(this);
|
|
6
op_crates/web/internal.d.ts
vendored
6
op_crates/web/internal.d.ts
vendored
|
@ -12,5 +12,11 @@ declare namespace globalThis {
|
||||||
declare var location: {
|
declare var location: {
|
||||||
getLocationHref(): string | undefined;
|
getLocationHref(): string | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
declare var base64: {
|
||||||
|
byteLength(b64: string): number;
|
||||||
|
toByteArray(b64: string): Uint8Array;
|
||||||
|
fromByteArray(uint8: Uint8Array): string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,6 @@ pub fn init(isolate: &mut JsRuntime) {
|
||||||
"deno:op_crates/web/12_location.js",
|
"deno:op_crates/web/12_location.js",
|
||||||
include_str!("12_location.js"),
|
include_str!("12_location.js"),
|
||||||
),
|
),
|
||||||
(
|
|
||||||
"deno:op_crates/web/21_filereader.js",
|
|
||||||
include_str!("21_filereader.js"),
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
for (url, source_code) in files {
|
for (url, source_code) in files {
|
||||||
isolate.execute(url, source_code).unwrap();
|
isolate.execute(url, source_code).unwrap();
|
||||||
|
|
|
@ -22,6 +22,7 @@ deno_core = { path = "../core", version = "0.83.0" }
|
||||||
deno_console = { path = "../op_crates/console", version = "0.2.1" }
|
deno_console = { path = "../op_crates/console", version = "0.2.1" }
|
||||||
deno_crypto = { path = "../op_crates/crypto", version = "0.16.1" }
|
deno_crypto = { path = "../op_crates/crypto", version = "0.16.1" }
|
||||||
deno_fetch = { path = "../op_crates/fetch", version = "0.24.1" }
|
deno_fetch = { path = "../op_crates/fetch", version = "0.24.1" }
|
||||||
|
deno_file = { path = "../op_crates/file", version = "0.1.0" }
|
||||||
deno_web = { path = "../op_crates/web", version = "0.32.1" }
|
deno_web = { path = "../op_crates/web", version = "0.32.1" }
|
||||||
deno_url = { path = "../op_crates/url", version = "0.2.1" }
|
deno_url = { path = "../op_crates/url", version = "0.2.1" }
|
||||||
deno_webidl = { path = "../op_crates/webidl", version = "0.2.1" }
|
deno_webidl = { path = "../op_crates/webidl", version = "0.2.1" }
|
||||||
|
@ -37,6 +38,7 @@ deno_core = { path = "../core", version = "0.83.0" }
|
||||||
deno_console = { path = "../op_crates/console", version = "0.2.1" }
|
deno_console = { path = "../op_crates/console", version = "0.2.1" }
|
||||||
deno_crypto = { path = "../op_crates/crypto", version = "0.16.1" }
|
deno_crypto = { path = "../op_crates/crypto", version = "0.16.1" }
|
||||||
deno_fetch = { path = "../op_crates/fetch", version = "0.24.1" }
|
deno_fetch = { path = "../op_crates/fetch", version = "0.24.1" }
|
||||||
|
deno_file = { path = "../op_crates/file", version = "0.1.0" }
|
||||||
deno_web = { path = "../op_crates/web", version = "0.32.1" }
|
deno_web = { path = "../op_crates/web", version = "0.32.1" }
|
||||||
deno_url = { path = "../op_crates/url", version = "0.2.1" }
|
deno_url = { path = "../op_crates/url", version = "0.2.1" }
|
||||||
deno_webidl = { path = "../op_crates/webidl", version = "0.2.1" }
|
deno_webidl = { path = "../op_crates/webidl", version = "0.2.1" }
|
||||||
|
|
|
@ -17,6 +17,7 @@ fn create_snapshot(
|
||||||
deno_console::init(&mut js_runtime);
|
deno_console::init(&mut js_runtime);
|
||||||
deno_url::init(&mut js_runtime);
|
deno_url::init(&mut js_runtime);
|
||||||
deno_web::init(&mut js_runtime);
|
deno_web::init(&mut js_runtime);
|
||||||
|
deno_file::init(&mut js_runtime);
|
||||||
deno_fetch::init(&mut js_runtime);
|
deno_fetch::init(&mut js_runtime);
|
||||||
deno_websocket::init(&mut js_runtime);
|
deno_websocket::init(&mut js_runtime);
|
||||||
deno_crypto::init(&mut js_runtime);
|
deno_crypto::init(&mut js_runtime);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
pub use deno_console;
|
pub use deno_console;
|
||||||
pub use deno_crypto;
|
pub use deno_crypto;
|
||||||
pub use deno_fetch;
|
pub use deno_fetch;
|
||||||
|
pub use deno_file;
|
||||||
pub use deno_url;
|
pub use deno_url;
|
||||||
pub use deno_web;
|
pub use deno_web;
|
||||||
pub use deno_webgpu;
|
pub use deno_webgpu;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 681d273a49e7b5228394285b0c017f1b4c0d33b0
|
Subproject commit f897da00871cf39366bc2f0ceec051c65bc75703
|
|
@ -358,7 +358,7 @@
|
||||||
],
|
],
|
||||||
"patched-global.any.js": true,
|
"patched-global.any.js": true,
|
||||||
"reentrant-strategies.any.js": true,
|
"reentrant-strategies.any.js": true,
|
||||||
"tee.any.js": true,
|
"tee.any.js": false,
|
||||||
"templated.any.js": [
|
"templated.any.js": [
|
||||||
"ReadableStream (empty) reader: canceling via the stream should fail"
|
"ReadableStream (empty) reader: canceling via the stream should fail"
|
||||||
]
|
]
|
||||||
|
@ -784,7 +784,8 @@
|
||||||
},
|
},
|
||||||
"file": {
|
"file": {
|
||||||
"File-constructor.any.js": true
|
"File-constructor.any.js": true
|
||||||
}
|
},
|
||||||
|
"fileReader.any.js": true
|
||||||
},
|
},
|
||||||
"html": {
|
"html": {
|
||||||
"webappapis": {
|
"webappapis": {
|
||||||
|
|
Loading…
Reference in a new issue