
Research
Shai-Hulud Descends to Hades: Miasma Worm Campaign Spreads with New PyPI Wave
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.
Promise-based indexedDB: a wrapper object which provides a nicer and more useable API for client-side storage in indexedDB.
PixDB is compatible with modern browsers which supports ES modules.
Load the module from a CDN:
import { PixDB } from 'https://cdn.jsdelivr.net/npm/pixdb/dist/pixdb.js'
If using npm and a bundler, install with:
npm install pixdb
then import the module locally (path resolution will depend on the bundler):
import { PixDB } from 'pixdb';
// or perhaps: import { PixDB } from './node_modules/pixdb/dist/pixdb.js';
Most methods are asynchronous and Promise-based so you must use async/await or .then chains.
Initialize a new connection with a database name, version, and an optional upgrade function. The upgrade function receives the connection, the old version number, and the new version number so it can create object stores and indexes:
// initialize
const db = await new PixDB('db', 1, (init, oldVersion, newVersion) => {
log(`upgrading database from ${ oldVersion } to ${ newVersion }`);
switch (oldVersion) {
case 0: {
const state = init.createObjectStore('state', { keyPath: 'name' });
state.createIndex('updateIdx', 'update', { unique: false });
}
}
});
This creates an object store named state with a key on the name property and an index named updateIdx on the update property.
You can check the connection, name, and version:
// db 1 true
console.log( db.name, db.version, db.isConnected );
Add a single new record into state - but not permit overwrites:
await db.add({ store: 'state', item: { name: 'a', value: 1, update: new Date() } });
or add an array of records (again, overwriting is not permitted):
await db.add({ store: 'state', item: [
{ name: 'b', value: 'two', update: new Date() },
{ name: 'c', value: [3,3,3], update: new Date() }
]
});
The .put() method is identical to .add() except it permits overwrites:
await db.put({ store: 'state', item: { name: 'a', value: 'new' } });
Count the number of items in a store:
// 3
await db.count({ store: 'state' });
Get a single value by its key:
// { name: 'a', value: 'new' }
await db.get({ store: 'state', key: 'a'});
Get an array of all values with a lowerBound, upperBound, and a maximum count of records:
// [
// { name: 'a', value: 'new' },
// { name: 'b', value: 'two', update: '2023-08-18' },
// { name: 'c', value: [3,3,3], update: '2023-08-18' }
// ]
await db.getAll({ store: 'state', lowerBound: 'a', upperBound: 'z', count: 5 });
Get an array of all store keys:
// ['a', 'b', 'c']
await db.getAllKeys({ store: 'state' });
Use a cursor to iterate through each record one at a time and pass the value to a synchronous callback function:
await db.getCursor({
store: 'state',
callback: cursor => console.log( cursor.value )
});
Note that if the callback function returns a numeric number greater than 1, it will jump forward that number of records.
Delete a record using its key:
await db.delete({ store: 'state', key: 'a' });
Clear every record in a store:
await db.clear({ store: 'state' });
Close the database connection:
await db.close();
Most PixDB object methods:
The PixDB constructor parameters:
| name | type | description |
|---|---|---|
name | string | database name |
version | number | version number |
upgrade | function | upgrade function |
The upgrade function receives the database connection, oldVersion, and newVersion.
The constructor returns a Promise which resolves/rejects when the database connection is established, so await can be used:
Example:
const db = await new PixDB('db', 1, (init, oldVersion, newVersion) => {
log(`upgrading database from ${ oldVersion } to ${ newVersion }`);
switch (oldVersion) {
case 0: {
const state = init.createObjectStore('state', { keyPath: 'name' });
state.createIndex('updateIdx', 'update', { unique: false });
}
}
});
Returns true when the database connection is active.
Returns the database name string (or null if the database has been dropped).
Returns the database version number (or null if the database has been dropped).
Add one or more new records but does not permit overwrites.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
item | object | array | single record or an array of records to add |
Returns a Promise which resolves/rejects when all records are written.
// add one record
await db.add({ store: 'state', item: { name: 'a', value: 1 } });
// add more than one record in one transaction
await db.add({ store: 'state', item: [
{ name: 'b', value: 2 },
{ name: 'c', value: 3 }
]
});
Identical to .add() except overwrites are permitted.
Delete a record in an object store by key name.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
key | * | key value (required) |
Returns a Promise which resolves/rejects when the record is deleted. It also resolves if the record does not exist.
await db.delete({ store: 'state', key: 'a' });
Delete all records referenced between optional lower and upper boundaries on a store or index.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
index | string | object store index |
lowerBound | * | lower key value |
upperBound | * | upper key value |
Returns a Promise which resolves/rejects all records are deleted.
await db.deleteAll({ store: 'state', lowerBound: 'x', upperBound: 'z' });
Delete all records in an object store.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
Returns a Promise which resolves/rejects when all store records are deleted.
await db.clear({ store: 'state' });
Count records in an object store or index.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
index | string | object store index |
lowerBound | * | lower key value |
upperBound | * | upper key value |
Returns a Promise which resolves/rejects when number of records is determined.
// number of records in 'state'
await db.count({ store: 'state' });
// number of records in 'state' starting from 'x'
await db.count({ store: 'state', lowerBound: 'x' });
Fetches a single record referenced by key or index key.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
index | string | object store index |
key | * | key value (required) |
Returns a Promise which resolves/rejects when record is found or not found.
const a = await db.get({ store: 'state', key: 'a'});
Fetches an array of records referenced between optional lower and upper boundaries on a store or index.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
index | string | object store index |
lowerBound | * | lower key value |
upperBound | * | upper key value |
count | number | maximum number of records |
Returns a Promise which resolves/rejects when an array of records is found.
const all = await db.getAll({ store: 'state', lowerBound: 'a', upperBound: 'z', count: 10 });
Fetches an array of record keys referenced between optional lower and upper boundaries on a store or index.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
index | string | object store index |
lowerBound | * | lower key value |
upperBound | * | upper key value |
count | number | maximum number of records |
Returns a Promise which resolves/rejects when an array of keys is found.
const allKeys = await db.getAllKeys({ store: 'state' });
Fetches all records in a store or index range and pass each to a processing callback function.
paramObject properties:
| property | type | description |
|---|---|---|
store | string | object store (required) |
index | string | object store index |
lowerBound | * | lower key value |
upperBound | * | upper key value |
direction | string | direction to travel: next (default), nextunique, prev, or prevunique |
callback | function | the cursor is passed to this synchronous function so cursor methods can be used. The function can optionally return a positive integer to jump forward N records |
Returns a Promise which resolves/rejects once all records have been processed.
await db.getCursor({
store: 'state',
callback: cursor => console.log(cursor.value)
});
Close the database connection. Nothing is returned.
db.close();
Reconnect to database after .close() has closed a connection. Returns a Promise which resolves/rejects when the database connection is established.
await db.connect();
Delete the whole database, its stores, indexes, and data. Returns a Promise which resolves/rejects when database has been deleted.
await db.drop();
You are free to use this as you like but please do not republish it as your own work.
Please consider sponsorship if you use PixDB commercially, require support, or need new features.
FAQs
Promise-based indexedDB wrapper
We found that pixdb demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.