Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions mm2src/mm2_db/src/indexed_db/drivers/builder.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{construct_event_closure, DbUpgrader, IdbDatabaseImpl, OnUpgradeError, OnUpgradeNeededCb, OPEN_DATABASES};
use crate::indexed_db::get_idb_factory;
use common::{log::info, stringify_js_error};
use derive_more::Display;
use futures::channel::mpsc;
Expand Down Expand Up @@ -73,12 +74,7 @@ impl IdbDatabaseBuilder {
let (table_names, on_upgrade_needed_handlers) = Self::tables_into_parts(self.tables)?;
info!("Open '{}' database with tables: {:?}", self.db_name, table_names);

let window = web_sys::window().expect("!window");
let indexed_db = match window.indexed_db() {
Ok(Some(db)) => db,
Ok(None) => return MmError::err(InitDbError::NotSupported("Unknown error".to_owned())),
Err(e) => return MmError::err(InitDbError::NotSupported(stringify_js_error(&e))),
};
let indexed_db = get_idb_factory()?;

let db_request = match indexed_db.open_with_u32(&self.db_name, self.db_version) {
Ok(r) => r,
Expand Down
30 changes: 30 additions & 0 deletions mm2src/mm2_db/src/indexed_db/indexed_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use async_trait::async_trait;
use common::executor::spawn_local;
use common::log::debug;
use common::stringify_js_error;
use derive_more::Display;
use futures::channel::{mpsc, oneshot};
use futures::StreamExt;
Expand All @@ -22,6 +23,8 @@ use serde_json::{self as json, Value as Json};
use std::collections::HashMap;
use std::marker::PhantomData;
use std::sync::Mutex;
use wasm_bindgen::JsCast;
use web_sys::{Window, WorkerGlobalScope};

macro_rules! try_serialize_index_value {
($exp:expr, $index:expr) => {{
Expand Down Expand Up @@ -805,6 +808,33 @@ fn open_cursor(
result_tx.send(Ok(event_tx)).ok();
}

/// Detects the current execution environment (window or worker) and follows the appropriate way
/// of getting `web_sys::IdbFactory` instance.
pub(crate) fn get_idb_factory() -> Result<web_sys::IdbFactory, InitDbError> {
let global = js_sys::global();

let idb_factory = if let Some(window) = global.dyn_ref::<Window>() {
window.indexed_db()
} else if let Some(worker) = global.dyn_ref::<WorkerGlobalScope>() {
worker.indexed_db()
} else {
return Err(InitDbError::NotSupported("Unknown WASM environment.".to_string()));
};

match idb_factory {
Ok(Some(db)) => Ok(db),
Ok(None) => Err(InitDbError::NotSupported(
if global.dyn_ref::<Window>().is_some() {
"IndexedDB not supported in window context"
} else {
"IndexedDB not supported in worker context"
}
.to_string(),
)),
Err(e) => Err(InitDbError::NotSupported(stringify_js_error(&e))),
}
}

/// Internal events.
mod internal {
use super::*;
Expand Down
21 changes: 18 additions & 3 deletions mm2src/mm2_net/src/wasm_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::collections::HashMap;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::JsFuture;
use web_sys::{Request, RequestInit, RequestMode, Response as JsResponse};
use web_sys::{Request, RequestInit, RequestMode, Response as JsResponse, Window, WorkerGlobalScope};

/// The result containing either a pair of (HTTP status code, body) or a stringified error.
pub type FetchResult<T> = Result<(StatusCode, T), MmError<SlurpError>>;
Expand Down Expand Up @@ -48,6 +48,22 @@ pub async fn slurp_post_json(url: &str, body: String) -> SlurpResult {
.map(|(status_code, response)| (status_code, HeaderMap::new(), response.into_bytes()))
}

/// This function is a wrapper around the `fetch_with_request`, providing compatibility across
/// different execution environments, such as window and worker.
fn compatible_fetch_with_request(js_request: &web_sys::Request) -> MmResult<js_sys::Promise, SlurpError> {
let global = js_sys::global();

if let Some(scope) = global.dyn_ref::<Window>() {
return Ok(scope.fetch_with_request(js_request));
}

if let Some(scope) = global.dyn_ref::<WorkerGlobalScope>() {
return Ok(scope.fetch_with_request(js_request));
}

MmError::err(SlurpError::Internal("Unknown WASM environment.".to_string()))
}

pub struct FetchRequest {
uri: String,
method: FetchMethod,
Expand Down Expand Up @@ -147,7 +163,6 @@ impl FetchRequest {
}

async fn fetch(request: Self) -> FetchResult<JsResponse> {
let window = web_sys::window().expect("!window");
let uri = request.uri;

let mut req_init = RequestInit::new();
Expand All @@ -167,7 +182,7 @@ impl FetchRequest {
.map_to_mm(|e| SlurpError::Internal(stringify_js_error(&e)))?;
}

let request_promise = window.fetch_with_request(&js_request);
let request_promise = compatible_fetch_with_request(&js_request)?;

let future = JsFuture::from(request_promise);
let resp_value = future.await.map_to_mm(|e| SlurpError::Transport {
Expand Down