Repository
A repository is a data access object that provides an abstraction over the underlying data source. BotKit provides a few built-in repositories that can be used to interact with the database, but you can also create your own repositories to interact with other data sources.
KvRepository
It is the default repository provided by BotKit. If you omit the repository option of the createBot() function, BotKit will use the KvRepository by default.
The KvRepository is a repository that stores data in a key–value store through the KvStore interface, which is provided by the Fedify. Since the KvStore interface itself also abstracts over the underlying data source, you can easily switch between different key–value stores without changing the repository implementation.
There are several KvStore implementations available in the Fedify:
RedisKvStoreRedisKvStoreis a key–value store implementation that uses Redis as the backend storage. It provides scalability and high performance, making it suitable for production use in distributed systems. It requires a Redis server setup and maintenance.NOTE
The
RedisKvStoreclass is available in the @fedify/redis package.PostgresKvStorePostgresKvStoreis a key–value store implementation that uses PostgreSQL as the backend storage. It provides scalability and high performance, making it suitable for production use in distributed systems. It requires a PostgreSQL server setup and maintenance.NOTE
The
PostgresKvStoreclass is available in the @fedify/postgres package.DenoKvStore(Deno only)DenoKvStoreis a key–value store implementation for Deno runtime that uses Deno's built-inDeno.openKv()API. It provides persistent storage and good performance for Deno environments. It's suitable for production use in Deno applications.NOTE
The
DenoKvStoreclass is available in x/deno module of the @fedify/fedify package.MemoryKvStoreA simple in-memory key–value store that doesn't persist data. It's best suited for development and testing environments where data don't have to be shared across multiple nodes. No setup is required, making it easy to get started.
TIP
Although
MemoryKvStoreis provided by Fedify, BotKit also re-exports it for convenience.
SqliteRepository
This API is available since BotKit 0.3.0.
The SqliteRepository is a repository that stores data in a SQLite database using the node:sqlite module. It provides a production-ready storage solution with excellent performance and reliability, while maintaining compatibility with both Deno and Node.js environments.
Unlike KvRepository which requires a separate key–value store setup, SqliteRepository can operate with either an in-memory database for development/testing or a file-based database for production use. It offers ACID compliance through transactions, write-ahead logging (WAL) mode for optimal performance, and proper indexing for efficient data retrieval.
In order to use SqliteRepository, you need to install the @fedify/botkit-sqlite package:
deno add jsr:@fedify/botkit-sqlitenpm add @fedify/botkit-sqlitepnpm add @fedify/botkit-sqliteyarn add @fedify/botkit-sqliteThe SqliteRepository constructor accepts an options object with the following properties:
path(optional)- Path to the SQLite database file. Defaults to
":memory:"for an in-memory database. Use a file path for persistent storage. wal(optional)- Whether to enable write-ahead logging (WAL) mode for better performance. Defaults to
truefor file-based databases. WAL mode is not applicable for in-memory databases.
MemoryRepository
The MemoryRepository is a repository that stores data in memory, which means that data is not persisted across restarts. It's best suited for development and testing environments where data don't have to be shared across multiple nodes. No setup is required, making it easy to get started.
TIP
How does it differ from using KvRepository with MemoryKvStore?—In practice, there's no difference between using MemoryRepository and KvRepository with MemoryKvStore. The only differences are that MemoryRepository is a more convenient way to use MemoryKvStore and that it's slightly more efficient because it doesn't have to go through the KvStore interface.
MemoryCachedRepository
This API is available since BotKit 0.3.0.
The MemoryCachedRepository is a repository decorator that adds an in-memory cache layer on top of another repository. This is useful for improving performance by reducing the number of accesses to the underlying persistent storage, but it increases memory usage. The cache is not persistent and will be lost when the process exits.
It takes an existing Repository instance (like KvRepository or even another MemoryCachedRepository) and wraps it. Write operations are performed on both the underlying repository and the cache. Read operations first check the cache; if the data is found, it's returned directly. Otherwise, the data is fetched from the underlying repository, stored in the cache, and then returned.
NOTE
List operations like getMessages and getFollowers, and count operations like countMessages and countFollowers are not cached due to the complexity of handling various filtering and pagination options. These operations always delegate directly to the underlying repository.
Implementing a custom repository
You can create your own repository by implementing the Repository interface. The Repository interface is a generic interface that defines the basic CRUD (create, read, update, delete) operations for data access.
The Repository interface consists of the following five domains of operations in general:
- Key pairs
Key pairs are the singleton data that are used for the bot actor. At the surface level, the key pairs are represented as
CryptoKeyPairobjects, but you would typically store them as JWK.TIP
Fedify provides
exportJwk()andimportJwk()functions to convert aCryptoKeyobject to a JWK object and vice versa.- Messages
Messages are the data of the messages that are published by the bot. Remote messages received from the remote server are not included in this domain. Each message has its own UUID and represented by either a
Createobject or anAnnounceobject (which both are provided by Fedify).You probably want to serialize the messages into JSON before storing them, so you can use
toJsonLd()method that belong to theCreateandAnnounceobjects, and usefromJsonLd()method to deserialize them.- Followers
Followers are the data of the actors that follow the bot. Each follower is represented by
Actorobject (provided by Fedify) and is associated with a follow ID, a URI of theFollowactivity.Similar to messages, you can serialize the
Actorobject into JSON using thetoJsonLd()method, and deserialize it using thefromJsonLd()method.CAUTION
The
Repository.hasFollower()method takes the URI of anActor, not the follow ID.- Sent follows
Sent follows are the data of the follow requests that the bot has sent. Each sent follow is represented by a
Followobject (provided by Fedify) and is associated with its own UUID.Similar to messages and followers, you can serialize the
Followobject into JSON using thetoJsonLd()method, and deserialize it using thefromJsonLd()method.- Followees
Followees are the data of the actors that the bot follows. Each followee is represented by a
Followobject (provided by Fedify) instead ofActor, and associated with an actor ID (not a follow ID).Similar to messages, followers, and sent follows, you can serialize the
Followobject into JSON using thetoJsonLd()method, and deserialize it using thefromJsonLd()method.