LogoRobo.js

Adapters

Configure storage backends — filesystem, Keyv, or custom adapters.

Flashcore uses the local filesystem by default but supports pluggable adapters for any storage backend.

Built-in Adapters

FileAdapter (Default)

Stores data as JSON files in .robo/flashcore/. This is the default adapter with no configuration needed.

import { FileAdapter } from 'robo.js/flashcore'

const adapter = new FileAdapter({
	baseDir: '.robo/flashcore' // default
})
import { FileAdapter } from 'robo.js/flashcore'

const adapter = new FileAdapter({
	baseDir: '.robo/flashcore' // default
})

Supports: scan, setIfNotExists.

LegacyFileAdapter

Compatible with the pre-v0.11 .robo/data/ format. Used internally by the migration adapter for backward compatibility.

KeyvAdapter

Wraps any Keyv instance, giving you access to dozens of storage backends.

Configuration

Robo Config

Set the adapter in your Robo configuration:

config/robo.mjs
import { FileAdapter } from 'robo.js/flashcore'

export default {
	flashcore: {
		adapter: new FileAdapter({ baseDir: '.data/flashcore' })
	}
}
config/robo.mjs
import { FileAdapter } from 'robo.js/flashcore'

export default {
	flashcore: {
		adapter: new FileAdapter({ baseDir: '.data/flashcore' })
	}
}

Keyv Adapters

Use the flashcore.keyv config to connect to external databases:

config/robo.mjs
import KeyvRedis from '@keyv/redis'

export default {
	flashcore: {
		keyv: {
			store: new KeyvRedis('redis://localhost:6379')
		}
	}
}
config/robo.mjs
import KeyvRedis from '@keyv/redis'

export default {
	flashcore: {
		keyv: {
			store: new KeyvRedis('redis://localhost:6379')
		}
	}
}

Other popular adapters:

// SQLite
import KeyvSqlite from '@keyv/sqlite'
store: new KeyvSqlite('sqlite://robo.db')

// PostgreSQL
import KeyvPostgres from '@keyv/postgres'
store: new KeyvPostgres('postgresql://user:pass@localhost:5432/mydb')

// MongoDB
import KeyvMongo from '@keyv/mongo'
store: new KeyvMongo('mongodb://localhost:27017/mydb')

See the Keyv documentation for the full list of available storage adapters.

Programmatic Init

Initialize Flashcore manually with a custom adapter:

import { Flashcore } from 'robo.js'

await Flashcore.$.init({
	adapter: myCustomAdapter
})
import { Flashcore } from 'robo.js'

await Flashcore.$.init({
	adapter: myCustomAdapter
})

Adapter Capabilities

Not all adapters support the same features. Flashcore detects capabilities at initialization and gates features accordingly:

CapabilityDescriptionRequired For
scanList keys by prefixWAL recovery, integrity checks
setIfNotExistsAtomic create-if-absentRace-free unique constraints
compareAndSwapAtomic read-modify-writeOptimistic concurrency
atomicBatchMulti-key atomic writesBulk operations
transactionNative transaction supportFull ACID transactions

The built-in FileAdapter supports scan, setIfNotExists, and compareAndSwap. For full ACID transaction support, use a Keyv adapter backed by a database that supports transactions (like PostgreSQL).

If an adapter lacks a required capability, Flashcore throws a FeatureNotSupportedError when the unsupported operation is attempted.

Custom Adapters

Implement the FlashcoreAdapter interface to create your own adapter:

import type { FlashcoreAdapter } from 'robo.js/flashcore'

export class MyAdapter implements FlashcoreAdapter {
	readonly name = 'MyAdapter'

	async get(key: string): Promise<unknown> {
		// Read from your storage
	}

	async set(key: string, value: unknown): Promise<boolean> {
		// Write to your storage
		return true
	}

	async delete(key: string): Promise<boolean> {
		// Delete from your storage
		return true
	}

	async has(key: string): Promise<boolean> {
		// Check existence
		return false
	}

	async clear(): Promise<void> {
		// Clear all data
	}

	// Optional methods for advanced capabilities:
	// async scan(prefix: string): Promise<string[]> { ... }
	// async setIfNotExists(key: string, value: unknown): Promise<boolean> { ... }
	// async compareAndSwap(key: string, expected: unknown, value: unknown): Promise<boolean> { ... }
	// async atomicBatch(ops: BatchOperation[]): Promise<void> { ... }

	// Optional: self-report capabilities
	// capabilities() { return { isolation: 'serializable' } }
}
export class MyAdapter {
	name = 'MyAdapter'

	async get(key) {
		// Read from your storage
	}

	async set(key, value) {
		// Write to your storage
		return true
	}

	async delete(key) {
		// Delete from your storage
		return true
	}

	async has(key) {
		// Check existence
		return false
	}

	async clear() {
		// Clear all data
	}
}

Adapter Wrappers

For production deployments, @robojs/flashcore-extras provides adapter wrappers that add caching, compression, encryption, and retry logic to any adapter. See Adapter Wrappers for details.

On this page