Building Adapters

Create custom adapters to integrate YAKMESH with any database, API, or platform.

What is an Adapter?

Adapters are plugins that connect YAKMESH to external systems. They implement a standard interface for fetching changes, applying updates, and synchronizing data across the mesh network.

BaseAdapter Interface

All adapters extend the BaseAdapter class:

import { BaseAdapter } from '@yakmesh/core/adapters';

class MyAdapter extends BaseAdapter {
  constructor(config) {
    super('my-adapter', '1.0.0');
    this.config = config;
  }

  async init() {
    // Initialize connection to your system
    this.db = await connectToDatabase(this.config.connectionString);
  }

  getSchema() {
    // Define what data this adapter manages
    return {
      tables: ['users', 'posts'],
      primaryKeys: { users: 'id', posts: 'id' }
    };
  }

  async fetchChanges(since) {
    // Return changes since the given timestamp
    return await this.db.query(
      'SELECT * FROM changes WHERE updated_at > ?',
      [since]
    );
  }

  async applyChange(change) {
    // Apply a change received from the mesh
    await this.db.query(
      'INSERT OR REPLACE INTO ?? SET ?',
      [change.table, change.data]
    );
  }

  async validate(data) {
    // Validate data before applying
    return { valid: true };
  }
}

Required Methods

init()

Called once when the adapter is loaded. Initialize connections here.

getSchema()

Returns the data schema this adapter manages.

fetchChanges(since)

Returns all changes since the given timestamp for sync.

applyChange(change)

Applies a change received from another node.

validate(data)

Validates data before applying. Return { valid: true } or { valid: false, error: '...' }.

Registering Your Adapter

import { YAKMESHNode } from '@yakmesh/core';
import { MyAdapter } from './my-adapter.js';

const node = new YAKMESHNode();

// Register the adapter
node.registerAdapter(new MyAdapter({
  connectionString: 'postgres://localhost/mydb'
}));

// Start the node
await node.start();

Example: SQLite Adapter

import { BaseAdapter } from '@yakmesh/core/adapters';
import initSqlJs from 'sql.js';

class SQLiteAdapter extends BaseAdapter {
  constructor(dbPath) {
    super('sqlite', '1.0.0');
    this.dbPath = dbPath;
  }

  async init() {
    const SQL = await initSqlJs();
    const data = fs.readFileSync(this.dbPath);
    this.db = new SQL.Database(data);
  }

  getSchema() {
    const tables = this.db.exec(
      "SELECT name FROM sqlite_master WHERE type='table'"
    );
    return { tables: tables[0].values.flat() };
  }

  async fetchChanges(since) {
    // Implementation depends on your change tracking strategy
  }

  async applyChange(change) {
    this.db.run(change.sql, change.params);
  }
}

Pro Tip

Use the this.emit() method inherited from BaseAdapter to emit events that the mesh can react to, like 'change', 'error', or custom events.

Content Adapters v3.0

Content Adapters serve documents via DARSHAN streaming with optional chat integration. They implement a capability-based security model.

ContentAdapter Interface

import { ContentAdapter, CONTENT_CAPABILITIES } from '@yakmesh/adapters/content-adapter';

class MyContentAdapter extends ContentAdapter {
  constructor(config) {
    super({
      name: 'My Content Source',
      id: 'my-content',
      capabilities: [
        CONTENT_CAPABILITIES.SERVE_PDF,
        CONTENT_CAPABILITIES.SEARCH_REFERENCE,
        CONTENT_CAPABILITIES.CHAT_QUOTE,
      ],
      ...config,
    });
  }

  async lookupReference(reference) {
    // Parse and look up the reference
    return { reference, text: 'Content here...', found: true };
  }

  async getContentStream(contentId) {
    // Return a stream for DARSHAN's view-not-copy paradigm
    return fs.createReadStream(this.getContentPath(contentId));
  }
}

Capabilities

Capability Description
SERVE_PDF Serve PDF documents via DARSHAN
SERVE_TEXT Serve plain text content
SEARCH_REFERENCE Support looking up by reference
CHAT_QUOTE Generate quote cards for KATHA chat
STREAM_NETWORK Stream content over the mesh

Chat Mod Adapters v3.0

Chat Mod Adapters extend KATHA chat with slash commands and interactive features. They include security measures to prevent abuse.

ChatModAdapter Interface

import { ChatModAdapter, ChatModManifest, CHAT_MOD_CAPABILITIES } from '@yakmesh/adapters/chat-mod-adapter';

class MyChatMod extends ChatModAdapter {
  constructor() {
    super(new ChatModManifest({
      id: 'my-chat-mod',
      version: '1.0.0',
      capabilities: [
        CHAT_MOD_CAPABILITIES.CMD_SLASH,
        CHAT_MOD_CAPABILITIES.GEN_QUOTE,
      ],
      commands: ['/mycommand', '/help'],
      rateLimit: { maxPerMinute: 30 },
    }));
  }

  async handleCommand(command, args, context) {
    if (command === '/mycommand') {
      return this._signResponse({
        type: 'text',
        content: 'Hello from my adapter!',
      });
    }
  }
}

Security Features

Capability Declaration

Adapters must declare what they can do upfront. Undeclared capabilities are blocked.

Rate Limiting

Default 30 messages per minute per user. Configurable per adapter.

Response Signing

All responses include adapter ID, version, and manifest hash for verification.

Context Sanitization

Adapters only receive context data matching their declared capabilities.

Example: MLV Bible Adapter

The MLV Bible Adapter demonstrates content + chat integration for scripture distribution. It serves the Modern Literal Version Bible via DARSHAN and adds /bible, /verse commands to KATHA.

import { MLVBibleAdapter } from '@yakmesh/adapters/adapter-mlv-bible';

// Create and initialize
const mlv = new MLVBibleAdapter({
  contentPath: './mlv-content',
});
await mlv.init();

// Register with DARSHAN for P2P streaming
await mlv.registerWithDarshan(darshan);

// Register with KATHA for chat commands
mlv.registerWithKatha(katha, chatModRegistry);

// Now users can:
// - Stream MLV PDFs via DARSHAN (view-not-copy)
// - Use /bible John 3:16 in chat
// - Use /verse Gen 1:1-5 for passage lookups

Anti-Censorship Philosophy

Content adapters embody Yakmesh's core principle: no central authority can block your content.

The MLV Bible Adapter is a template for creating adapters for any belief system or documents. Each user hosts their own content—peer-to-peer, cryptographically verified, censorship-resistant.