Added IndexedDB utility functions for reading and writing bookmarks
Summary: These are utility function for reading from the IndexedDB and writing to it. This will be used for persistant storage of bookmarks. The reason I chose IndexedDB over local storage is due to the poor efficiency of stringifying and parsing a long list of bookmarks everytime we read and write to local storage. With IndexedDB we can modify a single value at a time. Bookmarks are passed around as a Map, with the key being the uri's and the common names being the values. This allows me to check if a specified uri is in the Map in O(1) time, so that I can highlight the star icon in the UI with gold. Reviewed By: jknoxville Differential Revision: D16498744 fbshipit-source-id: 7c7af28bf4eb3fcc985a71dfd61ffbdb8481b6a6
This commit is contained in:
committed by
Facebook Github Bot
parent
f6a4ad59c0
commit
e4601a89f3
31
flow-typed/indexedDB.js
vendored
Normal file
31
flow-typed/indexedDB.js
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
declare class DOMStringList {
|
||||||
|
+[key: number]: string;
|
||||||
|
+length: number;
|
||||||
|
item: number => string | null;
|
||||||
|
contains: string => boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare interface IDBDatabase extends EventTarget {
|
||||||
|
close(): void;
|
||||||
|
createObjectStore(
|
||||||
|
name: string,
|
||||||
|
options?: {
|
||||||
|
keyPath?: ?(string | string[]),
|
||||||
|
autoIncrement?: boolean,
|
||||||
|
...
|
||||||
|
},
|
||||||
|
): IDBObjectStore;
|
||||||
|
deleteObjectStore(name: string): void;
|
||||||
|
transaction(
|
||||||
|
storeNames: string | string[],
|
||||||
|
mode?: 'readonly' | 'readwrite' | 'versionchange',
|
||||||
|
): IDBTransaction;
|
||||||
|
name: string;
|
||||||
|
version: number;
|
||||||
|
objectStoreNames: string[];
|
||||||
|
objectStoreNames: DOMStringList;
|
||||||
|
onabort: (e: any) => mixed;
|
||||||
|
onclose: (e: any) => mixed;
|
||||||
|
onerror: (e: any) => mixed;
|
||||||
|
onversionchange: (e: any) => mixed;
|
||||||
|
}
|
||||||
94
src/plugins/navigation/util/indexedDB.js
Normal file
94
src/plugins/navigation/util/indexedDB.js
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2018-present Facebook.
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
* @format
|
||||||
|
* @flow strict-local
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type {Bookmark} from '../';
|
||||||
|
|
||||||
|
const FLIPPER_NAVIGATION_PLUGIN_DB = 'flipper_navigation_plugin_db';
|
||||||
|
const FLIPPER_NAVIGATION_PLUGIN_DB_VERSION = 1;
|
||||||
|
|
||||||
|
const BOOKMARKS_KEY = 'bookmarks';
|
||||||
|
|
||||||
|
const createBookmarksObjectStore: IDBDatabase => Promise<void> = (
|
||||||
|
db: IDBDatabase,
|
||||||
|
) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!db.objectStoreNames.contains(BOOKMARKS_KEY)) {
|
||||||
|
const bookmarksObjectStore = db.createObjectStore(BOOKMARKS_KEY, {
|
||||||
|
keyPath: 'uri',
|
||||||
|
});
|
||||||
|
bookmarksObjectStore.transaction.oncomplete = () => resolve();
|
||||||
|
bookmarksObjectStore.transaction.onerror = event =>
|
||||||
|
reject(event.target.error);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const initializeNavigationPluginDB: IDBDatabase => Promise<Array<void>> = (
|
||||||
|
db: IDBDatabase,
|
||||||
|
) => {
|
||||||
|
return Promise.all([createBookmarksObjectStore(db)]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openNavigationPluginDB: () => Promise<IDBDatabase> = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const openRequest = window.indexedDB.open(
|
||||||
|
FLIPPER_NAVIGATION_PLUGIN_DB,
|
||||||
|
FLIPPER_NAVIGATION_PLUGIN_DB_VERSION,
|
||||||
|
);
|
||||||
|
openRequest.onupgradeneeded = () => {
|
||||||
|
const db = openRequest.result;
|
||||||
|
initializeNavigationPluginDB(db).then(() => resolve(db));
|
||||||
|
};
|
||||||
|
openRequest.onerror = event => reject(event.target.error);
|
||||||
|
openRequest.onsuccess = () => resolve(openRequest.result);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const writeBookmarkToDB: Bookmark => Promise<void> = (
|
||||||
|
bookmark: Bookmark,
|
||||||
|
) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
openNavigationPluginDB()
|
||||||
|
.then((db: IDBDatabase) => {
|
||||||
|
const bookmarksObjectStore = db
|
||||||
|
.transaction(BOOKMARKS_KEY, 'readwrite')
|
||||||
|
.objectStore(BOOKMARKS_KEY);
|
||||||
|
const request = bookmarksObjectStore.put(bookmark);
|
||||||
|
request.onsuccess = () => resolve();
|
||||||
|
request.onerror = event => reject(event.target.error);
|
||||||
|
})
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const readBookmarksFromDB: () => Promise<Map<string, Bookmark>> = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const bookmarks = new Map();
|
||||||
|
openNavigationPluginDB()
|
||||||
|
.then((db: IDBDatabase) => {
|
||||||
|
const bookmarksObjectStore = db
|
||||||
|
.transaction(BOOKMARKS_KEY)
|
||||||
|
.objectStore(BOOKMARKS_KEY);
|
||||||
|
bookmarksObjectStore.openCursor().onsuccess = event => {
|
||||||
|
const cursor = event.target.result;
|
||||||
|
if (cursor) {
|
||||||
|
const bookmark = cursor.value;
|
||||||
|
bookmarks.set(bookmark.uri, bookmark);
|
||||||
|
cursor.continue();
|
||||||
|
} else {
|
||||||
|
resolve(bookmarks);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
bookmarksObjectStore.openCursor().onerror = event =>
|
||||||
|
reject(event.target.error);
|
||||||
|
})
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user