Socket
Socket
Sign inDemoInstall

reduxed-chrome-storage

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

reduxed-chrome-storage - npm Package Compare versions

Comparing version 2.2.0 to 2.4.0

dist/types/listeners.d.ts

20

dist/index.d.ts
import { StoreCreator, StoreEnhancer, Reducer } from 'redux';
import { ExtendedStore } from './types/store';
import { ChromeNamespace, BrowserNamespace } from './types/apis';
import { ChangeListener, ErrorListener } from './types/listeners';
export { ChromeNamespace, BrowserNamespace } from './types/apis';
export declare type ChangeListener = (store: ExtendedStore, oldState?: any) => void;
export { ChangeListener, ErrorListener } from './types/listeners';
/**

@@ -29,10 +30,16 @@ * ReduxedChromeStorage creator factory.

* receives two parameters:
* a one-time store-container of the current state and the previous state.
* 1) a one-time store - container of the current state;
* 2) the previous state.
* This option only makes sense in Manifest V3 service workers
* or event-driven background scripts.
* If this option is supplied, the async store creator returned by the factory
* is to only be used for holding the arguments to be passed to
* the original createStore upon a one-time store creation
* is not supposed to be immediately used for store creation;
* its only purpose in this case is to hold the arguments to be passed
* to the original `createStore` upon a one-time store creation
* @param obj.errorListener a function to be called whenever an error occurs
* during chrome.storage update, receives two parameters:
* 1) an error message defined by storage API;
* 2) a boolean indicating if the limit for the used storage area is exceeded
* @param obj.storageArea the name of chrome.storage area to be used,
* defaults to 'sync'
* either 'local' or 'sync', defaults to 'local'
* @param obj.storageKey key under which the state will be stored/tracked

@@ -44,3 +51,3 @@ * in chrome.storage, defaults to 'reduxed'

*/
export default function reduxedStorageCreatorFactory({ createStore, namespace, chromeNs, browserNs, changeListener, storageArea, storageKey, bufferLife }: {
export default function reduxedStorageCreatorFactory({ createStore, namespace, chromeNs, browserNs, changeListener, errorListener, storageArea, storageKey, bufferLife }: {
createStore: StoreCreator;

@@ -51,2 +58,3 @@ namespace?: string;

changeListener?: ChangeListener;
errorListener?: ErrorListener;
storageArea?: string;

@@ -53,0 +61,0 @@ storageKey?: string;

/**
* @license
* ReduxedChromeStorage v2.2.0
* ReduxedChromeStorage v2.4.0
* https://github.com/hindmost/reduxed-chrome-storage

@@ -104,16 +104,6 @@ * Copyright (c) Savr Goryaev aka hindmost

_createStore(initialState) {
try {
return this.createStore(this.reducer, initialState, this.enhancer);
}
catch (err) {
throw new Error('createStore() call failed');
}
return this.createStore(this.reducer, initialState, this.enhancer);
}
_send2Storage(data) {
try {
this.storage.save(data);
}
catch (err) {
throw new Error('Browser storage limit exceeded');
}
this.storage.save(data);
}

@@ -209,3 +199,6 @@ _setState(data) {

this.key = key || 'reduxed';
this.keyLen = this.key.length;
this.lastSize = 0;
this.listeners = [];
this.errorListeners = [];
}

@@ -220,2 +213,3 @@ init() {

return;
this.lastSize = JSON.stringify(newValue).length;
// call external chrome.storage.onChanged listeners

@@ -230,2 +224,36 @@ for (const fn of this.listeners) {

}
subscribeForError(fn) {
typeof fn === 'function' && this.errorListeners.push(fn);
}
fireErrorListeners(message, exceeded) {
for (const fn of this.errorListeners) {
fn(message, exceeded);
}
}
getErrorMessage() {
if (!this.ns.runtime.lastError)
return;
const { message } = this.ns.runtime.lastError;
return message || '';
}
callbackOnLoad(data, callback) {
data = !this.ns.runtime.lastError && data && data[this.key];
if (!this.lastSize && data) {
this.lastSize = JSON.stringify(data).length;
}
callback(data);
}
checkQuotaPerItem(msg, area, data) {
const b = this.areaName === StorageAreaName.sync &&
area && area.QUOTA_BYTES_PER_ITEM && data &&
JSON.stringify(data).length + this.keyLen > area.QUOTA_BYTES_PER_ITEM;
b && this.fireErrorListeners(msg);
return b;
}
checkQuota(msg, area, data, total) {
const b = !this.ns.runtime.lastError &&
area && area.QUOTA_BYTES && data && total > 0 && this.lastSize > 0 &&
JSON.stringify(data).length - this.lastSize > area.QUOTA_BYTES - total;
this.fireErrorListeners(msg, b);
}
}

@@ -241,3 +269,3 @@

this.areaApi.get(this.key, data => {
fn(!this.ns.runtime.lastError && data && data[this.key]);
this.callbackOnLoad(data, fn);
});

@@ -247,4 +275,8 @@ }

this.areaApi.set({ [this.key]: data }, () => {
if (this.ns.runtime.lastError)
throw new Error();
const message = this.getErrorMessage();
typeof message !== 'undefined' &&
!this.checkQuotaPerItem(message, this.areaApi, data) &&
this.areaApi.getBytesInUse(null, total => {
this.checkQuota(message, this.areaApi, data, total);
});
});

@@ -261,12 +293,14 @@ }

typeof fn === 'function' &&
this.areaApi.get(this.key)
.then(data => {
fn(!this.ns.runtime.lastError && data && data[this.key]);
this.areaApi.get(this.key).then(data => {
this.callbackOnLoad(data, fn);
});
}
save(data) {
this.areaApi.set({ [this.key]: data })
.then(() => {
if (this.ns.runtime.lastError)
throw new Error();
this.areaApi.set({ [this.key]: data }).then(() => {
const message = this.getErrorMessage();
typeof message !== 'undefined' &&
!this.checkQuotaPerItem(message, this.areaApi, data) &&
this.areaApi.getBytesInUse(null).then(total => {
this.checkQuota(message, this.areaApi, data, total);
});
});

@@ -304,10 +338,16 @@ }

* receives two parameters:
* a one-time store-container of the current state and the previous state.
* 1) a one-time store - container of the current state;
* 2) the previous state.
* This option only makes sense in Manifest V3 service workers
* or event-driven background scripts.
* If this option is supplied, the async store creator returned by the factory
* is to only be used for holding the arguments to be passed to
* the original createStore upon a one-time store creation
* is not supposed to be immediately used for store creation;
* its only purpose in this case is to hold the arguments to be passed
* to the original `createStore` upon a one-time store creation
* @param obj.errorListener a function to be called whenever an error occurs
* during chrome.storage update, receives two parameters:
* 1) an error message defined by storage API;
* 2) a boolean indicating if the limit for the used storage area is exceeded
* @param obj.storageArea the name of chrome.storage area to be used,
* defaults to 'sync'
* either 'local' or 'sync', defaults to 'local'
* @param obj.storageKey key under which the state will be stored/tracked

@@ -319,3 +359,3 @@ * in chrome.storage, defaults to 'reduxed'

*/
function reduxedStorageCreatorFactory({ createStore, namespace, chromeNs, browserNs, changeListener, storageArea, storageKey, bufferLife }) {
function reduxedStorageCreatorFactory({ createStore, namespace, chromeNs, browserNs, changeListener, errorListener, storageArea, storageKey, bufferLife }) {
if (typeof createStore !== 'function')

@@ -331,2 +371,4 @@ throw new Error(`Missing 'createStore' property/option`);

storage.init();
typeof errorListener === 'function' &&
storage.subscribeForError(errorListener);
function asyncStoreCreator(reducer, initialState, enhancer) {

@@ -355,2 +397,2 @@ if (typeof reducer !== 'function')

export default reduxedStorageCreatorFactory;
export { reduxedStorageCreatorFactory as default };
/**
* @license
* ReduxedChromeStorage v2.2.0
* ReduxedChromeStorage v2.4.0
* https://github.com/hindmost/reduxed-chrome-storage

@@ -75,7 +75,7 @@ * Copyright (c) Savr Goryaev aka hindmost

ReduxedStorage.prototype.init = function init () {
var this$1 = this;
var this$1$1 = this;
if (this.inited)
{ return new Promise(function (resolve) {
resolve(this$1);
resolve(this$1$1);
}); }

@@ -85,6 +85,6 @@ var defaultState = this._createStore().getState();

this.storage.subscribe(function (data, oldData) {
if (isEqual(data, this$1.state))
if (isEqual(data, this$1$1.state))
{ return; }
this$1._setState(data);
for (var i = 0, list = this$1.listeners; i < list.length; i += 1) {
this$1$1._setState(data);
for (var i = 0, list = this$1$1.listeners; i < list.length; i += 1) {
var fn = list[i];

@@ -99,13 +99,13 @@

// try to restore the last state stored in chrome.storage, if any
this$1.storage.load(function (storedState) {
this$1$1.storage.load(function (storedState) {
var state = storedState ?
mergeOrReplace(defaultState, storedState) : defaultState;
if (this$1.state0) {
state = mergeOrReplace(state, this$1.state0);
if (this$1$1.state0) {
state = mergeOrReplace(state, this$1$1.state0);
}
this$1._setState(state);
this$1$1._setState(state);
if (!isEqual(state, storedState)) {
this$1._send2Storage(state);
this$1$1._send2Storage(state);
}
resolve(this$1);
resolve(this$1$1);
});

@@ -120,23 +120,13 @@ });

ReduxedStorage.prototype.uninit = function uninit () {
var this$1 = this;
var this$1$1 = this;
return new Promise(function (resolve) {
resolve(this$1);
resolve(this$1$1);
});
};
ReduxedStorage.prototype._createStore = function _createStore (initialState) {
try {
return this.createStore(this.reducer, initialState, this.enhancer);
}
catch (err) {
throw new Error('createStore() call failed');
}
return this.createStore(this.reducer, initialState, this.enhancer);
};
ReduxedStorage.prototype._send2Storage = function _send2Storage (data) {
try {
this.storage.save(data);
}
catch (err) {
throw new Error('Browser storage limit exceeded');
}
this.storage.save(data);
};

@@ -152,3 +142,3 @@ ReduxedStorage.prototype._setState = function _setState (data) {

ReduxedStorage.prototype.subscribe = function subscribe (fn) {
var this$1 = this;
var this$1$1 = this;

@@ -158,3 +148,3 @@ typeof fn === 'function' && this.listeners.push(fn);

if (typeof fn === 'function') {
this$1.listeners = this$1.listeners.filter(function (v) { return v !== fn; });
this$1$1.listeners = this$1$1.listeners.filter(function (v) { return v !== fn; });
}

@@ -164,3 +154,3 @@ };

ReduxedStorage.prototype.dispatch = function dispatch (action) {
var this$1 = this;
var this$1$1 = this;

@@ -173,3 +163,3 @@ if (!this.buffStore) {

setTimeout(function () {
this$1.buffStore = null;
this$1$1.buffStore = null;
}, this.buffLife);

@@ -184,10 +174,10 @@ }

// otherwise an async action is implied, so use lastStore instead
var store = this$1.buffStore || lastStore;
var store = this$1$1.buffStore || lastStore;
var state = store && store.getState();
// we need a state change to be effective, so the current state should differ from the last saved one
if (isEqual(state, this$1.lastState))
if (isEqual(state, this$1$1.lastState))
{ return; }
// send the current state to chrome.storage & update this.lastState
this$1._send2Storage(state);
this$1.lastState = state;
this$1$1._send2Storage(state);
this$1$1.lastState = state;
// as we already catched the 1st effective state change, we don't need this listener and lastStore anymore,

@@ -244,12 +234,15 @@ // so we unsubscribe the former and reset the latter in order to release the related resources

this.key = key || 'reduxed';
this.keyLen = this.key.length;
this.lastSize = 0;
this.listeners = [];
this.errorListeners = [];
};
WrappedStorage.prototype.init = function init () {
var this$1 = this;
var this$1$1 = this;
// Setup internal (shared) listener for chrome.storage.onChanged
this.ns.storage.onChanged.addListener(function (changes, area) {
if (area !== this$1.areaName || !(this$1.key in changes))
if (area !== this$1$1.areaName || !(this$1$1.key in changes))
{ return; }
var ref = changes[this$1.key];
var ref = changes[this$1$1.key];
var newValue = ref.newValue;

@@ -259,4 +252,5 @@ var oldValue = ref.oldValue;

{ return; }
this$1$1.lastSize = JSON.stringify(newValue).length;
// call external chrome.storage.onChanged listeners
for (var i = 0, list = this$1.listeners; i < list.length; i += 1) {
for (var i = 0, list = this$1$1.listeners; i < list.length; i += 1) {
var fn = list[i];

@@ -271,3 +265,40 @@

};
WrappedStorage.prototype.subscribeForError = function subscribeForError (fn) {
typeof fn === 'function' && this.errorListeners.push(fn);
};
WrappedStorage.prototype.fireErrorListeners = function fireErrorListeners (message, exceeded) {
for (var i = 0, list = this.errorListeners; i < list.length; i += 1) {
var fn = list[i];
fn(message, exceeded);
}
};
WrappedStorage.prototype.getErrorMessage = function getErrorMessage () {
if (!this.ns.runtime.lastError)
{ return; }
var ref = this.ns.runtime.lastError;
var message = ref.message;
return message || '';
};
WrappedStorage.prototype.callbackOnLoad = function callbackOnLoad (data, callback) {
data = !this.ns.runtime.lastError && data && data[this.key];
if (!this.lastSize && data) {
this.lastSize = JSON.stringify(data).length;
}
callback(data);
};
WrappedStorage.prototype.checkQuotaPerItem = function checkQuotaPerItem (msg, area, data) {
var b = this.areaName === StorageAreaName.sync &&
area && area.QUOTA_BYTES_PER_ITEM && data &&
JSON.stringify(data).length + this.keyLen > area.QUOTA_BYTES_PER_ITEM;
b && this.fireErrorListeners(msg);
return b;
};
WrappedStorage.prototype.checkQuota = function checkQuota (msg, area, data, total) {
var b = !this.ns.runtime.lastError &&
area && area.QUOTA_BYTES && data && total > 0 && this.lastSize > 0 &&
JSON.stringify(data).length - this.lastSize > area.QUOTA_BYTES - total;
this.fireErrorListeners(msg, b);
};
var WrappedChromeStorage = /*@__PURE__*/(function (WrappedStorage) {

@@ -287,16 +318,20 @@ function WrappedChromeStorage(ref) {

WrappedChromeStorage.prototype.load = function load (fn) {
var this$1 = this;
var this$1$1 = this;
typeof fn === 'function' &&
this.areaApi.get(this.key, function (data) {
fn(!this$1.ns.runtime.lastError && data && data[this$1.key]);
this$1$1.callbackOnLoad(data, fn);
});
};
WrappedChromeStorage.prototype.save = function save (data) {
var this$1 = this;
var this$1$1 = this;
var obj;
this.areaApi.set(( obj = {}, obj[this.key] = data, obj ), function () {
if (this$1.ns.runtime.lastError)
{ throw new Error(); }
var message = this$1$1.getErrorMessage();
typeof message !== 'undefined' &&
!this$1$1.checkQuotaPerItem(message, this$1$1.areaApi, data) &&
this$1$1.areaApi.getBytesInUse(null, function (total) {
this$1$1.checkQuota(message, this$1$1.areaApi, data, total);
});
});

@@ -322,18 +357,20 @@ };

WrappedBrowserStorage.prototype.load = function load (fn) {
var this$1 = this;
var this$1$1 = this;
typeof fn === 'function' &&
this.areaApi.get(this.key)
.then(function (data) {
fn(!this$1.ns.runtime.lastError && data && data[this$1.key]);
this.areaApi.get(this.key).then(function (data) {
this$1$1.callbackOnLoad(data, fn);
});
};
WrappedBrowserStorage.prototype.save = function save (data) {
var this$1 = this;
var this$1$1 = this;
var obj;
this.areaApi.set(( obj = {}, obj[this.key] = data, obj ))
.then(function () {
if (this$1.ns.runtime.lastError)
{ throw new Error(); }
this.areaApi.set(( obj = {}, obj[this.key] = data, obj )).then(function () {
var message = this$1$1.getErrorMessage();
typeof message !== 'undefined' &&
!this$1$1.checkQuotaPerItem(message, this$1$1.areaApi, data) &&
this$1$1.areaApi.getBytesInUse(null).then(function (total) {
this$1$1.checkQuota(message, this$1$1.areaApi, data, total);
});
});

@@ -373,10 +410,16 @@ };

* receives two parameters:
* a one-time store-container of the current state and the previous state.
* 1) a one-time store - container of the current state;
* 2) the previous state.
* This option only makes sense in Manifest V3 service workers
* or event-driven background scripts.
* If this option is supplied, the async store creator returned by the factory
* is to only be used for holding the arguments to be passed to
* the original createStore upon a one-time store creation
* is not supposed to be immediately used for store creation;
* its only purpose in this case is to hold the arguments to be passed
* to the original `createStore` upon a one-time store creation
* @param obj.errorListener a function to be called whenever an error occurs
* during chrome.storage update, receives two parameters:
* 1) an error message defined by storage API;
* 2) a boolean indicating if the limit for the used storage area is exceeded
* @param obj.storageArea the name of chrome.storage area to be used,
* defaults to 'sync'
* either 'local' or 'sync', defaults to 'local'
* @param obj.storageKey key under which the state will be stored/tracked

@@ -394,2 +437,3 @@ * in chrome.storage, defaults to 'reduxed'

var changeListener = ref.changeListener;
var errorListener = ref.errorListener;
var storageArea = ref.storageArea;

@@ -409,2 +453,4 @@ var storageKey = ref.storageKey;

storage.init();
typeof errorListener === 'function' &&
storage.subscribeForError(errorListener);
function asyncStoreCreator(reducer, initialState, enhancer) {

@@ -411,0 +457,0 @@ if (typeof reducer !== 'function')

/**
* @license
* ReduxedChromeStorage v2.2.0
* ReduxedChromeStorage v2.4.0
* https://github.com/hindmost/reduxed-chrome-storage

@@ -11,2 +11,2 @@ * Copyright (c) Savr Goryaev aka hindmost

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).reduxedChromeStorage=e()}(this,(function(){"use strict";function t(e){return null==e||"object"!=typeof e?e:Array.isArray(e)?e.map((function(e){return t(e)})):Object.keys(e).reduce((function(r,n){return r[n]=t(e[n]),r}),{})}function e(t,r){if(t===r)return!0;if(null==t||"object"!=typeof t||null==r||"object"!=typeof r)return!1;var n=Object.keys(t),i=Object.keys(r);if(n.length!==i.length)return!1;for(var o=0,s=n;s.length>o;o+=1){var a=s[o];if(-1>=i.indexOf(a)||!e(t[a],r[a]))return!1}return!0}function r(e,n){return Array.isArray(n)?t(n):"object"!=typeof e||Array.isArray(e)||"object"!=typeof n?void 0!==n?n:e:Object.keys(e).concat(Object.keys(n).filter((function(t){return!e[t]}))).reduce((function(t,i){return t[i]=r(e[i],n[i]),t}),{})}var n,i=function(t){var e=t.reducer,r=t.storage,n=t.bufferLife,i=t.initialState,o=t.enhancer;this.createStore=t.createStore,this.storage=r,this.reducer=e,this.enhancer=o,this.buffLife=n?Math.min(Math.max(n,0),2e3):100,this.state0=i,this.state=null,this.buffStore=null,this.lastState=null,this.listeners=[],this.inited=!1,this.dispatch=this.dispatch.bind(this),this.subscribe=this.subscribe.bind(this)};i.prototype.init=function(){var t=this;if(this.inited)return new Promise((function(e){e(t)}));var n=this._createStore().getState();return this.storage.subscribe((function(r,n){if(!e(r,t.state)){t._setState(r);for(var i=0,o=t.listeners;o.length>i;i+=1){(0,o[i])(n)}}})),this.inited=!0,new Promise((function(i){t.storage.load((function(o){var s=o?r(n,o):n;t.state0&&(s=r(s,t.state0)),t._setState(s),e(s,o)||t._send2Storage(s),i(t)}))}))},i.prototype.initFrom=function(t){return this._setState(t),this.inited=!0,this},i.prototype.uninit=function(){var t=this;return new Promise((function(e){e(t)}))},i.prototype._createStore=function(t){try{return this.createStore(this.reducer,t,this.enhancer)}catch(t){throw Error("createStore() call failed")}},i.prototype._send2Storage=function(t){try{this.storage.save(t)}catch(t){throw Error("Browser storage limit exceeded")}},i.prototype._setState=function(e){e&&(this.state=t(e))},i.prototype.getState=function(){return this.state},i.prototype.subscribe=function(t){var e=this;return"function"==typeof t&&this.listeners.push(t),function(){"function"==typeof t&&(e.listeners=e.listeners.filter((function(e){return e!==t})))}},i.prototype.dispatch=function(t){var r=this;this.buffStore||(this.buffStore=this._createStore(this.state),this.lastState=this.buffStore.getState(),setTimeout((function(){r.buffStore=null}),this.buffLife));var n=this.buffStore,i=n.subscribe((function(){var t=r.buffStore||n,o=t&&t.getState();e(o,r.lastState)||(r._send2Storage(o),r.lastState=o,i(),n=null)}));return n.dispatch(t)},i.prototype.replaceReducer=function(t){return"function"==typeof t&&(this.reducer=t),this},i.prototype[Symbol.observable]=function(){var t,e=this.getState,r=this.subscribe;return(t={subscribe:function(t){if("object"!=typeof t||null===t)throw new TypeError("Expected the observer to be an object.");function n(){t.next&&t.next(e())}return n(),{unsubscribe:r(n)}}})[Symbol.observable]=function(){return this},t},function(t){t.local="local",t.sync="sync"}(n||(n={}));var o=function(t){var e=t.area,r=t.key;this.ns=t.namespace,this.areaName=e===n.sync?n.sync:n.local,this.key=r||"reduxed",this.listeners=[]};o.prototype.init=function(){var t=this;this.ns.storage.onChanged.addListener((function(e,r){if(r===t.areaName&&t.key in e){var n=e[t.key],i=n.newValue,o=n.oldValue;if(i)for(var s=0,a=t.listeners;a.length>s;s+=1){(0,a[s])(i,o)}}}))},o.prototype.subscribe=function(t){"function"==typeof t&&this.listeners.push(t)};var s,a=function(t){function e(e){t.call(this,{namespace:e.namespace,area:e.area,key:e.key}),this.areaApi=this.ns.storage[this.areaName]}return t&&(e.__proto__=t),(e.prototype=Object.create(t&&t.prototype)).constructor=e,e.prototype.load=function(t){var e=this;"function"==typeof t&&this.areaApi.get(this.key,(function(r){t(!e.ns.runtime.lastError&&r&&r[e.key])}))},e.prototype.save=function(t){var e,r=this;this.areaApi.set(((e={})[this.key]=t,e),(function(){if(r.ns.runtime.lastError)throw Error()}))},e}(o),c=function(t){function e(e){t.call(this,{namespace:e.namespace,area:e.area,key:e.key}),this.areaApi=this.ns.storage[this.areaName]}return t&&(e.__proto__=t),(e.prototype=Object.create(t&&t.prototype)).constructor=e,e.prototype.load=function(t){var e=this;"function"==typeof t&&this.areaApi.get(this.key).then((function(r){t(!e.ns.runtime.lastError&&r&&r[e.key])}))},e.prototype.save=function(t){var e,r=this;this.areaApi.set((e={},e[this.key]=t,e)).then((function(){if(r.ns.runtime.lastError)throw Error()}))},e}(o);return function(t){t.chrome="chrome",t.browser="browser"}(s||(s={})),function(t){var e=t.createStore,r=t.namespace,n=t.chromeNs,o=t.browserNs,u=t.changeListener,f=t.storageArea,h=t.storageKey,p=t.bufferLife;if("function"!=typeof e)throw Error("Missing 'createStore' property/option");var y=o||r===s.browser?new c({namespace:o||browser,area:f,key:h}):new a({namespace:n||chrome,area:f,key:h});return y.init(),function(t,r,n){if("function"!=typeof t)throw Error("Missing 'reducer' parameter");if("function"==typeof r&&"function"==typeof n)throw Error("Multiple 'enhancer' parameters unallowed");"function"==typeof r&&void 0===n&&(n=r,r=void 0);var o=new i({createStore:e,storage:y,bufferLife:p,reducer:t,initialState:r,enhancer:n});return"function"!=typeof u?o.init():(y.subscribe((function(t,e){u(o.initFrom(t),e)})),o.uninit())}}}));
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).reduxedChromeStorage=e()}(this,(function(){"use strict";function t(e){return null==e||"object"!=typeof e?e:Array.isArray(e)?e.map((function(e){return t(e)})):Object.keys(e).reduce((function(r,n){return r[n]=t(e[n]),r}),{})}function e(t,r){if(t===r)return!0;if(null==t||"object"!=typeof t||null==r||"object"!=typeof r)return!1;var n=Object.keys(t),i=Object.keys(r);if(n.length!==i.length)return!1;for(var o=0,s=n;s.length>o;o+=1){var a=s[o];if(-1>=i.indexOf(a)||!e(t[a],r[a]))return!1}return!0}function r(e,n){return Array.isArray(n)?t(n):"object"!=typeof e||Array.isArray(e)||"object"!=typeof n?void 0!==n?n:e:Object.keys(e).concat(Object.keys(n).filter((function(t){return!e[t]}))).reduce((function(t,i){return t[i]=r(e[i],n[i]),t}),{})}var n,i=function(t){var e=t.reducer,r=t.storage,n=t.bufferLife,i=t.initialState,o=t.enhancer;this.createStore=t.createStore,this.storage=r,this.reducer=e,this.enhancer=o,this.buffLife=n?Math.min(Math.max(n,0),2e3):100,this.state0=i,this.state=null,this.buffStore=null,this.lastState=null,this.listeners=[],this.inited=!1,this.dispatch=this.dispatch.bind(this),this.subscribe=this.subscribe.bind(this)};i.prototype.init=function(){var t=this;if(this.inited)return new Promise((function(e){e(t)}));var n=this._createStore().getState();return this.storage.subscribe((function(r,n){if(!e(r,t.state)){t._setState(r);for(var i=0,o=t.listeners;o.length>i;i+=1){(0,o[i])(n)}}})),this.inited=!0,new Promise((function(i){t.storage.load((function(o){var s=o?r(n,o):n;t.state0&&(s=r(s,t.state0)),t._setState(s),e(s,o)||t._send2Storage(s),i(t)}))}))},i.prototype.initFrom=function(t){return this._setState(t),this.inited=!0,this},i.prototype.uninit=function(){var t=this;return new Promise((function(e){e(t)}))},i.prototype._createStore=function(t){return this.createStore(this.reducer,t,this.enhancer)},i.prototype._send2Storage=function(t){this.storage.save(t)},i.prototype._setState=function(e){e&&(this.state=t(e))},i.prototype.getState=function(){return this.state},i.prototype.subscribe=function(t){var e=this;return"function"==typeof t&&this.listeners.push(t),function(){"function"==typeof t&&(e.listeners=e.listeners.filter((function(e){return e!==t})))}},i.prototype.dispatch=function(t){var r=this;this.buffStore||(this.buffStore=this._createStore(this.state),this.lastState=this.buffStore.getState(),setTimeout((function(){r.buffStore=null}),this.buffLife));var n=this.buffStore,i=n.subscribe((function(){var t=r.buffStore||n,o=t&&t.getState();e(o,r.lastState)||(r._send2Storage(o),r.lastState=o,i(),n=null)}));return n.dispatch(t)},i.prototype.replaceReducer=function(t){return"function"==typeof t&&(this.reducer=t),this},i.prototype[Symbol.observable]=function(){var t,e=this.getState,r=this.subscribe;return(t={subscribe:function(t){if("object"!=typeof t||null===t)throw new TypeError("Expected the observer to be an object.");function n(){t.next&&t.next(e())}return n(),{unsubscribe:r(n)}}})[Symbol.observable]=function(){return this},t},function(t){t.local="local",t.sync="sync"}(n||(n={}));var o=function(t){var e=t.area,r=t.key;this.ns=t.namespace,this.areaName=e===n.sync?n.sync:n.local,this.key=r||"reduxed",this.keyLen=this.key.length,this.lastSize=0,this.listeners=[],this.errorListeners=[]};o.prototype.init=function(){var t=this;this.ns.storage.onChanged.addListener((function(e,r){if(r===t.areaName&&t.key in e){var n=e[t.key],i=n.newValue,o=n.oldValue;if(i){t.lastSize=JSON.stringify(i).length;for(var s=0,a=t.listeners;a.length>s;s+=1){(0,a[s])(i,o)}}}}))},o.prototype.subscribe=function(t){"function"==typeof t&&this.listeners.push(t)},o.prototype.subscribeForError=function(t){"function"==typeof t&&this.errorListeners.push(t)},o.prototype.fireErrorListeners=function(t,e){for(var r=0,n=this.errorListeners;n.length>r;r+=1){(0,n[r])(t,e)}},o.prototype.getErrorMessage=function(){if(this.ns.runtime.lastError)return this.ns.runtime.lastError.message||""},o.prototype.callbackOnLoad=function(t,e){t=!this.ns.runtime.lastError&&t&&t[this.key],!this.lastSize&&t&&(this.lastSize=JSON.stringify(t).length),e(t)},o.prototype.checkQuotaPerItem=function(t,e,r){var i=this.areaName===n.sync&&e&&e.QUOTA_BYTES_PER_ITEM&&r&&JSON.stringify(r).length+this.keyLen>e.QUOTA_BYTES_PER_ITEM;return i&&this.fireErrorListeners(t),i},o.prototype.checkQuota=function(t,e,r,n){var i=!this.ns.runtime.lastError&&e&&e.QUOTA_BYTES&&r&&n>0&&this.lastSize>0&&JSON.stringify(r).length-this.lastSize>e.QUOTA_BYTES-n;this.fireErrorListeners(t,i)};var s,a=function(t){function e(e){t.call(this,{namespace:e.namespace,area:e.area,key:e.key}),this.areaApi=this.ns.storage[this.areaName]}return t&&(e.__proto__=t),(e.prototype=Object.create(t&&t.prototype)).constructor=e,e.prototype.load=function(t){var e=this;"function"==typeof t&&this.areaApi.get(this.key,(function(r){e.callbackOnLoad(r,t)}))},e.prototype.save=function(t){var e,r=this;this.areaApi.set(((e={})[this.key]=t,e),(function(){var e=r.getErrorMessage();void 0!==e&&!r.checkQuotaPerItem(e,r.areaApi,t)&&r.areaApi.getBytesInUse(null,(function(n){r.checkQuota(e,r.areaApi,t,n)}))}))},e}(o),c=function(t){function e(e){t.call(this,{namespace:e.namespace,area:e.area,key:e.key}),this.areaApi=this.ns.storage[this.areaName]}return t&&(e.__proto__=t),(e.prototype=Object.create(t&&t.prototype)).constructor=e,e.prototype.load=function(t){var e=this;"function"==typeof t&&this.areaApi.get(this.key).then((function(r){e.callbackOnLoad(r,t)}))},e.prototype.save=function(t){var e,r=this;this.areaApi.set((e={},e[this.key]=t,e)).then((function(){var e=r.getErrorMessage();void 0!==e&&!r.checkQuotaPerItem(e,r.areaApi,t)&&r.areaApi.getBytesInUse(null).then((function(n){r.checkQuota(e,r.areaApi,t,n)}))}))},e}(o);return function(t){t.chrome="chrome",t.browser="browser"}(s||(s={})),function(t){var e=t.createStore,r=t.namespace,n=t.chromeNs,o=t.browserNs,u=t.changeListener,f=t.errorListener,h=t.storageArea,p=t.storageKey,l=t.bufferLife;if("function"!=typeof e)throw Error("Missing 'createStore' property/option");var y=o||r===s.browser?new c({namespace:o||browser,area:h,key:p}):new a({namespace:n||chrome,area:h,key:p});return y.init(),"function"==typeof f&&y.subscribeForError(f),function(t,r,n){if("function"!=typeof t)throw Error("Missing 'reducer' parameter");if("function"==typeof r&&"function"==typeof n)throw Error("Multiple 'enhancer' parameters unallowed");"function"==typeof r&&void 0===n&&(n=r,r=void 0);var o=new i({createStore:e,storage:y,bufferLife:l,reducer:t,initialState:r,enhancer:n});return"function"!=typeof u?o.init():(y.subscribe((function(t,e){u(o.initFrom(t),e)})),o.uninit())}}}));

@@ -23,3 +23,9 @@ export declare enum StorageAreaName {

export declare type StorageGetKeys = string | string[] | StorageData | null;
export interface StorageAreaCallbacked {
export declare type StorageUsageCallback = (data: number) => void;
export declare type StorageUsageKeys = string | string[] | null;
export interface StorageAreaQuotas {
QUOTA_BYTES: number;
QUOTA_BYTES_PER_ITEM?: number;
}
export interface StorageAreaCallbacked extends StorageAreaQuotas {
get(callback: StorageGetCallback): void;

@@ -29,7 +35,9 @@ get(keys: StorageGetKeys, callback: StorageGetCallback): void;

clear(): void;
getBytesInUse(keys: StorageUsageKeys, callback: StorageUsageCallback): void;
}
export interface StorageAreaPromised {
export interface StorageAreaPromised extends StorageAreaQuotas {
get(keys?: StorageGetKeys): Promise<StorageData>;
set(data: StorageData): Promise<void>;
clear(): void;
getBytesInUse(keys: StorageUsageKeys): Promise<number>;
}

@@ -36,0 +44,0 @@ export interface ApisNamespace {

{
"name": "reduxed-chrome-storage",
"version": "2.2.0",
"version": "2.4.0",
"description": "Redux-compatible interface to chrome.storage. Unified way to use Redux in all modern browser extensions. The only way to get Redux working in Manifest V3 Chrome extensions",

@@ -16,2 +16,4 @@ "license": "MIT",

"chrome-storage",
"browser-extension",
"webextension",
"store",

@@ -32,23 +34,23 @@ "state"

"chai": "^4",
"eslint": "^6",
"eslint-import-resolver-typescript": "^2",
"eslint-plugin-import": "^2",
"eslint": "^7",
"eslint-import-resolver-typescript": "^2.4",
"eslint-plugin-import": "^2.24",
"mocha": "^8",
"redux": "^4",
"redux-thunk": "^2",
"rollup": "^2",
"rollup": "^2.56",
"@rollup/plugin-buble": "^0.21",
"rollup-plugin-delete": "^2",
"rollup-plugin-license": "^2",
"rollup-plugin-license": "^2.5",
"rollup-plugin-terser": "^7",
"rollup-plugin-typescript2": "^0.29",
"rollup-plugin-typescript2": "^0.30",
"sinon": "^9",
"ts-mocha": "^8",
"typescript": "^4",
"typescript": "^4.3",
"@types/chai": "^4",
"@types/mocha": "^8",
"@types/node": "^14",
"@types/node": "^16.4",
"@types/sinon": "^9",
"@typescript-eslint/eslint-plugin": "^4",
"@typescript-eslint/parser": "^4"
"@typescript-eslint/eslint-plugin": "^4.29",
"@typescript-eslint/parser": "^4.29"
},

@@ -55,0 +57,0 @@ "scripts": {

@@ -117,9 +117,17 @@ # Reduxed Chrome Storage

This option only makes sense in Manifest V3 service workers or event-driven background scripts. If this option is supplied, the async store creator returned by the factory is to only be used for holding the arguments to be passed to the original `createStore` upon a one-time store creation.
This option only makes sense in Manifest V3 service workers or event-driven background scripts. However it works in the same way in persistent scripts too, which may be useful for cross-browser development. Note: if this option is supplied, the async store creator returned by the factory is not supposed to be immediately used for store creation; its only purpose in this case is to hold the arguments to be passed to the original `createStore` upon a one-time store creation.
### errorListener
Type: `function` (`ErrorListener` in Typescript definition)<br>
A function to be called whenever an error occurs during `chrome.storage` update, receives two parameters:
1. an error message defined by storage API;
2. a boolean indicating if the limit for the used storage area is exceeded.
### storageArea
Type: `string`<br>
Default: `'sync'`
Default: `'local'`
The name of `chrome.storage` area to be used, either `'sync'` or `'local'`.
The name of `chrome.storage` area to be used, either `'sync'` or `'local'`. Note: it is not recommended to use `sync` area for immediately storing the state of extension. Use `local` area instead - it has less strict limits than `sync`. If you need to sync the state (entirely or partially) to a user's account, create a temporary store of `sync` area, then copy the needed data to (or from) the main store (of `local` area).

@@ -126,0 +134,0 @@ ### storageKey

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