From 58e8ae0759ccfa97c478ccae4e0778bdce70966f Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 22 Jan 2026 22:40:02 +0000
Subject: [PATCH] =DirectoryManager.php updates, some javascript tweaks for CRUD.js, and minor style changes

---
 assets/js/concise/DataStore.js |   35 ++++++++++++++++++++++++++---------
 1 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/assets/js/concise/DataStore.js b/assets/js/concise/DataStore.js
index 3610c26..58ec874 100644
--- a/assets/js/concise/DataStore.js
+++ b/assets/js/concise/DataStore.js
@@ -45,7 +45,7 @@
 	 * @param {object|array} configs An object defining the store, or an array of objects defining the stores
 	 * @param {number} version the database version
 	 */
-	register(name, configs = [], version = 1.1) {
+	register(name, configs = [], version = 1.2) {
 		if (!Array.isArray(configs)) configs = [configs];
 		if (configs.length === 0) return;
 
@@ -471,13 +471,16 @@
 
 			let result;
 			tx.oncomplete = () => resolve(result);
-			tx.onerror = () => reject(tx.error);
+			tx.onerror = () => {
+				const error = tx.error || new Error('Transaction failed with unknown error');
+				reject(error);
+			};
 
 			// Call callback immediately to queue operations
 			try {
 				result = callback(objectStore, tx);
 			} catch (error) {
-				reject(error);
+				reject(error || new Error('Callback failed with unknown error'));
 			}
 		});
 	}
@@ -589,11 +592,13 @@
 			return data;
 
 		} catch (error) {
-			if (error.name !== 'AbortError') {
+			const isAbortError = error?.name === 'AbortError';
+
+			if (!isAbortError) {
 				console.error(`Fetch error for store "${name}":`, error);
 				this.notify(name, 'fetch-error', { error });
+				throw error;
 			}
-			throw error;
 
 		} finally {
 			store.isFetching = false;
@@ -628,8 +633,8 @@
 	 */
 	async processFetchedData(name, data, cacheKey, response) {
 		const store = this.stores.get(name);
-		const items = data.items || [];
-		const changes = []; // Track all changes
+		const items = (data.items || []).filter(item => item && typeof item === 'object');
+		const changes = [];
 
 		// Batch process with single transaction
 		if (store.db && items.length > 0) {
@@ -829,7 +834,15 @@
 	}
 
 	processForStorage(obj, validate = true, path = 'root') {
-		if (obj === null || obj === undefined) return { valid: true, data: obj };
+		if (obj === null) {
+			return { valid: true, data: null };
+		}
+		if (obj === undefined) {
+			if (validate) {
+				return { valid: false, error: `Undefined value at ${path}` };
+			}
+			return { valid: true, data: undefined };
+		}
 
 		const type = typeof obj;
 
@@ -890,7 +903,10 @@
 			for (const [key, value] of Object.entries(obj)) {
 				const result = this.processForStorage(value, validate, `${path}.${key}`);
 				if (!result.valid) return result;
-				if (result.data !== undefined) processed[key] = result.data;
+				// Include null values, skip undefined
+				if (result.data !== undefined || value === null) {
+					processed[key] = result.data;
+				}
 			}
 			return { valid: true, data: processed };
 		}
@@ -1005,6 +1021,7 @@
 		if (!store) return [];
 
 		return Array.from(store.data.values()).filter(item => {
+			if (!item || typeof item !== 'object') return false;
 			return Object.entries(criteria).every(([key, value]) => {
 				const accepted = Array.isArray(value) ? value : [value];
 				return accepted.includes(item[key]);

--
Gitblit v1.10.0