A lightweight, type-safe ORM for IndexedDB that closely matches the supabase-js API.
npm i @yuo-app/idb-ormimport{typeDatabase,typeDatabaseSchema,IdbOrm}from'@yuo-app/idb-orm'// Define your database schemaconstschema={users: {id: {type: 'number',primaryKey: true},name: {type: 'string',required: true},age: {type: 'number'},}}satisfiesDatabaseSchema// Types are automatically inferred from schematypeDB=Database<typeofschema>typeUser=DB['users']// { id: number, name: string, age?: number }// Initialize and connectconstdb=newIdbOrm('database',1,schema)awaitdb.connect()Don't forget to increment the database version when you change the schema!
Use primaryKey: true to define a primary key.
type: 'number'can be used to auto-increment the primary key combined withautoIncrement: true.type: 'string'generates a UUID
string, number, boolean, array, object
Use required: true to enforce a field to be non-nullable.
Use default to set a default value.
Note
idb-orm differs from supabase-js in one key way:
- you need to terminate chains with
get()to execute them. get()will always return the modified data like when supabase'sselect()is called on insert methods.
Use from() to select a table, and select() to retrieve data.
constallUsers=awaitdb.from('users').select().get()select(...fields) can be used to select specific fields.
constuserIdsAndNames=awaitdb.from('users').select('id','name').get()getAll() can be used to get the entire database.
constallData=awaitdb.getAll()insert() will insert a new record and return the inserted data.
Tip
It's recommended to use upsert() which directly inserts or updates a record.
- use
insert()only if you want it to fail when the record already exists update()will not fail if the record does not exist, it will return an empty array
awaitdb.from('users').insert({name: 'Me',age: 30}).get()Use the Insert and Update helper types to create your actions.
typeUserInsert=Insert<typeofschema['users']>// id is optional, fields with default values are optionaltypeUserUpdate=Update<typeofschema['users']>// all fields are optional (Partial<> also works)update() will update records that match the query and return the updated data.
awaitdb.from('users').update({age: 31}).eq('name','Me').get()upsert() will insert a new record or update an existing record and return the data.
awaitdb.from('users').upsert({name: 'Me',age: 31}).get()delete() will remove records that match the query.
awaitdb.from('users').delete().eq('name','Me').get()Use eq(), neq(), gt(), gte(), lt(), lte() to filter records.
constadults=awaitdb.from('users').select().gte('age',18).get()Sort records using order(field, direction). Use asc or desc for the direction.
constsortedUsers=awaitdb.from('users').select().order('age','asc').get()Use limit() to return the first N records. Combine this with sort() to get the last N records.
constfirstUser=awaitdb.from('users').select().limit(3).get()offset() can be used to skip the first N records.
single() can be used instead of get() to return just one row of data, and not an array.
constuser=awaitdb.from('users').limit(1).single()Use getTableNames() to get a list of table names.
consttableNames=awaitdb.getTableNames()// ['users']clearAll() will remove all data but keep the tables.
deleteAll() will remove all data and tables.
awaitdb.clearAll()awaitdb.deleteAll()MIT