Fix: Restore Native caching business logic and implement 3-mode launcher

- Implemented Default, Onsite, and Native launcher modes in launcher_file_cont.svelte.
- Restored background pre-caching logic with configurable timers in new LauncherBackgroundSync component.
- Fixed standard browser download regression for regular website mode.
- Modernized electron_relay to TypeScript and standardized bridge detection in layout.
- Detailed startup and background sync technical flow in documentation.
This commit is contained in:
Scott Idem
2026-01-23 15:17:50 -05:00
parent 20b41ebaef
commit 683ea0394d
11 changed files with 558 additions and 961 deletions

View File

@@ -1,333 +0,0 @@
/* ### Electron Specific JavaScript ### */
// import crypto from 'crypto';
// import {fs} from 'fs';
// import path from 'path';
// const crypto = require('crypto');
// const fs = require('fs');
// const fs_promises = require('node:fs/promises');
// const path = require('path');
// const { ipcRenderer } = require('electron');
// function sleep(milliseconds) {
// const date = Date.now();
// let currentDate = null;
// do {
// currentDate = Date.now();
// } while (currentDate - date < milliseconds);
// }
// // exports.check_hash_file_cache should no longer be needed with this.
// // Updated 2022-10-11
// export let check_hash_file_cache_v2 = async function check_hash_file_cache_v2({local_file_cache_path, hash, check_hash=false}) {
// console.log('*** check_hash_file_cache_v2() ***');
// console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}`);
// let hash_filename = `${hash}.file`;
// let subdirectory = hash_filename.substring(0,2);
// let subdirectory_path = path.join(local_file_cache_path, subdirectory);
// if (fs.existsSync(subdirectory_path)) {
// } else {
// console.log(`Hashed file subdirectory not found in cache: ${subdirectory_path}`);
// return null;
// }
// let hash_file_cache_path = path.join(subdirectory_path, hash_filename);
// if (fs.existsSync(hash_file_cache_path)) {
// console.log(`Hashed file exists in cache: ${hash_file_cache_path}`);
// if (check_hash) {
// const file_buffer = fs.readFileSync(hash_file_cache_path);
// const file_hash_sha256 = crypto.createHash('sha256');
// file_hash_sha256.update(file_buffer);
// const file_hash_sha256_check = file_hash_sha256.digest('hex');
// if (file_hash_sha256_check == hash) {
// console.log('File hash match', file_hash_sha256_check);
// } else {
// console.log('File hash does not match', file_hash_sha256_check);
// return false;
// }
// }
// return true;
// } else {
// console.log(`Hashed file not found in cache: ${hash_file_cache_path}`);
// return null;
// }
// }
// @ts-nocheck
// Updated 2022-05-07
export let kill_processes = async function kill_processes({ process_name_li = [] }) {
console.log('*** kill_processes() ***');
console.log(`Process Name List: ${process_name_li}`);
let fail_flag = null;
if (process_name_li) {
for (let i = 0; i < process_name_li.length; i++) {
// separate the keys and the values
let process_name = process_name_li[i];
let signal = null;
if (process_name == 'osit_aperture_wrapper') {
signal = 'INT'; // INT (interrupt) correctly stops the wrapper
}
let kill_processes_result = await native_app.kill_processes({
process_name: process_name,
signal: signal
});
console.log(kill_processes_result);
if (kill_processes_result) {
console.log('Killed process.');
// return kill_processes_result;
} else {
console.log('Did not kill process. Something went wrong.');
fail_flag = true;
// return false;
}
}
}
return fail_flag;
// let kill_processes_result = await native_app.kill_processes({process_name: process_name});
// console.log(kill_processes_result);
// if (kill_processes_result) {
// console.log('Killed process.');
// return kill_processes_result;
// } else {
// console.log('Did not kill process. Something went wrong.');
// return false;
// }
};
// Updated 2022-05-06
export let open_local_file = async function open_local_file({ file_path, filename }) {
console.log('*** open_local_file() ***');
console.log(`File Path: ${file_path}; Filename: ${filename}`);
console.log(
'Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory'
);
// let check_local_file_result = await native_app.check_local_file({local_file_path: file_path, filename: filename});
// console.log(check_local_file_result);
// if (check_local_file_result) {
// console.log('Local file found.');
// } else {
// console.log('Local file not found. Will not attempt to open.');
// return false;
// }
// console.log('Local file file found and ready to be opened.');
let open_local_file_result = await native_app.open_local_file({
local_file_path: file_path,
filename: filename
});
console.log(open_local_file_result);
if (open_local_file_result) {
console.log('Local file was opened.');
return open_local_file_result;
} else {
console.log('Local file was not opened. Something went wrong.');
return false;
}
};
// exports.open_local_file should no longer be needed with this.
// Updated 2022-10-11
export let open_local_file_v2 = async function open_local_file_v2({ file_path, filename }) {
console.log('*** open_local_file_v2() ***');
console.log(`Local File Path: ${file_path}; Filename: ${filename}`);
console.log(
'Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory'
);
let open_local_file_result = await ipcRenderer
.invoke('open_local_file', file_path, filename)
.then((result) => {
console.log('IPC open local file finished');
if (result) {
console.log('Local file was opened.');
return result;
} else {
console.log('Local file was not opened. Something went wrong.');
console.log(result);
return false;
}
console.log(result);
return true;
});
return open_local_file_result;
};
// // Updated 2022-05-06
// export let open_hash_file_to_temp = async function open_hash_file_to_temp({local_file_cache_path, hash, host_file_temp_path, filename}) {
// console.log('*** open_hash_file_to_temp() ***');
// console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Host File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
// console.log('Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory');
// let open_hash_file_to_temp_result = await native_app.open_hash_file_to_temp({local_file_cache_path: local_file_cache_path, hash: hash, host_file_temp_path: host_file_temp_path, filename: filename});
// console.log(open_hash_file_to_temp_result);
// if (open_hash_file_to_temp_result) {
// console.log('Local hash file was opened from temp directory.');
// return open_hash_file_to_temp_result;
// } else {
// console.log('Local hash file was not opened from the temp directory. Something went wrong.');
// return false;
// }
// }
// // exports.open_hash_file_to_temp should no longer be needed with this.
// // Updated 2022-10-11
// export let open_hash_file_to_temp_v2 = async function open_hash_file_to_temp_v2({local_file_cache_path, hash, host_file_temp_path, filename}) {
// console.log('*** open_hash_file_to_temp_v2() ***');
// console.log(`Host File Cache Path: ${local_file_cache_path}; Hash: ${hash}; Host File Temp Path: ${host_file_temp_path}; Filename: ${filename}`);
// console.log('Process: Check local hash file cache, Download hash file to cache, and Open cached hash file after copying to temp directory');
// let subdirectory = hash.substring(0,2);
// let subdirectory_path = path.join(local_file_cache_path, subdirectory);
// if (fs.existsSync(subdirectory_path)) {
// } else {
// console.log(`Hashed file subdirectory not found in cache: ${subdirectory_path}`);
// return null;
// }
// let hash_filename = hash+'.file';
// let full_cache_file_path = path.join(subdirectory_path, hash_filename);
// console.log(full_cache_file_path);
// const file_buffer = fs.readFileSync(full_cache_file_path);
// const file_hash_sha256 = crypto.createHash('sha256');
// file_hash_sha256.update(file_buffer);
// const file_hash_sha256_check = file_hash_sha256.digest('hex');
// if (file_hash_sha256_check == hash) {
// console.log('File hash match', file_hash_sha256_check);
// } else {
// console.log('File hash does not match', file_hash_sha256_check);
// // await setTimeout(async () => {console.log('Done waiting????'); open_file_clicked = false;}, 5000);
// // sleep(6000);
// // console.log('???????? WAITED X SECONDS ????????');
// return false;
// }
// let open_hash_file_to_temp_result = await ipcRenderer.invoke('open_hash_file_to_temp', subdirectory_path, hash, host_file_temp_path, filename).then((result) => {
// console.log('IPC open hash file to temp finished');
// if (result) {
// console.log('Local hash file was opened from temp directory.');
// return result;
// } else {
// console.log('Local hash file was not opened from the temp directory. Something went wrong.');
// console.log(result);
// return false;
// }
// })
// return open_hash_file_to_temp_result;
// }
// Updated 2022-05-07
export let run_cmd = async function run_cmd({ cmd = null, return_stdout = null }) {
console.log('*** run_cmd() ***');
let run_cmd_result = await native_app
.run_cmd({ cmd: cmd, return_stdout: return_stdout })
.then(function (result) {
if (result) {
console.log('Command ran');
} else {
console.log('Command did not run. Something went wrong.');
return false;
}
if (return_stdout) {
return result;
} else {
return true;
}
});
console.log('Run Command Result:', run_cmd_result);
return run_cmd_result;
};
// Updated 2022-10-27
export let run_cmd_sync = function run_cmd_sync({ cmd = null, return_stdout = null }) {
console.log('*** run_cmd_sync() ***');
let run_cmd_result = native_app.run_cmd_sync({ cmd: cmd, return_stdout: return_stdout });
// if (run_cmd_result) {
// console.log('Command ran');
// } else {
// console.log('Command did not run. Something went wrong.');
// // return false;
// }
// if (return_stdout) {
// return run_cmd_result;
// } else {
// return true;
// }
console.log('Run Command Result:', run_cmd_result);
return run_cmd_result;
};
// Updated 2022-05-07
export let run_osascript = async function run_osascript({
cmd = null,
interactive = false,
language = null,
flags = 'h',
program_file = null
}) {
console.log('*** run_osascript() ***');
let run_osascript_result = await native_app.run_osascript({
cmd: cmd,
interactive: interactive,
language: language,
flags: flags,
program_file: program_file
});
console.log(run_osascript_result);
if (run_osascript_result) {
console.log('Apple Script ran');
} else {
console.log('Apple Script did not run. Something went wrong.');
}
return run_osascript_result;
};
// Updated 2022-05-07
export let get_device_info = async function get_device_info({ event_device_id }) {
console.log('*** get_device_info() ***');
console.log(event_device_id);
let get_device_info_result = await native_app.get_device_info();
console.log(get_device_info_result);
if (get_device_info_result) {
console.log('Success');
} else {
console.log('Failed? Something went wrong.');
}
return get_device_info_result;
};

View File

@@ -0,0 +1,123 @@
/**
* Aether Electron Relay (V3)
* Maps legacy launcher commands to the modern Aether Native Bridge.
*/
const log_lvl = 1;
/**
* Returns the native bridge if available.
*/
function getBridge() {
if (typeof window !== 'undefined' && (window as any).aetherNative) {
return (window as any).aetherNative;
}
return null;
}
/**
* Open a local directory in the OS File Manager.
*/
export async function open_folder(path: string) {
const bridge = getBridge();
if (!bridge) return { success: false, error: 'Native bridge not found' };
if (log_lvl) console.log(`Relay: Opening folder: ${path}`);
return await bridge.openFolder(path);
}
/**
* Launch a file using the OS default application.
*/
export async function launch_file(path: string) {
const bridge = getBridge();
if (!bridge) return { success: false, error: 'Native bridge not found' };
if (log_lvl) console.log(`Relay: Launching file: ${path}`);
return await bridge.launchFile(path);
}
/**
* Legacy compatibility alias for launch_file.
*/
export const open_local_file_v2 = async ({ file_path, filename }: { file_path: string, filename: string }) => {
return launch_file(`${file_path}/${filename}`);
};
/**
* Run a shell command.
*/
export async function run_cmd({ cmd, return_stdout = true }: { cmd: string, return_stdout?: boolean }) {
const bridge = getBridge();
if (!bridge) return { success: false, error: 'Native bridge not found' };
if (log_lvl) console.log(`Relay: Running command: ${cmd}`);
const result = await bridge.runCommand(cmd);
if (return_stdout) return result.stdout;
return result.success;
}
/**
* Legacy compatibility alias for run_cmd.
*/
export const run_cmd_sync = run_cmd;
/**
* Kill specific processes by name.
*/
export async function kill_processes({ process_name_li = [] }: { process_name_li: string[] }) {
const bridge = getBridge();
if (!bridge) return { success: false, error: 'Native bridge not found' };
for (const name of process_name_li) {
if (log_lvl) console.log(`Relay: Killing process: ${name}`);
await bridge.runCommand(`pkill -f "${name}"`);
}
return true;
}
/**
* Check if a file hash exists in the local cache.
*/
export async function check_hash_file_cache({ cacheRoot, hash }: { cacheRoot: string, hash: string }) {
const bridge = getBridge();
if (!bridge) return false;
return await bridge.checkCache({ cacheRoot, hash });
}
/**
* Download a file to the local cache.
*/
export async function download_to_cache({ url, cacheRoot, hash, apiKey }: { url: string, cacheRoot: string, hash: string, apiKey: string }) {
const bridge = getBridge();
if (!bridge) return { success: false, error: 'Native bridge not found' };
return await bridge.downloadToCache({ url, cacheRoot, hash, apiKey });
}
/**
* Launch a file from the local cache (copies to temp first).
*/
export async function launch_from_cache({ cacheRoot, hash, tempRoot, filename }: { cacheRoot: string, hash: string, tempRoot: string, filename: string }) {
const bridge = getBridge();
if (!bridge) return { success: false, error: 'Native bridge not found' };
return await bridge.launchFromCache({ cacheRoot, hash, tempRoot, filename });
}
/**
* Get system/device info.
*/
export async function get_device_info() {
const bridge = getBridge();
if (!bridge) return null;
return await bridge.getDeviceConfig();
}
/**
* Placeholder for legacy AppleScript execution.
*/
export async function run_osascript({ cmd }: { cmd: string }) {
const bridge = getBridge();
if (!bridge) return null;
return await bridge.runCommand(`osascript -e '${cmd}'`);
}