JS / CSS / files loader + key/value storage

Related tags

Storage bag.js
Overview

bag.js - JS / CSS loader + KV storage

Build Status NPM version

bag.js is loader for .js / .css and other files, that uses IndexedDB/ WebSQL / localStorage for caching. Consider it as alternative for other types of loaders for modern browsers, that reduce number of server requests, especially for mobile devices. Also bag.js can be used as simple key/value storage, that doesn't require you to know details about IndexedDB and WebSQL.

This project is inspired by basket.js, but provides more safe storages for big assets and universal key/value interface. Key features are:

  • Parallel load and sequential execution for JS / CSS and other types of files
  • Use IndexedDB / WebSQL / localStorage - no size limits for big assets.
  • KV storage for objects, with simple interface.
  • You can use multiple instances with different storage options. For example Indexeddb + WebSQL for assets and localStorage for user settings.
  • Partial compatibility with basket.js.

Requirements:

This package requires Promise polyfill for old browsers. We recommend lie, it's small enougth and fast.

Install

via bower:

bower install bag.js

via npm:

bower install bagjs --save

Examples

Simple:

var bag = new window.Bag();

bag.require(['/site.css', '/jquery.js', '/site.js'])
  .then(() => {
    // code to run after loading
    // ...
  })
  .catch(err => console.log('loading error: ', err));

Advanced:

var bag = new window.Bag({
  prefix: 'my_namespace',
  stores: ['indexeddb', 'websql'],
  timeout: 20000,
  expire: 24
});

bag.isValidItem = function(source, obj) {
  return (source && (source.url === obj.url)) ? true : false;
};

var files = [
  { url: '/site.css', expire: 1 },
  { url: '/jquery.js', expire: 10 },
  { url: '/site.js' },
  { url: '/more_styles.css', expire: 5, execute: false }
];

bag.require(files)
  .then(data => {
    console.log('loaded', data);
  })
  .catch(err => console.log(err));
})

You can skip new keyword. Also, you can use callbacks:

window.Bag().require([ '/site.css', '/site.js']
  .then(data => {
    console.log(data);
  })
  .catch(err => console.log(err));

Using as key/value storage:

var obj = { lorem: 'ipsum' };
var bag = new window.Bag();

bag.set('dolorem', obj)
  .then(() => bag.get('dolorem'));
  .then(data => console.log('Loaded data:\n', data));
  .catch(err => console.log(err));
  .then(() => bag.remove('dolorem'));

API

Note, all methods with optional callbacks will return promises if callback is not set.

new Bag([options])

Object constructor. You can also define options after constructor call, via instance properties (they have the same names). Options (hash):

  • prefix - Data namespace. Default - bag. Used to separate data for multiple instances.
  • stores - Array of storage names to use, ordered by preference. Default ['indexeddb', 'websql', 'localstorage'].
  • timeout - files loading timeout, in seconds. Default 20.
  • expire - require() data expiration, in hours. Default - 1 month. 0 or unset - don't expire.

Note 1: you can skip new keyword, calling Bag() will return you new instance anyway.

Note 2: prefix must be set before require/get/set/remove/clear calls. Other options can be changed anytime.

.require(files) -> Promise

  1. Load files from server or from cache.
  2. Inject known types into page (js/css by default), unless execution is disabled. When multiple files requested (files are Array), those are loaded in parallel, but injected in defined order.
  3. Also, content of the files is returned in the result.

files param can be:

  • Object - resource info (see details below).
  • String - just resource url, other params will be default.
  • Array(Object|String) - list of resources to load in parallel.

resource info:

  • url - resource URI, required.
  • expire - optional, expiration time in hours. 0 or not set - don't expire.
  • key - the name, used to store loaded file, if not defined, then url will be used.
  • unique - a token stored with the cached item. If you request the same item again with a different token the script will be fetched and cached again.
  • live - force cache bypass, for development needs.
  • cached - force request from cache only.

result (Promise):

  • (Array|String) with loaded content, depending on files type. If a single resource is requested (Object|String), data is String. If an Array of resources is requested, or chained call done, data is array of strings.

Note, unless you pass resources info in short form, input objects are extended with loaded data.

.get(key) -> Promise

Load data by key name. Not existing values are returned as undefined.

.set(key, data [, expire]) -> Promise

Put data into storage under key name.

  • key - String to address data.
  • data - JS object to store. We currently support only objects, serializable by JSON. Don't try to put functions or arraybuffers.
  • expire - Expiration time in seconds. Don't expire by default.

.remove(key) -> Promise

Remove key data from store.

.clear([expiredOnly]) -> Promise

Clear all storage data (in your namespace), or just expired objects when called as bag.clear(true).

.addHandler(types, handler)

Add handler for loaded files with specified mime types. By default, handlers for application/javascript and text/css already exist. If you set execute: false in resource info, then handler will not be applied.

  • types - String with mime type or Array of strings.
  • handler - function to "execute" file of that type.

.removeHandler(types)

Remove handler for specified mime type (opposite to addHandler).

Related projects

License

MIT

Comments
  • bug report

    bug report

    I am using this package: https://github.com/Daemonite/material . bagjs has a bug. when loading .js files by bagjs, this page (https://github.com/Daemonite/material/blob/master/templates/ui-button.html) can't work normally. you will see when not loading by bagjs, the title will change when you scroll down. I test bagjs for 2 days, if loading .css, the image files loaded by css will be changed to the root path.

    opened by klausgao 11
  • support oldstyle MIME-types of javascript

    support oldstyle MIME-types of javascript

    There are several MIME-types for javascript: http://stackoverflow.com/questions/876561/when-serving-javascript-files-is-it-better-to-use-the-application-javascript-or

    Would you mind to support old styled types? something like this:

        handlers['application/x-javascript'] =
          handlers['text/javascript'] =
            handlers['application/javascript']
    
    opened by tyv 9
  • Cannot load relative import in css.

    Cannot load relative import in css.

    For example, I have a style file like:

    /* foo.css */
    @import url(bar.css);
    

    and I call bag.js as the following:

    var bag = new window.Bag();
    bag.require(["foo.css"]);
    

    It will success load foo.css, but not load bar.css.

    opened by loggerhead 3
  • [question] Forcing replace of cached scripts

    [question] Forcing replace of cached scripts

    Hi,

    I've started playing with your library and looks very useful.

    I have a question about the possibility to be able to set (as ex) a file hash (like gulp-rev) and tell loader to retrieve the script from the server and replace the old one even is not expired.

    Ore any other way to achieve that.

    Thanks, Paul

    opened by devel-pa 3
  • Namespacing

    Namespacing

    How can I load modules into namespaces for use in other modules? For example, reuqire.js or curl.js does it like this:

    requirejs(['jquery', 'canvas', 'app/sub'], function   ($, canvas, sub) {
        //jQuery, canvas and the app/sub module are loaded and can be used here now.
    
        return {
            helloWorld: function() {
              console.log('Hi there!');
            }
        };
    });
    

    The namespaces are then "$, canvas, sub", How can I achieve the same with bag.js? Thanks

    opened by kokujin 3
  • Syntax for css-js-loading

    Syntax for css-js-loading

    var bag = new window.Bag(); bag.require(['/site.css', '/jquery.js', '/site.js']);

    is that corrrect for just loading files as with

    Which other loader do you propose ?

    opened by gtbu 1
  • Security improvement

    Security improvement

    Local storage can be sensitive for XSS-attacs. More at https://auth0.com/blog/secure-browser-storage-the-facts/ Session tokens, personally identifiable information, API keys are not really safe.

    My proposal : Implement secure local storage like https://github.com/randlabs/encrypted-local-storage

    opened by gtbu 1
  • clearing all storage(websql and indexeddb)

    clearing all storage(websql and indexeddb)

    Am I misunderstanding the purpose of bag.clear? I am able to remove individual keys by using bag.remove. However, bag.clear(true) does not remove all keys. Is this expected behavior?

    opened by afrozl 1
  • requiring js/css dynamically

    requiring js/css dynamically

    Is it possible to load javascript dynamically via ajax/rpc? I should explain what I mean. I have an app that dynamically pulls ins new 'widgets' with their own scoped css and js code. These css and js snippets are stored in mongodb. I would like to be able to use bag.js to require them as needed and store them in local storage ( along with appending them to the appropriate widget element as script and style elements )

    Does that make sense?

    question 
    opened by afrozl 1
  • accessing functions defined in bag

    accessing functions defined in bag

    I notice that any functions defined in bag.js startup are no longer accessible in the global name space, eg:

    bag.require(['/site.css', '/jquery.js', '/site.js'], function (err) {
      if (err) {
        console.log('loading error: ', err);
        return
      }
      // code to run after loading
      function testFunction() {
                   console.log('hello');
           }
    })
    .

    How do I access these named functions as

    window'testFunction'
    no longer works?

    question 
    opened by afrozl 1
  • Is there a SYNC way to bag.get ?

    Is there a SYNC way to bag.get ?

    THIS IS THE ASYNC WAY

    bag.get('dolorem', function(err, data) {
        if (err) {
          console.log('Loading error: ', err);
          return;
        }
    
        console.log('Loaded data:\n', data);
        }
    

    Someone Like me, want to use the SYNC Way

    let data = bag.get('dolorem');
    console.log('Loaded data:\n', data);
    
    question 
    opened by yanzixiang 1
  • Add info about ie6-7

    Add info about ie6-7

    • JSON polyfill required
    • Should fallback to "transparent" mode
    • Need to test somehow

    • try https://github.com/defunctzombie/zuul, looks nice
    opened by puzrin 0
Owner
Nodeca
rcopen.com sources and node.js libraries
Nodeca
A script and resource loader for caching & loading files with localStorage

Basket.js is a script and resource loader for caching and loading scripts using localStorage ##Introduction for the Non-Developer Modern web applicati

Addy Osmani 3.4k Dec 30, 2022
A enhanced web storage with env support, expire time control, change callback and LRU storage clear strategy.

enhanced-web-storage A enhanced web storage with env support, expire time control, change callback and LRU storage clear strategy. How to Start import

Ziwen Mei 15 Sep 10, 2021
Cross-browser storage for all use cases, used across the web.

Store.js Cross-browser storage for all use cases, used across the web. Store.js has been around since 2010 (first commit, v1 release). It is used in p

Marcus Westin 13.9k Dec 29, 2022
💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.

localForage localForage is a fast and simple storage library for JavaScript. localForage improves the offline experience of your web app by using asyn

localForage 21.5k Jan 4, 2023
Cross domain local storage, with permissions

Cross domain local storage, with permissions. Enables multiple browser windows/tabs, across a variety of domains, to share a single localStorage. Feat

Zendesk 2.2k Jan 6, 2023
A lightweight vanilla ES6 cookies and local storage JavaScript library

?? CrumbsJS ?? A lightweight, intuitive, vanilla ES6 fueled JS cookie and local storage library. Quick Start Adding a single cookie or a local storage

null 233 Dec 13, 2022
:sunglasses: Everything you need to know about Client-side Storage.

awesome-web-storage Everything you need to know about Client-side Storage. Table of Contents Introduction Browser Support Cookies Pros Cons API Useful

Varun Malhotra 420 Dec 12, 2022
An AngularJS module that gives you access to the browsers local storage with cookie fallback

angular-local-storage An Angular module that gives you access to the browsers local storage Table of contents: Get Started Video Tutorial Development

Gregory Pike 2.9k Dec 25, 2022
local storage wrapper for both react-native and browser. Support size controlling, auto expiring, remote data auto syncing and getting batch data in one query.

react-native-storage This is a local storage wrapper for both react native apps (using AsyncStorage) and web apps (using localStorage). ES6 syntax, pr

Sunny Luo 2.9k Dec 16, 2022
💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.

localForage localForage is a fast and simple storage library for JavaScript. localForage improves the offline experience of your web app by using asyn

localForage 21.5k Jan 1, 2023
⁂ The simple file storage service for IPFS & Filecoin

⁂ web3.storage The simple file storage service for IPFS & Filecoin. Getting started This project uses node v16 and npm v7. It's a monorepo that use np

Web3 Storage 423 Dec 25, 2022
This is an upload script which allows you to upload to web3 storage using JS.

This is an upload script which allows you to upload to web3 storage using JS. first make sure to run npm install on the directory run script using nod

null 1 Dec 24, 2021
A javascript based module to access and perform operations on Linode object storage via code.

Linode Object Storage JS Module A javascript based module to access and perform operations on Linode object storage via code. Code Guardian Installing

Core.ai 3 Jan 11, 2022
Dustbin - Just Another Text Storage Service

Dustbin It's just another text storage service built in fastify. API Ofcouse we

Dustbin Server 25 Dec 3, 2022
Store your data in the world's fastest and most secure storage, powered by the blockchain technology⚡️

Store your data in the world's fastest and most secure storage, powered by the blockchain technology.

BlockDB 3 Mar 5, 2022
Expirable data storage based on localStorage and sessionStorage.

Expirable storage About The Project Expirable data storage based on localStorage and sessionStorage. Getting Started To get a local copy up and runnin

Wayfair Tech – Incubator 5 Oct 31, 2022
Browser storage interface for IndexedDB, WebSQL, LocalStorage, and in memory data with Schema and data validator.

Client Web Storage Browser storage interface for IndexedDB, WebSQL, LocalStorage, and in memory data with basic Schema and data validation. Installati

Before Semicolon 19 Sep 30, 2022
Simple key-value storage with support for multiple backends

Simple key-value storage with support for multiple backends Keyv provides a consistent interface for key-value storage across multiple backends via st

Luke Childs 2k Jan 7, 2023
Byteroo - Key-value storage for your Node.js applications

Byteroo Byteroo is a key-value storage for your Node.js applications. Usage: const Byteroo = require('byteroo'); const storage = new Byteroo({ name:

JMax 1 Jan 3, 2022
Persistent key/value data storage for your Browser and/or PWA, promisified, including file support and service worker support, all with IndexedDB. Perfectly suitable for your next (PWA) app.

BrowstorJS ?? ?? ?? Persistent key/value data storage for your Browser and/or PWA, promisified, including file support and service worker support, all

Nullix 8 Aug 5, 2022