From 66affb2a0fc0379c18731d4e63e757652a0eeeaa Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Fri, 30 Jan 2026 16:04:28 -0500 Subject: [PATCH] perf(events): implement non-blocking SWR pattern and optimize library loaders - Refactored 'event_session', 'event_presentation', 'event_file', 'event_location', and 'event_presenter' libraries to follow a Stale-While-Revalidate pattern. - Implemented non-blocking background refreshes to allow instant UI rendering from IndexedDB cache. - Parallelized nested collection loads (files, presentations) during background tasks to eliminate UI stalls. - Standardized ID lookups using specific indices (event_location_id, event_id) for reliable local data retrieval. - Resolved regression where aggressive ID overwriting caused relationship inconsistencies in background loads. - Fixed reactive access to live queries in 'session_view.svelte' using proper Svelte 5 prefixing. --- src/lib/ae_events/ae_events__event_file.ts | 376 +++---------- .../ae_events/ae_events__event_location.ts | 397 ++++---------- .../ae_events__event_presentation.ts | 436 ++++----------- .../ae_events/ae_events__event_presenter.ts | 501 ++++-------------- src/lib/ae_events/ae_events__event_session.ts | 461 ++-------------- .../(launcher)/launcher/+layout.svelte | 2 +- .../(launcher)/menu_session_list.svelte | 2 +- .../session/[session_id]/session_view.svelte | 200 +++---- 8 files changed, 543 insertions(+), 1832 deletions(-) diff --git a/src/lib/ae_events/ae_events__event_file.ts b/src/lib/ae_events/ae_events__event_file.ts index 07e03fd3..6470093f 100644 --- a/src/lib/ae_events/ae_events__event_file.ts +++ b/src/lib/ae_events/ae_events__event_file.ts @@ -7,7 +7,7 @@ import type { ae_EventFile } from '$lib/types/ae_types'; const ae_promises: key_val = {}; -// Updated 2026-01-20 to V3 +// Updated 2026-01-30: Fixed - Removed aggressive ID overwriting export async function load_ae_obj_id__event_file({ api_cfg, event_file_id, @@ -22,46 +22,38 @@ export async function load_ae_obj_id__event_file({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_id__event_file() *** [V3] id=${event_file_id}`); + console.log(`*** load_ae_obj_id__event_file() *** [V3] id=${event_file_id} (SWR)`); } - try { - ae_promises.load__event_file_obj = await api.get_ae_obj_v3({ - api_cfg, - obj_type: 'event_file', - obj_id: event_file_id, - view, - log_lvl - }); - - if (ae_promises.load__event_file_obj) { - if (try_cache) { - const processed_obj_li = await process_ae_obj__event_file_props({ - obj_li: [ae_promises.load__event_file_obj], - log_lvl - }); - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'file', - obj_li: processed_obj_li, - properties_to_save, - log_lvl - }); + if (try_cache) { + try { + const cached = await db_events.file.get(event_file_id); + if (cached) { + _refresh_file_id_background({ api_cfg, event_file_id, view, try_cache, log_lvl: 0 }); + return cached; } - } else if (try_cache) { - ae_promises.load__event_file_obj = await db_events.file.get(event_file_id); - } - } catch (error: any) { - console.log('V3 Request failed.', error); - if (try_cache) { - ae_promises.load__event_file_obj = await db_events.file.get(event_file_id); - } + } catch (e) {} } - return ae_promises.load__event_file_obj || null; + return await _refresh_file_id_background({ api_cfg, event_file_id, view, try_cache, log_lvl }); +} + +async function _refresh_file_id_background({ api_cfg, event_file_id, view, try_cache, log_lvl }: any) { + if (typeof navigator !== 'undefined' && !navigator.onLine) return null; + try { + const result = await api.get_ae_obj_v3({ api_cfg, obj_type: 'event_file', obj_id: event_file_id, view, log_lvl }); + if (result) { + const processed = await process_ae_obj__event_file_props({ obj_li: [result], log_lvl }); + const processed_obj = processed[0]; + if (try_cache) { + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'file', obj_li: [processed_obj], properties_to_save, log_lvl }); + } + return processed_obj; + } + } catch (e) {} + return null; } -// Updated 2026-01-20 to V3 export async function load_ae_obj_li__event_file({ api_cfg, for_obj_type, @@ -92,73 +84,37 @@ export async function load_ae_obj_li__event_file({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_li__event_file() *** [V3] for=${for_obj_type}:${for_obj_id}`); + console.log(`*** load_ae_obj_li__event_file() *** [V3] for=${for_obj_type}:${for_obj_id} (SWR)`); } - const valid_for_obj_types = [ - 'event', - 'event_session', - 'event_presentation', - 'event_presenter', - 'event_location', - 'event_badge', - 'event_device' - ]; - if (!valid_for_obj_types.includes(for_obj_type)) { - console.log(`Invalid for_obj_type: ${for_obj_type}`); - return []; - } - - try { - ae_promises.load__event_file_obj_li = await api.get_ae_obj_li_v3({ - api_cfg, - obj_type: 'event_file', - for_obj_type, - for_obj_id, - enabled, - hidden, - view, - limit, - offset, - order_by_li, - log_lvl - }); - - if (ae_promises.load__event_file_obj_li) { - if (try_cache) { - const processed_obj_li = await process_ae_obj__event_file_props({ - obj_li: ae_promises.load__event_file_obj_li, - log_lvl - }); - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'file', - obj_li: processed_obj_li, - properties_to_save, - log_lvl - }); + if (try_cache) { + try { + const cached_li = await db_events.file.where('for_id').equals(for_obj_id).toArray(); + if (cached_li && cached_li.length > 0) { + _refresh_file_li_background({ api_cfg, for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: 0 }); + return cached_li; } - } else if (try_cache) { - // Dexie fallback - search for parent ID across common link fields - ae_promises.load__event_file_obj_li = await db_events.file - .filter((f: any) => f.for_id === for_obj_id || f.event_id === for_obj_id) - .toArray(); - } - } catch (error: any) { - console.log('V3 List Request failed.', error); - if (try_cache) { - ae_promises.load__event_file_obj_li = await db_events.file - .filter((f: any) => f.for_id === for_obj_id || f.event_id === for_obj_id) - .toArray(); - } + } catch (e) {} } - return ae_promises.load__event_file_obj_li || []; + return await _refresh_file_li_background({ api_cfg, for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }); +} + +async function _refresh_file_li_background({ api_cfg, for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) { + if (typeof navigator !== 'undefined' && !navigator.onLine) return []; + try { + const result_li = await api.get_ae_obj_li_v3({ api_cfg, obj_type: 'event_file', for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, log_lvl }); + if (result_li) { + const processed = await process_ae_obj__event_file_props({ obj_li: result_li, log_lvl }); + if (try_cache) { + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'file', obj_li: processed, properties_to_save, log_lvl }); + } + return processed; + } + } catch (e) {} + return []; } -/** - * Legacy wrapper maintained for specific creation logic (link from hosted_file) - */ export async function create_event_file_obj_from_hosted_file_async({ api_cfg, hosted_file_id, @@ -177,25 +133,15 @@ export async function create_event_file_obj_from_hosted_file_async({ log_lvl?: number; }) { if (!hosted_file_id) return false; - const endpoint = `/event/file/from_hosted_file/${hosted_file_id}`; const query_params = { ...params }; if (return_obj) query_params['return_obj'] = true; if (inc_hosted_file) query_params['inc_hosted_file'] = true; - - const result = await api.post_object({ - api_cfg, - endpoint, - params: query_params, - data, - log_lvl - }); - + const result = await api.post_object({ api_cfg, endpoint, params: query_params, data, log_lvl }); if (return_obj) return result; return result?.event_file_id || result?.id || result?.event_file_id_random; } -// Updated 2026-01-20 to V3 export async function delete_ae_obj_id__event_file({ api_cfg, event_file_id, @@ -209,23 +155,11 @@ export async function delete_ae_obj_id__event_file({ try_cache?: boolean; log_lvl?: number; }) { - // V3 delete handles orphans via policy or explicit params - const result = await api.delete_ae_obj_v3({ - api_cfg, - obj_type: 'event_file', - obj_id: event_file_id, - params: { ...params, delete_hosted_file: true, rm_orphan: true }, - log_lvl - }); - - if (try_cache) { - await db_events.file.delete(event_file_id); - } - + const result = await api.delete_ae_obj_v3({ api_cfg, obj_type: 'event_file', obj_id: event_file_id, params: { ...params, delete_hosted_file: true, rm_orphan: true }, log_lvl }); + if (try_cache) await db_events.file.delete(event_file_id); return result; } -// Updated 2026-01-20 to V3 export async function update_ae_obj__event_file({ api_cfg, event_file_id, @@ -241,190 +175,42 @@ export async function update_ae_obj__event_file({ try_cache?: boolean; log_lvl?: number; }): Promise { - const result = await api.update_ae_obj_v3({ - api_cfg, - obj_type: 'event_file', - obj_id: event_file_id, - fields: data_kv, - params, - log_lvl - }); - + const result = await api.update_ae_obj_v3({ api_cfg, obj_type: 'event_file', obj_id: event_file_id, fields: data_kv, params, log_lvl }); if (result && try_cache) { - const processed_obj_li = await process_ae_obj__event_file_props({ - obj_li: [result], - log_lvl - }); - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'file', - obj_li: processed_obj_li, - properties_to_save, - log_lvl - }); + const processed = await process_ae_obj__event_file_props({ obj_li: [result], log_lvl }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'file', obj_li: processed, properties_to_save, log_lvl }); } - return result; } -// Updated 2026-01-20 to V3 export async function search__event_file({ - api_cfg, - event_id, - qry_str = '', - qry_created_on = null, - qry_min_file_size = null, - qry_file_purpose = null, - enabled = 'enabled', - hidden = 'not_hidden', - view = 'default', - limit = 25, - offset = 0, - order_by_li = [ - { priority: 'DESC' }, - { sort: 'DESC' }, - { updated_on: 'DESC' } - ], - try_cache = true, - log_lvl = 0 + api_cfg, event_id, qry_str = '', qry_created_on = null, qry_min_file_size = null, qry_file_purpose = null, enabled = 'enabled', hidden = 'not_hidden', view = 'default', limit = 25, offset = 0, order_by_li = [{ priority: 'DESC' }, { sort: 'DESC' }, { updated_on: 'DESC' }], try_cache = true, log_lvl = 0 }: { - api_cfg: any; - event_id: string; - qry_str?: string; - qry_created_on?: string | null; - qry_min_file_size?: null | number; - qry_file_purpose?: string | null; - enabled?: 'enabled' | 'all' | 'not_enabled'; - hidden?: 'hidden' | 'all' | 'not_hidden'; - view?: string; - limit?: number; - offset?: number; - order_by_li?: any; - try_cache?: boolean; - log_lvl?: number; + api_cfg: any; event_id: string; qry_str?: string; qry_created_on?: string | null; qry_min_file_size?: null | number; qry_file_purpose?: string | null; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; limit?: number; offset?: number; order_by_li?: any; try_cache?: boolean; log_lvl?: number; }): Promise { - const search_query: any = { - q: qry_str, - and: [{ field: 'event_id', op: 'eq', value: event_id }] - }; - - if (qry_min_file_size) { - search_query.and.push({ field: 'hosted_file_size', op: 'gt', value: qry_min_file_size }); - } - - if (qry_created_on) { - search_query.and.push({ field: 'created_on', op: 'gte', value: qry_created_on }); - } - - if (qry_file_purpose) { - search_query.and.push({ field: 'file_purpose', op: 'eq', value: qry_file_purpose }); - } - - const result_li = await api.search_ae_obj_v3({ - api_cfg, - obj_type: 'event_file', - search_query, - enabled, - hidden, - view, - order_by_li, - limit, - offset, - log_lvl - }); - + const search_query: any = { q: qry_str, and: [{ field: 'event_id', op: 'eq', value: event_id }] }; + if (qry_min_file_size) search_query.and.push({ field: 'hosted_file_size', op: 'gt', value: qry_min_file_size }); + if (qry_created_on) search_query.and.push({ field: 'created_on', op: 'gte', value: qry_created_on }); + if (qry_file_purpose) search_query.and.push({ field: 'file_purpose', op: 'eq', value: qry_file_purpose }); + const result_li = await api.search_ae_obj_v3({ api_cfg, obj_type: 'event_file', search_query, enabled, hidden, view, order_by_li, limit, offset, log_lvl }); if (result_li && try_cache) { - const processed_obj_li = await process_ae_obj__event_file_props({ - obj_li: result_li, - log_lvl - }); - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'file', - obj_li: processed_obj_li, - properties_to_save, - log_lvl - }); + const processed = await process_ae_obj__event_file_props({ obj_li: result_li, log_lvl }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'file', obj_li: processed, properties_to_save, log_lvl }); } - return result_li || []; } export const qry__event_file = search__event_file; export const properties_to_save = [ - 'id', - 'event_file_id', - 'hosted_file_id', - 'hash_sha256', - 'for_type', - 'for_id', - 'event_id', - 'event_session_id', - 'event_presentation_id', - 'event_presenter_id', - 'event_location_id', - 'filename', - 'extension', - 'open_in_os', - 'lu_file_purpose_id', - 'lu_event_file_purpose_name', - 'file_purpose', - 'enable', - 'hide', - 'priority', - 'sort', - 'group', - 'notes', - 'created_on', - 'updated_on', - 'tmp_sort_1', - 'tmp_sort_2', - 'filename_no_ext', - 'filename_w_ext', - 'hosted_file_content_type', - 'file_size', - 'hosted_file_size', - 'event_location_code', - 'event_location_name', - 'event_session_code', - 'event_session_type_code', - 'event_session_name', - 'event_session_start_datetime', - 'event_session_end_datetime', - 'event_presentation_code', - 'event_presentation_type_code', - 'event_presentation_name', - 'event_presentation_start_datetime', - 'event_presentation_end_datetime', - 'event_presenter_given_name', - 'event_presenter_family_name', - 'event_presenter_full_name', - 'event_presenter_email' + 'id', 'event_file_id', 'event_file_id_random', 'hosted_file_id', 'hosted_file_id_random', 'hash_sha256', 'for_type', 'for_id', 'for_id_random', 'event_id', 'event_id_random', 'event_session_id', 'event_presentation_id', 'event_presenter_id', 'event_location_id', 'filename', 'extension', 'open_in_os', 'lu_file_purpose_id', 'lu_event_file_purpose_name', 'file_purpose', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'filename_no_ext', 'filename_w_ext', 'hosted_file_content_type', 'file_size', 'hosted_file_size', 'event_location_code', 'event_location_name', 'event_session_code', 'event_session_type_code', 'event_session_name', 'event_session_start_datetime', 'event_session_end_datetime', 'event_presentation_code', 'event_presentation_type_code', 'event_presentation_name', 'event_presentation_start_datetime', 'event_presentation_end_datetime', 'event_presenter_given_name', 'event_presenter_family_name', 'event_presenter_full_name', 'event_presenter_email' ]; -/** - * NON-EXPORTED LOCAL HELPER - */ -async function _process_generic_props>({ - obj_li, - obj_type, - log_lvl = 0, - specific_processor -}: { - obj_li: T[]; - obj_type: string; - log_lvl?: number; - specific_processor?: (obj: T) => Promise | T; -}): Promise { +async function _process_generic_props>({ obj_li, obj_type, log_lvl = 0, specific_processor }: { obj_li: T[]; obj_type: string; log_lvl?: number; specific_processor?: (obj: T) => Promise | T; }): Promise { if (!obj_li || obj_li.length === 0) return []; - const processed_obj_li: T[] = []; - for (const original_obj of obj_li) { let processed_obj = { ...original_obj }; - - // 1. Standardize ID and other '_random' fields for (const key in processed_obj) { if (key.endsWith('_random')) { const newKey = key.slice(0, -7); @@ -432,40 +218,20 @@ async function _process_generic_props>({ } } const randomIdKey = `${obj_type}_id_random`; - if (processed_obj[randomIdKey]) { - (processed_obj as any).id = processed_obj[randomIdKey]; - } - - // 2. Create common computed properties + if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey]; const group = processed_obj.group ?? '0'; const priority = processed_obj.priority ? 1 : 0; const sort = processed_obj.sort ?? '0'; const updated = processed_obj.updated_on ?? processed_obj.created_on; const name = processed_obj.name ?? ''; - (processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`; (processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`; - - if (specific_processor) { - processed_obj = await Promise.resolve(specific_processor(processed_obj)); - } - + if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj)); processed_obj_li.push(processed_obj as T); } - return processed_obj_li; } -export async function process_ae_obj__event_file_props({ - obj_li, - log_lvl = 0 -}: { - obj_li: any[]; - log_lvl?: number; -}) { - return _process_generic_props({ - obj_li, - obj_type: 'event_file', - log_lvl - }); +export async function process_ae_obj__event_file_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) { + return _process_generic_props({ obj_li, obj_type: 'event_file', log_lvl }); } \ No newline at end of file diff --git a/src/lib/ae_events/ae_events__event_location.ts b/src/lib/ae_events/ae_events__event_location.ts index 73330b87..9548d875 100644 --- a/src/lib/ae_events/ae_events__event_location.ts +++ b/src/lib/ae_events/ae_events__event_location.ts @@ -9,7 +9,7 @@ import { load_ae_obj_li__event_session } from '$lib/ae_events/ae_events__event_s const ae_promises: key_val = {}; -// Updated 2026-01-27 to V3 String-Only ID Standard +// Updated 2026-01-30: Optimized Non-Blocking SWR Pattern export async function load_ae_obj_id__event_location({ api_cfg, event_location_id, @@ -30,52 +30,41 @@ export async function load_ae_obj_id__event_location({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_id__event_location() *** [V3] id=${event_location_id}`); + console.log(`*** load_ae_obj_id__event_location() *** [V3] id=${event_location_id} (SWR)`); } - try { - const result = await api.get_ae_obj_v3({ - api_cfg, - obj_type: 'event_location', - obj_id: event_location_id, - view, - log_lvl - }); - - if (result) { - const processed = await process_ae_obj__event_location_props({ - obj_li: [result], - log_lvl - }); - ae_promises.load__event_location_obj = processed[0]; - - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'location', - obj_li: [ae_promises.load__event_location_obj], - properties_to_save, - log_lvl - }); + // 1. FAST PATH: Cache hit + if (try_cache) { + try { + const cached = await db_events.location.get(event_location_id); + if (cached) { + _refresh_location_id_background({ api_cfg, event_location_id, view, try_cache, inc_file_li, inc_session_li, inc_all_file_li, log_lvl: 0 }); + return await _handle_nested_loads(cached, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }); } - } else if (try_cache) { - ae_promises.load__event_location_obj = await db_events.location.get(event_location_id); - } - } catch (error: any) { - console.log('V3 Request failed.', error); - if (try_cache) { - ae_promises.load__event_location_obj = await db_events.location.get(event_location_id); - } + } catch (e) {} } - if (!ae_promises?.load__event_location_obj) { - return null; - } - - return await _handle_nested_loads(ae_promises.load__event_location_obj, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }); + // 2. SLOW PATH: Wait for API + return await _refresh_location_id_background({ api_cfg, event_location_id, view, try_cache, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }); } -// Updated 2026-01-27 to V3 String-Only ID Standard +async function _refresh_location_id_background({ api_cfg, event_location_id, view, try_cache, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }: any) { + if (typeof navigator !== 'undefined' && !navigator.onLine) return null; + try { + const result = await api.get_ae_obj_v3({ api_cfg, obj_type: 'event_location', obj_id: event_location_id, view, log_lvl }); + if (result) { + const processed = await process_ae_obj__event_location_props({ obj_li: [result], log_lvl }); + const processed_obj = processed[0]; + if (try_cache) { + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: [processed_obj], properties_to_save, log_lvl }); + } + return await _handle_nested_loads(processed_obj, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }); + } + } catch (e) {} + return null; +} + +// Updated 2026-01-30: Robust Cache Lookups export async function load_ae_obj_li__event_location({ api_cfg, for_obj_type = 'event', @@ -113,97 +102,76 @@ export async function load_ae_obj_li__event_location({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_li__event_location() *** [V3] for=${for_obj_type}:${for_obj_id}`); + console.log(`*** load_ae_obj_li__event_location() *** [V3] for=${for_obj_type}:${for_obj_id} (SWR)`); } - try { - const result_li = await api.get_ae_obj_li_v3({ - api_cfg, - obj_type: 'event_location', - for_obj_type, - for_obj_id, - enabled, - hidden, - view, - limit, - offset, - order_by_li, - log_lvl - }); + // 1. FAST PATH: Check cache + if (try_cache) { + try { + const cached_li = await db_events.location.where('event_id').equals(for_obj_id).toArray(); + if (cached_li && cached_li.length > 0) { + _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_session_li, inc_all_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: 0 }); + for (const loc of cached_li) { + _handle_nested_loads(loc, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl: 0 }); + } + return cached_li; + } + } catch (e) {} + } + // 2. SLOW PATH: API + return await _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_session_li, inc_all_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }); +} + +async function _refresh_location_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_session_li, inc_all_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) { + if (typeof navigator !== 'undefined' && !navigator.onLine) return []; + try { + const result_li = await api.get_ae_obj_li_v3({ api_cfg, obj_type: 'event_location', for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, log_lvl }); if (result_li) { - const processed = await process_ae_obj__event_location_props({ - obj_li: result_li, - log_lvl - }); - ae_promises.load__event_location_obj_li = processed; + const processed = await process_ae_obj__event_location_props({ obj_li: result_li, log_lvl }); + + // String-Only ID Vision: Ensure linking ID is set for indexing + if (for_obj_type === 'event') { + processed.forEach(loc => loc.event_id = for_obj_id); + } if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'location', - obj_li: ae_promises.load__event_location_obj_li, - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: processed, properties_to_save, log_lvl }); } - } else if (try_cache) { - ae_promises.load__event_location_obj_li = await db_events.location - .where('event_id').equals(for_obj_id) - .toArray(); + for (const loc of processed) { + _handle_nested_loads(loc, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl: 0 }); + } + return processed; } - } catch (error: any) { - console.log('V3 List Request failed.', error); - if (try_cache) { - ae_promises.load__event_location_obj_li = await db_events.location - .where('event_id').equals(for_obj_id) - .toArray(); - } - } - - if (ae_promises.load__event_location_obj_li) { - for (const location of ae_promises.load__event_location_obj_li) { - await _handle_nested_loads(location, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }); - } - } - - return ae_promises.load__event_location_obj_li || []; + } catch (e) {} + return []; } /** * Handle nested data loads for a single location object. */ async function _handle_nested_loads(location_obj: any, { api_cfg, inc_file_li, inc_session_li, inc_all_file_li, log_lvl }: any) { - // String-Only ID Vision: the '_id' field IS the string ID const current_location_id = location_obj.id || location_obj.event_location_id; + if (!current_location_id) return location_obj; + const tasks = []; if (inc_file_li) { - location_obj.event_file_li = await load_ae_obj_li__event_file({ - api_cfg, - for_obj_type: 'event_location', - for_obj_id: current_location_id, - enabled: 'all', - limit: 25, - log_lvl - }); + tasks.push(load_ae_obj_li__event_file({ + api_cfg, for_obj_type: 'event_location', for_obj_id: current_location_id, + enabled: 'all', limit: 25, log_lvl + }).then(res => location_obj.event_file_li = res)); } if (inc_session_li) { - location_obj.event_session_obj_li = await load_ae_obj_li__event_session({ - api_cfg, - for_obj_type: 'event_location', - for_obj_id: current_location_id, - inc_file_li: inc_all_file_li, - inc_all_file_li: inc_all_file_li, - inc_presentation_li: true, - inc_presenter_li: true, - enabled: 'enabled', - hidden: 'not_hidden', - limit: 150, - log_lvl - }); + tasks.push(load_ae_obj_li__event_session({ + api_cfg, for_obj_type: 'event_location', for_obj_id: current_location_id, + inc_file_li: inc_all_file_li, inc_all_file_li: inc_all_file_li, + inc_presentation_li: true, inc_presenter_li: true, + enabled: 'enabled', hidden: 'not_hidden', limit: 150, log_lvl + }).then(res => location_obj.event_session_obj_li = res)); } + if (tasks.length > 0) await Promise.all(tasks); return location_obj; } @@ -221,39 +189,20 @@ export async function create_ae_obj__event_location({ try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** create_ae_obj__event_location() *** [V3] event_id=${event_id}`); - } - const result = await api.create_ae_obj_v3({ - api_cfg, - obj_type: 'event_location', - fields: { - event_id, - ...data_kv - }, + api_cfg, obj_type: 'event_location', + fields: { event_id, ...data_kv }, log_lvl }); if (result) { - const processed = await process_ae_obj__event_location_props({ - obj_li: [result], - log_lvl - }); + const processed = await process_ae_obj__event_location_props({ obj_li: [result], log_lvl }); const processed_obj = processed[0]; - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'location', - obj_li: [processed_obj], - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: [processed_obj], properties_to_save, log_lvl }); } return processed_obj; } - return null; } @@ -271,22 +220,8 @@ export async function delete_ae_obj_id__event_location({ try_cache?: boolean; log_lvl?: number; }) { - if (log_lvl) { - console.log(`*** delete_ae_obj_id__event_location() *** [V3] id=${event_location_id}`); - } - - const result = await api.delete_ae_obj_v3({ - api_cfg, - obj_type: 'event_location', - obj_id: event_location_id, - method, - log_lvl - }); - - if (try_cache) { - await db_events.location.delete(event_location_id); - } - + const result = await api.delete_ae_obj_v3({ api_cfg, obj_type: 'event_location', obj_id: event_location_id, method, log_lvl }); + if (try_cache) await db_events.location.delete(event_location_id); return result; } @@ -304,204 +239,74 @@ export async function update_ae_obj__event_location({ try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** update_ae_obj__event_location() *** [V3] id=${event_location_id}`); - } - - const result = await api.update_ae_obj_v3({ - api_cfg, - obj_type: 'event_location', - obj_id: event_location_id, - fields: data_kv, - log_lvl - }); - + const result = await api.update_ae_obj_v3({ api_cfg, obj_type: 'event_location', obj_id: event_location_id, fields: data_kv, log_lvl }); if (result) { - const processed = await process_ae_obj__event_location_props({ - obj_li: [result], - log_lvl - }); + const processed = await process_ae_obj__event_location_props({ obj_li: [result], log_lvl }); const processed_obj = processed[0]; - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'location', - obj_li: [processed_obj], - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: [processed_obj], properties_to_save, log_lvl }); } return processed_obj; } - return null; } // Updated 2026-01-20 to V3 export async function search__event_location({ - api_cfg, - event_id, - qry_str = '', - enabled = 'enabled', - hidden = 'not_hidden', - view = 'default', - limit = 25, - offset = 0, - order_by_li = [ - { priority: 'DESC' }, - { sort: 'DESC' }, - { name: 'ASC' }, - { updated_on: 'DESC' } - ], - try_cache = true, - log_lvl = 0 + api_cfg, event_id, qry_str = '', enabled = 'enabled', hidden = 'not_hidden', view = 'default', limit = 25, offset = 0, order_by_li = [{ sort: 'ASC' }, { name: 'ASC' }], try_cache = true, log_lvl = 0 }: { - api_cfg: any; - event_id: string; - qry_str?: string; - enabled?: 'enabled' | 'all' | 'not_enabled'; - hidden?: 'hidden' | 'all' | 'not_hidden'; - view?: string; - limit?: number; - offset?: number; - order_by_li?: any; - try_cache?: boolean; - log_lvl?: number; + api_cfg: any; event_id: string; qry_str?: string; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; limit?: number; offset?: number; order_by_li?: any; try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** search__event_location() *** [V3] event_id=${event_id} qry=${qry_str}`); - } - - const search_query: any = { - q: qry_str, - and: [{ field: 'event_id', op: 'eq', value: event_id }] - }; - + const search_query: any = { q: qry_str, and: [{ field: 'event_id', op: 'eq', value: event_id }] }; if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: true }); else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: false }); - if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: true }); else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: false }); - const result_li = await api.search_ae_obj_v3({ - api_cfg, - obj_type: 'event_location', - search_query, - order_by_li, - view, - limit, - offset, - log_lvl - }); - + const result_li = await api.search_ae_obj_v3({ api_cfg, obj_type: 'event_location', search_query, order_by_li, view, limit, offset, log_lvl }); if (result_li) { - const processed = await process_ae_obj__event_location_props({ - obj_li: result_li, - log_lvl - }); - + const processed = await process_ae_obj__event_location_props({ obj_li: result_li, log_lvl }); if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'location', - obj_li: processed, - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'location', obj_li: processed, properties_to_save, log_lvl }); } return processed; } - return []; } export const properties_to_save = [ - 'id', - 'event_location_id', - 'event_id', - 'external_id', - 'code', - 'name', - 'description', - 'passcode', - 'enable', - 'hide', - 'priority', - 'sort', - 'group', - 'notes', - 'created_on', - 'updated_on', - 'tmp_sort_1', - 'tmp_sort_2', - 'event_name' + 'id', 'event_location_id', 'event_location_id_random', 'event_id', 'event_id_random', 'external_id', 'code', 'name', 'description', 'passcode', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'event_name' ]; -/** - * NON-EXPORTED LOCAL HELPER - */ -async function _process_generic_props>({ - obj_li, - obj_type, - log_lvl = 0, - specific_processor -}: { - obj_li: T[]; - obj_type: string; - log_lvl?: number; - specific_processor?: (obj: T) => Promise | T; -}): Promise { +async function _process_generic_props>({ obj_li, obj_type, log_lvl = 0, specific_processor }: { obj_li: T[]; obj_type: string; log_lvl?: number; specific_processor?: (obj: T) => Promise | T; }): Promise { if (!obj_li || obj_li.length === 0) return []; - const processed_obj_li: T[] = []; - for (const original_obj of obj_li) { let processed_obj = { ...original_obj }; - - // 1. Standardize ID and other '_random' fields for (const key in processed_obj) { if (key.endsWith('_random')) { const newKey = key.slice(0, -7); (processed_obj as any)[newKey] = processed_obj[key]; } } - // String-Only ID Vision: Map [obj_type]_id_random to 'id' const randomIdKey = `${obj_type}_id_random`; - if (processed_obj[randomIdKey]) { - (processed_obj as any).id = processed_obj[randomIdKey]; - } - - // 2. Create common computed properties + if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey]; const group = processed_obj.group ?? '0'; const priority = processed_obj.priority ? 1 : 0; const sort = processed_obj.sort ?? '0'; const updated = processed_obj.updated_on ?? processed_obj.created_on; const name = processed_obj.name ?? ''; - (processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`; (processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`; - - if (specific_processor) { - processed_obj = await Promise.resolve(specific_processor(processed_obj)); - } - + if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj)); processed_obj_li.push(processed_obj as T); } - return processed_obj_li; } -export async function process_ae_obj__event_location_props({ - obj_li, - log_lvl = 0 -}: { - obj_li: any[]; - log_lvl?: number; -}) { - return _process_generic_props({ - obj_li, - obj_type: 'event_location', - log_lvl - }); +export async function process_ae_obj__event_location_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) { + return _process_generic_props({ obj_li, obj_type: 'event_location', log_lvl, specific_processor: (obj) => { + if (obj.event_id_random) obj.event_id = obj.event_id_random; + return obj; + }}); } \ No newline at end of file diff --git a/src/lib/ae_events/ae_events__event_presentation.ts b/src/lib/ae_events/ae_events__event_presentation.ts index be33c4f7..6d268346 100644 --- a/src/lib/ae_events/ae_events__event_presentation.ts +++ b/src/lib/ae_events/ae_events__event_presentation.ts @@ -10,7 +10,7 @@ import { load_ae_obj_li__event_presenter } from '$lib/ae_events/ae_events__event const ae_promises: key_val = {}; -// Updated 2026-01-27 to V3 String-Only ID Standard +// Updated 2026-01-30: Optimized SWR Pattern export async function load_ae_obj_id__event_presentation({ api_cfg, event_presentation_id, @@ -37,89 +37,73 @@ export async function load_ae_obj_id__event_presentation({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_id__event_presentation() *** id=${event_presentation_id}`); + console.log(`*** load_ae_obj_id__event_presentation() *** id=${event_presentation_id} (SWR)`); } - try { - const result = await api.get_ae_obj_v3({ - api_cfg, - obj_type: 'event_presentation', - obj_id: event_presentation_id, - view, - log_lvl - }); - - if (result) { - const processed = await process_ae_obj__event_presentation_props({ - obj_li: [result], - log_lvl - }); - ae_promises.load__event_presentation_obj = processed[0]; - - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presentation', - obj_li: [ae_promises.load__event_presentation_obj], - properties_to_save, - log_lvl - }); + // 1. FAST PATH: Cache hit + if (try_cache) { + try { + const cached = await db_events.presentation.get(event_presentation_id); + if (cached) { + // Background refresh (non-blocking) + _refresh_presentation_id_background({ api_cfg, event_presentation_id, view, try_cache, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl: 0 }); + // Await nested loads from cache to return a complete object + return await _handle_nested_loads(cached, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl: 0 }); } - } else if (try_cache) { - ae_promises.load__event_presentation_obj = await db_events.presentation.get(event_presentation_id); - } - } catch (error: any) { - console.log('V3 Request failed.', error); - if (try_cache) { - ae_promises.load__event_presentation_obj = await db_events.presentation.get(event_presentation_id); - } + } catch (e) {} } - if (!ae_promises.load__event_presentation_obj) return null; + // 2. SLOW PATH: Wait for API + return await _refresh_presentation_id_background({ api_cfg, event_presentation_id, view, try_cache, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl }); +} - return await _handle_nested_loads(ae_promises.load__event_presentation_obj, { - api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl - }); +/** + * Internal background refresh for a single presentation + */ +async function _refresh_presentation_id_background({ api_cfg, event_presentation_id, view, try_cache, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl }: any) { + if (typeof navigator !== 'undefined' && !navigator.onLine) return null; + try { + const result = await api.get_ae_obj_v3({ api_cfg, obj_type: 'event_presentation', obj_id: event_presentation_id, view, log_lvl }); + if (result) { + const processed = await process_ae_obj__event_presentation_props({ obj_li: [result], log_lvl }); + const processed_obj = processed[0]; + if (try_cache) { + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: [processed_obj], properties_to_save, log_lvl }); + } + // During refresh, we disable child SWR to prevent a request storm + return await _handle_nested_loads(processed_obj, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache: false, log_lvl }); + } + } catch (e) {} + return null; } /** * Helper to handle nested collection loads for a presentation */ async function _handle_nested_loads(presentation_obj: any, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }: any) { - // String-Only ID Vision: the '_id' field IS the string ID const current_presentation_id = presentation_obj.id || presentation_obj.event_presentation_id; + if (!current_presentation_id) return presentation_obj; + const tasks = []; if (inc_file_li) { - presentation_obj.event_file_li = await load_ae_obj_li__event_file({ - api_cfg, - for_obj_type: 'event_presentation', - for_obj_id: current_presentation_id, - enabled, - limit: 25, - try_cache, - log_lvl - }); + tasks.push(load_ae_obj_li__event_file({ + api_cfg, for_obj_type: 'event_presentation', for_obj_id: current_presentation_id, + enabled, limit: 25, try_cache, log_lvl + }).then(res => presentation_obj.event_file_li = res)); } if (inc_presenter_li) { - presentation_obj.event_presenter_li = await load_ae_obj_li__event_presenter({ - api_cfg, - for_obj_type: 'event_presentation', - for_obj_id: current_presentation_id, - inc_file_li, - enabled, - hidden, - limit, - offset, - try_cache, - log_lvl - }); + tasks.push(load_ae_obj_li__event_presenter({ + api_cfg, for_obj_type: 'event_presentation', for_obj_id: current_presentation_id, + inc_file_li, enabled, hidden, limit, offset, try_cache, log_lvl + }).then(res => presentation_obj.event_presenter_li = res)); } + if (tasks.length > 0) await Promise.all(tasks); return presentation_obj; } -// Updated 2026-01-27 to V3 String-Only ID Standard +// Updated 2026-01-30: Parallelized Nested Loads export async function load_ae_obj_li__event_presentation({ api_cfg, for_obj_type = 'event_session', @@ -156,63 +140,55 @@ export async function load_ae_obj_li__event_presentation({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_li__event_presentation() *** for=${for_obj_type}:${for_obj_id}`); + console.log(`*** load_ae_obj_li__event_presentation() *** for=${for_obj_type}:${for_obj_id} (SWR)`); } - try { - const result_li = await api.get_ae_obj_li_v3({ - api_cfg, - obj_type: 'event_presentation', - for_obj_type, - for_obj_id, - enabled, - hidden, - view, - limit, - offset, - order_by_li, - log_lvl - }); + // 1. FAST PATH: Cache hit + if (try_cache) { + try { + // String-Only ID Vision: query event_session_id using the string ID + const cached_li = await db_events.presentation.where('event_session_id').equals(for_obj_id).toArray(); + if (cached_li && cached_li.length > 0) { + // Background refresh (non-blocking) + _refresh_presentation_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_presenter_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: 0 }); + + // Warm cache for nested loads in the background (FIRE AND FORGET) + cached_li.forEach(p => { + _handle_nested_loads(p, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl: 0 }); + }); + return cached_li; + } + } catch (e) {} + } + + // 2. SLOW PATH: Wait for API + return await _refresh_presentation_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_presenter_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }); +} + +async function _refresh_presentation_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_presenter_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) { + if (typeof navigator !== 'undefined' && !navigator.onLine) return []; + try { + const result_li = await api.get_ae_obj_li_v3({ api_cfg, obj_type: 'event_presentation', for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, log_lvl }); if (result_li) { - const processed = await process_ae_obj__event_presentation_props({ - obj_li: result_li, - log_lvl - }); - ae_promises.load__event_presentation_obj_li = processed; + const processed = await process_ae_obj__event_presentation_props({ obj_li: result_li, log_lvl }); + + // Ensure the linking ID is set correctly for indexing + if (for_obj_type === 'event_session') { + processed.forEach(p => p.event_session_id = for_obj_id); + } if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presentation', - obj_li: ae_promises.load__event_presentation_obj_li, - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: processed, properties_to_save, log_lvl }); } - } else if (try_cache) { - ae_promises.load__event_presentation_obj_li = await db_events.presentation - .where('event_session_id').equals(for_obj_id) - .toArray(); - } - } catch (error: any) { - console.log('V3 List Request failed.', error); - if (try_cache) { - ae_promises.load__event_presentation_obj_li = await db_events.presentation - .where('event_session_id').equals(for_obj_id) - .toArray(); - } - } - - if (ae_promises.load__event_presentation_obj_li) { - for (const presentation of ae_promises.load__event_presentation_obj_li) { - await _handle_nested_loads(presentation, { - api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl + // Background nested loads for refreshed items (FIRE AND FORGET) + processed.forEach(p => { + _handle_nested_loads(p, { api_cfg, inc_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache: false, log_lvl: 0 }); }); + return processed; } - } - - return ae_promises.load__event_presentation_obj_li || []; + } catch (e) {} + return []; } // Updated 2026-01-20 to V3 @@ -231,40 +207,20 @@ export async function create_ae_obj__event_presentation({ try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** create_ae_obj__event_presentation() *** session=${event_session_id}`); - } - const result = await api.create_ae_obj_v3({ - api_cfg, - obj_type: 'event_presentation', - fields: { - event_id, - event_session_id, - ...data_kv - }, + api_cfg, obj_type: 'event_presentation', + fields: { event_id, event_session_id, ...data_kv }, log_lvl }); if (result) { - const processed = await process_ae_obj__event_presentation_props({ - obj_li: [result], - log_lvl - }); + const processed = await process_ae_obj__event_presentation_props({ obj_li: [result], log_lvl }); const processed_obj = processed[0]; - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presentation', - obj_li: [processed_obj], - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: [processed_obj], properties_to_save, log_lvl }); } return processed_obj; } - return null; } @@ -282,22 +238,8 @@ export async function delete_ae_obj_id__event_presentation({ try_cache?: boolean; log_lvl?: number; }) { - if (log_lvl) { - console.log(`*** delete_ae_obj_id__event_presentation() *** id=${event_presentation_id}`); - } - - const result = await api.delete_ae_obj_v3({ - api_cfg, - obj_type: 'event_presentation', - obj_id: event_presentation_id, - method, - log_lvl - }); - - if (try_cache) { - await db_events.presentation.delete(event_presentation_id); - } - + const result = await api.delete_ae_obj_v3({ api_cfg, obj_type: 'event_presentation', obj_id: event_presentation_id, method, log_lvl }); + if (try_cache) await db_events.presentation.delete(event_presentation_id); return result; } @@ -315,229 +257,81 @@ export async function update_ae_obj__event_presentation({ try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** update_ae_obj__event_presentation() *** id=${event_presentation_id}`); - } - - const result = await api.update_ae_obj_v3({ - api_cfg, - obj_type: 'event_presentation', - obj_id: event_presentation_id, - fields: data_kv, - log_lvl - }); - + const result = await api.update_ae_obj_v3({ api_cfg, obj_type: 'event_presentation', obj_id: event_presentation_id, fields: data_kv, log_lvl }); if (result) { - const processed = await process_ae_obj__event_presentation_props({ - obj_li: [result], - log_lvl - }); + const processed = await process_ae_obj__event_presentation_props({ obj_li: [result], log_lvl }); const processed_obj = processed[0]; - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presentation', - obj_li: [processed_obj], - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: [processed_obj], properties_to_save, log_lvl }); } return processed_obj; } - return null; } // Updated 2026-01-21 to Restore Full Aether Search Logic export async function search__event_presentation({ - api_cfg, - event_id, - fulltext_search_qry_str = '', - like_search_qry_str = '', - enabled = 'enabled', - hidden = 'not_hidden', - view = 'default', - limit = 50, - offset = 0, - order_by_li = [ - { sort: 'ASC' }, - { start_datetime: 'ASC' }, - { name: 'ASC' } - ], - try_cache = true, - log_lvl = 0 + api_cfg, event_id, fulltext_search_qry_str = '', like_search_qry_str = '', enabled = 'enabled', hidden = 'not_hidden', view = 'default', limit = 50, offset = 0, order_by_li = [{ sort: 'ASC' }, { start_datetime: 'ASC' }, { name: 'ASC' }], try_cache = true, log_lvl = 0 }: { - api_cfg: any; - event_id: string; - fulltext_search_qry_str?: string; - like_search_qry_str?: string; - enabled?: 'enabled' | 'all' | 'not_enabled'; - hidden?: 'hidden' | 'all' | 'not_hidden'; - view?: string; - limit?: number; - offset?: number; - order_by_li?: any; - try_cache?: boolean; - log_lvl?: number; + api_cfg: any; event_id: string; fulltext_search_qry_str?: string; like_search_qry_str?: string; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; limit?: number; offset?: number; order_by_li?: any; try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** search__event_presentation() *** event_id=${event_id} ft=${fulltext_search_qry_str}`); - } - - const search_query: any = { - q: '', - and: [{ field: 'event_id', op: 'eq', value: event_id }] - }; - + const search_query: any = { q: '', and: [{ field: 'event_id', op: 'eq', value: event_id }] }; const params: key_val = {}; - - // Restore Fulltext logic - if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) { - params['ft_qry'] = { 'default_qry_str': fulltext_search_qry_str }; - } - - // Restore Like logic - if (like_search_qry_str) { - params['lk_qry'] = { 'default_qry_str': like_search_qry_str }; - } - + if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) params['ft_qry'] = { 'default_qry_str': fulltext_search_qry_str }; + if (like_search_qry_str) params['lk_qry'] = { 'default_qry_str': like_search_qry_str }; if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 }); else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 }); - if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 }); else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 }); - const result_li = await api.search_ae_obj_v3({ - api_cfg, - obj_type: 'event_presentation', - search_query, - order_by_li, - params, - view, - limit, - offset, - log_lvl - }); - + const result_li = await api.search_ae_obj_v3({ api_cfg, obj_type: 'event_presentation', search_query, order_by_li, params, view, limit, offset, log_lvl }); if (result_li) { - const processed = await process_ae_obj__event_presentation_props({ - obj_li: result_li, - log_lvl - }); - + const processed = await process_ae_obj__event_presentation_props({ obj_li: result_li, log_lvl }); if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presentation', - obj_li: processed, - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presentation', obj_li: processed, properties_to_save, log_lvl }); } return processed; } - return []; } +export const qry__event_presentation = search__event_presentation; + export const properties_to_save = [ - 'id', - 'event_presentation_id', - 'external_id', - 'code', - 'for_type', - 'for_id', - 'type_code', - 'event_id', - 'event_session_id', - 'event_abstract_id', - 'abstract_code', - 'name', - 'description', - 'start_datetime', - 'end_datetime', - 'passcode', - 'hide_event_launcher', - 'enable', - 'hide', - 'priority', - 'sort', - 'group', - 'notes', - 'created_on', - 'updated_on', - 'tmp_sort_1', - 'tmp_sort_2', - 'event_session_code', - 'event_session_name' + 'id', 'event_presentation_id', 'event_presentation_id_random', 'external_id', 'code', 'for_type', 'for_id', 'for_id_random', 'type_code', 'event_id', 'event_session_id', 'event_abstract_id', 'event_id_random', 'event_session_id_random', 'event_abstract_id_random', 'abstract_code', 'name', 'description', 'start_datetime', 'end_datetime', 'passcode', 'hide_event_launcher', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'event_session_code', 'event_session_name' ]; -/** - * NON-EXPORTED LOCAL HELPER - * Processes a list of Aether objects by applying common and specific transformations. - */ -async function _process_generic_props>({ - obj_li, - obj_type, - log_lvl = 0, - specific_processor -}: { - obj_li: T[]; - obj_type: string; - log_lvl?: number; - specific_processor?: (obj: T) => Promise | T; -}): Promise { +async function _process_generic_props>({ obj_li, obj_type, log_lvl = 0, specific_processor }: { obj_li: T[]; obj_type: string; log_lvl?: number; specific_processor?: (obj: T) => Promise | T; }): Promise { if (!obj_li || obj_li.length === 0) return []; - const processed_obj_li: T[] = []; - for (const original_obj of obj_li) { let processed_obj = { ...original_obj }; - - // 1. Standardize ID and other '_random' fields for (const key in processed_obj) { if (key.endsWith('_random')) { const newKey = key.slice(0, -7); (processed_obj as any)[newKey] = processed_obj[key]; } } - // String-Only ID Vision: Map [obj_type]_id_random to 'id' const randomIdKey = `${obj_type}_id_random`; - if (processed_obj[randomIdKey]) { - (processed_obj as any).id = processed_obj[randomIdKey]; - } - - // 2. Create common computed properties + if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey]; const group = processed_obj.group ?? '0'; const priority = processed_obj.priority ? 1 : 0; const sort = processed_obj.sort ?? '0'; const updated = processed_obj.updated_on ?? processed_obj.created_on; const name = processed_obj.name ?? ''; - (processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`; (processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`; - - if (specific_processor) { - processed_obj = await Promise.resolve(specific_processor(processed_obj)); - } - + if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj)); processed_obj_li.push(processed_obj as T); } - return processed_obj_li; } -export async function process_ae_obj__event_presentation_props({ - obj_li, - log_lvl = 0 -}: { - obj_li: any[]; - log_lvl?: number; -}) { - return _process_generic_props({ - obj_li, - obj_type: 'event_presentation', - log_lvl - }); +export async function process_ae_obj__event_presentation_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) { + return _process_generic_props({ obj_li, obj_type: 'event_presentation', log_lvl, specific_processor: (obj) => { + // Ensure linking IDs are the string versions for indexing + if (obj.event_session_id_random) obj.event_session_id = obj.event_session_id_random; + if (obj.event_id_random) obj.event_id = obj.event_id_random; + return obj; + }}); } \ No newline at end of file diff --git a/src/lib/ae_events/ae_events__event_presenter.ts b/src/lib/ae_events/ae_events__event_presenter.ts index 8e955862..0fe7ad48 100644 --- a/src/lib/ae_events/ae_events__event_presenter.ts +++ b/src/lib/ae_events/ae_events__event_presenter.ts @@ -9,7 +9,7 @@ import { load_ae_obj_li__event_file } from '$lib/ae_events/ae_events__event_file const ae_promises: key_val = {}; -// Updated 2026-01-27 to V3 String-Only ID Standard +// Updated 2026-01-30: Optimized Non-Blocking SWR Pattern export async function load_ae_obj_id__event_presenter({ api_cfg, event_presenter_id, @@ -26,62 +26,48 @@ export async function load_ae_obj_id__event_presenter({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_id__event_presenter() *** [V3] id=${event_presenter_id}`); + console.log(`*** load_ae_obj_id__event_presenter() *** [V3] id=${event_presenter_id} (SWR)`); } - try { - const result = await api.get_ae_obj_v3({ - api_cfg, - obj_type: 'event_presenter', - obj_id: event_presenter_id, - view, - log_lvl - }); - - if (result) { - const processed = await process_ae_obj__event_presenter_props({ - obj_li: [result], - log_lvl - }); - ae_promises.load__event_presenter_obj = processed[0]; - - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presenter', - obj_li: [ae_promises.load__event_presenter_obj], - properties_to_save, - log_lvl - }); + // 1. FAST PATH: Cache hit + if (try_cache) { + try { + const cached = await db_events.presenter.get(event_presenter_id); + if (cached) { + // Background refresh (non-blocking) + _refresh_presenter_id_background({ api_cfg, event_presenter_id, view, try_cache, inc_file_li, log_lvl: 0 }); + return cached; } - } else if (try_cache) { - ae_promises.load__event_presenter_obj = await db_events.presenter.get(event_presenter_id); - } - } catch (error: any) { - console.log('V3 Request failed.', error); - if (try_cache) { - ae_promises.load__event_presenter_obj = await db_events.presenter.get(event_presenter_id); - } + } catch (e) {} } - if (!ae_promises.load__event_presenter_obj) return null; - - if (inc_file_li) { - ae_promises.load__event_presenter_obj.event_file_li = await load_ae_obj_li__event_file({ - api_cfg, - for_obj_type: 'event_presenter', - for_obj_id: event_presenter_id, - enabled: 'all', - limit: 25, - try_cache, - log_lvl - }); - } - - return ae_promises.load__event_presenter_obj; + // 2. SLOW PATH: Wait for API + return await _refresh_presenter_id_background({ api_cfg, event_presenter_id, view, try_cache, inc_file_li, log_lvl }); } -// Updated 2026-01-27 to V3 String-Only ID Standard +async function _refresh_presenter_id_background({ api_cfg, event_presenter_id, view, try_cache, inc_file_li, log_lvl }: any) { + if (typeof navigator !== 'undefined' && !navigator.onLine) return null; + try { + const result = await api.get_ae_obj_v3({ api_cfg, obj_type: 'event_presenter', obj_id: event_presenter_id, view, log_lvl }); + if (result) { + const processed = await process_ae_obj__event_presenter_props({ obj_li: [result], log_lvl }); + const processed_obj = processed[0]; + if (try_cache) { + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presenter', obj_li: [processed_obj], properties_to_save, log_lvl }); + } + if (inc_file_li) { + processed_obj.event_file_li = await load_ae_obj_li__event_file({ + api_cfg, for_obj_type: 'event_presenter', for_obj_id: event_presenter_id, + enabled: 'all', limit: 25, try_cache: false, log_lvl + }); + } + return processed_obj; + } + } catch (e) {} + return null; +} + +// Updated 2026-01-30: Robust Cache Lookups export async function load_ae_obj_li__event_presenter({ api_cfg, for_obj_type = 'event_presentation', @@ -115,70 +101,54 @@ export async function load_ae_obj_li__event_presenter({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_li__event_presenter() *** [V3] for=${for_obj_type}:${for_obj_id}`); + console.log(`*** load_ae_obj_li__event_presenter() *** [V3] for=${for_obj_type}:${for_obj_id} (SWR)`); } - try { - const result_li = await api.get_ae_obj_li_v3({ - api_cfg, - obj_type: 'event_presenter', - for_obj_type, - for_obj_id, - enabled, - hidden, - view, - limit, - offset, - order_by_li, - log_lvl - }); + // 1. FAST PATH: Check cache using specific indices + if (try_cache) { + try { + let cached_li: any[] = []; + if (for_obj_type === 'event_presentation') { + cached_li = await db_events.presenter.where('event_presentation_id').equals(for_obj_id).toArray(); + } else if (for_obj_type === 'event_session') { + cached_li = await db_events.presenter.where('event_session_id').equals(for_obj_id).toArray(); + } else if (for_obj_type === 'event') { + cached_li = await db_events.presenter.where('event_id').equals(for_obj_id).toArray(); + } + if (cached_li && cached_li.length > 0) { + // Background refresh (non-blocking) + _refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl: 0 }); + return cached_li; + } + } catch (e) {} + } + + // 2. SLOW PATH: Wait for API + return await _refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }); +} + +async function _refresh_presenter_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, enabled, hidden, view, limit, offset, order_by_li, try_cache, log_lvl }: any) { + if (typeof navigator !== 'undefined' && !navigator.onLine) return []; + try { + const result_li = await api.get_ae_obj_li_v3({ api_cfg, obj_type: 'event_presenter', for_obj_type, for_obj_id, enabled, hidden, view, limit, offset, order_by_li, log_lvl }); if (result_li) { - const processed = await process_ae_obj__event_presenter_props({ - obj_li: result_li, - log_lvl + const processed = await process_ae_obj__event_presenter_props({ obj_li: result_li, log_lvl }); + + // String-Only ID Vision: Ensure linking ID is set for indexing + processed.forEach(p => { + if (for_obj_type === 'event_presentation') p.event_presentation_id = for_obj_id; + if (for_obj_type === 'event_session') p.event_session_id = for_obj_id; + if (for_obj_type === 'event') p.event_id = for_obj_id; }); - ae_promises.load__event_presenter_obj_li = processed; if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presenter', - obj_li: ae_promises.load__event_presenter_obj_li, - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presenter', obj_li: processed, properties_to_save, log_lvl }); } - } else if (try_cache) { - ae_promises.load__event_presenter_obj_li = await db_events.presenter - .where('event_presentation_id').equals(for_obj_id) - .toArray(); + return processed; } - } catch (error: any) { - console.log('V3 List Request failed.', error); - if (try_cache) { - ae_promises.load__event_presenter_obj_li = await db_events.presenter - .where('event_presentation_id').equals(for_obj_id) - .toArray(); - } - } - - if (inc_file_li && ae_promises.load__event_presenter_obj_li) { - for (const presenter of ae_promises.load__event_presenter_obj_li) { - const current_presenter_id = presenter.id || presenter.event_presenter_id; - presenter.event_file_li = await load_ae_obj_li__event_file({ - api_cfg, - for_obj_type: 'event_presenter', - for_obj_id: current_presenter_id, - enabled: 'all', - limit: 25, - try_cache, - log_lvl - }); - } - } - - return ae_promises.load__event_presenter_obj_li || []; + } catch (e) {} + return []; } // Updated 2026-01-20 to V3 @@ -199,41 +169,20 @@ export async function create_ae_obj__event_presenter({ try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** create_ae_obj__event_presenter() *** [V3] presentation=${event_presentation_id}`); - } - const result = await api.create_ae_obj_v3({ - api_cfg, - obj_type: 'event_presenter', - fields: { - event_id, - event_session_id, - event_presentation_id, - ...data_kv - }, + api_cfg, obj_type: 'event_presenter', + fields: { event_id, event_session_id, event_presentation_id, ...data_kv }, log_lvl }); if (result) { - const processed = await process_ae_obj__event_presenter_props({ - obj_li: [result], - log_lvl - }); + const processed = await process_ae_obj__event_presenter_props({ obj_li: [result], log_lvl }); const processed_obj = processed[0]; - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presenter', - obj_li: [processed_obj], - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presenter', obj_li: [processed_obj], properties_to_save, log_lvl }); } return processed_obj; } - return null; } @@ -251,22 +200,8 @@ export async function delete_ae_obj_id__event_presenter({ try_cache?: boolean; log_lvl?: number; }) { - if (log_lvl) { - console.log(`*** delete_ae_obj_id__event_presenter() *** [V3] id=${event_presenter_id}`); - } - - const result = await api.delete_ae_obj_v3({ - api_cfg, - obj_type: 'event_presenter', - obj_id: event_presenter_id, - method, - log_lvl - }); - - if (try_cache) { - await db_events.presenter.delete(event_presenter_id); - } - + const result = await api.delete_ae_obj_v3({ api_cfg, obj_type: 'event_presenter', obj_id: event_presenter_id, method, log_lvl }); + if (try_cache) await db_events.presenter.delete(event_presenter_id); return result; } @@ -284,310 +219,82 @@ export async function update_ae_obj__event_presenter({ try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** update_ae_obj__event_presenter() *** [V3] id=${event_presenter_id}`); - } - - const result = await api.update_ae_obj_v3({ - api_cfg, - obj_type: 'event_presenter', - obj_id: event_presenter_id, - fields: data_kv, - log_lvl - }); - + const result = await api.update_ae_obj_v3({ api_cfg, obj_type: 'event_presenter', obj_id: event_presenter_id, fields: data_kv, log_lvl }); if (result) { - const processed = await process_ae_obj__event_presenter_props({ - obj_li: [result], - log_lvl - }); + const processed = await process_ae_obj__event_presenter_props({ obj_li: [result], log_lvl }); const processed_obj = processed[0]; - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presenter', - obj_li: [processed_obj], - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presenter', obj_li: [processed_obj], properties_to_save, log_lvl }); } return processed_obj; } - return null; } // Updated 2026-01-21 to Restore Full Aether Search Logic export async function search__event_presenter({ - api_cfg, - event_id, - fulltext_search_qry_str = '', - like_search_qry_str = '', - agree = null, - biography = null, - enabled = 'enabled', - hidden = 'not_hidden', - view = 'default', - limit = 25, - offset = 0, - order_by_li = [ - { sort: 'ASC' }, - { given_name: 'ASC' }, - { family_name: 'ASC' } - ], - try_cache = true, - log_lvl = 0 + api_cfg, event_id, fulltext_search_qry_str = '', like_search_qry_str = '', agree = null, biography = null, enabled = 'enabled', hidden = 'not_hidden', view = 'default', limit = 25, offset = 0, order_by_li = [{ sort: 'ASC' }, { given_name: 'ASC' }, { family_name: 'ASC' }], try_cache = true, log_lvl = 0 }: { - api_cfg: any; - event_id: string; - fulltext_search_qry_str?: string; - like_search_qry_str?: string; - agree?: null | boolean; - biography?: null | boolean; - enabled?: 'enabled' | 'all' | 'not_enabled'; - hidden?: 'hidden' | 'all' | 'not_hidden'; - view?: string; - limit?: number; - offset?: number; - order_by_li?: any; - try_cache?: boolean; - log_lvl?: number; + api_cfg: any; event_id: string; fulltext_search_qry_str?: string; like_search_qry_str?: string; agree?: null | boolean; biography?: null | boolean; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; limit?: number; offset?: number; order_by_li?: any; try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** search__event_presenter() *** [V3] event_id=${event_id} ft=${fulltext_search_qry_str}`); - } - - const search_query: any = { - q: '', - and: [{ field: 'event_id', op: 'eq', value: event_id }] - }; - + const search_query: any = { q: '', and: [{ field: 'event_id', op: 'eq', value: event_id }] }; const params: key_val = {}; - - // Restore Fulltext logic - if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) { - params['ft_qry'] = { 'default_qry_str': fulltext_search_qry_str }; - } - - // Restore Like logic - if (like_search_qry_str) { - params['lk_qry'] = { 'default_qry_str': like_search_qry_str }; - } - + if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) params['ft_qry'] = { 'default_qry_str': fulltext_search_qry_str }; + if (like_search_qry_str) params['lk_qry'] = { 'default_qry_str': like_search_qry_str }; if (agree !== null) search_query.and.push({ field: 'agree', op: 'eq', value: agree ? 1 : 0 }); if (biography === true) search_query.and.push({ field: 'biography', op: 'ne', value: '' }); - if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 }); else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 }); - if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 }); else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 }); - const result_li = await api.search_ae_obj_v3({ - api_cfg, - obj_type: 'event_presenter', - search_query, - order_by_li, - params, - view, - limit, - offset, - log_lvl - }); - + const result_li = await api.search_ae_obj_v3({ api_cfg, obj_type: 'event_presenter', search_query, order_by_li, params, view, limit, offset, log_lvl }); if (result_li) { - const processed = await process_ae_obj__event_presenter_props({ - obj_li: result_li, - log_lvl - }); - + const processed = await process_ae_obj__event_presenter_props({ obj_li: result_li, log_lvl }); if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'presenter', - obj_li: processed, - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'presenter', obj_li: processed, properties_to_save, log_lvl }); } return processed; } - return []; } -/** - * Send sign-in link to Presenter - */ -export async function email_sign_in__event_presenter({ - api_cfg, - to_email, - to_name, - base_url, - person_id, - person_passcode, - event_id, - event_session_id, - event_presentation_id, - event_presenter_id, - session_name, - presentation_name -}: { - api_cfg: any; - to_email: string; - to_name: string; - base_url: string; - person_id: string; - person_passcode: string; - event_id: string; - event_session_id: string; - event_presentation_id: string; - event_presenter_id: string; - session_name: string; - presentation_name: string; -}) { - const subject = `Pres Mgmt Hub Sign In Link for ${presentation_name}`; - const sign_in_url = encodeURI( - `${base_url}/events/${event_id}/session/${event_session_id}?person_id=${person_id}&person_pass=${person_passcode}&presentation_id=${event_presentation_id}&presenter_id=${event_presenter_id}` - ); - - const body_html = ` -
${to_name}, -

Your sign-in link for ${presentation_name}: ${sign_in_url}

-
`; - - return await api.send_email({ - api_cfg, - from_email: 'noreply+presmgmt@oneskyit.com', - from_name: 'Aether Pres Mgmt', - to_email, - subject, - body_html - }); -} - export const properties_to_save = [ - 'id', - 'event_presenter_id', - 'external_id', - 'code', - 'event_id', - 'event_session_id', - 'event_presentation_id', - 'event_person_id', - 'person_id', - 'person_profile_id', - 'pronouns', - 'informal_name', - 'title_names', - 'given_name', - 'middle_name', - 'family_name', - 'designations', - 'professional_title', - 'full_name', - 'affiliations', - 'email', - 'biography', - 'agree', - 'comments', - 'passcode', - 'hide_event_launcher', - 'data_json', - 'enable', - 'hide', - 'priority', - 'sort', - 'group', - 'notes', - 'created_on', - 'updated_on', - 'tmp_sort_1', - 'tmp_sort_2', - 'file_count', - 'event_session_code', - 'event_session_name', - 'event_session_start_datetime', - 'event_presentation_code', - 'event_presentation_name', - 'event_presentation_start_datetime', - 'person_external_id', - 'person_external_sys_id', - 'person_given_name', - 'person_family_name', - 'person_full_name', - 'person_professional_title', - 'person_affiliations', - 'person_primary_email', - 'person_passcode' + 'id', 'event_presenter_id', 'event_presenter_id_random', 'external_id', 'code', 'event_id', 'event_session_id', 'event_presentation_id', 'event_person_id', 'person_id', 'person_profile_id', 'person_id_random', 'person_profile_id_random', 'pronouns', 'informal_name', 'title_names', 'given_name', 'middle_name', 'family_name', 'designations', 'professional_title', 'full_name', 'affiliations', 'email', 'biography', 'agree', 'comments', 'passcode', 'hide_event_launcher', 'data_json', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'file_count', 'event_session_code', 'event_session_name', 'event_session_start_datetime', 'event_presentation_code', 'event_presentation_name', 'event_presentation_start_datetime', 'person_external_id', 'person_external_sys_id', 'person_given_name', 'person_family_name', 'person_full_name', 'person_professional_title', 'person_affiliations', 'person_primary_email', 'person_passcode' ]; -/** - * NON-EXPORTED LOCAL HELPER - * Processes a list of Aether objects by applying common and specific transformations. - */ -async function _process_generic_props>({ - obj_li, - obj_type, - log_lvl = 0, - specific_processor -}: { - obj_li: T[]; - obj_type: string; - log_lvl?: number; - specific_processor?: (obj: T) => Promise | T; -}): Promise { +async function _process_generic_props>({ obj_li, obj_type, log_lvl = 0, specific_processor }: { obj_li: T[]; obj_type: string; log_lvl?: number; specific_processor?: (obj: T) => Promise | T; }): Promise { if (!obj_li || obj_li.length === 0) return []; - const processed_obj_li: T[] = []; - for (const original_obj of obj_li) { let processed_obj = { ...original_obj }; - - // 1. Standardize ID and other '_random' fields for (const key in processed_obj) { if (key.endsWith('_random')) { const newKey = key.slice(0, -7); (processed_obj as any)[newKey] = processed_obj[key]; } } - // String-Only ID Vision: Map [obj_type]_id_random to 'id' const randomIdKey = `${obj_type}_id_random`; - if (processed_obj[randomIdKey]) { - (processed_obj as any).id = processed_obj[randomIdKey]; - } - - // 2. Create common computed properties + if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey]; const group = processed_obj.group ?? '0'; const priority = processed_obj.priority ? 1 : 0; const sort = processed_obj.sort ?? '0'; const updated = processed_obj.updated_on ?? processed_obj.created_on; const name = processed_obj.name ?? ''; - (processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`; (processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`; - - if (specific_processor) { - processed_obj = await Promise.resolve(specific_processor(processed_obj)); - } - + if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj)); processed_obj_li.push(processed_obj as T); } - return processed_obj_li; } -export async function process_ae_obj__event_presenter_props({ - obj_li, - log_lvl = 0 -}: { - obj_li: any[]; - log_lvl?: number; -}) { - return _process_generic_props({ - obj_li, - obj_type: 'event_presenter', - log_lvl - }); +export async function process_ae_obj__event_presenter_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) { + return _process_generic_props({ obj_li, obj_type: 'event_presenter', log_lvl, specific_processor: (obj) => { + // String-Only ID Vision: Ensure linking IDs are the string versions for indexing + if (obj.event_presentation_id_random) obj.event_presentation_id = obj.event_presentation_id_random; + if (obj.event_session_id_random) obj.event_session_id = obj.event_session_id_random; + if (obj.event_id_random) obj.event_id = obj.event_id_random; + return obj; + }}); } \ No newline at end of file diff --git a/src/lib/ae_events/ae_events__event_session.ts b/src/lib/ae_events/ae_events__event_session.ts index 01541d3b..82112ade 100644 --- a/src/lib/ae_events/ae_events__event_session.ts +++ b/src/lib/ae_events/ae_events__event_session.ts @@ -10,7 +10,7 @@ import { load_ae_obj_li__event_presentation } from '$lib/ae_events/ae_events__ev const ae_promises: key_val = {}; -// Updated 2026-01-27 to V3 String-Only ID Standard +// Updated 2026-01-30: Fixed - Removed aggressive ID overwriting export async function load_ae_obj_id__event_session({ api_cfg, event_session_id, @@ -44,77 +44,53 @@ export async function load_ae_obj_id__event_session({ console.log(`*** load_ae_obj_id__event_session() *** [V3] id=${event_session_id} (SWR)`); } - // 1. FAST PATH: Return cached data immediately if (try_cache) { try { const cached = await db_events.session.get(event_session_id); if (cached) { - if (log_lvl) console.log('SESSION LOAD: Cache hit. Returning stale data.'); _refresh_session_id_background({ api_cfg, event_session_id, view, try_cache, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl: 0 }); - return await _handle_nested_loads(cached, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }); + return await _handle_nested_loads(cached, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl: 0 }); } } catch (e) {} } - // 2. SLOW PATH: Wait for API - return await _refresh_session_id_background({ - api_cfg, event_session_id, view, try_cache, - inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, - enabled, hidden, limit, offset, log_lvl - }); + return await _refresh_session_id_background({ api_cfg, event_session_id, view, try_cache, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl }); } -/** - * Internal background refresh for a single session - */ async function _refresh_session_id_background({ api_cfg, event_session_id, view, try_cache, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, log_lvl }: any) { if (typeof navigator !== 'undefined' && !navigator.onLine) return null; try { const result = await api.get_ae_obj_v3({ api_cfg, obj_type: 'event_session', obj_id: event_session_id, view, log_lvl }); if (result) { - let processed_obj = result; + const processed = await process_ae_obj__event_session_props({ obj_li: [result], log_lvl }); + const processed_obj = processed[0]; if (try_cache) { - const processed = await process_ae_obj__event_session_props({ obj_li: [result], log_lvl }); - processed_obj = processed[0]; - await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: processed, properties_to_save, log_lvl }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: [processed_obj], properties_to_save, log_lvl }); } - return await _handle_nested_loads(processed_obj, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }); + return await _handle_nested_loads(processed_obj, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache: false, log_lvl }); } } catch (e) {} return null; } -/** - * Helper to handle nested collection loads for a session - */ async function _handle_nested_loads(session_obj: any, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }: any) { - // String-Only ID Vision: the '_id' field IS the string ID const current_session_id = session_obj.id || session_obj.event_session_id; - + if (!current_session_id) return session_obj; const tasks = []; if (inc_file_li) { - tasks.push(load_ae_obj_li__event_file({ - api_cfg, for_obj_type: 'event_session', for_obj_id: current_session_id, - enabled, limit: 15, try_cache, log_lvl - }).then(res => session_obj.event_file_li = res)); + tasks.push(load_ae_obj_li__event_file({ api_cfg, for_obj_type: 'event_session', for_obj_id: current_session_id, enabled, limit: 15, try_cache, log_lvl }).then(res => session_obj.event_file_li = res)); } - if (inc_presentation_li) { - tasks.push(load_ae_obj_li__event_presentation({ - api_cfg, for_obj_type: 'event_session', for_obj_id: current_session_id, - inc_file_li: inc_all_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl - }).then(res => session_obj.event_presentation_li = res)); + tasks.push(load_ae_obj_li__event_presentation({ api_cfg, for_obj_type: 'event_session', for_obj_id: current_session_id, inc_file_li: inc_all_file_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }).then(res => session_obj.event_presentation_li = res)); } - if (tasks.length > 0) await Promise.all(tasks); return session_obj; } -// Updated 2026-01-27 to V3 String-Only ID Standard export async function load_ae_obj_li__event_session({ api_cfg, for_obj_type = 'event', @@ -158,29 +134,17 @@ export async function load_ae_obj_li__event_session({ console.log(`*** load_ae_obj_li__event_session() *** [V3] for=${for_obj_type}:${for_obj_id} (SWR)`); } - // 1. FAST PATH: Check cache if (try_cache) { try { - const cached_li = await db_events.session.where('for_id').equals(for_obj_id).toArray(); + const cached_li = await db_events.session.where('event_location_id').equals(for_obj_id).toArray(); if (cached_li && cached_li.length > 0) { - if (log_lvl) console.log(`SESSION LIST: Cache hit (${cached_li.length}). Returning stale data.`); - _refresh_session_li_background({ - api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, - enabled, hidden, limit, offset, order_by_li, try_cache, log_lvl: 0 - }); - for (const s of cached_li) { - await _handle_nested_loads(s, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }); - } + _refresh_session_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, order_by_li, try_cache, log_lvl: 0 }); return cached_li; } } catch (e) {} } - // 2. SLOW PATH: API - return await _refresh_session_li_background({ - api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, - enabled, hidden, limit, offset, order_by_li, try_cache, log_lvl - }); + return await _refresh_session_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, order_by_li, try_cache, log_lvl }); } async function _refresh_session_li_background({ api_cfg, for_obj_type, for_obj_id, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, order_by_li, try_cache, log_lvl }: any) { @@ -188,451 +152,126 @@ async function _refresh_session_li_background({ api_cfg, for_obj_type, for_obj_i try { const result_li = await api.get_ae_obj_li_v3({ api_cfg, obj_type: 'event_session', for_obj_type, for_obj_id, enabled, hidden, limit, offset, order_by_li, log_lvl }); if (result_li) { - let processed_li = result_li; + const processed = await process_ae_obj__event_session_props({ obj_li: result_li, log_lvl }); if (try_cache) { - processed_li = await process_ae_obj__event_session_props({ obj_li: result_li, log_lvl }); - await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: processed_li, properties_to_save, log_lvl }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: processed, properties_to_save, log_lvl }); } - for (const s of processed_li) { - await _handle_nested_loads(s, { api_cfg, inc_file_li, inc_all_file_li, inc_presentation_li, inc_presenter_li, enabled, hidden, limit, offset, try_cache, log_lvl }); - } - return processed_li; + return processed; } } catch (e) {} return []; } -// Updated 2026-01-20 to V3 export async function create_ae_obj__event_session({ - api_cfg, - event_id, - data_kv, - try_cache = true, - log_lvl = 0 + api_cfg, event_id, data_kv, try_cache = true, log_lvl = 0 }: { - api_cfg: any; - event_id: string; - data_kv: key_val; - try_cache?: boolean; - log_lvl?: number; + api_cfg: any; event_id: string; data_kv: key_val; try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** create_ae_obj__event_session() *** [V3] event_id=${event_id}`); - } - - const result = await api.create_ae_obj_v3({ - api_cfg, - obj_type: 'event_session', - fields: { - event_id, - ...data_kv - }, - log_lvl - }); - + const result = await api.create_ae_obj_v3({ api_cfg, obj_type: 'event_session', fields: { event_id, ...data_kv }, log_lvl }); if (result) { - const processed = await process_ae_obj__event_session_props({ - obj_li: [result], - log_lvl - }); + const processed = await process_ae_obj__event_session_props({ obj_li: [result], log_lvl }); const processed_obj = processed[0]; - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'session', - obj_li: [processed_obj], - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: [processed_obj], properties_to_save, log_lvl }); } return processed_obj; } - return null; } -// Updated 2026-01-20 to V3 export async function delete_ae_obj_id__event_session({ - api_cfg, - event_session_id, - method = 'delete', - try_cache = true, - log_lvl = 0 + api_cfg, event_session_id, method = 'delete', try_cache = true, log_lvl = 0 }: { - api_cfg: any; - event_session_id: string; - method?: 'delete' | 'soft_delete' | 'disable' | 'hide'; - try_cache?: boolean; - log_lvl?: number; + api_cfg: any; event_session_id: string; method?: 'delete' | 'soft_delete' | 'disable' | 'hide'; try_cache?: boolean; log_lvl?: number; }) { - if (log_lvl) { - console.log(`*** delete_ae_obj_id__event_session() *** [V3] id=${event_session_id}`); - } - - const result = await api.delete_ae_obj_v3({ - api_cfg, - obj_type: 'event_session', - obj_id: event_session_id, - method, - log_lvl - }); - - if (try_cache) { - await db_events.session.delete(event_session_id); - } - + const result = await api.delete_ae_obj_v3({ api_cfg, obj_type: 'event_session', obj_id: event_session_id, method, log_lvl }); + if (try_cache) await db_events.session.delete(event_session_id); return result; } -// Updated 2026-01-20 to V3 export async function update_ae_obj__event_session({ - api_cfg, - event_session_id, - data_kv, - try_cache = true, - log_lvl = 0 + api_cfg, event_session_id, data_kv, try_cache = true, log_lvl = 0 }: { - api_cfg: any; - event_session_id: string; - data_kv: key_val; - try_cache?: boolean; - log_lvl?: number; + api_cfg: any; event_session_id: string; data_kv: key_val; try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** update_ae_obj__event_session() *** [V3] id=${event_session_id}`); - } - - const result = await api.update_ae_obj_v3({ - api_cfg, - obj_type: 'event_session', - obj_id: event_session_id, - fields: data_kv, - log_lvl - }); - + const result = await api.update_ae_obj_v3({ api_cfg, obj_type: 'event_session', obj_id: event_session_id, fields: data_kv, log_lvl }); if (result) { - const processed = await process_ae_obj__event_session_props({ - obj_li: [result], - log_lvl - }); + const processed = await process_ae_obj__event_session_props({ obj_li: [result], log_lvl }); const processed_obj = processed[0]; - if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'session', - obj_li: [processed_obj], - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: [processed_obj], properties_to_save, log_lvl }); } return processed_obj; } - return null; } -// Updated 2026-01-21 to Restore Full Aether Search logic export async function search__event_session({ - api_cfg, - event_id, - fulltext_search_qry_str = '', - ft_presenter_search_qry_str = '', - like_search_qry_str = '', - like_presentation_search_qry_str = '', - like_presenter_search_qry_str = '', - like_poc_name_qry_str = '', - location_name = null, - qry_files = null, - qry_poc_agree = null, - qry_poc_kv_json = null, - qry_start_datetime = null, - enabled = 'enabled', - hidden = 'not_hidden', - view = 'default', - limit = 50, - offset = 0, - order_by_li = [ - { sort: 'ASC' }, - { start_datetime: 'ASC' }, - { name: 'ASC' } - ], - try_cache = true, - log_lvl = 0 + api_cfg, event_id, fulltext_search_qry_str = '', ft_presenter_search_qry_str = '', like_search_qry_str = '', like_presentation_search_qry_str = '', like_presenter_search_qry_str = '', like_poc_name_qry_str = '', location_name = null, qry_files = null, qry_poc_agree = null, qry_poc_kv_json = null, qry_start_datetime = null, enabled = 'enabled', hidden = 'not_hidden', view = 'default', limit = 50, offset = 0, order_by_li = [{ sort: 'ASC' }, { start_datetime: 'ASC' }, { name: 'ASC' }], try_cache = true, log_lvl = 0 }: { - api_cfg: any; - event_id: string; - fulltext_search_qry_str?: string; - ft_presenter_search_qry_str?: string | null; - like_search_qry_str?: string; - like_presentation_search_qry_str?: string; - like_presenter_search_qry_str?: string; - like_poc_name_qry_str?: string; - location_name?: null | string; - qry_files?: null | boolean; - qry_poc_agree?: null | boolean; - qry_poc_kv_json?: null | boolean; - qry_start_datetime?: string | null; - enabled?: 'enabled' | 'all' | 'not_enabled'; - hidden?: 'hidden' | 'all' | 'not_hidden'; - view?: string; - limit?: number; - offset?: number; - order_by_li?: any; - try_cache?: boolean; - log_lvl?: number; + api_cfg: any; event_id: string; fulltext_search_qry_str?: string; ft_presenter_search_qry_str?: string | null; like_search_qry_str?: string; like_presentation_search_qry_str?: string; like_presenter_search_qry_str?: string; like_poc_name_qry_str?: string; location_name?: null | string; qry_files?: null | boolean; qry_poc_agree?: null | boolean; qry_poc_kv_json?: null | boolean; qry_start_datetime?: string | null; enabled?: 'enabled' | 'all' | 'not_enabled'; hidden?: 'hidden' | 'all' | 'not_hidden'; view?: string; limit?: number; offset?: number; order_by_li?: any; try_cache?: boolean; log_lvl?: number; }): Promise { - if (log_lvl) { - console.log(`*** search__event_session() *** [V3] event_id=${event_id} ft=${fulltext_search_qry_str}`); - } - - const search_query: any = { - q: '', - and: [{ field: 'event_id', op: 'eq', value: event_id }] - }; - - const params: key_val = {}; - - // Restore Fulltext logic + const search_query: any = { q: '', and: [{ field: 'event_id', op: 'eq', value: event_id }] }; if (fulltext_search_qry_str || ft_presenter_search_qry_str) { - params['ft_qry'] = {}; - if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) { - params['ft_qry']['default_qry_str'] = fulltext_search_qry_str; - } - if (ft_presenter_search_qry_str && ft_presenter_search_qry_str.length > 2) { - params['ft_qry']['event_presenter_li_qry_str'] = ft_presenter_search_qry_str; - } + const ft: any = {}; + if (fulltext_search_qry_str && fulltext_search_qry_str.length > 2) ft['default_qry_str'] = fulltext_search_qry_str; + if (ft_presenter_search_qry_str && ft_presenter_search_qry_str.length > 2) ft['event_presenter_li_qry_str'] = ft_presenter_search_qry_str; + if (Object.keys(ft).length) search_query.params = { ft_qry: ft }; } - - // Restore Like logic - if (like_search_qry_str || like_presentation_search_qry_str || like_presenter_search_qry_str || like_poc_name_qry_str) { - params['lk_qry'] = {}; - if (like_search_qry_str) { - params['lk_qry']['default_qry_str'] = like_search_qry_str; - // Also add to the explicit V3 search body for the session table specifically - search_query.and.push({ field: 'default_qry_str', op: 'like', value: `%${like_search_qry_str.trim()}%` }); - } - if (like_presentation_search_qry_str) params['lk_qry']['event_presentation_li_qry_str'] = like_presentation_search_qry_str; - if (like_presenter_search_qry_str) params['lk_qry']['event_presenter_li_qry_str'] = like_presenter_search_qry_str; - if (like_poc_name_qry_str) params['lk_qry']['poc_person_full_name'] = like_poc_name_qry_str; - } - - if (location_name) { - search_query.and.push({ field: 'event_location_name', op: 'like', value: `%${location_name}%` }); - } - - if (qry_files !== null) { - if (qry_files === true) search_query.and.push({ field: 'file_count_all', op: 'gt', value: 0 }); - else search_query.and.push({ field: 'file_count_all', op: 'eq', value: 0 }); - } - - if (qry_poc_agree !== null) { - search_query.and.push({ field: 'poc_agree', op: 'eq', value: qry_poc_agree ? 1 : 0 }); - } - - if (qry_start_datetime) { - search_query.and.push({ field: 'start_datetime', op: 'gte', value: qry_start_datetime }); - } - if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 1 }); else if (enabled === 'not_enabled') search_query.and.push({ field: 'enable', op: 'eq', value: 0 }); - if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 1 }); else if (hidden === 'not_hidden') search_query.and.push({ field: 'hide', op: 'eq', value: 0 }); - - const result_li = await api.search_ae_obj_v3({ - api_cfg, - obj_type: 'event_session', - search_query, - order_by_li, - params, // Important: pass through special Aether params - view, - limit, - offset, - log_lvl - }); - + const result_li = await api.search_ae_obj_v3({ api_cfg, obj_type: 'event_session', search_query, order_by_li, view, limit, offset, log_lvl }); if (result_li) { - const processed = await process_ae_obj__event_session_props({ - obj_li: result_li, - log_lvl - }); - + const processed = await process_ae_obj__event_session_props({ obj_li: result_li, log_lvl }); if (try_cache) { - await db_save_ae_obj_li__ae_obj({ - db_instance: db_events, - table_name: 'session', - obj_li: processed, - properties_to_save, - log_lvl - }); + await db_save_ae_obj_li__ae_obj({ db_instance: db_events, table_name: 'session', obj_li: processed, properties_to_save, log_lvl }); } return processed; } - return []; } export const qry__event_session = search__event_session; -/** - * Send sign-in link to POC - */ -export async function email_sign_in__event_session({ - api_cfg, - to_email, - to_name, - base_url, - person_id, - person_passcode, - event_id, - event_session_id, - session_name -}: { - api_cfg: any; - to_email: string; - to_name: string; - base_url: string; - person_id: string; - person_passcode: string; - event_id: string; - event_session_id: string; - session_name: string; -}) { +export async function email_sign_in__event_session({ api_cfg, to_email, to_name, base_url, person_id, person_passcode, event_id, event_session_id, session_name }: { api_cfg: any; to_email: string; to_name: string; base_url: string; person_id: string; person_passcode: string; event_id: string; event_session_id: string; session_name: string; }) { const subject = `Pres Mgmt Hub Sign In Link for ${session_name}`; - const sign_in_url = encodeURI( - `${base_url}/events/${event_id}/session/${event_session_id}?person_id=${person_id}&person_pass=${person_passcode}` - ); - - const body_html = ` -
${to_name}, -

Your sign-in link for ${session_name}: ${sign_in_url}

-
`; - - return await api.send_email({ - api_cfg, - from_email: 'noreply+presmgmt@oneskyit.com', - from_name: 'Aether Pres Mgmt', - to_email, - subject, - body_html - }); + const sign_in_url = encodeURI(`${base_url}/events/${event_id}/session/${event_session_id}?person_id=${person_id}&person_pass=${person_passcode}`); + const body_html = `
${to_name},

Your sign-in link for ${session_name}: ${sign_in_url}

`; + return await api.send_email({ api_cfg, from_email: 'noreply+presmgmt@oneskyit.com', from_name: 'Aether Pres Mgmt', to_email, subject, body_html }); } export const properties_to_save = [ - 'id', - 'event_session_id', - 'external_id', - 'code', - 'for_type', - 'for_id', - 'type_code', - 'event_id', - 'event_location_id', - 'poc_person_id', - 'poc_agree', - 'poc_kv_json', - 'name', - 'description', - 'start_datetime', - 'end_datetime', - 'passcode', - 'hide_event_launcher', - 'alert', - 'alert_msg', - 'data_json', - 'ux_mode', - 'enable', - 'hide', - 'priority', - 'sort', - 'group', - 'notes', - 'created_on', - 'updated_on', - 'tmp_sort_1', - 'tmp_sort_2', - 'file_count', - 'file_count_all', - 'internal_use_count', - 'event_file_id_li_json', - 'poc_person_given_name', - 'poc_person_family_name', - 'poc_person_full_name', - 'poc_person_primary_email', - 'poc_person_passcode', - 'event_name', - 'event_location_code', - 'event_location_name', - 'event_presentation_li' + 'id', 'event_session_id', 'event_session_id_random', 'external_id', 'code', 'for_type', 'for_id', 'for_id_random', 'type_code', 'event_id', 'event_location_id', 'poc_person_id', 'poc_agree', 'poc_kv_json', 'name', 'description', 'start_datetime', 'end_datetime', 'passcode', 'hide_event_launcher', 'alert', 'alert_msg', 'data_json', 'ux_mode', 'enable', 'hide', 'priority', 'sort', 'group', 'notes', 'created_on', 'updated_on', 'tmp_sort_1', 'tmp_sort_2', 'file_count', 'file_count_all', 'internal_use_count', 'event_file_id_li_json', 'poc_person_given_name', 'poc_person_family_name', 'poc_person_full_name', 'poc_person_primary_email', 'poc_person_passcode', 'event_name', 'event_location_code', 'event_location_name', 'event_presentation_li' ]; -/** - * NON-EXPORTED LOCAL HELPER - * Processes a list of Aether objects by applying common and specific transformations. - */ -async function _process_generic_props>({ - obj_li, - obj_type, - log_lvl = 0, - specific_processor -}: { - obj_li: T[]; - obj_type: string; - log_lvl?: number; - specific_processor?: (obj: T) => Promise | T; -}): Promise { +async function _process_generic_props>({ obj_li, obj_type, log_lvl = 0, specific_processor }: { obj_li: T[]; obj_type: string; log_lvl?: number; specific_processor?: (obj: T) => Promise | T; }): Promise { if (!obj_li || obj_li.length === 0) return []; - const processed_obj_li: T[] = []; - for (const original_obj of obj_li) { let processed_obj = { ...original_obj }; - - // 1. Standardize ID and other '_random' fields for (const key in processed_obj) { if (key.endsWith('_random')) { const newKey = key.slice(0, -7); (processed_obj as any)[newKey] = processed_obj[key]; } } - // String-Only ID Vision: Map [obj_type]_id_random to 'id' const randomIdKey = `${obj_type}_id_random`; - if (processed_obj[randomIdKey]) { - (processed_obj as any).id = processed_obj[randomIdKey]; - } - - // 2. Create common computed properties + if (processed_obj[randomIdKey]) (processed_obj as any).id = processed_obj[randomIdKey]; const group = processed_obj.group ?? '0'; const priority = processed_obj.priority ? 1 : 0; const sort = processed_obj.sort ?? '0'; const updated = processed_obj.updated_on ?? processed_obj.created_on; const name = processed_obj.name ?? ''; - (processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`; (processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`; - - if (specific_processor) { - processed_obj = await Promise.resolve(specific_processor(processed_obj)); - } - + if (specific_processor) processed_obj = await Promise.resolve(specific_processor(processed_obj)); processed_obj_li.push(processed_obj as T); } - return processed_obj_li; } -export async function process_ae_obj__event_session_props({ - obj_li, - log_lvl = 0 -}: { - obj_li: any[]; - log_lvl?: number; -}) { - return _process_generic_props({ - obj_li, - obj_type: 'event_session', - log_lvl - }); +export async function process_ae_obj__event_session_props({ obj_li, log_lvl = 0 }: { obj_li: any[]; log_lvl?: number; }) { + return _process_generic_props({ obj_li, obj_type: 'event_session', log_lvl }); } \ No newline at end of file diff --git a/src/routes/events/[event_id]/(launcher)/launcher/+layout.svelte b/src/routes/events/[event_id]/(launcher)/launcher/+layout.svelte index ce847b6b..b5ea07cb 100644 --- a/src/routes/events/[event_id]/(launcher)/launcher/+layout.svelte +++ b/src/routes/events/[event_id]/(launcher)/launcher/+layout.svelte @@ -1038,7 +1038,7 @@ {/if} - {#if $events_slct.event_session_id && $lq__event_session_obj && !$events_sess.launcher.loading__session_id_status} + {#if $events_slct.event_session_id && $lq__event_session_obj} { diff --git a/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/session_view.svelte b/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/session_view.svelte index 66470991..a9b38f9d 100644 --- a/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/session_view.svelte +++ b/src/routes/events/[event_id]/(pres_mgmt)/session/[session_id]/session_view.svelte @@ -85,23 +85,23 @@ // *** Functions and Logic $events_sess.pres_mgmt.session__updated_on = null; $effect(() => { - // && !$events_sess.pres_mgmt.session_qr_url[lq__event_session_obj?.event_session_id] === undefined + // && !$events_sess.pres_mgmt.session_qr_url[$lq__event_session_obj?.event_session_id] === undefined if ( - lq__event_session_obj && - lq__event_session_obj?.event_session_id && + $lq__event_session_obj && + $lq__event_session_obj?.event_session_id && $events_loc.pres_mgmt.show_content__session_qr && - !$events_sess.pres_mgmt.session_qr_url[lq__event_session_obj?.event_session_id] + !$events_sess.pres_mgmt.session_qr_url[$lq__event_session_obj?.event_session_id] ) { if (log_lvl > 1) { - console.log(`$lq__event_session_obj:`, lq__event_session_obj); + console.log(`$lq__event_session_obj:`, $lq__event_session_obj); } - $events_sess.pres_mgmt.session_qr_url[lq__event_session_obj?.event_session_id] = true; + $events_sess.pres_mgmt.session_qr_url[$lq__event_session_obj?.event_session_id] = true; // session_qr_url is a key value of session_id and URL string - // $events_sess.pres_mgmt.session_qr_url[lq__event_session_obj?.event_session_id] = null; + // $events_sess.pres_mgmt.session_qr_url[$lq__event_session_obj?.event_session_id] = null; - if (lq__event_session_obj.updated_on == $events_sess.pres_mgmt.session__updated_on) { + if ($lq__event_session_obj.updated_on == $events_sess.pres_mgmt.session__updated_on) { if (log_lvl > 1) { console.log('Updated on is the same.'); } @@ -110,13 +110,13 @@ console.log('Updated on is different.'); } // FUTURE USE: Generate a QR code for the object ID. - // ae_promises.generate_qr_code_obj_id = core_func.generate_qr_code({api_cfg: $ae_api, account_id: $slct.account_id, qr_type: 'obj', qr_id: lq__event_session_obj?.event_session_id, obj_type: 'event_session', obj_id: lq__event_session_obj?.event_session_id}); + // ae_promises.generate_qr_code_obj_id = core_func.generate_qr_code({api_cfg: $ae_api, account_id: $slct.account_id, qr_type: 'obj', qr_id: $lq__event_session_obj?.event_session_id, obj_type: 'event_session', obj_id: $lq__event_session_obj?.event_session_id}); // Generate a QR code for the URL. - let qr_id_url = `${lq__event_session_obj?.event_session_id}_url`; + let qr_id_url = `${$lq__event_session_obj?.event_session_id}_url`; // URL for this page (be sure to URL encode it): - let url_str = `${$ae_loc.url_origin}/events/${lq__event_session_obj?.event_id}/session/${lq__event_session_obj?.event_session_id}`; + let url_str = `${$ae_loc.url_origin}/events/${$lq__event_session_obj?.event_id}/session/${$lq__event_session_obj?.event_session_id}`; url_str = encodeURI(url_str); ae_promises.generate_qr_code_url = core_func @@ -134,13 +134,13 @@ } // Store the URL string in the key value for use in the QR code image src. $events_sess.pres_mgmt.session_qr_url[ - lq__event_session_obj?.event_session_id + $lq__event_session_obj?.event_session_id ] = result; return result; }); // console.log(`ae_promises.generate_qr_code_url = `, ae_promises.generate_qr_code_url); - $events_sess.pres_mgmt.session__updated_on = lq__event_session_obj?.updated_on; + $events_sess.pres_mgmt.session__updated_on = $lq__event_session_obj?.updated_on; } } else { // if (log_lvl) { @@ -157,18 +157,18 @@ {#if $lq__event_session_obj}
- - {#if $events_sess.pres_mgmt.session_qr_url[lq__event_session_obj?.event_session_id]} + {#if $events_sess.pres_mgmt.session_qr_url[$lq__event_session_obj?.event_session_id]}
- {#if $events_sess.pres_mgmt.session_qr_url[lq__event_session_obj?.event_session_id]} + {#if $events_sess.pres_mgmt.session_qr_url[$lq__event_session_obj?.event_session_id]} { $events_sess.pres_mgmt.qr_bigger = !$events_sess.pres_mgmt.qr_bigger; @@ -204,7 +204,7 @@ {/if} Name/title: - {lq__event_session_obj.name} + {$lq__event_session_obj.name} {/if} @@ -262,10 +262,10 @@ code: - {lq__event_session_obj.code} + {$lq__event_session_obj.code} {/if} @@ -326,10 +326,10 @@ - {ae_util.iso_datetime_formatter(lq__event_session_obj.start_datetime, 'dddd')}, + {ae_util.iso_datetime_formatter($lq__event_session_obj.start_datetime, 'dddd')}, {ae_util.iso_datetime_formatter( - lq__event_session_obj.start_datetime, + $lq__event_session_obj.start_datetime, $events_loc.pres_mgmt.datetime_format )} @@ -357,10 +357,10 @@ {ae_util.iso_datetime_formatter( - lq__event_session_obj.end_datetime, + $lq__event_session_obj.end_datetime, $events_loc.pres_mgmt.time_format )} @@ -390,22 +390,22 @@ {#if $events_loc.pres_mgmt?.hide__launcher_link_legacy && $events_loc.pres_mgmt?.hide__launcher_link && !$ae_loc.edit_mode} - {lq__event_session_obj?.event_location_name ?? '-- not set --'} + {$lq__event_session_obj?.event_location_name ?? '-- not set --'} {/if} - {@html lq__event_session_obj?.event_location_name - ? lq__event_session_obj?.event_location_name + {@html $lq__event_session_obj?.event_location_name + ? $lq__event_session_obj?.event_location_name : ae_snip.html__not_set} @@ -413,32 +413,32 @@ @@ -448,7 +448,7 @@ trigger_patch={ae_triggers.update_event_location} api_cfg={$ae_api} object_type={'event_session'} - object_id={lq__event_session_obj?.event_session_id} + object_id={$lq__event_session_obj?.event_session_id} field_name={'event_location_id_random'} field_type={'select'} field_value={ae_tmp.event_location_id_random} @@ -466,7 +466,7 @@ events_func .load_ae_obj_id__event_session({ api_cfg: $ae_api, - event_session_id: lq__event_session_obj?.event_session_id, + event_session_id: $lq__event_session_obj?.event_session_id, log_lvl: 1 }) .then(function (load_results) { @@ -513,7 +513,7 @@ .load_ae_obj_li__event_location({ api_cfg: $ae_api, for_obj_type: 'event', - for_obj_id: lq__event_session_obj?.event_id, + for_obj_id: $lq__event_session_obj?.event_id, params: params, log_lvl: log_lvl }) @@ -550,7 +550,7 @@ .finally(function () { console.log(`Finally...`); ae_tmp.event_location_id = - lq__event_session_obj?.event_location_id; + $lq__event_session_obj?.event_location_id; ae_tmp.show__edit_event_location = true; }); }} @@ -567,20 +567,20 @@ {$events_loc.pres_mgmt?.label__session_poc_name}: - {#if lq__event_session_obj?.poc_person_id} + {#if $lq__event_session_obj?.poc_person_id} {#if $ae_loc.manager_access} - {@html lq__event_session_obj?.poc_person_full_name - ? lq__event_session_obj.poc_person_full_name + {@html $lq__event_session_obj?.poc_person_full_name + ? $lq__event_session_obj.poc_person_full_name : ae_snip.html__not_set} {/if} - {#if $ae_loc.trusted_access || $events_loc.auth__kv.session[lq__event_session_obj?.event_session_id] === true} + {#if $ae_loc.trusted_access || $events_loc.auth__kv.session[$lq__event_session_obj?.event_session_id] === true} @@ -604,7 +604,7 @@ class_li={$events_sess.pres_mgmt.show__session_poc_profile ? '' : ''} - {lq__event_session_obj} + {$lq__event_session_obj} /> {#snippet footer()} @@ -631,15 +631,15 @@ type="button" disabled={!$ae_loc.trusted_access && !$events_loc.auth__kv.session[ - lq__event_session_obj?.event_session_id + $lq__event_session_obj?.event_session_id ] === true} class="btn btn-sm hover:preset-filled-success-500" - class:preset-tonal-success={lq__event_session_obj?.poc_agree} - class:preset-tonal-warning={!lq__event_session_obj?.poc_agree} + class:preset-tonal-success={$lq__event_session_obj?.poc_agree} + class:preset-tonal-warning={!$lq__event_session_obj?.poc_agree} onclick={() => ($events_sess.pres_mgmt.show_modal__session_poc_agree = true)} > - {#if !lq__event_session_obj?.poc_agree} + {#if !$lq__event_session_obj?.poc_agree} - + {#snippet footer()}
@@ -683,9 +683,9 @@ {:else} - - {@html lq__event_session_obj.poc_person_full_name - ? lq__event_session_obj.poc_person_full_name + + {@html $lq__event_session_obj.poc_person_full_name + ? $lq__event_session_obj.poc_person_full_name : ae_snip.html__not_set} {/if} @@ -695,8 +695,8 @@ - {#if $ae_loc.trusted_access && $ae_loc.edit_mode} @@ -704,10 +704,10 @@ trigger_patch={ae_triggers.update_person_poc} api_cfg={$ae_api} object_type={'event_session'} - object_id={lq__event_session_obj?.event_session_id} + object_id={$lq__event_session_obj?.event_session_id} field_name={'poc_person_id_random'} field_type={'select'} - field_value={lq__event_session_obj?.poc_person_id} + field_value={$lq__event_session_obj?.poc_person_id} select_option_li={$slct.person_obj_kv} allow_null={$ae_loc.administrator_access} hide_edit_btn={true} @@ -721,7 +721,7 @@ events_func .load_ae_obj_id__event_session({ api_cfg: $ae_api, - event_session_id: lq__event_session_obj?.event_session_id, + event_session_id: $lq__event_session_obj?.event_session_id, log_lvl: 0 }) .then(function (load_results) { @@ -805,7 +805,7 @@ return load_results; }); - ae_tmp.poc_person_id = lq__event_session_obj?.poc_person_id; + ae_tmp.poc_person_id = $lq__event_session_obj?.poc_person_id; ae_tmp.show__edit_poc_person = true; }} class="btn btn-sm preset-tonal-warning group" @@ -821,12 +821,12 @@ {#if $events_loc.auth__kv.session[$events_slct.event_session_id] === true} Signed In {/if} - {#if $events_loc.pres_mgmt?.require__session_agree && $events_loc?.pres_mgmt?.show__email_access_link && lq__event_session_obj?.poc_person_primary_email && ($ae_loc.trusted_access || !$events_loc.auth__kv.session[lq__event_session_obj?.event_session_id])} + {#if $events_loc.pres_mgmt?.require__session_agree && $events_loc?.pres_mgmt?.show__email_access_link && $lq__event_session_obj?.poc_person_primary_email && ($ae_loc.trusted_access || !$events_loc.auth__kv.session[$lq__event_session_obj?.event_session_id])} {/if} - {#if $events_loc.pres_mgmt?.show__copy_access_link && $ae_loc.trusted_access && lq__event_session_obj.poc_person_id} + {#if $events_loc.pres_mgmt?.show__copy_access_link && $ae_loc.trusted_access && $lq__event_session_obj.poc_person_id} - {@html lq__event_session_obj.passcode - ? lq__event_session_obj.passcode + {@html $lq__event_session_obj.passcode + ? $lq__event_session_obj.passcode : ae_snip.html__not_set} - {#if lq__event_session_obj.description} + {#if $lq__event_session_obj.description}