Clean up loading code, much cleaner invocation during init (and less prone to races)

This commit is contained in:
hppeng 2022-06-12 07:45:48 -07:00
parent 0f4dba258f
commit 4f7f0f9cfc
5 changed files with 411 additions and 237 deletions

View file

@ -335,16 +335,11 @@ function init() {
console.log("builder.js init"); console.log("builder.js init");
init_autocomplete(); init_autocomplete();
decodeBuild(url_tag); decodeBuild(url_tag);
for (const i of equipment_keys) {
update_field(i);
}
} }
function init2() { //load_init(init3);
load_ing_init(init); (async function() {
} let load_promises = [ load_init(), load_ing_init(), load_tome_init() ];
function init3() { await Promise.all(load_promises);
load_tome_init(init2) init();
} })();
load_init(init3);

View file

@ -19,3 +19,197 @@ document.addEventListener('DOMContentLoaded', function() {
console.log("Set up graph"); console.log("Set up graph");
}); });
// autocomplete initialize
function init_autocomplete() {
console.log("autocomplete init");
console.log(itemLists)
let dropdowns = new Map();
for (const eq of equipment_keys) {
if (tome_keys.includes(eq)) {
continue;
}
// build dropdown
let item_arr = [];
if (eq == 'weapon') {
for (const weaponType of weapon_keys) {
for (const weapon of itemLists.get(weaponType)) {
let item_obj = itemMap.get(weapon);
if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") {
continue;
}
if (item_obj["name"] == 'No '+ eq.charAt(0).toUpperCase() + eq.slice(1)) {
continue;
}
item_arr.push(weapon);
}
}
} else {
for (const item of itemLists.get(eq.replace(/[0-9]/g, ''))) {
let item_obj = itemMap.get(item);
if (item_obj["restrict"] && item_obj["restrict"] === "DEPRECATED") {
continue;
}
if (item_obj["name"] == 'No '+ eq.charAt(0).toUpperCase() + eq.slice(1)) {
continue;
}
item_arr.push(item)
}
}
// create dropdown
dropdowns.set(eq, new autoComplete({
data: {
src: item_arr
},
selector: "#"+ eq +"-choice",
wrapper: false,
resultsList: {
maxResults: 1000,
tabSelect: true,
noResults: true,
class: "search-box dark-7 rounded-bottom px-2 fw-bold dark-shadow-sm",
element: (list, data) => {
// dynamic result loc
let position = document.getElementById(eq+'-dropdown').getBoundingClientRect();
list.style.top = position.bottom + window.scrollY +"px";
list.style.left = position.x+"px";
list.style.width = position.width+"px";
list.style.maxHeight = position.height * 2 +"px";
if (!data.results.length) {
message = document.createElement('li');
message.classList.add('scaled-font');
message.textContent = "No results found!";
list.prepend(message);
}
},
},
resultItem: {
class: "scaled-font search-item",
selected: "dark-5",
element: (item, data) => {
item.classList.add(itemMap.get(data.value).tier);
},
},
events: {
input: {
selection: (event) => {
if (event.detail.selection.value) {
event.target.value = event.detail.selection.value;
}
},
},
}
}));
}
for (const eq of tome_keys) {
// build dropdown
let tome_arr = [];
for (const tome of tomeLists.get(eq.replace(/[0-9]/g, ''))) {
let tome_obj = tomeMap.get(tome);
if (tome_obj["restrict"] && tome_obj["restrict"] === "DEPRECATED") {
continue;
}
//this should suffice for tomes - jank
if (tome_obj["name"].includes('No ' + eq.charAt(0).toUpperCase())) {
continue;
}
let tome_name = tome;
tome_arr.push(tome_name);
}
// create dropdown
dropdowns.set(eq, new autoComplete({
data: {
src: tome_arr
},
selector: "#"+ eq +"-choice",
wrapper: false,
resultsList: {
maxResults: 1000,
tabSelect: true,
noResults: true,
class: "search-box dark-7 rounded-bottom px-2 fw-bold dark-shadow-sm",
element: (list, data) => {
// dynamic result loc
let position = document.getElementById(eq+'-dropdown').getBoundingClientRect();
list.style.top = position.bottom + window.scrollY +"px";
list.style.left = position.x+"px";
list.style.width = position.width+"px";
list.style.maxHeight = position.height * 2 +"px";
if (!data.results.length) {
message = document.createElement('li');
message.classList.add('scaled-font');
message.textContent = "No results found!";
list.prepend(message);
}
},
},
resultItem: {
class: "scaled-font search-item",
selected: "dark-5",
element: (tome, data) => {
tome.classList.add(tomeMap.get(data.value).tier);
},
},
events: {
input: {
selection: (event) => {
if (event.detail.selection.value) {
event.target.value = event.detail.selection.value;
}
},
},
}
}));
}
let filter_loc = ["filter1", "filter2", "filter3", "filter4"];
for (const i of filter_loc) {
dropdowns.set(i+"-choice", new autoComplete({
data: {
src: sq2ItemFilters,
},
selector: "#"+i+"-choice",
wrapper: false,
resultsList: {
tabSelect: true,
noResults: true,
class: "search-box dark-7 rounded-bottom px-2 fw-bold dark-shadow-sm",
element: (list, data) => {
// dynamic result loc
console.log(i);
list.style.zIndex = "100";
let position = document.getElementById(i+"-dropdown").getBoundingClientRect();
window_pos = document.getElementById("search-container").getBoundingClientRect();
list.style.top = position.bottom - window_pos.top + 5 +"px";
list.style.left = position.x - window_pos.x +"px";
list.style.width = position.width+"px";
if (!data.results.length) {
message = document.createElement('li');
message.classList.add('scaled-font');
message.textContent = "No filters found!";
list.prepend(message);
}
},
},
resultItem: {
class: "scaled-font search-item",
selected: "dark-5",
},
events: {
input: {
selection: (event) => {
if (event.detail.selection.value) {
event.target.value = event.detail.selection.value;
}
},
},
}
}));
}
}

View file

@ -14,42 +14,35 @@ let itemLists = new Map();
/* /*
* Load item set from local DB. Calls init() on success. * Load item set from local DB. Calls init() on success.
*/ */
async function load_local(init_func) { async function load_local() {
let get_tx = db.transaction(['item_db', 'set_db'], 'readonly'); return new Promise(function(resolve, reject) {
let sets_store = get_tx.objectStore('set_db'); let get_tx = db.transaction(['item_db', 'set_db'], 'readonly');
let get_store = get_tx.objectStore('item_db'); let sets_store = get_tx.objectStore('set_db');
let request = get_store.getAll(); let get_store = get_tx.objectStore('item_db');
request.onerror = function(event) { let request = get_store.getAll();
console.log("Could not read local item db..."); let request2 = sets_store.getAll();
} request.onerror = function(event) {
request.onsuccess = function(event) { reject("Could not read local item db...");
console.log("Successfully read local item db."); }
items = request.result; request.onsuccess = function(event) {
//console.log(items); console.log("Successfully read local item db.");
let request2 = sets_store.openCursor(); }
sets = {};
request2.onerror = function(event) { request2.onerror = function(event) {
console.log("Could not read local set db..."); reject("Could not read local set db...");
} }
request2.onsuccess = function(event) { request2.onsuccess = function(event) {
let cursor = event.target.result; console.log("Successfully read local set db.");
if (cursor) {
sets[cursor.primaryKey] = cursor.value;
cursor.continue();
}
else {
console.log("Successfully read local set db.");
//console.log(sets);
init_maps();
init_func();
load_complete = true;
}
} }
} get_tx.oncomplete = function(event) {
await get_tx.complete; items = request.result;
db.close(); sets = request2.result;
init_maps();
load_complete = true;
db.close();
resolve();
}
});
} }
/* /*
@ -91,7 +84,7 @@ function clean_item(item) {
/* /*
* Load item set from remote DB (aka a big json file). Calls init() on success. * Load item set from remote DB (aka a big json file). Calls init() on success.
*/ */
async function load(init_func) { async function load() {
let getUrl = window.location; let getUrl = window.location;
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";// + getUrl.pathname.split('/')[1]; let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";// + getUrl.pathname.split('/')[1];
@ -101,16 +94,6 @@ async function load(init_func) {
items = result.items; items = result.items;
sets = result.sets; sets = result.sets;
// let clear_tx = db.transaction(['item_db', 'set_db'], 'readwrite');
// let clear_items = clear_tx.objectStore('item_db');
// let clear_sets = clear_tx.objectStore('item_db');
//
// await clear_items.clear();
// await clear_sets.clear();
// await clear_tx.complete;
let add_tx = db.transaction(['item_db', 'set_db'], 'readwrite'); let add_tx = db.transaction(['item_db', 'set_db'], 'readwrite');
add_tx.onabort = function(e) { add_tx.onabort = function(e) {
console.log(e); console.log(e);
@ -131,74 +114,67 @@ async function load(init_func) {
add_promises.push(sets_store.add(sets[set], set)); add_promises.push(sets_store.add(sets[set], set));
} }
add_promises.push(add_tx.complete); add_promises.push(add_tx.complete);
Promise.all(add_promises).then((values) => {
init_maps(); await Promise.all(add_promises);
init_func(); init_maps();
load_complete = true; load_complete = true;
}); db.close();
// DB not closed? idfk man
} }
function load_init(init_func) { async function load_init() {
if (load_complete) { return new Promise((resolve, reject) => {
console.log("Item db already loaded, skipping load sequence"); let request = window.indexedDB.open('item_db', DB_VERSION);
init_func();
return;
}
let request = window.indexedDB.open('item_db', DB_VERSION);
request.onerror = function() { request.onerror = function() {
console.log("DB failed to open..."); reject("DB failed to open...");
}; };
request.onsuccess = function() { request.onsuccess = async function() {
(async function() {
db = request.result; db = request.result;
if (!reload) { if (load_in_progress) {
console.log("Using stored data...") while (!load_complete) {
load_local(init_func); await sleep(100);
}
console.log("Skipping load...")
} }
else { else {
if (load_in_progress) { load_in_progress = true
while (!load_complete) { if (reload) {
await sleep(100); console.log("Using new data...")
} await load();
console.log("Skipping load...")
init_func();
} }
else { else {
// Not 100% safe... whatever! console.log("Using stored data...")
load_in_progress = true await load_local();
console.log("Using new data...")
load(init_func);
} }
} }
})() resolve();
} };
request.onupgradeneeded = function(e) { request.onupgradeneeded = function(e) {
reload = true; reload = true;
let db = e.target.result; let db = e.target.result;
try { try {
db.deleteObjectStore('item_db'); db.deleteObjectStore('item_db');
} }
catch (error) { catch (error) {
console.log("Could not delete item DB. This is probably fine"); console.log("Could not delete item DB. This is probably fine");
} }
try { try {
db.deleteObjectStore('set_db'); db.deleteObjectStore('set_db');
} }
catch (error) { catch (error) {
console.log("Could not delete set DB. This is probably fine"); console.log("Could not delete set DB. This is probably fine");
} }
db.createObjectStore('item_db'); db.createObjectStore('item_db');
db.createObjectStore('set_db'); db.createObjectStore('set_db');
console.log("DB setup complete..."); console.log("DB setup complete...");
} };
});
} }
// List of 'raw' "none" items (No Helmet, etc), in order helmet, chestplate... ring1, ring2, brace, neck, weapon. // List of 'raw' "none" items (No Helmet, etc), in order helmet, chestplate... ring1, ring2, brace, neck, weapon.

View file

@ -4,6 +4,7 @@ const ING_DB_VERSION = 13;
let idb; let idb;
let ireload = false; let ireload = false;
let iload_in_progress = false;
let iload_complete = false; let iload_complete = false;
let ings; let ings;
let recipes; let recipes;
@ -20,32 +21,34 @@ let recipeIDMap;
/* /*
* Load item set from local DB. Calls init() on success. * Load item set from local DB. Calls init() on success.
*/ */
async function ing_load_local(init_func) { async function ing_load_local() {
console.log("IngMap is: \n " + ingMap); return new Promise(function(resolve, reject) {
let get_tx = idb.transaction(['ing_db', 'recipe_db'], 'readonly'); let get_tx = idb.transaction(['ing_db', 'recipe_db'], 'readonly');
let ings_store = get_tx.objectStore('ing_db'); let ings_store = get_tx.objectStore('ing_db');
let recipes_store = get_tx.objectStore('recipe_db'); let recipes_store = get_tx.objectStore('recipe_db');
let request3 = ings_store.getAll(); let request3 = ings_store.getAll();
request3.onerror = function(event) { request3.onerror = function(event) {
console.log("Could not read local ingredient db..."); reject("Could not read local ingredient db...");
} }
request3.onsuccess = function(event) { request3.onsuccess = function(event) {
console.log("Successfully read local ingredient db."); console.log("Successfully read local ingredient db.");
ings = request3.result; }
let request4 = recipes_store.getAll(); let request4 = recipes_store.getAll();
request4.onerror = function(event) { request4.onerror = function(event) {
console.log("Could not read local recipe db..."); reject("Could not read local recipe db...");
} }
request4.onsuccess = function(event) { request4.onsuccess = function(event) {
console.log("Successfully read local recipe db."); console.log("Successfully read local recipe db.");
}
get_tx.oncomplete = function(event) {
ings = request3.result;
recipes = request4.result; recipes = request4.result;
init_ing_maps(); init_ing_maps();
init_func();
iload_complete = true; iload_complete = true;
idb.close();
resolve()
} }
} });
await get_tx.complete;
idb.close();
} }
function clean_ing(ing) { function clean_ing(ing) {
@ -59,11 +62,12 @@ function clean_ing(ing) {
/* /*
* Load item set from remote DB (aka a big json file). Calls init() on success. * Load item set from remote DB (aka a big json file). Calls init() on success.
*/ */
async function load_ings(init_func) { async function load_ings() {
let getUrl = window.location; let getUrl = window.location;
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/" + getUrl.pathname.split('/')[1]; let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";// + getUrl.pathname.split('/')[1];
let url = baseUrl + "/ingreds_compress.json"; // "Random" string to prevent caching!
let url = baseUrl + "/ingreds_compress.json?"+new Date();
url = url.replace(/\w+.html/, "") ; url = url.replace(/\w+.html/, "") ;
let result = await (await fetch(url)).json(); let result = await (await fetch(url)).json();
@ -97,59 +101,65 @@ async function load_ings(init_func) {
} }
add_promises.push(add_tx2.complete); add_promises.push(add_tx2.complete);
add_promises.push(add_tx3.complete); add_promises.push(add_tx3.complete);
Promise.all(add_promises).then((values) => {
init_ing_maps(); await Promise.all(add_promises);
init_func(); init_ing_maps();
iload_complete = true; iload_complete = true;
}); idb.close();
// DB not closed? idfk man
} }
function load_ing_init(init_func) { async function load_ing_init() {
if (iload_complete) { return new Promise((resolve, reject) => {
console.log("Ingredient db already loaded, skipping load sequence"); let request = window.indexedDB.open("ing_db", ING_DB_VERSION)
init_func(); request.onerror = function() {
return; reject("DB failed to open...");
} }
let request = window.indexedDB.open("ing_db", ING_DB_VERSION)
request.onerror = function() {
console.log("DB failed to open...");
}
request.onsuccess = function() { request.onsuccess = async function() {
idb = request.result; idb = request.result;
if (!ireload) { if (iload_in_progress) {
console.log("Using stored data...") while (!iload_complete) {
ing_load_local(init_func); await sleep(100);
}
console.log("Skipping load...")
}
else {
iload_in_progress = true
if (ireload) {
console.log("Using new data...")
await load_ings();
}
else {
console.log("Using stored data...")
await ing_load_local();
}
}
resolve();
} }
else {
console.log("Using new data...")
load_ings(init_func);
}
}
request.onupgradeneeded = function(e) { request.onupgradeneeded = function(e) {
ireload = true; ireload = true;
let idb = e.target.result; let idb = e.target.result;
try { try {
idb.deleteObjectStore('ing_db'); idb.deleteObjectStore('ing_db');
} }
catch (error) { catch (error) {
console.log("Could not delete ingredient DB. This is probably fine"); console.log("Could not delete ingredient DB. This is probably fine");
} }
try { try {
idb.deleteObjectStore('recipe_db'); idb.deleteObjectStore('recipe_db');
} }
catch (error) { catch (error) {
console.log("Could not delete recipe DB. This is probably fine"); console.log("Could not delete recipe DB. This is probably fine");
} }
idb.createObjectStore('ing_db'); idb.createObjectStore('ing_db');
idb.createObjectStore('recipe_db'); idb.createObjectStore('recipe_db');
console.log("DB setup complete..."); console.log("DB setup complete...");
} }
});
} }
function init_ing_maps() { function init_ing_maps() {
@ -222,4 +232,5 @@ function init_ing_maps() {
recipeList.push(recipe["name"]); recipeList.push(recipe["name"]);
recipeIDMap.set(recipe["id"],recipe["name"]); recipeIDMap.set(recipe["id"],recipe["name"]);
} }
console.log(ingMap);
} }

View file

@ -13,29 +13,33 @@ let tomeLists = new Map();
/* /*
* Load tome set from local DB. Calls init() on success. * Load tome set from local DB. Calls init() on success.
*/ */
async function load_tome_local(init_func) { async function load_tome_local() {
let get_tx = tdb.transaction(['tome_db'], 'readonly'); return new Promise(function(resolve, reject) {
let get_store = get_tx.objectStore('tome_db'); let get_tx = tdb.transaction(['tome_db'], 'readonly');
let request = get_store.getAll(); let get_store = get_tx.objectStore('tome_db');
request.onerror = function(event) { let request = get_store.getAll();
console.log("Could not read local tome db..."); request.onerror = function(event) {
} reject("Could not read local tome db...");
request.onsuccess = function(event) { }
console.log("Successfully read local tome db."); request.onsuccess = function(event) {
tomes = request.result; console.log("Successfully read local tome db.");
}
init_tome_maps(); get_tx.oncomplete = function(event) {
init_func(); console.log('b');
tload_complete = true; console.log(request.readyState);
} tomes = request.result;
await get_tx.complete; init_tome_maps();
tdb.close(); tload_complete = true;
tdb.close();
resolve();
}
});
} }
/* /*
* Load tome set from remote DB (json). Calls init() on success. * Load tome set from remote DB (json). Calls init() on success.
*/ */
async function load_tome(init_func) { async function load_tome() {
let getUrl = window.location; let getUrl = window.location;
let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";// + getUrl.pathname.split('/')[1]; let baseUrl = getUrl.protocol + "//" + getUrl.host + "/";// + getUrl.pathname.split('/')[1];
@ -60,67 +64,61 @@ async function load_tome(init_func) {
}; };
add_promises.push(req); add_promises.push(req);
} }
Promise.all(add_promises).then((values) => { add_promises.push(add_tx.complete);
init_tome_maps();
init_func(); await Promise.all(add_promises);
tload_complete = true; init_tome_maps();
}); tload_complete = true;
// DB not closed? idfk man tdb.close();
} }
function load_tome_init(init_func) { async function load_tome_init() {
if (tload_complete) { return new Promise((resolve, reject) => {
console.log("Tome db already loaded, skipping load sequence"); let request = window.indexedDB.open('tome_db', TOME_DB_VERSION);
init_func();
return;
}
let request = window.indexedDB.open('tome_db', TOME_DB_VERSION);
request.onerror = function() { request.onerror = function() {
console.log("DB failed to open..."); reject("DB failed to open...");
}; };
request.onsuccess = function() { request.onsuccess = async function() {
(async function() {
tdb = request.result; tdb = request.result;
if (!treload) { if (tload_in_progress) {
console.log("Using stored data...") while (!tload_complete) {
load_tome_local(init_func); await sleep(100);
}
console.log("Skipping load...")
} }
else { else {
if (tload_in_progress) { tload_in_progress = true
while (!tload_complete) { if (treload) {
await sleep(100); console.log("Using new data...")
} await load_tome();
console.log("Skipping load...")
init_func();
} }
else { else {
// Not 100% safe... whatever! console.log("Using stored data...")
tload_in_progress = true await load_tome_local();
console.log("Using new data...")
load_tome(init_func);
} }
} }
})() resolve();
}
request.onupgradeneeded = function(e) {
treload = true;
let tdb = e.target.result;
try {
tdb.deleteObjectStore('tome_db');
}
catch (error) {
console.log("Could not delete tome DB. This is probably fine");
} }
tdb.createObjectStore('tome_db'); request.onupgradeneeded = function(e) {
treload = true;
console.log("DB setup complete..."); let tdb = e.target.result;
}
try {
tdb.deleteObjectStore('tome_db');
}
catch (error) {
console.log("Could not delete tome DB. This is probably fine");
}
tdb.createObjectStore('tome_db');
console.log("DB setup complete...");
}
});
} }
function init_tome_maps() { function init_tome_maps() {