Request persistent storage after first save

IndexedDB data can be evicted under storage pressure, especially on iOS
Safari. navigator.storage.persist() asks the browser to keep our data. On
Chromium+Firefox it succeeds silently when conditions allow (installed PWA,
engagement heuristics); on Safari it typically grants only for installed
PWAs.

- persistentStorage.js: isPersisted() and requestPersistence() with graceful
  fallback when the Storage API is unavailable.
- persistence.js: request persistence once, after the first successful save —
  a heuristic that works across Firefox (user gesture context) and
  Chromium/Safari (data-stored context).
- sw.js: bump cache version, precache new file.
- index.html: load new script.
This commit is contained in:
Randy Fischer 2026-04-15 15:54:06 +02:00
parent 92ad6a92e3
commit b005193dbc
4 changed files with 29 additions and 1 deletions

View File

@ -303,6 +303,7 @@
<script src="../src/Infrastructure/utils.js"></script> <script src="../src/Infrastructure/utils.js"></script>
<script src="../src/Infrastructure/geolocation.js"></script> <script src="../src/Infrastructure/geolocation.js"></script>
<script src="../src/Infrastructure/db.js"></script> <script src="../src/Infrastructure/db.js"></script>
<script src="../src/Infrastructure/persistentStorage.js"></script>
<script src="../src/Infrastructure/seedOrders.js"></script> <script src="../src/Infrastructure/seedOrders.js"></script>
<script src="../src/Infrastructure/csvLoader.js"></script> <script src="../src/Infrastructure/csvLoader.js"></script>
<script src="../src/Application/state.js"></script> <script src="../src/Application/state.js"></script>

View File

@ -1,4 +1,4 @@
const CACHE_VERSION = 'duimstok-v1'; const CACHE_VERSION = 'duimstok-v2';
const APP_SHELL = [ const APP_SHELL = [
'./', './',
@ -19,6 +19,7 @@ const APP_SHELL = [
'../src/Infrastructure/utils.js', '../src/Infrastructure/utils.js',
'../src/Infrastructure/geolocation.js', '../src/Infrastructure/geolocation.js',
'../src/Infrastructure/db.js', '../src/Infrastructure/db.js',
'../src/Infrastructure/persistentStorage.js',
'../src/Infrastructure/seedOrders.js', '../src/Infrastructure/seedOrders.js',
'../src/Infrastructure/csvLoader.js', '../src/Infrastructure/csvLoader.js',
'../src/Application/state.js', '../src/Application/state.js',

View File

@ -1,4 +1,6 @@
(function (A, I) { (function (A, I) {
let persistenceRequested = false;
function readFormFields() { function readFormFields() {
const fd = A.state.formData; const fd = A.state.formData;
fd.inspecteur = document.getElementById('inp_inspecteur').value; fd.inspecteur = document.getElementById('inp_inspecteur').value;
@ -14,6 +16,10 @@
await I.saveInspection(A.state.formData); await I.saveInspection(A.state.formData);
document.getElementById('statusSaved').textContent = document.getElementById('statusSaved').textContent =
'Opgeslagen: ' + new Date().toLocaleTimeString('nl-NL'); 'Opgeslagen: ' + new Date().toLocaleTimeString('nl-NL');
if (!persistenceRequested) {
persistenceRequested = true;
I.requestPersistence();
}
}; };
A.autoSave = function () { A.autoSave = function () {

View File

@ -0,0 +1,20 @@
(function (I) {
function supported() {
return navigator.storage && typeof navigator.storage.persist === 'function';
}
I.isPersisted = async function () {
if (!supported()) return false;
return navigator.storage.persisted();
};
I.requestPersistence = async function () {
if (!supported()) return false;
if (await navigator.storage.persisted()) return true;
try {
return await navigator.storage.persist();
} catch {
return false;
}
};
})(window.App.Infrastructure);