From 0feb9db2b57725d47a7b3cc1e84ba5b9a7553b12 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Mon, 3 Jan 2022 12:11:23 +0100 Subject: add "blocking" and "repos" object stores --- common/indexeddb.js | 81 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 11 deletions(-) (limited to 'common') diff --git a/common/indexeddb.js b/common/indexeddb.js index e54d1ca..8a30ce4 100644 --- a/common/indexeddb.js +++ b/common/indexeddb.js @@ -63,7 +63,9 @@ const stores = [ ["file_uses", {keyPath: "hash_key"}], ["resources", {keyPath: "identifier"}], ["mappings", {keyPath: "identifier"}], - ["settings", {keyPath: "name"}] + ["settings", {keyPath: "name"}], + ["blocking", {keyPath: "pattern"}], + ["repos", {keyPath: "url"}] ]; let db = null; @@ -364,17 +366,31 @@ const remove_resource = (id, ctx) => remove_item("resources", id, ctx); const remove_mapping = (id, ctx) => remove_item("mappings", id, ctx); #EXPORT remove_mapping -/* A simplified kind of transaction for modifying just the "settings" store. */ -async function start_settings_transaction() +/* Function to retrieve all items from a given store. */ +async function get_all(store_name) +{ + const transaction = (await get_db()).transaction([store_name]); + const all_req = transaction.objectStore(store_name).getAll(); + + return (await wait_request(all_req)).target.result; +} +#EXPORT get_all + +/* + * A simplified kind of transaction for modifying stores without special + * inter-store integrity constraints ("settings", "blocking", "repos"). + */ +async function start_simple_transaction(store_name) { const db = await get_db(); - return make_context(db.transaction("settings", "readwrite"), {}); + return make_context(db.transaction(store_name, "readwrite"), {}); } +/* Functions to access the "settings" store. */ async function set_setting(name, value) { - const context = await start_settings_transaction(); - broadcast.prepare(context.sender, `idb_changes_settings`, name); + const context = await start_simple_transaction("settings"); + broadcast.prepare(context.sender, "idb_changes_settings", name); await idb_put(context.transaction, "settings", {name, value}); return finalize_transaction(context); } @@ -387,6 +403,51 @@ async function get_setting(name) } #EXPORT get_setting +/* Functions to access the "blocking" store. */ +async function set_allowed(pattern, allow=true) +{ + const context = await start_simple_transaction("blocking"); + broadcast.prepare(context.sender, "idb_changes_blocking", pattern); + if (allow === null) + await idb_del(context.transaction, "blocking", pattern); + else + await idb_put(context.transaction, "blocking", {pattern, allow}); + return finalize_transaction(context); +} +#EXPORT set_allowed + +const set_disallowed = pattern => set_allowed(pattern, false); +#EXPORT set_disallowed + +const set_default_allowing = pattern => set_allowed(pattern, null); +#EXPORT set_default_allowing + +async function get_allowing(pattern) +{ + const transaction = (await get_db()).transaction("blocking"); + return ((await idb_get(transaction, "blocking", pattern)) || {}).allow; +} +#EXPORT get_allowing + +/* Functions to access the "repos" store. */ +async function set_repo(url, remove=false) +{ + const context = await start_simple_transaction("repos"); + broadcast.prepare(context.sender, "idb_changes_repos", url); + if (remove) + await idb_del(context.transaction, "repos", url); + else + await idb_put(context.transaction, "repos", {url}); + return finalize_transaction(context); +} +#EXPORT set_repo + +const del_repo = url => set_repo(url, true); +#EXPORT del_repo + +const get_repos = () => get_all("repos").then(list => list.map(obj => obj.url)); +#EXPORT get_repos + /* Callback used when listening to broadcasts while tracking db changes. */ async function track_change(tracking, key) { @@ -426,14 +487,12 @@ async function start_tracking(store_name, onchange) broadcast.listener_connection(msg => track_change(tracking, msg[1])); broadcast.subscribe(tracking.listener, `idb_changes_${store_name}`); - const transaction = (await get_db()).transaction([store_name]); - const all_req = transaction.objectStore(store_name).getAll(); - - return [tracking, (await wait_request(all_req)).target.result]; + return [tracking, await get_all(store_name)]; } const track = {}; -for (const store_name of ["resources", "mappings", "settings"]) +const trackable = ["resources", "mappings", "settings", "blocking", "repos"]; +for (const store_name of trackable) track[store_name] = onchange => start_tracking(store_name, onchange); #EXPORT track -- cgit v1.2.3