Comparing version 3.0.2 to 4.0.0-beta.0
{ | ||
"name": "idb", | ||
"version": "3.0.2", | ||
"description": "IndexedDB but with promises", | ||
"main": "lib/node.js", | ||
"module": "lib/idb.mjs", | ||
"browser": "build/idb.js", | ||
"typings": "lib/idb.d.ts", | ||
"version": "4.0.0-beta.0", | ||
"description": "A small wrapper that makes IndexedDB usable", | ||
"main": "build/cjs/index.js", | ||
"module": "build/esm/index.mjs", | ||
"typings": "build/esm/index.d.ts", | ||
"scripts": { | ||
"build": "rollup lib/idb.mjs --file build/idb.js --format umd --name idb" | ||
"clean": "rm -r build test-build", | ||
"build": "npm run clean && rollup -c && gzip-size build/iife/index-min.js && gzip-size build/iife/with-async-ittr-min.js", | ||
"dev": "npm run clean && rollup -c --watch" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/jakearchibald/indexeddb-promised.git" | ||
"url": "git://github.com/jakearchibald/idb.git" | ||
}, | ||
@@ -19,4 +20,19 @@ "author": "Jake Archibald", | ||
"devDependencies": { | ||
"rollup": "^1.0.2" | ||
"@types/chai": "^4.1.7", | ||
"@types/mocha": "^5.2.6", | ||
"chai": "^4.2.0", | ||
"conditional-type-checks": "^1.0.0", | ||
"gzip-size-cli": "^3.0.0", | ||
"mocha": "^6.0.2", | ||
"rollup": "^1.6.0", | ||
"rollup-plugin-commonjs": "^9.2.1", | ||
"rollup-plugin-copy": "^0.2.3", | ||
"rollup-plugin-node-resolve": "^4.0.1", | ||
"rollup-plugin-terser": "^4.0.4", | ||
"rollup-plugin-typescript2": "^0.19.3", | ||
"tslint": "^5.13.1", | ||
"tslint-config-airbnb": "^5.11.1", | ||
"tslint-react": "^3.6.0", | ||
"typescript": "^3.3.3333" | ||
} | ||
} |
496
README.md
@@ -1,9 +0,22 @@ | ||
# IndexedDB Promised | ||
# IndexedDB with usability. | ||
This is a tiny library that mirrors IndexedDB, but replaces the weird `IDBRequest` objects with promises, plus a couple of other small changes. | ||
This is a tiny (~1.17k) library that mostly mirrors the IndexedDB API, but with small improvements that make a big difference to usability. | ||
1. [Installation](#installation) | ||
1. [Changes](#changes) | ||
1. [API](#api) | ||
1. [`openDB`](#opendb) | ||
1. [`deleteDB`](#deletedb) | ||
1. [`unwrap`](#unwrap) | ||
1. [`wrap`](#wrap) | ||
1. [General enhancements](#general-enhancements) | ||
1. [`IDBDatabase` enhancements](#idbdatabase-enhancements) | ||
1. [`IDBTransaction` enhancements](#idbtransaction-enhancements) | ||
1. [`IDBCursor` enhancements](#idbcursor-enhancements) | ||
1. [Async iterators](#async-iterators) | ||
1. [Examples](#examples) | ||
1. [TypeScript](#typescript) | ||
# Installation | ||
If you're using Rollup/Webpack or similar: | ||
```sh | ||
@@ -13,377 +26,308 @@ npm install idb | ||
Then in your JS: | ||
Then, assuming you're using a module-compatible system (like Webpack, Rollup etc): | ||
```js | ||
import { openDb, deleteDb } from 'idb'; | ||
import { openDB, deleteDB, wrap, unwrap } from 'idb'; | ||
await openDb(…); | ||
async function doDatabaseStuff() { | ||
const db = await openDB(…); | ||
} | ||
``` | ||
Or include [the script](https://github.com/jakearchibald/idb/blob/master/build/idb.js) as it is, and `idb` will exist on the global scope. | ||
# Changes | ||
# Changes from 2.x | ||
This is a rewrite from 3.x. [See changes](changes.md). | ||
The library is now a module. To take advantage of this, importing has changed slightly: | ||
# API | ||
```js | ||
// Old 2.x way: | ||
import idb from 'idb'; | ||
idb.open(…); | ||
idb.delete(…); | ||
## `openDB` | ||
// New way: | ||
import { openDb, deleteDb } from 'idb'; | ||
openDb(…); | ||
deleteDb(…); | ||
``` | ||
This method opens a database, and returns a promise for an enhanced [`IDBDatabase`](https://w3c.github.io/IndexedDB/#database-interface). | ||
# Examples | ||
## Keyval Store | ||
This is very similar to `localStorage`, but async. If this is *all* you need, you may be interested in [idb-keyval](https://www.npmjs.com/package/idb-keyval), you can always upgrade to this library later. | ||
```js | ||
const dbPromise = openDb('keyval-store', 1, upgradeDB => { | ||
upgradeDB.createObjectStore('keyval'); | ||
}); | ||
const idbKeyval = { | ||
async get(key) { | ||
const db = await dbPromise; | ||
return db.transaction('keyval').objectStore('keyval').get(key); | ||
const db = await openDB(name, version, { | ||
upgrade(db, oldVersion, newVersion, transaction) { | ||
// … | ||
}, | ||
async set(key, val) { | ||
const db = await dbPromise; | ||
const tx = db.transaction('keyval', 'readwrite'); | ||
tx.objectStore('keyval').put(val, key); | ||
return tx.complete; | ||
blocked() { | ||
// … | ||
}, | ||
async delete(key) { | ||
const db = await dbPromise; | ||
const tx = db.transaction('keyval', 'readwrite'); | ||
tx.objectStore('keyval').delete(key); | ||
return tx.complete; | ||
}, | ||
async clear() { | ||
const db = await dbPromise; | ||
const tx = db.transaction('keyval', 'readwrite'); | ||
tx.objectStore('keyval').clear(); | ||
return tx.complete; | ||
}, | ||
async keys() { | ||
const db = await dbPromise; | ||
return db.transaction('keyval').objectStore('keyval').getAllKeys(key); | ||
}, | ||
}; | ||
blocking() { | ||
// … | ||
} | ||
}); | ||
``` | ||
### Usage | ||
* `name`: Name of the database. | ||
* `version`: Schema version. | ||
* `upgrade` (optional): Called if this version of the database has never been opened before. Use it to specify the schema for the database. This is similar to the `upgradeneeded` event in plain IndexedDB. | ||
* `db`: An enhanced `IDBDatabase`. | ||
* `oldVersion`: Last version of the database opened by the user. | ||
* `newVersion`: Whatever new version you provided. | ||
* `transaction`: The transaction for this upgrade. This is useful if you need to get data from other stores as part of a migration. | ||
* `blocked` (optional): Called if there are older versions of the database open on the origin, so this version cannot open. | ||
* `blocking` (optional): Called if this connection is blocking a future version of the database from opening. | ||
## `deleteDB` | ||
Delete a database. | ||
```js | ||
idbKeyval.set('foo', {hello: 'world'}); | ||
// logs: {hello: 'world'} | ||
idbKeyval.get('foo').then(val => console.log(val)); | ||
await deleteDB(name); | ||
``` | ||
## Set of objects | ||
* `name`: Name of the database. | ||
Imagine we had a set of objects like… | ||
## `unwrap` | ||
```json | ||
{ | ||
"id": 123456, | ||
"data": {"foo": "bar"} | ||
} | ||
```js | ||
const unwrapped = unwrap(wrapped); | ||
``` | ||
### Upgrading existing DB | ||
If for some reason you want to drop back into plain IndexedDB, give one of the enhanced objects to `unwrap` and you'll get the unmodified version back. | ||
```js | ||
const dbPromise = openDb('keyval-store', 2, upgradeDB => { | ||
// Note: we don't use 'break' in this switch statement, | ||
// the fall-through behaviour is what we want. | ||
switch (upgradeDB.oldVersion) { | ||
case 0: | ||
upgradeDB.createObjectStore('keyval'); | ||
case 1: | ||
upgradeDB.createObjectStore('objs', {keyPath: 'id'}); | ||
} | ||
}); | ||
``` | ||
Promises will also be converted back into `IDBRequest` objects. | ||
### Adding | ||
## `wrap` | ||
```js | ||
dbPromise.then(db => { | ||
const tx = db.transaction('objs', 'readwrite'); | ||
tx.objectStore('objs').put({ | ||
id: 123456, | ||
data: {foo: "bar"} | ||
}); | ||
return tx.complete; | ||
}); | ||
const wrapped = wrap(unwrapped); | ||
``` | ||
### Getting all | ||
Use this to convert a plain IDB object to one enhanced by this library. This is useful if some third party code gives you an `IDBDatabase` object and you want it to have the features of this library. | ||
```js | ||
dbPromise.then(db => { | ||
return db.transaction('objs') | ||
.objectStore('objs').getAll(); | ||
}).then(allObjs => console.log(allObjs)); | ||
``` | ||
This doesn't work with `IDBCursor`, [due to missing primitives](https://github.com/w3c/IndexedDB/issues/255). Also, if you wrap an `IDBTransaction`, `tx.store` and `tx.objectStoreNames` will not work in Edge. To avoid these issues, wrap the `IDBDatabase` object, and use the wrapped object to create a new transaction. | ||
### Getting by ID | ||
## General enhancements | ||
Once you've opened the database the API is the same as IndexedDB, except for a few changes to make things easier. | ||
Any method that usually returns an `IDBRequest` object will now return a promise for the result. | ||
```js | ||
dbPromise.then(db => { | ||
return db.transaction('objs') | ||
.objectStore('objs').get(123456); | ||
}).then(obj => console.log(obj)); | ||
const store = db.transaction(storeName).objectStore(storeName); | ||
const value = await store.get(key); | ||
``` | ||
# Limitations | ||
## `IDBDatabase` enhancements | ||
## Transaction lifetime | ||
### Shortcuts to get/set from an object store | ||
An IDB transaction will auto-close if it doesn't have anything to do once microtasks have been processed. As a result, this works fine: | ||
It's common to create a transaction for a single action, so helper methods are included for this: | ||
```js | ||
dbPromise.then(async db => { | ||
const tx = db.transaction('keyval', 'readwrite'); | ||
const store = tx.objectStore('keyval'); | ||
const val = await store.get('counter') || 0; | ||
store.put(val + 1, 'counter'); | ||
return tx.complete; | ||
}); | ||
// Get a value from a store: | ||
const value = await db.get(storeName, key); | ||
// Set a value in a store: | ||
await db.put(storeName, value, key); | ||
``` | ||
But this doesn't: | ||
The shortcuts are: `get`, `getKey`, `getAll`, `getAllKeys`, `count`, `put`, `add`, `delete`, and `clear`. Each method takes a `storeName` argument, the name of the object store, and the rest of the arguments are the same as the equivalent `IDBObjectStore` method. | ||
```js | ||
dbPromise.then(async db => { | ||
const tx = db.transaction('keyval', 'readwrite'); | ||
const store = tx.objectStore('keyval'); | ||
const val = await store.get('counter') || 0; | ||
// The transaction will auto-close while the fetch is in-progress | ||
const newVal = await fetch('/increment?val=' + val) | ||
store.put(newVal, 'counter'); | ||
return tx.complete; | ||
}); | ||
``` | ||
These methods depend on the same methods on `IDBObjectStore`, therefore `getKey`, `getAll`, and `getAllKeys` are missing in Edge as it lacks support. | ||
## Promise issues in older browsers | ||
### Shortcuts to get from an index | ||
Some older browsers don't handle promises properly, which causes issues if you do more than one thing in a transaction: | ||
The shortcuts are: `getFromIndex`, `getKeyFromIndex`, `getAllFromIndex`, `getAllKeysFromIndex`, and `countFromIndex`. | ||
```js | ||
dbPromise.then(async db => { | ||
const tx = db.transaction('keyval', 'readwrite'); | ||
const store = tx.objectStore('keyval'); | ||
const val = await store.get('counter') || 0; | ||
// In some older browsers, the transaction closes here. | ||
// Meaning this next line fails: | ||
store.put(val + 1, 'counter'); | ||
return tx.complete; | ||
}); | ||
// Get a value from an index: | ||
const value = await db.getFromIndex(storeName, indexName, key); | ||
``` | ||
All modern browsers have fixed this. [Test your browser](https://simple-idb-demo.glitch.me/microtask-issue.html). | ||
Each method takes `storeName` and `indexName` arguments, followed by the rest of the arguments from the equivalent `IDBIndex` method. Again, these methods depend on the equivalent methods on `IDBIndex`, so Edge does not support `getKeyFromIndex`, `getAllFromIndex`, or `getAllKeysFromIndex`. | ||
You can work around this in some versions of Firefox by using a promise polyfill that correctly uses microtasks, such as [es6-promise](https://github.com/jakearchibald/es6-promise). | ||
## `IDBTransaction` enhancements | ||
# API | ||
### `tx.store` | ||
## `idb` | ||
If a transaction involves a single store, the `store` property will reference that store. | ||
This is your entry point to the API. It's exposed to the global scope unless you're using a module system such as browserify, in which case it's the exported object. If you are using native ES modules, the functions are provided as individual exports, so you can `import * as idb from 'idb'` or `import { openDb, deleteDb } from 'idb'`. | ||
```js | ||
const tx = db.transaction('whatever'); | ||
const store = tx.store; | ||
``` | ||
### `openDb(name, version, upgradeCallback)` | ||
If a transaction involves multiple stores, `tx.store` is undefined. | ||
This method returns a promise that resolves to a `DB`. | ||
### `tx.done` | ||
`name` and `version` behave as they do in `indexedDB.open`. | ||
Transactions have a `.done` promise which resolves when the transaction completes successfully, and otherwise rejects. | ||
`upgradeCallback` is called if `version` is greater than the version last opened. It's similar to IDB's `onupgradeneeded`. The callback receives an instance of `UpgradeDB`. | ||
```js | ||
openDb('keyval-store', 2, upgradeDB => { | ||
// Note: we don't use 'break' in this switch statement, | ||
// the fall-through behaviour is what we want. | ||
switch (upgradeDB.oldVersion) { | ||
case 0: | ||
upgradeDB.createObjectStore('keyval'); | ||
case 1: | ||
upgradeDB.createObjectStore('stuff', {keyPath: ''}); | ||
} | ||
}).then(db => console.log("DB opened!", db)); | ||
const tx = db.transaction(storeName, 'readwrite'); | ||
tx.store.put('foo', 'bar'); | ||
await tx.done; | ||
``` | ||
### `deleteDb(name)` | ||
## `IDBCursor` enhancements | ||
Behaves like `indexedDB.deleteDatabase`, but returns a promise. | ||
Cursor advance methods (`advance`, `continue`, `continuePrimaryKey`) return a promise for the cursor, or null if there are no further values to provide. | ||
```js | ||
deleteDb('keyval-store').then(() => console.log('done!')); | ||
const store = db.transaction(storeName).objectStore(storeName); | ||
let cursor = await store.openCursor(); | ||
while (cursor) { | ||
console.log(cursor.key, cursor.value); | ||
cursor = await cursor.continue(); | ||
} | ||
``` | ||
## `DB` | ||
## Async iterators | ||
Properties: | ||
Async iterator support isn't included by default (Edge doesn't support them). To include them, import `idb/with-async-ittr.mjs` (~1.39k) instead of `idb`: | ||
* Same as equivalent properties on an instance of `IDBDatabase`: | ||
* `name` | ||
* `version` | ||
* `objectStoreNames` | ||
```js | ||
import { openDB } from 'idb/with-async-ittr.mjs'; | ||
``` | ||
Methods: | ||
Now you can iterate over stores, indexes, and cursors: | ||
* `close` - as `idbDatabase.close` | ||
* `transaction` - as `idbDatabase.transaction`, but returns a `Transaction` | ||
```js | ||
const tx = db.transaction(storeName); | ||
## `UpgradeDB` | ||
for await (const cursor of tx.store) { | ||
// … | ||
} | ||
``` | ||
As `DB`, except: | ||
Each yielded object is an `IDBCursor`. You can optionally use the advance methods to skip items (within an async iterator they return void): | ||
Properties: | ||
```js | ||
const tx = db.transaction(storeName); | ||
* `transaction` - this is a property rather than a method. It's a `Transaction` representing the upgrade transaction | ||
* `oldVersion` - the previous version of the DB seen by the browser, or 0 if it's new | ||
for await (const cursor of tx.store) { | ||
console.log(cursor.value); | ||
// Skip the next item | ||
cursor.advance(2); | ||
} | ||
``` | ||
Methods: | ||
If you don't manually advance the cursor, `cursor.continue()` is called for you. | ||
* `createObjectStore` - as `idbDatabase.createObjectStore`, but returns an `ObjectStore` | ||
* `deleteObjectStore` - as `idbDatabase.deleteObjectStore` | ||
Stores and indexes also have an `iterate` method which has the same signiture as `openCursor`, but returns an async iterator: | ||
## `Transaction` | ||
```js | ||
const tx = db.transaction('books'); | ||
const index = tx.store.index('author'); | ||
Properties: | ||
for await (const cursor of index.iterate('Douglas Adams')) { | ||
console.log(cursor.value); | ||
} | ||
``` | ||
* `complete` - a promise. Resolves when transaction completes, rejects if transaction aborts or errors | ||
* Same as equivalent properties on an instance of `IDBTransaction`: | ||
* `objectStoreNames` | ||
* `mode` | ||
# Examples | ||
Methods: | ||
## Keyval Store | ||
* `abort` - as `idbTransaction.abort` | ||
* `objectStore` - as `idbTransaction.objectStore`, but returns an `ObjectStore` | ||
This is very similar to `localStorage`, but async. If this is *all* you need, you may be interested in [idb-keyval](https://www.npmjs.com/package/idb-keyval), you can always upgrade to this library later. | ||
```js | ||
openDb('keyval-store', 1, upgradeDB => { | ||
switch (upgradeDB.oldVersion) { | ||
case 0: | ||
upgradeDB.createObjectStore('keyval'); | ||
const dbPromise = openDB('keyval-store', 1, { | ||
upgrade(db) { | ||
db.createObjectStore('keyval'); | ||
} | ||
}).then(db => { | ||
const tx = db.transaction('keyval', 'readwrite'); | ||
tx.objectStore('keyval').put('hello', 'world'); | ||
return tx.complete; | ||
}).then(() => console.log("Done!")); | ||
}); | ||
const idbKeyval = { | ||
async get(key) { | ||
return (await dbPromise).get('keyval', key); | ||
}, | ||
async set(key, val) { | ||
return (await dbPromise).put('keyval', val, key); | ||
}, | ||
async delete(key) { | ||
return (await dbPromise).delete('keyval', key); | ||
}, | ||
async clear() { | ||
return (await dbPromise).clear('keyval'); | ||
}, | ||
async keys() { | ||
return (await dbPromise).getAllKeys('keyval'); | ||
}, | ||
}; | ||
``` | ||
## `ObjectStore` | ||
# TypeScript | ||
Properties: | ||
This library is fully typed, and you can improve things by providing types for your database: | ||
* Same as equivalent properties on an instance of `IDBObjectStore`: | ||
* `name` | ||
* `keyPath` | ||
* `indexNames` | ||
* `autoIncrement` | ||
```ts | ||
import { openDB, DBSchema } from 'idb'; | ||
Methods: | ||
interface MyDB extends DBSchema { | ||
'favourite-numbers': { | ||
key: string, | ||
value: number[], | ||
}, | ||
'products': { | ||
value: { | ||
name: string, | ||
price: number, | ||
productCode: string, | ||
}, | ||
key: string, | ||
indexes: { 'by-price': number }, | ||
} | ||
} | ||
* Same as equivalent methods on an instance of `IDBObjectStore`, but returns a promise that resolves/rejects based on operation success/failure: | ||
* `put` | ||
* `add` | ||
* `delete` | ||
* `clear` | ||
* `get` | ||
* `getAll` | ||
* `getAllKeys` | ||
* `count` | ||
* Same as equivalent methods on an instance of `IDBObjectStore`, but returns a promise that resolves with a `Cursor`: | ||
* `openCursor` | ||
* `openKeyCursor` | ||
* `deleteIndex` - as `idbObjectStore.deleteIndex` | ||
* Same as equivalent methods on an instance of `IDBObjectStore`, but returns an `Index`: | ||
* `createIndex` | ||
* `index` | ||
* `iterateCursor` - see below | ||
* `iterateKeyCursor` - see below | ||
async function demo() { | ||
const db = await openDB<MyDB>('my-db', 1, { | ||
upgrade(db) { | ||
db.createObjectStore('favourite-numbers'); | ||
const productStore = db.createObjectStore('products', { keyPath: 'productCode' }); | ||
productStore.createIndex('by-price', 'price'); | ||
} | ||
}); | ||
### `iterateCursor` & `iterateKeyCursor` | ||
Due to the microtask issues in some browsers, iterating over a cursor using promises doesn't always work: | ||
```js | ||
const tx = db.transaction('stuff'); | ||
tx.objectStore('stuff').openCursor().then(function cursorIterate(cursor) { | ||
if (!cursor) return; | ||
console.log(cursor.value); | ||
return cursor.continue().then(cursorIterate); | ||
}); | ||
tx.complete.then(() => console.log('done')); | ||
// This works | ||
await db.put('favourite-numbers', [7, 95, 1023], 'Jen'); | ||
// This fails, as the 'favourite-numbers' store expects an array of numbers. | ||
await db.put('favourite-numbers', ['Twelve'], 'Jake'); | ||
} | ||
``` | ||
So in the mean time, `iterateCursor` and `iterateKeyCursor` map to `openCursor` & `openKeyCursor`, take identical arguments, plus an additional callback that receives an `IDBCursor`, so the above example becomes: | ||
To define types for your database, extend `DBSchema` with an interface where the keys are the names of your object stores. | ||
```js | ||
const tx = db.transaction('stuff'); | ||
tx.objectStore('stuff').iterateCursor(cursor => { | ||
if (!cursor) return; | ||
console.log(cursor.value); | ||
cursor.continue(); | ||
}); | ||
tx.complete.then(() => console.log('done')); | ||
``` | ||
For each value, provide an object where `value` is the type of values within the store, and `key` is the type of keys within the store. | ||
The intent is to remove `iterateCursor` and `iterateKeyCursor` from the library once browsers support promises and microtasks correctly. | ||
Optionally, `indexes` can contain a map of index names, to the type of key within that index. | ||
## `Index` | ||
Provide this interface when calling `openDB`, and from then on your database will be strongly typed. This also allows your IDE to autocomplete the names of stores and indexes. | ||
Properties: | ||
## Opting out of types | ||
* Same as equivalent properties on an instance of `IDBIndex`: | ||
* `name` | ||
* `keyPath` | ||
* `multiEntry` | ||
* `unique` | ||
If you call `openDB` without providing types, your database will use basic types. However, sometimes you'll need to interact with stores that aren't in your schema, perhaps during upgrades. In that case you can cast. | ||
Methods: | ||
Let's say we were renaming the 'favourite-numbers' store to 'fave-nums': | ||
* Same as equivalent methods on an instance of `IDBIndex`, but returns a promise that resolves/rejects based on operation success/failure: | ||
* `get` | ||
* `getKey` | ||
* `getAll` | ||
* `getAllKeys` | ||
* `count` | ||
* Same as equivalent methods on an instance of `IDBIndex`, but returns a promise that resolves with a `Cursor`: | ||
* `openCursor` | ||
* `openKeyCursor` | ||
* `iterateCursor` - as `objectStore.iterateCursor` but over the index | ||
* `iterateKeyCursor` - as `objectStore.iterateKeyCursor` but over the index | ||
```ts | ||
import { openDB, DBSchema, IDBPDatabase, IDBPTransaction } from 'idb'; | ||
## Cursor | ||
interface MyDBV1 extends DBSchema { | ||
'favourite-numbers': { key: string, value: number[] }, | ||
} | ||
Properties: | ||
interface MyDBV2 extends DBSchema { | ||
'fave-nums': { key: string, value: number[] }, | ||
} | ||
* Same as equivalent properties on an instance of `IDBCursor`: | ||
* `direction` | ||
* `key` | ||
* `primaryKey` | ||
* `value` | ||
const db = await openDB<MyDBV2>('my-db', 2, { | ||
async upgrade(db, oldVersion) { | ||
// Cast a reference of the database to the old schema. | ||
const v1Db = db as unknown as IDBPDatabase<MyDBV1>; | ||
Methods: | ||
if (oldVersion < 1) { | ||
v1Db.createObjectStore('favourite-numbers'); | ||
} | ||
if (oldVersion < 2) { | ||
const store = v1Db.createObjectStore('favourite-numbers'); | ||
store.name = 'fave-nums'; | ||
} | ||
} | ||
}); | ||
``` | ||
* Same as equivalent methods on an instance of `IDBCursor`, but returns a promise that resolves/rejects based on operation success/failure: | ||
* `update` | ||
* `delete` | ||
* Same as equivalent methods on an instance of `IDBCursor`, but returns a promise that resolves with a `Cursor`: | ||
* `advance` | ||
* `continue` | ||
* `continuePrimaryKey` | ||
You can also cast to a typeless database by omiting the type, eg `db as IDBPDatabase`. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37
4720
189950
16
2
333
1