ldb.js

This is an itsy-bitsy database for the browser. Useful for trivial web apps and other toy projects.

'use strict';

const ldb = {

  // Utils
  _uuid: () => {
    return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11)
      .replace(/[018]/g, c =>
        (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
  },
  _makeDocument: (document, dateCreated = null) => {
    const rightNow = new Date();
    let editedDate = null;
    if (dateCreated === null) {
      dateCreated = rightNow.toISOString();
    } else {
      dateCreated = dateCreated;
      editedDate = rightNow.toISOString();
    }
    const newDoc = {
      "created": dateCreated,
      "edited": editedDate,
      "doc": document
    };
    return newDoc;
  },
  _table: () => {
    const dump = JSON.parse(localStorage.getItem('ldb'));
    console.log('Number of rows: ' + Object.keys(dump).length);
    console.table(dump);
    return null;
  },
  _destroy: (confirm) => {
    if (confirm === true) {
      localStorage.removeItem('ldb');
    } else {
      console.error('You must confirm this action.');
    }
  },

  // GET
  Get: (idToGet) => {
    let returnData = null;
    if (idToGet) {
      const data = JSON.parse(localStorage.getItem('ldb'));
      returnData = data[idToGet];
      if (returnData === undefined) {
        console.error('Unable to find record with id "' + idToGet + '"');
        returnData = null;
      }
    } else {
      if (localStorage.getItem('ldb') === null) {
        const defaultData = {};
        localStorage.setItem('ldb', JSON.stringify(defaultData));
      }
      returnData = JSON.parse(localStorage.getItem('ldb'));
    }
    return returnData;
  },

  // PUT
  Put: (newDocumentData) => {
    if (typeof newDocumentData === 'object') {
      let pagesData = ldb.Get();
      const uuid = ldb._uuid();
      const row = ldb._makeDocument(newDocumentData);
      Object.assign(pagesData, {
        [uuid]: row
      });
      const preFlight = JSON.stringify(pagesData);
      localStorage.setItem('ldb', preFlight);
    } else {
      console.error('Data must be an object.');
      console.log('Data is ' + typeof newDocumentData);
      console.log(newDocumentData);
    }
  },

  // UPDATE
  Update: (idToModify, newDocumentData = null) => {
    let pagesData = ldb.Get();
    let targetRow = pagesData[idToModify];
    const updatedRow = ldb._makeDocument(newDocumentData, targetRow.created);
    Object.assign(pagesData, {
      [idToModify]: updatedRow
    });
    const preFlight = JSON.stringify(pagesData);
    localStorage.setItem('ldb', preFlight);
  },

  // DELETE
  Delete: (idToRemove) => {
    // TODO: UNTESTED!
    let pagesData = ldb.Get();
    let targetRow = pagesData[idToRemove];
    Object.assign(pagesData, {
      [idToRemove]: null
    }); // FIXME: this will leave an empty ID
    const preFlight = JSON.stringify(pagesData);
    localStorage.setItem('ldb', preFlight);
  },

  // EXPORT
  Export: () => {
    const rightNow = new Date();
    const pagesData = JSON.stringify(ldb.Get());
    const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(pagesData);
    const exportFileDefaultName = rightNow.toISOString() + '--ldb_export.json';
    let linkElement = document.createElement('a');
    linkElement.setAttribute('href', dataUri);
    linkElement.setAttribute('download', exportFileDefaultName);
    linkElement.click();
  }

};