GrvMkr: Persistence
TLDR
Spent another 3 days improving the GrvMkr MVP. I gave it a memory amongst other things. Oh, also i like AI now - ChatGPT is my friend.
TSMD (Too short, more detail)
I posted the MVP of GrvMkr on reddit and got exactly one upvote (lol).
I also searched the web to see if any one else apart from my mum was requesting this tool. Turns out there was one other person, also on reddit.
I showed them the MVP, and they came back with this:
Obviously, i had more work to do. What use is a tool where you can’t save your work?
Save & Load
I added save and load functionality, which basically persists the instrument and grid state structures into a big json file.
I made sure to create separate types for serialisation, so that if someone with an old JSON file wants to use a future version of the tool, the file will still deserialise properly. This complicates things slightly because if i change or add to the data structures in the app, i’ll need to support mapping from older versions of the json file to new structures, where data may not exist. However, i was set on making this tool as ‘production like’ as possible, and this is something you’d do as a business so, call it practice.
I used chat GPT to help me write all the boring boiler plate mapping code between types. It did really well here, and saved me a bunch of time.
Historically i’ve been very skeptical or AI’s usefulness, but i’m really beginning to open up to it recently. Maybe its because i’m writing a language i’m not proficient in. Asking it how to do something i know how to do in another language, in TypeScript, is a nice way to avoid doom-scrolling stackoverflow.
Persistence with indexedDB
Once i was done with persisting to a file, i thought it’d be fun to make the app remember your grooves. Currently, if you refresh the page you loose all your work, and if you didn’t save it to a file, its gone!
Wouldn’t it be nice if everything you did was persisted to a database in your browser, so if you browser crashes or you accidently close the tab, your work is safe?
Yes.
Somehow, in my over 10 year software careeer, i’ve never really done much database work. Its a real weak point in my skill set, so i was looking forward to diving into a foreign world.
indexedDB
After consulting ChatGPT, i settled on using indexedBD as it seemed to fit my usecase:
- IndexedDB (Best for Complex Data & Large Storage)
NoSQL database for storing structured data.
Supports transactions, indexes, and large storage.
Asynchronous API (uses Promises).
Good for offline applications and caching.
Having a little more faith in ChatGPT after the mapper work it performed valiantly for me, i decided to use it to write my boring data layer classes.
I gave it my data layer types, and said something like given these data types, write me a service class which handles mapping these domain types to the data types, and stores them in indexedDb using a seperate table class
.
It did take a few tries and a bit of back and forth clarifying certain things - i think my prompt engineering skills are currently lacking. However, the end result was 2 service classes GridService
and InstrumentService
, and 3 table classes InstrumentTable
, GridTable
and HitTable
, which happily handled CRUD operations on my domain objects (after some light editing and bug fixing).
What i thought would be a deep dive into the inner workings of indexedDB turned out to be a relatively simple exercise in AI prompt engineering.
Database upgrades
One aspect i overlooked was updating the database. At some point, i deployed the app and noticed it was very broken on mobile - assuming some mobile specific thing i set out to debug, and noticed some failure to open database table
type errors.
Turns out, when you add tables, you have to remember to update the version number manually, so indexedDB knows to run its onupgradeneeded
function. This is a function you define, which runs once after a version bump. I needed to check for the presence of the required tables, and if they didn’t exist, create them. Easy enough when you know.
Edge sucks?
After fixing this issue, i noticed a similar but different can't open database
(not the table, the database itself) error in Edge. The underlying error seemed to be a permissions issue as it was suggesting the browser user hadn’t given permissions to access the database.
Checking dev tools, showed the database didn’t even exist, which was probably the issue.
However, chrome seemed to create the tables fine, it was only Edge which wasn’t doing so.
Turns out, my fresh install of Edge had defaulted to not allowing cookies and site data - which is required to interact with indexedDB. Wondering how common this is, i decided to add a visible warning to users who were in the same situation.
Basic error handling really, catch the database error, check its the same one i was experiencing, and fire some event to the UI to show an error.
Printing
One of the main goals of the tool is to be able to print the grid notation out. This is aimed at community music scenarios like samba bands and drumming groups where sheet music may be handed out in sessions.
Currently, if a phrase is over around 4 bars long, it becomes illegible and hard to read due to the grid cells being squashed into the same A4 landscape paper size.
Here’s a simple 4 bar phrase, in the print preview window. Any more bars than this and it would become useless.
I decided to split phrases into 2 bar chunks, and display them vertically. This number was picked from thin air, so i might tweak it in future based on feedback.
After these changes, here’s the print preview of a 3 bar phrase on page 1, and a 1 bar phrase on page 2.
I’m filling all available space with notation, so for odd number bar phrases, it looks kinda weird, but they’re pretty uncommon and i think using all the available space is better than uniform layouts here.
While writing this article i’ve noticed that i should add some discrimination between the bars. Maybe a border around the bar, or an extra dark cell for the first beats of bars.
Final thoughts
Apparently i’m still procrastinating writing UI tests for Location Alam. I wonder how long this will continue. Am i a web developer now!?
In all seriousness though, there’s only one feature i want to add before I take a break from this project and call it ‘done’
More on that to come (maybe)
Comments