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.