Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
汪航洋 committed Jul 31, 2023
1 parent 1d3c613 commit 3a59dce
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 50 deletions.
168 changes: 122 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# 使用指南
# IDB-OPEN-PLUSH

## 简介
[![Coverage Status](https://coveralls.io/repos/github/cnwhy/idb-open-plush/badge.svg?branch=master)](https://coveralls.io/github/cnwhy/idb-open-plush?branch=master) [![github test](https://github.com/cnwhy/idb-open-plush/workflows/test/badge.svg?branch=master)](https://github.com/cnwhy/idb-open-plush/actions/workflows/test.yml)

**idbOpen** 是提供给需要使用 `indexedDB` 却被 `indexedDB version` 机制困扰的人; 它完全不需要手动处理 `version`, 至始至终都按你的需要 创建/打开/更新 对应的`IDBDatabase`;
**idb-open-plush** 是提供给需要使用 `indexedDB` 却被 `indexedDB version` 机制困扰的人; 使用它之后完全不需要再去处理 `version`, 至始至终都按你的需要 创建/打开/更新 对应的`IDBDatabase`;

## 使用方法及代码示例

### 简单 KV 库实现

```js
/* 简单kv库实现 */
import idbOpen from "idb-open";
import idbOpen from "idb-open-plush";

class IdbKV {
constructor(dbName, store) {
Expand Down Expand Up @@ -53,72 +54,94 @@ console.log(await kv1.get("key2"));

> 上面的代码,虽然两个 kv 对像用的同一个 db, 但我们不需要去处理 `db1` 这个库的更新;只是必须遵循一个原则,`IDBDatabase` 即用即取,不要缓存它;即每次要用事务时都先通过 `idbOpen()` 拿到 `IDBDatabase` , 内部是已经做好了缓存的,无需太过当心效率问题;
### 搭配`idb`库使用 代码变得更丝滑

```js
import idbOpen from "idb-open-plush";
import { openDB, wrap, unwrap } from "idb";

class IdbKV {
constructor(dbName, storeName) {
this.options = {
dbName,
store: storeName,
};
this.open = () => idbOpen(dbName, { store: storeName });
}
getDB = async () => {
const db = await this.open();
return wrap(db);
};
get = (id) => {
return this.getDB().then((db) => db.get(this.options.store, id));
};
set = (value, id) => {
return this.getDB().then((db) => db.put(this.options.store, value, id));
};
}
```

## API

```typescript
type idbOpen = (dbName: string, opeion: InitOptions) => Promise<IDBDatabase>;

export type InitOptions = {
/** 存储库名称 或者用于检测是否需要更新数据数的函数,返回 true 则不更新, 否则执行 upgradeneeded */
type idbOpen: (dbName: string, options?: InitOptions) => Promise<IDBDatabase>;

type Upgradeneeded = (
this: IDBOpenDBRequest,
db: IDBDatabase,
transaction: IDBTransaction,
event: IDBVersionChangeEvent
) => void;

type InitOptions = {
//** 存储库配置 */
store?:
| string
| { [name: string]: string }
| (( db: IDBDatabase, transaction?: IDBTransaction ) => void | Upgradeneeded);
/** 增量更新,默认开启 **/
| { [name: string]: string; }
| ((
db: IDBDatabase,
transaction?: IDBTransaction
) => void | Upgradeneeded);
incrementalUpdate?: boolean;
};
```

### 约定式

```typescript
import idbOpen from "idb-open";

function getDB(){
return idbOpen('db1', {store:'st1|++,name'}); // 只有一个ObjectStore时可以这样简写
// 等价于
return idbOpen('db1', {store:{
'st1': '++,name'
}})
}
```

### 自定义
### 约定式创建/更新 `ObjectStore`

```typescript
import idbOpen from "idb-open";

const getDB = async () => {
function getDB() {
// return idbOpen("db1", { store: "st1|++,name" }); // 只有一个ObjectStore时可以这样简写
// 等价于
return idbOpen("db1", {
store: (db)=>{
if(db.objectStoreNames.contains('ts1'));
return (db,transaction)=>{
const os = db.createObjectStore('ts1', {
autoIncrement: true,
})
// os.createIndex("name", "name", { unique: false });
}
}
store: {
st1: "++,name",
},
});
};

// 另外,约定式模式下,只有对像库名时,主键默认为 隐藏自增主键
// { store: "st1" } <==> { store: "st1|++" } <==> { store: { st1: '++'}}
}
```

> 但要注意 `store` 与返回的处理函数不能相悖, 不然可能会因为死循环报错;
#### 约定式 主键,索引规则

## 开发中
> 约定式模型参考自[dexie](https://github.com/dfahlander/Dexie.js);
### 约定式创建 `ObjectStore`
||||
|--|--|--|
|*主键约定*|
| | | |
| --- | --- | --- |
| _主键约定_ |
| ++keyPath | 自动递增主键 | |
| ++ | 隐藏的自增主键 | |
| keyPath | 非自增主键 | 需要主动提供主键 |
| *(blank)* | 隐藏的非自增主键 | 将第一个条目留空意味着主键是隐藏的,而不是自动递增的 |
|*索引约定*|
| _(blank)_ | 隐藏的非自增主键 | 将第一个条目留空意味着主键是隐藏的,而不是自动递增的 |
| _索引约定_ |
| keyPath | 普通索引 | |
| &keyPath | 唯一索引 | |
| *keyPath | Multi-valued | 表示如果key是一个数组,则每个数组值将被视为对象的键 |
| \*keyPath | Multi-valued | 表示如果 key 是一个数组,则每个数组值将被视为对象的键 |
| [keyPath1+keyPath2] | 复合索引 | |

```js
Expand All @@ -133,4 +156,57 @@ const getDB = async () => {
}
```

> 约定式模型参考自[dexie](https://github.com/dfahlander/Dexie.js);
#### 关于 `InitOptions.incrementalUpdate`

> `incrementalUpdate` 是约定模式下来控制更新规则开关,默认开启
- 开启时,更新配置不会删除存储库和索引; 适合多模块各自管理存储表的情况
- 关闭时,更新配置时会删除未配置的存储库和索引; 适合共用同一配置的情况

### 自定义创建/更新 `ObjectStore`

```typescript
import idbOpen from "idb-open";

const getDB = async () => {
return idbOpen("db1", {
store: (db) => {
// 判断是否需要更新,不需要直接返回;
if (db.objectStoreNames.contains("ts1")) return;

// 返回一个函数则表示需要更新;
return (db, transaction) => {
const os = db.createObjectStore("ts1", {
autoIncrement: true,
});
};
},
});
};

const getDB1 = async () => {
return idbOpen("db1", {
store: (db) => {
// 一个判断一个更新方法,适合迭代

if (!db.objectStoreNames.contains("ts1")) {
return (db, transaction) => {
const os = db.createObjectStore("ts1", {
autoIncrement: true,
});
};
}

if (!db.objectStoreNames.contains("ts2")) {
return (db, transaction) => {
const os = db.createObjectStore("ts2", {
autoIncrement: true,
});
};
}
},
});
};
```

> 注意 `store` 与返回的处理函数不能相悖, 不然可能会因为死循环报错;
8 changes: 4 additions & 4 deletions demo/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ window.idbOpen = idbOpen;
/**
* 实现给我和简单人kv库
*/
class OsCmd {
class IdbKV {
constructor(dbName, storeName) {
this.options = {
dbName,
Expand Down Expand Up @@ -43,7 +43,7 @@ class OsCmd {
/**
* 搭配 idb 库使用变得更丝滑
*/
class OsCmd1 {
class IdbKV1 {
constructor(dbName, storeName) {
this.options = {
dbName,
Expand Down Expand Up @@ -101,8 +101,8 @@ class IndexOsCmd1 extends IndexOsCmd {

async function demo1() {
await idbDelete("db1");
const cmd1 = new OsCmd("db1", "os1");
const cmd2 = new OsCmd1("db1", "os2");
const cmd1 = new IdbKV("db1", "os1");
const cmd2 = new IdbKV1("db1", "os2");
Promise.all([cmd1.get("key"), cmd2.get("key")]).then(console.log);
cmd1.set(["cmd1"], "key");
cmd2.set(["cmd2"], "key");
Expand Down

0 comments on commit 3a59dce

Please sign in to comment.