138 lines
3.7 KiB
TypeScript
138 lines
3.7 KiB
TypeScript
import * as path from "path";
|
|
import * as fs from "fs-extra";
|
|
import * as electron from "electron";
|
|
|
|
export namespace v1 {
|
|
/* main entry */
|
|
interface LocalUICache {
|
|
fetch_history?: FetchStatus;
|
|
versions?: LocalUICacheEntry[];
|
|
|
|
remote_index?: UIVersion[] | UIVersion;
|
|
remote_index_channel?: string; /* only set if the last status was a channel only*/
|
|
|
|
local_index?: UIVersion;
|
|
}
|
|
|
|
interface FetchStatus {
|
|
timestamp: number;
|
|
/**
|
|
* 0 = success
|
|
* 1 = connect fail
|
|
* 2 = internal fail
|
|
*/
|
|
status: number;
|
|
}
|
|
|
|
interface LocalUICacheEntry {
|
|
version: UIVersion;
|
|
download_timestamp: number;
|
|
tar_file: string;
|
|
checksum: string; /* SHA512 */
|
|
}
|
|
|
|
export interface UIVersion {
|
|
channel: string;
|
|
version: string;
|
|
git_hash: string;
|
|
timestamp: number;
|
|
|
|
required_client?: string;
|
|
filename?: string;
|
|
|
|
client_shipped?: boolean;
|
|
}
|
|
}
|
|
|
|
export interface CacheFile {
|
|
version: number; /* currently 2 */
|
|
|
|
cached_ui_packs: CachedUIPack[];
|
|
}
|
|
|
|
export interface UIPackInfo {
|
|
timestamp: number; /* build timestamp */
|
|
version: string; /* not really used anymore */
|
|
versions_hash: string; /* used, identifies the version. Its the git hash. */
|
|
|
|
channel: string;
|
|
min_client_version: string; /* minimum version from the client required for the pack */
|
|
}
|
|
|
|
export interface CachedUIPack {
|
|
download_timestamp: number;
|
|
local_file_path: string;
|
|
local_checksum: string | "none"; /* sha512 of the locally downloaded file. */
|
|
//TODO: Get the remote checksum and compare them instead of the local one
|
|
|
|
pack_info: UIPackInfo;
|
|
|
|
status: "valid" | "invalid";
|
|
invalid_reason?: string;
|
|
}
|
|
|
|
let cached_loading_promise_: Promise<CacheFile>;
|
|
let ui_cache_: CacheFile = {
|
|
version: 2,
|
|
cached_ui_packs: []
|
|
};
|
|
async function load_() : Promise<CacheFile> {
|
|
const file = path.join(cache_path(), "data.json");
|
|
|
|
try {
|
|
if(!(await fs.pathExists(file))) {
|
|
return ui_cache_;
|
|
}
|
|
|
|
const data = await fs.readJSON(file) as CacheFile;
|
|
if(!data) {
|
|
throw "invalid data object";
|
|
} else if(typeof data["version"] !== "number") {
|
|
throw "invalid versions tag";
|
|
} else if(data["version"] !== 2) {
|
|
console.warn("UI cache file contains an old version. Ignoring file and may override with newer version.");
|
|
return ui_cache_;
|
|
}
|
|
|
|
/* validating data */
|
|
if(!Array.isArray(data.cached_ui_packs)) {
|
|
throw "Invalid 'cached_ui_packs' entry within the UI cache file";
|
|
}
|
|
|
|
return (ui_cache_ = data as CacheFile);
|
|
} catch(error) {
|
|
console.warn("Failed to load UI cache file: %o. This will cause loss of the file content.", error);
|
|
return ui_cache_;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Will not throw or return undefined!
|
|
*/
|
|
export function load() : Promise<CacheFile> {
|
|
if(cached_loading_promise_) return cached_loading_promise_;
|
|
return (cached_loading_promise_ = load_());
|
|
}
|
|
|
|
export function unload() {
|
|
ui_cache_ = undefined;
|
|
cached_loading_promise_ = undefined;
|
|
}
|
|
|
|
/**
|
|
* Will not throw anything
|
|
*/
|
|
export async function save() {
|
|
const file = path.join(cache_path(), "data.json");
|
|
try {
|
|
if(!(await fs.pathExists(path.dirname(file))))
|
|
await fs.mkdirs(path.dirname(file));
|
|
await fs.writeJson(file, ui_cache_);
|
|
} catch (error) {
|
|
console.error("Failed to save UI cache file. This will may cause some data loss: %o", error);
|
|
}
|
|
}
|
|
|
|
export function cache_path() {
|
|
return path.join(electron.app.getPath('userData'), "cache", "ui");
|
|
} |