Launcher: preserve legacy address fields in IDB; add file_sync to loop_info
ae_events__event.ts: Add legacy flat address fields (address_name, address_line_1, address_city, etc.) to properties_to_save. Events predating location_address_json still return these flat fields from the API; they must survive an IDB round-trip without being stripped by _process_generic_props, or the edit form's fallback reads return undefined. launcher_background_sync.svelte: - Move file_sync interval into loop_info $state alongside other intervals; load from cfg/device config with fallback (30 s). Keeps all intervals in one place for UI display consistency. - Align onMount fallback values to match loop_info defaults. - Add sync_paused mid-loop break: long sync cycles now honour a pause request per-iteration rather than waiting for the entire batch.
This commit is contained in:
@@ -797,7 +797,7 @@ export async function qry_ae_obj_li__event_v2({
|
||||
return filtered_obj_li.slice(0, limit);
|
||||
}
|
||||
|
||||
// Updated 2025-05-09
|
||||
// Updated 2026-03-10
|
||||
export const properties_to_save = [
|
||||
'id',
|
||||
'event_id',
|
||||
@@ -858,7 +858,23 @@ export const properties_to_save = [
|
||||
'file_count',
|
||||
'file_count_all',
|
||||
'internal_use_count',
|
||||
'event_file_id_li_json'
|
||||
'event_file_id_li_json',
|
||||
// Legacy flat address fields — preserved so background SWR re-fires do not wipe
|
||||
// address data for events that predate location_address_json. The edit form reads
|
||||
// these as a fallback: location_address_json?.name ?? address_name ?? ''.
|
||||
// New saves always write structured data into location_address_json, but the API
|
||||
// may still return the flat fields for older records and they must survive an IDB
|
||||
// round-trip without being stripped by _process_generic_props.
|
||||
'address_location_id',
|
||||
'address_name',
|
||||
'address_line_1',
|
||||
'address_line_2',
|
||||
'address_city',
|
||||
'address_state',
|
||||
'address_postal_code',
|
||||
'address_country',
|
||||
'address_country_alpha_2_code',
|
||||
'address_country_subdivision_code'
|
||||
];
|
||||
|
||||
async function _process_generic_props<T extends Record<string, any>>({
|
||||
|
||||
@@ -21,16 +21,18 @@
|
||||
let last_heartbeat: string | null = $state(null);
|
||||
|
||||
// Loop Timings (Visible in UI)
|
||||
// WHY: Session was 15s which combined with the SWR background-refresh pattern
|
||||
// caused a continuous API call every 15s even on cache hits. 60s is still
|
||||
// WHY: Session was originally 15s which combined with the SWR background-refresh
|
||||
// pattern caused a continuous API call every 15s even on cache hits. 60s is still
|
||||
// responsive for live conference use but dramatically reduces server load.
|
||||
// Defaults here must match the onMount fallbacks below — keep in sync.
|
||||
let loop_info = $state({
|
||||
event: 90000,
|
||||
device: 60000,
|
||||
location: 60000,
|
||||
session: 60000,
|
||||
presentation: 120000,
|
||||
presenter: 120000
|
||||
presenter: 120000,
|
||||
file_sync: 30000
|
||||
});
|
||||
|
||||
// Timer Handles
|
||||
@@ -72,27 +74,28 @@
|
||||
const dev = $ae_loc.native_device || {};
|
||||
const cfg = $events_loc.launcher.sync_intervals || {};
|
||||
|
||||
// Load timings from persistent config, with fallbacks to device config or defaults
|
||||
loop_info.event = cfg.event || dev.check_event_loop_period || 90000;
|
||||
loop_info.device = cfg.device || dev.check_event_device_loop_period || 60000;
|
||||
loop_info.location = cfg.location || dev.check_event_location_loop_period || 30000;
|
||||
loop_info.session = cfg.session || dev.check_event_session_loop_period || 15000;
|
||||
loop_info.presentation = cfg.presentation || dev.check_event_presentation_loop_period || 45000;
|
||||
loop_info.presenter = cfg.presenter || dev.check_event_presenter_loop_period || 60000;
|
||||
// Load timings from persistent config, with fallbacks to device config or defaults.
|
||||
// Fallback values here must match the loop_info $state defaults above — keep in sync.
|
||||
loop_info.event = cfg.event || dev.check_event_loop_period || 90000;
|
||||
loop_info.device = cfg.device || dev.check_event_device_loop_period || 60000;
|
||||
loop_info.location = cfg.location || dev.check_event_location_loop_period || 60000;
|
||||
loop_info.session = cfg.session || dev.check_event_session_loop_period || 60000;
|
||||
loop_info.presentation = cfg.presentation || dev.check_event_presentation_loop_period || 120000;
|
||||
loop_info.presenter = cfg.presenter || dev.check_event_presenter_loop_period || 120000;
|
||||
loop_info.file_sync = cfg.file_sync || dev.check_file_sync_loop_period || 30000;
|
||||
|
||||
// 1. Structural/Metadata Loops
|
||||
timer__event = setInterval(() => refresh_event_data(), loop_info.event);
|
||||
timer__device = setInterval(() => run_device_heartbeat(), loop_info.device);
|
||||
timer__event = setInterval(() => refresh_event_data(), loop_info.event);
|
||||
timer__device = setInterval(() => run_device_heartbeat(), loop_info.device);
|
||||
timer__location = setInterval(() => refresh_location_config(), loop_info.location);
|
||||
|
||||
// 2. Room Content Refresh Loops (API -> Dexie)
|
||||
timer__session = setInterval(() => refresh_session_data(), loop_info.session);
|
||||
timer__session = setInterval(() => refresh_session_data(), loop_info.session);
|
||||
timer__presentation = setInterval(() => refresh_presentation_data(), loop_info.presentation);
|
||||
timer__presenter = setInterval(() => refresh_presenter_data(), loop_info.presenter);
|
||||
timer__presenter = setInterval(() => refresh_presenter_data(), loop_info.presenter);
|
||||
|
||||
// 3. Native File Sync Loop (Dexie -> Disk)
|
||||
const sync_period = cfg.file_sync || dev.check_file_sync_loop_period || 10000;
|
||||
timer__file_sync = setInterval(() => run_sync_cycle(), sync_period);
|
||||
timer__file_sync = setInterval(() => run_sync_cycle(), loop_info.file_sync);
|
||||
|
||||
// Immediate first run for metadata
|
||||
refresh_event_data();
|
||||
@@ -241,6 +244,11 @@
|
||||
let missing_count = 0;
|
||||
|
||||
for (const file_obj of files) {
|
||||
// Re-check pause flag each iteration — a sync cycle can run for many
|
||||
// seconds if there are missing files, so we must honour a pause request
|
||||
// mid-loop rather than waiting for the entire batch to finish.
|
||||
if ($events_loc.launcher.sync_paused) break;
|
||||
|
||||
if (!file_obj.hash_sha256) continue;
|
||||
if (sync_results[file_obj.event_file_id] === 'success') {
|
||||
cached_count++;
|
||||
|
||||
Reference in New Issue
Block a user