mirror of
https://github.com/denoland/deno.git
synced 2025-09-29 13:44:47 +00:00
feat: blob URL support (#10045)
This commit adds blob URL support. Blob URLs are stored in a process global storage, that can be accessed from all workers, and the module loader. Blob URLs can be created using `URL.createObjectURL` and revoked using `URL.revokeObjectURL`. This commit does not add support for `fetch`ing blob URLs. This will be added in a follow up commit.
This commit is contained in:
parent
2865f39bec
commit
966ce7de8a
33 changed files with 488 additions and 33 deletions
|
@ -1,7 +1,85 @@
|
|||
// 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::url::Url;
|
||||
use deno_core::JsRuntime;
|
||||
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(Clone)]
|
||||
pub struct Blob {
|
||||
pub data: Vec<u8>,
|
||||
pub media_type: String,
|
||||
}
|
||||
|
||||
pub struct Location(pub Url);
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct BlobUrlStore(Arc<Mutex<HashMap<Url, Blob>>>);
|
||||
|
||||
impl BlobUrlStore {
|
||||
pub fn get(&self, url: &ModuleSpecifier) -> Result<Option<Blob>, AnyError> {
|
||||
let blob_store = self.0.lock().unwrap();
|
||||
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,
|
||||
_zero_copy: Option<ZeroCopyBuf>,
|
||||
) -> Result<(), AnyError> {
|
||||
let url = Url::parse(&url)?;
|
||||
let blob_store = state.borrow::<BlobUrlStore>();
|
||||
blob_store.remove(&url);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Load and execute the javascript code.
|
||||
pub fn init(isolate: &mut JsRuntime) {
|
||||
|
@ -11,6 +89,10 @@ pub fn init(isolate: &mut JsRuntime) {
|
|||
"deno:op_crates/file/02_filereader.js",
|
||||
include_str!("02_filereader.js"),
|
||||
),
|
||||
(
|
||||
"deno:op_crates/file/03_blob_url.js",
|
||||
include_str!("03_blob_url.js"),
|
||||
),
|
||||
];
|
||||
for (url, source_code) in files {
|
||||
isolate.execute(url, source_code).unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue