Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@sodular/lite

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sodular/lite

Sodular a Lite JSON database similar to firebase. Visit the master branch: https://github.com/coorise/sodular-lite-js.git

  • 0.1.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
2
increased by100%
Maintainers
1
Weekly downloads
 
Created
Source

SoduLite JS v0.1.0

SoduLite (Sodular Lite) is a lightweight JSON database based on path-like (similar to firebase database )
The data can be saved on local json file if you use Node JS or on browser with localStorage.

Get Started

0. Download the package

Node JS: npm install @sodular/lite
Browser:

1. Import the database

//import SoduLite from '@sodular/lite'; //Node JS
import SoduLite from '../sodulite.min.js'; //For browser

2. Init the database

let db = SoduLite.init({
dbName: 'sodulite @&', // we use regex to replace any special character to '\_'
path: './database@/project-Z $é/', //same for path, using '/xxxx' or './xxxx' is not necessary because we use the root of the project only.
});

Note: path is only for Node JS

3. Call/Create the database service you want to work with

db = db = db.load('data'); //In Node Js, if .json is not added , it will automatically create it.

Note: load('service_name') is like your sub-dbName (sub-dbName.json if you are on Node Js).
As service you have: auth, data, storage...

4. Do CRUD (Create|Read|Update|Delete) operation

Note: All operations are async, for those who don't know what we mean, it is as example below:

doSomething.then((result)=>{
  //work with your result
})

//OR 

(async () => {
  let result= await doSomething()
  //work with your result
})()
  • 4.1 Do Create operation
let op = db
    .ref('/members/users/0')
    .create({ name: 'Alice' })
    .then((node) => { // using then to get the value
      console.log('Create Alice: ', {
        path: node.path,
        key: node.key,
        value: node.value,
        error: node.error,
      });
    })
    .catch((e) => {
      console.log('Create Alice Error: ', e);
    });

//OR

let  op = await db // asuming it's in an async function
    .ref('/members/users/0') // you could generate a unique uid for your users.
    .create({ name: 'Alice' })
    .catch((e) => {
      console.log('Create Bob Error: ', e);
    });
  console.log('Create Alice:', {
    path: op.path, 
    key: op.key,
    value: op.value, // you get the object value
    error: op.error,
  });

Note: If the ref with data exists already, you won't be allowed to create, instead you have to do the Update Operation.

  • 4.2 Do Read operation

//Get the value of a path

let alice = await db // asuming it's in an async function
    .ref('/members/users/0')
    .get() //let it empty
    .catch((e) => {
      console.log('Get Alice Error: ', e);
    });
  console.log('Get Alice:', {
    path: alice.path,
    key: alice.key,
    value: alice.value,//the info of alice is here or it will return false.
    error: alice.error,
  });

//If path is an array[list of ids] or object{list of ids}

  • Get the unique value of a path with a parameter
let alice = await db // asuming it's in an async function
    .ref('/members/users') //users is an array or object with ids as property
    .get({name:'Alice'}) // Will only fetch the first Alice found, so add multiple parameter to get your result efficiently like {name:'Alice,age:30,...}, but the best is {uid:'userId'}.
    .catch((e) => {
      console.log('Get Alice Error: ', e);
    });
  console.log('Get Alice:', {
    path: alice.path,
    key: alice.key,
    value: alice.value,//the info of alice is here or it will return false.
    error: alice.error,
  });
  • Do the Query(Search), query always return an [array] of the result.
let query = await db // asuming it's in an async function
    .ref('/members/users') //users is an array or object with ids as property
    .query({ filter: { age: { _lte: 30 } } }) //Or { '$<=': 30 } , to get the condition little or equal to 30.
    .catch((e) => {
      console.log('Get Query Error: ', e);
    });
  console.log('Get Query:', {
    path: query.path,
    key: query.key,
    value: query.value,//array the value of query is here or it will return false.
    error: query.error,
  });

Note: See the parameters for query(filter = {}, sort, pagination, mod)

//If you data is [], you could also use a path query string for a shorthand of pagination to get the list of objects in array.

let query = await db // asuming it's in an async function
    .ref('/members/users[0;1;5]') // if exist will select only the users[O], users[1] and users[5] in an array
    .query() //let it empty
    .catch((e) => {
      console.log('Get Query Error: ', e);
    });
  console.log('Get Query:', {
    path: query.path,
    key: query.key,
    value: query.value,//the array value of query is here or it will return false.
    error: query.error,
  });

Note: Check the path query string.

  • 4.3 Do Update operation

//Overwrite the previous data

let alice = await db // asuming it's in an async function
    .ref('/members/users/0')
    .update({ name: 'Alice Lite' })
    .catch((e) => {
      console.log('Update Alice Error: ', e);
    });
  console.log('Update Alice:', {
    path: alice.path,
    key: alice.key,
    value: alice.value,//the info of alice is here or it will return false.
    error: alice.error,
  });

// To merge with the previous data , you add {merge=true}

let alice = await db // asuming it's in an async function
    .ref('/members/users/0')
    .update({ age: 26 },{merge=true}) //Here we merge with the existing value.
    .catch((e) => {
      console.log('Update Alice Error: ', e);
    });
  console.log('Update Alice:', {
    path: alice.path,
    key: alice.key,
    value: alice.value,//the info of alice is here or it will return false.
    error: alice.error,
  });
  • 4.4 Do Delete operation

//Delete value with path

let alice = await db // asuming it's in an async function
    .ref('/members/users/0')
    .delete() //let it empty, it will delete everything on child=0
    .catch((e) => {
      console.log('Delete Alice Error: ', e);
    });
  console.log('Delete Alice:', {
    path: alice.path,
    key: alice.key,
    value: alice.value,//the info of alice is here or it will return false.
    error: alice.error,
  });

//If the final path is an array[list of ids] or object{list of ids}, the you can do the filter:

let alice = await db // asuming it's in an async function
    .ref('/members/users') //here you won't go to child=0, //users is an array or object with ids as property
    .delete({ age: 26 }) // will delete child which has age=26, 
    .catch((e) => {
      console.log('Delete Alice Error: ', e);
    });
  console.log('Delete Alice:', {
    path: alice.path,
    key: alice.key,
    value: alice.value,//the info of alice is here or it will return false.
    error: alice.error,
  });

Note:It will only delete the first object which has age=26 not all objects having age=26,
so be careful to delete a unique uid, instead you should do .delete({ uid: uid_of_user }) or delete with the first method using path only.

Advanced Options

Query

let filter={
  //...
}
let sort={
  //...
}
let pagination={
  //...
}
let mod={
  //...
}
let result=await db //assuming async
           .ref()
           .query({filter,sort,pagination,mod})
           .catch((e) => {})
console.log('The result of filter: ', result?.value)
  • Filter

The available parameters are:

  • Object : filter = {age:30, name:'Alice'}
  • Object with operator: filter = {age:{'$<=':30}},
    the operators are:
    • case '$<': same as
    • case '_lt':
      return value < operand;
    • case '$>': same as
    • case '_gt':
      return value > operand;
    • case '$=': same as
    • case '_eq':
      if (typeof operand == 'object') return deepEqual(value, operand);
      // can also compare array and obj
      else return value === operand;
    • case '$!=': same as
    • case '_neq':
      if (typeof operand == 'object') return !deepEqual(value, operand);
      // can also compare array and obj
      else return value !== operand;
    • case '$>=': same as
    • case '_gte':
      return value >= operand;
    • case '$<=': same as
    • case '_lte':
      return value <= operand;
    • case '$match':
      return new RegExp(operand).test(value);
    • case '$!match':
      return !new RegExp(operand).test(value);
    • case '$includes':
      return value?.includes(operand);
    • case '$!includes':
      return !value?.includes(operand);
    • case '$between':
      return value >= operand[0] && value <= operand[1];
    • case '$!between':
      return !(value >= operand[0] && value <= operand[1]);
    • case '$has':
      return hasProperties(value, operand); // similar to filter={a:value}, but also has the function to compare children with object {a:{a-child:'value-child'}}
    • case '$!has':
      return !hasProperties(value, operand);
    • case '$like':
      return new RegExp(^${operand?.replace(/\*/g, '.*')}$).test(value);
    • case '$!like':
      return !new RegExp(^${operand?.replace(/\*/g, '.*')}$).test(value);
    • case '$reg':
      return new RegExp(operand).test(value);
  • Sort
    • Object : sort = {age:'desc', name:'asc'}
      the sort properties are:
      • case 'asc': Ascendant values
      • case 'desc': Descendant values
  • Pagination
    • Object : pagination = {page:1, limit:10}
      the sort properties are:
      • case page: Int value
      • case limit: Int value
  • Mod
    • Object : mod = {with:['name','age'],}
      the mod properties are:
      • case with: Array of String regex path value, will only match the path properties you set, eg: with:['child/','child1//some_path']
      • case only: Array of String properties, select only the properties you selected, eg: only:['name']
      • case rm: Array of String properties, remove the properties you selected, eg: rm:['name']
  • Query String
    • String : db.ref('/path/users![a]').query()
      the available string param are:
      • case [a]: a is index int value, it will get list[a] value,
        eg: users[1] the second user, users[-1] the last user, users[-2] the user before the last user...etc
      • case ![a]: negation of [a]
      • case [a:b]: a,b are index int value, it will get the interval list from a to b values,
        eg: users[1:5]
      • case ![a:b]: negation of [a:b]
      • case [a,b,...etc]: a,b,...etc are index int value, it will select only list[a],list[b],...etc ,
        eg: users[1,5]
      • case ![a,b]: negation of [a,b]
      • case [?a]: a is index int value, it will get list from 0 to a similar to list[0:a],
        eg: users[?3]
      • case [?-a]: similar to [?a], but removes the indexes starting from last item(index from -1 to -a will be removed) ,
        eg: users[?-2] <=> users[0,-2]

Todo

  • Removing/Reduce some unusual dependencies,functions, refactoring paths/files...
  • Making good and easy documentation with tutorials (videos, webpage...)
  • Code Cleaning/ Making a suitable project structure with modular pattern (DRY and KISS dev).

Join US

If you have any suggestion, feature to add ...etc

Contributors

  • Agglomy Team :
    • Ivan Joel Sobgui

Licence

MIT: You can use it for educational/personal/business purpose!

Keywords

FAQs

Package last updated on 02 Dec 2023

Did you know?

Socket

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc