Skip to main content
This guide helps you migrate from the class-based API (new GDB()) to the new async factory function (await gdb()). It covers key changes, before/after examples, and common pitfalls.

Key Changes

Async Initialization

Must use await gdb(name, options) instead of new GDB()

Stable API

Public operations (put, get, map, etc.) remain unchanged

Internal Access

hybridClock, graph, syncChannel exposed for module compatibility

Better Errors

Using new GDB() throws error with migration instructions

Quick Migration

Basic Initialization

import { GDB } from 'gdb';
const db = new GDB('my-db');

Using map (Real-Time Subscription)

// Same API, just ensure async initialization
const { unsubscribe } = await db.map(({ id, value, action }) => {
  console.log('Node updated:', id, value);
});

Using get (Point-in-Time and Reactive)

// No signature changes
const { result } = await db.get(nodeId);

// Or reactive
const { unsubscribe } = await db.get(nodeId, (node) => {
  console.log('Node changed:', node);
});

Write and Delete

// Unchanged
await db.put({ text: 'hello' });
await db.remove(nodeId);

Security Manager (SM) Integration

const db = await gdb("my-db", {
  rtc: true,
  sm: {
    superAdmins: ["0x1234...", "0x5678..."]
  }
});

const sm = db.sm; // Access Security Manager
The sm object is injected when passing { sm: { superAdmins: [...] } }. Access it via db.sm.

Permission Check Example

const activeAddress = sm.getActiveEthAddress();
if (!activeAddress) {
  throw new Error('Login required');
}

// Validate permission before operation
await sm.executeWithPermission('delete');
await db.remove(nodeId);

Browser Usage (ESM)

<script type="module">
  import { gdb } from "../dist/index.js";
  
  const db = await gdb('mydb', { rtc: true });
</script>

Common Pitfalls

Cause: Using db before initialization completesFix:
// Wrong
const db = gdb('name'); // Missing await!
await db.map(...); // Error!

// Correct
const db = await gdb('name');
await db.map(...);
Cause: Module expected db.hybridClock which was not exposed in old versionsStatus: Fixed in current version. hybridClock, graph, and syncChannel are exposed as getters.
Cause: Not awaiting initialization or incorrect query filtersFix:
  • Ensure await gdb(...) before db.map(...)
  • Check your query filter isn’t too restrictive

Migration Checklist

1

Replace all new GDB()

Change every new GDB(name, options) to await gdb(name, options)
2

Ensure async/await

Make sure first use of db happens after await gdb(...)
3

Configure Security Manager

If using SM, initialize with { sm: { superAdmins: ['0x...'] } }
4

Review RBAC actions

Use standardized actions: read, write, link, sync, delete, assignRole
5

Test end-to-end

Verify: initial load, put, update, remove, link, and P2P sync

Full Example (To-Do List)

<script type="module">
  import { GDB } from "../dist/index.js";
  const db = new GDB('todoList');
  
  const { unsubscribe } = await db.map(({ id, value, action }) => {
    renderTodo(id, value, action);
  });
</script>

FAQ

It may exist in some contexts for legacy compatibility, but it’s not recommended. Prefer await gdb(...).
No. They still return { results, unsubscribe } or { result, unsubscribe } accordingly.
Use options: { query: {...}, field: 'timestamp', order: 'asc'|'desc', $limit, $after, $before }
Need help? Open an issue on GitHub with before/after code and the observed error.

Build docs developers (and LLMs) love