Skip to content
This repository has been archived by the owner on Sep 30, 2023. It is now read-only.

Update to level@8. Use storage-adapter for all other orbit-db-* packages. #16

Open
CSDUMMI opened this issue Aug 21, 2022 · 1 comment
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@CSDUMMI
Copy link
Contributor

CSDUMMI commented Aug 21, 2022

All of these packages directly depend on level in orbitdb (add more, if known):

  • orbit-db-keystore
  • orbit-db-cache
  • orbit-db-storage-adapter

All of them use an old version of level (<8.0.0). Because v8.0.0 changes the API for interacting with level, all of these packages must be refactored to be upgraded any further.

But this work that should not actually be necessary, because all orbit-db-* packages should only interact with level through orbit-db-storage-adapter.

There are two TODOs:

  • Refactor all other orbit-db-* packages to use orbit-db-storage-adapter instead of level directly.
  • Refactor orbit-db-storage-adapter to use the newest version of level (v8.0.0)

Link to the UPGRADING Guide by level

@aphelionz aphelionz added enhancement New feature or request help wanted Extra attention is needed labels Aug 21, 2022
@haydenyoung
Copy link
Member

haydenyoung commented Jan 12, 2023

I would recommend removing orbit-db-storage-adapter and passing the leveldb directly into the modules that require it.

Previous Level Implementation

When implemented,orbit-db-storage-adapter was designed to abstract away the "up/down" design of level. Originally, level was designed to be completely modular; underlying database bindings, encapsulated in "down" modules, were passed to levelup, a high level wrapper which provided a common API no matter what underlying data storage mechanism was used.

New Level Implementation

As the platform matured, the modular nature of levelup + leveldown produced potential pitfalls and resulted in a move to a bundled approach where a single database implementation was bundled with all of necessary pieces. Instead of a modular design, the latest version of level uses a bundled design whereby everything works out of the box for a targeted database type.

What was once levelup/leveldown is now bundled into a single module. For example, classic-level provides a full stack for node-based leveldb. browser-level for browser support. memory-level for memory-based dbs and so on. All db stacks inherit from abstract-level, which provides a common api for implementing a full stack targeted for a particular database binding. There is even a default "Level" module which provides both classic-level and browser-level implementations in a single package, removing the need to manage databases for either node or browser.

Because each database binding is encapsulated in a full stack inheriting from abstract-level, there is no longer a need (or the ability to pass any database binding (I.e. *down) to a single levelup. Instead, a developer should use the database stack.

What once was:

import leveldown from 'leveldown'
import leveljs from 'level-js'
import levelup from 'levelup'

var down = leveldown('mydb')
var js = leveljs('mydb')
var nodeDb = levelup(down)
var browserDb = levelup(js)

is now:

import { ClassicLevel } from 'classic-level'
import { BrowserLevel } from 'browser-level'

var nodeDb = new ClassicLevel('mydb')
var browserDb = new BrowserLevel('mydb')

Additionally, the former is now deprecated meaning it will be removed from newer versions.

Removing Storage Adapter and implementing level directly

When levelup was used to implement an underlying "down" binding, it made sense to provide an additional layer of abstraction. For example,

import leveldown from 'leveldown'
import Storage from 'orbit-db-storage-adapter'

var storage = Storage(down)
var storage = storage.createStore('mydb')

However, now that an entire stack handles all of the levelup/leveldown interaction, orbit-db-storage-adapter now serves no purpose. In fact, it accomplishes the same outcome as any abstract-level based package does, resulting in a duplication of the work done by the abstract-level packages and making its role redundant.

Instead, orbit-db-storage-adapter should be retired and any module implementing orbit-db-storage-adapter should instantiate the database directly using the necessary stack; classic-level, browser-level, memory-level, etc. This would also remove a lot of the conditionals which are required to address the various idiosyncrasies between database implementations (for example, checking if a db path is necessary, as it would be required for ClassicLevel but not for MemoryLevel).

Migrating away from orbit-db-storage-adapter

  • Most customizable level implementations are required for testing. The various db implementations are currently stored as an array in orbit-db-storage-adapter. These should be moved to orbit-db-test-utils,
  • The only packages implementing orbit-db-storage-adapter are orbit-db-keystore, ipfs-log and orbit-db-cache and most of these are for testing. These should be refactored to implement Level directly.
  • Much of the old conditional logic (if storage, which references a level module, is specified, use it to create the db and then pass to levelup, otherwise implement a new database), has been removed and new Level is now being used. Most orbit-db modules using level have been upgraded to version 8 and are simply wrapping the full stack in levelup, effectively resulting in levelup + (levelup + leveldown)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants