Operateable
Updated on April 7, 2026Source codeTests
Operateable is a class that enriches an IDBObjectStore, allowing it to:
- Perform database operations (add, put, get, delete, etc.) in sequence
- Track the status of those operations
- Expose any error that occurs during an operation
Construct an Operateable instance
The Operateable constructor accepts two parameters:
objectStoreIDBObjectStoreoptionsOperateable instance. No options are currently accepted.State and methods
objectStoreThe objectStore (IDBObjectStore) passed to the constructor.
If you assign a value directly to objectStore, a setter will pass the new value to setObjectStore.
statusThe status (String) of the Operateable instance.
See the Status reference section for all possible values and their meanings.
errorError encountered, populated after operateerrored.setObjectStore(objectStore)objectStore (IDBObjectStore)Operateable instanceoperate(descriptors)OperationDescriptor objects. See the Operation descriptors section for more guidance.Operateable instanceadd(descriptor)add operation against the object store.add descriptor object, i.e. an OperationDescriptor object for the add operation, omitting the operation key.Operateable instanceput(descriptor)put operation against the object store.put descriptor object, i.e. an OperationDescriptor object for the put operation, omitting the operation key.Operateable instanceget(descriptor)get operation against the object store.get descriptor object, i.e. an OperationDescriptor object for the get operation, omitting the operation key.Operateable instancegetKey(descriptor)getKey operation against the object store.getKey descriptor object, i.e. an OperationDescriptor object for the getKey operation, omitting the operation key.Operateable instancegetAll(descriptor)getAll operation against the object store.getAll descriptor object, i.e. an OperationDescriptor object for the getAll operation, omitting the operation key.Operateable instancegetAllKeys(descriptor)getAllKeys operation against the object store.getAllKeys descriptor object, i.e. an OperationDescriptor object for the getAllKeys operation, omitting the operation key.Operateable instancegetAllRecords(descriptor)getAllRecords operation against the object store.getAllRecords descriptor object, i.e. an OperationDescriptor object for the getAllRecords operation, omitting the operation key.Operateable instancedelete(descriptor)delete operation against the object store.delete descriptor object, i.e. an OperationDescriptor object for the delete operation, omitting the operation key.Operateable instanceclear(descriptor)clear operation against the object store.clear descriptor object, i.e. an OperationDescriptor object for the clear operation, omitting the operation key.Operateable instancecount(descriptor)count operation against the object store.count descriptor object, i.e. an OperationDescriptor object for the count operation, omitting the operation key.Operateable instanceopenCursor(descriptor)openCursor operation against the object store.openCursor descriptor object, i.e. an OperationDescriptor object for the openCursor operation, omitting the operation key.Operateable instanceopenKeyCursor(descriptor)openKeyCursor operation against the object store.openKeyCursor descriptor object, i.e. an OperationDescriptor object for the openKeyCursor operation, omitting the operation key.Operateable instancestop()Operateable instanceStatus reference
constructingreadyoperatingoperate() has been called and operations are in progress.operatedoperateerroredOperation descriptors
operate accepts an array of operation descriptors (objects). Each descriptor has an operation property that determines which IDBObjectStore method is called, as well as additional properties specific to that method.
Operations run sequentially: each operation waits for the previous one to succeed before starting.
For read operations, an optional effect callback receives the result of the operation.
operationaddvalue: any, key?: IDBValidKeyputvalue: any, key?: IDBValidKeygetquery: IDBValidKey | IDBKeyRange, effect?: (result: any) => voidgetKeyquery: IDBValidKey | IDBKeyRange, effect?: (result: IDBValidKey | undefined) => voidgetAllquery?: IDBValidKey | IDBKeyRange | null, count?: number, effect?: (result: any[]) => voidgetAllKeysquery?: IDBValidKey | IDBKeyRange | null, count?: number, effect?: (result: IDBValidKey[]) => voidgetAllRecordsquery?: IDBValidKey | IDBKeyRange | null, count?: number, effect?: (result: any[]) => void{ key, primaryKey, value } objects. Experimental — browser support may vary.deletequery: IDBValidKey | IDBKeyRangeclearcountquery?: IDBValidKey | IDBKeyRange, effect?: (result: number) => voidopenCursorquery?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection, effect?: (cursor: IDBCursorWithValue | null) => voidopenKeyCursorquery?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection, effect?: (cursor: IDBCursor | null) => void Using with Transactable
Operateable is designed to pair with Transactable:
const transactable = new Transactable('baleada')
transactable.open({
version: 1,
upgradeEffect: db => {
db.createObjectStore('ingredients', { keyPath: 'id' })
},
})
// Asynchronously, transactable status will change to 'opened'.
// Later in the application's lifecycle, you can run database
// transactions, like this transaction in `readwrite` mode:
transactable.readwrite(
// Pass a callback to perform side effects when the
// transaction is open:
transaction => {
// Inside of transaction effect callbacks, construct an
// Operateable instance around an object store:
const operateable = new Operateable(transaction.objectStore('ingredients'))
// Easily run sequences of database operations without
// closing the transaction:
operateable.operate([
{ operation: 'add', value: { id: 1, name: 'Tortilla' } },
{ operation: 'add', value: { id: 2, name: 'Beans' } },
{
operation: 'getAll',
effect: ingredients => {
console.log(ingredients)
},
},
])
// Or, synchronously request individual operations, which
// the browser will run independently and asynchronously:
operateable.add({ value: { id: 3, name: 'Egg' } })
operateable.openCursor({ effect: cursor => {
// Handle database cursor
}})
},
{ storeNames: ['ingredients'] }
)
Using with TypeScript
Operateable can strongly type the values you read from and write to your object store. To get this working, use the createDefineObjectStore helper function:
import { Operateable, createDefineObjectStore } from '@baleada/logic'
// Define a TypeScript type for your database, where the keys
// are store names and the indexed types are object schemas:
type MyDatabase = {
ingredients: { id?: number, name: string },
...
}
// Create your type inference helper:
const defineObjectStore = createDefineObjectStore<MyDatabase>()
// Use your type inference helper when retrieving the object
// store that you'll pass to `Operateable`:
transactable.readwrite(
transaction => {
// `ingredientsObjectStore` is now strongly typed.
// TypeScipt knows the exact shape of stored objects.
const ingredientsObjectStore = defineObjectStore(transaction, 'ingredients')
// Pass the store to `Operateable`, which will infer its type:
const operateable = new Operateable(ingredientsObjectStore)
// Now, all of Operateable's methods are type-safe:
operateable
.operate([
{
operation: 'add',
value: {
id: 1,
// Type error: `title` does not exist on this type
// (should be `name` instead)
title: 'Tortilla'
}
},
])
.openCursor({
effect: cursor => {
// Type error: `title` does not exist on this type
// (should be `name` instead)
console.log(cursor.value.title)
// `cursor.value.name` is strongly typed as `string`
console.log(cursor.value.name)
}
})
},
{ storeNames: ['ingredients'] }
)
API design compliance
options object.IDBObjectStore is passed in; no DOM access occurs during construction.objectStoresetObjectStoreset<Property> methodsstatus, erroroperate, stopstop methodable