mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
46 lines
1.8 KiB
TypeScript
46 lines
1.8 KiB
TypeScript
/**
|
|
* Persistent-storage request (web.dev → council; see reference/principles/web-dev.md).
|
|
*
|
|
* By default browser storage is **best-effort**: under storage pressure the
|
|
* browser may evict the whole origin's IndexedDB + Cache API data. For a
|
|
* local-first app whose workspace lives only in the browser, that is data loss.
|
|
* `navigator.storage.persist()` asks the browser not to evict us.
|
|
*
|
|
* Behaviour per web.dev guidance:
|
|
* - feature-detect; do nothing where the API is absent (never throw),
|
|
* - check `persisted()` first and request **at most once** — don't nag,
|
|
* - stay silent on denial: Chromium decides automatically from heuristics
|
|
* (installed / engagement / notifications), and there is nothing the user
|
|
* can act on, so no toast.
|
|
*
|
|
* Browser-only; the rest of the app reaches it through `orchestration/pwa`.
|
|
*/
|
|
|
|
export type PersistResult =
|
|
| { supported: false }
|
|
| { supported: true; persisted: boolean; alreadyPersisted: boolean };
|
|
|
|
/**
|
|
* Ensure persistent storage, requesting it once if not already granted.
|
|
* Resolves to the outcome; never rejects.
|
|
*/
|
|
export async function requestPersistentStorage(): Promise<PersistResult> {
|
|
const storage = typeof navigator !== 'undefined' ? navigator.storage : undefined;
|
|
if (
|
|
!storage ||
|
|
typeof storage.persist !== 'function' ||
|
|
typeof storage.persisted !== 'function'
|
|
) {
|
|
return { supported: false };
|
|
}
|
|
try {
|
|
const alreadyPersisted = await storage.persisted();
|
|
if (alreadyPersisted) return { supported: true, persisted: true, alreadyPersisted: true };
|
|
const persisted = await storage.persist();
|
|
return { supported: true, persisted, alreadyPersisted: false };
|
|
} catch {
|
|
// A rejected request is not actionable by the user — report not-persisted.
|
|
return { supported: true, persisted: false, alreadyPersisted: false };
|
|
}
|
|
}
|