Skip to content

ecmadao/chrome-utils

Repository files navigation

chrome-utils

npm version Build Status Coverage Status js-standard-style chrome-utils GitHub license

Some utils that help to build chrome extension. HAVE NO DEPENDENCIES.

Usage

$ npm i chrome-utils --save
// es6
import { store, message, i18n } from 'chrome-utils';

// es5
const store = require('chrome-utils').store;

Api

store

chrome.storage API is anti-human, for example, if you saved a non-plain object to store, {a: {b: 1, c: {d: 2}}}, then how to directly get the value of d from it?

One more question, if you have already save {a1: {b: 1}, a2: {c: 2}} to store, then wanna update b to 2, then how to do it? If we use raw API like chrome.storage.sync.set({a1: {b: 2}}), then we'll find a2 was totally disappeard!

Actually, by raw chrome.storage API:

  • you can only get the top key-value
  • you can only get a but not a.b.d.
  • if you wanna update a value in a object, you must get it from store first, then update the whole object, finally, save it to store.

WTF?


get & set

If target value exist, then auto to merge it

store.get(key[, resolve, reject]);
store.set(key, value[, options]);

// usage example
store.set('a.c', 1);
store.get('a'); // {c: 1}

store.set('a.b', 2);
store.get('a'); // inject b, get {b: 2, c: 1}
store.get('a.b'); // directly get b, return 2

store.set('a.b', 3);
store.get('a.b'); // update, get 3

listen

store.listen(...listeners);

// listener
const listener = {
	key, // the key you wanna to listen change
	callback
};
const listeners = [listener1, listener2, listener3];

clear & remove

store.clear();
store.remove(key[, callback]);

// example
store.set({a: {b: 1, c: 2}});
store.get('a'); // {b: 1, c: 2}

store.remove('a.b');
// after remove
store.get('a'); // => {b: null, c: 2}

store.remove('a');
// after remove
store.get('a'); // => null

storeAsync

Uses promises instead of callbacks. Plays well with async/await.

import { storeAsync as store } from 'chrome-utils';

// with promises
store.set('a', "xxx").then(e => console.log("done"))
store.get('a').then(e => console.log(e))
store.remove('a').then(e => console.log("done"))
store.clear().then(e => console.log("done"))

// with async/await
(async function() {
		await store.set("b", "yyy")
		const b = await store.get("b")
		console.debug("b", b)
})()

message

Compare with raw API chrome.runtime.onMessage & chrome.runtime.sendMessage, it:

  • force user add type for each msg
  • if msg listener as a type key, it will only response to target type msg

send message

message.sendMsg(msg[, callback]);

// msg
const msg = {
	type, // required
	data
};

send msg to tabs

message.sendToTabs(msg[, query]);

register listener

message.register(...listeners);

// listener
const listener = {
	callback, // required,
	type // not required, but if you use it, this listener will only listen same type msg
};

i18n

get message

i18n.get(...args);

Todo

  • remove merge api
  • expire time for store
  • test
  • more use case

Contributors

License

MIT License