diff --git a/src/lib/ae_journals/ae_journals__journal.ts b/src/lib/ae_journals/ae_journals__journal.ts index 4c4d8de7..48d8c3eb 100644 --- a/src/lib/ae_journals/ae_journals__journal.ts +++ b/src/lib/ae_journals/ae_journals__journal.ts @@ -46,7 +46,9 @@ export async function load_ae_obj_id__journal({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_id__journal() *** journal_id=${journal_id} (SWR)`); + console.log( + `*** load_ae_obj_id__journal() *** journal_id=${journal_id} (SWR)` + ); } // 1. FAST PATH: Return cached data immediately @@ -54,16 +56,39 @@ export async function load_ae_obj_id__journal({ try { const cached = await db_journals.journal.get(journal_id); if (cached) { - if (log_lvl) console.log('JOURNAL LOAD: Cache hit. Returning stale data.'); - _refresh_journal_id_background({ - api_cfg, journal_id, view, params, try_cache, - inc_entry_li, enabled, hidden, limit, offset, order_by_li, log_lvl: 0 + if (log_lvl) + console.log( + 'JOURNAL LOAD: Cache hit. Returning stale data.' + ); + _refresh_journal_id_background({ + api_cfg, + journal_id, + view, + params, + try_cache, + inc_entry_li, + enabled, + hidden, + limit, + offset, + order_by_li, + log_lvl: 0 }); if (inc_entry_li && !cached.journal_entry_li) { - cached.journal_entry_li = await load_ae_obj_li__journal_entry({ - api_cfg, for_obj_type: 'journal', for_obj_id: journal_id, - enabled, hidden, limit, offset, order_by_li, params, try_cache, log_lvl - }); + cached.journal_entry_li = + await load_ae_obj_li__journal_entry({ + api_cfg, + for_obj_type: 'journal', + for_obj_id: journal_id, + enabled, + hidden, + limit, + offset, + order_by_li, + params, + try_cache, + log_lvl + }); } return cached; } @@ -71,28 +96,76 @@ export async function load_ae_obj_id__journal({ } // 2. SLOW PATH: Wait for API - return await _refresh_journal_id_background({ - api_cfg, journal_id, view, params, try_cache, - inc_entry_li, enabled, hidden, limit, offset, order_by_li, log_lvl + return await _refresh_journal_id_background({ + api_cfg, + journal_id, + view, + params, + try_cache, + inc_entry_li, + enabled, + hidden, + limit, + offset, + order_by_li, + log_lvl }); } /** * Internal background refresh for a single journal */ -async function _refresh_journal_id_background({ api_cfg, journal_id, view, params, try_cache, inc_entry_li, enabled, hidden, limit, offset, order_by_li, log_lvl }: any) { +async function _refresh_journal_id_background({ + api_cfg, + journal_id, + view, + params, + try_cache, + inc_entry_li, + enabled, + hidden, + limit, + offset, + order_by_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: 'journal', obj_id: journal_id, view, params, log_lvl }); + const result = await api.get_ae_obj_v3({ + api_cfg, + obj_type: 'journal', + obj_id: journal_id, + view, + params, + log_lvl + }); if (result) { if (try_cache) { - const processed = await process_ae_obj__journal_props({ obj_li: [result], log_lvl }); - await db_save_ae_obj_li__ae_obj({ db_instance: db_journals, table_name: 'journal', obj_li: processed, properties_to_save, log_lvl }); + const processed = await process_ae_obj__journal_props({ + obj_li: [result], + log_lvl + }); + await db_save_ae_obj_li__ae_obj({ + db_instance: db_journals, + table_name: 'journal', + obj_li: processed, + properties_to_save, + log_lvl + }); } if (inc_entry_li) { result.journal_entry_li = await load_ae_obj_li__journal_entry({ - api_cfg, for_obj_type: 'journal', for_obj_id: journal_id, - enabled, hidden, limit, offset, order_by_li, params, try_cache, log_lvl + api_cfg, + for_obj_type: 'journal', + for_obj_id: journal_id, + enabled, + hidden, + limit, + offset, + order_by_li, + params, + try_cache, + log_lvl }); } return result; @@ -138,18 +211,37 @@ export async function load_ae_obj_li__journal({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_li__journal() *** for=${for_obj_type}:${for_obj_id} (SWR)`); + console.log( + `*** load_ae_obj_li__journal() *** for=${for_obj_type}:${for_obj_id} (SWR)` + ); } // 1. FAST PATH: Check cache if (try_cache) { try { - const cached_li = await db_journals.journal.where('for_id').equals(for_obj_id).toArray(); + const cached_li = await db_journals.journal + .where('for_id') + .equals(for_obj_id) + .toArray(); if (cached_li && cached_li.length > 0) { - if (log_lvl) console.log(`JOURNAL LIST: Cache hit (${cached_li.length}).`); - _refresh_journal_li_background({ - api_cfg, for_obj_type, for_obj_id, qry_person_id, inc_entry_li, - enabled, hidden, limit, offset, order_by_li, params, try_cache, log_lvl: 0 + if (log_lvl) + console.log( + `JOURNAL LIST: Cache hit (${cached_li.length}).` + ); + _refresh_journal_li_background({ + api_cfg, + for_obj_type, + for_obj_id, + qry_person_id, + inc_entry_li, + enabled, + hidden, + limit, + offset, + order_by_li, + params, + try_cache, + log_lvl: 0 }); return cached_li; } @@ -157,39 +249,110 @@ export async function load_ae_obj_li__journal({ } // 2. SLOW PATH: API - return await _refresh_journal_li_background({ - api_cfg, for_obj_type, for_obj_id, qry_person_id, inc_entry_li, - enabled, hidden, limit, offset, order_by_li, params, try_cache, log_lvl + return await _refresh_journal_li_background({ + api_cfg, + for_obj_type, + for_obj_id, + qry_person_id, + inc_entry_li, + enabled, + hidden, + limit, + offset, + order_by_li, + params, + try_cache, + log_lvl }); } -async function _refresh_journal_li_background({ api_cfg, for_obj_type, for_obj_id, qry_person_id, inc_entry_li, enabled, hidden, limit, offset, order_by_li, params, try_cache, log_lvl }: any) { +async function _refresh_journal_li_background({ + api_cfg, + for_obj_type, + for_obj_id, + qry_person_id, + inc_entry_li, + enabled, + hidden, + limit, + offset, + order_by_li, + params, + try_cache, + log_lvl +}: any) { if (typeof navigator !== 'undefined' && !navigator.onLine) return []; - + let promise; if (qry_person_id) { - const search_query: any = { and: [{ field: 'person_id_random', op: 'eq', value: qry_person_id }] }; - if (for_obj_id) search_query.and.push({ field: `${for_obj_type}_id_random`, op: 'eq', value: for_obj_id }); - if (enabled === 'enabled') search_query.and.push({ field: 'enable', op: 'eq', value: true }); - if (hidden === 'hidden') search_query.and.push({ field: 'hide', op: 'eq', value: true }); + const search_query: any = { + and: [{ field: 'person_id_random', op: 'eq', value: qry_person_id }] + }; + if (for_obj_id) + search_query.and.push({ + field: `${for_obj_type}_id_random`, + op: 'eq', + value: for_obj_id + }); + if (enabled === 'enabled') + search_query.and.push({ field: 'enable', op: 'eq', value: true }); + if (hidden === 'hidden') + search_query.and.push({ field: 'hide', op: 'eq', value: true }); - promise = api.search_ae_obj_v3({ api_cfg, obj_type: 'journal', search_query, order_by_li, limit, offset, log_lvl }); + promise = api.search_ae_obj_v3({ + api_cfg, + obj_type: 'journal', + search_query, + order_by_li, + limit, + offset, + log_lvl + }); } else { - promise = api.get_ae_obj_li_v3({ api_cfg, obj_type: 'journal', for_obj_type, for_obj_id, enabled, hidden, limit, offset, order_by_li, log_lvl }); + promise = api.get_ae_obj_li_v3({ + api_cfg, + obj_type: 'journal', + for_obj_type, + for_obj_id, + enabled, + hidden, + limit, + offset, + order_by_li, + log_lvl + }); } try { const results = await promise; if (results) { if (try_cache) { - const processed = await process_ae_obj__journal_props({ obj_li: results, log_lvl }); - await db_save_ae_obj_li__ae_obj({ db_instance: db_journals, table_name: 'journal', obj_li: processed, properties_to_save, log_lvl }); + const processed = await process_ae_obj__journal_props({ + obj_li: results, + log_lvl + }); + await db_save_ae_obj_li__ae_obj({ + db_instance: db_journals, + table_name: 'journal', + obj_li: processed, + properties_to_save, + log_lvl + }); } if (inc_entry_li) { for (const journal of results) { load_ae_obj_li__journal_entry({ - api_cfg, for_obj_type: 'journal', for_obj_id: journal.journal_id_random, - enabled, hidden, limit, offset, order_by_li, params, try_cache, log_lvl: 0 + api_cfg, + for_obj_type: 'journal', + for_obj_id: journal.journal_id_random, + enabled, + hidden, + limit, + offset, + order_by_li, + params, + try_cache, + log_lvl: 0 }); } } @@ -216,11 +379,15 @@ export async function create_ae_obj__journal({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** create_ae_obj__journal() *** account_id=${account_id}`); + console.log( + `*** create_ae_obj__journal() *** account_id=${account_id}` + ); } if (!account_id) { - console.log(`ERROR: Journals - Journal - account_id required to create`); + console.log( + `ERROR: Journals - Journal - account_id required to create` + ); return null; } @@ -239,10 +406,11 @@ export async function create_ae_obj__journal({ if (journal_obj_create_result) { if (try_cache) { // Process the results first - const processed_obj_li = await process_ae_obj__journal_props({ - obj_li: [journal_obj_create_result], - log_lvl: log_lvl - }); + const processed_obj_li = + await process_ae_obj__journal_props({ + obj_li: [journal_obj_create_result], + log_lvl: log_lvl + }); if (log_lvl) { console.log('Processed object list:', processed_obj_li); } @@ -284,7 +452,9 @@ export async function delete_ae_obj_id__journal({ log_lvl?: number; }) { if (log_lvl) { - console.log(`*** delete_ae_obj_id__journal() *** journal_id=${journal_id}`); + console.log( + `*** delete_ae_obj_id__journal() *** journal_id=${journal_id}` + ); } ae_promises.delete__journal_obj = await api @@ -302,7 +472,9 @@ export async function delete_ae_obj_id__journal({ .finally(async function () { if (try_cache) { if (log_lvl) { - console.log(`Attempting to remove IDB entry for journal_id=${journal_id}`); + console.log( + `Attempting to remove IDB entry for journal_id=${journal_id}` + ); } await db_journals.journal.delete(journal_id); } @@ -328,7 +500,10 @@ export async function update_ae_obj__journal({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** update_ae_obj__journal() *** journal_id=${journal_id}`, data_kv); + console.log( + `*** update_ae_obj__journal() *** journal_id=${journal_id}`, + data_kv + ); } // Perform the API update @@ -401,7 +576,9 @@ export async function qry__journal({ hidden?: 'hidden' | 'all' | 'not_hidden' | undefined; // all, hidden, not_hidden limit?: number; offset?: number; - order_by_li?: Record | Record[]; + order_by_li?: + | Record + | Record[]; params?: any; try_cache?: boolean; log_lvl?: number; @@ -417,17 +594,29 @@ export async function qry__journal({ if (qry_files === true) { search_query.and.push({ field: 'file_count_all', op: 'gt', value: 0 }); } else if (qry_files === false) { - search_query.and.push({ field: 'file_count_all', op: 'is', value: null }); + search_query.and.push({ + field: 'file_count_all', + op: 'is', + value: null + }); } if (qry_start_datetime) { - search_query.and.push({ field: 'start_datetime', op: 'gt', value: qry_start_datetime }); + search_query.and.push({ + field: 'start_datetime', + op: 'gt', + value: qry_start_datetime + }); } // Add for_obj_id context (Account ID) if (journal_id) { // Assuming journal_id here is actually the account_id as per original usage context - search_query.and.push({ field: 'account_id_random', op: 'eq', value: journal_id }); + search_query.and.push({ + field: 'account_id_random', + op: 'eq', + value: journal_id + }); } // Add enabled/hidden filters @@ -457,10 +646,11 @@ export async function qry__journal({ if (journal_obj_li_get_result) { if (try_cache) { // Process the results first - const processed_obj_li = await process_ae_obj__journal_props({ - obj_li: journal_obj_li_get_result, - log_lvl: log_lvl - }); + const processed_obj_li = + await process_ae_obj__journal_props({ + obj_li: journal_obj_li_get_result, + log_lvl: log_lvl + }); if (log_lvl) { console.log('Processed object list:', processed_obj_li); } @@ -486,7 +676,10 @@ export async function qry__journal({ }); if (log_lvl) { - console.log('ae_promises.load__journal_obj_li:', ae_promises.load__journal_obj_li); + console.log( + 'ae_promises.load__journal_obj_li:', + ae_promises.load__journal_obj_li + ); } return ae_promises.load__journal_obj_li; } @@ -624,12 +817,16 @@ async function _process_generic_props>({ 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}`; + (processed_obj as any).tmp_sort_1 = + `${group}_${priority}_${sort}_${updated}`; + (processed_obj as any).tmp_sort_2 = + `${group}_${priority}_${sort}_${name}_${updated}`; // --- Specific Transformations --- if (specific_processor) { - processed_obj = await Promise.resolve(specific_processor(processed_obj)); + processed_obj = await Promise.resolve( + specific_processor(processed_obj) + ); } processed_obj_li.push(processed_obj as T); @@ -656,7 +853,8 @@ export async function process_ae_obj__journal_props({ /^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, '' ); - obj.description_md_html = (await marked.parse(description_cleaned ?? '')) ?? null; + obj.description_md_html = + (await marked.parse(description_cleaned ?? '')) ?? null; obj.cfg_json = obj.cfg_json ?? {}; obj.data_json = obj.data_json ?? {}; @@ -669,4 +867,4 @@ export async function process_ae_obj__journal_props({ return obj; } }); -} \ No newline at end of file +} diff --git a/src/lib/ae_journals/ae_journals__journal_entry.ts b/src/lib/ae_journals/ae_journals__journal_entry.ts index f93fd533..2b4ca368 100644 --- a/src/lib/ae_journals/ae_journals__journal_entry.ts +++ b/src/lib/ae_journals/ae_journals__journal_entry.ts @@ -22,7 +22,9 @@ export async function load_ae_obj_id__journal_entry({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** load_ae_obj_id__journal_entry() *** journal_entry_id=${journal_entry_id}`); + console.log( + `*** load_ae_obj_id__journal_entry() *** journal_entry_id=${journal_entry_id}` + ); } ae_promises.load__journal_entry_obj = await api @@ -36,10 +38,11 @@ export async function load_ae_obj_id__journal_entry({ if (journal_entry_obj_get_result) { if (try_cache) { // Process the results first - const processed_obj_li = await process_ae_obj__journal_entry_props({ - obj_li: [journal_entry_obj_get_result], - log_lvl: log_lvl - }); + const processed_obj_li = + await process_ae_obj__journal_entry_props({ + obj_li: [journal_entry_obj_get_result], + log_lvl: log_lvl + }); if (log_lvl) { console.log('Processed object list:', processed_obj_li); } @@ -138,11 +141,15 @@ export async function load_ae_obj_li__journal_entry({ if (journal_entry_obj_li_get_result) { if (try_cache) { // Process the results first - const processed_obj_li = await process_ae_obj__journal_entry_props({ - obj_li: journal_entry_obj_li_get_result, - journal_id: for_obj_type === 'journal' ? for_obj_id : undefined, - log_lvl: log_lvl - }); + const processed_obj_li = + await process_ae_obj__journal_entry_props({ + obj_li: journal_entry_obj_li_get_result, + journal_id: + for_obj_type === 'journal' + ? for_obj_id + : undefined, + log_lvl: log_lvl + }); if (log_lvl) { console.log('Processed object list:', processed_obj_li); } @@ -197,7 +204,9 @@ export async function create_ae_obj__journal_entry({ log_lvl?: number; }): Promise { if (log_lvl) { - console.log(`*** create_ae_obj__journal_entry() *** journal_id=${journal_id}`); + console.log( + `*** create_ae_obj__journal_entry() *** journal_id=${journal_id}` + ); } if (!journal_id) { @@ -219,11 +228,12 @@ export async function create_ae_obj__journal_entry({ if (journal_entry_obj_create_result) { if (try_cache) { // Process the results first - const processed_obj_li = await process_ae_obj__journal_entry_props({ - obj_li: [journal_entry_obj_create_result], - journal_id, - log_lvl: log_lvl - }); + const processed_obj_li = + await process_ae_obj__journal_entry_props({ + obj_li: [journal_entry_obj_create_result], + journal_id, + log_lvl: log_lvl + }); if (log_lvl) { console.log('Processed object list:', processed_obj_li); } @@ -342,36 +352,64 @@ export async function qry__journal_entry({ log_lvl?: number; }) { if (log_lvl) { - console.log(`*** qry__journal_entry() *** journal_id=${journal_id} person_id=${person_id}`); + console.log( + `*** qry__journal_entry() *** journal_id=${journal_id} person_id=${person_id}` + ); } const search_query: any = { and: [] }; if (qry_str) { // Using 'like' with wildcards to ensure compatibility - search_query.and.push({ field: 'default_qry_str', op: 'like', value: `%${qry_str.trim()}%` }); - params['lk_qry'] = { 'default_qry_str': qry_str.trim() }; + search_query.and.push({ + field: 'default_qry_str', + op: 'like', + value: `%${qry_str.trim()}%` + }); + params['lk_qry'] = { default_qry_str: qry_str.trim() }; } if (qry_category_code) { - search_query.and.push({ field: 'category_code', op: 'eq', value: qry_category_code }); + search_query.and.push({ + field: 'category_code', + op: 'eq', + value: qry_category_code + }); } if (qry_created_on) { - search_query.and.push({ field: 'created_on', op: 'gt', value: qry_created_on }); + search_query.and.push({ + field: 'created_on', + op: 'gt', + value: qry_created_on + }); } if (qry_priority) { - search_query.and.push({ field: 'priority', op: 'eq', value: qry_priority }); + search_query.and.push({ + field: 'priority', + op: 'eq', + value: qry_priority + }); } // Context scoping: Prefer journal_id if provided, otherwise fallback to person_id (global search) if (journal_id) { - search_query.and.push({ field: 'journal_id_random', op: 'eq', value: journal_id }); + search_query.and.push({ + field: 'journal_id_random', + op: 'eq', + value: journal_id + }); } else if (person_id) { - search_query.and.push({ field: 'person_id_random', op: 'eq', value: person_id }); + search_query.and.push({ + field: 'person_id_random', + op: 'eq', + value: person_id + }); } else { - console.warn('qry__journal_entry: No journal_id or person_id provided. Search might be too broad.'); + console.warn( + 'qry__journal_entry: No journal_id or person_id provided. Search might be too broad.' + ); } // Add enabled/hidden filters @@ -413,11 +451,12 @@ export async function qry__journal_entry({ if (valid_result_li && valid_result_li.length > 0) { if (try_cache) { - const processed_obj_li = await process_ae_obj__journal_entry_props({ - obj_li: valid_result_li, - journal_id, - log_lvl - }); + const processed_obj_li = + await process_ae_obj__journal_entry_props({ + obj_li: valid_result_li, + journal_id, + log_lvl + }); await db_save_ae_obj_li__ae_obj({ db_instance: db_journals, table_name: 'journal_entry', @@ -907,12 +946,16 @@ async function _process_generic_props>({ 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}`; + (processed_obj as any).tmp_sort_1 = + `${group}_${priority}_${sort}_${updated}`; + (processed_obj as any).tmp_sort_2 = + `${group}_${priority}_${sort}_${name}_${updated}`; // --- Specific Transformations --- if (specific_processor) { - processed_obj = await Promise.resolve(specific_processor(processed_obj)); + processed_obj = await Promise.resolve( + specific_processor(processed_obj) + ); } processed_obj_li.push(processed_obj as T); @@ -952,8 +995,12 @@ export async function process_ae_obj__journal_entry_props({ content_cleaned = null; content_md_html = null; } else { - content_cleaned = content.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, ''); - content_md_html = (await marked.parse(content_cleaned ?? '')) ?? null; + content_cleaned = content.replace( + /^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, + '' + ); + content_md_html = + (await marked.parse(content_cleaned ?? '')) ?? null; } obj.content = content; obj.content_md_html = content_md_html; @@ -968,8 +1015,12 @@ export async function process_ae_obj__journal_entry_props({ history_cleaned = null; history_md_html = null; } else { - history_cleaned = history.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, ''); - history_md_html = (await marked.parse(history_cleaned ?? '')) ?? null; + history_cleaned = history.replace( + /^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, + '' + ); + history_md_html = + (await marked.parse(history_cleaned ?? '')) ?? null; } obj.history = history; obj.history_md_html = history_md_html; diff --git a/src/lib/ae_journals/ae_journals_decryption.ts b/src/lib/ae_journals/ae_journals_decryption.ts index 61d42f0f..f615d119 100644 --- a/src/lib/ae_journals/ae_journals_decryption.ts +++ b/src/lib/ae_journals/ae_journals_decryption.ts @@ -13,7 +13,7 @@ export interface DecryptionResult { /** * Decrypts a journal entry's content and history using the provided or stored passcode. - * + * * @param entry The journal entry object to decrypt. * @param journal The parent journal object (provides base passcode and private_passcode). * @param typed_passcode Optional: A user-entered passcode override. @@ -24,11 +24,10 @@ export async function decrypt_journal_entry( journal: ae_Journal, typed_passcode?: string ): Promise { - // Safety check: if not encrypted, return as-is if (!entry.content_encrypted) { - return { - success: true, + return { + success: true, content: entry.content ?? '', history: entry.history ?? '' }; @@ -37,36 +36,46 @@ export async function decrypt_journal_entry( // Determine which key to use let journal_key = typed_passcode; let key_source = 'user_typed'; - + // If no override, try the private passcode stored on the journal object if (!journal_key?.length) { journal_key = journal.private_passcode; key_source = 'journal_private_passcode'; } - + if (!journal_key) { - console.warn('decrypt_journal_entry: No key available. Source:', key_source); - return { - success: false, - error: 'No passcode provided or available for decryption.' + console.warn( + 'decrypt_journal_entry: No key available. Source:', + key_source + ); + return { + success: false, + error: 'No passcode provided or available for decryption.' }; } // Aether standard: combine the journal's public passcode with the private key const decrypt_key = `${journal.passcode ?? ''}:${journal_key}`; - - console.log(`decrypt_journal_entry: Attempting decryption. Source: ${key_source}`); + + console.log( + `decrypt_journal_entry: Attempting decryption. Source: ${key_source}` + ); // console.log(`decrypt_journal_entry: Key: ${decrypt_key}`); // Log ONLY for deep debugging try { // Decrypt Primary Content - const result = await ae_util.decrypt_wrapper(entry.content_encrypted, decrypt_key); + const result = await ae_util.decrypt_wrapper( + entry.content_encrypted, + decrypt_key + ); if (result === false) { - console.error('decrypt_journal_entry: Decryption wrapper returned false.'); - return { - success: false, - error: 'Decryption failed. Incorrect passcode or corrupted data.' + console.error( + 'decrypt_journal_entry: Decryption wrapper returned false.' + ); + return { + success: false, + error: 'Decryption failed. Incorrect passcode or corrupted data.' }; } @@ -75,24 +84,28 @@ export async function decrypt_journal_entry( // Decrypt History (if it exists) if (entry.history_encrypted) { - const h_res = await ae_util.decrypt_wrapper(entry.history_encrypted, decrypt_key); + const h_res = await ae_util.decrypt_wrapper( + entry.history_encrypted, + decrypt_key + ); if (h_res !== false) { decrypted_history = typeof h_res === 'string' ? h_res : ''; } } - console.log(`decrypt_journal_entry: SUCCESS. Source: ${key_source}, Content length: ${decrypted_text.length}. Preview: ${decrypted_text.substring(0, 30).replace(/\n/g, ' ')}...`); - return { - success: true, + console.log( + `decrypt_journal_entry: SUCCESS. Source: ${key_source}, Content length: ${decrypted_text.length}. Preview: ${decrypted_text.substring(0, 30).replace(/\n/g, ' ')}...` + ); + return { + success: true, content: decrypted_text, history: decrypted_history }; - } catch (err: any) { console.error('decrypt_journal_entry error:', err); - return { - success: false, - error: `System error during decryption: ${err.message}` + return { + success: false, + error: `System error during decryption: ${err.message}` }; } } diff --git a/src/lib/ae_journals/ae_journals_editor_helpers.ts b/src/lib/ae_journals/ae_journals_editor_helpers.ts index d7889fa6..511957b3 100644 --- a/src/lib/ae_journals/ae_journals_editor_helpers.ts +++ b/src/lib/ae_journals/ae_journals_editor_helpers.ts @@ -1,19 +1,28 @@ /** * Wraps the current selection in CodeMirror with the given prefix and suffix. */ -export function wrapSelection(view: any, prefix: string, suffix: string = prefix) { +export function wrapSelection( + view: any, + prefix: string, + suffix: string = prefix +) { if (!view || view.updateInProgress) return; - + const { state } = view; - view.dispatch(state.changeByRange((range: any) => { - return { - changes: [ - {from: range.from, insert: prefix}, - {from: range.to, insert: suffix} - ], - range: range.constructor.range(range.from + prefix.length, range.to + prefix.length) - }; - })); + view.dispatch( + state.changeByRange((range: any) => { + return { + changes: [ + { from: range.from, insert: prefix }, + { from: range.to, insert: suffix } + ], + range: range.constructor.range( + range.from + prefix.length, + range.to + prefix.length + ) + }; + }) + ); view.focus(); } @@ -22,32 +31,49 @@ export function wrapSelection(view: any, prefix: string, suffix: string = prefix */ export function toggleLinePrefix(view: any, prefix: string) { if (!view || view.updateInProgress) return; - + const { state } = view; - view.dispatch(state.changeByRange((range: any) => { - const lines = []; - for (let pos = range.from; pos <= range.to; ) { - const line = state.doc.lineAt(pos); - lines.push(line); - pos = line.to + 1; - } - - const isAlreadyPrefixed = lines.every(l => l.text.startsWith(prefix)); - const lineChanges = lines.map(l => { - if (isAlreadyPrefixed) { - return { from: l.from, to: l.from + prefix.length, insert: '' }; - } else { - return { from: l.from, insert: prefix }; + view.dispatch( + state.changeByRange((range: any) => { + const lines = []; + for (let pos = range.from; pos <= range.to; ) { + const line = state.doc.lineAt(pos); + lines.push(line); + pos = line.to + 1; } - }); - const newFrom = range.from + (isAlreadyPrefixed ? -prefix.length : prefix.length); - const newTo = range.to + (isAlreadyPrefixed ? (-prefix.length * lines.length) : (prefix.length * lines.length)); + const isAlreadyPrefixed = lines.every((l) => + l.text.startsWith(prefix) + ); + const lineChanges = lines.map((l) => { + if (isAlreadyPrefixed) { + return { + from: l.from, + to: l.from + prefix.length, + insert: '' + }; + } else { + return { from: l.from, insert: prefix }; + } + }); - return { - changes: lineChanges, - range: range.constructor.range(newFrom, Math.max(newFrom, newTo)) - }; - })); + const newFrom = + range.from + + (isAlreadyPrefixed ? -prefix.length : prefix.length); + const newTo = + range.to + + (isAlreadyPrefixed + ? -prefix.length * lines.length + : prefix.length * lines.length); + + return { + changes: lineChanges, + range: range.constructor.range( + newFrom, + Math.max(newFrom, newTo) + ) + }; + }) + ); view.focus(); -} \ No newline at end of file +} diff --git a/src/lib/ae_journals/ae_journals_export_templates.ts b/src/lib/ae_journals/ae_journals_export_templates.ts index 48e1b5cd..e0701c9d 100644 --- a/src/lib/ae_journals/ae_journals_export_templates.ts +++ b/src/lib/ae_journals/ae_journals_export_templates.ts @@ -24,12 +24,17 @@ export const template_standard_markdown: ExportTemplate = { description: 'Basic Markdown with title, date, and content.', extension: 'md', formatter: (entries) => { - return entries.map(entry => { - const dateStr = ae_util.iso_datetime_formatter(entry.created_on, 'datetime_12_long'); - const title = entry.name || dateStr; - const header = `# ${title}\n*${dateStr}*\n\n`; - return `${header}${entry.content || ''}\n\n---\n`; - }).join('\n'); + return entries + .map((entry) => { + const dateStr = ae_util.iso_datetime_formatter( + entry.created_on, + 'datetime_12_long' + ); + const title = entry.name || dateStr; + const header = `# ${title}\n*${dateStr}*\n\n`; + return `${header}${entry.content || ''}\n\n---\n`; + }) + .join('\n'); } }; @@ -50,12 +55,17 @@ export const template_personal_log: ExportTemplate = { return dateA.localeCompare(dateB); }); - return sorted.map(entry => { - const dateStr = ae_util.iso_datetime_formatter(entry.created_on, 'date_iso'); - const title = entry.name || ''; - const header = `## ${dateStr}${title ? ' - ' + title : ''}\n\n`; - return `${header}${entry.content || ''}\n\n`; - }).join('\n'); + return sorted + .map((entry) => { + const dateStr = ae_util.iso_datetime_formatter( + entry.created_on, + 'date_iso' + ); + const title = entry.name || ''; + const header = `## ${dateStr}${title ? ' - ' + title : ''}\n\n`; + return `${header}${entry.content || ''}\n\n`; + }) + .join('\n'); } }; @@ -69,19 +79,24 @@ export const template_amazon_vine: ExportTemplate = { description: 'Optimized for product reviews.', extension: 'md', formatter: (entries) => { - return entries.map(entry => { - const dateStr = ae_util.iso_datetime_formatter(entry.created_on, 'date_iso'); - // Try to find a product name in the title or content - const productName = entry.name || 'Unknown Product'; - - // Look for product link in content_json or tags if available, - // otherwise just output content - let output = `## ${productName}\n`; - output += `*Date: ${dateStr}*\n\n`; - output += `${entry.content || ''}\n\n`; - output += `---`; - return output; - }).join('\n\n'); + return entries + .map((entry) => { + const dateStr = ae_util.iso_datetime_formatter( + entry.created_on, + 'date_iso' + ); + // Try to find a product name in the title or content + const productName = entry.name || 'Unknown Product'; + + // Look for product link in content_json or tags if available, + // otherwise just output content + let output = `## ${productName}\n`; + output += `*Date: ${dateStr}*\n\n`; + output += `${entry.content || ''}\n\n`; + output += `---`; + return output; + }) + .join('\n\n'); } }; @@ -94,10 +109,14 @@ export const template_standard_html: ExportTemplate = { description: 'Semantic HTML5 articles.', extension: 'html', formatter: (entries) => { - const body = entries.map(entry => { - const dateStr = ae_util.iso_datetime_formatter(entry.created_on, 'datetime_12_long'); - const title = entry.name || dateStr; - return ` + const body = entries + .map((entry) => { + const dateStr = ae_util.iso_datetime_formatter( + entry.created_on, + 'datetime_12_long' + ); + const title = entry.name || dateStr; + return `

${title}

@@ -108,7 +127,8 @@ export const template_standard_html: ExportTemplate = {
`; - }).join('\n'); + }) + .join('\n'); return ` diff --git a/src/lib/ae_journals/ae_journals_functions.ts b/src/lib/ae_journals/ae_journals_functions.ts index 1c412f88..dad87abd 100644 --- a/src/lib/ae_journals/ae_journals_functions.ts +++ b/src/lib/ae_journals/ae_journals_functions.ts @@ -13,7 +13,8 @@ const export_obj = { load_ae_obj_id__journal_entry: journal_entry.load_ae_obj_id__journal_entry, load_ae_obj_li__journal_entry: journal_entry.load_ae_obj_li__journal_entry, create_ae_obj__journal_entry: journal_entry.create_ae_obj__journal_entry, - delete_ae_obj_id__journal_entry: journal_entry.delete_ae_obj_id__journal_entry, + delete_ae_obj_id__journal_entry: + journal_entry.delete_ae_obj_id__journal_entry, update_ae_obj__journal_entry: journal_entry.update_ae_obj__journal_entry, qry__journal_entry: journal_entry.qry__journal_entry // db_save_ae_obj_li__journal_entry: journal_entry.db_save_ae_obj_li__journal_entry, diff --git a/src/lib/ae_journals/ae_journals_parsers.ts b/src/lib/ae_journals/ae_journals_parsers.ts index 8bf1e117..f5c1eaf8 100644 --- a/src/lib/ae_journals/ae_journals_parsers.ts +++ b/src/lib/ae_journals/ae_journals_parsers.ts @@ -19,7 +19,10 @@ export interface AeJournalEntryInput { * - First line is title (if it looks like a title). * - Rest is content. */ -export async function parse_standard_note(file: File, text: string): Promise { +export async function parse_standard_note( + file: File, + text: string +): Promise { const lines = text.split('\n'); let name = file.name.replace(/\.md$/i, '').replace(/\.txt$/i, ''); let content = text; @@ -29,11 +32,15 @@ export async function parse_standard_note(file: File, text: string): Promise 0 && lines[0].startsWith('# ')) { name = lines[0].substring(2).trim(); content = lines.slice(1).join('\n').trim(); - } else if (lines.length > 0 && lines[0].trim().length > 0 && lines[0].trim().length < 60) { + } else if ( + lines.length > 0 && + lines[0].trim().length > 0 && + lines[0].trim().length < 60 + ) { // First line is short, treat as title if it doesn't look like frontmatter if (lines[0].trim() !== '---') { - name = lines[0].trim(); - content = lines.slice(1).join('\n').trim(); + name = lines[0].trim(); + content = lines.slice(1).join('\n').trim(); } } @@ -42,18 +49,28 @@ export async function parse_standard_note(file: File, text: string): Promise -1) { const frontmatter = lines.slice(1, endFrontmatter); - content = lines.slice(endFrontmatter + 1).join('\n').trim(); - + content = lines + .slice(endFrontmatter + 1) + .join('\n') + .trim(); + // Extract tags or title from frontmatter (very basic parsing) - frontmatter.forEach(line => { - if (line.startsWith('title:')) name = line.substring(6).trim().replace(/^['"]|['"]$/g, ''); + frontmatter.forEach((line) => { + if (line.startsWith('title:')) + name = line + .substring(6) + .trim() + .replace(/^['"]|['"]$/g, ''); if (line.startsWith('tags:')) { // This is brittle, assumes inline tags like [a, b] or comma separated const tagPart = line.substring(5).trim(); if (tagPart.startsWith('[') && tagPart.endsWith(']')) { - tagPart.substring(1, tagPart.length - 1).split(',').forEach(t => tags.push(t.trim())); + tagPart + .substring(1, tagPart.length - 1) + .split(',') + .forEach((t) => tags.push(t.trim())); } else { - tagPart.split(',').forEach(t => tags.push(t.trim())); + tagPart.split(',').forEach((t) => tags.push(t.trim())); } } }); @@ -62,31 +79,36 @@ export async function parse_standard_note(file: File, text: string): Promise { +export async function parse_personal_log( + file: File, + text: string +): Promise { const entries: AeJournalEntryInput[] = []; const dateRegex = /^##\s+(\d{4}-\d{2}-\d{2})(.*)$/; - + const lines = text.split('\n'); let currentEntry: Partial | null = null; let currentContent: string[] = []; - + // Check if the whole file is just one entry (no date headers) - if (!lines.some(l => dateRegex.test(l))) { + if (!lines.some((l) => dateRegex.test(l))) { return parse_standard_note(file, text); } @@ -104,19 +126,21 @@ export async function parse_personal_log(file: File, text: string): Promise { +export async function parse_amazon_vine( + file: File, + text: string +): Promise { // Split by `\n## ` but we need to keep the delimiter or reconstruct // JS split doesn't keep delimiter nicely unless captured. // Let's iterate lines. const entries: AeJournalEntryInput[] = []; const productHeaderRegex = /^##\s+(.+)$/; - + const lines = text.split('\n'); let currentEntry: any = null; let currentBody: string[] = []; - + for (const line of lines) { const match = line.match(productHeaderRegex); if (match) { - if (currentEntry) { - entries.push(format_vine_entry(currentEntry, currentBody, file)); - } - currentEntry = { productName: match[1].trim() }; - currentBody = []; + if (currentEntry) { + entries.push( + format_vine_entry(currentEntry, currentBody, file) + ); + } + currentEntry = { productName: match[1].trim() }; + currentBody = []; } else { if (currentEntry) { currentBody.push(line); @@ -169,15 +198,19 @@ export async function parse_amazon_vine(file: File, text: string): Promise @@ -124,7 +126,10 @@ > - + Æ Journals - - - @@ -182,7 +215,9 @@ >
- +
- +
- - + +
{/if} {#if $journals_sess.show__modal__journals_config} - + {/if} (show_import_modal = false)} on_import_complete={() => {}} -/> \ No newline at end of file +/> diff --git a/src/routes/journals/+page.ts b/src/routes/journals/+page.ts index 866aa184..995efb24 100644 --- a/src/routes/journals/+page.ts +++ b/src/routes/journals/+page.ts @@ -14,7 +14,9 @@ export async function load({ fetch, parent }) { let ae_acct = parent_data[account_id]; if (!ae_acct) { - console.warn(`ae Journals +page.ts: Account ${account_id} not found in parent data. Initializing ghost acct.`); + console.warn( + `ae Journals +page.ts: Account ${account_id} not found in parent data. Initializing ghost acct.` + ); ae_acct = { api: parent_data.ae_api || {}, loc: {}, @@ -30,7 +32,7 @@ export async function load({ fetch, parent }) { const person_id = ae_acct.loc.person_id; // OPTIMIZATION: Fire the journal list load in the background. - // Components using LiveQuery (db_journals) will display cached data + // Components using LiveQuery (db_journals) will display cached data // instantly while this refresh runs. journals_func.load_ae_obj_li__journal({ api_cfg: ae_acct.api, diff --git a/src/routes/journals/[journal_id]/+layout.svelte b/src/routes/journals/[journal_id]/+layout.svelte index d8bc5e92..5caaa139 100644 --- a/src/routes/journals/[journal_id]/+layout.svelte +++ b/src/routes/journals/[journal_id]/+layout.svelte @@ -35,11 +35,16 @@ let lq__journal_obj = $derived( liveQuery(async () => { - let results = await db_journals.journal.get($journals_slct?.journal_id ?? ''); // null or undefined does not reset things like '' does + let results = await db_journals.journal.get( + $journals_slct?.journal_id ?? '' + ); // null or undefined does not reset things like '' does // Check if results are different than the current session version stored under $journals_slct if ($journals_slct.journal_obj && results) { - if (JSON.stringify($journals_slct.journal_obj) !== JSON.stringify(results)) { + if ( + JSON.stringify($journals_slct.journal_obj) !== + JSON.stringify(results) + ) { $journals_slct.journal_obj = { ...results }; } } @@ -50,11 +55,14 @@ $effect(() => { if (log_lvl) { - console.log(`lq__journal_obj: journal_id = ${$journals_slct?.journal_id}`); + console.log( + `lq__journal_obj: journal_id = ${$journals_slct?.journal_id}` + ); console.log(`lq__journal_obj: results = `, lq__journal_obj); if ($journals_slct.journal_obj && lq__journal_obj) { if ( - JSON.stringify($journals_slct.journal_obj) !== JSON.stringify(lq__journal_obj) + JSON.stringify($journals_slct.journal_obj) !== + JSON.stringify(lq__journal_obj) ) { console.log( `Session slct stored version has changed for ID = ${$journals_slct.journal_id}`, @@ -99,7 +107,8 @@ " > - {/if} @@ -75,7 +95,7 @@ {#if journal?.cfg_json?.pref_editor == 'codemirror'} -
{#if $journals_loc.entry.auto_save} - {#if save_status === 'saving'} - {:else if save_status === 'saved'} + {#if save_status === 'saving'} + {:else if save_status === 'saved'} {:else}{/if} {/if} @@ -106,20 +152,25 @@ {#if entry.private} - {/if}
- {/if} - \ No newline at end of file + diff --git a/src/routes/journals/ae_comp__journal_entry_metadata.svelte b/src/routes/journals/ae_comp__journal_entry_metadata.svelte index 99dbbc79..53fc19e5 100644 --- a/src/routes/journals/ae_comp__journal_entry_metadata.svelte +++ b/src/routes/journals/ae_comp__journal_entry_metadata.svelte @@ -17,16 +17,24 @@