feat(core): add preserve_ls_keys and skip_ls options to clear_all_storage; update Clear & Reload buttons
core__browser_reset:
- clear_all_storage now accepts options: { preserve_ls_keys?, skip_ls? }
- preserve_ls_keys: saves named localStorage keys before clearing and restores them after
(use ['ae_loc'] to keep the user signed in through a full reset)
- skip_ls: skips localStorage and sessionStorage entirely
(for SW+Cache+IDB-only resets that should not disturb auth state)
journals/+layout.svelte:
- Replaced 60-line inline onclick with core_func.clear_idb() + ae_loc preserve pattern
- Hardcoded indexedDB.deleteDatabase() name list replaced with core_func.clear_idb()
(gets indexedDB.databases() enumeration + older-browser fallback automatically)
- Non-edit mode: IDB clear + reload; edit mode: IDB + localStorage (ae_loc preserved) + goto('/')
e_app_help_tech + +page.svelte Clear & Reload buttons:
- Replaced inline SW/Cache/IDB/localStorage logic with core_func.clear_all_storage()
- Non-edit: skip_ls=true (SW+Cache+IDB only; sign-in preserved naturally)
- Edit mode: preserve_ls_keys=['ae_loc'] (full clear; sign-in survives the wipe)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -66,8 +66,17 @@ export async function clear_idb(log?: BrowserResetLogFn): Promise<void> {
|
||||
* @param log Optional progress callback. Receives each step message and a severity level.
|
||||
* Use this to surface step-by-step feedback to the user (e.g. the fix-sw page).
|
||||
* Omit for silent operation (e.g. the sys bar reset buttons).
|
||||
* @param options Optional behavior overrides.
|
||||
* - preserve_ls_keys: localStorage keys to save before clearing and restore after.
|
||||
* Use ['ae_loc'] to keep the user signed in through the reset.
|
||||
* - skip_ls: if true, skip clearing localStorage and sessionStorage entirely.
|
||||
* Use this for "Clear & Reload" style resets that only need SW+Cache+IDB
|
||||
* cleared (non-destructive to auth state — no ae_loc preservation needed).
|
||||
*/
|
||||
export async function clear_all_storage(log?: BrowserResetLogFn): Promise<void> {
|
||||
export async function clear_all_storage(
|
||||
log?: BrowserResetLogFn,
|
||||
options?: { preserve_ls_keys?: string[]; skip_ls?: boolean }
|
||||
): Promise<void> {
|
||||
if (!browser) return;
|
||||
|
||||
log?.('Starting full storage reset...', 'info');
|
||||
@@ -110,13 +119,27 @@ export async function clear_all_storage(log?: BrowserResetLogFn): Promise<void>
|
||||
// 3. Clear all IndexedDB databases (handles enumeration + fallback internally)
|
||||
await clear_idb(log);
|
||||
|
||||
// 4. Clear localStorage
|
||||
if (options?.skip_ls) {
|
||||
log?.('Skipping localStorage and sessionStorage (skip_ls=true).', 'info');
|
||||
} else {
|
||||
// 4. Clear localStorage (saving and restoring any keys that should survive the reset)
|
||||
try {
|
||||
const local_count = localStorage.length;
|
||||
const preserved: Record<string, string> = {};
|
||||
for (const key of options?.preserve_ls_keys ?? []) {
|
||||
const val = localStorage.getItem(key);
|
||||
if (val !== null) preserved[key] = val;
|
||||
}
|
||||
localStorage.clear();
|
||||
log?.(`Cleared localStorage (${local_count} item(s)).`, 'ok');
|
||||
} catch (err: any) {
|
||||
log?.(`ERROR clearing localStorage: ${err.message}`, 'error');
|
||||
for (const [key, val] of Object.entries(preserved)) {
|
||||
localStorage.setItem(key, val);
|
||||
}
|
||||
const preserved_note = Object.keys(preserved).length
|
||||
? ` (preserved: ${Object.keys(preserved).join(', ')})`
|
||||
: '';
|
||||
log?.(`Cleared localStorage (${local_count} item(s))${preserved_note}.`, 'ok');
|
||||
} catch (err) {
|
||||
log?.(`ERROR clearing localStorage: ${(err as Error).message}`, 'error');
|
||||
}
|
||||
|
||||
// 5. Clear sessionStorage
|
||||
@@ -124,7 +147,8 @@ export async function clear_all_storage(log?: BrowserResetLogFn): Promise<void>
|
||||
const session_count = sessionStorage.length;
|
||||
sessionStorage.clear();
|
||||
log?.(`Cleared sessionStorage (${session_count} item(s)).`, 'ok');
|
||||
} catch (err: any) {
|
||||
log?.(`ERROR clearing sessionStorage: ${err.message}`, 'error');
|
||||
} catch (err) {
|
||||
log?.(`ERROR clearing sessionStorage: ${(err as Error).message}`, 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,28 +465,12 @@ class:to-90%={$ae_sess.show_help_tech} -->
|
||||
|
||||
if (!confirm(confirm_msg)) return;
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
const registrations = await navigator.serviceWorker.getRegistrations();
|
||||
for (const reg of registrations) await reg.unregister();
|
||||
}
|
||||
const cache_keys = await caches.keys();
|
||||
for (const key of cache_keys) await caches.delete(key);
|
||||
|
||||
// Enumerate and delete every IDB database on this origin.
|
||||
const db_list = await indexedDB.databases();
|
||||
console.log('[clear_reload] IDB databases found:', db_list.map((d) => d.name));
|
||||
for (const db of db_list) {
|
||||
if (db.name) indexedDB.deleteDatabase(db.name);
|
||||
}
|
||||
|
||||
if (edit_mode) {
|
||||
// Preserve ae_loc (sign-in credentials + permissions) across the wipe.
|
||||
const ae_loc_saved = localStorage.getItem('ae_loc');
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
if (ae_loc_saved) localStorage.setItem('ae_loc', ae_loc_saved);
|
||||
}
|
||||
|
||||
// Non-edit: skip_ls=true — SW+Cache+IDB only, localStorage untouched (sign-in preserved naturally).
|
||||
// Edit mode: preserve_ls_keys=['ae_loc'] — full clear but sign-in survives the wipe.
|
||||
await core_func.clear_all_storage(
|
||||
undefined,
|
||||
edit_mode ? { preserve_ls_keys: ['ae_loc'] } : { skip_ls: true }
|
||||
);
|
||||
window.location.reload();
|
||||
}}
|
||||
class="
|
||||
|
||||
@@ -97,25 +97,12 @@ onMount(() => {
|
||||
|
||||
if (!confirm(confirm_msg)) return;
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
const registrations = await navigator.serviceWorker.getRegistrations();
|
||||
for (const reg of registrations) await reg.unregister();
|
||||
}
|
||||
const cache_keys = await caches.keys();
|
||||
for (const key of cache_keys) await caches.delete(key);
|
||||
|
||||
const db_list = await indexedDB.databases();
|
||||
for (const db of db_list) {
|
||||
if (db.name) indexedDB.deleteDatabase(db.name);
|
||||
}
|
||||
|
||||
if (edit_mode) {
|
||||
const ae_loc_saved = localStorage.getItem('ae_loc');
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
if (ae_loc_saved) localStorage.setItem('ae_loc', ae_loc_saved);
|
||||
}
|
||||
|
||||
// Non-edit: skip_ls=true — SW+Cache+IDB only, localStorage untouched (sign-in preserved naturally).
|
||||
// Edit mode: preserve_ls_keys=['ae_loc'] — full clear but sign-in survives the wipe.
|
||||
await core_func.clear_all_storage(
|
||||
undefined,
|
||||
edit_mode ? { preserve_ls_keys: ['ae_loc'] } : { skip_ls: true }
|
||||
);
|
||||
window.location.reload();
|
||||
}}
|
||||
class="btn btn-sm
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
|
||||
// *** Import Aether specific variables and functions
|
||||
import { ae_loc, ae_sess, ae_api, slct } from '$lib/stores/ae_stores';
|
||||
import { core_func } from '$lib/ae_core/ae_core_functions';
|
||||
import {
|
||||
journals_loc,
|
||||
journals_slct,
|
||||
@@ -155,68 +156,26 @@ function scroll_container() {
|
||||
<!-- <a href="/settings" class="btn btn-sm">Settings</a> -->
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
if ($ae_loc.edit_mode) {
|
||||
// Confirm before clearing
|
||||
if (
|
||||
!confirm(
|
||||
'Are you sure you want to clear IndexedDB databases, localStorage, and sessionStorage? This will also reload the page.'
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
onclick={async () => {
|
||||
const edit_mode = $ae_loc.edit_mode;
|
||||
const confirm_msg = edit_mode
|
||||
? 'Clear all IDB caches, localStorage, and sessionStorage? Your sign-in will be preserved. This will reload the page.'
|
||||
: 'Clear all IDB caches? This will reload the page.';
|
||||
|
||||
console.log(
|
||||
'Clearing IndexedDB, localStorage, sessionStorage, and reloading the page...'
|
||||
);
|
||||
if (!confirm(confirm_msg)) return;
|
||||
|
||||
// Clear Indexed DB
|
||||
indexedDB.deleteDatabase('ae_archives_db'); // Archives module
|
||||
indexedDB.deleteDatabase('ae_core_db');
|
||||
indexedDB.deleteDatabase('ae_events_db'); // Events module
|
||||
indexedDB.deleteDatabase('ae_journals_db'); // Journals module
|
||||
indexedDB.deleteDatabase('ae_posts_db'); // Posts module
|
||||
indexedDB.deleteDatabase('ae_sponsorships_db'); // Sponsorships module
|
||||
await core_func.clear_idb();
|
||||
|
||||
// Clear localStorage and sessionStorage
|
||||
// Clearing the localStorage will force it to be re-created.
|
||||
if (edit_mode) {
|
||||
// Preserve ae_loc so the user stays signed in at their current level.
|
||||
const ae_loc_saved = localStorage.getItem('ae_loc');
|
||||
localStorage.clear();
|
||||
sessionStorage.clear();
|
||||
|
||||
if (ae_loc_saved) localStorage.setItem('ae_loc', ae_loc_saved);
|
||||
goto('/', { invalidateAll: true });
|
||||
|
||||
// window.location.reload(true);
|
||||
} else {
|
||||
// Confirm before clearing
|
||||
if (
|
||||
!confirm(
|
||||
'Are you sure you want to clear IndexedDB databases and some caches? This will also reload the page.'
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
'Clearing IndexedDB, localStorage, sessionStorage, and reloading the page...'
|
||||
);
|
||||
|
||||
// Clear Indexed DB
|
||||
indexedDB.deleteDatabase('ae_archives_db'); // Archives module
|
||||
indexedDB.deleteDatabase('ae_core_db');
|
||||
indexedDB.deleteDatabase('ae_events_db'); // Events module
|
||||
indexedDB.deleteDatabase('ae_journals_db'); // Journals module
|
||||
indexedDB.deleteDatabase('ae_posts_db'); // Posts module
|
||||
indexedDB.deleteDatabase('ae_sponsorships_db'); // Sponsorships module
|
||||
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// This does not seem to work fast enough or something?
|
||||
// goto('/', {invalidateAll: true});
|
||||
|
||||
// The page does usually seem to reload correctly?
|
||||
// window.location.reload(true); // true only works with Firefox
|
||||
// alert('Local and Session Storage cleared and Indexed DBs deleted. You will probably want to refresh the page.');
|
||||
}}
|
||||
class="btn btn-sm preset-tonal-surface border-surface-500 hover:preset-filled-warning-500 border"
|
||||
title="Clear App Data & Settings: Clear IndexedDB and reload. If in edit mode localStorage and sessionStorage will also be cleared.">
|
||||
|
||||
Reference in New Issue
Block a user