Added database faker for when indexedb is disabled
Database is now in a context with a status New FAQ for indexdb errors
This commit is contained in:
parent
05d5c76c86
commit
60059ff447
@ -9,6 +9,7 @@
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"dexie": "^2.0.4",
|
||||
"fake-indexeddb": "^3.0.0",
|
||||
"interactjs": "^1.9.7",
|
||||
"normalize-wheel": "^1.0.1",
|
||||
"react": "^16.13.0",
|
||||
|
39
src/App.js
39
src/App.js
@ -9,28 +9,31 @@ import About from "./routes/About";
|
||||
import FAQ from "./routes/FAQ";
|
||||
|
||||
import { AuthProvider } from "./contexts/AuthContext";
|
||||
import { DatabaseProvider } from "./contexts/DatabaseContext";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<ThemeProvider theme={theme}>
|
||||
<AuthProvider>
|
||||
<Router>
|
||||
<Switch>
|
||||
<Route path="/about">
|
||||
<About />
|
||||
</Route>
|
||||
<Route path="/faq">
|
||||
<FAQ />
|
||||
</Route>
|
||||
<Route path="/game/:id">
|
||||
<Game />
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Home />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</AuthProvider>
|
||||
<DatabaseProvider>
|
||||
<AuthProvider>
|
||||
<Router>
|
||||
<Switch>
|
||||
<Route path="/about">
|
||||
<About />
|
||||
</Route>
|
||||
<Route path="/faq">
|
||||
<FAQ />
|
||||
</Route>
|
||||
<Route path="/game/:id">
|
||||
<Game />
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Home />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</AuthProvider>
|
||||
</DatabaseProvider>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
import React from "react";
|
||||
import { Flex } from "theme-ui";
|
||||
import React, { useContext } from "react";
|
||||
import { Flex, Box, Text } from "theme-ui";
|
||||
import SimpleBar from "simplebar-react";
|
||||
|
||||
import AddIcon from "../../icons/AddIcon";
|
||||
|
||||
import MapTile from "./MapTile";
|
||||
import Link from "../Link";
|
||||
|
||||
import DatabaseContext from "../../contexts/DatabaseContext";
|
||||
|
||||
function MapTiles({
|
||||
maps,
|
||||
@ -16,59 +19,80 @@ function MapTiles({
|
||||
onMapReset,
|
||||
onSubmit,
|
||||
}) {
|
||||
const { databaseStatus } = useContext(DatabaseContext);
|
||||
return (
|
||||
<SimpleBar style={{ maxHeight: "300px", width: "500px" }}>
|
||||
<Flex
|
||||
py={2}
|
||||
bg="muted"
|
||||
sx={{
|
||||
flexWrap: "wrap",
|
||||
width: "500px",
|
||||
borderRadius: "4px",
|
||||
}}
|
||||
>
|
||||
<Box sx={{ position: "relative" }}>
|
||||
<SimpleBar style={{ maxHeight: "300px", width: "500px" }}>
|
||||
<Flex
|
||||
onClick={onMapAdd}
|
||||
sx={{
|
||||
":hover": {
|
||||
color: "primary",
|
||||
},
|
||||
":focus": {
|
||||
outline: "none",
|
||||
},
|
||||
":active": {
|
||||
color: "secondary",
|
||||
},
|
||||
width: "150px",
|
||||
height: "150px",
|
||||
borderRadius: "4px",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
m={2}
|
||||
py={2}
|
||||
bg="muted"
|
||||
aria-label="Add Map"
|
||||
title="Add Map"
|
||||
sx={{
|
||||
flexWrap: "wrap",
|
||||
width: "500px",
|
||||
borderRadius: "4px",
|
||||
}}
|
||||
>
|
||||
<AddIcon large />
|
||||
<Flex
|
||||
onClick={onMapAdd}
|
||||
sx={{
|
||||
":hover": {
|
||||
color: "primary",
|
||||
},
|
||||
":focus": {
|
||||
outline: "none",
|
||||
},
|
||||
":active": {
|
||||
color: "secondary",
|
||||
},
|
||||
width: "150px",
|
||||
height: "150px",
|
||||
borderRadius: "4px",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
m={2}
|
||||
bg="muted"
|
||||
aria-label="Add Map"
|
||||
title="Add Map"
|
||||
>
|
||||
<AddIcon large />
|
||||
</Flex>
|
||||
{maps.map((map) => (
|
||||
<MapTile
|
||||
key={map.id}
|
||||
map={map}
|
||||
mapState={
|
||||
selectedMap && map.id === selectedMap.id && selectedMapState
|
||||
}
|
||||
isSelected={selectedMap && map.id === selectedMap.id}
|
||||
onMapSelect={onMapSelect}
|
||||
onMapRemove={onMapRemove}
|
||||
onMapReset={onMapReset}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
))}
|
||||
</Flex>
|
||||
{maps.map((map) => (
|
||||
<MapTile
|
||||
key={map.id}
|
||||
map={map}
|
||||
mapState={
|
||||
selectedMap && map.id === selectedMap.id && selectedMapState
|
||||
}
|
||||
isSelected={selectedMap && map.id === selectedMap.id}
|
||||
onMapSelect={onMapSelect}
|
||||
onMapRemove={onMapRemove}
|
||||
onMapReset={onMapReset}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
))}
|
||||
</Flex>
|
||||
</SimpleBar>
|
||||
</SimpleBar>
|
||||
{databaseStatus === "disabled" && (
|
||||
<Box
|
||||
sx={{
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
textAlign: "center",
|
||||
}}
|
||||
bg="highlight"
|
||||
p={1}
|
||||
>
|
||||
<Text as="p" variant="body2">
|
||||
Map saving is unavailable. See <Link to="/faq">FAQ</Link> for more
|
||||
information.
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,15 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
import shortid from "shortid";
|
||||
|
||||
import { getRandomMonster } from "../helpers/monsters";
|
||||
import DatabaseContext from "./DatabaseContext";
|
||||
|
||||
import db from "../database";
|
||||
import { getRandomMonster } from "../helpers/monsters";
|
||||
|
||||
const AuthContext = React.createContext();
|
||||
|
||||
export function AuthProvider({ children }) {
|
||||
const { database } = useContext(DatabaseContext);
|
||||
|
||||
const [password, setPassword] = useState(
|
||||
sessionStorage.getItem("auth") || ""
|
||||
);
|
||||
@ -20,41 +22,47 @@ export function AuthProvider({ children }) {
|
||||
|
||||
const [userId, setUserId] = useState();
|
||||
useEffect(() => {
|
||||
if (!database) {
|
||||
return;
|
||||
}
|
||||
async function loadUserId() {
|
||||
const storedUserId = await db.table("user").get("userId");
|
||||
const storedUserId = await database.table("user").get("userId");
|
||||
if (storedUserId) {
|
||||
setUserId(storedUserId.value);
|
||||
} else {
|
||||
const id = shortid.generate();
|
||||
setUserId(id);
|
||||
db.table("user").add({ key: "userId", value: id });
|
||||
database.table("user").add({ key: "userId", value: id });
|
||||
}
|
||||
}
|
||||
|
||||
loadUserId();
|
||||
}, []);
|
||||
}, [database]);
|
||||
|
||||
const [nickname, setNickname] = useState("");
|
||||
useEffect(() => {
|
||||
if (!database) {
|
||||
return;
|
||||
}
|
||||
async function loadNickname() {
|
||||
const storedNickname = await db.table("user").get("nickname");
|
||||
const storedNickname = await database.table("user").get("nickname");
|
||||
if (storedNickname) {
|
||||
setNickname(storedNickname.value);
|
||||
} else {
|
||||
const name = getRandomMonster();
|
||||
setNickname(name);
|
||||
db.table("user").add({ key: "nickname", value: name });
|
||||
database.table("user").add({ key: "nickname", value: name });
|
||||
}
|
||||
}
|
||||
|
||||
loadNickname();
|
||||
}, []);
|
||||
}, [database]);
|
||||
|
||||
useEffect(() => {
|
||||
if (nickname !== undefined) {
|
||||
db.table("user").update("nickname", { value: nickname });
|
||||
if (nickname !== undefined && database !== undefined) {
|
||||
database.table("user").update("nickname", { value: nickname });
|
||||
}
|
||||
}, [nickname]);
|
||||
}, [nickname, database]);
|
||||
|
||||
const value = {
|
||||
userId,
|
||||
|
54
src/contexts/DatabaseContext.js
Normal file
54
src/contexts/DatabaseContext.js
Normal file
@ -0,0 +1,54 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import Dexie from "dexie";
|
||||
|
||||
const DatabaseContext = React.createContext();
|
||||
|
||||
export function DatabaseProvider({ children }) {
|
||||
const [database, setDatabase] = useState();
|
||||
const [databaseStatus, setDatabaseStatus] = useState("loading");
|
||||
|
||||
function loadVersions(db) {
|
||||
db.version(1).stores({
|
||||
maps: "id, owner",
|
||||
states: "mapId",
|
||||
tokens: "id, owner",
|
||||
user: "key",
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
// Create a test database and open it to see if indexedDB is enabled
|
||||
let testDBRequest = window.indexedDB.open("__test");
|
||||
testDBRequest.onsuccess = function () {
|
||||
testDBRequest.result.close();
|
||||
let db = new Dexie("OwlbearRodeoDB");
|
||||
loadVersions(db);
|
||||
setDatabase(db);
|
||||
setDatabaseStatus("loaded");
|
||||
window.indexedDB.deleteDatabase("__test");
|
||||
};
|
||||
// If indexedb disabled create an in memory database
|
||||
testDBRequest.onerror = async function () {
|
||||
console.warn("Database is disabled, no state will be saved");
|
||||
const indexedDB = await import("fake-indexeddb");
|
||||
const IDBKeyRange = await import("fake-indexeddb/lib/FDBKeyRange");
|
||||
let db = new Dexie("OwlbearRodeoDB", { indexedDB, IDBKeyRange });
|
||||
loadVersions(db);
|
||||
setDatabase(db);
|
||||
setDatabaseStatus("disabled");
|
||||
window.indexedDB.deleteDatabase("__test");
|
||||
};
|
||||
}, []);
|
||||
|
||||
const value = {
|
||||
database,
|
||||
databaseStatus,
|
||||
};
|
||||
return (
|
||||
<DatabaseContext.Provider value={value}>
|
||||
{children}
|
||||
</DatabaseContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default DatabaseContext;
|
@ -1,11 +0,0 @@
|
||||
import Dexie from "dexie";
|
||||
|
||||
const db = new Dexie("OwlbearRodeoDB");
|
||||
db.version(1).stores({
|
||||
maps: "id, owner",
|
||||
states: "mapId",
|
||||
tokens: "id, owner",
|
||||
user: "key",
|
||||
});
|
||||
|
||||
export default db;
|
@ -2,13 +2,12 @@ import React, { useRef, useState, useEffect, useContext } from "react";
|
||||
import { Box, Button, Flex, Label, Text } from "theme-ui";
|
||||
import shortid from "shortid";
|
||||
|
||||
import db from "../database";
|
||||
|
||||
import Modal from "../components/Modal";
|
||||
import MapTiles from "../components/map/MapTiles";
|
||||
import MapSettings from "../components/map/MapSettings";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import DatabaseContext from "../contexts/DatabaseContext";
|
||||
|
||||
import usePrevious from "../helpers/usePrevious";
|
||||
import blobToBuffer from "../helpers/blobToBuffer";
|
||||
@ -43,6 +42,7 @@ function SelectMapModal({
|
||||
// The map currently being view in the map screen
|
||||
currentMap,
|
||||
}) {
|
||||
const { database } = useContext(DatabaseContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
|
||||
const wasOpen = usePrevious(isOpen);
|
||||
@ -55,7 +55,7 @@ function SelectMapModal({
|
||||
const [maps, setMaps] = useState([]);
|
||||
// Load maps from the database and ensure state is properly setup
|
||||
useEffect(() => {
|
||||
if (!userId) {
|
||||
if (!userId || !database) {
|
||||
return;
|
||||
}
|
||||
async function getDefaultMaps() {
|
||||
@ -73,16 +73,16 @@ function SelectMapModal({
|
||||
...defaultMapProps,
|
||||
});
|
||||
// Add a state for the map if there isn't one already
|
||||
const state = await db.table("states").get(id);
|
||||
const state = await database.table("states").get(id);
|
||||
if (!state) {
|
||||
await db.table("states").add({ ...defaultMapState, mapId: id });
|
||||
await database.table("states").add({ ...defaultMapState, mapId: id });
|
||||
}
|
||||
}
|
||||
return defaultMapsWithIds;
|
||||
}
|
||||
|
||||
async function loadMaps() {
|
||||
let storedMaps = await db
|
||||
let storedMaps = await database
|
||||
.table("maps")
|
||||
.where({ owner: userId })
|
||||
.toArray();
|
||||
@ -93,7 +93,7 @@ function SelectMapModal({
|
||||
|
||||
// reload map state as is may have changed while the modal was closed
|
||||
if (selectedMap) {
|
||||
const state = await db.table("states").get(selectedMap.id);
|
||||
const state = await database.table("states").get(selectedMap.id);
|
||||
if (state) {
|
||||
setSelectedMapState(state);
|
||||
}
|
||||
@ -103,7 +103,7 @@ function SelectMapModal({
|
||||
if (!wasOpen && isOpen) {
|
||||
loadMaps();
|
||||
}
|
||||
}, [userId, isOpen, wasOpen, selectedMap]);
|
||||
}, [userId, database, isOpen, wasOpen, selectedMap]);
|
||||
|
||||
const fileInputRef = useRef();
|
||||
|
||||
@ -180,21 +180,21 @@ function SelectMapModal({
|
||||
}
|
||||
|
||||
async function handleMapAdd(map) {
|
||||
await db.table("maps").add(map);
|
||||
await database.table("maps").add(map);
|
||||
const state = { ...defaultMapState, mapId: map.id };
|
||||
await db.table("states").add(state);
|
||||
await database.table("states").add(state);
|
||||
setMaps((prevMaps) => [map, ...prevMaps]);
|
||||
setSelectedMap(map);
|
||||
setSelectedMapState(state);
|
||||
}
|
||||
|
||||
async function handleMapRemove(id) {
|
||||
await db.table("maps").delete(id);
|
||||
await db.table("states").delete(id);
|
||||
await database.table("maps").delete(id);
|
||||
await database.table("states").delete(id);
|
||||
setMaps((prevMaps) => {
|
||||
const filtered = prevMaps.filter((map) => map.id !== id);
|
||||
setSelectedMap(filtered[0]);
|
||||
db.table("states").get(filtered[0].id).then(setSelectedMapState);
|
||||
database.table("states").get(filtered[0].id).then(setSelectedMapState);
|
||||
return filtered;
|
||||
});
|
||||
// Removed the map from the map screen if needed
|
||||
@ -204,14 +204,14 @@ function SelectMapModal({
|
||||
}
|
||||
|
||||
async function handleMapSelect(map) {
|
||||
const state = await db.table("states").get(map.id);
|
||||
const state = await database.table("states").get(map.id);
|
||||
setSelectedMapState(state);
|
||||
setSelectedMap(map);
|
||||
}
|
||||
|
||||
async function handleMapReset(id) {
|
||||
const state = { ...defaultMapState, mapId: id };
|
||||
await db.table("states").put(state);
|
||||
await database.table("states").put(state);
|
||||
setSelectedMapState(state);
|
||||
// Reset the state of the current map if needed
|
||||
if (currentMap && currentMap.id === selectedMap.id) {
|
||||
@ -261,7 +261,7 @@ function SelectMapModal({
|
||||
|
||||
async function handleMapSettingsChange(key, value) {
|
||||
const change = { [key]: value, lastModified: Date.now() };
|
||||
db.table("maps").update(selectedMap.id, change);
|
||||
database.table("maps").update(selectedMap.id, change);
|
||||
const newMap = { ...selectedMap, ...change };
|
||||
setMaps((prevMaps) => {
|
||||
const newMaps = [...prevMaps];
|
||||
@ -275,7 +275,7 @@ function SelectMapModal({
|
||||
}
|
||||
|
||||
async function handleMapStateSettingsChange(key, value) {
|
||||
db.table("states").update(selectedMap.id, { [key]: value });
|
||||
database.table("states").update(selectedMap.id, { [key]: value });
|
||||
setSelectedMapState((prevState) => ({ ...prevState, [key]: value }));
|
||||
}
|
||||
|
||||
|
@ -4,20 +4,20 @@ import { Box, Label, Flex, Button, useColorMode, Checkbox } from "theme-ui";
|
||||
import Modal from "../components/Modal";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
|
||||
import db from "../database";
|
||||
import DatabaseContext from "../contexts/DatabaseContext";
|
||||
|
||||
function SettingsModal({ isOpen, onRequestClose }) {
|
||||
const { database } = useContext(DatabaseContext);
|
||||
const { userId } = useContext(AuthContext);
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
|
||||
async function handleEraseAllData() {
|
||||
await db.delete();
|
||||
await database.delete();
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
async function handleClearCache() {
|
||||
await db.table("maps").where("owner").notEqual(userId).delete();
|
||||
await database.table("maps").where("owner").notEqual(userId).delete();
|
||||
// TODO: With custom tokens look up all tokens that aren't being used in a state
|
||||
window.location.reload();
|
||||
}
|
||||
|
@ -131,6 +131,20 @@ function FAQ() {
|
||||
</ExternalLink>
|
||||
.
|
||||
</Text>
|
||||
<Text my={1} variant="heading" as="h2" sx={{ fontSize: 3 }}>
|
||||
Saving
|
||||
</Text>
|
||||
<Text my={1} variant="heading" as="h3">
|
||||
Database is disabled.
|
||||
</Text>
|
||||
<Text variant="body2" as="p">
|
||||
Owlbear Rodeo uses a local database to store saved data. If you are
|
||||
seeing a database is disabled message this usually means you have data
|
||||
storage disabled. The most common occurances of this is if you are
|
||||
using Private Browsing modes or in Firefox have the Never Remember
|
||||
History option enabled. The site will still function in these cases
|
||||
however all data will be lost when the page closes or reloads.
|
||||
</Text>
|
||||
</Flex>
|
||||
<Footer />
|
||||
</Flex>
|
||||
|
@ -2,8 +2,6 @@ import React, { useState, useEffect, useCallback, useContext } from "react";
|
||||
import { Flex, Box, Text } from "theme-ui";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import db from "../database";
|
||||
|
||||
import { omit, isStreamStopped } from "../helpers/shared";
|
||||
import useSession from "../helpers/useSession";
|
||||
import useDebounce from "../helpers/useDebounce";
|
||||
@ -18,10 +16,12 @@ import Link from "../components/Link";
|
||||
import AuthModal from "../modals/AuthModal";
|
||||
|
||||
import AuthContext from "../contexts/AuthContext";
|
||||
import DatabaseContext from "../contexts/DatabaseContext";
|
||||
|
||||
import { tokens as defaultTokens } from "../tokens";
|
||||
|
||||
function Game() {
|
||||
const { database } = useContext(DatabaseContext);
|
||||
const { id: gameId } = useParams();
|
||||
const { authenticationStatus, userId, nickname, setNickname } = useContext(
|
||||
AuthContext
|
||||
@ -78,11 +78,14 @@ function Game() {
|
||||
debouncedMapState &&
|
||||
debouncedMapState.mapId &&
|
||||
map &&
|
||||
map.owner === userId
|
||||
map.owner === userId &&
|
||||
database
|
||||
) {
|
||||
db.table("states").update(debouncedMapState.mapId, debouncedMapState);
|
||||
database
|
||||
.table("states")
|
||||
.update(debouncedMapState.mapId, debouncedMapState);
|
||||
}
|
||||
}, [map, debouncedMapState, userId]);
|
||||
}, [map, debouncedMapState, userId, database]);
|
||||
|
||||
function handleMapChange(newMap, newMapState) {
|
||||
setMapState(newMapState);
|
||||
@ -267,7 +270,8 @@ function Game() {
|
||||
const newMap = data.data;
|
||||
// If is a file map check cache and request the full file if outdated
|
||||
if (newMap && newMap.type === "file") {
|
||||
db.table("maps")
|
||||
database
|
||||
.table("maps")
|
||||
.get(newMap.id)
|
||||
.then((cachedMap) => {
|
||||
if (cachedMap && cachedMap.lastModified === newMap.lastModified) {
|
||||
@ -291,7 +295,8 @@ function Game() {
|
||||
if (data.data && data.data.type === "file") {
|
||||
const newMap = { ...data.data, file: data.data.file };
|
||||
// Store in db
|
||||
db.table("maps")
|
||||
database
|
||||
.table("maps")
|
||||
.put(newMap)
|
||||
.then(() => {
|
||||
setMap(newMap);
|
||||
|
57
yarn.lock
57
yarn.lock
@ -2652,6 +2652,11 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
base64-arraybuffer-es6@0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.5.0.tgz#27877d01148bcfb3919c17ecf64ea163d9bdba62"
|
||||
integrity sha512-UCIPaDJrNNj5jG2ZL+nzJ7czvZV/ZYX6LaIRgfVU1k1edJOQg7dkbiSKzwHkNp6aHEHER/PhlFBrMYnlvJJQEw==
|
||||
|
||||
base64-arraybuffer@0.1.5:
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
|
||||
@ -3493,7 +3498,7 @@ core-js-pure@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a"
|
||||
integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==
|
||||
|
||||
core-js@^2.4.0:
|
||||
core-js@^2.4.0, core-js@^2.5.3:
|
||||
version "2.6.11"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
|
||||
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
|
||||
@ -4751,6 +4756,14 @@ extsprintf@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
fake-indexeddb@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-3.0.0.tgz#1bd0ffce41b0f433409df301d334d8fd7d77da27"
|
||||
integrity sha512-VrnV9dJWlVWvd8hp9MMR+JS4RLC4ZmToSkuCg91ZwpYE5mSODb3n5VEaV62Hf3AusnbrPfwQhukU+rGZm5W8PQ==
|
||||
dependencies:
|
||||
realistic-structured-clone "^2.0.1"
|
||||
setimmediate "^1.0.5"
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
|
||||
@ -9246,6 +9259,16 @@ readdirp@~3.3.0:
|
||||
dependencies:
|
||||
picomatch "^2.0.7"
|
||||
|
||||
realistic-structured-clone@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/realistic-structured-clone/-/realistic-structured-clone-2.0.2.tgz#2f8ec225b1f9af20efc79ac96a09043704414959"
|
||||
integrity sha512-5IEvyfuMJ4tjQOuKKTFNvd+H9GSbE87IcendSBannE28PTrbolgaVg5DdEApRKhtze794iXqVUFKV60GLCNKEg==
|
||||
dependencies:
|
||||
core-js "^2.5.3"
|
||||
domexception "^1.0.1"
|
||||
typeson "^5.8.2"
|
||||
typeson-registry "^1.0.0-alpha.20"
|
||||
|
||||
realpath-native@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c"
|
||||
@ -9797,7 +9820,7 @@ set-value@^2.0.0, set-value@^2.0.1:
|
||||
is-plain-object "^2.0.3"
|
||||
split-string "^3.0.1"
|
||||
|
||||
setimmediate@^1.0.4:
|
||||
setimmediate@^1.0.4, setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
|
||||
@ -10749,6 +10772,20 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typeson-registry@^1.0.0-alpha.20:
|
||||
version "1.0.0-alpha.35"
|
||||
resolved "https://registry.yarnpkg.com/typeson-registry/-/typeson-registry-1.0.0-alpha.35.tgz#b86abfe440e6ee69102eebb0e8c5a916dd182ff9"
|
||||
integrity sha512-a/NffrpFswBTyU6w2d6vjk62K1TZ45H64af9AfRbn7LXqNEfL+h+gw3OV2IaG+enfwqgLB5WmbkrNBaQuc/97A==
|
||||
dependencies:
|
||||
base64-arraybuffer-es6 "0.5.0"
|
||||
typeson "5.18.2"
|
||||
whatwg-url "7.1.0"
|
||||
|
||||
typeson@5.18.2, typeson@^5.8.2:
|
||||
version "5.18.2"
|
||||
resolved "https://registry.yarnpkg.com/typeson/-/typeson-5.18.2.tgz#0d217fc0e11184a66aa7ca0076d9aa7707eb7bc2"
|
||||
integrity sha512-Vetd+OGX05P4qHyHiSLdHZ5Z5GuQDrHHwSdjkqho9NSCYVSLSfRMjklD/unpHH8tXBR9Z/R05rwJSuMpMFrdsw==
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
|
||||
@ -11175,19 +11212,19 @@ whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0:
|
||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
||||
|
||||
whatwg-url@^6.4.1:
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8"
|
||||
integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==
|
||||
whatwg-url@7.1.0, whatwg-url@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"
|
||||
integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==
|
||||
dependencies:
|
||||
lodash.sortby "^4.7.0"
|
||||
tr46 "^1.0.1"
|
||||
webidl-conversions "^4.0.2"
|
||||
|
||||
whatwg-url@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"
|
||||
integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==
|
||||
whatwg-url@^6.4.1:
|
||||
version "6.5.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8"
|
||||
integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==
|
||||
dependencies:
|
||||
lodash.sortby "^4.7.0"
|
||||
tr46 "^1.0.1"
|
||||
|
Loading…
Reference in New Issue
Block a user