npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

an-db

v1.0.9

Published

小巧好用的本地存储管理模块

Downloads

9

Readme

An-DB

小巧好用的本地存储管理模块

什么是本地存储

如今,在web端,我们常见的缓存有如下几种

  • localStorage & sessionStorage 简单灵活,方便存取数据,但是存储空间只有2.5M~10M之间,碰见一些大型数据就显得有些束手无策了
  • cookie 每次请求都会携带,但存储大小只有4KB,很难满足当下的业务场景
  • indexDb 最接近真正意义上的数据库,能建立索引,提供增删改查能力,但操作比较繁琐。

An-DB 能做什么

提供了一整套基于 indexDb 的最纯粹的函数库,让你能再使用 indexDb 时更方便,直观。

An-DB 有哪些优势

  • 完整的TypeScript类型检查
  • 简单好用的API
  • 更加严谨的数据结构检查
  • 。。。

安装

npm install an-db
or
yarn add an-db

快速上手

import andb, { columnType } from 'an-db'

const db = await andb.useDB('person')

const student = await db.useTable(
    'student',
    {
        structure: {
            name: {
                type: columnType.String,
                unique: true
            },
            age: {
                type: columnType.Number,
                required: true
            }
        },
        index: ['name', 'age']
    }
)

// 添加数据
const result = await student.inset({ name: 'Tom', age: 18 })
console.log(result) // 1

// 查询数据
const result = await student.select(1)
const result = await student.select(data => data.age > 15) 
console.log(result) // []

// 修改数据
const result = await student.update(1, { age: 16 })
const result = await student.update(data => data.age > 15, { age: 16 }) 
console.log(result) // { pre:  }

// 删除数据
const result = await student.delete(1)
const result = await student.delete(data => data.age > 15, { age: 16 }) 
console.log(result) // 1

API

useDB 【连接数据库】

如果数据库不存在,则会自动创建

@param {string} dbName 数据库名
@return {IDBDatabase} db 数据库实例对象

示例

andb.useDB('person')

useTable 【连接表】

如果数据库不存在,则会自动创建

@param {string} tableName 表名
@param {object} option 表结构配置
    {
        primaryKey // 可选 主键,唯一,默认会有一个 ID 主键
        structure: { // 表数据结构
            [filedName: string]: string | {
                type: string, // 字段值类型
                unique: boolean, // 唯一索引
                required: boolean // 是否必传
            }
        },
        index: Array<string> // 索引列表,列表中的字段如果在结构中定义的字段不存在,则会被忽略掉
    }
@return {DBTable} table 表实例对象

示例

示例

const student = await db.useTable(
    'student', // 表名
    {
        primaryKey: 'student_id', // 主键,可选,没有传默认使用一个名为 ID 的主键,且自动增长
        structure: { // 数据表结构,必传,定义了表数据的结构,后续有关添加类的操作都会进行一次数据结构匹配
            student_id: columnType.Number, // 当你自定义了主键,就必须为这个主键声明数据类型
            name: {
                type: columnType.String, // 必传,数据类型
                unique: true // 可选,默认false,唯一索引,会为此字段添加唯一索引
                required: true // 可选,默认false,是否必传
            },
        },
        index: ['name', 'student_id'] // 索引列表
    }
)

insert 【新增数据】

添加的数据类型结构必须和表的类型结构保持一致,否则会抛出异常

@param {object} data 添加的数据
@return {number} count 添加成功的条数 0表示执行 insert 失败,控制台会打印相关错误信息

示例

const result = await student.inset({ 
    student_id: 1, // 上面定义了 student_id 的类型为 columnType.Number,那么这个字段的值的类型就必须是Number类型,否则会抛出异常
    name: 'Tom', // 上面定义了 name 的类型为 columnType.String 且 unique 为true 且 required: true,那么这个字段数据的值就不能有重复且必传,否则会抛出异常
})
console.log(result) // 1 返回执行成功的条数

select 【查询数据】

@param {'*' | number | Array<number | string> | Object | Function} condition 查询条件
    * 查询全部
    number | Array<number | string> 适用于主键查询
    Object 对象匹配查询
    Function 自定义函数匹配查询
@return {Array<any>} result 查询结果集

示例

const result = await student.select(1) // 通过主键值查
const result = await student.select([1, 2]) // 通过主键查询可以传一个数组,数组中放置主键值
const result = await student.select({grade: '19届', class: '高三年级一班'}) // 通过对象查,会和数据进行深比较
const result = await student.select(function confirm(data){ // 通过自定义函数查,会将每条数据传递给函数,判断函数的返回的 true/false 来进行筛选
    if(data.age > 19) {
        return true
    }
    return false
}) 
console.log(result) // 返回所有匹配条件的数据集,是一个数组

update 【修改数据】

修改的数据的类型结构必须和表的类型结构保持一致,否则会抛出异常

@param {'*' | number | Array<number | string> | Object | Function} condition 查询条件
    * 查询全部
    number | Array<number | string> 适用于主键值匹配
    Object 对象匹配
    Function 自定义函数匹配
@param {object} modifyValue 修改的数据
@return {object} result { pre: 修改前匹配的数据结果集,next: 修改后的结果集 } 返回修改前和修改后的数据

示例

const result = await student.update(1, { age: 16 })
const result = await student.update([1, 2], { age: 16 }) // 通过主键修改可以传一个数组,数组中放置主键值
const result = await student.update({grade: '19届', class: '高三年级一班'}, { age: 16 }) // 通过对象匹配进行修改,会和数据进行深比较
const result = await student.update(function confirm(data){ // 通过自定义函数匹配,会将每条数据传递给函数,判断函数的返回的 true/false 来进行筛选匹配
    if(data.age > 19) {
        return true
    }
    return false
}, { age: 16 }) 
console.log(result) // 返回一个对象 { pre: 修改前的数据(Array), next: 修改后的数据(Array) }

delete 【删除数据】

@param {'*' | number | Array<number | string> | Object | Function} condition 查询条件
    * 查询全部
    number | Array<number | string> 适用于主键匹配删除
    Object 对象匹配删除
    Function 自定义函数匹配删除
@return {number} count 删除成功的条数

示例

const result = await student.delete(1) // 通过主键值匹配删除
const result = await student.delete([1, 2]) // 通过主键删除可以传一个数组,数组中放置主键值
const result = await student.delete({grade: '19届', class: '高三年级一班'}) // 通过对象进行匹配删除,会和数据进行深比较
const result = await student.delete(function confirm(data){ // 通过自定义函数匹配,会将每条数据传递给函数,判断函数的返回的 true/false 来进行匹配删除
    if(data.age > 19) {
        return true
    }
    return false
}) 
console.log(result) // 返回被删除的数据的条数,Number

trigger 【触发器】

每个表都可以设置三种触发器,insert update delete,对应三种操作,在每种操作执行成功时会指定对应的触发器,并将操作的数据传给触发器函数

student.trigger.insert.use(function (data) { ... })
student.trigger.update.use(function (data) { ... })
student.trigger.delete.use(function (data) { ... })

完整示例

import andb, { columnType } from 'an-db'

// 使用/创建 person 数据库, 如果不存在,则会自动创建
const db = await andb.useDB('person')

// 使用/创建 student 表,如果不存在,则会自动创建
const student = await db.useTable(
    'student', // 表名
    {
        primaryKey: 'student_id', // 主键,可选,没有传默认使用一个名为 ID 的主键,且自动增长
        structure: { // 数据表结构,必传,定义了表数据的结构,后续有关添加类的操作都会进行一次数据结构匹配
            student_id: columnType.Number, // 当你自定义了主键,就必须为这个主键声明数据类型
            name: {
                type: columnType.String, // 必传,数据类型
                unique: true // 可选,默认false,唯一索引,会为此字段添加唯一索引
            },
            age: {
                type: columnType.Number, // 数据类型
                required: true // 可选,默认false,表示必传
            },
            class: columnType.String, 
            grade: columnType.String,
            school_info: {
                type: columnType.Object
            },
            course: {
                type: columnType.Array,
                required: true
            }
        },
        index: ['grade', class] // 索引列表
    }
)

// 添加触发器
student.trigger.insert.use(function (data) { 
    console.log('执行了insert', data)
})
student.trigger.update.use(function (data) { 
    console.log('执行了update', data)
})
student.trigger.delete.use(function (data) { 
    console.log('执行了delete', data)
})

// 添加数据
const result = await student.inset({ 
    student_id: 1, // 上面定义了 student_id 的类型为 columnType.Number,那么这个字段的值的类型就必须是Number类型,否则会抛出异常
    name: 'Tom', // 上面定义了 name 的类型为 columnType.String 且 unique 为true,那么这个字段数据的值就不能有重复,否则会抛出异常
    age: 18, // 上面定义了 age 的类型为 columnType.Number 且 required 为true,那么数据中就必须要有 age 字段,否则会抛出异常
    class: '高三年级一班',
    grade: '19届',
    school_info: {
        name: '进贤二中',
        address: '江西省南昌市进贤县滨湖大道中段',
        postCode: 331700
    },
    course: ['Russian', 'French', 'calculus', 'computers']
})
console.log(result) // 1 返回执行成功的条数,返回0则表示执行insert失败

// 查询数据
const result = await student.select(1) // 通过主键值查
const result = await student.select([1, 2]) // 通过主键查询可以传一个数组,数组中放置主键值
const result = await student.select({grade: '19届', class: '高三年级一班'}) // 通过对象查,会和数据进行深比较
const result = await student.select(function confirm(data){ // 通过自定义函数查,会将每条数据传递给函数,判断函数的返回的 true/false 来进行筛选
    if(data.age > 19) {
        return true
    }
    return false
}) 
console.log(result) // 返回所有匹配条件的数据集,是一个数组

// 修改数据
// 修改值的对象类型也需要和定义的表结构匹配,否则会抛出异常
const result = await student.update(1, { age: 16 })
const result = await student.update([1, 2], { age: 16 }) // 通过主键修改可以传一个数组,数组中放置主键值
const result = await student.update({grade: '19届', class: '高三年级一班'}, { age: 16 }) // 通过对象匹配进行修改,会和数据进行深比较
const result = await student.update(function confirm(data){ // 通过自定义函数匹配,会将每条数据传递给函数,判断函数的返回的 true/false 来进行筛选匹配
    if(data.age > 19) {
        return true
    }
    return false
}, { age: 16 }) 
console.log(result) // 返回一个对象 { pre: 修改前的数据(Array), next: 修改后的数据(Array) }

// 删除数据
const result = await student.delete(1) // 通过主键值匹配删除
const result = await student.delete([1, 2]) // 通过主键删除可以传一个数组,数组中放置主键值
const result = await student.delete({grade: '19届', class: '高三年级一班'}) // 通过对象进行匹配删除,会和数据进行深比较
const result = await student.delete(function confirm(data){ // 通过自定义函数匹配,会将每条数据传递给函数,判断函数的返回的 true/false 来进行匹配删除
    if(data.age > 19) {
        return true
    }
    return false
}) 
console.log(result) // 返回被删除的数据的条数,Number