Dexie.js

IndexedDB 的一个最小化包装。(A Minimalistic Wrapper for IndexedDB. )

Github stars Tracking Chart

Dexie.js 是 indexedDB 的包装库 -- 浏览器中的标准数据库。

为什么?

Dexie使用本机IndexedDB API解决了三个主要问题:

  • 模棱两可的错误处理
  • 不好查询
  • 代码复杂性

Dexie 提供了一个简洁的数据库API,它具有经过深思熟虑的 API 设计、健壮的错误处理、可扩展性、更改跟踪意识和扩展的 KeyRange 支持(不区分大小写的搜索、设置匹配和或操作)。

特性
  • 容易学习 -- Dexie写得直截了当,容易学习。 如果您曾经使用过本机IndexedDB,那么您一定会感谢Dexie简洁的API。
  • 记录好 -- 没有很好的文档,任何开发工具有什么好处? Dexie已经彻底解释,并提供了一些例子来帮助您。
  • 高性能 -- Dexie具有近乎原生的表现。 它的大量操作在indexedDB中使用了很少使用的功能 -- 可能时忽略成功回调。

Hello World

<!doctype html>
<html>
 <head>
  <script src="https://unpkg.com/dexie@latest/dist/dexie.js"></script>
  <script>
   //
   // Declare Database
   //
   var db = new Dexie("FriendDatabase");
   db.version(1).stores({
     friends: "++id,name,age"
   });

   //
   // Manipulate and Query Database
   //
   db.friends.add({name: "Josephine", age: 21}).then(function() {
       return db.friends.where("age").below(25).toArray();
   }).then(function (youngFriends) {
       alert ("My young friends: " + JSON.stringify(youngFriends));
   }).catch(function (e) {
       alert ("Error: " + (e.stack || e));
   });
  </script>
 </head>
</html>

是的,就是这么简单。

教程

API 参考

示例

性能

Dexie表现出色。 它的批量方法利用了IndexedDB中一个鲜为人知的特性,可以在不收听每个onsuccess事件的情况下存储东西。 这样可以最大限度地提高性能。

支持的操作
above(key): Collection;
aboveOrEqual(key): Collection;
add(item, key?): Promise;
and(filter: (x) => boolean): Collection;
anyOf(keys[]): Collection;
anyOfIgnoreCase(keys: string[]): Collection;
below(key): Collection;
belowOrEqual(key): Collection;
between(lower, upper, includeLower?, includeUpper?): Collection;
bulkAdd(items: Array): Promise;
bulkDelete(keys: Array): Promise;
bulkPut(items: Array): Promise;
clear(): Promise;
count(): Promise;
delete(key): Promise;
distinct(): Collection;
each(callback: (obj) => any): Promise;
eachKey(callback: (key) => any): Promise;
eachPrimaryKey(callback: (key) => any): Promise;
eachUniqueKey(callback: (key) => any): Promise;
equals(key): Collection;
equalsIgnoreCase(key): Collection;
filter(fn: (obj) => boolean): Collection;
first(): Promise;
get(key): Promise;
inAnyRange(ranges): Collection;
keys(): Promise;
last(): Promise;
limit(n: number): Collection;
modify(changeCallback: (obj: T, ctx:{value: T}) => void): Promise;
modify(changes: { [keyPath: string]: any } ): Promise;
noneOf(keys: Array): Collection;
notEqual(key): Collection;
offset(n: number): Collection;
or(indexOrPrimayKey: string): WhereClause;
orderBy(index: string): Collection;
primaryKeys(): Promise;
put(item: T, key?: Key): Promise;
reverse(): Collection;
sortBy(keyPath: string): Promise;
startsWith(key: string): Collection;
startsWithAnyOf(prefixes: string[]): Collection;
startsWithAnyOfIgnoreCase(prefixes: string[]): Collection;
startsWithIgnoreCase(key: string): Collection;
toArray(): Promise;
toCollection(): Collection;
uniqueKeys(): Promise;
until(filter: (value) => boolean, includeStopEntry?: boolean): Collection;
update(key: Key, changes: { [keyPath: string]: any }): Promise;

这是WhereClauseTableCollection 的混合方法。 深入了解 API参考 以查看详细信息。

Overview

Name With Ownerdexie/Dexie.js
Primary LanguageJavaScript
Program languageHTML (Language Count: 4)
PlatformWeb browsers
License:Apache License 2.0
Release Count149
Last Release Namev4.0.4 (Posted on 2024-04-10 18:49:30)
First Release Namev1.0 (Posted on )
Created At2014-02-26 08:16:16
Pushed At2024-05-04 21:28:08
Last Commit At2024-05-04 00:59:40
Stargazers Count10.8k
Watchers Count107
Fork Count620
Commits Count2.5k
Has Issues Enabled
Issues Count1390
Issue Open Count530
Pull Requests Count427
Pull Requests Open Count4
Pull Requests Close Count80
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private

Dexie.js

NPM Version Build StatusTested with Browserstack

Dexie.js is a wrapper library for indexedDB - the standard database in the browser. http://dexie.org

Why?

Dexie solves three main issues with the native IndexedDB API:

  1. Ambiguous error handling
  2. Poor queries
  3. Code complexity

Dexie provides a neat database API with a well thought-through API design, robust error handling, extendability, change tracking awareness and extended KeyRange support (case insensitive search, set matches and OR operations).

Hello World

<!doctype html>
<html>
 <head>
  <script src="https://unpkg.com/dexie@latest/dist/dexie.js"></script>
  <script>
   //
   // Declare Database
   //
   var db = new Dexie("FriendDatabase");
   db.version(1).stores({
     friends: "++id,name,age"
   });

   //
   // Manipulate and Query Database
   //
   db.friends.add({name: "Josephine", age: 21}).then(function() {
       return db.friends.where("age").below(25).toArray();
   }).then(function (youngFriends) {
       alert ("My young friends: " + JSON.stringify(youngFriends));
   }).catch(function (e) {
       alert ("Error: " + (e.stack, e));
   });
  </script>
 </head>
</html>

Yes, it's that simple.

Tutorial

API Reference

Samples

Performance

Dexie has kick-ass performance. Its bulk methods take advantage of a lesser-known feature in IndexedDB that makes it possible to store stuff without listening to every onsuccess event. This speeds up the performance to a maximum.

Supported operations

above(key): Collection;
aboveOrEqual(key): Collection;
add(item, key?): Promise;
and(filter: (x) => boolean): Collection;
anyOf(keys[]): Collection;
anyOfIgnoreCase(keys: string[]): Collection;
below(key): Collection;
belowOrEqual(key): Collection;
between(lower, upper, includeLower?, includeUpper?): Collection;
bulkAdd(items: Array): Promise;
bulkDelete(keys: Array): Promise;
bulkPut(items: Array): Promise;
clear(): Promise;
count(): Promise;
delete(key): Promise;
distinct(): Collection;
each(callback: (obj) => any): Promise;
eachKey(callback: (key) => any): Promise;
eachPrimaryKey(callback: (key) => any): Promise;
eachUniqueKey(callback: (key) => any): Promise;
equals(key): Collection;
equalsIgnoreCase(key): Collection;
filter(fn: (obj) => boolean): Collection;
first(): Promise;
get(key): Promise;
inAnyRange(ranges): Collection;
keys(): Promise;
last(): Promise;
limit(n: number): Collection;
modify(changeCallback: (obj: T, ctx:{value: T}) => void): Promise;
modify(changes: { [keyPath: string]: any } ): Promise;
noneOf(keys: Array): Collection;
notEqual(key): Collection;
offset(n: number): Collection;
or(indexOrPrimayKey: string): WhereClause;
orderBy(index: string): Collection;
primaryKeys(): Promise;
put(item: T, key?: Key): Promise;
reverse(): Collection;
sortBy(keyPath: string): Promise;
startsWith(key: string): Collection;
startsWithAnyOf(prefixes: string[]): Collection;
startsWithAnyOfIgnoreCase(prefixes: string[]): Collection;
startsWithIgnoreCase(key: string): Collection;
toArray(): Promise;
toCollection(): Collection;
uniqueKeys(): Promise;
until(filter: (value) => boolean, includeStopEntry?: boolean): Collection;
update(key: Key, changes: { [keyPath: string]: any }): Promise;

This is a mix of methods from WhereClause, Table and Collection. Dive into the API reference to see the details.

Hello World (ES2016 / ES7)

import Dexie from 'dexie';

//
// Declare Database
//
const db = new Dexie("FriendDatabase");
db.version(1).stores({ friends: "++id,name,age" });

db.transaction('rw', db.friends, async() => {

    // Make sure we have something in DB:
    if ((await db.friends.where({name: 'Josephine'}).count()) === 0) {
        const id = await db.friends.add({name: "Josephine", age: 21});
        alert (`Addded friend with id ${id}`);
    }

    // Query:
    const youngFriends = await db.friends.where("age").below(25).toArray();

    // Show result:
    alert ("My young friends: " + JSON.stringify(youngFriends));

}).catch(e => {
    alert(e.stack, e);
});

Hello World (Typescript)

import Dexie from 'dexie';

interface Friend {
    id?: number;
    name?: string;
    age?: number;
}

//
// Declare Database
//
class FriendDatabase extends Dexie {
    public friends: Dexie.Table<Friend, number>; // id is number in this case

    public constructor() {
        super("FriendDatabase");
        this.version(1).stores({
            friends: "++id,name,age"
        });
        this.friends = this.table("friends");
    }
}

const db = new FriendDatabase();

db.transaction('rw', db.friends, async() => {

    // Make sure we have something in DB:
    if ((await db.friends.where({name: 'Josephine'}).count()) === 0) {
        const id = await db.friends.add({name: "Josephine", age: 21});
        alert (`Addded friend with id ${id}`);
    }

    // Query:
    const youngFriends = await db.friends.where("age").below(25).toArray();

    // Show result:
    alert ("My young friends: " + JSON.stringify(youngFriends));

}).catch(e => {
    alert(e.stack, e);
});

Samples

http://dexie.org/docs/Samples

https://github.com/dfahlander/Dexie.js/tree/master/samples

Knowledge Base

http://dexie.org/docs/Questions-and-Answers

Website

http://dexie.org

Install over npm

npm install dexie

Download

For those who don't like package managers, here's the download links:

https://unpkg.com/dexie@latest/dist/dexie.js

https://unpkg.com/dexie@latest/dist/dexie.js.map

https://unpkg.com/dexie@latest/dist/dexie.d.ts

Contributing

Here is a little cheat-sheet for how to symlink your app's node_modules/dexie to a place where you can edit the source, version control your changes and create pull requests back to Dexie. Assuming you've already ran npm install dexie --save for the app your are developing.

  1. Fork Dexie.js from the web gui on github

  2. Clone your fork locally by launching a shell/command window and cd to a neutral place (like ~repos/, c:\repos or whatever)

  3. Run the following commands:

    git clone https://github.com/YOUR-USERNAME/Dexie.js.git dexie
    cd dexie
    npm install
    npm run build
    npm link
    
  4. cd to your app directory and write:

    npm link dexie
    

Your app's node_modules/dexie/ is now sym-linked to the Dexie.js clone on your hard drive so any change you do there will propagate to your app. Build dexie.js using npm run build or npm run watch. The latter will react on any source file change and rebuild the dist files.

That's it. Now you're up and running to test and commit changes to files under dexie/src/* or dexie/test/* and the changes will instantly affect the app you are developing.

Pull requests are more than welcome. Some advices are:

  • Run npm test before making a pull request.
  • If you find an issue, a unit test that reproduces it is lovely ;). If you don't know where to put it, put it in test/tests-misc.js. We use qunit. Just look at existing tests in tests-misc.js to see how they should be written. Tests are transpiled in the build script so you can use ES6 if you like.

Build

npm install
npm run build

Test

npm test

Watch

npm run watch
To the top