...
This commit is contained in:
311
www/debug.html
Normal file
311
www/debug.html
Normal file
@@ -0,0 +1,311 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>IndexedDB Inspector</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
color: #2c3e50;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
pre {
|
||||
background-color: #f8f8f8;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
overflow: auto;
|
||||
max-height: 400px;
|
||||
}
|
||||
button {
|
||||
background-color: #4CAF50;
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 10px 15px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
margin: 4px 2px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #45a049;
|
||||
}
|
||||
.error {
|
||||
color: #e74c3c;
|
||||
background-color: #fceaea;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
}
|
||||
th, td {
|
||||
padding: 12px 15px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
text-align: left;
|
||||
}
|
||||
th {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
tr:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>IndexedDB Inspector</h1>
|
||||
|
||||
<h2>Database Information</h2>
|
||||
<div>
|
||||
<p>Database Name: <strong>CryptoSpaceDB</strong></p>
|
||||
<p>Store Name: <strong>keySpaces</strong></p>
|
||||
</div>
|
||||
|
||||
<h2>Actions</h2>
|
||||
<div>
|
||||
<button id="list-dbs">List All Databases</button>
|
||||
<button id="open-db">Open CryptoSpaceDB</button>
|
||||
<button id="list-stores">List Object Stores</button>
|
||||
<button id="list-keys">List All Keys</button>
|
||||
</div>
|
||||
|
||||
<h2>Result</h2>
|
||||
<div id="result-area">
|
||||
<pre id="result">Results will appear here...</pre>
|
||||
</div>
|
||||
|
||||
<h2>Key-Value Viewer</h2>
|
||||
<div id="kv-viewer">
|
||||
<table id="kv-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="kv-body">
|
||||
<!-- Data will be populated here -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Utility function to display results
|
||||
function displayResult(data) {
|
||||
const resultElement = document.getElementById('result');
|
||||
if (typeof data === 'object') {
|
||||
resultElement.textContent = JSON.stringify(data, null, 2);
|
||||
} else {
|
||||
resultElement.textContent = data;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility function to display error
|
||||
function displayError(error) {
|
||||
const resultElement = document.getElementById('result');
|
||||
resultElement.textContent = `ERROR: ${error.message || error}`;
|
||||
resultElement.classList.add('error');
|
||||
}
|
||||
|
||||
// List all available databases
|
||||
document.getElementById('list-dbs').addEventListener('click', async () => {
|
||||
try {
|
||||
if (!window.indexedDB) {
|
||||
throw new Error("Your browser doesn't support IndexedDB");
|
||||
}
|
||||
|
||||
if (!indexedDB.databases) {
|
||||
displayResult("Your browser doesn't support indexedDB.databases() method. Try opening the database directly.");
|
||||
return;
|
||||
}
|
||||
|
||||
const databases = await indexedDB.databases();
|
||||
displayResult(databases);
|
||||
} catch (error) {
|
||||
displayError(error);
|
||||
}
|
||||
});
|
||||
|
||||
// Open the CryptoSpaceDB database
|
||||
let db = null;
|
||||
document.getElementById('open-db').addEventListener('click', () => {
|
||||
try {
|
||||
if (!window.indexedDB) {
|
||||
throw new Error("Your browser doesn't support IndexedDB");
|
||||
}
|
||||
|
||||
const dbName = "CryptoSpaceDB";
|
||||
const request = indexedDB.open(dbName);
|
||||
|
||||
request.onerror = (event) => {
|
||||
displayError(`Failed to open database: ${event.target.error}`);
|
||||
};
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
db = event.target.result;
|
||||
displayResult(`Successfully opened database: ${db.name}, version ${db.version}`);
|
||||
};
|
||||
|
||||
request.onupgradeneeded = (event) => {
|
||||
db = event.target.result;
|
||||
displayResult(`Database ${db.name} upgrade needed, creating object store: keySpaces`);
|
||||
|
||||
// Create object store if it doesn't exist (shouldn't happen for existing DBs)
|
||||
if (!db.objectStoreNames.contains("keySpaces")) {
|
||||
db.createObjectStore("keySpaces");
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
displayError(error);
|
||||
}
|
||||
});
|
||||
|
||||
// List all object stores in the database
|
||||
document.getElementById('list-stores').addEventListener('click', () => {
|
||||
try {
|
||||
if (!db) {
|
||||
throw new Error("Database not opened. Click 'Open CryptoSpaceDB' first.");
|
||||
}
|
||||
|
||||
const storeNames = Array.from(db.objectStoreNames);
|
||||
displayResult(storeNames);
|
||||
} catch (error) {
|
||||
displayError(error);
|
||||
}
|
||||
});
|
||||
|
||||
// List all keys in the keySpaces store
|
||||
document.getElementById('list-keys').addEventListener('click', () => {
|
||||
try {
|
||||
if (!db) {
|
||||
throw new Error("Database not opened. Click 'Open CryptoSpaceDB' first.");
|
||||
}
|
||||
|
||||
if (!db.objectStoreNames.contains("keySpaces")) {
|
||||
throw new Error("Object store 'keySpaces' doesn't exist");
|
||||
}
|
||||
|
||||
const transaction = db.transaction(["keySpaces"], "readonly");
|
||||
const store = transaction.objectStore("keySpaces");
|
||||
const request = store.getAllKeys();
|
||||
|
||||
request.onerror = (event) => {
|
||||
displayError(`Failed to get keys: ${event.target.error}`);
|
||||
};
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
const keys = event.target.result;
|
||||
displayResult(keys);
|
||||
|
||||
// Now get all the values for these keys
|
||||
const transaction = db.transaction(["keySpaces"], "readonly");
|
||||
const store = transaction.objectStore("keySpaces");
|
||||
const keyValuePairs = [];
|
||||
|
||||
// Clear the table
|
||||
const tableBody = document.getElementById('kv-body');
|
||||
tableBody.innerHTML = '';
|
||||
|
||||
// For each key, get its value
|
||||
let pendingRequests = keys.length;
|
||||
|
||||
if (keys.length === 0) {
|
||||
const row = tableBody.insertRow();
|
||||
const cell = row.insertCell(0);
|
||||
cell.colSpan = 3;
|
||||
cell.textContent = "No data found in the database";
|
||||
}
|
||||
|
||||
keys.forEach(key => {
|
||||
const request = store.get(key);
|
||||
|
||||
request.onerror = (event) => {
|
||||
displayError(`Failed to get value for key ${key}: ${event.target.error}`);
|
||||
pendingRequests--;
|
||||
};
|
||||
|
||||
request.onsuccess = (event) => {
|
||||
const value = event.target.result;
|
||||
keyValuePairs.push({ key, value });
|
||||
|
||||
// Add a row to the table
|
||||
const row = tableBody.insertRow();
|
||||
|
||||
// Key cell
|
||||
const keyCell = row.insertCell(0);
|
||||
keyCell.textContent = key;
|
||||
|
||||
// Value cell (truncated for display)
|
||||
const valueCell = row.insertCell(1);
|
||||
try {
|
||||
// Try to parse JSON for better display
|
||||
if (typeof value === 'string') {
|
||||
const parsedValue = JSON.parse(value);
|
||||
valueCell.innerHTML = `<pre>${JSON.stringify(parsedValue, null, 2).substring(0, 100)}${parsedValue.length > 100 ? '...' : ''}</pre>`;
|
||||
} else {
|
||||
valueCell.innerHTML = `<pre>${JSON.stringify(value, null, 2).substring(0, 100)}${value.length > 100 ? '...' : ''}</pre>`;
|
||||
}
|
||||
} catch (e) {
|
||||
// If not JSON, display as string with truncation
|
||||
valueCell.textContent = typeof value === 'string' ?
|
||||
`${value.substring(0, 100)}${value.length > 100 ? '...' : ''}` :
|
||||
String(value);
|
||||
}
|
||||
|
||||
// Actions cell
|
||||
const actionsCell = row.insertCell(2);
|
||||
const viewButton = document.createElement('button');
|
||||
viewButton.textContent = 'View Full';
|
||||
viewButton.addEventListener('click', () => {
|
||||
const valueStr = typeof value === 'object' ?
|
||||
JSON.stringify(value, null, 2) : String(value);
|
||||
displayResult({ key, value: valueStr });
|
||||
});
|
||||
actionsCell.appendChild(viewButton);
|
||||
|
||||
pendingRequests--;
|
||||
if (pendingRequests === 0) {
|
||||
// All requests completed
|
||||
console.log("All key-value pairs retrieved:", keyValuePairs);
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
} catch (error) {
|
||||
displayError(error);
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize by checking if IndexedDB is available
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
if (!window.indexedDB) {
|
||||
displayError("Your browser doesn't support IndexedDB");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user