311 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			311 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!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> |