Closed vweevers closed 2 years ago
Option 3, where *-level
naming means a database and level-*
means a plugin, could look like:
Old module(s) | New module |
---|---|
abstract-leveldown |
abstract-level |
memdown / level-mem |
memory-level |
leveldown |
leveldb-level |
level-js |
indexeddb-level |
level |
level 1 |
rocksdb / level-rocksdb |
rocks-level |
level-party |
party-level |
multileveldown |
protobuf-level ? peer-level ? |
subleveldown |
? |
level-test |
can be done differently |
encoding-down |
n/a |
deferred-leveldown |
n/a |
1 Would export leveldb-level
in Node and indexeddb-level
in browsers.
- Keep
memdown
(as anabstract-level
database); deprecatelevel-mem
(as alevelup
db)
Not really an option to me, when it doesn't make sense for everything to be called down
.
2. Deprecate
memdown
(as anabstract-leveldown
database); move code tolevel-mem
(as anabstract-level
db)
I think this is the best for consumers, but I wonder how we would do that. If we moved the code, we'd lose history, if we renamed the repos people might be confused.
3. Deprecate both and create a new
memory-level
package (as well asleveldb-level
,indexeddb-level
, etc)
Prefixes are nicer because they sort well 🤔
I wonder how we would do that. If we moved the code, we'd lose history, if we renamed the repos people might be confused.
The best (but indeed not perfect) way would be to rename level-mem
to e.g. level-mem-archived
and fork memdown
to level-mem
(not through github). Because level-mem
is a light wrapper with relatively little git(hub) history.
The potential confusion is why I'm leaning towards option 3 atm, because it makes a clean split. Consumers will have to replace their require()
or import
statements, which is not that bad especially if it results in a consistent set of names (which is a source of confusion today and not just because of "up" vs "down"; I'm looking at you level-js
and rocksdb
).
Prefixes are nicer because they sort well
It's a crowded namespace so we'd have to use an npm @level
scope for that. A nice thing about the current "down" naming is that you can tell if a module is a store or a plugin; *-level
naming preserves that (though again, not perfectly).
It will be confusing either way, so I'm also leaning towards option 3, to make it less confusing. New names also makes it easier to talk about different things.
To increase the benefit of new names, we could take them a bit further. For example rave-level
to replace level-party
.
I considered scopes for a bit but it doesn't help because we'll still lack unique names for repos, code variables and human communication.
As for subleveldown
(though later on I want to merge that into abstract-level
too) I think I'll go for prefix-level
:
Here's a complete set of names. Unique enough, available on npm, and able to distinguish between the name of the abstract-level
implementation and its underlying store (e.g. LevelDB). I think this works rather well.
Old module(s) | New module | Named export |
---|---|---|
abstract-leveldown |
abstract-level |
AbstractLevel |
leveldown |
classic-level |
ClassicLevel |
memdown & level-mem |
memory-level |
MemoryLevel |
level-js |
browser-level |
BrowserLevel |
level |
level 1 |
Level |
rocksdb & level-rocksdb |
rocks-level |
RocksLevel |
multileveldown |
many-level |
ManyLevel |
level-party |
rave-level |
RaveLevel |
subleveldown 2 |
prefix-level |
PrefixLevel |
1 Will export classic-level
in Node and browser-level
in browsers.
2 Later decided to make sublevels builtin to abstract-level
.
To clarify that "Named export" column, I'm also thinking of using classes and named exports everywhere. E.g.:
const { ClassicLevel } = require('classic-level')
const { MemoryLevel } = require('memory-level')
const db = new ClassicLevel('./db', { valueEncoding: 'json' })
const db = new MemoryLevel({ valueEncoding: 'json' })
This makes TypeScript typings easier (cc @MeirionHughes) as the main class can only be called in one way (with new
) which is simpler to type, and the type declarations can have additional exports (that don't necessarily have a counterpart in JS) like reusable interfaces. Without messing with default exports. E.g.:
export class ClassicLevel {
// ...
}
export interface ReadOptions {
fillCache?: boolean | undefined
}
Closing as "resolved". If you have objections please raise them soon, because after landing https://github.com/Level/abstract-level/pull/8, I'll release abstract-level
1.0.0 and start to push new repo's - classic-level
, memory-level
and browser-level
are code complete (what's left is mainly docs). I've been postponing benchmarks just because I'm not in the mood for that type of work (in my free time) and that's fine. I want to get this thing out the door. I'm not gonna do a prerelease round, going straight to 1.0.0 versions.
With
abstract-level
, there is no "down" or "up" anymore. For example,memdown
does not have to be wrapped withlevelup
. This meanslevel-mem
could just domodule.exports = require('memdown')
to export (largely) the same functionality as before. Which begs the question, should we:memdown
(as anabstract-level
database); deprecatelevel-mem
(as alevelup
db)memdown
(as anabstract-leveldown
database); move code tolevel-mem
(as anabstract-level
db)memory-level
package (as well asleveldb-level
,indexeddb-level
, etc)@Level/core thoughts?