286 lines
8.4 KiB
JavaScript
286 lines
8.4 KiB
JavaScript
/**
|
|
* Cache API Functions for SageUtils
|
|
* Handles all server communication for cache operations
|
|
*/
|
|
|
|
/**
|
|
* Cache API Module for SageUtils
|
|
* Handles all server communication and cache data management
|
|
*/
|
|
|
|
import { api } from "../../../../scripts/api.js";
|
|
|
|
// Global cache data store
|
|
export let cacheData = {
|
|
hash: {},
|
|
info: {}
|
|
};
|
|
|
|
/**
|
|
* Fetch cache hash data from server
|
|
* @returns {Promise<Object>} - Hash data mapping file paths to hashes
|
|
*/
|
|
export async function fetchCacheHash() {
|
|
try {
|
|
const response = await api.fetchApi('/sage_cache/hash');
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
cacheData.hash = data;
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error fetching cache hash:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch cache info data from server
|
|
* @returns {Promise<Object>} - Info data mapping hashes to model information
|
|
*/
|
|
export async function fetchCacheInfo() {
|
|
try {
|
|
const response = await api.fetchApi('/sage_cache/info');
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
cacheData.info = data;
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error fetching cache info:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pull metadata for a specific file from Civitai
|
|
* @param {string} filePath - Full path to the model file
|
|
* @param {boolean} force - Whether to force re-pull even if data exists
|
|
* @returns {Promise<Object>} - API response
|
|
*/
|
|
export async function pullMetadata(filePath, force = false) {
|
|
try {
|
|
const response = await api.fetchApi('/sage_utils/pull_metadata', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
file_path: filePath,
|
|
force: force
|
|
})
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const result = await response.json();
|
|
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Unknown error occurred');
|
|
}
|
|
|
|
return result;
|
|
} catch (error) {
|
|
console.error('Error pulling metadata:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update cache info for a specific model
|
|
* @param {string} hash - Model hash
|
|
* @param {Object} updatedInfo - Updated model information
|
|
* @returns {Promise<Object>} - API response
|
|
*/
|
|
export async function updateCacheInfo(hash, updatedInfo) {
|
|
try {
|
|
const response = await api.fetchApi('/sage_utils/update_cache_info', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
hash: hash,
|
|
info: updatedInfo
|
|
})
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const result = await response.json();
|
|
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Unknown error occurred');
|
|
}
|
|
|
|
// Update local cache data
|
|
cacheData.info[hash] = updatedInfo;
|
|
|
|
return result;
|
|
} catch (error) {
|
|
console.error('Error updating cache info:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Refresh both hash and info cache data
|
|
* @returns {Promise<Array>} - Array containing [hashData, infoData]
|
|
*/
|
|
export async function refreshCacheData() {
|
|
try {
|
|
const [hashData, infoData] = await Promise.all([
|
|
fetchCacheHash(),
|
|
fetchCacheInfo()
|
|
]);
|
|
|
|
return [hashData, infoData];
|
|
} catch (error) {
|
|
console.error('Error refreshing cache data:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get file path for a given hash
|
|
* @param {string} hash - Model hash to find
|
|
* @returns {string|null} - File path or null if not found
|
|
*/
|
|
export function getFilePathForHash(hash) {
|
|
for (const [filePath, fileHash] of Object.entries(cacheData.hash)) {
|
|
if (fileHash === hash) {
|
|
return filePath;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Scan filesystem for model files in specified folder types
|
|
* @param {Array<string>} folderTypes - Array of folder types to scan (e.g., ['checkpoints', 'loras'])
|
|
* @returns {Promise<Object>} - Object mapping folder types to arrays of file paths
|
|
*/
|
|
export async function scanModelFolders(folderTypes = ['all']) {
|
|
try {
|
|
// Convert folderTypes array to query parameter
|
|
const folderType = folderTypes.length === 1 ? folderTypes[0] : 'all';
|
|
const url = `/sage_cache/scan_model_folders${folderType !== 'all' ? `?folderType=${folderType}` : ''}`;
|
|
|
|
const response = await api.fetchApi(url, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
return data;
|
|
} catch (error) {
|
|
console.error('Error scanning model folders:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reconcile cached model paths with the local filesystem without changing cache data.
|
|
* @returns {Promise<Object>} Path status lists and counts
|
|
*/
|
|
export async function reconcileCache() {
|
|
try {
|
|
const response = await api.fetchApi('/sage_cache/reconcile');
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const result = await response.json();
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Unable to reconcile model cache');
|
|
}
|
|
|
|
return result;
|
|
} catch (error) {
|
|
console.error('Error reconciling model cache:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch recent durable scan summaries.
|
|
* @returns {Promise<Array>} Scan history entries
|
|
*/
|
|
export async function fetchScanHistory() {
|
|
const response = await api.fetchApi('/sage_cache/scan_history');
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const result = await response.json();
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Unable to load scan history');
|
|
}
|
|
return result.history || [];
|
|
}
|
|
|
|
export async function previewScan(categories, scanMode = 'all', force = false, includeCached = true) {
|
|
const response = await api.fetchApi('/sage_cache/scan_preview', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
categories,
|
|
scan_mode: scanMode,
|
|
force,
|
|
include_cached: includeCached
|
|
})
|
|
});
|
|
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
const result = await response.json();
|
|
if (!result.success) throw new Error(result.error || 'Unable to preview scan');
|
|
return result.preview;
|
|
}
|
|
|
|
/**
|
|
* Fetch live registered model files joined with cached metadata.
|
|
* @returns {Promise<Object>} Inventory records and counts
|
|
*/
|
|
export async function fetchModelInventory() {
|
|
const response = await api.fetchApi('/sage_cache/inventory');
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const result = await response.json();
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Unable to load model inventory');
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Remove explicitly confirmed missing cache paths while preserving metadata.
|
|
* @param {Array<string>} paths - Paths from a reconciliation preview
|
|
* @returns {Promise<Object>} Cleanup result
|
|
*/
|
|
export async function cleanupMissingCachePaths(paths) {
|
|
const response = await api.fetchApi('/sage_cache/cleanup_missing', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ paths, confirm: true })
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const result = await response.json();
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Unable to clean missing cache paths');
|
|
}
|
|
return result;
|
|
}
|