diff options
40 files changed, 173 insertions, 268 deletions
diff --git a/Cargo.lock b/Cargo.lock index 098c2799b..022a609b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -535,7 +535,6 @@ dependencies = [ "deno_crypto", "deno_doc", "deno_fetch", - "deno_file", "deno_lint", "deno_runtime", "deno_timers", @@ -674,7 +673,7 @@ dependencies = [ "bytes", "data-url", "deno_core", - "deno_file", + "deno_web", "http", "reqwest", "serde", @@ -684,14 +683,6 @@ dependencies = [ ] [[package]] -name = "deno_file" -version = "0.7.0" -dependencies = [ - "deno_core", - "uuid", -] - -[[package]] name = "deno_lint" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -722,7 +713,6 @@ dependencies = [ "deno_core", "deno_crypto", "deno_fetch", - "deno_file", "deno_timers", "deno_url", "deno_web", @@ -790,6 +780,7 @@ dependencies = [ "encoding_rs", "futures", "serde", + "uuid", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5f60ac660..26ea13647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ members = [ "extensions/console", "extensions/crypto", "extensions/fetch", - "extensions/file", "extensions/timers", "extensions/url", "extensions/web", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 305b19c9b..64f261c7b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -25,7 +25,6 @@ deno_console = { version = "0.8.0", path = "../extensions/console" } deno_core = { version = "0.89.0", path = "../core" } deno_crypto = { version = "0.22.0", path = "../extensions/crypto" } deno_fetch = { version = "0.30.0", path = "../extensions/fetch" } -deno_file = { version = "0.7.0", path = "../extensions/file" } deno_timers = { version = "0.6.0", path = "../extensions/timers" } deno_url = { version = "0.8.0", path = "../extensions/url" } deno_web = { version = "0.39.0", path = "../extensions/web" } diff --git a/cli/build.rs b/cli/build.rs index 053d05395..c88c00376 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -59,7 +59,6 @@ fn create_compiler_snapshot( 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.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.webgpu", deno_webgpu::get_declaration()); op_crate_libs.insert("deno.websocket", deno_websocket::get_declaration()); @@ -276,10 +275,6 @@ fn main() { deno_web::get_declaration().display() ); println!( - "cargo:rustc-env=DENO_FILE_LIB_PATH={}", - deno_file::get_declaration().display() - ); - println!( "cargo:rustc-env=DENO_FETCH_LIB_PATH={}", deno_fetch::get_declaration().display() ); diff --git a/cli/dts/lib.deno.shared_globals.d.ts b/cli/dts/lib.deno.shared_globals.d.ts index e35de2e77..a59a7af36 100644 --- a/cli/dts/lib.deno.shared_globals.d.ts +++ b/cli/dts/lib.deno.shared_globals.d.ts @@ -6,7 +6,6 @@ /// <reference no-default-lib="true" /> /// <reference lib="esnext" /> /// <reference lib="deno.console" /> -/// <reference lib="deno.file" /> /// <reference lib="deno.url" /> /// <reference lib="deno.web" /> /// <reference lib="deno.fetch" /> diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs index 8403c660d..bd16cb1e1 100644 --- a/cli/file_fetcher.rs +++ b/cli/file_fetcher.rs @@ -19,7 +19,7 @@ use deno_core::futures; use deno_core::futures::future::FutureExt; use deno_core::ModuleSpecifier; use deno_runtime::deno_fetch::reqwest; -use deno_runtime::deno_file::BlobUrlStore; +use deno_runtime::deno_web::BlobUrlStore; use deno_runtime::permissions::Permissions; use log::debug; use log::info; @@ -579,7 +579,7 @@ mod tests { use deno_core::error::get_custom_error_class; use deno_core::resolve_url; use deno_core::resolve_url_or_path; - use deno_runtime::deno_file::Blob; + use deno_runtime::deno_web::Blob; use std::rc::Rc; use tempfile::TempDir; diff --git a/cli/lsp/registries.rs b/cli/lsp/registries.rs index 29ec3258b..83b322eab 100644 --- a/cli/lsp/registries.rs +++ b/cli/lsp/registries.rs @@ -26,7 +26,7 @@ use deno_core::serde_json::json; use deno_core::url::Position; use deno_core::url::Url; use deno_core::ModuleSpecifier; -use deno_runtime::deno_file::BlobUrlStore; +use deno_runtime::deno_web::BlobUrlStore; use deno_runtime::permissions::Permissions; use log::error; use lspower::lsp; diff --git a/cli/main.rs b/cli/main.rs index 23b51219f..5827203ce 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -330,12 +330,11 @@ fn print_cache_info( pub fn get_types(unstable: bool) -> String { let mut types = format!( - "{}\n{}\n{}\n{}\n{}\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_CONSOLE_LIB, crate::tsc::DENO_URL_LIB, crate::tsc::DENO_WEB_LIB, - crate::tsc::DENO_FILE_LIB, crate::tsc::DENO_FETCH_LIB, crate::tsc::DENO_WEBGPU_LIB, crate::tsc::DENO_WEBSOCKET_LIB, diff --git a/cli/program_state.rs b/cli/program_state.rs index c3c399b69..95362165f 100644 --- a/cli/program_state.rs +++ b/cli/program_state.rs @@ -16,7 +16,7 @@ use crate::source_maps::SourceMapGetter; use crate::specifier_handler::FetchHandler; use crate::version; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; -use deno_runtime::deno_file::BlobUrlStore; +use deno_runtime::deno_web::BlobUrlStore; use deno_runtime::inspector_server::InspectorServer; use deno_runtime::permissions::Permissions; diff --git a/cli/specifier_handler.rs b/cli/specifier_handler.rs index 900b918ab..cd27e45cc 100644 --- a/cli/specifier_handler.rs +++ b/cli/specifier_handler.rs @@ -574,7 +574,7 @@ pub mod tests { use crate::file_fetcher::CacheSetting; use crate::http_cache::HttpCache; use deno_core::resolve_url_or_path; - use deno_runtime::deno_file::BlobUrlStore; + use deno_runtime::deno_web::BlobUrlStore; use tempfile::TempDir; macro_rules! map ( diff --git a/cli/standalone.rs b/cli/standalone.rs index 7216a5fd6..8cb21f710 100644 --- a/cli/standalone.rs +++ b/cli/standalone.rs @@ -23,7 +23,7 @@ use deno_core::ModuleLoader; use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; -use deno_runtime::deno_file::BlobUrlStore; +use deno_runtime::deno_web::BlobUrlStore; use deno_runtime::permissions::Permissions; use deno_runtime::permissions::PermissionsOptions; use deno_runtime::worker::MainWorker; diff --git a/cli/tsc.rs b/cli/tsc.rs index 9d7b2a5ff..f87682fca 100644 --- a/cli/tsc.rs +++ b/cli/tsc.rs @@ -33,7 +33,6 @@ 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_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_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_WEBGPU_LIB: &str = include_str!(env!("DENO_WEBGPU_LIB_PATH")); pub static DENO_WEBSOCKET_LIB: &str = diff --git a/extensions/fetch/20_headers.js b/extensions/fetch/20_headers.js index 5f865749a..24dcdb74a 100644 --- a/extensions/fetch/20_headers.js +++ b/extensions/fetch/20_headers.js @@ -3,8 +3,7 @@ // @ts-check /// <reference path="../webidl/internal.d.ts" /> /// <reference path="../web/internal.d.ts" /> -/// <reference path="../file/internal.d.ts" /> -/// <reference path="../file/lib.deno_file.d.ts" /> +/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="./internal.d.ts" /> /// <reference path="./11_streams_types.d.ts" /> /// <reference path="./lib.deno_fetch.d.ts" /> diff --git a/extensions/fetch/21_formdata.js b/extensions/fetch/21_formdata.js index beae69aca..32a4e69a7 100644 --- a/extensions/fetch/21_formdata.js +++ b/extensions/fetch/21_formdata.js @@ -3,8 +3,7 @@ // @ts-check /// <reference path="../webidl/internal.d.ts" /> /// <reference path="../web/internal.d.ts" /> -/// <reference path="../file/internal.d.ts" /> -/// <reference path="../file/lib.deno_file.d.ts" /> +/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="./internal.d.ts" /> /// <reference path="./11_streams_types.d.ts" /> /// <reference path="./lib.deno_fetch.d.ts" /> diff --git a/extensions/fetch/22_body.js b/extensions/fetch/22_body.js index dcf1128a7..5039ab910 100644 --- a/extensions/fetch/22_body.js +++ b/extensions/fetch/22_body.js @@ -5,8 +5,7 @@ /// <reference path="../url/internal.d.ts" /> /// <reference path="../url/lib.deno_url.d.ts" /> /// <reference path="../web/internal.d.ts" /> -/// <reference path="../file/internal.d.ts" /> -/// <reference path="../file/lib.deno_file.d.ts" /> +/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="./internal.d.ts" /> /// <reference path="./11_streams_types.d.ts" /> /// <reference path="./lib.deno_fetch.d.ts" /> diff --git a/extensions/fetch/22_http_client.js b/extensions/fetch/22_http_client.js index 770080cc9..9900cfb58 100644 --- a/extensions/fetch/22_http_client.js +++ b/extensions/fetch/22_http_client.js @@ -4,8 +4,7 @@ /// <reference path="../webidl/internal.d.ts" /> /// <reference path="../web/internal.d.ts" /> /// <reference path="../url/internal.d.ts" /> -/// <reference path="../file/internal.d.ts" /> -/// <reference path="../file/lib.deno_file.d.ts" /> +/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="./internal.d.ts" /> /// <reference path="./11_streams_types.d.ts" /> /// <reference path="./lib.deno_fetch.d.ts" /> diff --git a/extensions/fetch/23_request.js b/extensions/fetch/23_request.js index d03023687..ad05b5cd8 100644 --- a/extensions/fetch/23_request.js +++ b/extensions/fetch/23_request.js @@ -3,8 +3,7 @@ // @ts-check /// <reference path="../webidl/internal.d.ts" /> /// <reference path="../web/internal.d.ts" /> -/// <reference path="../file/internal.d.ts" /> -/// <reference path="../file/lib.deno_file.d.ts" /> +/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="./internal.d.ts" /> /// <reference path="./11_streams_types.d.ts" /> /// <reference path="./lib.deno_fetch.d.ts" /> diff --git a/extensions/fetch/23_response.js b/extensions/fetch/23_response.js index b1b037187..a8fd52162 100644 --- a/extensions/fetch/23_response.js +++ b/extensions/fetch/23_response.js @@ -4,8 +4,7 @@ /// <reference path="../webidl/internal.d.ts" /> /// <reference path="../web/internal.d.ts" /> /// <reference path="../url/internal.d.ts" /> -/// <reference path="../file/internal.d.ts" /> -/// <reference path="../file/lib.deno_file.d.ts" /> +/// <reference path="../web/lib.deno_web.d.ts" /> /// <reference path="./internal.d.ts" /> /// <reference path="./11_streams_types.d.ts" /> /// <reference path="./lib.deno_fetch.d.ts" /> diff --git a/extensions/fetch/Cargo.toml b/extensions/fetch/Cargo.toml index c01af459a..27ab2e05d 100644 --- a/extensions/fetch/Cargo.toml +++ b/extensions/fetch/Cargo.toml @@ -17,7 +17,7 @@ path = "lib.rs" bytes = "1.0.1" data-url = "0.1.0" deno_core = { version = "0.89.0", path = "../../core" } -deno_file = { version = "0.7.0", path = "../file" } +deno_web = { version = "0.39.0", path = "../web" } http = "0.2.4" reqwest = { version = "0.11.3", default-features = false, features = ["rustls-tls", "stream", "gzip", "brotli"] } serde = { version = "1.0.125", features = ["derive"] } diff --git a/extensions/fetch/lib.rs b/extensions/fetch/lib.rs index 2fbd38b3a..5638b1f33 100644 --- a/extensions/fetch/lib.rs +++ b/extensions/fetch/lib.rs @@ -25,7 +25,7 @@ use deno_core::ResourceId; use deno_core::ZeroCopyBuf; use data_url::DataUrl; -use deno_file::BlobUrlStore; +use deno_web::BlobUrlStore; use reqwest::header::HeaderMap; use reqwest::header::HeaderName; use reqwest::header::HeaderValue; diff --git a/extensions/file/Cargo.toml b/extensions/file/Cargo.toml deleted file mode 100644 index da70cf1b8..000000000 --- a/extensions/file/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -[package] -name = "deno_file" -version = "0.7.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.89.0", path = "../../core" } -uuid = { version = "0.8.2", features = ["v4"] } diff --git a/extensions/file/README.md b/extensions/file/README.md deleted file mode 100644 index c421bf004..000000000 --- a/extensions/file/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# deno_file - -This crate implements the File API. - -Spec: https://w3c.github.io/FileAPI diff --git a/extensions/file/internal.d.ts b/extensions/file/internal.d.ts deleted file mode 100644 index dd892e736..000000000 --- a/extensions/file/internal.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -// 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; - }; - readonly _byteSequence: unique symbol; - File: typeof File & { - [globalThis.__bootstrap.file._byteSequence]: Uint8Array; - }; - }; - } -} diff --git a/extensions/file/lib.deno_file.d.ts b/extensions/file/lib.deno_file.d.ts deleted file mode 100644 index a907c3f50..000000000 --- a/extensions/file/lib.deno_file.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -// 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; -} diff --git a/extensions/file/lib.rs b/extensions/file/lib.rs deleted file mode 100644 index 1dcc02d27..000000000 --- a/extensions/file/lib.rs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. - -use deno_core::error::null_opbuf; -use deno_core::error::AnyError; -use deno_core::include_js_files; -use deno_core::op_sync; -use deno_core::url::Url; -use deno_core::Extension; -use deno_core::ModuleSpecifier; -use deno_core::ZeroCopyBuf; -use std::collections::HashMap; -use std::path::PathBuf; -use std::sync::Arc; -use std::sync::Mutex; -use uuid::Uuid; - -#[derive(Debug, Clone)] -pub struct Blob { - pub data: Vec<u8>, - pub media_type: String, -} - -pub struct Location(pub Url); - -#[derive(Debug, Default, Clone)] -pub struct BlobUrlStore(Arc<Mutex<HashMap<Url, Blob>>>); - -impl BlobUrlStore { - pub fn get(&self, mut url: Url) -> Result<Option<Blob>, AnyError> { - let blob_store = self.0.lock().unwrap(); - url.set_fragment(None); - Ok(blob_store.get(&url).cloned()) - } - - pub fn insert(&self, blob: Blob, maybe_location: Option<Url>) -> Url { - let origin = if let Some(location) = maybe_location { - location.origin().ascii_serialization() - } else { - "null".to_string() - }; - let id = Uuid::new_v4(); - let url = Url::parse(&format!("blob:{}/{}", origin, id)).unwrap(); - - let mut blob_store = self.0.lock().unwrap(); - blob_store.insert(url.clone(), blob); - - url - } - - pub fn remove(&self, url: &ModuleSpecifier) { - let mut blob_store = self.0.lock().unwrap(); - blob_store.remove(&url); - } -} - -pub fn op_file_create_object_url( - state: &mut deno_core::OpState, - media_type: String, - zero_copy: Option<ZeroCopyBuf>, -) -> Result<String, AnyError> { - let data = zero_copy.ok_or_else(null_opbuf)?; - let blob = Blob { - data: data.to_vec(), - media_type, - }; - - let maybe_location = state.try_borrow::<Location>(); - let blob_store = state.borrow::<BlobUrlStore>(); - - let url = - blob_store.insert(blob, maybe_location.map(|location| location.0.clone())); - - Ok(url.to_string()) -} - -pub fn op_file_revoke_object_url( - state: &mut deno_core::OpState, - url: String, - _: (), -) -> Result<(), AnyError> { - let url = Url::parse(&url)?; - let blob_store = state.borrow::<BlobUrlStore>(); - blob_store.remove(&url); - Ok(()) -} - -pub fn init( - blob_url_store: BlobUrlStore, - maybe_location: Option<Url>, -) -> Extension { - Extension::builder() - .js(include_js_files!( - prefix "deno:extensions/file", - "01_file.js", - "02_filereader.js", - "03_blob_url.js", - )) - .ops(vec![ - ( - "op_file_create_object_url", - op_sync(op_file_create_object_url), - ), - ( - "op_file_revoke_object_url", - op_sync(op_file_revoke_object_url), - ), - ]) - .state(move |state| { - state.put(blob_url_store.clone()); - if let Some(location) = maybe_location.clone() { - state.put(Location(location)); - } - Ok(()) - }) - .build() -} - -pub fn get_declaration() -> PathBuf { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_file.d.ts") -} diff --git a/extensions/file/01_file.js b/extensions/web/09_file.js index 42298c3a1..403bbee35 100644 --- a/extensions/file/01_file.js +++ b/extensions/web/09_file.js @@ -7,7 +7,6 @@ /// <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"; diff --git a/extensions/file/02_filereader.js b/extensions/web/10_filereader.js index 7cc40f7a5..b8bb6172a 100644 --- a/extensions/file/02_filereader.js +++ b/extensions/web/10_filereader.js @@ -7,7 +7,6 @@ /// <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"; diff --git a/extensions/file/03_blob_url.js b/extensions/web/11_blob_url.js index 2b5e16b55..d030d79bd 100644 --- a/extensions/file/03_blob_url.js +++ b/extensions/web/11_blob_url.js @@ -9,7 +9,6 @@ /// <reference path="../url/internal.d.ts" /> /// <reference path="../url/lib.deno_url.d.ts" /> /// <reference path="./internal.d.ts" /> -/// <reference path="./lib.deno_file.d.ts" /> /// <reference lib="esnext" /> "use strict"; diff --git a/extensions/web/Cargo.toml b/extensions/web/Cargo.toml index a914d1b48..05a0f17f2 100644 --- a/extensions/web/Cargo.toml +++ b/extensions/web/Cargo.toml @@ -18,6 +18,7 @@ base64 = "0.13.0" deno_core = { version = "0.89.0", path = "../../core" } encoding_rs = "0.8.28" serde = "1.0" +uuid = { version = "0.8.2", features = ["v4"] } [dev-dependencies] futures = "0.3.15" diff --git a/extensions/web/README.md b/extensions/web/README.md index 03c1b7f89..d847ae52e 100644 --- a/extensions/web/README.md +++ b/extensions/web/README.md @@ -1,5 +1,6 @@ # deno web -Op crate that implements Event, TextEncoder, TextDecoder. +Op crate that implements Event, TextEncoder, TextDecoder and File API +(https://w3c.github.io/FileAPI). Testing for text encoding is done via WPT in cli/. diff --git a/extensions/web/internal.d.ts b/extensions/web/internal.d.ts index ebfa0d39e..4492e6554 100644 --- a/extensions/web/internal.d.ts +++ b/extensions/web/internal.d.ts @@ -70,5 +70,15 @@ declare namespace globalThis { atob(data: string): string; btoa(data: string): string; }; + + declare var file: { + Blob: typeof Blob & { + [globalThis.__bootstrap.file._byteSequence]: Uint8Array; + }; + readonly _byteSequence: unique symbol; + File: typeof File & { + [globalThis.__bootstrap.file._byteSequence]: Uint8Array; + }; + }; } } diff --git a/extensions/web/lib.deno_web.d.ts b/extensions/web/lib.deno_web.d.ts index 0c3673351..a1b6a0595 100644 --- a/extensions/web/lib.deno_web.d.ts +++ b/extensions/web/lib.deno_web.d.ts @@ -341,3 +341,39 @@ declare var FileReader: { readonly EMPTY: number; readonly LOADING: number; }; + +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; +} diff --git a/extensions/web/lib.rs b/extensions/web/lib.rs index 95adb822a..b2906acaf 100644 --- a/extensions/web/lib.rs +++ b/extensions/web/lib.rs @@ -1,12 +1,15 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. use deno_core::error::bad_resource_id; +use deno_core::error::null_opbuf; use deno_core::error::range_error; use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::include_js_files; use deno_core::op_sync; +use deno_core::url::Url; use deno_core::Extension; +use deno_core::ModuleSpecifier; use deno_core::OpState; use deno_core::Resource; use deno_core::ResourceId; @@ -17,15 +20,21 @@ use encoding_rs::DecoderResult; use encoding_rs::Encoding; use serde::Deserialize; use serde::Serialize; - use std::borrow::Cow; use std::cell::RefCell; +use std::collections::HashMap; use std::fmt; use std::path::PathBuf; +use std::sync::Arc; +use std::sync::Mutex; use std::usize; +use uuid::Uuid; /// Load and execute the javascript code. -pub fn init() -> Extension { +pub fn init( + blob_url_store: BlobUrlStore, + maybe_location: Option<Url>, +) -> Extension { Extension::builder() .js(include_js_files!( prefix "deno:extensions/web", @@ -38,6 +47,9 @@ pub fn init() -> Extension { "04_global_interfaces.js", "05_base64.js", "08_text_encoding.js", + "09_file.js", + "10_filereader.js", + "11_blob_url.js", "12_location.js", )) .ops(vec![ @@ -50,7 +62,22 @@ pub fn init() -> Extension { ("op_encoding_new_decoder", op_sync(op_encoding_new_decoder)), ("op_encoding_decode", op_sync(op_encoding_decode)), ("op_encoding_encode_into", op_sync(op_encoding_encode_into)), + ( + "op_file_create_object_url", + op_sync(op_file_create_object_url), + ), + ( + "op_file_revoke_object_url", + op_sync(op_file_revoke_object_url), + ), ]) + .state(move |state| { + state.put(blob_url_store.clone()); + if let Some(location) = maybe_location.clone() { + state.put(Location(location)); + } + Ok(()) + }) .build() } @@ -318,3 +345,73 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { .map(|_| "DOMExceptionInvalidCharacterError") }) } + +#[derive(Debug, Clone)] +pub struct Blob { + pub data: Vec<u8>, + pub media_type: String, +} + +pub struct Location(pub Url); + +#[derive(Debug, Default, Clone)] +pub struct BlobUrlStore(Arc<Mutex<HashMap<Url, Blob>>>); + +impl BlobUrlStore { + pub fn get(&self, mut url: Url) -> Result<Option<Blob>, AnyError> { + let blob_store = self.0.lock().unwrap(); + url.set_fragment(None); + Ok(blob_store.get(&url).cloned()) + } + + pub fn insert(&self, blob: Blob, maybe_location: Option<Url>) -> Url { + let origin = if let Some(location) = maybe_location { + location.origin().ascii_serialization() + } else { + "null".to_string() + }; + let id = Uuid::new_v4(); + let url = Url::parse(&format!("blob:{}/{}", origin, id)).unwrap(); + + let mut blob_store = self.0.lock().unwrap(); + blob_store.insert(url.clone(), blob); + + url + } + + pub fn remove(&self, url: &ModuleSpecifier) { + let mut blob_store = self.0.lock().unwrap(); + blob_store.remove(&url); + } +} + +pub fn op_file_create_object_url( + state: &mut deno_core::OpState, + media_type: String, + zero_copy: Option<ZeroCopyBuf>, +) -> Result<String, AnyError> { + let data = zero_copy.ok_or_else(null_opbuf)?; + let blob = Blob { + data: data.to_vec(), + media_type, + }; + + let maybe_location = state.try_borrow::<Location>(); + let blob_store = state.borrow::<BlobUrlStore>(); + + let url = + blob_store.insert(blob, maybe_location.map(|location| location.0.clone())); + + Ok(url.to_string()) +} + +pub fn op_file_revoke_object_url( + state: &mut deno_core::OpState, + url: String, + _: (), +) -> Result<(), AnyError> { + let url = Url::parse(&url)?; + let blob_store = state.borrow::<BlobUrlStore>(); + blob_store.remove(&url); + Ok(()) +} diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index a5245bb29..0bd8d13c4 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -23,7 +23,6 @@ deno_console = { version = "0.8.0", path = "../extensions/console" } deno_core = { version = "0.89.0", path = "../core" } deno_crypto = { version = "0.22.0", path = "../extensions/crypto" } deno_fetch = { version = "0.30.0", path = "../extensions/fetch" } -deno_file = { version = "0.7.0", path = "../extensions/file" } deno_timers = { version = "0.6.0", path = "../extensions/timers" } deno_url = { version = "0.8.0", path = "../extensions/url" } deno_web = { version = "0.39.0", path = "../extensions/web" } @@ -42,7 +41,6 @@ deno_console = { version = "0.8.0", path = "../extensions/console" } deno_core = { version = "0.89.0", path = "../core" } deno_crypto = { version = "0.22.0", path = "../extensions/crypto" } deno_fetch = { version = "0.30.0", path = "../extensions/fetch" } -deno_file = { version = "0.7.0", path = "../extensions/file" } deno_timers = { version = "0.6.0", path = "../extensions/timers" } deno_url = { version = "0.8.0", path = "../extensions/url" } deno_web = { version = "0.39.0", path = "../extensions/web" } diff --git a/runtime/build.rs b/runtime/build.rs index d228fffd6..701d027a4 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -41,8 +41,7 @@ fn create_runtime_snapshot(snapshot_path: &Path, files: Vec<PathBuf>) { deno_webidl::init(), deno_console::init(), deno_url::init(), - deno_web::init(), - deno_file::init(Default::default(), Default::default()), + deno_web::init(Default::default(), Default::default()), deno_fetch::init::<deno_fetch::NoFetchPermissions>("".to_owned(), None), deno_websocket::init::<deno_websocket::NoWebSocketPermissions>( "".to_owned(), diff --git a/runtime/examples/hello_runtime.rs b/runtime/examples/hello_runtime.rs index 95a82a25f..28ea64043 100644 --- a/runtime/examples/hello_runtime.rs +++ b/runtime/examples/hello_runtime.rs @@ -3,7 +3,7 @@ use deno_core::error::AnyError; use deno_core::FsModuleLoader; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; -use deno_runtime::deno_file::BlobUrlStore; +use deno_runtime::deno_web::BlobUrlStore; use deno_runtime::permissions::Permissions; use deno_runtime::worker::MainWorker; use deno_runtime::worker::WorkerOptions; diff --git a/runtime/lib.rs b/runtime/lib.rs index 91bea8303..63829c2d2 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -4,7 +4,6 @@ pub use deno_broadcast_channel; pub use deno_console; pub use deno_crypto; pub use deno_fetch; -pub use deno_file; pub use deno_timers; pub use deno_url; pub use deno_web; diff --git a/runtime/web_worker.rs b/runtime/web_worker.rs index d246843b4..948d063fc 100644 --- a/runtime/web_worker.rs +++ b/runtime/web_worker.rs @@ -28,7 +28,7 @@ use deno_core::ModuleLoader; use deno_core::ModuleSpecifier; use deno_core::RuntimeOptions; use deno_core::ZeroCopyBuf; -use deno_file::BlobUrlStore; +use deno_web::BlobUrlStore; use log::debug; use std::cell::RefCell; use std::env; @@ -255,11 +255,7 @@ impl WebWorker { deno_webidl::init(), deno_console::init(), deno_url::init(), - deno_web::init(), - deno_file::init( - options.blob_url_store.clone(), - Some(main_module.clone()), - ), + deno_web::init(options.blob_url_store.clone(), Some(main_module.clone())), deno_fetch::init::<Permissions>( options.user_agent.clone(), options.ca_data.clone(), diff --git a/runtime/worker.rs b/runtime/worker.rs index 971449859..83594fc4a 100644 --- a/runtime/worker.rs +++ b/runtime/worker.rs @@ -23,7 +23,7 @@ use deno_core::ModuleId; use deno_core::ModuleLoader; use deno_core::ModuleSpecifier; use deno_core::RuntimeOptions; -use deno_file::BlobUrlStore; +use deno_web::BlobUrlStore; use log::debug; use std::env; use std::pin::Pin; @@ -96,8 +96,7 @@ impl MainWorker { deno_webidl::init(), deno_console::init(), deno_url::init(), - deno_web::init(), - deno_file::init(options.blob_url_store.clone(), options.location.clone()), + deno_web::init(options.blob_url_store.clone(), options.location.clone()), deno_fetch::init::<Permissions>( options.user_agent.clone(), options.ca_data.clone(), diff --git a/tools/cut_a_release.md b/tools/cut_a_release.md index 2b823738b..cff04b8f3 100644 --- a/tools/cut_a_release.md +++ b/tools/cut_a_release.md @@ -34,10 +34,8 @@ between the crates, it must be done in specific order: first - `bench_util` - crates in `extensions/` directory - - `deno_crypto` and `deno_webstorage` depend on `deno_web`, so the latter must - be bumped and released first - - `deno_fetch` depends on `deno_file`, so the latter must be bumped and - released first + - `deno_fetch`, `deno_crypto` and `deno_webstorage` depend on `deno_web`, so + the latter must be bumped and released first - `runtime` - this crate depends on `deno_core` and all crates in `extensions/` directory |