npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

chain-db-ts

v1.0.0-rc.3

Published

Chain DB Client for Javascript/Typescript Node apps.

Downloads

1

Readme

Chain DB TS / JS Client (Node)

A TypeScript / JavaScript client for Chain DB, a secure database system with built-in history tracking, offering AES-256-GCM encryption, atomic operations with rollback capability, and automatic backups.

Installation

npm install chain-db-ts
# or
yarn add chain-db-ts

Usage

Connecting to Chain DB

import { connect } from 'chain-db-ts'

// Connect to Chain DB
// Parameters: server | database | user | password
// If the server parameter is null, "http://localhost:2818" will be used as default
const db = await connect({
  server: 'http://localhost:2818',
  database: 'my-database',
  user: 'root',
  password: '1234',
})

Working with Tables

Define your table structure using TypeScript interfaces:

// Define your table structure
interface GreetingTable {
  greeting: string
}

// Define a more complex table
interface UserTable {
  id: number
  name: string
  email: string
  active: boolean
  createdAt: string
}

Getting a Table

// Get a table instance
// If the table already exists in the chain, its data will be loaded. (data from the last record stored in the table)
const greetingTable = await db.getTable<GreetingTable>('greeting')

// Access the current document data (the last record stored in the table)
console.log(greetingTable.currentDoc) // e.g., { greeting: 'Hello' }

Modifying and Persisting Data

// Modify the current document data
greetingTable.currentDoc.greeting = 'Hello, Chain DB!'

// Persist changes to database (creates a new record with a new doc_id)
const result = await greetingTable.persist()

// The persist method returns the created document with its doc_id
console.log(result.doc_id) // e.g., '550e8400-e29b-41d4-a716-446655440000'

// You can also access the current document's ID directly
const currentDocId = greetingTable.getCurrentDocId()
console.log(currentDocId) // Same as result.doc_id

Updating Item

// To update a specific document, first get it by ID
const docId = '550e8400-e29b-41d4-a716-446655440000'
const specificDoc = await greetingTable.getDoc(docId)

// Then update its data
specificDoc.doc.greeting = 'Updated greeting'
await specificDoc.update()

Getting a Specific Document

// Get a specific document by its ID (assuming we know a document ID)
// The document ID is generated by ChainDB when data is persisted
const docId = '550e8400-e29b-41d4-a716-446655440000' // Example ID
const specificDoc = await greetingTable.getDoc(docId)

// Access the document data
console.log(specificDoc.doc) // e.g., { greeting: 'Hello from specific doc', doc_id: '550e8400-e29b-41d4-a716-446655440000' }

// The doc_id is also available directly in the document object
console.log(specificDoc.doc.doc_id) // '550e8400-e29b-41d4-a716-446655440000'

// Update the specific document
specificDoc.doc.greeting = 'Updated greeting for specific doc'
await specificDoc.update() // Updates only this specific document

// Refetch the document data if it might have been updated elsewhere
await specificDoc.refetch()
console.log(specificDoc.doc) // Updated data from the database

// Get the table name this document belongs to
const tableName = specificDoc.getTableName() // 'greeting'

Note: The TableDoc instance returned by getDoc() is a simplified version of a table that only allows updating the specific document. It cannot create new records with persist() or perform other table operations.

Getting Table History

// Get the last 100 changes to the table
const history = await greetingTable.getHistory(100)
console.log(history)
// Example output:
// [
//   { greeting: 'Hello, Chain DB!' },
//   { greeting: 'Hello' },
//   { greeting: 'Hi there' },
//   ...
// ]

Real-time Events with WebSockets

Chain DB supports real-time updates through WebSockets. You can subscribe to table events to get notified when data changes:

import { EventTypes, EventData } from 'chain-db-ts'

// Subscribe to table update events
db.events().subscribe(EventTypes.TABLE_UPDATE, (eventData: EventData) => {
  console.log('Table updated:', eventData.table)
  console.log('New data:', eventData.data)
})

// Subscribe to new data persistence events
db.events().subscribe(EventTypes.TABLE_PERSIST, (eventData: EventData) => {
  console.log('New data added to table:', eventData.table)
  console.log('Data:', eventData.data)
})

// Unsubscribe from an event
const myCallback = (eventData: EventData) => {
  // Handle event
}
db.events().subscribe(EventTypes.TABLE_UPDATE, myCallback)
// Later, when you want to unsubscribe:
db.events().unsubscribe(EventTypes.TABLE_UPDATE, myCallback)

// Close WebSocket connection when done
db.events().closeEvents()

The EventData object contains:

  • event_type: The type of event (TableUpdate, TablePersist)
  • database: The database name
  • table: The table name
  • data: The data associated with the event
  • timestamp: When the event occurred

Querying Data

Basic Queries

// Find items with exact matches
const users = await userTable.findWhere(
  { active: true, name: 'John' }, // criteria
  10, // limit (default: 1000)
  true // reverse order (default: true)
)

Advanced Queries

import { Operators } from 'chain-db-ts'

// Find items with advanced criteria
const users = await userTable.findWhereAdvanced(
  [
    {
      field: 'name',
      operator: Operators.CONTAINS,
      value: 'John',
    },
    {
      field: 'age',
      operator: Operators.GREATER_THAN,
      value: 25,
    },
  ],
  10, // limit
  true // reverse order
)

Available operators:

  • EQUAL (==)
  • NOT_EQUAL (!=)
  • GREATER_THAN (>)
  • GREATER_THAN_OR_EQUAL (>=)
  • LESS_THAN (<)
  • LESS_THAN_OR_EQUAL (<=)
  • CONTAINS (for strings and arrays)
  • STARTS_WITH (for strings)
  • ENDS_WITH (for strings)

Other Table Methods

// Check if a table is empty
const isEmpty = greetingTable.isEmpty()

// Get the table name
const tableName = greetingTable.getName()

// Refetch the table data from the database
await greetingTable.refetch()

Complete Example

import { connect, EventTypes, EventData } from 'chain-db-ts'

// Define table structure
interface GreetingTable {
  greeting: string
}

async function main() {
  // Connect to Chain DB
  const db = await connect({
    server: 'http://localhost:2818',
    database: 'test-db',
    user: 'root',
    password: '1234',
  })

  // Get the "greeting" table
  const greetingTable = await db.getTable<GreetingTable>('greeting')
  console.log(greetingTable.currentDoc) // e.g., { greeting: 'Hi' }

  // Subscribe to table update events
  db.events().subscribe(EventTypes.TABLE_UPDATE, (eventData: EventData) => {
    if (eventData.table === 'greeting') {
      console.log('Greeting table updated:', eventData.data)
    }
  })

  // Modify and persist data
  greetingTable.currentDoc.greeting = 'Hello my dear!'
  const persistResult = await greetingTable.persist() // Data is persisted on database

  // Get the doc_id of the newly created document
  console.log('New document ID:', persistResult.doc_id)

  // You can also get the current document ID directly from the table
  const currentDocId = greetingTable.getCurrentDocId()
  console.log('Current document ID:', currentDocId)

  // See the updated values
  console.log(greetingTable.currentDoc) // { greeting: 'Hello my dear!', doc_id: '...' }

  // Get a specific document by its ID
  // We can use the ID we just got from the persist operation
  const specificDoc = await greetingTable.getDoc(currentDocId)

  // Access the document data and ID
  console.log(specificDoc.doc) // { greeting: 'Hello my dear!', doc_id: '...' }
  console.log(specificDoc.doc.doc_id) // Same as currentDocId

  // Update a specific document
  specificDoc.doc.greeting = 'Updated specific document'
  await specificDoc.update() // Updates only this specific document

  // Refetch the document to get the latest data
  await specificDoc.refetch()
  console.log(specificDoc.doc) // Latest data from the database

  // Get the last 100 changes
  const greetingHistory = await greetingTable.getHistory(100)
  console.log(greetingHistory)
  // [
  //   { greeting: 'Updated specific document' },
  //   { greeting: 'Hello my dear!' },
  //   { greeting: 'Hi' },
  //   ...
  // ]

  // Close WebSocket connection when done
  db.events().closeEvents()
}

main().catch(console.error)

License

MIT