A simple offline-first todo app made with Svelte 5 and Sqlite.
On the server we use a sqlite
database to store the todos, on the client we also use sql.js
which is a version of
sqlite compiled to WASM
.
All the routes are prerendered and all the static files are cache and serve from a service worker
when offline.
We also run a node server within the same app, I patched the @sveltejs/adapter-node
so it can generate a fallback page that is used for dynamic routes.
While the user have connection (online) each time a todo is added, updated or deleted, we make a call to the backend to create/update/delete that todo, and also update the local database.
When the user have not connection (offline) we only write in the local database and also keep track of the added/updated/delete (currently in localStorage
),
after the user recover the connection we make a request to the backend with all the records that where affected while offline to synchronize with the backend.
Each time the page refresh if the user is online we get all the records from the backend and recreate the local database.
graph TD;
subgraph Server
DB[(SQLite Database)]
NodeServer[Node.js Server]
AdapterPatch[Svelte Adapter Node Patched]
ServiceWorker[Service Worker]
end
subgraph Client
LocalDB[(sql.js WASM)]
localStorage[(localStorage)]
end
subgraph ConnectionStatus
Online[Online]
Offline[Offline]
end
subgraph TodoActions
AddTodo[Add Todo]
UpdateTodo[Update Todo]
DeleteTodo[Delete Todo]
RefreshPage[Refresh Page]
end
TodoActions -->|if Online| Online
TodoActions -->|if Offline| Offline
Online -->|Sync with backend| NodeServer --> DB
Online -->|Update local DB| LocalDB
Online -->|Sync offline changes| NodeServer
Online -->|Sync offline changes| LocalDB
Online -->|Refresh Page| NodeServer -->|Fetch all records| LocalDB
Offline -->|Update local DB| LocalDB
Offline -->|Track changes| localStorage
NodeServer --> AdapterPatch
AdapterPatch -->|Generate fallback page| NodeServer
ServiceWorker -->|Cache static files| Client
NodeServer -->|Communicate with Client| Client