From d88f94c76fc1c4130cbe2c67644134fff8a85334 Mon Sep 17 00:00:00 2001 From: petamoriken Date: Wed, 11 Apr 2018 08:31:42 +0900 Subject: [PATCH 1/5] Update API for v0.1.0 Rename getAndDelete to take Change getAll, deleteAll, takeAll arguments Append count method --- .eslintrc.js | 9 ++--- index.d.ts | 62 +++++++++++++++++++---------- src/index.js | 107 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 111 insertions(+), 67 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 0e943c8..fa56c84 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,7 +2,7 @@ module.exports = { // To give you an idea how to override rule options: parser: "babel-eslint", parserOptions: { - sourceType: "module" + sourceType: "module", }, extends: ["eslint:recommended"], env: { @@ -11,11 +11,8 @@ module.exports = { }, rules: { "quotes": [2, "double", "avoid-escape"], - "no-console": [0], + "semi": [2], "no-unused-vars": [1, {"vars": "all", "args": "after-used"}], "no-return-await": [1], - "eol-last": [0], - "no-mixed-requires": [0], - "no-underscore-dangle": [0] } -}; \ No newline at end of file +}; diff --git a/index.d.ts b/index.d.ts index 30e4852..9557d23 100644 --- a/index.d.ts +++ b/index.d.ts @@ -11,24 +11,30 @@ export interface SimpleIDBKeyAndValue { value: any, } +export interface SimpleIDBQueryOptions { + query?: SimpleIDBQuery, + count?: number, + direction?: SimpleIDBCursorDirection, +} + export declare class SimpleIDB { constructor(name: string, version: number, onupgradeneeded: (this: IDBOpenDBRequest, event: IDBVersionChangeEvent) => any); /** - * IndexedDB を開き、成功したら自身を返す + * IndexedDB を開き, 成功したら自身を返す */ ready(): Promise; /** - * ObjectStore に値を追加する。追加された key を返す + * ObjectStore に値を追加する. 追加された key を返す * @param storeName ObjectStore の名前 * @param value 追加する値 - * @param key 追加する値のキー。ObjectStore が autoIncrement の場合は省略可能 + * @param key 追加する値のキー. ObjectStore が autoIncrement の場合は省略可能 */ add(storeName: string, value: any, key?: SimpleIDBInputKey): Promise; /** - * ObjectStore の値を追加もしくは更新する。追加もしくは更新された key を返す + * ObjectStore の値を追加もしくは更新する. 追加もしくは更新された key を返す * @param storeName ObjectStore の名前 * @param value 追加もしくは更新する値 * @param key 追加もしくは更新する値のキー @@ -50,38 +56,52 @@ export declare class SimpleIDB { delete(storeName: string, key: SimpleIDBInputKey): Promise; /** - * ObjectStore の値を取得し、同時に削除する + * ObjectStore の値を取得し, 同時に削除する * @param storeName ObjectStore の名前 - * @param key 取得、削除する値のキー + * @param key 取得, 削除する値のキー */ - getAndDelete(storeName: string, key: SimpleIDBInputKey): Promise; + take(storeName: string, key: SimpleIDBInputKey): Promise; /** * ObjectStore の値を複数取得する * @param storeName ObjectStore の名前 - * @param query 取得する際のクエリ。null の場合全件取得する - * @param count 取得する値の個数の上限値 - * @param direction 昇順、降順 + * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得する + * @param options 取得する際のオプション + * @param options.query 取得する際のクエリ + * @param options.count 取得する値の個数の上限値 + * @param options.direction 昇順, 降順 */ - getAll(storeName: string, query?: SimpleIDBQuery, count?: number, direction?: SimpleIDBCursorDirection): Promise; + getAll(storeName: string, indexName?: string | null, options?: SimpleIDBQueryOptions): Promise; /** * ObjectStore の値を複数削除する * @param storeName ObjectStore の名前 - * @param query 削除する際のクエリ。null の場合全件を表す - * @param count 削除する値の個数の上限値 - * @param direction 昇順、降順 + * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から削除する + * @param options 削除する際のオプション + * @param options.query 削除する際のクエリ + * @param options.count 削除する値の個数の上限値 + * @param options.direction 昇順, 降順 + */ + deleteAll(storeName: string, indexName?: string | null, options?: SimpleIDBQueryOptions): Promise; + + /** + * ObjectStore の値を複数取得し, 同時に削除する + * @param storeName ObjectStore の名前 + * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得, 削除する + * @param options 取得, 削除する際のオプション + * @param options.query 取得, 削除する際のクエリ + * @param options.count 取得, 削除する値の個数の上限値 + * @param options.direction 昇順, 降順 */ - deleteAll(storeName: string, query?: SimpleIDBQuery, count?: number, direction?: SimpleIDBCursorDirection): Promise; + takeAll(storeName: string, indexName?: string | null, options?: SimpleIDBQueryOptions): Promise; /** - * ObjectStore の値を複数取得し、同時に削除する + * ObjectStore の値数を数える * @param storeName ObjectStore の名前 - * @param query 取得、削除する際のクエリ。null の場合全件を表す - * @param count 取得、削除する値の個数の上限値 - * @param direction 昇順、降順 + * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得する + * @param query 取得する際のクエリ */ - getAndDeleteAll(storeName: string, query?: SimpleIDBQuery, count?: number, direction?: SimpleIDBCursorDirection): Promise; + count(storeName: string, indexName?: string | null, query?: SimpleIDBQuery); /** * ObjectStore の値を全件削除する @@ -90,7 +110,7 @@ export declare class SimpleIDB { clear(storeName: string): Promise; /** - * ObjectStore を直接入手する。複雑なクエリを使う必要がある時に用いる + * ObjectStore を直接入手する. 複雑なクエリを使う必要がある時に用いる * @param storeNames ObjectStore の名前の配列 * @param mode IDBTransaction のモード * @param oncomplete IDBTransaction が完了したときに呼ばれる callback diff --git a/src/index.js b/src/index.js index 61669f2..a1705e2 100644 --- a/src/index.js +++ b/src/index.js @@ -22,7 +22,7 @@ export class SimpleIDB { } /** - * IndexedDB を開き、成功したら自身を返す + * IndexedDB を開き, 成功したら自身を返す */ ready() { if (this._ready === null && this._readyData !== null) { @@ -45,10 +45,10 @@ export class SimpleIDB { } /** - * ObjectStore に値を追加する。追加された key を返す + * ObjectStore に値を追加する. 追加された key を返す * @param storeName ObjectStore の名前 * @param value 追加する値 - * @param key 追加する値のキー。ObjectStore が autoIncrement の場合は省略可能 + * @param key 追加する値のキー. ObjectStore が autoIncrement の場合は省略可能 */ add(storeName, value, key = undefined) { return new Promise((resolve, reject) => { @@ -60,7 +60,7 @@ export class SimpleIDB { } /** - * ObjectStore の値を追加もしくは更新する。追加もしくは更新された key を返す + * ObjectStore の値を追加もしくは更新する. 追加もしくは更新された key を返す * @param storeName ObjectStore の名前 * @param value 追加もしくは更新する値 * @param key 追加もしくは更新する値のキー @@ -102,11 +102,11 @@ export class SimpleIDB { } /** - * ObjectStore の値を取得し、同時に削除する + * ObjectStore の値を取得し, 同時に削除する * @param storeName ObjectStore の名前 - * @param key 取得、削除する値のキー + * @param key 取得, 削除する値のキー */ - getAndDelete(storeName, key) { + take(storeName, key) { return new Promise((resolve, reject) => { let value = null; const store = this.getObjectStore(storeName, "readwrite", () => resolve(value), reject); @@ -120,86 +120,113 @@ export class SimpleIDB { /** * ObjectStore の値を複数取得する * @param storeName ObjectStore の名前 - * @param query 取得する際のクエリ。null の場合全件取得する - * @param count 取得する値の個数の上限値 - * @param direction 昇順、降順 + * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得する + * @param options 取得する際のオプション + * @param options.query 取得する際のクエリ + * @param options.count 取得する値の個数の上限値 + * @param options.direction 昇順, 降順 */ - getAll(storeName, query = null, count = Infinity, direction = "next") { + getAll(storeName, indexName = null, {query = null, count = Infinity, direction = "next"} = {}) { return new Promise((resolve, reject) => { const ret = []; const store = this.getObjectStore(storeName, "readonly", () => resolve(ret), reject); + const index = indexName !== null ? store.index(indexName) : null; - let index = 0; - store.openCursor(query, direction).onsuccess = (event) => { + let i = 0; + (index || store).openCursor(query, direction).onsuccess = (event) => { const cursor = event.target.result; if (cursor == null) { return; } ret.push({ key: cursor.key, value: cursor.value }); - if (index < count) { - ++index; + if (i < count) { + ++i; cursor.continue(); } - } + }; }); } /** * ObjectStore の値を複数削除する * @param storeName ObjectStore の名前 - * @param query 削除する際のクエリ。null の場合全件を表す - * @param count 削除する値の個数の上限値 - * @param direction 昇順、降順 + * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から削除する + * @param options 削除する際のオプション + * @param options.query 削除する際のクエリ + * @param options.count 削除する値の個数の上限値 + * @param options.direction 昇順, 降順 */ - deleteAll(storeName, query = null, count = Infinity, direction = "next") { + deleteAll(storeName, indexName = null, {query = null, count = Infinity, direction = "next"} = {}) { return new Promise((resolve, reject) => { const store = this.getObjectStore(storeName, "readwrite", resolve, reject); + const index = indexName !== null ? store.index(indexName) : null; - if (count === Infinity) { + if (index === null && count === Infinity) { if (query === null) { store.clear(); } else { store.delete(query); } } else { - let index = 0; - store.openCursor(query, direction).onsuccess = (event) => { + let i = 0; + (index || store).openCursor(query, direction).onsuccess = (event) => { const cursor = event.target.result; if (cursor == null) { return; } cursor.delete(); - if (index < count) { - ++index; + if (i < count) { + ++i; cursor.continue(); } - } + }; } }); } /** - * ObjectStore の値を複数取得し、同時に削除する + * ObjectStore の値を複数取得し, 同時に削除する * @param storeName ObjectStore の名前 - * @param query 取得、削除する際のクエリ。null の場合全件を表す - * @param count 取得、削除する値の個数の上限値 - * @param direction 昇順、降順 + * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得, 削除する + * @param options 取得, 削除する際のオプション + * @param options.query 取得, 削除する際のクエリ + * @param options.count 取得, 削除する値の個数の上限値 + * @param options.direction 昇順, 降順 */ - getAndDeleteAll(storeName, query = null, count = Infinity, direction = "next") { + takeAll(storeName, indexName = null, {query = null, count = Infinity, direction = "next"} = {}) { return new Promise((resolve, reject) => { const ret = []; const store = this.getObjectStore(storeName, "readwrite", () => resolve(ret), reject); + const index = indexName !== null ? store.index(indexName) : null; - let index = 0; - store.openCursor(query, direction).onsuccess = (event) => { + let i = 0; + (index || store).openCursor(query, direction).onsuccess = (event) => { const cursor = event.target.result; if (cursor == null) { return; } ret.push({ key: cursor.key, value: cursor.value }); cursor.delete(); - if (index < count) { - ++index; + if (i < count) { + ++i; cursor.continue(); } - } + }; + }); + } + + /** + * ObjectStore の値数を数える + * @param storeName ObjectStore の名前 + * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得する + * @param query 取得する際のクエリ + */ + count(storeName, indexName = null, query = null) { + return new Promise((resolve, reject) => { + let ret = 0; + const store = this.getObjectStore(storeName, "readonly", () => resolve(ret), reject); + const index = indexName !== null ? store.index(indexName) : null; + + (index || store).count(query).onsuccess = (event) => { + ret = event.target.result; + }; }); } @@ -215,13 +242,13 @@ export class SimpleIDB { } /** - * ObjectStore を直接入手する。複雑なクエリを使う必要がある時に用いる + * ObjectStore を直接入手する. 複雑なクエリを使う必要がある時に用いる * @param storeNames ObjectStore の名前の配列 * @param mode IDBTransaction のモード * @param oncomplete IDBTransaction が完了したときに呼ばれる callback * @param onerror IDBTransaction が失敗したときに呼ばれる callback */ - getObjectStores(storeNames, mode = "readonly", completeCallback, errorCallback) { + getObjectStores(storeNames, mode = "readonly", completeCallback = null, errorCallback = null) { const transaction = this.getTransaction(storeNames, mode, completeCallback, errorCallback); return storeNames.map(storeName => transaction.objectStore(storeName)); } @@ -241,8 +268,8 @@ export class SimpleIDB { if (this._db === null) { throw new Error("Indexed DB hasn't been opened yet. Please await SimpleIDB#ready()"); } const transaction = this._db.transaction(storeName, mode); - if (completeCallback != null) { transaction.oncomplete = () => completeCallback(); } - if (errorCallback != null) { transaction.onerror = (e) => errorCallback(e.target.error); } + if (completeCallback !== null) { transaction.oncomplete = () => completeCallback(); } + if (errorCallback !== null) { transaction.onerror = (event) => errorCallback(event.target.error); } return transaction; } } From 71be3240d7bc02dc01cf6381b23e6d8ece1423eb Mon Sep 17 00:00:00 2001 From: petamoriken Date: Mon, 16 Apr 2018 08:40:51 +0900 Subject: [PATCH 2/5] Change API interface Append update, getAllKeys, getAllValues, updateAll, close methods --- index.d.ts | 131 +++++++++++++++---- src/index.js | 349 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 398 insertions(+), 82 deletions(-) diff --git a/index.d.ts b/index.d.ts index 9557d23..4dc2e39 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,23 +2,49 @@ export type SimpleIDBKey = string | number | Date | ArrayBuffer | SimpleIDBKeyAr export type SimpleIDBInputKey = string | number | Date | ArrayBuffer | ArrayBufferView | SimpleIDBInputKeyArray; export type SimpleIDBQuery = IDBKeyRange | null; export type SimpleIDBCursorDirection = "next" | "nextunique" | "prev" | "prevunique"; +export type SimpleIDBResult = SimpleIDBResultKey & SimpleIDBResultValue; export interface SimpleIDBKeyArray extends Array {} export interface SimpleIDBInputKeyArray extends Array {} -export interface SimpleIDBKeyAndValue { +export interface SimpleIDBResultKey { key: SimpleIDBKey, + primaryKey: SimpleIDBKey, +} + +export interface SimpleIDBResultValue { value: any, } export interface SimpleIDBQueryOptions { + indexName?: string, query?: SimpleIDBQuery, count?: number, direction?: SimpleIDBCursorDirection, } export declare class SimpleIDB { - constructor(name: string, version: number, onupgradeneeded: (this: IDBOpenDBRequest, event: IDBVersionChangeEvent) => any); + /** + * @param name データベースの名前 + */ + static deleteDatabase(name: string): Promise; + + /** + * データベースの名前 + */ + readonly name: string; + + /** + * データベースのバージョン + */ + readonly version: number; + + /** + * @param name データベースの名前 + * @param version データベースのバージョン. ObjectStore や Index の変更時に増やしていく + * @param onupgradeneeded ObjectStore や Index の初期化, 変更を行う函数 + */ + constructor(name: string, version: number, onupgradeneeded: (this: IDBOpenDBRequest, event: IDBVersionChangeEvent, self: SimpleIDB) => any); /** * IndexedDB を開き, 成功したら自身を返す @@ -26,82 +52,138 @@ export declare class SimpleIDB { ready(): Promise; /** - * ObjectStore に値を追加する. 追加された key を返す + * ObjectStore に値を追加する. 追加されたプライマリキーを返す * @param storeName ObjectStore の名前 * @param value 追加する値 - * @param key 追加する値のキー. ObjectStore が autoIncrement の場合は省略可能 + * @param primaryKey 追加する値のプライマリキー. ObjectStore が autoIncrement の場合は省略可能 */ - add(storeName: string, value: any, key?: SimpleIDBInputKey): Promise; + add(storeName: string, value: any, primaryKey?: SimpleIDBInputKey): Promise; /** - * ObjectStore の値を追加もしくは更新する. 追加もしくは更新された key を返す + * ObjectStore の値を追加もしくは更新する. 追加もしくは更新されたプライマリキーを返す * @param storeName ObjectStore の名前 * @param value 追加もしくは更新する値 - * @param key 追加もしくは更新する値のキー + * @param primaryKey 追加もしくは更新する値のプライマリキー */ - put(storeName: string, value: any, key: SimpleIDBInputKey): Promise; + put(storeName: string, value: any, primaryKey: SimpleIDBInputKey): Promise; /** * ObjectStore の値を取得する * @param storeName ObjectStore の名前 - * @param key 取得する値のキー + * @param primaryKey 取得する値のプライマリキー */ - get(storeName: string, key: SimpleIDBInputKey): Promise; + get(storeName: string, primaryKey: SimpleIDBInputKey): Promise; + + /** + * ObjectStore の値を更新する. 存在しない場合更新を行う函数は呼ばれない + * @param storeName ObjectStore の名前 + * @param primaryKey 更新する値のプライマリキー + * @param mapFn 更新を行う函数 + */ + update(storeName: string, primaryKey: SimpleIDBInputKey, mapFn: (this: this, value: any) => any): Promise; /** * ObjectStore の値を削除する * @param storeName ObjectStore の名前 - * @param key 削除する値のキー + * @param primaryKey 削除する値のプライマリキー */ - delete(storeName: string, key: SimpleIDBInputKey): Promise; + delete(storeName: string, primaryKey: SimpleIDBInputKey): Promise; /** * ObjectStore の値を取得し, 同時に削除する * @param storeName ObjectStore の名前 - * @param key 取得, 削除する値のキー + * @param primaryKey 取得, 削除する値のプライマリキー */ - take(storeName: string, key: SimpleIDBInputKey): Promise; + take(storeName: string, primaryKey: SimpleIDBInputKey): Promise; + + /** + * ObjectStore に値を複数追加する. 追加されたプライマリキーを返す + * @param storeName ObjectStore の名前 + * @param keyAndValues 追加するプライマリキーと値のペア. プライマリキーはObjectStore が autoIncrement の場合は省略可能 + */ + addAll(storeName: string, values: {value: any, primaryKey?: SimpleIDBInputKey}[]): Promise; + + /** + * ObjectStore に値を複数追加もしくは更新する. 追加もしくは更新されたキーを返す + * @param storeName ObjectStore の名前 + * @param keyAndValues 追加するプライマリキーと値のペア + */ + putAll(storeName: string, keyAndValues: {value: any, primaryKey: SimpleIDBInputKey}[]): Promise; /** * ObjectStore の値を複数取得する * @param storeName ObjectStore の名前 - * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得する * @param options 取得する際のオプション + * @param options.indexName ObjectStore の Index の名前 * @param options.query 取得する際のクエリ * @param options.count 取得する値の個数の上限値 * @param options.direction 昇順, 降順 */ - getAll(storeName: string, indexName?: string | null, options?: SimpleIDBQueryOptions): Promise; + getAll(storeName: string, options?: SimpleIDBQueryOptions): Promise; + + /** + * ObjectStore のキーのみを複数取得する. 値を取らない分効率的 + * @param storeName ObjectStore の名前 + * @param options 取得する際のオプション + * @param options.indexName ObjectStore の Index の名前 + * @param options.query 取得する際のクエリ + * @param options.count 取得する値の個数の上限値 + * @param options.direction 昇順, 降順 + */ + getAllKeys(storeName: string, options?: SimpleIDBQueryOptions): Promise; + + /** + * ObjectStore の値のみを複数取得する. キーを取らない分効率的 + * @param storeName ObjectStore の名前 + * @param options 取得する際のオプション + * @param options.indexName ObjectStore の Index の名前 + * @param options.query 取得する際のクエリ + * @param options.count 取得する値の個数の上限値 + * @param options.direction 昇順, 降順 + */ + getAllValues(storeName: string, options?: SimpleIDBQueryOptions): Promise; + + /** + * ObjectStore の値を複数更新する + * @param storeName ObjectStore の名前 + * @param mapFn 更新を行う函数 + * @param options 削除する際のオプション + * @param options.indexName ObjectStore の Index の名前 + * @param options.query 更新する際のクエリ + * @param options.count 更新する値の個数の上限値 + * @param options.direction 昇順, 降順 + */ + updateAll(storeName: string, mapFn: (this: this, value: any, key: SimpleIDBKey, primaryKey: SimpleIDBKey) => any, options: SimpleIDBQueryOptions): Promise; /** * ObjectStore の値を複数削除する * @param storeName ObjectStore の名前 - * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から削除する * @param options 削除する際のオプション + * @param options.indexName ObjectStore の Index の名前 * @param options.query 削除する際のクエリ * @param options.count 削除する値の個数の上限値 * @param options.direction 昇順, 降順 */ - deleteAll(storeName: string, indexName?: string | null, options?: SimpleIDBQueryOptions): Promise; + deleteAll(storeName: string, options: SimpleIDBQueryOptions): Promise; /** * ObjectStore の値を複数取得し, 同時に削除する * @param storeName ObjectStore の名前 - * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得, 削除する * @param options 取得, 削除する際のオプション + * @param options.indexName ObjectStore の Index の名前 * @param options.query 取得, 削除する際のクエリ * @param options.count 取得, 削除する値の個数の上限値 * @param options.direction 昇順, 降順 */ - takeAll(storeName: string, indexName?: string | null, options?: SimpleIDBQueryOptions): Promise; + takeAll(storeName: string, options?: SimpleIDBQueryOptions): Promise; /** - * ObjectStore の値数を数える + * ObjectStore の値の個数を数える * @param storeName ObjectStore の名前 * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得する * @param query 取得する際のクエリ */ - count(storeName: string, indexName?: string | null, query?: SimpleIDBQuery); + count(storeName: string, options?: {indexName?: string, query?: SimpleIDBQuery}): number; /** * ObjectStore の値を全件削除する @@ -117,4 +199,9 @@ export declare class SimpleIDB { * @param onerror IDBTransaction が失敗したときに呼ばれる callback */ getObjectStores(storeName: string[], mode?: "readonly" | "readwrite", oncomplete?: ((this: SimpleIDB) => any) | null, onerror?: ((this: SimpleIDB, error: DOMException) => any) | null): IDBObjectStore[]; + + /** + * データベースとのコネクションを閉じる + */ + close(): void; } diff --git a/src/index.js b/src/index.js index a1705e2..47401d8 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,53 @@ +const MAX_UINT32_INTEGER = -1 >>> 0; + export class SimpleIDB { + /** + * @param name データベースの名前 + */ + static deleteDatabase(name) { + return new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = () => resolve(); + request.onerror = (event) => reject(event.target.error); + }); + } + + /** + * データベースの名前 + */ + get name() { + return this._name; + } + + /** + * データベースのバージョン + */ + get version() { + return this._version; + } + + /** + * @param name データベースの名前 + * @param version データベースのバージョン. ObjectStore や Index の変更時に増やしていく + * @param onupgradeneeded ObjectStore や Index の初期化, 変更を行う函数 + */ constructor(name, version, onupgradeneeded) { + /** + * @private {string} + */ + this._name = name; + + /** + * @private {number} + */ + this._version = version | 0; + + /** + * @private {(this: IDBOpenDBRequest, event: IDBVersionChangeEvent, self: SimpleIDB) => any | null} + */ + this._onupgradeneeded = onupgradeneeded; + /** * @private {IDBDatabase | null} */ @@ -12,26 +59,38 @@ export class SimpleIDB { this._ready = null; /** - * @private {{name: string, version: number, onupgradeneeded: (this: IDBOpenDBRequest, event: IDBVersionChangeEvent) => any} | null} + * @private {IDBTransaction | null} + */ + this._versionChangeTransaction = null; + + /** + * @private {boolean} + */ + this._useOpenKeyCursor = IDBObjectStore.prototype.openKeyCursor !== undefined && IDBIndex.prototype.openKeyCursor !== undefined; + + /** + * @private {boolean} */ - this._readyData = { - name, - version, - onupgradeneeded - }; + this._useGetAll = IDBObjectStore.prototype.getAll !== undefined && IDBIndex.prototype.getAll !== undefined; } /** * IndexedDB を開き, 成功したら自身を返す */ ready() { - if (this._ready === null && this._readyData !== null) { - const {name, version, onupgradeneeded} = this._readyData; + if (this._ready === null && this._onupgradeneeded !== null) { + const {_name: name, _version: version, _onupgradeneeded: onupgradeneeded} = this; this._ready = new Promise((resolve, reject) => { const request = indexedDB.open(name, version); // migration - request.onupgradeneeded = onupgradeneeded; + request.onupgradeneeded = (event) => { + this._db = request.result; + this._versionChangeTransaction = request.transaction; + onupgradeneeded.call(request, event, this); + this._db = null; + this._versionChangeTransaction = null; + }; request.onsuccess = () => { this._db = request.result; @@ -39,37 +98,40 @@ export class SimpleIDB { }; request.onerror = () => reject(request.error); }); - this._readyData = null; + // for GC + this._onupgradeneeded = null; } return this._ready; } /** - * ObjectStore に値を追加する. 追加された key を返す + * ObjectStore に値を追加する. 追加されたプライマリキーを返す * @param storeName ObjectStore の名前 * @param value 追加する値 - * @param key 追加する値のキー. ObjectStore が autoIncrement の場合は省略可能 + * @param primaryKey 追加する値のプライマリキー. ObjectStore が autoIncrement の場合は省略可能 */ - add(storeName, value, key = undefined) { + add(storeName, value, primaryKey = undefined) { return new Promise((resolve, reject) => { - const store = this.getObjectStore(storeName, "readwrite", () => resolve(key), reject); - store.add(value, key).onsuccess = (event) => { - key = event.target.result; + let ret; + const store = this.getObjectStore(storeName, "readwrite", () => resolve(ret), reject); + store.add(value, primaryKey).onsuccess = (event) => { + ret = event.target.result; }; }); } /** - * ObjectStore の値を追加もしくは更新する. 追加もしくは更新された key を返す + * ObjectStore の値を追加もしくは更新する. 追加もしくは更新されたプライマリキーを返す * @param storeName ObjectStore の名前 * @param value 追加もしくは更新する値 - * @param key 追加もしくは更新する値のキー + * @param primaryKey 追加もしくは更新する値のプライマリキー */ - put(storeName, value, key) { + put(storeName, value, primaryKey) { return new Promise((resolve, reject) => { - const store = this.getObjectStore(storeName, "readwrite", () => resolve(key), reject); - store.put(value, key).onsuccess = (event) => { - key = event.target.result; + let ret; + const store = this.getObjectStore(storeName, "readwrite", () => resolve(ret), reject); + store.put(value, primaryKey).onsuccess = (event) => { + ret = event.target.result; }; }); } @@ -77,14 +139,32 @@ export class SimpleIDB { /** * ObjectStore の値を取得する * @param storeName ObjectStore の名前 - * @param key 取得する値のキー + * @param primaryKey 取得する値のプライマリキー + */ + get(storeName, primaryKey) { + return new Promise((resolve, reject) => { + let ret; + const store = this.getObjectStore(storeName, "readonly", () => resolve(ret), reject); + store.get(primaryKey).onsuccess = (event) => { + ret = event.target.result; + }; + }); + } + + /** + * ObjectStore の値を更新する + * @param storeName ObjectStore の名前 + * @param primaryKey 更新する値のプライマリキー + * @param mapFn 更新を行う函数 */ - get(storeName, key) { + update(storeName, primaryKey, mapFn) { return new Promise((resolve, reject) => { - let value = null; - const store = this.getObjectStore(storeName, "readonly", () => resolve(value), reject); - store.get(key).onsuccess = (event) => { - value = event.target.result; + const store = this.getObjectStore(storeName, "readwrite", resolve, reject); + store.openCursor(primaryKey).onsuccess = (event) => { + const cursor = event.target.result; + if (cursor == null) { return; } + + cursor.update(mapFn.call(this, cursor.value)); }; }); } @@ -92,52 +172,188 @@ export class SimpleIDB { /** * ObjectStore の値を削除する * @param storeName ObjectStore の名前 - * @param key 削除する値のキー + * @param primaryKey 削除する値のプライマリキー */ - delete(storeName, key) { + delete(storeName, primaryKey) { return new Promise((resolve, reject) => { const store = this.getObjectStore(storeName, "readwrite", resolve, reject); - store.delete(key); + store.delete(primaryKey); }); } /** * ObjectStore の値を取得し, 同時に削除する * @param storeName ObjectStore の名前 - * @param key 取得, 削除する値のキー + * @param primaryKey 取得, 削除する値のプライマリキー */ - take(storeName, key) { + take(storeName, primaryKey) { return new Promise((resolve, reject) => { - let value = null; - const store = this.getObjectStore(storeName, "readwrite", () => resolve(value), reject); - store.get(key).onsuccess = (event) => { - value = event.target.result; - store.delete(key); + let ret; + const store = this.getObjectStore(storeName, "readwrite", () => resolve(ret), reject); + store.get(primaryKey).onsuccess = (event) => { + ret = event.target.result; }; + store.delete(primaryKey); + }); + } + + /** + * ObjectStore に値を複数追加する. 追加されたキーを返す + * @param storeName ObjectStore の名前 + * @param keyAndValues 追加するプライマリキーと値のペア. プライマリキーはObjectStore が autoIncrement の場合は省略可能 + */ + addAll(storeName, keyAndValues) { + return new Promise((resolve, reject) => { + const ret = []; + const store = this.getObjectStore(storeName, "readwrite", () => resolve(ret), reject); + for (const {primaryKey, value} of keyAndValues) { + store.add(value, primaryKey).onsuccess = (event) => { + ret.push(event.target.result); + }; + } + }); + } + + /** + * ObjectStore に値を複数追加もしくは更新する. 追加もしくは更新されたプライマリキーを返す + * @param storeName ObjectStore の名前 + * @param keyAndValues 追加するプライマリキーと値のペア + */ + putAll(storeName, keyAndValues) { + return new Promise((resolve, reject) => { + const ret = []; + const store = this.getObjectStore(storeName, "readwrite", () => resolve(ret), reject); + for (const {primaryKey, value} of keyAndValues) { + store.put(value, primaryKey).onsuccess = (event) => { + ret.push(event.target.result); + }; + } }); } /** * ObjectStore の値を複数取得する * @param storeName ObjectStore の名前 - * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得する * @param options 取得する際のオプション + * @param options.indexName ObjectStore の Index の名前 * @param options.query 取得する際のクエリ * @param options.count 取得する値の個数の上限値 * @param options.direction 昇順, 降順 */ - getAll(storeName, indexName = null, {query = null, count = Infinity, direction = "next"} = {}) { + getAll(storeName, {indexName = null, query = null, count = MAX_UINT32_INTEGER, direction = "next"} = {}) { return new Promise((resolve, reject) => { const ret = []; + if (count === 0) { resolve(ret); return; } + const store = this.getObjectStore(storeName, "readonly", () => resolve(ret), reject); const index = indexName !== null ? store.index(indexName) : null; - let i = 0; + let i = 1; (index || store).openCursor(query, direction).onsuccess = (event) => { const cursor = event.target.result; if (cursor == null) { return; } - ret.push({ key: cursor.key, value: cursor.value }); + ret.push({ primaryKey: cursor.primaryKey, key: cursor.key, value: cursor.value }); + if (i < count) { + ++i; + cursor.continue(); + } + }; + }); + } + + /** + * ObjectStore のキーのみを複数取得する. 値を取らない分効率的 + * @param storeName ObjectStore の名前 + * @param options 取得する際のオプション + * @param options.indexName ObjectStore の Index の名前 + * @param options.query 取得する際のクエリ + * @param options.count 取得する値の個数の上限値 + * @param options.direction 昇順, 降順 + */ + getAllKeys(storeName, {indexName = null, query = null, count = MAX_UINT32_INTEGER, direction = "next"} = {}) { + return new Promise((resolve, reject) => { + const ret = []; + if (count === 0) { resolve(ret); return; } + + const store = this.getObjectStore(storeName, "readonly", () => resolve(ret), reject); + const index = indexName !== null ? store.index(indexName) : null; + + let i = 1; + (index || store)[this._useOpenKeyCursor ? "openKeyCursor" : "openCursor"](query, direction).onsuccess = (event) => { + const cursor = event.target.result; + if (cursor == null) { return; } + + ret.push({ primaryKey: cursor.primaryKey, key: cursor.key }); + if (i < count) { + ++i; + cursor.continue(); + } + }; + }); + } + + /** + * ObjectStore の値のみを複数取得する. キーを取らない分効率的 + * @param storeName ObjectStore の名前 + * @param options 取得する際のオプション + * @param options.indexName ObjectStore の Index の名前 + * @param options.query 取得する際のクエリ + * @param options.count 取得する値の個数の上限値 + * @param options.direction 昇順, 降順 + */ + getAllValues(storeName, {indexName = null, query = null, count = MAX_UINT32_INTEGER, direction = "next"} = {}) { + return new Promise((resolve, reject) => { + let ret = []; + if (count === 0) { resolve(ret); return; } + + const store = this.getObjectStore(storeName, "readonly", () => resolve(ret), reject); + const index = indexName !== null ? store.index(indexName) : null; + + if (this._useGetAll && direction === "next") { + (index || store).getAll(query, count).onsuccess = (event) => { + ret = event.target.result.map((value) => ({ value })); + }; + return; + } + + let i = 1; + (index || store).openCursor(query, direction).onsuccess = (event) => { + const cursor = event.target.result; + if (cursor == null) { return; } + + ret.push({ value: cursor.value }); + if (i < count) { + ++i; + cursor.continue(); + } + }; + }); + } + + /** + * ObjectStore の値を複数更新する + * @param storeName ObjectStore の名前 + * @param mapFn 更新を行う函数 + * @param options 削除する際のオプション + * @param options.indexName ObjectStore の Index の名前 + * @param options.query 更新する際のクエリ + * @param options.count 更新する値の個数の上限値 + * @param options.direction 昇順, 降順 + */ + updateAll(storeName, mapFn, {indexName = null, query = null, count = MAX_UINT32_INTEGER, direction = "next"} = {}) { + return new Promise((resolve, reject) => { + if (count === 0) { resolve(); return; } + + const store = this.getObjectStore(storeName, "readwrite", resolve, reject); + const index = indexName !== null ? store.index(indexName) : null; + + let i = 1; + (index || store).openCursor(query, direction).onsuccess = (event) => { + const cursor = event.target.result; + if (cursor == null) { return; } + + cursor.update(mapFn.call(this, cursor.value, cursor.key, cursor.primaryKey)); if (i < count) { ++i; cursor.continue(); @@ -149,25 +365,27 @@ export class SimpleIDB { /** * ObjectStore の値を複数削除する * @param storeName ObjectStore の名前 - * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から削除する * @param options 削除する際のオプション + * @param options.indexName ObjectStore の Index の名前 * @param options.query 削除する際のクエリ * @param options.count 削除する値の個数の上限値 * @param options.direction 昇順, 降順 */ - deleteAll(storeName, indexName = null, {query = null, count = Infinity, direction = "next"} = {}) { + deleteAll(storeName, {indexName = null, query = null, count = MAX_UINT32_INTEGER, direction = "next"} = {}) { return new Promise((resolve, reject) => { + if (count === 0) { resolve(); return; } + const store = this.getObjectStore(storeName, "readwrite", resolve, reject); const index = indexName !== null ? store.index(indexName) : null; - if (index === null && count === Infinity) { + if (index === null && count === MAX_UINT32_INTEGER) { if (query === null) { store.clear(); } else { store.delete(query); } } else { - let i = 0; + let i = 1; (index || store).openCursor(query, direction).onsuccess = (event) => { const cursor = event.target.result; if (cursor == null) { return; } @@ -185,24 +403,26 @@ export class SimpleIDB { /** * ObjectStore の値を複数取得し, 同時に削除する * @param storeName ObjectStore の名前 - * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得, 削除する * @param options 取得, 削除する際のオプション + * @param options.indexName ObjectStore の Index の名前 * @param options.query 取得, 削除する際のクエリ * @param options.count 取得, 削除する値の個数の上限値 * @param options.direction 昇順, 降順 */ - takeAll(storeName, indexName = null, {query = null, count = Infinity, direction = "next"} = {}) { + takeAll(storeName, {indexName = null, query = null, count = MAX_UINT32_INTEGER, direction = "next"} = {}) { return new Promise((resolve, reject) => { const ret = []; + if (count === 0) { resolve(ret); return; } + const store = this.getObjectStore(storeName, "readwrite", () => resolve(ret), reject); const index = indexName !== null ? store.index(indexName) : null; - let i = 0; + let i = 1; (index || store).openCursor(query, direction).onsuccess = (event) => { const cursor = event.target.result; if (cursor == null) { return; } - ret.push({ key: cursor.key, value: cursor.value }); + ret.push({ primaryKey: cursor.primaryKey, key: cursor.key, value: cursor.value }); cursor.delete(); if (i < count) { ++i; @@ -213,14 +433,15 @@ export class SimpleIDB { } /** - * ObjectStore の値数を数える + * ObjectStore の値の個数を数える * @param storeName ObjectStore の名前 - * @param indexName ObjectStore の Index の名前. null の場合は直接 ObjectStore から取得する - * @param query 取得する際のクエリ + * @param options 取得する際のオプション + * @param options.indexName ObjectStore の Index の名前 + * @param options.query 取得する際のクエリ */ - count(storeName, indexName = null, query = null) { + count(storeName, {indexName = null, query = null} = {}) { return new Promise((resolve, reject) => { - let ret = 0; + let ret; const store = this.getObjectStore(storeName, "readonly", () => resolve(ret), reject); const index = indexName !== null ? store.index(indexName) : null; @@ -250,26 +471,34 @@ export class SimpleIDB { */ getObjectStores(storeNames, mode = "readonly", completeCallback = null, errorCallback = null) { const transaction = this.getTransaction(storeNames, mode, completeCallback, errorCallback); + if (completeCallback !== null) { transaction.oncomplete = () => completeCallback(); } + if (errorCallback !== null) { transaction.onerror = (event) => errorCallback(event.target.error); } return storeNames.map(storeName => transaction.objectStore(storeName)); } + /** + * データベースとのコネクションを閉じる + */ + close() { + this._db.close(); + } + /** * @private */ getObjectStore(storeName, mode, completeCallback, errorCallback) { const transaction = this.getTransaction(storeName, mode, completeCallback, errorCallback); + transaction.oncomplete = () => completeCallback(); + transaction.onerror = (event) => errorCallback(event.target.error); return transaction.objectStore(storeName); } /** * @private */ - getTransaction(storeName, mode, completeCallback, errorCallback) { + getTransaction(storeName, mode) { if (this._db === null) { throw new Error("Indexed DB hasn't been opened yet. Please await SimpleIDB#ready()"); } - - const transaction = this._db.transaction(storeName, mode); - if (completeCallback !== null) { transaction.oncomplete = () => completeCallback(); } - if (errorCallback !== null) { transaction.onerror = (event) => errorCallback(event.target.error); } + const transaction = this._versionChangeTransaction || this._db.transaction(storeName, mode); return transaction; } } From 11a4b181d488d463d2bb0a27594f4755a35b9a0a Mon Sep 17 00:00:00 2001 From: petamoriken Date: Mon, 16 Apr 2018 08:48:06 +0900 Subject: [PATCH 3/5] Add basic test --- .eslintrc.js | 2 + package.json | 8 +- test/SimpleIDB.js | 230 +++++++++++++++ test/mocha.opts | 1 + yarn.lock | 699 ++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 849 insertions(+), 91 deletions(-) create mode 100644 test/SimpleIDB.js create mode 100644 test/mocha.opts diff --git a/.eslintrc.js b/.eslintrc.js index fa56c84..6f03caa 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -7,7 +7,9 @@ module.exports = { extends: ["eslint:recommended"], env: { "browser": true, + "node": true, "es6": true, + "mocha": true, }, rules: { "quotes": [2, "double", "avoid-escape"], diff --git a/package.json b/package.json index a9b753d..2755f27 100644 --- a/package.json +++ b/package.json @@ -32,12 +32,18 @@ "scripts": { "build": "babel src -d lib", "lint": "eslint src", + "test": "mocha", "prepublishOnly": "yarn run lint && yarn run build" }, "devDependencies": { "babel-cli": "^6.26.0", "babel-eslint": "^8.2.1", "babel-preset-env": "^1.6.1", - "eslint": "^4.15.0" + "eslint": "^4.15.0", + "fake-indexeddb": "^2.0.4", + "faker": "^4.1.0", + "intelli-espower-loader": "^1.0.1", + "mocha": "^5.0.5", + "power-assert": "^1.5.0" } } diff --git a/test/SimpleIDB.js b/test/SimpleIDB.js new file mode 100644 index 0000000..1633012 --- /dev/null +++ b/test/SimpleIDB.js @@ -0,0 +1,230 @@ +"use strict"; + +require("fake-indexeddb/build/global"); + +const assert = require("power-assert"); +const faker = require("faker"); + +const SimpleIDB = require("../lib").SimpleIDB; + +describe("SimpleIDB test", () => { + describe("basic", () => { + let simpleIDB; + + const storeName = "zip"; + const setupData = Object.freeze([ + { primaryKey: 1, value: faker.address.zipCode() }, + { primaryKey: 2, value: faker.address.zipCode() }, + { primaryKey: 3, value: faker.address.zipCode() }, + ]); + + beforeEach(async () => { + simpleIDB = new SimpleIDB("basic test" + Math.random(), 1, (event, simpleIDB) => { + const db = event.target.result; + db.createObjectStore(storeName, { autoIncrement: true }); + + // setup + simpleIDB.addAll(storeName, setupData); + }); + + await simpleIDB.ready(); + }); + + afterEach(async () => { + simpleIDB.close(); + SimpleIDB.deleteDatabase(simpleIDB.name); + }); + + async function checkCurrentStore(results) { + const current = await simpleIDB.getAll(storeName); + assert(current.length === results.length); + for (let i = 0; i < current.length; ++i) { + assert(current[i].primaryKey = results[i].primaryKey); + assert(current[i].value === results[i].value); + } + } + + it("name, version", () => { + assert(simpleIDB.name === simpleIDB._db.name); + assert(simpleIDB.version === simpleIDB._db.version); + }); + + it("add", async () => { + const zipValue1 = faker.address.zipCode(); + const zipValue2 = faker.address.zipCode(); + assert(await simpleIDB.add(storeName, zipValue1) === 4); + assert(await simpleIDB.add(storeName, zipValue2, 10) === 10); + await checkCurrentStore([ + ...setupData, + { primaryKey: 4, value: zipValue1 }, + { primaryKey: 10, value: zipValue2 }, + ]); + }); + + it("put", async () => { + const zipValue1 = faker.address.zipCode(); + assert(await simpleIDB.put(storeName, zipValue1, 10) === 10); + await checkCurrentStore([ + ...setupData, + { primaryKey: 10, value: zipValue1 }, + ]); + }); + + it("get", async () => { + const [{ value: zipValue1 }, { value: zipValue2 }, { value: zipValue3 }] = setupData; + assert(await simpleIDB.get(storeName, 1) === zipValue1); + assert(await simpleIDB.get(storeName, 2) === zipValue2); + assert(await simpleIDB.get(storeName, 3) === zipValue3); + }); + + it("update", async () => { + const zipValue1 = faker.address.zipCode(); + assert(await simpleIDB.update(storeName, 1, (value) => { + assert(value === setupData[0].value); + return zipValue1; + }) === undefined); + assert(await simpleIDB.update(storeName, 100, () => { throw new Error("unreachable"); }) === undefined); + + const testData = [].concat(setupData); + testData[0].value = zipValue1; + await checkCurrentStore(testData); + }); + + it("delete", async () => { + assert(await simpleIDB.delete(storeName, 1) === undefined); + await checkCurrentStore(setupData.slice(1)); + }); + + it("take", async () => { + assert(await simpleIDB.take(storeName, 1) === setupData[0].value); + await checkCurrentStore(setupData.slice(1)); + }); + + it("addAll", async () => { + const zipValue1 = faker.address.zipCode(); + const zipValue2 = faker.address.zipCode(); + assert.deepStrictEqual(await simpleIDB.addAll(storeName, [ + { value: zipValue1 }, + { primaryKey: 10, value: zipValue2 }, + ]), [4, 10]); + await checkCurrentStore([ + ...setupData, + { primaryKey: 4, value: zipValue1 }, + { primaryKey: 10, value: zipValue2 }, + ]); + }); + + it("putAll", async () => { + const zipValue1 = faker.address.zipCode(); + const zipValue2 = faker.address.zipCode(); + assert.deepStrictEqual(await simpleIDB.addAll(storeName, [ + { primaryKey: 4, value: zipValue1 }, + { primaryKey: 10, value: zipValue2 }, + ]), [4, 10]); + await checkCurrentStore([ + ...setupData, + { primaryKey: 4, value: zipValue1 }, + { primaryKey: 10, value: zipValue2 }, + ]); + }); + + it("getAll", async () => { + assert.deepStrictEqual(await simpleIDB.getAll(storeName, { query: IDBKeyRange.lowerBound(1, true) }), [ + { key: 2, primaryKey: 2, value: setupData[1].value}, + { key: 3, primaryKey: 3, value: setupData[2].value}, + ]); + assert.deepStrictEqual(await simpleIDB.getAll(storeName, { query: IDBKeyRange.lowerBound(100) }), []); + }); + + it("getAllKeys", async () => { + assert.deepStrictEqual(await simpleIDB.getAllKeys(storeName), [ + { key: 1, primaryKey: 1 }, + { key: 2, primaryKey: 2 }, + { key: 3, primaryKey: 3 }, + ]); + assert.deepStrictEqual(await simpleIDB.getAllKeys(storeName, { query: IDBKeyRange.lowerBound(1, true) }), [ + { key: 2, primaryKey: 2 }, + { key: 3, primaryKey: 3 }, + ]); + assert.deepStrictEqual(await simpleIDB.getAllKeys(storeName, { query: IDBKeyRange.lowerBound(100) }), []); + + // fallback + simpleIDB._useOpenKeyCursor = false; + assert.deepStrictEqual(await simpleIDB.getAllKeys(storeName), [ + { key: 1, primaryKey: 1 }, + { key: 2, primaryKey: 2 }, + { key: 3, primaryKey: 3 }, + ]); + assert.deepStrictEqual(await simpleIDB.getAllKeys(storeName, { query: IDBKeyRange.lowerBound(1, true) }), [ + { key: 2, primaryKey: 2 }, + { key: 3, primaryKey: 3 }, + ]); + assert.deepStrictEqual(await simpleIDB.getAllKeys(storeName, { query: IDBKeyRange.lowerBound(100) }), []); + simpleIDB._useOpenKeyCursor = true; + }); + + it("getAllValues", async () => { + assert.deepStrictEqual(await simpleIDB.getAllValues(storeName), [ + { value: setupData[0].value }, + { value: setupData[1].value }, + { value: setupData[2].value }, + ]); + assert.deepStrictEqual(await simpleIDB.getAllValues(storeName, { query: IDBKeyRange.lowerBound(1, true) }), [ + { value: setupData[1].value }, + { value: setupData[2].value }, + ]); + assert.deepStrictEqual(await simpleIDB.getAllValues(storeName, { query: IDBKeyRange.lowerBound(100) }), []); + + // fallback + simpleIDB._useGetAll = false; + assert.deepStrictEqual(await simpleIDB.getAllValues(storeName), [ + { value: setupData[0].value }, + { value: setupData[1].value }, + { value: setupData[2].value }, + ]); + assert.deepStrictEqual(await simpleIDB.getAllValues(storeName, { query: IDBKeyRange.lowerBound(1, true) }), [ + { value: setupData[1].value }, + { value: setupData[2].value }, + ]); + assert.deepStrictEqual(await simpleIDB.getAllValues(storeName, { query: IDBKeyRange.lowerBound(100) }), []); + simpleIDB._useGetAll = true; + }); + + it("updateAll", async () => { + const zipValue1 = faker.address.zipCode(); + assert(await simpleIDB.updateAll(storeName, () => zipValue1, { query: IDBKeyRange.lowerBound(1, true) }) === undefined); + await checkCurrentStore([ + setupData[0], + { primaryKey: 1, value: zipValue1 }, + { primaryKey: 2, value: zipValue1 }, + ]); + }); + + it("deleteAll", async () => { + assert(await simpleIDB.deleteAll(storeName, { query: IDBKeyRange.lowerBound(1, true), count: 1 }) === undefined); + await checkCurrentStore([ + setupData[0], + setupData[2], + ]); + }); + + it("takeAll", async () => { + assert.deepStrictEqual(await simpleIDB.takeAll(storeName, { query: IDBKeyRange.lowerBound(1, true), count: 1 }), [ + { key: 2, primaryKey: 2, value: setupData[1].value}, + ]); + await checkCurrentStore([ + setupData[0], + setupData[2], + ]); + }); + + it("count", async () => { + assert(await simpleIDB.count(storeName) === 3); + }); + + it("clear", async () => { + assert(await simpleIDB.clear(storeName) === undefined); + await checkCurrentStore([]); + }); + }); +}); diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 0000000..0ebce8f --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1 @@ +--require intelli-espower-loader \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8318dc1..db46e0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,77 +2,77 @@ # yarn lockfile v1 -"@babel/code-frame@7.0.0-beta.42", "@babel/code-frame@^7.0.0-beta.40": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.42.tgz#a9c83233fa7cd06b39dc77adbb908616ff4f1962" +"@babel/code-frame@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" dependencies: - "@babel/highlight" "7.0.0-beta.42" + "@babel/highlight" "7.0.0-beta.44" -"@babel/generator@7.0.0-beta.42": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.42.tgz#777bb50f39c94a7e57f73202d833141f8159af33" +"@babel/generator@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" dependencies: - "@babel/types" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.44" jsesc "^2.5.1" lodash "^4.2.0" source-map "^0.5.0" trim-right "^1.0.1" -"@babel/helper-function-name@7.0.0-beta.42": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.42.tgz#b38b8f4f85168d1812c543dd700b5d549b0c4658" +"@babel/helper-function-name@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" dependencies: - "@babel/helper-get-function-arity" "7.0.0-beta.42" - "@babel/template" "7.0.0-beta.42" - "@babel/types" "7.0.0-beta.42" + "@babel/helper-get-function-arity" "7.0.0-beta.44" + "@babel/template" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" -"@babel/helper-get-function-arity@7.0.0-beta.42": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.42.tgz#ad072e32f912c033053fc80478169aeadc22191e" +"@babel/helper-get-function-arity@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" dependencies: - "@babel/types" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.44" -"@babel/helper-split-export-declaration@7.0.0-beta.42": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.42.tgz#0d0d5254220a9cc4e7e226240306b939dc210ee7" +"@babel/helper-split-export-declaration@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" dependencies: - "@babel/types" "7.0.0-beta.42" + "@babel/types" "7.0.0-beta.44" -"@babel/highlight@7.0.0-beta.42": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.42.tgz#a502a1c0d6f99b2b0e81d468a1b0c0e81e3f3623" +"@babel/highlight@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" dependencies: chalk "^2.0.0" esutils "^2.0.2" js-tokens "^3.0.0" -"@babel/template@7.0.0-beta.42": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.42.tgz#7186d4e70d44cdec975049ba0a73bdaf5cdee052" +"@babel/template@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" dependencies: - "@babel/code-frame" "7.0.0-beta.42" - "@babel/types" "7.0.0-beta.42" - babylon "7.0.0-beta.42" + "@babel/code-frame" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" lodash "^4.2.0" -"@babel/traverse@^7.0.0-beta.40": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.42.tgz#f4bf4d1e33d41baf45205e2d0463591d57326285" +"@babel/traverse@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" dependencies: - "@babel/code-frame" "7.0.0-beta.42" - "@babel/generator" "7.0.0-beta.42" - "@babel/helper-function-name" "7.0.0-beta.42" - "@babel/helper-split-export-declaration" "7.0.0-beta.42" - "@babel/types" "7.0.0-beta.42" - babylon "7.0.0-beta.42" + "@babel/code-frame" "7.0.0-beta.44" + "@babel/generator" "7.0.0-beta.44" + "@babel/helper-function-name" "7.0.0-beta.44" + "@babel/helper-split-export-declaration" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" debug "^3.1.0" globals "^11.1.0" invariant "^2.2.0" lodash "^4.2.0" -"@babel/types@7.0.0-beta.42", "@babel/types@^7.0.0-beta.40": - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.42.tgz#1e2118767684880f6963801b272fd2b3348efacc" +"@babel/types@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" dependencies: esutils "^2.0.2" lodash "^4.2.0" @@ -82,6 +82,10 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +acorn-es7-plugin@^1.0.10, acorn-es7-plugin@^1.0.12: + version "1.1.7" + resolved "https://registry.yarnpkg.com/acorn-es7-plugin/-/acorn-es7-plugin-1.1.7.tgz#f2ee1f3228a90eead1245f9ab1922eb2e71d336b" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" @@ -92,7 +96,11 @@ acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^5.5.0: +acorn@^4.0.0: + version "4.0.13" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + +acorn@^5.0.0, acorn@^5.5.0: version "5.5.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" @@ -116,6 +124,10 @@ ajv@^5.2.3, ajv@^5.3.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -172,6 +184,14 @@ arr-flatten@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" +array-filter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" + +array-find@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -215,8 +235,8 @@ aws-sign2@~0.6.0: resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" aws4@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + version "1.7.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" babel-cli@^6.26.0: version "6.26.0" @@ -272,13 +292,13 @@ babel-core@^6.26.0: source-map "^0.5.6" babel-eslint@^8.2.1: - version "8.2.2" - resolved "http://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.2.tgz#1102273354c6f0b29b4ea28a65f97d122296b68b" + version "8.2.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.3.tgz#1a2e6681cc9bc4473c32899e59915e19cd6733cf" dependencies: - "@babel/code-frame" "^7.0.0-beta.40" - "@babel/traverse" "^7.0.0-beta.40" - "@babel/types" "^7.0.0-beta.40" - babylon "^7.0.0-beta.40" + "@babel/code-frame" "7.0.0-beta.44" + "@babel/traverse" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" eslint-scope "~3.7.1" eslint-visitor-keys "^1.0.0" @@ -712,9 +732,9 @@ babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: lodash "^4.17.4" to-fast-properties "^1.0.3" -babylon@7.0.0-beta.42, babylon@^7.0.0-beta.40: - version "7.0.0-beta.42" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.42.tgz#67cfabcd4f3ec82999d29031ccdea89d0ba99657" +babylon@7.0.0-beta.44: + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" babylon@^6.18.0: version "6.18.0" @@ -724,6 +744,10 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +base64-arraybuffer-es6@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.3.1.tgz#fdf0e382f4e2f56caf881f48ee0ce01ae79afe48" + bcrypt-pbkdf@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" @@ -761,6 +785,10 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + browserslist@^2.1.2: version "2.11.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" @@ -772,6 +800,19 @@ buffer-from@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531" +call-matcher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.1.tgz#5134d077984f712a54dad3cbf62de28dce416ca8" + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -783,8 +824,8 @@ callsites@^0.2.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" caniuse-lite@^1.0.30000792: - version "1.0.30000820" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000820.tgz#6e36ee75187a2c83d26d6504a1af47cc580324d2" + version "1.0.30000830" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000830.tgz#cb96b8a2dd3cbfe04acea2af3c4e894249095328" caseless@~0.12.0: version "0.12.0" @@ -865,6 +906,10 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" +commander@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + commander@^2.11.0: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" @@ -886,13 +931,13 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" -convert-source-map@^1.5.0: +convert-source-map@^1.1.0, convert-source-map@^1.1.1, convert-source-map@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" -core-js@^2.4.0, core-js@^2.5.0: - version "2.5.4" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.4.tgz#f2c8bf181f2a80b92f360121429ce63a2f0aeae0" +core-js@^2.0.0, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0, core-js@^2.5.3: + version "2.5.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.5.tgz#b14dde936c640c0579a6b50cabcc132dd6127e3b" core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -912,23 +957,33 @@ cryptiles@2.x.x: dependencies: boom "2.x.x" +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" dependencies: assert-plus "^1.0.0" +debug@3.1.0, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + debug@^2.2.0, debug@^2.6.8: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: ms "2.0.0" -debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" deep-extend@~0.4.0: version "0.4.2" @@ -938,6 +993,13 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -968,12 +1030,30 @@ detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" +diff-match-patch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.0.tgz#1cc3c83a490d67f95d91e39f6ad1f2e086b63048" + +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" dependencies: esutils "^2.0.2" +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + +eastasianwidth@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.1.1.tgz#44d656de9da415694467335365fb3147b8572b7c" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -981,13 +1061,113 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" electron-to-chromium@^1.3.30: - version "1.3.40" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.40.tgz#1fbd6d97befd72b8a6f921dc38d22413d2f6fddf" + version "1.3.42" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.42.tgz#95c33bf01d0cc405556aec899fe61fd4d76ea0f9" + +empower-assert@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/empower-assert/-/empower-assert-1.1.0.tgz#8d327fbe69a88af90dda98d1bfc9829d2a24fd62" + dependencies: + estraverse "^4.2.0" + +empower-core@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.2.tgz#5adef566088e31fba80ba0a36df47d7094169144" + dependencies: + call-signature "0.0.2" + core-js "^2.0.0" + +empower@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/empower/-/empower-1.2.3.tgz#6f0da73447f4edd838fec5c60313a88ba5cb852b" + dependencies: + core-js "^2.0.0" + empower-core "^0.6.2" + +es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.42" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.42.tgz#8c07dd33af04d5dcd1310b5cef13bea63a89ba8d" + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "1" -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escallmatch@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/escallmatch/-/escallmatch-1.5.0.tgz#50099d86e8091b092df8ddfbc3f9a6fb05a024d0" + dependencies: + call-matcher "^1.0.0" + esprima "^2.0.0" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escodegen@^1.6.1, escodegen@^1.7.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escope@^3.3.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint-scope@^3.7.1, eslint-scope@~3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" @@ -1042,6 +1222,56 @@ eslint@^4.15.0: table "4.0.2" text-table "~0.2.0" +espower-loader@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/espower-loader/-/espower-loader-1.2.2.tgz#edb46c3c59a06bac8ea73a695c86e5c5a0bc82da" + dependencies: + convert-source-map "^1.1.0" + espower-source "^2.0.0" + minimatch "^3.0.0" + source-map-support "^0.4.0" + xtend "^4.0.0" + +espower-location-detector@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-1.0.0.tgz#a17b7ecc59d30e179e2bef73fb4137704cb331b5" + dependencies: + is-url "^1.2.1" + path-is-absolute "^1.0.0" + source-map "^0.5.0" + xtend "^4.0.0" + +espower-source@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/espower-source/-/espower-source-2.2.0.tgz#7e005255ae47b5c136448644b3f3d802d503f752" + dependencies: + acorn "^5.0.0" + acorn-es7-plugin "^1.0.10" + convert-source-map "^1.1.1" + empower-assert "^1.0.0" + escodegen "^1.6.1" + espower "^2.0.0" + estraverse "^4.0.0" + merge-estraverse-visitors "^1.0.0" + multi-stage-sourcemap "^0.2.1" + path-is-absolute "^1.0.0" + xtend "^4.0.0" + +espower@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/espower/-/espower-2.1.0.tgz#ce1edb3d98702841fdf596d1cb8e85bdc4ae8e48" + dependencies: + array-find "^1.0.0" + escallmatch "^1.5.0" + escodegen "^1.7.0" + escope "^3.3.0" + espower-location-detector "^1.0.0" + espurify "^1.3.0" + estraverse "^4.1.0" + source-map "^0.5.0" + type-name "^2.0.0" + xtend "^4.0.0" + espree@^3.5.4: version "3.5.4" resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" @@ -1049,13 +1279,27 @@ espree@^3.5.4: acorn "^5.5.0" acorn-jsx "^3.0.0" +esprima@^2.0.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" +espurify@^1.3.0, espurify@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.7.0.tgz#1c5cf6cbccc32e6f639380bd4f991fab9ba9d226" + dependencies: + core-js "^2.0.0" + esquery@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" dependencies: estraverse "^4.0.0" @@ -1065,7 +1309,7 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -1073,6 +1317,13 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + dependencies: + d "1" + es5-ext "~0.10.14" + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -1090,8 +1341,8 @@ extend@~3.0.0: resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" external-editor@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: chardet "^0.4.0" iconv-lite "^0.4.17" @@ -1111,6 +1362,18 @@ extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" +fake-indexeddb@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-2.0.4.tgz#401715deb7fc9501866c9f329bde7742599e2de8" + dependencies: + core-js "^2.4.1" + realistic-structured-clone "^2.0.1" + setimmediate "^1.0.5" + +faker@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/faker/-/faker-4.1.0.tgz#1e45bbbecc6774b3c195fad2835109c6d748cc3f" + fast-deep-equal@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" @@ -1169,6 +1432,10 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -1249,7 +1516,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: +glob@7.1.2, glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -1283,6 +1550,10 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.4: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +growl@1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" + har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" @@ -1300,6 +1571,10 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1317,6 +1592,10 @@ hawk@3.1.3, hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" @@ -1337,8 +1616,10 @@ http-signature@~1.1.0: sshpk "^1.7.0" iconv-lite@^0.4.17: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + version "0.4.21" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798" + dependencies: + safer-buffer "^2.1.0" ignore@^3.3.3: version "3.3.7" @@ -1348,6 +1629,10 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -1382,6 +1667,12 @@ inquirer@^3.0.6: strip-ansi "^4.0.0" through "^2.3.6" +intelli-espower-loader@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/intelli-espower-loader/-/intelli-espower-loader-1.0.1.tgz#2c7b03146bc1d46bf210d0a0397c5c91ab4ca2b0" + dependencies: + espower-loader "^1.0.0" + invariant@^2.2.0, invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -1486,6 +1777,10 @@ is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" +is-url@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1589,6 +1884,10 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: version "4.17.5" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" @@ -1606,6 +1905,12 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" +merge-estraverse-visitors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/merge-estraverse-visitors/-/merge-estraverse-visitors-1.0.0.tgz#eb968338b5ded5ceed82cec0307decba2d8ea994" + dependencies: + estraverse "^4.0.0" + micromatch@^2.1.5: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -1638,7 +1943,7 @@ mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -1652,16 +1957,38 @@ minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" -"mkdirp@>=0.5 0", mkdirp@^0.5.1: +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" +mocha@^5.0.5: + version "5.1.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.1.0.tgz#5ff11cc39c0bb65330ac6c41f9086634e3e3f686" + dependencies: + browser-stdout "1.3.1" + commander "2.11.0" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.3" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "4.4.0" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +multi-stage-sourcemap@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz#b09fc8586eaa17f81d575c4ad02e0f7a3f6b1105" + dependencies: + source-map "^0.1.34" + mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -1674,6 +2001,10 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +next-tick@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + node-pre-gyp@^0.6.39: version "0.6.39" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" @@ -1724,6 +2055,10 @@ object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-keys@^1.0.0, object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -1743,7 +2078,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" dependencies: @@ -1816,6 +2151,94 @@ pluralize@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" +power-assert-context-formatter@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-context-formatter/-/power-assert-context-formatter-1.1.1.tgz#edba352d3ed8a603114d667265acce60d689ccdf" + dependencies: + core-js "^2.0.0" + power-assert-context-traversal "^1.1.1" + +power-assert-context-reducer-ast@^1.0.7: + version "1.1.2" + resolved "https://registry.yarnpkg.com/power-assert-context-reducer-ast/-/power-assert-context-reducer-ast-1.1.2.tgz#484a99e26f4973ff8832e5c5cc756702e6094174" + dependencies: + acorn "^4.0.0" + acorn-es7-plugin "^1.0.12" + core-js "^2.0.0" + espurify "^1.6.0" + estraverse "^4.2.0" + +power-assert-context-traversal@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-context-traversal/-/power-assert-context-traversal-1.1.1.tgz#88cabca0d13b6359f07d3d3e8afa699264577ed9" + dependencies: + core-js "^2.0.0" + estraverse "^4.1.0" + +power-assert-formatter@^1.3.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/power-assert-formatter/-/power-assert-formatter-1.4.1.tgz#5dc125ed50a3dfb1dda26c19347f3bf58ec2884a" + dependencies: + core-js "^2.0.0" + power-assert-context-formatter "^1.0.7" + power-assert-context-reducer-ast "^1.0.7" + power-assert-renderer-assertion "^1.0.7" + power-assert-renderer-comparison "^1.0.7" + power-assert-renderer-diagram "^1.0.7" + power-assert-renderer-file "^1.0.7" + +power-assert-renderer-assertion@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-assertion/-/power-assert-renderer-assertion-1.1.1.tgz#cbfc0e77e0086a8f96af3f1d8e67b9ee7e28ce98" + dependencies: + power-assert-renderer-base "^1.1.1" + power-assert-util-string-width "^1.1.1" + +power-assert-renderer-base@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-base/-/power-assert-renderer-base-1.1.1.tgz#96a650c6fd05ee1bc1f66b54ad61442c8b3f63eb" + +power-assert-renderer-comparison@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-comparison/-/power-assert-renderer-comparison-1.1.1.tgz#d7439d97d85156be4e30a00f2fb5a72514ce3c08" + dependencies: + core-js "^2.0.0" + diff-match-patch "^1.0.0" + power-assert-renderer-base "^1.1.1" + stringifier "^1.3.0" + type-name "^2.0.1" + +power-assert-renderer-diagram@^1.0.7: + version "1.1.2" + resolved "https://registry.yarnpkg.com/power-assert-renderer-diagram/-/power-assert-renderer-diagram-1.1.2.tgz#655f8f711935a9b6d541b86327654717c637a986" + dependencies: + core-js "^2.0.0" + power-assert-renderer-base "^1.1.1" + power-assert-util-string-width "^1.1.1" + stringifier "^1.3.0" + +power-assert-renderer-file@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-renderer-file/-/power-assert-renderer-file-1.1.1.tgz#a37e2bbd178ccacd04e78dbb79c92fe34933c5e7" + dependencies: + power-assert-renderer-base "^1.1.1" + +power-assert-util-string-width@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/power-assert-util-string-width/-/power-assert-util-string-width-1.1.1.tgz#be659eb7937fdd2e6c9a77268daaf64bd5b7c592" + dependencies: + eastasianwidth "^0.1.1" + +power-assert@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/power-assert/-/power-assert-1.5.0.tgz#624caa76a5dc228c00f36704bb1762657c174fee" + dependencies: + define-properties "^1.1.2" + empower "^1.2.3" + power-assert-formatter "^1.3.1" + universal-deep-strict-equal "^1.2.1" + xtend "^4.0.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -1844,6 +2267,10 @@ punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" +punycode@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" @@ -1865,15 +2292,15 @@ rc@^1.1.7: strip-json-comments "~2.0.1" readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2: - version "2.3.5" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.5.tgz#b4f85003a938cbb6ecbce2a124fb1012bd1a838d" + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: core-util-is "~1.0.0" inherits "~2.0.3" isarray "~1.0.0" process-nextick-args "~2.0.0" safe-buffer "~5.1.1" - string_decoder "~1.0.3" + string_decoder "~1.1.1" util-deprecate "~1.0.1" readdirp@^2.0.0: @@ -1885,6 +2312,15 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" +realistic-structured-clone@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/realistic-structured-clone/-/realistic-structured-clone-2.0.2.tgz#2f8ec225b1f9af20efc79ac96a09043704414959" + dependencies: + core-js "^2.5.3" + domexception "^1.0.1" + typeson "^5.8.2" + typeson-registry "^1.0.0-alpha.20" + regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" @@ -1912,8 +2348,8 @@ regex-cache@^0.4.2: is-equal-shallow "^0.1.3" regexpp@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.0.1.tgz#d857c3a741dce075c2848dcb019a0a975b190d43" + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" regexpu-core@^2.0.0: version "2.0.0" @@ -2022,6 +2458,10 @@ safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safer-buffer@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + semver@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" @@ -2034,6 +2474,10 @@ set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -2064,16 +2508,26 @@ sntp@1.x.x: dependencies: hoek "2.x.x" -source-map-support@^0.4.15: +source-map-support@^0.4.0, source-map-support@^0.4.15: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" dependencies: source-map "^0.5.6" +source-map@^0.1.34: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" +source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -2107,12 +2561,20 @@ string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" dependencies: safe-buffer "~5.1.0" +stringifier@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/stringifier/-/stringifier-1.3.0.tgz#def18342f6933db0f2dbfc9aa02175b448c17959" + dependencies: + core-js "^2.0.0" + traverse "^0.6.6" + type-name "^2.0.1" + stringstream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" @@ -2133,6 +2595,12 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +supports-color@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + dependencies: + has-flag "^2.0.0" + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -2203,6 +2671,16 @@ tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +tr46@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + +traverse@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -2223,14 +2701,39 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-name@^2.0.0, type-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/type-name/-/type-name-2.0.2.tgz#efe7d4123d8ac52afff7f40c7e4dec5266008fb4" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +typeson-registry@^1.0.0-alpha.20: + version "1.0.0-alpha.21" + resolved "https://registry.yarnpkg.com/typeson-registry/-/typeson-registry-1.0.0-alpha.21.tgz#8a4e31abb471d482aa0306ad56d35af7633a166a" + dependencies: + base64-arraybuffer-es6 "0.3.1" + typeson "5.8.2" + uuid "3.2.1" + whatwg-url "6.4.0" + +typeson@5.8.2, typeson@^5.8.2: + version "5.8.2" + resolved "https://registry.yarnpkg.com/typeson/-/typeson-5.8.2.tgz#cc26f45b705760a8777fba5d3c910cc3f0e8d7dd" + uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" +universal-deep-strict-equal@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/universal-deep-strict-equal/-/universal-deep-strict-equal-1.2.2.tgz#0da4ac2f73cff7924c81fa4de018ca562ca2b0a7" + dependencies: + array-filter "^1.0.0" + indexof "0.0.1" + object-keys "^1.0.0" + user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" @@ -2239,7 +2742,7 @@ util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -uuid@^3.0.0: +uuid@3.2.1, uuid@^3.0.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" @@ -2257,6 +2760,18 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +webidl-conversions@^4.0.1, webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + +whatwg-url@6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.0" + webidl-conversions "^4.0.1" + which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" @@ -2283,6 +2798,10 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" From f3a721d64a6c690f4d468e1539a02897ee2f4a61 Mon Sep 17 00:00:00 2001 From: petamoriken Date: Mon, 16 Apr 2018 10:36:45 +0900 Subject: [PATCH 4/5] Change onupgradeneeded interface --- index.d.ts | 2 +- src/index.js | 12 +++++++----- test/SimpleIDB.js | 3 +-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/index.d.ts b/index.d.ts index 4dc2e39..95ec317 100644 --- a/index.d.ts +++ b/index.d.ts @@ -44,7 +44,7 @@ export declare class SimpleIDB { * @param version データベースのバージョン. ObjectStore や Index の変更時に増やしていく * @param onupgradeneeded ObjectStore や Index の初期化, 変更を行う函数 */ - constructor(name: string, version: number, onupgradeneeded: (this: IDBOpenDBRequest, event: IDBVersionChangeEvent, self: SimpleIDB) => any); + constructor(name: string, version: number, onupgradeneeded: (this: SimpleIDB, db: IDBDatabase, transaction: IDBTransaction, oldVersion: number, newVersion: number) => any); /** * IndexedDB を開き, 成功したら自身を返す diff --git a/src/index.js b/src/index.js index 47401d8..5ddd5c2 100644 --- a/src/index.js +++ b/src/index.js @@ -44,7 +44,7 @@ export class SimpleIDB { this._version = version | 0; /** - * @private {(this: IDBOpenDBRequest, event: IDBVersionChangeEvent, self: SimpleIDB) => any | null} + * @private {(this: SimpleIDB, db: IDBDatabase, transaction: IDBTransaction, oldVersion: number, newVersion: number) => any | null} */ this._onupgradeneeded = onupgradeneeded; @@ -83,11 +83,13 @@ export class SimpleIDB { this._ready = new Promise((resolve, reject) => { const request = indexedDB.open(name, version); - // migration request.onupgradeneeded = (event) => { - this._db = request.result; - this._versionChangeTransaction = request.transaction; - onupgradeneeded.call(request, event, this); + const {oldVersion, newVersion} = event; + const {result: db, transaction} = request; + + this._db = db; + this._versionChangeTransaction = transaction; + onupgradeneeded.call(this, db, transaction, oldVersion, newVersion); this._db = null; this._versionChangeTransaction = null; }; diff --git a/test/SimpleIDB.js b/test/SimpleIDB.js index 1633012..e0b66a9 100644 --- a/test/SimpleIDB.js +++ b/test/SimpleIDB.js @@ -19,8 +19,7 @@ describe("SimpleIDB test", () => { ]); beforeEach(async () => { - simpleIDB = new SimpleIDB("basic test" + Math.random(), 1, (event, simpleIDB) => { - const db = event.target.result; + simpleIDB = new SimpleIDB("basic test" + Math.random(), 1, (db) => { db.createObjectStore(storeName, { autoIncrement: true }); // setup From c0624d581e9b24891ccd54591afc059f39cbd8d2 Mon Sep 17 00:00:00 2001 From: petamoriken Date: Mon, 23 Apr 2018 07:28:20 +0900 Subject: [PATCH 5/5] Append test --- test/SimpleIDB.js | 80 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/test/SimpleIDB.js b/test/SimpleIDB.js index e0b66a9..99f583d 100644 --- a/test/SimpleIDB.js +++ b/test/SimpleIDB.js @@ -19,7 +19,7 @@ describe("SimpleIDB test", () => { ]); beforeEach(async () => { - simpleIDB = new SimpleIDB("basic test" + Math.random(), 1, (db) => { + simpleIDB = new SimpleIDB("test", 1, (db) => { db.createObjectStore(storeName, { autoIncrement: true }); // setup @@ -226,4 +226,82 @@ describe("SimpleIDB test", () => { await checkCurrentStore([]); }); }); + + describe.only("store object with index", () => { + let simpleIDB; + + const storeName = "user"; + const indexName = "birthday"; + const setupData = Object.freeze([ + { value: { id: faker.random.uuid(), name: faker.name.findName(), birthday: faker.date.between(1990, 1999) } }, + { value: { id: faker.random.uuid(), name: faker.name.findName(), birthday: faker.date.between(2000, 2009) } }, + { value: { id: faker.random.uuid(), name: faker.name.findName(), birthday: faker.date.between(2010, 2020) } }, + ]); + + beforeEach(async () => { + simpleIDB = new SimpleIDB("test", 1, (db) => { + const store = db.createObjectStore(storeName, { autoIncrement: true }); + store.createIndex(indexName, "birthday"); + + // setup + simpleIDB.addAll(storeName, setupData); + }); + + await simpleIDB.ready(); + }); + + afterEach(async () => { + simpleIDB.close(); + SimpleIDB.deleteDatabase(simpleIDB.name); + }); + + it("getAll", async () => { + const value = setupData[1].value; + assert.deepStrictEqual(await simpleIDB.getAll(storeName, { indexName, query: IDBKeyRange.lowerBound(new Date(2000, 0)), count: 1 }), [ + { primaryKey: 2, key: value.birthday, value }, + ]); + }); + + it("getAllKeys", async () => { + const value = setupData[1].value; + assert.deepStrictEqual(await simpleIDB.getAllKeys(storeName, { indexName, query: IDBKeyRange.lowerBound(new Date(2000, 0)), count: 1 }), [ + { primaryKey: 2, key: value.birthday }, + ]); + }); + + it("getAllValues", async () => { + const value = setupData[1].value; + assert.deepStrictEqual(await simpleIDB.getAllValues(storeName, { indexName, query: IDBKeyRange.lowerBound(new Date(2000, 0)), count: 1 }), [ + { value }, + ]); + }); + + it("updateAll", async () => { + const name = faker.name.findName(); + await simpleIDB.updateAll(storeName, (value) => Object.assign(value, name), { indexName, query: IDBKeyRange.lowerBound(new Date(2000, 0)), count: 1 }); + assert.deepStrictEqual(await simpleIDB.getAll(storeName), [ + { primaryKey: 1, key: 1, value: setupData[0].value }, + { primaryKey: 2, key: 2, value: Object.assign(setupData[1].value, name) }, + { primaryKey: 3, key: 3, value: setupData[2].value }, + ]); + }); + + it("deleteAll", async () => { + await simpleIDB.deleteAll(storeName, { indexName, query: IDBKeyRange.lowerBound(new Date(2000, 0)), count: 1 }); + assert.deepStrictEqual(await simpleIDB.getAll(storeName), [ + { primaryKey: 1, key: 1, value: setupData[0].value }, + { primaryKey: 3, key: 3, value: setupData[2].value }, + ]); + }); + + it("takeAll", async () => { + assert.deepStrictEqual(await simpleIDB.takeAll(storeName, { indexName, query: IDBKeyRange.lowerBound(new Date(2000, 0)), count: 1 }), [ + { primaryKey: 2, key: setupData[1].value.birthday, value: setupData[1].value } + ]); + assert.deepStrictEqual(await simpleIDB.getAll(storeName), [ + { primaryKey: 1, key: 1, value: setupData[0].value }, + { primaryKey: 3, key: 3, value: setupData[2].value }, + ]); + }); + }); });