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.