Documentation Index
Fetch the complete documentation index at: https://mintlify.com/estebanrfp/gdb/llms.txt
Use this file to discover all available pages before exploring further.
๐ API Reference
Minimalist Graph Database with P2P support and real-time querying.
๐ฆ Installation
๐ฅ Import
1. Via NPM
2. Direct use in browser from a CDN
โ๏ธ Async Factory Function (for top-level await)
await gdb(name, options?)
Creates and configures a database connection.
-
Parameters:
name{string}โ Database name (used for local storage or sync).options{Object}(optional):rtc{boolean | Object}โ Iftrue, enables real-time P2P networking and relay connections.
To customize relays or TURN servers, pass an object:
{ relayUrls, turnConfig }relayUrls{string[]}โ Custom list of secure WebSocket relay URLs (for Nostr), now passed inside thertcobject.turnConfig{Array<Object>}โ Configuration for TURN servers, now passed inside thertcobject.cells{boolean | Object}โ Enable Cellular Mesh overlay for massive scalability. Passtruefor defaults or an object with options:{ cellSize, bridgesPerEdge, maxCellSize, targetCells, debug }.
sm{Object}โ Enables and configures the Security Manager. Provide at leastsuperAdmins(an array of authorized addresses).ai{boolean}โ Iftrue, loads the AI module.nlq{boolean}โ Iftrue, loads the Natural Language for Queries module.geo{boolean}โ Iftrue, loads the Geo module.audit{boolean}โ Iftrue, loads the Audit module.password{string}โ Optional encryption key.debug{boolean}(optional) โ Iftrue, enables GenosDBโs internal debug logging (persistence, synchronization, networking and module activity). The console stays fully silent by default. Defaults tofalse.saveDelay{number}(optional) โ The debounce delay in milliseconds for saving the graph to persistent storage. Higher values reduce disk I/O under heavy write loads but increase the risk of data loss if the browser crashes. Defaults to200.oplogSize{number}(optional) โ The maximum number of recent operations to keep in the operation log for delta-based P2P synchronization. Larger values allow peers to sync efficiently after longer disconnections but consume more memory. Defaults to20.
-
Returns:
gdbobject.
Initialize without a password
Initialize with a password (optional)
rtc To explicitly enable the P2P networking module (opcional)
relayUrls (opcional)
To specify custom relays for Nostr when initializing the database:
turnConfig (optional)
Once you have a TURN server, configure GenosDB with it like this:
cells (optional) โ Cellular Mesh Network
Enable the Cellular Mesh overlay for massive P2P scalability. This architecture organizes peers into logical โcellsโ with bridge nodes for inter-cell communication, reducing connection complexity from O(Nยฒ) to O(N).
๐งฉ Core Methods
use(middleware)
Registers a middleware function to process or transform incoming P2P messages before they are applied to the local database. Middlewares are executed in the order they are registered.
- Parameters:
middlewareasync {Function}โ An asynchronous function that receives an array of incoming operations. It must return a (potentially modified) array of operations to be processed. Returning an empty array[]will effectively discard the incoming batch.
- Returns:
{void}
๐งฉ Core Methods
async put(value, id?)
Inserts or updates a node.
- Parameters:
value{Object}โ Node content (must be serializable).id{string}(optional) โ If provided, updates the node.
- Returns:
{Promise<string>}โ Node ID (hash or custom).
More examples: See PUT Guide.
async get(id, callback?)
Retrieves a node by its ID. If a callback is provided, it enters reactive mode, invoking the callback immediately with the nodeโs state and on any subsequent changes.
- Parameters:
id{string}callback{Function}(optional) โ The callback function, which receives the full node object ({ id, value, edges, timestamp }) ornullif the node is deleted.
- Returns:
{Promise<Object>}โ A promise resolving to an object with:result: The initial node state.unsubscribe: A function to stop listening for updates (if in reactive mode).
More examples: See GET Guide.
async link(sourceId, targetId)
Creates a directed relationship between two nodes.
- Parameters:
sourceId{string}targetId{string}
- Returns:
{Promise<void>}
async remove(id)
Deletes a node and its references.
- Parameters:
id{string}
- Returns:
{Promise<void>}
async map(...args)
Queries nodes and can listen for real-time updates.
It flexibly accepts zero or more arguments. Typically, these are:
- An options object (for
queryConfig) to define filtering, sorting, etc. - A callback function to process real-time updates.
-
Arguments (
...args):-
options{Object}(optional) โ Configuration for the query. If an object is passed, its properties will be merged with the default query options.query{Object}โ MongoDB-style filter. Defaults to{}(all nodes). Supports advanced operators, including the recursive$edgeoperator for graph traversal.field{string}(optional) โ Sort field.order{string}(optional) โ'asc'|'desc'. Defaults to'asc'.$limit{number}(optional) โ Limit the number of results.$after{string}(optional) โ Paginate after a specific node ID.$before{string}(optional) โ Paginate before a specific node ID.realtime{boolean}(optional) โ Explicitly enable or disable real-time mode. If acallbackis provided andrealtimeis not explicitly set tofalsein options, real-time mode is automatically enabled. Defaults tofalse.
-
callback{Function}(optional) โ If provided, enables real-time mode (unlessrealtime: falseis in options). This function is invoked with an event object for:-
Each node initially matching the query (
action: 'initial'). - Any subsequent changes (additions, updates, removals) to nodes that match the query.
-
The callback receives a single event object argument. Itโs common and recommended to destructure the properties you need directly in the functionโs signature. The most frequent and often sufficient signature is
({ id, value, action }). -
This full event object contains:
-
id{string}โ The ID of the node. -
value{Object}โ The content of the node. For the'removed'action,valuewill benull. -
edges{Array}โ An array of edges connected to the node. The developer can choose to use this data based on application needs. -
timestamp{Object}โ The nodeโs Hybrid Logical Clock (HLC) timestamp (e.g.,{ physical: number, logical: number }). For the โremovedโ action, this is the HLC of the removal event. -
action{string}โ Indicates the type of event:'initial': For existing nodes matching the query whenmapis first subscribed. This provides the initial dataset directly to the callback, often making separate handling of theresultsarray (returned bymap) unnecessary for real-time UI updates.'added': When a new node matching the query is inserted.'updated': When an existing node matching the query is modified.'removed': When a node matching the query is deleted.
-
-
If you also need
edgesortimestamp, you can easily include them in the destructuring:({ id, value, action, edges, timestamp }).
-
Each node initially matching the query (
-
-
Returns:
Promise<Object>โ A Promise that resolves to an object containing:-
results:Array<Object>โ An array of nodes that match the query at the time of the call. Each node object includesid,value,edges, andtimestamp. -
unsubscribe:Function(optional) โ If real-time mode is active, this function is provided to stop listening for updates. Calling it will remove the real-time listener.
-
Recursive Graph Traversal Queries with the $edge Operator
This is one of the most powerful features of GenosDB. The $edge operator transforms a standard query into a graph exploration tool. It uses the initial matching nodes as starting points to traverse their entire descendant tree (children, grandchildren, and so on), returning a final, flat list of all descendant nodes that match the specified criteria.
This allows you to perform complex, multi-hop graph traversals within a single, declarative query.
How It Works
A query with$edge has two logical parts:
- The Starting Point Query: The main part of the query object (
type,name, etc.) is used to find the node(s) from which the traversal will begin. - The Descendant Filter: The object provided as the value for
$edgeis a sub-query that will be applied to every single node found during the exploration of the descendant tree.
db.map() will be an array of the descendant nodes that matched the $edge sub-query, not the starting nodes.
Syntax and Example
More examples: See - MAP Guide for logical operators and pagination.
async clear()
Removes all nodes and indexes.
- Returns:
{Promise<void>}
GenosRTC API Reference
Note: All features described in this section are available only when the database is initialized with the { rtc: true } option, as this enables the GenosRTC module.
Every GDB object includes a db.room object, powered by the internal GenosRTC module, for real-time peer-to-peer communication.
The db.room object allows you to handle peer connections, send data, and stream audio/video directly between users.
Key Concepts
- Joining a Room: A room is automatically created and joined when you instantiate
GDB. The database name serves as the room identifier. - Events: Use
db.room.on(eventName, callback)to react to events. - Data Channels: Use
db.room.channel(type)to send and receive any kind of data. - Media Streams: Use
db.room.addStream(stream)to send audio or video.
Handling Peer Connections
Listen for peers joining or leaving the room.Sending & Receiving Data
Create a named channel to send and receive data like chat messages or game states.Streaming Audio & Video
Capture the userโs webcam and stream it to other peers in the room.For more details and advanced options, please refer to the complete GenosRTC API Reference documentation.
๐งช API Status: Stable Beta
The GenosDB API is currently in a stable beta. We are actively adding features and improving stability. We recommend checking the CHANGELOG as we continue to refine the API for its first stable release.
๐ก Best Practices & UI/UX Patterns
1. Embrace Top-level await for Cleaner Code
GenosDB is initialized using an Async Factory Function: await gdb(...). In modern environments like <script type="module">, you should leverage Top-level await.
This allows you to use await directly at the top level of your script, avoiding unnecessary async function wrappers and leading to simpler, more readable code.
Recommended Practice: Direct Initialization
Initialize the database and set up your listeners directly. The code flows naturally from top to bottom.
async function when it needs to be triggered by a user action that occurs after the initial page load, like a button click.
2. Use Destructuring in Callbacks for Clarity
The event object passed to yourdb.map() callback contains properties like id, value, and action. Using JavaScriptโs object destructuring directly in the function signature makes your code more readable and self-documenting.
Recommended Practice: Extract only the properties you need.
3. Always Clean Up Subscriptions to Prevent Memory Leaks
When you usedb.map() with a callback, it creates an active listener that runs until you stop it. Failing to stop the listener when itโs no longer needed (e.g., when a user navigates away) will cause memory leaks.
Recommended Practice: Always store the returned unsubscribe function and call it when the component or view is destroyed.
4. Distinguish Between Persistent State and Ephemeral Events
GenosDB offers two distinct channels for P2P communication. Using the right one is crucial for performance and building a scalable application. Ask yourself: โDoes this data need to survive a page refresh?โ1. Database Sync (for Persistent State)
If the answer is YES, use the core database methods. This is for data that represents the shared state of your application.- Use:
db.put(),db.link(),db.remove() - Examples: User profiles, document content, to-do list items.
2. Real-time Messaging with db.room (for Ephemeral Events)
If the answer is NO, use db.room. This is for high-frequency, temporary messages that do not need to be stored.
- Use:
db.room.channel(...).send() - Examples: Live cursor positions, โuser is typingโ notifications, temporary alerts.
This distinction prevents you from overloading the database with temporary data and ensures your application remains fast and efficient.
5. Code for Modernity, Clarity, and Performance
To get the most out of GenosDB, we recommend adopting a modern and efficient coding style. Prioritize ES2020+ features likeasync/await, destructuring, and optional chaining (?.) to write code that is both compact and highly readable.
Emphasize immutability and favor high-performance patterns, such as using array methods (.map, .filter) over traditional loops. This approach not only improves the maintainability and reliability.
๐ Whatโs Next? Your Journey with GenosDB
You now have the tools and best practices to build powerful, real-time, and decentralized applications. Whether youโre creating a collaborative tool, a social platform, or the next big P2P game, the reactive and simple API of GenosDB is designed to help you succeed. Weโre excited to see what youโll create. Here are some next steps to continue your journey:- ๐ Explore Practical Examples: Dive into our examples guide to see complete, working code for common use cases.
- ๐ฐ๏ธ Master Real-Time Communication: For advanced P2P features like video and audio streaming, consult the full GenosRTC API Reference.
- ๐ Report Bugs & Contribute: Your feedback is invaluable. If you find a bug or have an idea, please open an issue on GitHub. Contributions are always welcome!