refactor(launcher): standardize helper names and apply batch formatting
- Renamed internal 'preventDefault' to 'prevent_default' in launcher files. - Fixed native 'event.preventDefault()' call in launcher_file_cont.svelte. - Applied batch formatting (printWidth: 80) across the (launcher) module.
This commit is contained in:
@@ -14,7 +14,9 @@
|
||||
let { log_lvl = 1 } = $props();
|
||||
|
||||
let currently_syncing: string | null = $state(null);
|
||||
let sync_results: Record<string, 'success' | 'error' | 'pending'> = $state({});
|
||||
let sync_results: Record<string, 'success' | 'error' | 'pending'> = $state(
|
||||
{}
|
||||
);
|
||||
let sync_stats = $state({ total: 0, cached: 0, missing: 0 });
|
||||
let last_heartbeat: string | null = $state(null);
|
||||
|
||||
@@ -49,7 +51,10 @@
|
||||
$ae_loc.native_device.home_directory = info.home_directory;
|
||||
$ae_loc.native_device.tmp_directory = info.tmp_directory;
|
||||
|
||||
if (log_lvl) console.log('Sync: Native OS metadata hydrated.', { home: info.home_directory });
|
||||
if (log_lvl)
|
||||
console.log('Sync: Native OS metadata hydrated.', {
|
||||
home: info.home_directory
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Sync: Metadata hydration FAILED:', err);
|
||||
@@ -66,8 +71,14 @@
|
||||
|
||||
// Timers run in both browser and native for dev/testing
|
||||
timer__event = setInterval(() => run_sync_cycle(), loop_info.event);
|
||||
timer__device = setInterval(() => run_device_heartbeat(), loop_info.device);
|
||||
timer__location = setInterval(() => refresh_location_config(), loop_info.location);
|
||||
timer__device = setInterval(
|
||||
() => run_device_heartbeat(),
|
||||
loop_info.device
|
||||
);
|
||||
timer__location = setInterval(
|
||||
() => refresh_location_config(),
|
||||
loop_info.location
|
||||
);
|
||||
timer__session = setInterval(() => run_sync_cycle(), loop_info.session);
|
||||
|
||||
// Immediate first run
|
||||
@@ -88,22 +99,42 @@
|
||||
const cache_root = $ae_loc.local_file_cache_path;
|
||||
const prefix_len = $ae_loc.native_device?.hash_prefix_length || 2;
|
||||
|
||||
if (!location_id || !cache_root || is_syncing || !$ae_loc.is_native) return;
|
||||
if (!location_id || !cache_root || is_syncing || !$ae_loc.is_native)
|
||||
return;
|
||||
|
||||
is_syncing = true;
|
||||
try {
|
||||
const sessions = await db_events.session.where('event_location_id').equals(location_id).toArray();
|
||||
const session_ids = sessions.map(s => s.event_session_id);
|
||||
const sessions = await db_events.session
|
||||
.where('event_location_id')
|
||||
.equals(location_id)
|
||||
.toArray();
|
||||
const session_ids = sessions.map((s) => s.event_session_id);
|
||||
if (session_ids.length === 0) return;
|
||||
|
||||
const presentations = await db_events.presentation.where('event_session_id').anyOf(session_ids).toArray();
|
||||
const presentation_ids = presentations.map(p => p.event_presentation_id);
|
||||
const presentations = await db_events.presentation
|
||||
.where('event_session_id')
|
||||
.anyOf(session_ids)
|
||||
.toArray();
|
||||
const presentation_ids = presentations.map(
|
||||
(p) => p.event_presentation_id
|
||||
);
|
||||
|
||||
const presenters = await db_events.presenter.where('event_session_id').anyOf(session_ids).toArray();
|
||||
const presenter_ids = presenters.map(p => p.event_presenter_id);
|
||||
const presenters = await db_events.presenter
|
||||
.where('event_session_id')
|
||||
.anyOf(session_ids)
|
||||
.toArray();
|
||||
const presenter_ids = presenters.map((p) => p.event_presenter_id);
|
||||
|
||||
const all_for_ids = [...session_ids, ...presentation_ids, ...presenter_ids, $events_slct.event_id];
|
||||
const files = await db_events.file.where('for_id').anyOf(all_for_ids).toArray();
|
||||
const all_for_ids = [
|
||||
...session_ids,
|
||||
...presentation_ids,
|
||||
...presenter_ids,
|
||||
$events_slct.event_id
|
||||
];
|
||||
const files = await db_events.file
|
||||
.where('for_id')
|
||||
.anyOf(all_for_ids)
|
||||
.toArray();
|
||||
|
||||
sync_stats.total = files.length;
|
||||
let cached_count = 0;
|
||||
@@ -111,7 +142,10 @@
|
||||
|
||||
for (const file_obj of files) {
|
||||
if (!file_obj.hash_sha256) continue;
|
||||
if (sync_results[file_obj.event_file_id] === 'success') { cached_count++; continue; }
|
||||
if (sync_results[file_obj.event_file_id] === 'success') {
|
||||
cached_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const exists = await native.check_hash_file_cache({
|
||||
cache_root,
|
||||
@@ -127,17 +161,22 @@
|
||||
|
||||
missing_count++;
|
||||
currently_syncing = file_obj.filename;
|
||||
$events_sess.launcher.sync_stats.currently_syncing = currently_syncing;
|
||||
$events_sess.launcher.sync_stats.currently_syncing =
|
||||
currently_syncing;
|
||||
|
||||
// Use the PROVEN endpoint path from api.ts that is known to work in Default Mode.
|
||||
const url = `${$ae_api.base_url}/v3/action/hosted_file/${file_obj.hosted_file_id}/download?return_file=true&filename=${encodeURIComponent(file_obj.filename)}&key=${$ae_api.account_id}`;
|
||||
const result = await native.download_to_cache({
|
||||
url, cache_root, hash: file_obj.hash_sha256,
|
||||
api_key: $ae_api.api_secret_key, account_id: $ae_api.account_id,
|
||||
url,
|
||||
cache_root,
|
||||
hash: file_obj.hash_sha256,
|
||||
api_key: $ae_api.api_secret_key,
|
||||
account_id: $ae_api.account_id,
|
||||
hash_prefix_length: prefix_len
|
||||
});
|
||||
|
||||
if (result.success) sync_results[file_obj.event_file_id] = 'success';
|
||||
if (result.success)
|
||||
sync_results[file_obj.event_file_id] = 'success';
|
||||
}
|
||||
sync_stats.cached = cached_count;
|
||||
sync_stats.missing = missing_count;
|
||||
@@ -165,15 +204,23 @@
|
||||
async function run_device_heartbeat() {
|
||||
const dev = $ae_loc.native_device;
|
||||
// String-Only ID Vision: Prioritize semantic string IDs, then generic, then legacy random strings
|
||||
const device_id = dev?.event_device_id || dev?.id || dev?.event_device_id_random || dev?.id_random;
|
||||
const device_id =
|
||||
dev?.event_device_id ||
|
||||
dev?.id ||
|
||||
dev?.event_device_id_random ||
|
||||
dev?.id_random;
|
||||
|
||||
if (!device_id) {
|
||||
if (log_lvl) console.warn('Sync: Heartbeat skipped, no device_id found in $ae_loc.native_device.');
|
||||
if (log_lvl)
|
||||
console.warn(
|
||||
'Sync: Heartbeat skipped, no device_id found in $ae_loc.native_device.'
|
||||
);
|
||||
$events_sess.launcher.heartbeat_info.status = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
if (log_lvl > 1) console.log(`Sync: Running heartbeat for device: ${device_id}`);
|
||||
if (log_lvl > 1)
|
||||
console.log(`Sync: Running heartbeat for device: ${device_id}`);
|
||||
|
||||
try {
|
||||
let info = null;
|
||||
@@ -183,7 +230,10 @@
|
||||
|
||||
const update_payload: any = {
|
||||
// Use standard SQL format YYYY-MM-DD HH:mm:ss for MySQL compatibility
|
||||
heartbeat: ae_util.iso_datetime_formatter(new Date(), 'datetime_iso')
|
||||
heartbeat: ae_util.iso_datetime_formatter(
|
||||
new Date(),
|
||||
'datetime_iso'
|
||||
)
|
||||
};
|
||||
|
||||
if (info) {
|
||||
@@ -194,7 +244,8 @@
|
||||
release: info.release,
|
||||
arch: info.arch,
|
||||
cpus: info.cpus,
|
||||
total_mem: Math.round(info.total_mem / (1024 * 1024)) + 'MB',
|
||||
total_mem:
|
||||
Math.round(info.total_mem / (1024 * 1024)) + 'MB',
|
||||
free_mem: Math.round(info.free_mem / (1024 * 1024)) + 'MB'
|
||||
};
|
||||
} else {
|
||||
@@ -243,42 +294,70 @@
|
||||
</script>
|
||||
|
||||
<!-- Monitor Overlay (Hidden by default, triggered by config modal or secret gesture) -->
|
||||
<div class="fixed bottom-4 right-4 z-[9999] flex flex-col items-end gap-2 pointer-events-none">
|
||||
<div
|
||||
class="fixed bottom-4 right-4 z-[9999] flex flex-col items-end gap-2 pointer-events-none"
|
||||
>
|
||||
{#if show_monitor}
|
||||
<div class="bg-black/90 text-white p-3 rounded-lg border border-primary-500 shadow-2xl text-[10px] font-mono min-w-48 pointer-events-auto">
|
||||
<div class="flex justify-between border-b border-primary-500 pb-1 mb-2">
|
||||
<span class="font-bold text-primary-400">NATIVE SYNC MONITOR</span>
|
||||
<button type="button" onclick={() => show_monitor = false} class="text-error-500 hover:text-error-400">×</button>
|
||||
<div
|
||||
class="bg-black/90 text-white p-3 rounded-lg border border-primary-500 shadow-2xl text-[10px] font-mono min-w-48 pointer-events-auto"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between border-b border-primary-500 pb-1 mb-2"
|
||||
>
|
||||
<span class="font-bold text-primary-400"
|
||||
>NATIVE SYNC MONITOR</span
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (show_monitor = false)}
|
||||
class="text-error-500 hover:text-error-400">×</button
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-4 gap-y-1 mb-2">
|
||||
<span class="opacity-70 text-primary-300">Room Status:</span>
|
||||
<span class="text-right">{sync_stats.cached} / {sync_stats.total} Files</span>
|
||||
<span class="text-right"
|
||||
>{sync_stats.cached} / {sync_stats.total} Files</span
|
||||
>
|
||||
|
||||
<span class="opacity-70 text-primary-300">Prefix Len:</span>
|
||||
<span class="text-right">{$ae_loc.native_device?.hash_prefix_length || 2} chars</span>
|
||||
<span class="text-right"
|
||||
>{$ae_loc.native_device?.hash_prefix_length || 2} chars</span
|
||||
>
|
||||
|
||||
<span class="opacity-70 text-primary-300">Heartbeat:</span>
|
||||
<span class="text-right {last_heartbeat ? 'text-success-500' : 'text-error-500'}">
|
||||
<span
|
||||
class="text-right {last_heartbeat
|
||||
? 'text-success-500'
|
||||
: 'text-error-500'}"
|
||||
>
|
||||
{last_heartbeat || 'Pending...'}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-white/10 pt-2 flex flex-col gap-1">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class:text-primary-500={timer__event}>Event Loop:</span>
|
||||
<span class:text-primary-500={timer__event}
|
||||
>Event Loop:</span
|
||||
>
|
||||
<span>{loop_info.event / 1000}s</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class:text-primary-500={timer__device}>Device Loop:</span>
|
||||
<span class:text-primary-500={timer__device}
|
||||
>Device Loop:</span
|
||||
>
|
||||
<span>{loop_info.device / 1000}s</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class:text-primary-500={timer__location}>Location Loop:</span>
|
||||
<span class:text-primary-500={timer__location}
|
||||
>Location Loop:</span
|
||||
>
|
||||
<span>{loop_info.location / 1000}s</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class:text-primary-500={timer__session}>Session Loop:</span>
|
||||
<span class:text-primary-500={timer__session}
|
||||
>Session Loop:</span
|
||||
>
|
||||
<span>{loop_info.session / 1000}s</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -286,27 +365,34 @@
|
||||
{/if}
|
||||
|
||||
{#if currently_syncing}
|
||||
<button type="button"
|
||||
onclick={() => show_monitor = !show_monitor}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (show_monitor = !show_monitor)}
|
||||
class="bg-black/80 text-white p-2 rounded-lg text-[10px] border border-primary-500 animate-pulse shadow-2xl pointer-events-auto transition-transform active:scale-95"
|
||||
>
|
||||
<div class="flex items-center gap-2 text-left">
|
||||
<span class="fas fa-sync fa-spin text-primary-500 text-sm"></span>
|
||||
<span class="fas fa-sync fa-spin text-primary-500 text-sm"
|
||||
></span>
|
||||
<div class="flex flex-col">
|
||||
<span class="font-bold">Syncing Room Files...</span>
|
||||
<span class="opacity-70 truncate max-w-48">{currently_syncing}</span>
|
||||
<span class="text-[8px] mt-1 text-primary-300">Monitor Ready (Click to View)</span>
|
||||
<span class="opacity-70 truncate max-w-48"
|
||||
>{currently_syncing}</span
|
||||
>
|
||||
<span class="text-[8px] mt-1 text-primary-300"
|
||||
>Monitor Ready (Click to View)</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
{:else}
|
||||
<!-- Secret button area to toggle monitor when not syncing -->
|
||||
<button type="button"
|
||||
onclick={() => show_monitor = !show_monitor}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (show_monitor = !show_monitor)}
|
||||
class="w-8 h-8 opacity-0 hover:opacity-20 bg-primary-500 rounded-full pointer-events-auto flex items-center justify-center transition-opacity"
|
||||
title="Toggle Sync Monitor"
|
||||
>
|
||||
<span class="fas fa-microchip text-white text-[10px]"></span>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user