From 13bc903ad99e060c1ba9c213161c71a82adca18b Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Mon, 26 Jan 2026 12:57:59 -0500 Subject: [PATCH] fix(launcher): resolve heartbeat timezone shift and enable browser testing - Removed manual 'Z' suffix addition in device processing to fix incorrect offsets. - Switched heartbeat payload to standard UTC ISO strings. - Enabled background timers in non-native environments for easier verification. - Hardened telemetry gathering to skip Electron-only APIs when running in a browser. --- src/lib/ae_events/ae_events__event_device.ts | 5 ++- .../launcher_background_sync.svelte | 32 ++++++++++++------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/lib/ae_events/ae_events__event_device.ts b/src/lib/ae_events/ae_events__event_device.ts index 75906662..23782c28 100644 --- a/src/lib/ae_events/ae_events__event_device.ts +++ b/src/lib/ae_events/ae_events__event_device.ts @@ -480,9 +480,8 @@ export async function process_ae_obj__event_device_props({ obj_type: 'event_device', log_lvl, specific_processor: (obj) => { - if (obj.heartbeat) { - obj.heartbeat = obj.heartbeat + 'Z'; - } + // Note: V3 API returns proper ISO strings. + // We no longer manually append 'Z' to avoid timezone corruption. return obj; } }); diff --git a/src/routes/events/[event_id]/(launcher)/launcher_background_sync.svelte b/src/routes/events/[event_id]/(launcher)/launcher_background_sync.svelte index 3e0642a3..38da5154 100644 --- a/src/routes/events/[event_id]/(launcher)/launcher_background_sync.svelte +++ b/src/routes/events/[event_id]/(launcher)/launcher_background_sync.svelte @@ -36,8 +36,6 @@ let show_monitor = $state(false); onMount(() => { - if (!$ae_loc.is_native) return; - const dev = $ae_loc.native_device || {}; // Load timings from device config @@ -46,6 +44,7 @@ loop_info.location = dev.check_event_location_loop_period || 30000; loop_info.session = dev.check_event_session_loop_period || 10000; + // 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); @@ -69,7 +68,7 @@ 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) return; + if (!location_id || !cache_root || is_syncing || !$ae_loc.is_native) return; is_syncing = true; try { @@ -144,22 +143,31 @@ if (log_lvl > 1) console.log(`Sync: Running heartbeat for device: ${device_id}`); try { - const info = await native.get_device_info(); - if (!info) return; + let info = null; + if ($ae_loc.is_native) { + info = await native.get_device_info(); + } - const update_payload = { - heartbeat: ae_util.iso_datetime_formatter(new Date(), 'datetime_iso'), - info_hostname: info.hostname, - info_ip_list: info.ip_addresses.join(', '), - meta_json: { + const update_payload: any = { + // Use standard toISOString() for unambiguous UTC on server + heartbeat: new Date().toISOString() + }; + + if (info) { + update_payload.info_hostname = info.hostname; + update_payload.info_ip_list = info.ip_addresses.join(', '); + update_payload.meta_json = { platform: info.platform, release: info.release, arch: info.arch, cpus: info.cpus, total_mem: Math.round(info.total_mem / (1024 * 1024)) + 'MB', free_mem: Math.round(info.free_mem / (1024 * 1024)) + 'MB' - } - }; + }; + } else { + update_payload.info_hostname = 'Web Browser'; + update_payload.notes = 'Heartbeat from non-native web session.'; + } await events_func.update_ae_obj__event_device({ api_cfg: $ae_api,