-
Notifications
You must be signed in to change notification settings - Fork 2
System Documentation
Protowallet is an offline expense tracking application. Thus, it's core feature is (you might have guessed it) tracking expenses. Currently application has not grown too big and is quite simple. Following points mentioned below will give you a fairly good insight.
- Expenses are recorded into
Transactionand entire system is built around it. - Entire data is loaded into memory during start of application and "synced" to file system periodically.
- No server is involved since it is offline. Business logic is written into packages which are bundled into application distribution.
All the values, including Account Balances, Budgets, etc. are calculated on runtime and never directly stored on disk. This is done to seamlessly supported Recurring Transactions, Automated Budgeting, Analytics, etc. Only amount from transactions is stored persistently. This decision is taken keeping in mind that
- data lives in memory (so traversing is cheap)
- recurring transactions / budgets won't need to be added via Cron (so no dangling background processes)
- data is owned by user and calculations happen on user-side (so it won't lead to scaling issues. Even 10M transactions will take hardly take a second).
Entire codebase is organized in a mono-repo. Building and versioning managed by Lerna and dependencies managed by Yarn Workspaces. Important directories and files:
-
appsThis is where all the distributions live. Distribution is something which is consumable by end user. -
packagesBusiness logic functionalities are divided into packages withcorepackage being most important and entry point for apps. -
docsEntire package-specific documentation lives here. Generated from Typedoc -
lerna.jsonBuild and release configuration stays here.
We use LokiJS as the in-memory datastore and leverage different adapters based on use case to save data to a persistent place. We use,
- IndexedDB Adapter to store data in browser's IndexedDB.
- FS Adapter to store data on disc encrypted.
This version of documentation only explains core package as everything else is trivial as of now.

Internally, it all starts with Feeds. Feeds are raw references to underlying Collection object of corresponding entity. It can be used to directly manipulate documents inside of collection.
On top of feeds, we have Repositories. A repository is a wrapper around feeds with utility functionalities provided along with validations. Repositories are singleton i.e same instance is used throughout application lifecycle. They can be grabbed from repository-provider
Lastly, we have services separated by topics (can be inferred from class name) which hold calculation/business logic.
Any of the above ones can be accessed by client.