diff options
Diffstat (limited to 'cli')
-rw-r--r-- | cli/Cargo.toml | 1 | ||||
-rw-r--r-- | cli/bench/cache_api.js | 56 | ||||
-rw-r--r-- | cli/build.rs | 5 | ||||
-rw-r--r-- | cli/dts/lib.deno.window.d.ts | 4 | ||||
-rw-r--r-- | cli/dts/lib.deno.worker.d.ts | 2 | ||||
-rw-r--r-- | cli/lsp/tsc.rs | 2 | ||||
-rw-r--r-- | cli/main.rs | 1 | ||||
-rw-r--r-- | cli/standalone.rs | 1 | ||||
-rw-r--r-- | cli/tests/unit/cache_api_test.ts | 96 | ||||
-rw-r--r-- | cli/tests/unit/fetch_test.ts | 1 | ||||
-rw-r--r-- | cli/tests/unit/test_util.ts | 1 | ||||
-rw-r--r-- | cli/tsc.rs | 1 | ||||
-rw-r--r-- | cli/worker.rs | 20 |
13 files changed, 188 insertions, 3 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 22929fd21..15e236a2b 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -27,6 +27,7 @@ path = "./bench/lsp_bench_standalone.rs" [build-dependencies] deno_broadcast_channel = { version = "0.64.0", path = "../ext/broadcast_channel" } +deno_cache = { version = "0.1.0", path = "../ext/cache" } deno_console = { version = "0.70.0", path = "../ext/console" } deno_core = { version = "0.152.0", path = "../core" } deno_crypto = { version = "0.84.0", path = "../ext/crypto" } diff --git a/cli/bench/cache_api.js b/cli/bench/cache_api.js new file mode 100644 index 000000000..3e059e80a --- /dev/null +++ b/cli/bench/cache_api.js @@ -0,0 +1,56 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. + +const cacheName = "cache-v1"; +const cache = await caches.open(cacheName); +const req = "https://deno.com"; + +Deno.bench( + `cache_storage_open`, + async () => { + await caches.open("cache-v2"); + }, +); + +Deno.bench( + `cache_storage_has`, + async () => { + await caches.has("cache-v2"); + }, +); + +Deno.bench( + `cache_storage_delete`, + async () => { + await caches.delete("cache-v2"); + }, +); + +// 100 bytes. +const loremIpsum = + `Lorem ipsum dolor sit amet, consectetur adipiscing…es ligula in libero. Sed dignissim lacinia nunc. `; +let body; +for (let index = 1; index <= 110; index++) { + body += loremIpsum; +} + +Deno.bench( + `cache_put_body_${Math.floor(body.length / 1024)}_KiB`, + async () => { + await cache.put(req, new Response(body)); + }, +); + +Deno.bench("cache_put_no_body", async () => { + await cache.put( + "https://deno.land/redirect", + Response.redirect("https://deno.com"), + ); +}); + +Deno.bench("cache_match", async () => { + await cache.match(req); +}); + +Deno.bench("cache_delete", async () => { + await cache.delete(req); +}); diff --git a/cli/build.rs b/cli/build.rs index 1a4eaa425..df4cd5917 100644 --- a/cli/build.rs +++ b/cli/build.rs @@ -81,6 +81,7 @@ fn create_compiler_snapshot( ) { // libs that are being provided by op crates. let mut op_crate_libs = HashMap::new(); + op_crate_libs.insert("deno.cache", deno_cache::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.web", deno_web::get_declaration()); @@ -373,6 +374,10 @@ fn main() { deno_webstorage::get_declaration().display() ); println!( + "cargo:rustc-env=DENO_CACHE_LIB_PATH={}", + deno_cache::get_declaration().display() + ); + println!( "cargo:rustc-env=DENO_CRYPTO_LIB_PATH={}", deno_crypto::get_declaration().display() ); diff --git a/cli/dts/lib.deno.window.d.ts b/cli/dts/lib.deno.window.d.ts index 9877ffc75..9515f5b23 100644 --- a/cli/dts/lib.deno.window.d.ts +++ b/cli/dts/lib.deno.window.d.ts @@ -6,6 +6,7 @@ /// <reference lib="deno.webgpu" /> /// <reference lib="deno.webstorage" /> /// <reference lib="esnext" /> +/// <reference lib="deno.cache" /> /** @category Web APIs */ interface WindowEventMap { @@ -36,6 +37,7 @@ declare class Window extends EventTarget { location: Location; localStorage: Storage; sessionStorage: Storage; + caches: CacheStorage; addEventListener<K extends keyof WindowEventMap>( type: K, @@ -83,6 +85,8 @@ declare var onunhandledrejection: declare var localStorage: Storage; /** @category Web Storage API */ declare var sessionStorage: Storage; +/** @category Cache API */ +declare var caches: CacheStorage; /** @category Web APIs */ declare class Navigator { diff --git a/cli/dts/lib.deno.worker.d.ts b/cli/dts/lib.deno.worker.d.ts index 63826b5ef..10a771807 100644 --- a/cli/dts/lib.deno.worker.d.ts +++ b/cli/dts/lib.deno.worker.d.ts @@ -5,6 +5,7 @@ /// <reference lib="deno.shared_globals" /> /// <reference lib="deno.webgpu" /> /// <reference lib="esnext" /> +/// <reference lib="deno.cache" /> /** @category Web Workers */ interface WorkerGlobalScopeEventMap { @@ -51,6 +52,7 @@ declare class WorkerGlobalScope extends EventTarget { ): void; Deno: typeof Deno; + caches: CacheStorage; } /** @category Web APIs */ diff --git a/cli/lsp/tsc.rs b/cli/lsp/tsc.rs index 3560ca547..e198c4fb8 100644 --- a/cli/lsp/tsc.rs +++ b/cli/lsp/tsc.rs @@ -3775,7 +3775,7 @@ mod tests { // You might have found this assertion starts failing after upgrading TypeScript. // Just update the new number of assets (declaration files) for this number. - assert_eq!(assets.len(), 70); + assert_eq!(assets.len(), 71); // get some notification when the size of the assets grows let mut total_size = 0; diff --git a/cli/main.rs b/cli/main.rs index 70c8c78d0..2ad5c83c0 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -217,6 +217,7 @@ pub fn get_types(unstable: bool) -> String { tsc::DENO_BROADCAST_CHANNEL_LIB, tsc::DENO_NET_LIB, tsc::SHARED_GLOBALS_LIB, + tsc::DENO_CACHE_LIB, tsc::WINDOW_LIB, ]; diff --git a/cli/standalone.rs b/cli/standalone.rs index 65a51fde5..0c454ce77 100644 --- a/cli/standalone.rs +++ b/cli/standalone.rs @@ -300,6 +300,7 @@ pub async fn run( module_loader, npm_resolver: None, // not currently supported get_error_class_fn: Some(&get_error_class_name), + cache_storage_dir: None, origin_storage_dir: None, blob_store, broadcast_channel, diff --git a/cli/tests/unit/cache_api_test.ts b/cli/tests/unit/cache_api_test.ts new file mode 100644 index 000000000..4d7c6511b --- /dev/null +++ b/cli/tests/unit/cache_api_test.ts @@ -0,0 +1,96 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. +import { + assert, + assertEquals, + assertFalse, + assertRejects, +} from "./test_util.ts"; + +Deno.test(async function cacheStorage() { + const cacheName = "cache-v1"; + const _cache = await caches.open(cacheName); + assert(await caches.has(cacheName)); + assert(await caches.delete(cacheName)); + assertFalse(await caches.has(cacheName)); +}); + +Deno.test(async function cacheApi() { + const cacheName = "cache-v1"; + const cache = await caches.open(cacheName); + // Test cache.put() with url string as key. + { + const req = "https://deno.com"; + await cache.put(req, new Response("deno.com - key is string")); + const res = await cache.match(req); + assertEquals(await res?.text(), "deno.com - key is string"); + assert(await cache.delete(req)); + } + // Test cache.put() with url instance as key. + { + const req = new URL("https://deno.com"); + await cache.put(req, new Response("deno.com - key is URL")); + const res = await cache.match(req); + assertEquals(await res?.text(), "deno.com - key is URL"); + assert(await cache.delete(req)); + } + // Test cache.put() with request instance as key. + { + const req = new Request("https://deno.com"); + await cache.put(req, new Response("deno.com - key is Request")); + const res = await cache.match(req); + assertEquals(await res?.text(), "deno.com - key is Request"); + assert(await cache.delete(req)); + } + + // Test cache.put() throws with response Vary header set to *. + { + const req = new Request("https://deno.com"); + assertRejects( + async () => { + await cache.put( + req, + new Response("deno.com - key is Request", { + headers: { Vary: "*" }, + }), + ); + }, + TypeError, + "Vary header must not contain '*'", + ); + } + + // Test cache.match() with same url but different values for Vary header. + { + await cache.put( + new Request("https://example.com/", { + headers: { + "Accept": "application/json", + }, + }), + Response.json({ msg: "hello world" }, { + headers: { + "Content-Type": "application/json", + "Vary": "Accept", + }, + }), + ); + const res = await cache.match("https://example.com/"); + assertEquals(res, undefined); + const res2 = await cache.match( + new Request("https://example.com/", { + headers: { "Accept": "text/html" }, + }), + ); + assertEquals(res2, undefined); + + const res3 = await cache.match( + new Request("https://example.com/", { + headers: { "Accept": "application/json" }, + }), + ); + assertEquals(await res3?.json(), { msg: "hello world" }); + } + + assert(await caches.delete(cacheName)); + assertFalse(await caches.has(cacheName)); +}); diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts index 7a531392d..36c1926f2 100644 --- a/cli/tests/unit/fetch_test.ts +++ b/cli/tests/unit/fetch_test.ts @@ -1782,7 +1782,6 @@ Deno.test( const blob = new Blob(["ok"], { type: "text/plain" }); const url = URL.createObjectURL(blob); const res = await fetch(url); - console.log(res); assert(res.url.startsWith("blob:http://js-unit-tests/")); assertEquals(res.status, 200); assertEquals(res.headers.get("content-length"), "2"); diff --git a/cli/tests/unit/test_util.ts b/cli/tests/unit/test_util.ts index 4ad4b2575..19cad092d 100644 --- a/cli/tests/unit/test_util.ts +++ b/cli/tests/unit/test_util.ts @@ -6,6 +6,7 @@ import { resolve } from "../../../test_util/std/path/mod.ts"; export { assert, assertEquals, + assertFalse, assertMatch, assertNotEquals, assertRejects, diff --git a/cli/tsc.rs b/cli/tsc.rs index 1951c5a10..e9800d9d2 100644 --- a/cli/tsc.rs +++ b/cli/tsc.rs @@ -45,6 +45,7 @@ pub static DENO_WEBSOCKET_LIB: &str = include_str!(env!("DENO_WEBSOCKET_LIB_PATH")); pub static DENO_WEBSTORAGE_LIB: &str = include_str!(env!("DENO_WEBSTORAGE_LIB_PATH")); +pub static DENO_CACHE_LIB: &str = include_str!(env!("DENO_CACHE_LIB_PATH")); pub static DENO_CRYPTO_LIB: &str = include_str!(env!("DENO_CRYPTO_LIB_PATH")); pub static DENO_BROADCAST_CHANNEL_LIB: &str = include_str!(env!("DENO_BROADCAST_CHANNEL_LIB_PATH")); diff --git a/cli/worker.rs b/cli/worker.rs index cc497630e..0454069fa 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -379,13 +379,20 @@ pub async fn create_main_worker( create_web_worker_pre_execute_module_callback(ps.clone()); let maybe_storage_key = ps.options.resolve_storage_key(&main_module); - let origin_storage_dir = maybe_storage_key.map(|key| { + let origin_storage_dir = maybe_storage_key.as_ref().map(|key| { ps.dir .root // TODO(@crowlKats): change to origin_data for 2.0 .join("location_data") .join(checksum::gen(&[key.as_bytes()])) }); + let cache_storage_dir = maybe_storage_key.map(|key| { + // TODO(@satyarohith): storage quota management + // Note: we currently use temp_dir() to avoid managing storage size. + std::env::temp_dir() + .join("deno_cache") + .join(checksum::gen(&[key.as_bytes()])) + }); let mut extensions = ops::cli_exts(ps.clone()); extensions.append(&mut custom_extensions); @@ -427,6 +434,7 @@ pub async fn create_main_worker( module_loader, npm_resolver: Some(Rc::new(ps.npm_resolver.clone())), get_error_class_fn: Some(&errors::get_error_class_name), + cache_storage_dir, origin_storage_dir, blob_store: ps.blob_store.clone(), broadcast_channel: ps.broadcast_channel.clone(), @@ -496,6 +504,15 @@ fn create_web_worker_callback( let extensions = ops::cli_exts(ps.clone()); + let maybe_storage_key = ps.options.resolve_storage_key(&args.main_module); + let cache_storage_dir = maybe_storage_key.map(|key| { + // TODO(@satyarohith): storage quota management + // Note: we currently use temp_dir() to avoid managing storage size. + std::env::temp_dir() + .join("deno_cache") + .join(checksum::gen(&[key.as_bytes()])) + }); + let options = WebWorkerOptions { bootstrap: BootstrapOptions { args: ps.options.argv().clone(), @@ -538,6 +555,7 @@ fn create_web_worker_callback( shared_array_buffer_store: Some(ps.shared_array_buffer_store.clone()), compiled_wasm_module_store: Some(ps.compiled_wasm_module_store.clone()), stdio: stdio.clone(), + cache_storage_dir, }; WebWorker::bootstrap_from_options( |