-
-
Notifications
You must be signed in to change notification settings - Fork 17
Description
Interstellar's code base is growing steadily, and I think it would be a good time to reevaluate some of our technology & library choices, so here are just a few ideas I had (this is by no means definite, just some brainstorming).
Routing with Navigator 2.0
The Navigation and routing page in the Flutter docs gives a great overview on the different types of navigation that Flutter provides. ATM, we're using "Navigator 1.0", which is an imperative API that is extremely simple and easy to use: call Navigator.push to add a screen, and call Navigator.pop to remove a screen; nothing really special about it. Flutter also has "Navigator 2.0", which is a declarative API that defines screens based on page route paths, similar to how a website might have a "/user/johndoe" URL path.
With "Navigator 2.0", it is extremely recommended to use a package with it. The two packages I've found are go_router and auto_route. go_router is more popular and officially recommended in the Flutter docs, but auto_route uses code generation (which we conveniently already use) to provide a type safe API for switching routes.
If we want to support the web platform (which wouldn't be a bad idea), then we would definitely need to switch to "Navigator 2.0". Besides web support, we would also be able to set up deep linking if we thought that would be nice.
Storage
I've seen people recommend Isar and Hive in the past, but those are both long dead, and I don't want to migrate to something that's already unmaintained. I did read this interesting blog post detailing the best local databases for Flutter. I think I've narrowed it down to these three options though.
Drift (SQL)
Drift is a reactive library to store relational data in Dart and Flutter applications, built on top of SQLite.
Drift seems to be the best contender if we want a local database built on top of SQLite. Due to being SQL, it makes migrations extremely easy when needed, and we can also run any complex SQL query required in the app to fetch any data. One thing that's cool about Drift is that it's so popular that it has a bunch of different integrations from external packages, such as this in-app drift db viewer, which would be great as a debug tool.
sembast (NoSQL)
Yet another NoSQL persistent store database solution for single process io applications. The whole document based database resides in a single file and is loaded in memory when opened. Changes are appended right away to the file and the file is automatically compacted when needed.
This is what we're already using, so it already has a +1 due to not needing to migrate to it. It's good to rethink it, though.
Just some thoughts: In the past, I have found it a bit "clunky" to use; maybe I'm just making this up, but the API, especially for making search queries, just feels weird to use, but I probably just need to get used to it. I do find its lack of type safety in certain areas annoying too. Additionally, I'm not really sure how I feel about the whole database being loaded all at once in memory once the app starts. I'm sure our database would never be that big that we have to worry about it crashing people's phones, but I still feel like it's something to think about. Additionally, sembast doesn't have any migration mechanisms (correct me if I'm wrong); migration in general is a pain to handle, but it is something that an app has to deal with if it's around long enough. All I'm saying here is that it wouldn't hurt to consider our options; maybe we should stick with sembast, or maybe we should switch to something else.
Roll our own (Filesystem)
This is an option I would consider as seriously as the other options. If we rolled out our own system of data storage, we would have full control over it, and Interstellar would integrate seamlessly with it. What I'm imagining is that we just use the OS's own file system to store and organize everything. Each settings profile, for instance, could have its own file in a profiles directory. I've looked at Firefox's data storage before, and it similarly has a folder to store data for each of its profiles. Doing it like this would also make the data extremely easy to debug, share, export, import, and manipulate. I would imagine the file structure could look something like the following:
interstellar.jwr.one/entry(contains values needed for app startup, such as the selected account and profile)profiles/Main.jsonModerate.json
accounts/kbin.earth.jsonjohndoe@kbin.earth.json
Of course, just using the filesystem wouldn't work (at least not easily) if we wanted to support web.
State management
Provider's been working pretty well for us for the most part, but we could always consider a more advanced state management library. The two big ones are Riverpod (which was actually developed by the creator of Provider) and BLoC. I've never used either of them though, so if we did want to switch, I wouldn't know which one to go for; I'd have to do some research.
Let me know your thoughts on all this @olorin99! I just wanted to put out some ideas to make the codebase more maintainable.