mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
feat: add WebStorage API (#7819)
This commit introduces localStorage and sessionStorage.
This commit is contained in:
parent
32ad8f77d6
commit
dfe528198d
20 changed files with 819 additions and 45 deletions
147
Cargo.lock
generated
147
Cargo.lock
generated
|
@ -37,9 +37,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -114,9 +114,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b72c1f1154e234325b50864a349b9c8e56939e266a4c307c0f159812df2f9537"
|
||||
checksum = "5443ccbb270374a2b1055fc72da40e1f237809cd6bb0e97e66d264cd138473a6"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"flate2",
|
||||
|
@ -442,9 +442,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
|
||||
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
|
@ -697,6 +697,7 @@ dependencies = [
|
|||
"deno_webgpu",
|
||||
"deno_webidl",
|
||||
"deno_websocket",
|
||||
"deno_webstorage",
|
||||
"dlopen",
|
||||
"encoding_rs",
|
||||
"filetime",
|
||||
|
@ -787,6 +788,15 @@ dependencies = [
|
|||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_webstorage"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.13"
|
||||
|
@ -1013,6 +1023,18 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-streaming-iterator"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "fancy-regex"
|
||||
version = "0.5.0"
|
||||
|
@ -1483,9 +1505,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc018e188373e2777d0ef2467ebff62a08e66c3f5857b23c8fbec3018210dc00"
|
||||
checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
|
@ -1509,6 +1531,15 @@ dependencies = [
|
|||
"ahash 0.4.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d99cf782f0dc4372d26846bec3de7804ceb5df083c2d4462c0b8d2330e894fa8"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.2"
|
||||
|
@ -1787,9 +1818,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.93"
|
||||
version = "0.2.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
|
@ -1801,6 +1832,17 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19cb1effde5f834799ac5e5ef0e40d45027cd74f271b1de786ba8abb30e2164d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.4"
|
||||
|
@ -1809,9 +1851,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
|||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
|
||||
checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
@ -1908,9 +1950,9 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "metal"
|
||||
|
@ -2253,6 +2295,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
|
||||
[[package]]
|
||||
name = "pmutil"
|
||||
version = "0.5.3"
|
||||
|
@ -2327,7 +2375,7 @@ version = "1.0.26"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2505,9 +2553,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.6"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041"
|
||||
checksum = "85dd92e586f7355c633911e11f77f3d12f04b1b1bd76a198bd34ae3af8341ef2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
@ -2526,9 +2574,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.23"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "relative-path"
|
||||
|
@ -2624,6 +2672,21 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbc783b7ddae608338003bac1fa00b6786a75a9675fbd8e87243ecfdea3f6ed2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
"libsqlite3-sys",
|
||||
"memchr",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
|
@ -3010,9 +3073,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_bundler"
|
||||
version = "0.32.5"
|
||||
version = "0.32.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a3fd9db5796f48c7db74c045838c77981aed155c47e8ecf7dca2f7c47408e70"
|
||||
checksum = "2c724be1aea9b099b11b2d57ab59e25ed8428c03d9daa8fdded8fa81d17b6d56"
|
||||
dependencies = [
|
||||
"ahash 0.7.2",
|
||||
"anyhow",
|
||||
|
@ -3076,9 +3139,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_codegen"
|
||||
version = "0.52.3"
|
||||
version = "0.52.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bffd587bf624fc3ad732433704cc4ff415967ed9feed26accf2db9130237e09"
|
||||
checksum = "4f62df17607eee6c488fdd24d192911db862b2af68a6ea72e166bb699f8a417a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"num-bigint",
|
||||
|
@ -3132,7 +3195,7 @@ dependencies = [
|
|||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_visit",
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3152,7 +3215,7 @@ dependencies = [
|
|||
"swc_ecma_transforms_typescript",
|
||||
"swc_ecma_utils",
|
||||
"swc_ecma_visit",
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3176,9 +3239,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_optimization"
|
||||
version = "0.15.5"
|
||||
version = "0.15.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f187623203e84095337ea16b499ef6768819c3f2f7e3cdae24022135282dd3d"
|
||||
checksum = "70ae2bd352c1365d1c8f02c5016f729de6e1fb2fe03afd5c37a896468d1f20a4"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"fxhash",
|
||||
|
@ -3217,9 +3280,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_react"
|
||||
version = "0.14.3"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da3cfd8e900a1f1e26ea705f4614717b3deceec40d4b2fd4b1dc65a2b90de066"
|
||||
checksum = "b13d80190e922c2f83edec85c40372cbc0dd14d15973447471c0885ca408ce78"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"dashmap",
|
||||
|
@ -3267,7 +3330,7 @@ dependencies = [
|
|||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_visit",
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3285,9 +3348,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecmascript"
|
||||
version = "0.31.3"
|
||||
version = "0.31.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45286c7e1199a0c9ef13951535f5c6f777228d26df2fcf2d2d81ef11d0f22e40"
|
||||
checksum = "9148743bf5d6dcc482fd4db219968b216bff61a475c7838e0f60e00886cfa2b4"
|
||||
dependencies = [
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_codegen",
|
||||
|
@ -3365,7 +3428,7 @@ checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.26",
|
||||
"quote 1.0.9",
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3640,9 +3703,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.25"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
|
||||
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
|
@ -3651,9 +3714,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.17"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
|
||||
checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
@ -3852,9 +3915,9 @@ checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
|
@ -3897,6 +3960,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbdbff6266a24120518560b5dc983096efb98462e51d0d68169895b237be3e5d"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
|
|
|
@ -16,6 +16,7 @@ use deno_runtime::deno_url;
|
|||
use deno_runtime::deno_web;
|
||||
use deno_runtime::deno_webgpu;
|
||||
use deno_runtime::deno_websocket;
|
||||
use deno_runtime::deno_webstorage;
|
||||
use regex::Regex;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
@ -71,6 +72,7 @@ fn create_compiler_snapshot(
|
|||
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());
|
||||
op_crate_libs.insert("deno.webstorage", deno_webstorage::get_declaration());
|
||||
op_crate_libs.insert("deno.crypto", deno_crypto::get_declaration());
|
||||
|
||||
// ensure we invalidate the build properly.
|
||||
|
@ -290,6 +292,10 @@ fn main() {
|
|||
"cargo:rustc-env=DENO_WEBSOCKET_LIB_PATH={}",
|
||||
deno_websocket::get_declaration().display()
|
||||
);
|
||||
println!(
|
||||
"cargo:rustc-env=DENO_WEBSTORAGE_LIB_PATH={}",
|
||||
deno_webstorage::get_declaration().display()
|
||||
);
|
||||
println!(
|
||||
"cargo:rustc-env=DENO_CRYPTO_LIB_PATH={}",
|
||||
deno_crypto::get_declaration().display()
|
||||
|
|
5
cli/dts/lib.deno.window.d.ts
vendored
5
cli/dts/lib.deno.window.d.ts
vendored
|
@ -4,6 +4,7 @@
|
|||
/// <reference lib="deno.ns" />
|
||||
/// <reference lib="deno.shared_globals" />
|
||||
/// <reference lib="deno.webgpu" />
|
||||
/// <reference lib="deno.webstorage" />
|
||||
/// <reference lib="esnext" />
|
||||
|
||||
declare class Window extends EventTarget {
|
||||
|
@ -22,12 +23,16 @@ declare class Window extends EventTarget {
|
|||
navigator: Navigator;
|
||||
Location: typeof Location;
|
||||
location: Location;
|
||||
localStorage: Storage;
|
||||
sessionStorage: Storage;
|
||||
}
|
||||
|
||||
declare var window: Window & typeof globalThis;
|
||||
declare var self: Window & typeof globalThis;
|
||||
declare var onload: ((this: Window, ev: Event) => any) | null;
|
||||
declare var onunload: ((this: Window, ev: Event) => any) | null;
|
||||
declare var localStorage: Storage;
|
||||
declare var sessionStorage: Storage;
|
||||
|
||||
declare class Navigator {
|
||||
constructor();
|
||||
|
|
11
cli/main.rs
11
cli/main.rs
|
@ -204,6 +204,14 @@ pub fn create_main_worker(
|
|||
no_color: !colors::use_color(),
|
||||
get_error_class_fn: Some(&crate::errors::get_error_class_name),
|
||||
location: program_state.flags.location.clone(),
|
||||
location_data_dir: program_state.flags.location.clone().map(|loc| {
|
||||
program_state
|
||||
.dir
|
||||
.root
|
||||
.clone()
|
||||
.join("location_data")
|
||||
.join(checksum::gen(&[loc.to_string().as_bytes()]))
|
||||
}),
|
||||
blob_url_store: program_state.blob_url_store.clone(),
|
||||
};
|
||||
|
||||
|
@ -295,7 +303,7 @@ 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{}",
|
||||
crate::tsc::DENO_NS_LIB,
|
||||
crate::tsc::DENO_CONSOLE_LIB,
|
||||
crate::tsc::DENO_URL_LIB,
|
||||
|
@ -304,6 +312,7 @@ pub fn get_types(unstable: bool) -> String {
|
|||
crate::tsc::DENO_FETCH_LIB,
|
||||
crate::tsc::DENO_WEBGPU_LIB,
|
||||
crate::tsc::DENO_WEBSOCKET_LIB,
|
||||
crate::tsc::DENO_WEBSTORAGE_LIB,
|
||||
crate::tsc::DENO_CRYPTO_LIB,
|
||||
crate::tsc::SHARED_GLOBALS_LIB,
|
||||
crate::tsc::WINDOW_LIB,
|
||||
|
|
|
@ -191,6 +191,7 @@ pub async fn run(
|
|||
no_color: !colors::use_color(),
|
||||
get_error_class_fn: Some(&get_error_class_name),
|
||||
location: metadata.location,
|
||||
location_data_dir: None,
|
||||
blob_url_store,
|
||||
};
|
||||
let mut worker =
|
||||
|
|
|
@ -37,6 +37,8 @@ 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 =
|
||||
include_str!(env!("DENO_WEBSOCKET_LIB_PATH"));
|
||||
pub static DENO_WEBSTORAGE_LIB: &str =
|
||||
include_str!(env!("DENO_WEBSTORAGE_LIB_PATH"));
|
||||
pub static DENO_CRYPTO_LIB: &str = include_str!(env!("DENO_CRYPTO_LIB_PATH"));
|
||||
pub static SHARED_GLOBALS_LIB: &str =
|
||||
include_str!("dts/lib.deno.shared_globals.d.ts");
|
||||
|
|
190
extensions/webstorage/01_webstorage.js
Normal file
190
extensions/webstorage/01_webstorage.js
Normal file
|
@ -0,0 +1,190 @@
|
|||
((window) => {
|
||||
const core = window.Deno.core;
|
||||
const webidl = window.__bootstrap.webidl;
|
||||
|
||||
const _rid = Symbol("[[rid]]");
|
||||
|
||||
class Storage {
|
||||
[_rid];
|
||||
|
||||
constructor() {
|
||||
webidl.illegalConstructor();
|
||||
}
|
||||
|
||||
get length() {
|
||||
webidl.assertBranded(this, Storage);
|
||||
return core.opSync("op_webstorage_length", this[_rid]);
|
||||
}
|
||||
|
||||
key(index) {
|
||||
webidl.assertBranded(this, Storage);
|
||||
const prefix = "Failed to execute 'key' on 'Storage'";
|
||||
webidl.requiredArguments(arguments.length, 1, { prefix });
|
||||
index = webidl.converters["unsigned long"](index, {
|
||||
prefix,
|
||||
context: "Argument 1",
|
||||
});
|
||||
|
||||
return core.opSync("op_webstorage_key", {
|
||||
rid: this[_rid],
|
||||
index,
|
||||
});
|
||||
}
|
||||
|
||||
setItem(key, value) {
|
||||
webidl.assertBranded(this, Storage);
|
||||
const prefix = "Failed to execute 'setItem' on 'Storage'";
|
||||
webidl.requiredArguments(arguments.length, 2, { prefix });
|
||||
key = webidl.converters.DOMString(key, {
|
||||
prefix,
|
||||
context: "Argument 1",
|
||||
});
|
||||
value = webidl.converters.DOMString(value, {
|
||||
prefix,
|
||||
context: "Argument 2",
|
||||
});
|
||||
|
||||
core.opSync("op_webstorage_set", {
|
||||
rid: this[_rid],
|
||||
keyName: key,
|
||||
keyValue: value,
|
||||
});
|
||||
}
|
||||
|
||||
getItem(key) {
|
||||
webidl.assertBranded(this, Storage);
|
||||
const prefix = "Failed to execute 'getItem' on 'Storage'";
|
||||
webidl.requiredArguments(arguments.length, 1, { prefix });
|
||||
key = webidl.converters.DOMString(key, {
|
||||
prefix,
|
||||
context: "Argument 1",
|
||||
});
|
||||
|
||||
return core.opSync("op_webstorage_get", {
|
||||
rid: this[_rid],
|
||||
keyName: key,
|
||||
});
|
||||
}
|
||||
|
||||
removeItem(key) {
|
||||
webidl.assertBranded(this, Storage);
|
||||
const prefix = "Failed to execute 'removeItem' on 'Storage'";
|
||||
webidl.requiredArguments(arguments.length, 1, { prefix });
|
||||
key = webidl.converters.DOMString(key, {
|
||||
prefix,
|
||||
context: "Argument 1",
|
||||
});
|
||||
|
||||
core.opSync("op_webstorage_remove", {
|
||||
rid: this[_rid],
|
||||
keyName: key,
|
||||
});
|
||||
}
|
||||
|
||||
clear() {
|
||||
webidl.assertBranded(this, Storage);
|
||||
core.opSync("op_webstorage_clear", this[_rid]);
|
||||
}
|
||||
}
|
||||
|
||||
function createStorage(persistent) {
|
||||
if (persistent) window.location;
|
||||
|
||||
const rid = core.opSync("op_webstorage_open", persistent);
|
||||
|
||||
const storage = webidl.createBranded(Storage);
|
||||
storage[_rid] = rid;
|
||||
|
||||
const proxy = new Proxy(storage, {
|
||||
deleteProperty(target, key) {
|
||||
if (typeof key == "symbol") {
|
||||
delete target[key];
|
||||
} else {
|
||||
target.removeItem(key);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
defineProperty(target, key, descriptor) {
|
||||
if (typeof key == "symbol") {
|
||||
Object.defineProperty(target, key, descriptor);
|
||||
} else {
|
||||
target.setItem(key, descriptor.value);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
get(target, key) {
|
||||
if (typeof key == "symbol") return target[key];
|
||||
if (key in target) {
|
||||
return Reflect.get(...arguments);
|
||||
} else {
|
||||
return target.getItem(key) ?? undefined;
|
||||
}
|
||||
},
|
||||
set(target, key, value) {
|
||||
if (typeof key == "symbol") {
|
||||
Object.defineProperty(target, key, {
|
||||
value,
|
||||
configurable: true,
|
||||
});
|
||||
} else {
|
||||
target.setItem(key, value);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
has(target, p) {
|
||||
return (typeof target.getItem(p)) === "string";
|
||||
},
|
||||
ownKeys() {
|
||||
return core.opSync("op_webstorage_iterate_keys", rid);
|
||||
},
|
||||
getOwnPropertyDescriptor(target, key) {
|
||||
if (arguments.length === 1) {
|
||||
return undefined;
|
||||
}
|
||||
if (key in target) {
|
||||
return undefined;
|
||||
}
|
||||
const value = target.getItem(key);
|
||||
if (value === null) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
value,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
proxy[Symbol.for("Deno.customInspect")] = function (inspect) {
|
||||
return `${this.constructor.name} ${
|
||||
inspect({
|
||||
length: this.length,
|
||||
...Object.fromEntries(Object.entries(proxy)),
|
||||
})
|
||||
}`;
|
||||
};
|
||||
|
||||
return proxy;
|
||||
}
|
||||
|
||||
let localStorage;
|
||||
let sessionStorage;
|
||||
|
||||
window.__bootstrap.webStorage = {
|
||||
localStorage() {
|
||||
if (!localStorage) {
|
||||
localStorage = createStorage(true);
|
||||
}
|
||||
return localStorage;
|
||||
},
|
||||
sessionStorage() {
|
||||
if (!sessionStorage) {
|
||||
sessionStorage = createStorage(false);
|
||||
}
|
||||
return sessionStorage;
|
||||
},
|
||||
Storage,
|
||||
};
|
||||
})(this);
|
19
extensions/webstorage/Cargo.toml
Normal file
19
extensions/webstorage/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
[package]
|
||||
name = "deno_webstorage"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
description = "Implementation of WebStorage API 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.86.0", path = "../../core" }
|
||||
rusqlite = { version = "0.25.0", features = ["unlock_notify", "bundled"] }
|
||||
serde = { version = "1.0.125", features = ["derive"] }
|
5
extensions/webstorage/README.md
Normal file
5
extensions/webstorage/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# deno_webstorage
|
||||
|
||||
This op crate implements the WebStorage spec in Deno.
|
||||
|
||||
Spec: https://html.spec.whatwg.org/multipage/webstorage.html
|
42
extensions/webstorage/lib.deno_webstorage.d.ts
vendored
Normal file
42
extensions/webstorage/lib.deno_webstorage.d.ts
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
// deno-lint-ignore-file no-explicit-any
|
||||
|
||||
/// <reference no-default-lib="true" />
|
||||
/// <reference lib="esnext" />
|
||||
|
||||
/** This Web Storage API interface provides access to a particular domain's session or local storage. It allows, for example, the addition, modification, or deletion of stored data items. */
|
||||
interface Storage {
|
||||
/**
|
||||
* Returns the number of key/value pairs currently present in the list associated with the object.
|
||||
*/
|
||||
readonly length: number;
|
||||
/**
|
||||
* Empties the list associated with the object of all key/value pairs, if there are any.
|
||||
*/
|
||||
clear(): void;
|
||||
/**
|
||||
* Returns the current value associated with the given key, or null if the given key does not exist in the list associated with the object.
|
||||
*/
|
||||
getItem(key: string): string | null;
|
||||
/**
|
||||
* Returns the name of the nth key in the list, or null if n is greater than or equal to the number of key/value pairs in the object.
|
||||
*/
|
||||
key(index: number): string | null;
|
||||
/**
|
||||
* Removes the key/value pair with the given key from the list associated with the object, if a key/value pair with the given key exists.
|
||||
*/
|
||||
removeItem(key: string): void;
|
||||
/**
|
||||
* Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.
|
||||
*
|
||||
* Throws a "QuotaExceededError" DOMException exception if the new value couldn't be set. (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.)
|
||||
*/
|
||||
setItem(key: string, value: string): void;
|
||||
[name: string]: any;
|
||||
}
|
||||
|
||||
declare var Storage: {
|
||||
prototype: Storage;
|
||||
new (): Storage;
|
||||
};
|
316
extensions/webstorage/lib.rs
Normal file
316
extensions/webstorage/lib.rs
Normal file
|
@ -0,0 +1,316 @@
|
|||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use deno_core::error::bad_resource_id;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::include_js_files;
|
||||
use deno_core::op_sync;
|
||||
use deno_core::Extension;
|
||||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ZeroCopyBuf;
|
||||
use rusqlite::params;
|
||||
use rusqlite::Connection;
|
||||
use rusqlite::OptionalExtension;
|
||||
use serde::Deserialize;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct LocationDataDir(PathBuf);
|
||||
|
||||
pub fn init(location_data_dir: Option<PathBuf>) -> Extension {
|
||||
Extension::builder()
|
||||
.js(include_js_files!(
|
||||
prefix "deno:extensions/webstorage",
|
||||
"01_webstorage.js",
|
||||
))
|
||||
.ops(vec![
|
||||
("op_webstorage_open", op_sync(op_webstorage_open)),
|
||||
("op_webstorage_length", op_sync(op_webstorage_length)),
|
||||
("op_webstorage_key", op_sync(op_webstorage_key)),
|
||||
("op_webstorage_set", op_sync(op_webstorage_set)),
|
||||
("op_webstorage_get", op_sync(op_webstorage_get)),
|
||||
("op_webstorage_remove", op_sync(op_webstorage_remove)),
|
||||
("op_webstorage_clear", op_sync(op_webstorage_clear)),
|
||||
(
|
||||
"op_webstorage_iterate_keys",
|
||||
op_sync(op_webstorage_iterate_keys),
|
||||
),
|
||||
])
|
||||
.state(move |state| {
|
||||
if let Some(location_data_dir) = location_data_dir.clone() {
|
||||
state.put(LocationDataDir(location_data_dir));
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn get_declaration() -> PathBuf {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_webstorage.d.ts")
|
||||
}
|
||||
|
||||
struct WebStorageConnectionResource(Connection);
|
||||
|
||||
impl Resource for WebStorageConnectionResource {
|
||||
fn name(&self) -> Cow<str> {
|
||||
"webStorage".into()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn op_webstorage_open(
|
||||
state: &mut OpState,
|
||||
persistent: bool,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<u32, AnyError> {
|
||||
let connection = if persistent {
|
||||
let path = state.try_borrow::<LocationDataDir>().ok_or_else(|| {
|
||||
DomExceptionNotSupportedError::new(
|
||||
"LocalStorage is not supported in this context.",
|
||||
)
|
||||
})?;
|
||||
std::fs::create_dir_all(&path.0)?;
|
||||
Connection::open(path.0.join("local_storage"))?
|
||||
} else {
|
||||
Connection::open_in_memory()?
|
||||
};
|
||||
|
||||
connection.execute(
|
||||
"CREATE TABLE IF NOT EXISTS data (key VARCHAR UNIQUE, value VARCHAR)",
|
||||
params![],
|
||||
)?;
|
||||
|
||||
let rid = state
|
||||
.resource_table
|
||||
.add(WebStorageConnectionResource(connection));
|
||||
Ok(rid)
|
||||
}
|
||||
|
||||
pub fn op_webstorage_length(
|
||||
state: &mut OpState,
|
||||
rid: u32,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<u32, AnyError> {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<WebStorageConnectionResource>(rid)
|
||||
.ok_or_else(bad_resource_id)?;
|
||||
|
||||
let mut stmt = resource.0.prepare("SELECT COUNT(*) FROM data")?;
|
||||
|
||||
let length: u32 = stmt.query_row(params![], |row| row.get(0))?;
|
||||
|
||||
Ok(length)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct KeyArgs {
|
||||
rid: u32,
|
||||
index: u32,
|
||||
}
|
||||
|
||||
pub fn op_webstorage_key(
|
||||
state: &mut OpState,
|
||||
args: KeyArgs,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<WebStorageConnectionResource>(args.rid)
|
||||
.ok_or_else(bad_resource_id)?;
|
||||
|
||||
let mut stmt = resource
|
||||
.0
|
||||
.prepare("SELECT key FROM data LIMIT 1 OFFSET ?")?;
|
||||
|
||||
let key: Option<String> = stmt
|
||||
.query_row(params![args.index], |row| row.get(0))
|
||||
.optional()?;
|
||||
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SetArgs {
|
||||
rid: u32,
|
||||
key_name: String,
|
||||
key_value: String,
|
||||
}
|
||||
|
||||
pub fn op_webstorage_set(
|
||||
state: &mut OpState,
|
||||
args: SetArgs,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<WebStorageConnectionResource>(args.rid)
|
||||
.ok_or_else(bad_resource_id)?;
|
||||
|
||||
let mut stmt = resource
|
||||
.0
|
||||
.prepare("SELECT SUM(pgsize) FROM dbstat WHERE name = 'data'")?;
|
||||
let size: u32 = stmt.query_row(params![], |row| row.get(0))?;
|
||||
|
||||
if size >= 5000000 {
|
||||
return Err(
|
||||
DomExceptionQuotaExceededError::new("Exceeded maximum storage size")
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
resource.0.execute(
|
||||
"INSERT OR REPLACE INTO data (key, value) VALUES (?, ?)",
|
||||
params![args.key_name, args.key_value],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GetArgs {
|
||||
rid: u32,
|
||||
key_name: String,
|
||||
}
|
||||
|
||||
pub fn op_webstorage_get(
|
||||
state: &mut OpState,
|
||||
args: GetArgs,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<WebStorageConnectionResource>(args.rid)
|
||||
.ok_or_else(bad_resource_id)?;
|
||||
|
||||
let mut stmt = resource.0.prepare("SELECT value FROM data WHERE key = ?")?;
|
||||
|
||||
let val = stmt
|
||||
.query_row(params![args.key_name], |row| row.get(0))
|
||||
.optional()?;
|
||||
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RemoveArgs {
|
||||
rid: u32,
|
||||
key_name: String,
|
||||
}
|
||||
|
||||
pub fn op_webstorage_remove(
|
||||
state: &mut OpState,
|
||||
args: RemoveArgs,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<WebStorageConnectionResource>(args.rid)
|
||||
.ok_or_else(bad_resource_id)?;
|
||||
|
||||
resource
|
||||
.0
|
||||
.execute("DELETE FROM data WHERE key = ?", params![args.key_name])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn op_webstorage_clear(
|
||||
state: &mut OpState,
|
||||
rid: u32,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<WebStorageConnectionResource>(rid)
|
||||
.ok_or_else(bad_resource_id)?;
|
||||
|
||||
resource.0.execute("DROP TABLE data", params![])?;
|
||||
resource.0.execute(
|
||||
"CREATE TABLE data (key VARCHAR UNIQUE, value VARCHAR)",
|
||||
params![],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn op_webstorage_iterate_keys(
|
||||
state: &mut OpState,
|
||||
rid: u32,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<Vec<String>, AnyError> {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<WebStorageConnectionResource>(rid)
|
||||
.ok_or_else(bad_resource_id)?;
|
||||
|
||||
let mut stmt = resource.0.prepare("SELECT key FROM data")?;
|
||||
|
||||
let keys = stmt
|
||||
.query_map(params![], |row| row.get::<_, String>(0))?
|
||||
.map(|r| r.unwrap())
|
||||
.collect();
|
||||
|
||||
Ok(keys)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DomExceptionQuotaExceededError {
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
impl DomExceptionQuotaExceededError {
|
||||
pub fn new(msg: &str) -> Self {
|
||||
DomExceptionQuotaExceededError {
|
||||
msg: msg.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DomExceptionQuotaExceededError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad(&self.msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for DomExceptionQuotaExceededError {}
|
||||
|
||||
pub fn get_quota_exceeded_error_class_name(
|
||||
e: &AnyError,
|
||||
) -> Option<&'static str> {
|
||||
e.downcast_ref::<DomExceptionQuotaExceededError>()
|
||||
.map(|_| "DOMExceptionQuotaExceededError")
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DomExceptionNotSupportedError {
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
impl DomExceptionNotSupportedError {
|
||||
pub fn new(msg: &str) -> Self {
|
||||
DomExceptionNotSupportedError {
|
||||
msg: msg.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DomExceptionNotSupportedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad(&self.msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for DomExceptionNotSupportedError {}
|
||||
|
||||
pub fn get_not_supported_error_class_name(
|
||||
e: &AnyError,
|
||||
) -> Option<&'static str> {
|
||||
e.downcast_ref::<DomExceptionNotSupportedError>()
|
||||
.map(|_| "DOMExceptionNotSupportedError")
|
||||
}
|
|
@ -29,6 +29,7 @@ deno_web = { path = "../extensions/web", version = "0.35.0" }
|
|||
deno_webgpu = { path = "../extensions/webgpu", version = "0.6.0" }
|
||||
deno_webidl = { path = "../extensions/webidl", version = "0.5.0" }
|
||||
deno_websocket = { path = "../extensions/websocket", version = "0.10.0" }
|
||||
deno_webstorage = { path = "../extensions/webstorage", version = "0.1.0" }
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
winres = "0.1.11"
|
||||
|
@ -46,6 +47,7 @@ deno_web = { path = "../extensions/web", version = "0.35.0" }
|
|||
deno_webgpu = { path = "../extensions/webgpu", version = "0.6.0" }
|
||||
deno_webidl = { path = "../extensions/webidl", version = "0.5.0" }
|
||||
deno_websocket = { path = "../extensions/websocket", version = "0.10.0" }
|
||||
deno_webstorage = { path = "../extensions/webstorage", version = "0.1.0" }
|
||||
|
||||
atty = "0.2.14"
|
||||
bytes = "1"
|
||||
|
|
|
@ -48,6 +48,7 @@ fn create_runtime_snapshot(snapshot_path: &Path, files: Vec<PathBuf>) {
|
|||
"".to_owned(),
|
||||
None,
|
||||
),
|
||||
deno_webstorage::init(None),
|
||||
deno_crypto::init(None),
|
||||
deno_webgpu::init(false),
|
||||
deno_timers::init::<deno_timers::NoTimersPermission>(),
|
||||
|
|
|
@ -157,6 +157,8 @@ fn get_nix_error_class(error: &nix::Error) -> &'static str {
|
|||
pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
|
||||
deno_core::error::get_custom_error_class(e)
|
||||
.or_else(|| deno_webgpu::error::get_error_class_name(e))
|
||||
.or_else(|| deno_webstorage::get_quota_exceeded_error_class_name(e))
|
||||
.or_else(|| deno_webstorage::get_not_supported_error_class_name(e))
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<dlopen::Error>()
|
||||
.map(get_dlopen_error_class)
|
||||
|
|
|
@ -40,6 +40,7 @@ async fn main() -> Result<(), AnyError> {
|
|||
no_color: false,
|
||||
get_error_class_fn: Some(&get_error_class_name),
|
||||
location: None,
|
||||
location_data_dir: None,
|
||||
blob_url_store: BlobUrlStore::default(),
|
||||
};
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ delete Object.prototype.__proto__;
|
|||
const fileReader = window.__bootstrap.fileReader;
|
||||
const webgpu = window.__bootstrap.webgpu;
|
||||
const webSocket = window.__bootstrap.webSocket;
|
||||
const webStorage = window.__bootstrap.webStorage;
|
||||
const file = window.__bootstrap.file;
|
||||
const formData = window.__bootstrap.formData;
|
||||
const fetch = window.__bootstrap.fetch;
|
||||
|
@ -190,6 +191,18 @@ delete Object.prototype.__proto__;
|
|||
return new DOMException(msg, "OperationError");
|
||||
},
|
||||
);
|
||||
core.registerErrorBuilder(
|
||||
"DOMExceptionQuotaExceededError",
|
||||
function DOMExceptionQuotaExceededError(msg) {
|
||||
return new DOMException(msg, "QuotaExceededError");
|
||||
},
|
||||
);
|
||||
core.registerErrorBuilder(
|
||||
"DOMExceptionNotSupportedError",
|
||||
function DOMExceptionNotSupportedError(msg) {
|
||||
return new DOMException(msg, "NotSupported");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class Navigator {
|
||||
|
@ -351,6 +364,17 @@ delete Object.prototype.__proto__;
|
|||
alert: util.writable(prompt.alert),
|
||||
confirm: util.writable(prompt.confirm),
|
||||
prompt: util.writable(prompt.prompt),
|
||||
localStorage: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: webStorage.localStorage,
|
||||
},
|
||||
sessionStorage: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: webStorage.sessionStorage,
|
||||
},
|
||||
Storage: util.nonEnumerable(webStorage.Storage),
|
||||
};
|
||||
|
||||
const workerRuntimeGlobalProperties = {
|
||||
|
|
|
@ -10,6 +10,7 @@ pub use deno_web;
|
|||
pub use deno_webgpu;
|
||||
pub use deno_webidl;
|
||||
pub use deno_websocket;
|
||||
pub use deno_webstorage;
|
||||
|
||||
pub mod colors;
|
||||
pub mod errors;
|
||||
|
|
|
@ -69,6 +69,7 @@ pub struct WorkerOptions {
|
|||
pub no_color: bool,
|
||||
pub get_error_class_fn: Option<GetErrorClassFn>,
|
||||
pub location: Option<Url>,
|
||||
pub location_data_dir: Option<std::path::PathBuf>,
|
||||
pub blob_url_store: BlobUrlStore,
|
||||
}
|
||||
|
||||
|
@ -104,6 +105,7 @@ impl MainWorker {
|
|||
options.user_agent.clone(),
|
||||
options.ca_data.clone(),
|
||||
),
|
||||
deno_webstorage::init(options.location_data_dir.clone()),
|
||||
deno_crypto::init(options.seed),
|
||||
deno_webgpu::init(options.unstable),
|
||||
deno_timers::init::<Permissions>(),
|
||||
|
@ -291,6 +293,7 @@ mod tests {
|
|||
no_color: true,
|
||||
get_error_class_fn: None,
|
||||
location: None,
|
||||
location_data_dir: None,
|
||||
blob_url_store: BlobUrlStore::default(),
|
||||
};
|
||||
|
||||
|
|
26
tools/wpt.ts
26
tools/wpt.ts
|
@ -34,6 +34,10 @@ import {
|
|||
red,
|
||||
yellow,
|
||||
} from "https://deno.land/std@0.84.0/fmt/colors.ts";
|
||||
import {
|
||||
writeAll,
|
||||
writeAllSync,
|
||||
} from "https://deno.land/std@0.95.0/io/util.ts";
|
||||
import { saveExpectation } from "./wpt/utils.ts";
|
||||
|
||||
const command = Deno.args[0];
|
||||
|
@ -104,7 +108,7 @@ async function setup() {
|
|||
throw err;
|
||||
}
|
||||
});
|
||||
await Deno.writeAll(
|
||||
await writeAll(
|
||||
file,
|
||||
new TextEncoder().encode(
|
||||
"\n\n# Configured for Web Platform Tests (Deno)\n" + entries,
|
||||
|
@ -150,7 +154,7 @@ async function run() {
|
|||
rest.length == 0 ? undefined : rest,
|
||||
expectation,
|
||||
);
|
||||
assertAllExpectationsHaveTests(expectation, tests);
|
||||
assertAllExpectationsHaveTests(expectation, tests, rest);
|
||||
console.log(`Going to run ${tests.length} test files.`);
|
||||
|
||||
const results = await runWithTestUtil(false, async () => {
|
||||
|
@ -182,6 +186,7 @@ async function run() {
|
|||
function assertAllExpectationsHaveTests(
|
||||
expectation: Expectation,
|
||||
testsToRun: TestToRun[],
|
||||
filter?: string[],
|
||||
): void {
|
||||
const tests = new Set(testsToRun.map((t) => t.path));
|
||||
const missingTests: string[] = [];
|
||||
|
@ -189,6 +194,12 @@ function assertAllExpectationsHaveTests(
|
|||
function walk(parentExpectation: Expectation, parent: string) {
|
||||
for (const key in parentExpectation) {
|
||||
const path = `${parent}/${key}`;
|
||||
if (
|
||||
filter &&
|
||||
!filter.find((filter) => path.substring(1).startsWith(filter))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const expectation = parentExpectation[key];
|
||||
if (typeof expectation == "boolean" || Array.isArray(expectation)) {
|
||||
if (!tests.has(path)) {
|
||||
|
@ -422,7 +433,7 @@ function analyzeTestResult(
|
|||
function reportVariation(result: TestResult, expectation: boolean | string[]) {
|
||||
if (result.status !== 0) {
|
||||
console.log(`test stderr:`);
|
||||
Deno.writeAllSync(Deno.stdout, new TextEncoder().encode(result.stderr));
|
||||
writeAllSync(Deno.stdout, new TextEncoder().encode(result.stderr));
|
||||
|
||||
const expectFail = expectation === false;
|
||||
console.log(
|
||||
|
@ -508,7 +519,7 @@ function createReportTestCase(expectation: boolean | string[]) {
|
|||
break;
|
||||
}
|
||||
|
||||
console.log(simpleMessage);
|
||||
writeAllSync(Deno.stdout, new TextEncoder().encode(simpleMessage + "\n"));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -536,7 +547,12 @@ function discoverTestsToRun(
|
|||
) {
|
||||
if (!path) continue;
|
||||
const url = new URL(path, "http://web-platform.test:8000");
|
||||
if (!url.pathname.endsWith(".any.html")) continue;
|
||||
if (
|
||||
!url.pathname.endsWith(".any.html") &&
|
||||
!url.pathname.endsWith(".window.html")
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const finalPath = url.pathname + url.search;
|
||||
|
||||
const split = finalPath.split("/");
|
||||
|
|
|
@ -1064,6 +1064,66 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"webstorage": {
|
||||
"defineProperty.window.html": true,
|
||||
"set.window.html": true,
|
||||
"storage_enumerate.window.html": true,
|
||||
"storage_in.window.html": true,
|
||||
"event_constructor.window.html": false,
|
||||
"event_initstorageevent.window.html": false,
|
||||
"missing_arguments.window.html": true,
|
||||
"storage_builtins.window.html": true,
|
||||
"storage_clear.window.html": true,
|
||||
"storage_functions_not_overwritten.window.html": true,
|
||||
"storage_getitem.window.html": true,
|
||||
"storage_indexing.window.html": true,
|
||||
"storage_key.window.html": true,
|
||||
"storage_key_empty_string.window.html": true,
|
||||
"storage_length.window.html": true,
|
||||
"storage_local_setitem_quotaexceedederr.window.html": true,
|
||||
"storage_local_window_open.window.html": false,
|
||||
"storage_removeitem.window.html": true,
|
||||
"storage_session_setitem_quotaexceedederr.window.html": true,
|
||||
"storage_session_window_noopener.window.html": false,
|
||||
"storage_session_window_open.window.html": false,
|
||||
"storage_set_value_enumerate.window.html": true,
|
||||
"storage_setitem.window.html": [
|
||||
"localStorage[\"\ud800\"]",
|
||||
"localStorage[] = \"\ud800\"",
|
||||
"localStorage[\"\udbff\"]",
|
||||
"localStorage[] = \"\udbff\"",
|
||||
"localStorage[\"\udc00\"]",
|
||||
"localStorage[] = \"\udc00\"",
|
||||
"localStorage[\"\udfff\"]",
|
||||
"localStorage[] = \"\udfff\"",
|
||||
"localStorage[\"\\ufffd\"]",
|
||||
"localStorage[] = \"\\ufffd\"",
|
||||
"localStorage[\"\ud83ca\"]",
|
||||
"localStorage[] = \"\ud83ca\"",
|
||||
"localStorage[\"a\udf4d\"]",
|
||||
"localStorage[] = \"a\udf4d\"",
|
||||
"sessionStorage[\"\ud800\"]",
|
||||
"sessionStorage[] = \"\ud800\"",
|
||||
"sessionStorage[\"\udbff\"]",
|
||||
"sessionStorage[] = \"\udbff\"",
|
||||
"sessionStorage[\"\udc00\"]",
|
||||
"sessionStorage[] = \"\udc00\"",
|
||||
"sessionStorage[\"\udfff\"]",
|
||||
"sessionStorage[] = \"\udfff\"",
|
||||
"sessionStorage[\"\\ufffd\"]",
|
||||
"sessionStorage[] = \"\\ufffd\"",
|
||||
"sessionStorage[\"\ud83ca\"]",
|
||||
"sessionStorage[] = \"\ud83ca\"",
|
||||
"sessionStorage[\"a\udf4d\"]",
|
||||
"sessionStorage[] = \"a\udf4d\""
|
||||
],
|
||||
"storage_string_conversion.window.html": true,
|
||||
"storage_supported_property_names.window.html": true,
|
||||
"symbol-props.window.html": [
|
||||
"localStorage: defineProperty not configurable",
|
||||
"sessionStorage: defineProperty not configurable"
|
||||
]
|
||||
},
|
||||
"xhr": {
|
||||
"formdata": {
|
||||
"append.any.html": true,
|
||||
|
|
Loading…
Reference in a new issue