It took awhile for the concept to crystallize but now I think I have a better idea of how to implement the open function.
The straightforward approach is to enumerate the use cases for this functionality, and then design in a direction towards those use cases that maximizes overlap (e.g. avoiding DRY violations) while also minimizing unused features (e.g. unused parameters).
There are three use cases (I think?):
opening a connection to the application's database using the default name and version and a default timeout and the default upgrade handler. This is the most frequent use case.
opening a connection using the defaults, except for the timeout parameter. There is a rare use case, where either the time it takes to establish the connection is irrelevant, or it is expected that the time will be substantial. Off the top of my head I cannot think of irrelevant times but I am pretty sure there are a few. I can think of a very specific case where the time will be substantial, that is when a new version is specified and it is anticipated that a database upgrade will occur.
opening a connection for test purposes, where we want to use a different name and version, a different or no channel, all or part of the default upgrade handler, and most of the time the timing it takes is irrelevant (so long as the test timeout itself is long enough to allow the test to run).
What this tells me, I think, is that the best way to design the feature is the following:
db/open only provides a timeout parameter. it uses the default database name, version, channel, and upgrade handler. the timeout value defaults to a sensible value like 5 seconds or something. This supports use case 1 and 2, favoring 1 (the most frequent). In the 2 use case, it will be the only time the timeout parameter is specified to be something other than the default.
db/test-open provides name/version/upgrade parameters, or because it is so wildly different amongst tests or barely does any material amount of decoration over indexeddb-utils/open, does not exist at all, and each test instead interacts directly with indexeddb-utils/open. there is no timeout parameter because it is basically irrelevant.
db/test-open relies directly on indexeddb-utils/open, not db/open, as a second user of the library independent of the db/open user.
the upgrade functionality is placed into a separate module within the db folder, is always used by db/open, and then is optionally used in part or in whole by the test-open call.
Originally I was trying to support the 3rd use case using db/open, and that was where I went down the wrong path, because the name and version never change in the first two use cases, only the timeout does. I also made the mistake of not timing out by default, which is actually the typical case.
It took awhile for the concept to crystallize but now I think I have a better idea of how to implement the open function.
The straightforward approach is to enumerate the use cases for this functionality, and then design in a direction towards those use cases that maximizes overlap (e.g. avoiding DRY violations) while also minimizing unused features (e.g. unused parameters).
There are three use cases (I think?):
What this tells me, I think, is that the best way to design the feature is the following:
Originally I was trying to support the 3rd use case using db/open, and that was where I went down the wrong path, because the name and version never change in the first two use cases, only the timeout does. I also made the mistake of not timing out by default, which is actually the typical case.