Spaces:
Running
Running
File size: 4,829 Bytes
9bd422a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | /**
* ModelLoader - Bộ Tải Mô Hình
* Tải danh sách mô hình từ models/models.json và các tệp mô hình ONNX
* Requirements: 1.1, 1.2, 1.3, 1.5, 3.1, 3.2
*/
class ModelLoader {
constructor() {
/** @type {Array|null} In-memory cache for the model list */
this._modelListCache = null;
}
/**
* Tải danh sách mô hình từ tệp cấu hình JSON
* @param {string} configPath - Đường dẫn đến tệp models.json
* @returns {Promise<Array<{id, name, description, path, category, version, size, labelsFile?}>>}
*/
async loadModelList(configPath = CONFIG.MODELS_CONFIG_FILE) {
// Return cached list if available (Requirement 15.4)
if (this._modelListCache !== null) {
console.log('[ModelLoader] Returning cached model list');
return this._modelListCache;
}
try {
const response = await fetch(configPath);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const json = await response.json();
if (!json || !Array.isArray(json.models)) {
throw new Error('Invalid models.json format: missing "models" array');
}
const models = json.models.map(model => ({
id: model.id || '',
name: model.name || '',
description: model.description || '',
path: model.path || '',
category: model.category || '',
version: model.version || '',
size: model.size || 0,
labelsFile: model.labelsFile || null
}));
// Cache the result in memory
this._modelListCache = models;
return models;
} catch (error) {
console.error('[ModelLoader] Failed to load model list:', error);
return [];
}
}
/**
* Tải tệp mô hình ONNX từ đường dẫn
* @param {string} filePath - Đường dẫn đến tệp .onnx
* @returns {Promise<ArrayBuffer>}
* @throws {Error} Nếu không thể tải tệp
*/
async loadModelFile(filePath) {
const response = await fetch(filePath);
if (!response.ok) {
throw new Error(`Failed to load model file "${filePath}": HTTP ${response.status} ${response.statusText}`);
}
const buffer = await response.arrayBuffer();
return buffer;
}
/**
* Xử lý tải lên tệp từ người dùng
* @param {File} file - Đối tượng File từ input hoặc drag-and-drop
* @returns {Promise<{success: boolean, data?: ArrayBuffer, error?: string}>}
*/
async handleFileUpload(file) {
// Xác thực tệp tồn tại
if (!file) {
return { success: false, error: 'No file provided.' };
}
// Xác thực phần mở rộng tệp
const fileName = file.name || '';
const hasValidExtension = CONFIG.FILE.ALLOWED_EXTENSIONS.some(ext =>
fileName.toLowerCase().endsWith(ext)
);
if (!hasValidExtension) {
const allowed = CONFIG.FILE.ALLOWED_EXTENSIONS.join(', ');
return {
success: false,
error: `Invalid file type. Only ${allowed} files are supported.`
};
}
// Xác thực kích thước tệp
if (file.size > CONFIG.FILE.MAX_FILE_SIZE) {
const maxMB = Math.round(CONFIG.FILE.MAX_FILE_SIZE / (1024 * 1024));
return {
success: false,
error: `File is too large. Maximum allowed size is ${maxMB}MB.`
};
}
// Đọc tệp dưới dạng ArrayBuffer
try {
const data = await this._readFileAsArrayBuffer(file);
return { success: true, data };
} catch (error) {
console.error('[ModelLoader] Failed to read uploaded file:', error);
return {
success: false,
error: `Failed to read file: ${error.message || CONFIG.ERRORS.UPLOAD_ERROR}`
};
}
}
/**
* Đọc File object dưới dạng ArrayBuffer
* @param {File} file
* @returns {Promise<ArrayBuffer>}
* @private
*/
_readFileAsArrayBuffer(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => resolve(event.target.result);
reader.onerror = () => reject(new Error(reader.error ? reader.error.message : 'FileReader error'));
reader.readAsArrayBuffer(file);
});
}
}
// Export as global for browser usage
window.ModelLoader = ModelLoader;
|