Building Addons
Methods for Extending Dexie
The Dexie.addons array contains functions that extend Dexie. An addon may register itself in Dexie.addons by using Dexie.addons.push(fn)
.
Example:
import Dexie from 'dexie';
export function ForEachAddon (db) {
// Makes it possible to use forEach() instead of each() on collections.
db.Collection.prototype.forEach = db.Collection.prototype.each;
}
// Register the addon to be included by default (optional)
Dexie.addons.push(ForEachAddon);
ES5:
function ForEachAddon (db) {
// Makes it possible to use forEach() instead of each() on collections.
db.Collection.prototype.forEach = db.Collection.prototype.each;
}
// Register the addon to be included by default (optional)
Dexie.addons.push(ForEachAddon);
Understanding where Dexie classes reside
Dexie classes such as Collection and Table are created in the closure scope of the Dexie constructor. To extend the prototypes you must work with an instance of Dexie. See example above.
Overriding existing methods
To override an existing method on any class, you can just change its current value to your own function. A handy function for overriding is the Dexie.override() function. Example:
db.Collection.prototype.each = Dexie.override (db.Collection.prototype.each, function (originalEach) {
return function () {
var returnValue = originalEach.apply(this, arguments);
// Do some more stuff
return returnValue;
}
});
Protected methods
The API Reference does not document the protected methods and properties of Dexie. You may however look into the code and find lots of methods and properties with a leading underscore. Your addon may then override protected methods to change the behaviour of the database engine. To see an example of this, look at how Dexie.Observable.js is implemented.
Note: We will try to keep all the not-yet-documented underscore properties and methods backward compatible as much as possible, but it’s not a guarantee. To be certain we inform you about important API changes, please let us know about your addon and where to find its source. To be even more certain, let your addon reside under your fork of Dexie.js/addons and keep us updated with pull requests.
When to use prototype and when not
All inner classes (Collection, WhereClause, Table, Transaction, etc.) use prototype for all their methods. This is because it will optimize instance creations. But the main Dexie class itself does not use prototype for now since instance creation is more rare with the main class which is typically singleton.
So to extend or override methods on the main class (Dexie), you should change the property on the given db instance that your addon retrieves as its first argument. For all other internal classes, such as Collection, WhereClause, Table, etc, all methods are prototyped, so you can override the prototype of those.
Creating Subclasses
Another way to extend Dexie is to derive from it or make your extension create new classes that derives from existing ones. For example, you could derive from Table and then override the protected method db._tableFactory() method and create your instance there.
Alternate way of doing an addon
Instead of registering into Dexie.addons, you could instead create a derived class and call it something else. Example:
import Dexie from 'dexie';
class MyDerivedDexie extends Dexie {
anotherProperty;
anotherMethod() {
// Do something here...
}
constructor (name, options) {
super(name, options);
this.anotherProperty = "other prop";
}
}
ES5:
function MyDerivedDexie (dbname, options) {
Dexie.call(this, dbname, options);
this.anotherProperty = "other prop";
this.anotherMethod = function () {
// Do something here...
};
}
To use the addon:
var db = new MyDerivedDexie("DerivedSampleDB");
alert (db.anotherProperty);
db.anotherMethod ();
Creating an AMD based addon
If you write a pure AMD based addon, you should (by convention) not register it to Dexie.addons but let the module user explicitly provide your addon as an option to the Dexie constructor.
define('Dexie.NequalAddon', ["Dexie"], function (Dexie) {
function NequalAddon (db) {
db.WhereClause.prototype.notEqualTo = function (value) {
return this.below(value).or(this._ctx.index).above(value);
};
}
return NequalAddon;
});
To use your addon:
require(['Dexie', 'Dexie.NequalAddon'], function (Dexie, DexieNequalAddon) {
var db = new Dexie('testdb', {addons: [DexieNequalAddon]});
db.version(1).stores({...});
db.open();
...
});
Table of Contents
- API Reference
- Access Control in Dexie Cloud
- Add demo users
- Add public data
- Authentication in Dexie Cloud
- Best Practices
- Building Addons
- Collection
- Collection.and()
- Collection.clone()
- Collection.count()
- Collection.delete()
- Collection.desc()
- Collection.distinct()
- Collection.each()
- Collection.eachKey()
- Collection.eachPrimaryKey()
- Collection.eachUniqueKey()
- Collection.filter()
- Collection.first()
- Collection.keys()
- Collection.last()
- Collection.limit()
- Collection.modify()
- Collection.offset()
- Collection.or()
- Collection.primaryKeys()
- Collection.raw()
- Collection.reverse()
- Collection.sortBy()
- Collection.toArray()
- Collection.uniqueKeys()
- Collection.until()
- Compound Index
- Consistency in Dexie Cloud
- Consistent add() operator
- Consistent remove() operator
- Consistent replacePrefix() operator
- Consuming Dexie as a module
- Custom Emails in Dexie Cloud
- DBCore
- DBCoreAddRequest
- DBCoreCountRequest
- DBCoreCursor
- DBCoreDeleteRangeRequest
- DBCoreDeleteRequest
- DBCoreGetManyRequest
- DBCoreGetRequest
- DBCoreIndex
- DBCoreKeyRange
- DBCoreMutateRequest
- DBCoreMutateResponse
- DBCoreOpenCursorRequest
- DBCorePutRequest
- DBCoreQuery
- DBCoreQueryRequest
- DBCoreQueryResponse
- DBCoreRangeType
- DBCoreSchema
- DBCoreTable
- DBCoreTableSchema
- DBCoreTransaction
- DBCoreTransactionMode
- DBPermissionSet
- Deprecations
- Derived Work
- Design
- Dexie Cloud API
- Dexie Cloud API Limits
- Dexie Cloud Best Practices
- Dexie Cloud CLI
- Dexie Cloud Docs
- Dexie Cloud REST API
- Dexie Cloud Web Hooks
- Dexie Constructor
- Dexie.AbortError
- Dexie.BulkError
- Dexie.ConstraintError
- Dexie.DataCloneError
- Dexie.DataError
- Dexie.DatabaseClosedError
- Dexie.IncompatiblePromiseError
- Dexie.InternalError
- Dexie.InvalidAccessError
- Dexie.InvalidArgumentError
- Dexie.InvalidStateError
- Dexie.InvalidTableError
- Dexie.MissingAPIError
- Dexie.ModifyError
- Dexie.NoSuchDatabaseErrorError
- Dexie.NotFoundError
- Dexie.Observable
- Dexie.Observable.DatabaseChange
- Dexie.OpenFailedError
- Dexie.PrematureCommitError
- Dexie.QuotaExceededError
- Dexie.ReadOnlyError
- Dexie.SchemaError
- Dexie.SubTransactionError
- Dexie.Syncable
- Dexie.Syncable.IDatabaseChange
- Dexie.Syncable.IPersistentContext
- Dexie.Syncable.ISyncProtocol
- Dexie.Syncable.StatusTexts
- Dexie.Syncable.Statuses
- Dexie.Syncable.registerSyncProtocol()
- Dexie.TimeoutError
- Dexie.TransactionInactiveError
- Dexie.UnknownError
- Dexie.UnsupportedError
- Dexie.UpgradeError()
- Dexie.VersionChangeError
- Dexie.VersionError
- Dexie.[table]
- Dexie.addons
- Dexie.async()
- Dexie.backendDB()
- Dexie.close()
- Dexie.currentTransaction
- Dexie.debug
- Dexie.deepClone()
- Dexie.defineClass()
- Dexie.delByKeyPath()
- Dexie.delete()
- Dexie.derive()
- Dexie.events()
- Dexie.exists()
- Dexie.extend()
- Dexie.fakeAutoComplete()
- Dexie.getByKeyPath()
- Dexie.getDatabaseNames()
- Dexie.hasFailed()
- Dexie.ignoreTransaction()
- Dexie.isOpen()
- Dexie.js
- Dexie.name
- Dexie.on()
- Dexie.on.blocked
- Dexie.on.close
- Dexie.on.error
- Dexie.on.populate
- Dexie.on.populate-(old-version)
- Dexie.on.ready
- Dexie.on.storagemutated
- Dexie.on.versionchange
- Dexie.open()
- Dexie.override()
- Dexie.semVer
- Dexie.setByKeyPath()
- Dexie.shallowClone()
- Dexie.spawn()
- Dexie.table()
- Dexie.tables
- Dexie.transaction()
- Dexie.transaction()-(old-version)
- Dexie.use()
- Dexie.verno
- Dexie.version
- Dexie.version()
- Dexie.vip()
- Dexie.waitFor()
- DexieCloudOptions
- DexieError
- Docs Home
- Download
- EntityTable
- Export and Import Database
- Get started with Dexie in Angular
- Get started with Dexie in React
- Get started with Dexie in Svelte
- Get started with Dexie in Vue
- Hello World
- How To Use the StorageManager API
- Inbound
- IndexSpec
- Indexable Type
- IndexedDB on Safari
- Invite
- Member
- Migrating existing DB to Dexie
- MultiEntry Index
- PersistedSyncState
- Privacy Policy
- Promise
- Promise.PSD
- Promise.catch()
- Promise.finally()
- Promise.on.error
- Promise.onuncatched
- Questions and Answers
- Realm
- Releasing Dexie
- Road Map
- Road Map: Dexie 5.0
- Road Map: Dexie Cloud
- Role
- Run Dexie Cloud on Own Servers
- Sharding and Scalability
- Simplify with yield
- Support Ukraine
- SyncState
- Table
- Table Schema
- Table.add()
- Table.bulkAdd()
- Table.bulkDelete()
- Table.bulkGet()
- Table.bulkPut()
- Table.bulkUpdate()
- Table.clear()
- Table.count()
- Table.defineClass()
- Table.delete()
- Table.each()
- Table.filter()
- Table.get()
- Table.hook('creating')
- Table.hook('deleting')
- Table.hook('reading')
- Table.hook('updating')
- Table.limit()
- Table.mapToClass()
- Table.name
- Table.offset()
- Table.orderBy()
- Table.put()
- Table.reverse()
- Table.schema
- Table.toArray()
- Table.toCollection()
- Table.update()
- Table.where()
- The main limitations of IndexedDB
- Transaction
- Transaction.abort()
- Transaction.on.abort
- Transaction.on.complete
- Transaction.on.error
- Transaction.table()
- Tutorial
- Typescript
- Typescript (old)
- Understanding the basics
- UserLogin
- Version
- Version.stores()
- Version.upgrade()
- WhereClause
- WhereClause.above()
- WhereClause.aboveOrEqual()
- WhereClause.anyOf()
- WhereClause.anyOfIgnoreCase()
- WhereClause.below()
- WhereClause.belowOrEqual()
- WhereClause.between()
- WhereClause.equals()
- WhereClause.equalsIgnoreCase()
- WhereClause.inAnyRange()
- WhereClause.noneOf()
- WhereClause.notEqual()
- WhereClause.startsWith()
- WhereClause.startsWithAnyOf()
- WhereClause.startsWithAnyOfIgnoreCase()
- WhereClause.startsWithIgnoreCase()
- db.cloud.configure()
- db.cloud.currentUser
- db.cloud.currentUserId
- db.cloud.events.syncComplete
- db.cloud.invites
- db.cloud.login()
- db.cloud.logout()
- db.cloud.options
- db.cloud.permissions()
- db.cloud.persistedSyncState
- db.cloud.roles
- db.cloud.schema
- db.cloud.sync()
- db.cloud.syncState
- db.cloud.userInteraction
- db.cloud.usingServiceWorker
- db.cloud.version
- db.cloud.webSocketStatus
- db.members
- db.realms
- db.roles
- db.syncable.connect()
- db.syncable.delete()
- db.syncable.disconnect()
- db.syncable.getOptions()
- db.syncable.getStatus()
- db.syncable.list()
- db.syncable.on('statusChanged')
- db.syncable.setFilter()
- dexie-cloud-addon
- dexie-react-hooks
- liveQuery()
- unhandledrejection-event
- useLiveQuery()
- useObservable()
- usePermissions()