style(journals): apply expanded 80-width formatting and snake_case

- Batch formatted all Journals module files using Prettier with printWidth: 80.
- Refactored preventDefault to prevent_default across all Svelte components.
- Standardized line breaks for imports and long attribute lists for better readability.
- Ensured consistent snake_case naming for internal identifiers.
This commit is contained in:
Scott Idem
2026-02-06 14:15:43 -05:00
parent 07dd6c18a1
commit 2f3125c64b
37 changed files with 3033 additions and 1133 deletions

View File

@@ -46,7 +46,9 @@ export async function load_ae_obj_id__journal({
log_lvl?: number;
}): Promise<ae_Journal | null> {
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<ae_Journal[]> {
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<ae_Journal | null> {
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<ae_Journal | null> {
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<string, 'ASC' | 'DESC'> | Record<string, 'ASC' | 'DESC'>[];
order_by_li?:
| Record<string, 'ASC' | 'DESC'>
| Record<string, 'ASC' | 'DESC'>[];
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<T extends Record<string, any>>({
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;
}
});
}
}

View File

@@ -22,7 +22,9 @@ export async function load_ae_obj_id__journal_entry({
log_lvl?: number;
}): Promise<ae_JournalEntry | null> {
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<ae_JournalEntry | null> {
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<T extends Record<string, any>>({
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;

View File

@@ -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<DecryptionResult> {
// 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}`
};
}
}

View File

@@ -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();
}
}

View File

@@ -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 `
<article class="journal-entry" id="entry-${entry.journal_entry_id}">
<header>
<h1>${title}</h1>
@@ -108,7 +127,8 @@ export const template_standard_html: ExportTemplate = {
</div>
<hr/>
</article>`;
}).join('\n');
})
.join('\n');
return `<!DOCTYPE html>
<html lang="en">

View File

@@ -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,

View File

@@ -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<AeJournalEntryInput[]> {
export async function parse_standard_note(
file: File,
text: string
): Promise<AeJournalEntryInput[]> {
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<AeJ
if (lines.length > 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<AeJ
const endFrontmatter = lines.indexOf('---', 1);
if (endFrontmatter > -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<AeJ
const lastModified = new Date(file.lastModified).toISOString();
return [{
name,
content,
tags,
updated_on: lastModified,
created_on: lastModified, // We don't really know creation time from File object usually
original_filename: file.name,
type_code: 'note'
}];
return [
{
name,
content,
tags,
updated_on: lastModified,
created_on: lastModified, // We don't really know creation time from File object usually
original_filename: file.name,
type_code: 'note'
}
];
}
/**
* Personal Log Parser
* - Splits file by dates: `## YYYY-MM-DD`
*/
export async function parse_personal_log(file: File, text: string): Promise<AeJournalEntryInput[]> {
export async function parse_personal_log(
file: File,
text: string
): Promise<AeJournalEntryInput[]> {
const entries: AeJournalEntryInput[] = [];
const dateRegex = /^##\s+(\d{4}-\d{2}-\d{2})(.*)$/;
const lines = text.split('\n');
let currentEntry: Partial<AeJournalEntryInput> | 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<AeJo
// Start new entry
const dateStr = match[1];
const extraTitle = match[2].trim();
currentEntry = {
name: extraTitle ? `${dateStr} - ${extraTitle}` : `${fileBaseName} - ${dateStr}`,
name: extraTitle
? `${dateStr} - ${extraTitle}`
: `${fileBaseName} - ${dateStr}`,
created_on: `${dateStr}T12:00:00`, // Noon on that day
updated_on: new Date(file.lastModified).toISOString(),
tags: ['log'],
type_code: 'log',
original_filename: file.name,
original_filename: file.name
// Reconstruct the header as part of content? Or just skip it?
// Python parser added it back: `## {date_str}\n\n{body}`
// Let's add it back for context.
};
currentContent = [`## ${dateStr} ${extraTitle}`];
currentContent = [`## ${dateStr} ${extraTitle}`];
} else {
if (currentEntry) {
currentContent.push(line);
@@ -141,25 +165,30 @@ export async function parse_personal_log(file: File, text: string): Promise<AeJo
* - Splits by `## Product Name`
* - Looks for URL and `### Review Title`
*/
export async function parse_amazon_vine(file: File, text: string): Promise<AeJournalEntryInput[]> {
export async function parse_amazon_vine(
file: File,
text: string
): Promise<AeJournalEntryInput[]> {
// 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<AeJou
if (currentEntry) {
entries.push(format_vine_entry(currentEntry, currentBody, file));
}
return entries;
}
function format_vine_entry(entry: any, bodyLines: string[], file: File): AeJournalEntryInput {
function format_vine_entry(
entry: any,
bodyLines: string[],
file: File
): AeJournalEntryInput {
let url = '';
let reviewTitle = '';
const cleanBody: string[] = [];
for (const line of bodyLines) {
const trimmed = line.trim();
if (!url && trimmed.startsWith('* http')) {
@@ -190,12 +223,12 @@ function format_vine_entry(entry: any, bodyLines: string[], file: File): AeJourn
}
cleanBody.push(line);
}
let content = '';
if (reviewTitle) content += `# ${reviewTitle}\n\n`;
content += cleanBody.join('\n').trim();
if (url) content += `\n\n**Product Link:** ${url}`;
return {
name: entry.productName,
content: content,

View File

@@ -38,7 +38,8 @@ const journals_local_data_struct: key_val = {
llm__max_retries: 3, // Number of times to retry a failed LLM API call.
llm__retry_delay_ms: 2000, // 2 seconds between retries.
llm__system_prompt: 'You are a helpful assistant that helps people find information.',
llm__system_prompt:
'You are a helpful assistant that helps people find information.',
llm__max_tokens: 1024,
llm__temperature: 0.7,
llm__top_p: 1.0,
@@ -57,8 +58,8 @@ const journals_local_data_struct: key_val = {
qry__limit: 25,
qry__offset: 0,
qry__order_by_li: {
// 'created_on': 'desc',
// 'updated_on': 'desc',
// 'created_on': 'desc',
// 'updated_on': 'desc',
},
type_code_li: [

View File

@@ -20,7 +20,7 @@ import type { ae_Journal, ae_JournalEntry } from '$lib/types/ae_types';
export interface Journal extends ae_Journal {
// Add any Dexie-specific or legacy local-only fields here if not in ae_Journal
// Most fields are now in ae_Journal and ae_BaseObj
// For backward compatibility with some views that expect these
combined_passcode?: string;
person__given_name?: string;
@@ -29,7 +29,7 @@ export interface Journal extends ae_Journal {
person__primary_email?: string;
person__passcode?: string;
person__kv_json?: string;
journal_entry_kv?: key_val;
journal_entry_li?: any[];
journal_file_kv?: key_val;
@@ -80,7 +80,7 @@ export interface Journal_Entry extends ae_JournalEntry {
person__primary_email?: string;
person__passcode?: string;
person__kv_json?: string;
journal_file_kv?: key_val;
journal_file_li?: any[];
}